8 |
* All rights reserved. |
* All rights reserved. |
9 |
*/ |
*/ |
10 |
|
|
|
#define NR 200 |
|
|
#define NC 200 |
|
|
|
|
11 |
#include <string.h> |
#include <string.h> |
12 |
#include <stdio.h> |
#include <stdio.h> |
13 |
|
#include <assert.h> |
14 |
#include <Diderot/diderot.h> |
#include <Diderot/diderot.h> |
15 |
|
|
16 |
|
struct struct_world { |
17 |
|
bool isArray; // is the initialization an array or collection? |
18 |
|
uint32_t nDims; // depth of iteration nesting |
19 |
|
int32_t *base; // nDims array of base indices |
20 |
|
uint32_t *size; // nDims array of iteration sizes |
21 |
|
uint32_t numStrands; // number of strands in the world |
22 |
|
void **inState; |
23 |
|
void **outState; |
24 |
|
bool *isActive; // array of isActive flags |
25 |
|
}; |
26 |
|
|
27 |
extern float getOutf (void *self); |
extern float getOutf (void *self); |
28 |
|
|
29 |
int main (int argc, const char **argv) |
int main (int argc, const char **argv) |
34 |
|
|
35 |
// FIXME: we need to figure out how initialization should be handled. |
// FIXME: we need to figure out how initialization should be handled. |
36 |
printf("initializing strands ...\n"); |
printf("initializing strands ...\n"); |
37 |
void *strands1[NR*NC], *strands2[NR*NC]; |
Diderot_World_t *wrld = Diderot_Initially (); |
|
bool active[NR*NC]; |
|
|
for (int r = 0; r < NR; r++) { |
|
|
for (int c = 0; c < NC; c++) { |
|
|
int i = NC*r + c; |
|
|
strands1[i] = Diderot_AllocStrand (&(Diderot_Strands[0])); |
|
|
strands2[i] = Diderot_AllocStrand (&(Diderot_Strands[0])); |
|
|
active[i] = true; |
|
|
Diderot_Strands[0].init(strands1[i], r, c); |
|
|
// copy so that static fields are initialized |
|
|
memcpy (strands2[i], strands1[i], Diderot_Strands[0].stateSzb); |
|
|
} |
|
|
} |
|
38 |
|
|
39 |
// iterate until all strands are stable |
// iterate until all strands are stable |
40 |
printf("run ...\n"); |
printf("run ...\n"); |
41 |
int nSteps = 0, nUpdates = 0; |
int nSteps = 0, nUpdates = 0; |
42 |
int nActive = NR*NC; |
int nActive = wrld->numStrands; |
|
void **in = &(strands1[0]); |
|
|
void **out = &(strands2[0]); |
|
43 |
while (nActive > 0) { |
while (nActive > 0) { |
44 |
nSteps++; |
nSteps++; |
45 |
// update strands |
// update strands |
46 |
for (int i = 0; i < NR*NC; i++) { |
for (int i = 0; i < wrld->numStrands; i++) { |
47 |
if (active[i]) { |
if (wrld->isActive[i]) { |
48 |
nUpdates++; |
nUpdates++; |
49 |
StrandStatus_t sts = Diderot_Strands[0].update(in[i], out[i]); |
StrandStatus_t sts = Diderot_Strands[0].update(wrld->inState[i], wrld->outState[i]); |
50 |
if (sts == DIDEROT_STABILIZE) { |
if (sts == DIDEROT_STABILIZE) { |
51 |
// copy out to in so that both copies are the stable state |
// copy out to in so that both copies are the stable state |
52 |
memcpy (in[i], out[i], Diderot_Strands[0].stateSzb); |
// FIXME: there is a race condition here, since other strands might query this strand |
53 |
active[i] = false; |
memcpy (wrld->outState[i], wrld->inState[i], Diderot_Strands[0].stateSzb); |
54 |
|
wrld->isActive[i] = false; |
55 |
nActive--; |
nActive--; |
56 |
} |
} |
57 |
} |
} |
58 |
} |
} |
59 |
// swap in and out |
// swap in and out |
60 |
void **tmp = in; |
void **tmp = wrld->inState; |
61 |
in = out; |
wrld->inState = wrld->outState; |
62 |
out = tmp; |
wrld->outState = tmp; |
63 |
} |
} |
64 |
|
|
65 |
printf("done: %d updates, %d steps\n", nUpdates, nSteps); |
printf("done: %d updates, %d steps\n", nUpdates, nSteps); |
70 |
exit (8); |
exit (8); |
71 |
} |
} |
72 |
|
|
73 |
for (int r = 0; r <= 199; r++) { |
for (int i = 0; i < wrld->numStrands; i++) { |
74 |
for (int c = 0; c <= 199; c++) { |
float outV = getOutf (wrld->inState[i]); |
|
int i = NC*r + c; |
|
|
float outV = getOutf (in[i]); |
|
75 |
fprintf (outS, "%f\n", outV); |
fprintf (outS, "%f\n", outV); |
76 |
} |
} |
|
} |
|
77 |
fclose (outS); |
fclose (outS); |
78 |
|
|
79 |
return 0; |
return 0; |
86 |
{ |
{ |
87 |
return malloc(strand->stateSzb); |
return malloc(strand->stateSzb); |
88 |
} |
} |
89 |
|
|
90 |
|
// block allocation of an initial collection of strands |
91 |
|
Diderot_World_t *Diderot_AllocInitially (Strand_t *strand, Diderot_Initially_t *init) |
92 |
|
{ |
93 |
|
Diderot_World_t *wrld = (Diderot_World_t *) malloc (sizeof(Diderot_World_t)); |
94 |
|
if (wrld == 0) { |
95 |
|
fprintf (stderr, "unable to allocate world\n"); |
96 |
|
exit (1); |
97 |
|
} |
98 |
|
|
99 |
|
wrld->isArray = init->isArray; |
100 |
|
wrld->nDims = init->nDims; |
101 |
|
wrld->base = (int32_t *) malloc (wrld->nDims * sizeof(int32_t)); |
102 |
|
wrld->size = (int32_t *) malloc (wrld->nDims * sizeof(int32_t)); |
103 |
|
size_t numStrands = 1; |
104 |
|
for (int i = 0; i < wrld->nDims; i++) { |
105 |
|
numStrands *= init->size[i]; |
106 |
|
wrld->base[i] = init->base[i]; |
107 |
|
wrld->size[i] = init->size[i]; |
108 |
|
} |
109 |
|
|
110 |
|
// allocate the strand state pointers |
111 |
|
wrld->numStrands = numStrands; |
112 |
|
wrld->inState = (void **) malloc (numStrands * sizeof(void *)); |
113 |
|
wrld->outState = (void **) malloc (numStrands * sizeof(void *)); |
114 |
|
wrld->isActive = (bool *) malloc (numStrands * sizeof(bool)); |
115 |
|
if ((wrld->inState == 0) || (wrld->outState == 0) || (wrld->isActive == 0)) { |
116 |
|
fprintf (stderr, "unable to allocate strand states\n"); |
117 |
|
exit (1); |
118 |
|
} |
119 |
|
|
120 |
|
// initialize strand state pointers etc. |
121 |
|
for (size_t i = 0; i < numStrands; i++) { |
122 |
|
wrld->inState[i] = Diderot_AllocStrand (strand); |
123 |
|
wrld->outState[i] = Diderot_AllocStrand (strand); |
124 |
|
wrld->isActive[i] = true; |
125 |
|
} |
126 |
|
|
127 |
|
return wrld; |
128 |
|
|
129 |
|
} |
130 |
|
|
131 |
|
// get strand state pointers |
132 |
|
void *Diderot_InState (Diderot_World_t *wrld, uint32_t i) |
133 |
|
{ |
134 |
|
assert (i < wrld->numStrands); |
135 |
|
return wrld->inState[i]; |
136 |
|
} |
137 |
|
|
138 |
|
void *Diderot_OutState (Diderot_World_t *wrld, uint32_t i) |
139 |
|
{ |
140 |
|
assert (i < wrld->numStrands); |
141 |
|
return wrld->outState[i]; |
142 |
|
} |
143 |
|
|
144 |
|
bool Diderot_IsActive (Diderot_World_t *wrld, uint32_t i) |
145 |
|
{ |
146 |
|
assert (i < wrld->numStrands); |
147 |
|
return wrld->isActive[i]; |
148 |
|
} |