SCM Repository
Annotation of /branches/pure-cfg/src/lib/c-target/main.c
Parent Directory
|
Revision Log
Revision 1518 - (view) (download) (as text)
1 : | jhr | 1093 | /*! \file main.c |
2 : | * | ||
3 : | * \author John Reppy | ||
4 : | */ | ||
5 : | |||
6 : | /* | ||
7 : | * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu) | ||
8 : | * All rights reserved. | ||
9 : | */ | ||
10 : | |||
11 : | jhr | 1411 | #include <Diderot/diderot.h> |
12 : | jhr | 1093 | #include <string.h> |
13 : | #include <stdio.h> | ||
14 : | #include <assert.h> | ||
15 : | nseltzer | 1450 | #include <teem/nrrd.h> |
16 : | jhr | 1093 | |
17 : | jhr | 1262 | // NOTE: we probably should put this in a file that supports runtime printing |
18 : | jhr | 1276 | static bool VerboseFlg = false; |
19 : | static bool TimingFlg = false; | ||
20 : | nseltzer | 1450 | static bool NrrdOutputFlg = false; |
21 : | jhr | 1262 | |
22 : | jhr | 1093 | struct struct_world { |
23 : | jhr | 1448 | const char *name; //!< the program name |
24 : | bool isArray; //!< is the initialization an array or collection? | ||
25 : | uint32_t nDims; //!< depth of iteration nesting | ||
26 : | int32_t *base; //!< nDims array of base indices | ||
27 : | uint32_t *size; //!< nDims array of iteration sizes | ||
28 : | uint32_t numStrands; //!< number of strands in the world | ||
29 : | jhr | 1276 | void **inState; |
30 : | void **outState; | ||
31 : | jhr | 1448 | uint8_t *status; //!< array of strand status flags |
32 : | jhr | 1093 | }; |
33 : | |||
34 : | extern float getOutf (void *self); | ||
35 : | |||
36 : | int main (int argc, const char **argv) | ||
37 : | { | ||
38 : | lamonts | 1462 | |
39 : | jhr | 1262 | Diderot_Options_t *opts = Diderot_OptNew (); |
40 : | jhr | 1093 | |
41 : | jhr | 1263 | Diderot_OptAddFlag (opts, "verbose", "enable runtime-system messages", &VerboseFlg); |
42 : | jhr | 1276 | Diderot_OptAddFlag (opts, "timing", "enable execution timing", &TimingFlg); |
43 : | nseltzer | 1450 | Diderot_OptAddFlag (opts, "nrrd", "enable nrrd output", &NrrdOutputFlg); |
44 : | jhr | 1262 | Diderot_RegisterGlobalOpts (opts); |
45 : | Diderot_OptProcess (opts, argc, argv); | ||
46 : | Diderot_OptFree (opts); | ||
47 : | |||
48 : | // run the generated global initialization code | ||
49 : | jhr | 1411 | if (VerboseFlg) |
50 : | fprintf (stderr, "initializing globals ...\n"); | ||
51 : | jhr | 1262 | Diderot_InitGlobals (); |
52 : | |||
53 : | jhr | 1093 | // FIXME: we need to figure out how initialization should be handled. |
54 : | jhr | 1276 | if (VerboseFlg) fprintf (stderr, "initializing strands ...\n"); |
55 : | jhr | 1093 | Diderot_World_t *wrld = Diderot_Initially (); |
56 : | for (int i = 0; i < wrld->numStrands; i++) { | ||
57 : | // hack to make the invariant part of the state the same in both copies | ||
58 : | jhr | 1276 | memcpy (wrld->outState[i], wrld->inState[i], Diderot_Strands[0]->stateSzb); |
59 : | jhr | 1093 | } |
60 : | |||
61 : | // iterate until all strands are stable | ||
62 : | jhr | 1276 | if (VerboseFlg) fprintf(stderr, "run with %d strands ...\n", wrld->numStrands); |
63 : | double t0 = GetTime(); | ||
64 : | jhr | 1093 | int nSteps = 0, nUpdates = 0; |
65 : | int nActive = wrld->numStrands; | ||
66 : | while (nActive > 0) { | ||
67 : | jhr | 1276 | nSteps++; |
68 : | jhr | 1093 | // update strands |
69 : | jhr | 1276 | bool existsStabilizing = false; |
70 : | for (int i = 0; i < wrld->numStrands; i++) { | ||
71 : | if (! wrld->status[i]) { | ||
72 : | nUpdates++; | ||
73 : | StrandStatus_t sts = Diderot_Strands[0]->update(wrld->inState[i], wrld->outState[i]); | ||
74 : | switch (sts) { | ||
75 : | case DIDEROT_STABILIZE: | ||
76 : | jhr | 1494 | Diderot_Strands[0]->stabilize(wrld->inState[i], wrld->outState[i]); |
77 : | jhr | 1276 | existsStabilizing = true; |
78 : | wrld->status[i] = DIDEROT_STABILIZE; | ||
79 : | break; | ||
80 : | case DIDEROT_DIE: | ||
81 : | wrld->status[i] = DIDEROT_DIE; | ||
82 : | nActive--; | ||
83 : | break; | ||
84 : | default: | ||
85 : | break; | ||
86 : | } | ||
87 : | } | ||
88 : | } | ||
89 : | if (existsStabilizing) { | ||
90 : | for (int i = 0; i < wrld->numStrands; i++) { | ||
91 : | jhr | 1130 | // NOTE: we may want to compact the array of strands |
92 : | jhr | 1276 | if (wrld->status[i] == DIDEROT_STABILIZE) { |
93 : | jhr | 1448 | #ifdef STABILIZE_FIXED |
94 : | // stabilize the strand's state. Note that the outState has been set by | ||
95 : | // the last call to update, so we make the inState be the target of the | ||
96 : | // stabilize method. This call also has the effect of copying out to in. | ||
97 : | Diderot_Strands[0]->stabilize(wrld->outState[i], wrld->inState[i]); | ||
98 : | #endif | ||
99 : | jhr | 1276 | // copy out to in so that both copies are the stable state |
100 : | memcpy (wrld->inState[i], wrld->outState[i], Diderot_Strands[0]->stateSzb); | ||
101 : | wrld->status[i] = DIDEROT_STABLE; | ||
102 : | nActive--; | ||
103 : | } | ||
104 : | } | ||
105 : | } | ||
106 : | jhr | 1093 | // swap in and out |
107 : | jhr | 1276 | void **tmp = wrld->inState; |
108 : | wrld->inState = wrld->outState; | ||
109 : | wrld->outState = tmp; | ||
110 : | jhr | 1093 | } |
111 : | jhr | 1276 | double totalTime = GetTime() - t0; |
112 : | jhr | 1093 | |
113 : | jhr | 1276 | if (VerboseFlg) |
114 : | fprintf (stderr, "done: %d updates, %d steps, in %f seconds\n", nUpdates, nSteps, totalTime); | ||
115 : | else if (TimingFlg) | ||
116 : | printf ("usr=%f\n", totalTime); | ||
117 : | |||
118 : | jhr | 1482 | // output the final strand states |
119 : | jhr | 1481 | Output_Args_t outArgs; |
120 : | outArgs.name = wrld->name; | ||
121 : | outArgs.isArray = wrld->isArray; | ||
122 : | outArgs.numStrands = wrld->numStrands; | ||
123 : | outArgs.status = wrld->status; | ||
124 : | outArgs.inState = wrld->inState; | ||
125 : | outArgs.nDims = wrld->nDims; | ||
126 : | outArgs.size = wrld->size; | ||
127 : | lamonts | 1513 | outArgs.outputSzb = Diderot_Strands[0]->outputSzb; |
128 : | jhr | 1481 | if (NrrdOutputFlg) |
129 : | Diderot_Output (&outArgs); | ||
130 : | else | ||
131 : | Diderot_Print (&outArgs); | ||
132 : | jhr | 1093 | |
133 : | jhr | 1214 | Diderot_Shutdown (wrld); |
134 : | |||
135 : | jhr | 1093 | return 0; |
136 : | |||
137 : | } | ||
138 : | |||
139 : | |||
140 : | // this should be the part of the scheduler | ||
141 : | void *Diderot_AllocStrand (Strand_t *strand) | ||
142 : | { | ||
143 : | jhr | 1472 | return CheckedAlloc(strand->stateSzb); |
144 : | jhr | 1093 | } |
145 : | |||
146 : | // block allocation of an initial collection of strands | ||
147 : | Diderot_World_t *Diderot_AllocInitially ( | ||
148 : | jhr | 1280 | const char *name, // the name of the program |
149 : | jhr | 1276 | Strand_t *strand, // the type of strands being allocated |
150 : | bool isArray, // is the initialization an array or collection? | ||
151 : | uint32_t nDims, // depth of iteration nesting | ||
152 : | int32_t *base, // nDims array of base indices | ||
153 : | uint32_t *size) // nDims array of iteration sizes | ||
154 : | jhr | 1093 | { |
155 : | jhr | 1472 | Diderot_World_t *wrld = NEW(Diderot_World_t); |
156 : | jhr | 1093 | if (wrld == 0) { |
157 : | jhr | 1276 | fprintf (stderr, "unable to allocate world\n"); |
158 : | exit (1); | ||
159 : | jhr | 1093 | } |
160 : | |||
161 : | jhr | 1287 | wrld->name = name; /* NOTE: we are assuming that name is statically allocated! */ |
162 : | jhr | 1093 | wrld->isArray = isArray; |
163 : | wrld->nDims = nDims; | ||
164 : | jhr | 1472 | wrld->base = NEWVEC(int32_t, nDims); |
165 : | wrld->size = NEWVEC(uint32_t, nDims); | ||
166 : | jhr | 1093 | size_t numStrands = 1; |
167 : | for (int i = 0; i < wrld->nDims; i++) { | ||
168 : | jhr | 1276 | numStrands *= size[i]; |
169 : | wrld->base[i] = base[i]; | ||
170 : | wrld->size[i] = size[i]; | ||
171 : | jhr | 1093 | } |
172 : | |||
173 : | jhr | 1276 | if (VerboseFlg) { |
174 : | fprintf(stderr, "AllocInitially: %d", size[0]); | ||
175 : | for (int i = 1; i < nDims; i++) fprintf(stderr, " x %d", size[i]); | ||
176 : | fprintf(stderr, "\n"); | ||
177 : | } | ||
178 : | jhr | 1093 | |
179 : | // allocate the strand state pointers | ||
180 : | wrld->numStrands = numStrands; | ||
181 : | jhr | 1472 | wrld->inState = NEWVEC(void *, numStrands); |
182 : | wrld->outState = NEWVEC(void *, numStrands); | ||
183 : | wrld->status = NEWVEC(uint8_t, numStrands); | ||
184 : | jhr | 1130 | if ((wrld->inState == 0) || (wrld->outState == 0) || (wrld->status == 0)) { |
185 : | jhr | 1276 | fprintf (stderr, "unable to allocate strand states\n"); |
186 : | exit (1); | ||
187 : | jhr | 1093 | } |
188 : | |||
189 : | // initialize strand state pointers etc. | ||
190 : | for (size_t i = 0; i < numStrands; i++) { | ||
191 : | jhr | 1276 | wrld->inState[i] = Diderot_AllocStrand (strand); |
192 : | wrld->outState[i] = Diderot_AllocStrand (strand); | ||
193 : | wrld->status[i] = DIDEROT_ACTIVE; | ||
194 : | jhr | 1093 | } |
195 : | |||
196 : | return wrld; | ||
197 : | |||
198 : | } | ||
199 : | |||
200 : | // get strand state pointers | ||
201 : | void *Diderot_InState (Diderot_World_t *wrld, uint32_t i) | ||
202 : | { | ||
203 : | assert (i < wrld->numStrands); | ||
204 : | return wrld->inState[i]; | ||
205 : | } | ||
206 : | |||
207 : | void *Diderot_OutState (Diderot_World_t *wrld, uint32_t i) | ||
208 : | { | ||
209 : | assert (i < wrld->numStrands); | ||
210 : | return wrld->outState[i]; | ||
211 : | } | ||
212 : | |||
213 : | bool Diderot_IsActive (Diderot_World_t *wrld, uint32_t i) | ||
214 : | { | ||
215 : | assert (i < wrld->numStrands); | ||
216 : | jhr | 1130 | return !wrld->status[i]; |
217 : | jhr | 1093 | } |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |