SCM Repository
Annotation of /branches/lamont/src/compiler/c-target/fragments/par-kdtree.in
Parent Directory
|
Revision Log
Revision 2570 - (view) (download)
1 : | lamonts | 2453 | /* sequential version of the merge sort for the spatial indices */ |
2 : | void Diderot_Spatial_SeqMergeSort(@PREFIX@World_t *wrld, uint32_t * indices, uint32_t * tmpIndices, int low, int high, uint32_t dim) | ||
3 : | lamonts | 2422 | { |
4 : | |||
5 : | lamonts | 2453 | if (low >= high) |
6 : | return; | ||
7 : | lamonts | 2422 | |
8 : | lamonts | 2453 | int mid = (low + high) / 2; |
9 : | |||
10 : | //Sort two sub-arrays first so that they are placed into the temporary | ||
11 : | //indices array. | ||
12 : | Diderot_Spatial_SeqMergeSort(wrld,tmpIndices,indices, low, mid,dim); | ||
13 : | Diderot_Spatial_SeqMergeSort(wrld,tmpIndices,indices, mid + 1, high,dim); | ||
14 : | |||
15 : | // Once temporary indice array contains the two sorted sub-arrays | ||
16 : | // they are merged into indice array | ||
17 : | Diderot_Spatial_SeqMerge(wrld,indices,tmpIndices,low, mid, mid + 1, high,low,dim); | ||
18 : | } | ||
19 : | /* sequential version of the merge operation for the spatial indices */ | ||
20 : | /* Note: Sub-arrays are adjacent to each other in the | ||
21 : | the sequential version but not necessarily for the parallel version; | ||
22 : | therefore, sub-arrays boundaries must be specified | ||
23 : | explicitly.*/ | ||
24 : | void Diderot_Spatial_SeqMerge(@PREFIX@World_t *wrld, uint32_t * indices, uint32_t * tmpIndices, int lowL, int highL, int lowR, int highR, int low, uint32_t dim) | ||
25 : | { | ||
26 : | int high = low + highL - lowL + highR - lowR + 1; | ||
27 : | |||
28 : | //Note: The offset is needed for the way the tree is built. We need to make sure the next axis to be sorted | ||
29 : | //has a duplicate copy of the current sorted axis | ||
30 : | lamonts | 2570 | int offSet = (dim + 1) * wrld->numStrands; |
31 : | bool setOffSet = (dim + 1) != wrld->spatialTree->dim; | ||
32 : | lamonts | 2453 | // Bottom-up implementation |
33 : | for (;low <= high; low++) | ||
34 : | { | ||
35 : | if (lowL > highL){ | ||
36 : | indices[low] = tmpIndices[lowR]; | ||
37 : | lamonts | 2570 | if(setOffSet){ |
38 : | indices[low + offSet] = tmpIndices[lowR]; | ||
39 : | tmpIndices[low + offSet] = tmpIndices[lowR]; | ||
40 : | } | ||
41 : | lamonts | 2453 | lowR++; |
42 : | }else if (lowR > highR) { | ||
43 : | indices[low] = tmpIndices[lowL]; | ||
44 : | lamonts | 2570 | if(setOffSet){ |
45 : | indices[low + offSet] = tmpIndices[lowL]; | ||
46 : | tmpIndices[low + offSet] = tmpIndices[lowL]; | ||
47 : | } | ||
48 : | lamonts | 2453 | lowL++; |
49 : | }else { | ||
50 : | Diderot_real_t lowLValue = Diderot_KDTree_GetPosValue(wrld->inState[tmpIndices[lowL]],dim); | ||
51 : | Diderot_real_t lowRValue = Diderot_KDTree_GetPosValue(wrld->inState[tmpIndices[lowR]],dim); | ||
52 : | if(lowLValue < lowRValue){ | ||
53 : | indices[low] = tmpIndices[lowL]; | ||
54 : | lamonts | 2570 | if(setOffSet){ |
55 : | indices[low + offSet] = tmpIndices[lowL]; | ||
56 : | tmpIndices[low + offSet] = tmpIndices[lowL]; | ||
57 : | } | ||
58 : | lamonts | 2453 | lowL++; |
59 : | }else { | ||
60 : | indices[low] = tmpIndices[lowR]; | ||
61 : | lamonts | 2570 | if(setOffSet) { |
62 : | indices[low + offSet] = tmpIndices[lowR]; | ||
63 : | tmpIndices[low + offSet] = tmpIndices[lowR]; | ||
64 : | } | ||
65 : | lamonts | 2453 | lowR++; |
66 : | } | ||
67 : | } | ||
68 : | lamonts | 2422 | } |
69 : | lamonts | 2453 | } |
70 : | /* Swaps the values at two addresses */ | ||
71 : | void Diderot_KDTree_SwapValues(int * a, int *b){ | ||
72 : | int temp; | ||
73 : | temp = *a; | ||
74 : | *a = *b; | ||
75 : | *b = temp; | ||
76 : | } | ||
77 : | int Diderot_BinarySearch(@PREFIX@World_t *wrld,uint32_t *tmpIndices, int low, int high, Diderot_real_t searchValue, int dim) | ||
78 : | { | ||
79 : | if(low > high + 1) | ||
80 : | high = low; | ||
81 : | else | ||
82 : | high = high + 1; | ||
83 : | lamonts | 2422 | |
84 : | lamonts | 2453 | while (low < high) |
85 : | { | ||
86 : | int mid = (low + high) / 2; | ||
87 : | Diderot_real_t pivot = Diderot_KDTree_GetPosValue(wrld->inState[tmpIndices[mid]],dim); | ||
88 : | if (pivot < searchValue) | ||
89 : | low = mid + 1; | ||
90 : | else | ||
91 : | high = mid; | ||
92 : | } | ||
93 : | return low; | ||
94 : | } | ||
95 : | /* Assigns a worker to perform a spatial task (merge sort, merge,or tree node construction) */ | ||
96 : | lamonts | 2562 | SpatialWorkerArgs_t * Diderot_Grab_SpatailWorker(SpatialScheduler_t* sched,ParSpatialWorkerType workerType,void * nodeData, bool * donePtr){ |
97 : | lamonts | 2422 | |
98 : | lamonts | 2453 | SpatialWorkerArgs_t * retWorker = 0; |
99 : | pthread_mutex_lock (&sched->lock); | ||
100 : | lamonts | 2565 | for(int i = sched->nextWorker; i < sched->numWorkers; i++){ |
101 : | lamonts | 2453 | if(sched->workerData[i].isIdle){ |
102 : | sched->workerData[i].isIdle = false; | ||
103 : | sched->workerData[i].data = nodeData; | ||
104 : | lamonts | 2562 | sched->workerData[i].isDone = donePtr; |
105 : | lamonts | 2453 | sched->workerData[i].workerType = workerType; |
106 : | retWorker = &sched->workerData[i]; | ||
107 : | pthread_cond_signal (&sched->workerData[i].runWait); | ||
108 : | sched->nextWorker++; | ||
109 : | lamonts | 2565 | if(sched->nextWorker == sched->numWorkers-1) |
110 : | lamonts | 2453 | sched->nextWorker = 0; |
111 : | break; | ||
112 : | } | ||
113 : | } | ||
114 : | pthread_mutex_unlock (&sched->lock); | ||
115 : | return retWorker; | ||
116 : | lamonts | 2422 | } |
117 : | lamonts | 2453 | /* parallel version of the merge sort for the spatial indices */ |
118 : | void Diderot_Spatial_ParMergeSort(@PREFIX@World_t *wrld,SpatialScheduler_t * sched,uint32_t * indices, uint32_t * tmpIndices, int low, int high, int depth, uint32_t dim) | ||
119 : | lamonts | 2422 | { |
120 : | lamonts | 2562 | bool isDone = false; |
121 : | lamonts | 2453 | // If the depth is less than zero or there's not enough work to perform in parallel |
122 : | // then run the sequential version. | ||
123 : | if (high - low + 1 <= sched->seqThreshold || depth <= 0) | ||
124 : | { | ||
125 : | Diderot_Spatial_SeqMergeSort(wrld,indices,tmpIndices, low, high,dim); | ||
126 : | return; | ||
127 : | } | ||
128 : | if(low < high) { | ||
129 : | int mid = (low + high) / 2; | ||
130 : | depth--; | ||
131 : | lamonts | 2422 | |
132 : | lamonts | 2453 | //Assign a worker to do the upper half the merge sort. |
133 : | MergetSortNode_t node; | ||
134 : | node.low=low; | ||
135 : | node.high = mid; | ||
136 : | node.indices = tmpIndices; | ||
137 : | node.tmpIndices = indices; | ||
138 : | node.depth = depth; | ||
139 : | node.dim = dim; | ||
140 : | |||
141 : | lamonts | 2562 | SpatialWorkerArgs_t * worker = Diderot_Grab_SpatailWorker(sched,MERGESORT_WORKER,(void *)&node,&isDone); |
142 : | lamonts | 2453 | |
143 : | //If a worker is not avaliable then this worker will perform both halves. | ||
144 : | if(!worker){ | ||
145 : | Diderot_Spatial_ParMergeSort(wrld,sched,tmpIndices,indices,low, mid,depth,dim); | ||
146 : | Diderot_Spatial_ParMergeSort(wrld,sched,tmpIndices,indices,mid + 1, high, depth,dim); | ||
147 : | }else { | ||
148 : | lamonts | 2570 | Diderot_Spatial_ParMergeSort(wrld,sched,tmpIndices,indices,mid + 1, high, depth,dim); |
149 : | lamonts | 2453 | //Wait until the worker has completed its task |
150 : | pthread_mutex_lock (&worker->lock); | ||
151 : | lamonts | 2562 | while(!isDone) |
152 : | lamonts | 2570 | pthread_cond_wait (&worker->done,&worker->lock); |
153 : | pthread_mutex_unlock (&worker->lock); | ||
154 : | } | ||
155 : | //Merge the two sorted lists. | ||
156 : | Diderot_Spatial_ParMerge(wrld,sched,indices,tmpIndices,low, mid, mid + 1, high, low, depth,dim); | ||
157 : | lamonts | 2453 | } |
158 : | |||
159 : | } | ||
160 : | /* parallel version of the merge operation for the spatial indices */ | ||
161 : | void Diderot_Spatial_ParMerge(@PREFIX@World_t *wrld,SpatialScheduler_t * sched,uint32_t * indices, uint32_t * tmpIndices,int lowL, int highL, int lowR, int highR, int low, int depth, int dim) | ||
162 : | { | ||
163 : | int nL = highL - lowL + 1; | ||
164 : | int nR = highR - lowR + 1; | ||
165 : | lamonts | 2562 | bool isDone = false; |
166 : | lamonts | 2453 | |
167 : | // If the depth is less than zero or there's not enough work to perform in parallel | ||
168 : | // then run the sequential version. | ||
169 : | if (nL + nR <= sched->seqThreshold || depth <= 0) | ||
170 : | lamonts | 2570 | { |
171 : | Diderot_Spatial_SeqMerge(wrld,indices,tmpIndices,lowL, highL, lowR, highR,low,dim); | ||
172 : | lamonts | 2453 | return; |
173 : | } | ||
174 : | |||
175 : | if (nL < nR) | ||
176 : | { | ||
177 : | Diderot_KDTree_SwapValues(&lowL,&lowR); | ||
178 : | Diderot_KDTree_SwapValues(&highL,&highR); | ||
179 : | Diderot_KDTree_SwapValues(&nL,&nR); | ||
180 : | } | ||
181 : | if(nL == 0) return; | ||
182 : | else | ||
183 : | { | ||
184 : | int midL = (lowL + highL) / 2; | ||
185 : | |||
186 : | Diderot_real_t pivot = Diderot_KDTree_GetPosValue(wrld->inState[tmpIndices[midL]],dim); | ||
187 : | |||
188 : | int midR = Diderot_BinarySearch(wrld,tmpIndices, lowR, highR, pivot,dim); | ||
189 : | |||
190 : | lamonts | 2562 | int mid = low + (midL - lowL) + (midR - lowR); |
191 : | lamonts | 2453 | |
192 : | indices[mid] = tmpIndices[midL]; | ||
193 : | |||
194 : | lamonts | 2570 | if((dim + 1) < wrld->spatialTree->dim) |
195 : | { | ||
196 : | //Note: The offset is needed for the way the tree is built. We need to make sure the next axis to be sorted | ||
197 : | //has a duplicate copy of the current sorted axis | ||
198 : | int offSet = ((dim + 1) * wrld->numStrands); | ||
199 : | indices[mid + offSet] = tmpIndices[midL]; | ||
200 : | tmpIndices[mid + offSet] = tmpIndices[midL]; | ||
201 : | } | ||
202 : | lamonts | 2453 | |
203 : | lamonts | 2570 | depth--; |
204 : | |||
205 : | lamonts | 2453 | //Have a worker perform the upper half of the merge |
206 : | MergeNode_t node; | ||
207 : | node.depth = depth; | ||
208 : | node.lowL = lowL; | ||
209 : | node.highL= midL - 1; | ||
210 : | node.lowR = lowR; | ||
211 : | lamonts | 2562 | node.indices = indices; |
212 : | node.tmpIndices = tmpIndices; | ||
213 : | lamonts | 2453 | node.highR = midR - 1; |
214 : | node.low = low; | ||
215 : | node.dim = dim; | ||
216 : | |||
217 : | lamonts | 2562 | SpatialWorkerArgs_t * worker = Diderot_Grab_SpatailWorker(sched,MERGE_WORKER,(void *)&node,&isDone); |
218 : | lamonts | 2453 | |
219 : | if(!worker){ | ||
220 : | Diderot_Spatial_ParMerge(wrld,sched,indices,tmpIndices, lowL, midL-1, lowR, midR -1, low, depth,dim); | ||
221 : | Diderot_Spatial_ParMerge(wrld,sched,indices,tmpIndices, midL + 1, highL, midR, highR, mid + 1, depth,dim); | ||
222 : | }else { | ||
223 : | Diderot_Spatial_ParMerge(wrld,sched,indices,tmpIndices, midL + 1, highL, midR, highR, mid + 1, depth,dim); | ||
224 : | pthread_mutex_lock (&worker->lock); | ||
225 : | lamonts | 2562 | while(!isDone) |
226 : | lamonts | 2453 | pthread_cond_wait (&worker->done,&worker->lock); |
227 : | pthread_mutex_unlock (&worker->lock); | ||
228 : | } | ||
229 : | } | ||
230 : | } | ||
231 : | /*The worker function for all the workers */ | ||
232 : | void treeWorker(SpatialWorkerArgs_t * workerArg){ | ||
233 : | |||
234 : | while(!workerArg->sched->buildIsDone) | ||
235 : | { | ||
236 : | //Wait until a task is assigned to the worker | ||
237 : | pthread_mutex_lock (&workerArg->sched->lock); | ||
238 : | lamonts | 2566 | if(!workerArg->sched->buildIsDone){ |
239 : | lamonts | 2570 | if(workerArg->sched->numRunning - 1 > 0) |
240 : | lamonts | 2566 | { |
241 : | workerArg->isIdle = true; | ||
242 : | workerArg->sched->numRunning-=1; | ||
243 : | pthread_cond_wait (&workerArg->runWait,&workerArg->sched->lock); | ||
244 : | }else { | ||
245 : | workerArg->sched->buildIsDone = true; | ||
246 : | for(unsigned int i = 0; i < workerArg->sched->numWorkers; i++){ | ||
247 : | if(i != workerArg->id) | ||
248 : | pthread_cond_signal (&workerArg->sched->workerData[i].runWait); | ||
249 : | } | ||
250 : | } | ||
251 : | workerArg->sched->numRunning+=1; | ||
252 : | } | ||
253 : | lamonts | 2453 | pthread_mutex_unlock (&workerArg->sched->lock); |
254 : | |||
255 : | lamonts | 2562 | if(workerArg->sched->buildIsDone){ |
256 : | workerArg->isIdle = false; | ||
257 : | break; | ||
258 : | } | ||
259 : | lamonts | 2453 | //Based on the worker type perform the assigned task. |
260 : | if(workerArg->workerType == MERGESORT_WORKER){ | ||
261 : | MergetSortNode_t * node = (MergetSortNode_t *)workerArg->data; | ||
262 : | Diderot_Spatial_ParMergeSort(workerArg->wrld, | ||
263 : | workerArg->sched, | ||
264 : | node->indices, | ||
265 : | node->tmpIndices, | ||
266 : | node->low, | ||
267 : | node->high, | ||
268 : | node->depth, | ||
269 : | node->dim); | ||
270 : | |||
271 : | }else if(workerArg->workerType == MERGE_WORKER) { | ||
272 : | MergeNode_t * node = (MergeNode_t *)workerArg->data; | ||
273 : | Diderot_Spatial_ParMerge(workerArg->wrld, | ||
274 : | workerArg->sched, | ||
275 : | node->indices, | ||
276 : | node->tmpIndices, | ||
277 : | node->lowL, | ||
278 : | node->highL, | ||
279 : | node->lowR, | ||
280 : | node->highR, | ||
281 : | node->low, | ||
282 : | node->depth, | ||
283 : | node->dim); | ||
284 : | }else if(workerArg->workerType == TREE_WORKER){ | ||
285 : | lamonts | 2570 | KDNode_t* node = (KDNode_t *)workerArg->data; |
286 : | if((node->start + node->len)- 1> workerArg->wrld->numStrands){ | ||
287 : | printf("worker=%d, PROBLEM start = %d len = %d\n",workerArg->id,node->start,node->len); | ||
288 : | exit(1); | ||
289 : | } | ||
290 : | node->right = Diderot_KDTree_BuildHelper(workerArg->wrld, | ||
291 : | lamonts | 2453 | workerArg->sched, |
292 : | node->start, | ||
293 : | node->len, | ||
294 : | node->axis); | ||
295 : | |||
296 : | } | ||
297 : | //Notify any worker waiting for this task to be completed. | ||
298 : | lamonts | 2566 | if(workerArg->workerType == MERGESORT_WORKER || |
299 : | workerArg->workerType == MERGE_WORKER) { | ||
300 : | pthread_mutex_lock (&workerArg->lock); | ||
301 : | *(workerArg->isDone)= true; | ||
302 : | pthread_cond_signal (&workerArg->done); | ||
303 : | pthread_mutex_unlock (&workerArg->lock); | ||
304 : | } | ||
305 : | lamonts | 2453 | } |
306 : | } | ||
307 : | /* Finds the median strand in an array of strands based on the given axis*/ | ||
308 : | @STRANDTY@ * find_median(@PREFIX@World_t *wrld, SpatialScheduler_t * sched, int start, int end, int idx, int * mid){ | ||
309 : | |||
310 : | int startIdx = start + (idx * wrld->numStrands); | ||
311 : | int endIdx = end + (idx * wrld->numStrands); | ||
312 : | int midIdx = startIdx + (endIdx - startIdx)/2; | ||
313 : | |||
314 : | if(end <= start) return NULL; | ||
315 : | if(end == start + 1) { | ||
316 : | *mid = start; | ||
317 : | return wrld->inState[wrld->spatialIndices[startIdx]]; | ||
318 : | } | ||
319 : | lamonts | 2570 | /* int count = 0; |
320 : | bool error=false; | ||
321 : | for(int i = startIdx + 1; i < endIdx; i++){ | ||
322 : | |||
323 : | Diderot_real_t t1 = Diderot_KDTree_GetPosValue(wrld->inState[wrld->spatialIndices[i-1]],idx); | ||
324 : | Diderot_real_t t2 = Diderot_KDTree_GetPosValue(wrld->inState[wrld->spatialIndices[i]],idx); | ||
325 : | if(t1 > t2){ | ||
326 : | printf("Problem start=%d, end=%d curr=%d, t1=%f t2=%f\n",start,end,count,t1,t2); | ||
327 : | error = true; | ||
328 : | } | ||
329 : | count++; | ||
330 : | } | ||
331 : | if(error) | ||
332 : | exit(1); */ | ||
333 : | lamonts | 2453 | *mid = start + (end-start)/2; |
334 : | lamonts | 2570 | if(midIdx > (2 * wrld->numStrands)) { |
335 : | printf("MidIdx is bigger = %d\n",midIdx); | ||
336 : | exit(1); | ||
337 : | } | ||
338 : | lamonts | 2453 | return wrld->inState[wrld->spatialIndices[midIdx]]; |
339 : | } | ||
340 : | /* A recursive tree building function */ | ||
341 : | KDNode_t * Diderot_KDTree_BuildHelper(@PREFIX@World_t *wrld, SpatialScheduler_t * sched,int start, int len, int axis) | ||
342 : | { | ||
343 : | KDNode_t* newNode = NULL; | ||
344 : | lamonts | 2562 | bool isDone = false; |
345 : | lamonts | 2453 | @STRANDTY@ * n; |
346 : | if (!len) return 0; | ||
347 : | int mid; | ||
348 : | lamonts | 2570 | |
349 : | lamonts | 2453 | if ((n = find_median(wrld,sched,start,start + len,axis,&mid))) { |
350 : | lamonts | 2570 | |
351 : | printf("Start=%d,Len=%d,Mid=%d\n",start,len,mid); | ||
352 : | |||
353 : | pthread_mutex_lock (&sched->lock); | ||
354 : | lamonts | 2563 | newNode = Diderot_KDTree_GrabNode(wrld->spatialTree); |
355 : | pthread_mutex_unlock (&sched->lock); | ||
356 : | lamonts | 2453 | newNode->strandId = n->strandId; |
357 : | axis = (axis + 1) % wrld->spatialTree->dim; | ||
358 : | |||
359 : | // If the depth is less than zero or there's not enough work to perform in parallel | ||
360 : | // then run the sequential version. | ||
361 : | if(len < sched->seqThreshold){ | ||
362 : | newNode->left = Diderot_KDTree_BuildHelper(wrld,sched,start,mid - start, axis); | ||
363 : | newNode->right = Diderot_KDTree_BuildHelper(wrld,sched,mid + 1,start + len - (mid+ 1), axis); | ||
364 : | }else{ | ||
365 : | //Have a woker build the right side of the tree. | ||
366 : | lamonts | 2570 | newNode->axis = axis; |
367 : | newNode->len = start + len - (mid + 1); | ||
368 : | newNode->start = mid + 1; | ||
369 : | lamonts | 2453 | |
370 : | lamonts | 2570 | SpatialWorkerArgs_t * worker = Diderot_Grab_SpatailWorker(sched,TREE_WORKER,(void *)newNode,&isDone); |
371 : | lamonts | 2453 | |
372 : | lamonts | 2570 | |
373 : | if((newNode->start + newNode->len)- 1> wrld->numStrands){ | ||
374 : | if(worker) | ||
375 : | printf("INSIDE BUILD worker=%d, PROBLEM start = %d len = %d\n",worker->id,newNode->start,newNode->len); | ||
376 : | else | ||
377 : | printf("INSIDE BUILD no worker, PROBLEM start = %d len = %d\n",newNode->start,newNode->len); | ||
378 : | exit(1); | ||
379 : | } | ||
380 : | |||
381 : | lamonts | 2453 | if(!worker){ |
382 : | newNode->left = Diderot_KDTree_BuildHelper(wrld,sched,start,mid - start, axis); | ||
383 : | newNode->right = Diderot_KDTree_BuildHelper(wrld,sched,mid + 1,start + len - (mid+ 1), axis); | ||
384 : | }else { | ||
385 : | newNode->left = Diderot_KDTree_BuildHelper(wrld,sched,start,mid - start, axis); | ||
386 : | } | ||
387 : | lamonts | 2422 | } |
388 : | lamonts | 2453 | } |
389 : | return newNode; | ||
390 : | } | ||
391 : | lamonts | 2565 | //Debugging purpoes |
392 : | lamonts | 2562 | void printTree(KDNode_t* newNode){ |
393 : | if(newNode != NULL){ | ||
394 : | printf("id=%d\n",newNode->strandId); | ||
395 : | printTree(newNode->right); | ||
396 : | printTree(newNode->left); | ||
397 : | } | ||
398 : | lamonts | 2565 | } |
399 : | lamonts | 2562 | void Diderot_KDTree_Build(@PREFIX@World_t *wrld, uint32_t id, double * spatialTotalTime) |
400 : | lamonts | 2453 | { |
401 : | SpatialScheduler_t * sched = wrld->spatialSched; | ||
402 : | lamonts | 2562 | if(sched->leaderId != id) { |
403 : | lamonts | 2453 | treeWorker(&sched->workerData[id]); |
404 : | return; | ||
405 : | lamonts | 2422 | } |
406 : | lamonts | 2562 | double spatialT0 = airTime(); |
407 : | lamonts | 2453 | KDTree_t * tree = wrld->spatialTree; |
408 : | lamonts | 2570 | int numStrands = *(tree->numOfStrands); |
409 : | lamonts | 2453 | memcpy(wrld->spatialTmpIndices,wrld->spatialIndices, sizeof(uint32_t)*@SPATIAL_DIMENSION@ * wrld->numStrands); |
410 : | Diderot_KDTree_PoolClear(tree); | ||
411 : | lamonts | 2570 | /* Sort the position data */ |
412 : | double spatialST0 = airTime(); | ||
413 : | Diderot_Spatial_ParMergeSort(wrld,sched,wrld->spatialIndices,wrld->spatialTmpIndices,0,numStrands -1,33390,0); | ||
414 : | if(@SPATIAL_DIMENSION@ > 1){ | ||
415 : | Diderot_Spatial_ParMergeSort(wrld,sched,wrld->spatialIndices,wrld->spatialTmpIndices,wrld->numStrands,(2 * wrld->numStrands)-1,33390,1); | ||
416 : | if(@SPATIAL_DIMENSION@ > 2){ | ||
417 : | Diderot_Spatial_ParMergeSort(wrld,sched,wrld->spatialIndices,wrld->spatialTmpIndices,wrld->numStrands * 2,(3 * wrld->numStrands)-1,33390,2); | ||
418 : | } | ||
419 : | } | ||
420 : | double spatialTotalTimeS = (airTime() - spatialST0); | ||
421 : | if(spatialTotalTimeS >= 0.03) | ||
422 : | printf("maybe fixed parallel time to sort=%f\n",spatialTotalTimeS); | ||
423 : | |||
424 : | lamonts | 2453 | tree->root = Diderot_KDTree_BuildHelper(wrld, wrld->spatialSched,0,*(tree->numOfStrands),0); |
425 : | lamonts | 2570 | printf("!!!!!!DONE!!!!\n"); |
426 : | pthread_mutex_lock(&sched->lock); | ||
427 : | sched->numWorkers +=1; | ||
428 : | pthread_mutex_unlock(&sched->lock); | ||
429 : | lamonts | 2566 | treeWorker(&sched->workerData[id]); |
430 : | lamonts | 2565 | //printTree(tree->root); |
431 : | lamonts | 2562 | *(spatialTotalTime) = *(spatialTotalTime) + (airTime() - spatialT0); |
432 : | lamonts | 2569 | printf("Build Done\n"); |
433 : | lamonts | 2453 | } |
434 : | void Diderot_KDTree_Init(@PREFIX@World_t *wrld) | ||
435 : | { | ||
436 : | Diderot_KDTree_Alloc(&wrld->spatialTree,&wrld->numStrands,@SPATIAL_DIMENSION@); | ||
437 : | wrld->spatialIndices= NEWVEC(uint32_t,@SPATIAL_DIMENSION@ * wrld->numStrands); | ||
438 : | wrld->spatialTmpIndices= NEWVEC(uint32_t,@SPATIAL_DIMENSION@ * wrld->numStrands); | ||
439 : | lamonts | 2422 | |
440 : | lamonts | 2453 | uint32_t len = @SPATIAL_DIMENSION@ * wrld->numStrands; |
441 : | lamonts | 2422 | |
442 : | lamonts | 2453 | SpatialScheduler_t * scheduler = (SpatialScheduler_t *)CheckedAlloc(sizeof(SpatialScheduler_t)); |
443 : | if ((pthread_mutex_init (&scheduler->lock, 0)) != 0){ | ||
444 : | printf("Error in initializing the spatial scheduler's lock"); | ||
445 : | exit(EXIT_FAILURE); | ||
446 : | } | ||
447 : | int nWorkers = wrld->sched->numWorkers; | ||
448 : | SpatialWorkerArgs_t * workerArgs = NEWVEC(SpatialWorkerArgs_t, nWorkers); | ||
449 : | scheduler->workerData=workerArgs; | ||
450 : | scheduler->nextWorker = 0; | ||
451 : | lamonts | 2562 | scheduler->numRunning= 0; |
452 : | lamonts | 2453 | scheduler->seqThreshold = SPATIAL_SEQ_THERSHOLD; |
453 : | scheduler->numWorkers = nWorkers; | ||
454 : | scheduler->buildIsDone = false; | ||
455 : | wrld->spatialSched = scheduler; | ||
456 : | lamonts | 2422 | |
457 : | lamonts | 2453 | for(unsigned int i = 0; i < nWorkers; i++){ |
458 : | lamonts | 2562 | workerArgs[i].isIdle = false; |
459 : | lamonts | 2453 | workerArgs[i].data= 0; |
460 : | workerArgs[i].sched = scheduler; | ||
461 : | workerArgs[i].wrld = wrld; | ||
462 : | workerArgs[i].id = i; | ||
463 : | if ((pthread_cond_init (&(workerArgs[i].runWait), 0)) != 0){ | ||
464 : | printf("Error in initializing the scheduler lock"); | ||
465 : | exit(EXIT_FAILURE); | ||
466 : | } | ||
467 : | if ((pthread_cond_init (&(workerArgs[i].done), 0)) != 0){ | ||
468 : | printf("Error in initializing the done condition var "); | ||
469 : | exit(EXIT_FAILURE); | ||
470 : | } | ||
471 : | if ((pthread_mutex_init (&(workerArgs[i].lock), 0)) != 0){ | ||
472 : | printf("Error in initializing the worker lock"); | ||
473 : | exit(EXIT_FAILURE); | ||
474 : | } | ||
475 : | } | ||
476 : | for(uint32_t i = 0; i < len; i++){ | ||
477 : | wrld->spatialIndices[i]= i % wrld->numStrands; | ||
478 : | } | ||
479 : | lamonts | 2422 | } |
480 : | lamonts | 2453 | void Diderot_KDTree_Realloc(@PREFIX@World_t *wrld) |
481 : | { | ||
482 : | wrld->spatialIndices= (uint32_t*)CheckedAlloc(sizeof(uint32_t)*@SPATIAL_DIMENSION@ * wrld->numStrands); | ||
483 : | wrld->spatialTmpIndices= (uint32_t*)CheckedAlloc(sizeof(uint32_t)*@SPATIAL_DIMENSION@ * wrld->numStrands); | ||
484 : | uint32_t len = @SPATIAL_DIMENSION@ * wrld->numStrands; | ||
485 : | for(uint32_t i = 0; i < len; i++){ | ||
486 : | wrld->spatialIndices[i]= i % wrld->numStrands; | ||
487 : | } | ||
488 : | } |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |