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