1 /*************************************************************************
2 * *
3 * Vega FEM Simulation Library Version 3.1 *
4 * *
5 * "distance field" library , Copyright (C) 2007 CMU, 2016 USC *
6 * All rights reserved. *
7 * *
8 * Code author: Jernej Barbic *
9 * http://www.jernejbarbic.com/code *
10 * *
11 * Research: Jernej Barbic, Hongyi Xu, Doug L. James *
12 * *
13 * Funding: National Science Foundation, Link Foundation, *
14 * Zumberge Research and Innovation Fund at USC *
15 * *
16 * This library is free software; you can redistribute it and/or *
17 * modify it under the terms of the BSD-style license that is *
18 * included with this library in the file LICENSE.txt *
19 * *
20 * This library is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file *
23 * LICENSE.TXT for more details. *
24 * *
25 *************************************************************************/
26
27 /*
28 Multithreaded computation of the distance field. Main computational routines.
29 */
30
31 #ifdef COMPUTE_SIGNED_FIELD
32 #ifdef COMPUTE_FLOOD_FIELD
33 #define COMPUTEFIELDMT_CLASSNAME DistanceFieldMT
34 #define COMPUTEFIELDMT_STRUCTNAME DistanceFieldMT_signed_flood_struct
35 #define COMPUTEFIELDMT_WORKERTHREADNAME DistanceFieldMT_signed_flood_WorkerThread
36 #define ZIGZAGROUTINE DistanceField::ZigZagFloodFillSigned
37 #else
38 #ifdef COMPUTE_CLOSEST_POINT
39 #define COMPUTEFIELDMT_CLASSNAME ClosestPointFieldMT
40 #define COMPUTEFIELDMT_STRUCTNAME ClosestPointFieldMT_signed_struct
41 #define COMPUTEFIELDMT_WORKERTHREADNAME ClosestPointFieldMT_signed_WorkerThread
42 #define ZIGZAGROUTINE ClosestPointField::ZigZagSigned
43 #else
44 #define COMPUTEFIELDMT_CLASSNAME DistanceFieldMT
45 #define COMPUTEFIELDMT_STRUCTNAME DistanceFieldMT_signed_struct
46 #define COMPUTEFIELDMT_WORKERTHREADNAME DistanceFieldMT_signed_WorkerThread
47 #define ZIGZAGROUTINE DistanceField::ZigZagSigned
48 #endif
49 #endif
50 #else
51 #ifdef COMPUTE_CLOSEST_POINT
52 #define COMPUTEFIELDMT_CLASSNAME ClosestPointFieldMT
53 #define COMPUTEFIELDMT_STRUCTNAME ClosestPointFieldMT_unsigned_struct
54 #define COMPUTEFIELDMT_WORKERTHREADNAME ClosestPointFieldMT_unsigned_WorkerThread
55 #define ZIGZAGROUTINE ClosestPointField::ZigZagUnsigned
56 #else
57 #define COMPUTEFIELDMT_CLASSNAME DistanceFieldMT
58 #define COMPUTEFIELDMT_STRUCTNAME DistanceFieldMT_unsigned_struct
59 #define COMPUTEFIELDMT_WORKERTHREADNAME DistanceFieldFieldMT_unsigned_WorkerThread
60 #define ZIGZAGROUTINE DistanceField::ZigZagUnsigned
61 #endif
62 #endif
63
64 //#define USE_MULTICORE_LIBRARY
65 #ifdef USE_MULTICORE_LIBRARY
66 #include "multicore.h"
67 #endif
68
69 struct COMPUTEFIELDMT_STRUCTNAME
70 {
71 COMPUTEFIELDMT_CLASSNAME * object;
72 void * objMeshOctree;
73 void * meshGraph;
74 int rank;
75 int startSlice;
76 int endSlice;
77 };
78
COMPUTEFIELDMT_WORKERTHREADNAME(void * arg)79 void * COMPUTEFIELDMT_WORKERTHREADNAME(void * arg)
80 {
81 struct COMPUTEFIELDMT_STRUCTNAME * threadArgp = (struct COMPUTEFIELDMT_STRUCTNAME*) arg;
82 COMPUTEFIELDMT_CLASSNAME * object = threadArgp->object;
83 void * objMeshOctree = threadArgp->objMeshOctree;
84 void * meshGraph = threadArgp->meshGraph;
85 int rank = threadArgp->rank;
86 //int startSlice = object->GetStartSlice(rank);
87 //int endSlice = object->GetEndSlice(rank);
88 int startSlice = threadArgp->startSlice;
89 int endSlice = threadArgp->endSlice;
90 //printf("rank: %d startSlice: %d endSlice: %d\n", rank, startSlice, endSlice);
91
92 int asterisk=0;
93 if (rank == 0)
94 asterisk = 1;
95
96 object->ZIGZAGROUTINE(objMeshOctree, meshGraph, startSlice, endSlice-1, asterisk);
97
98 return NULL;
99 }
100
101 #ifdef COMPUTE_SIGNED_FIELD
102 #ifdef COMPUTE_CLOSEST_POINT
ZigZagSigned(void * objMeshOctree_,void * meshGraph_)103 int ClosestPointFieldMT::ZigZagSigned(void * objMeshOctree_, void * meshGraph_)
104 #else
105 #ifdef COMPUTE_FLOOD_FIELD
106 int DistanceFieldMT::ZigZagFloodFillSigned(void * objMeshOctree_, void * meshGraph_)
107 #else
108 int DistanceFieldMT::ZigZagSigned(void * objMeshOctree_, void * meshGraph_)
109 #endif
110 #endif
111 #else
112 #ifdef COMPUTE_CLOSEST_POINT
113 int ClosestPointFieldMT::ZigZagUnsigned(void * objMeshOctree_, void * meshGraph_)
114 #else
115 int DistanceFieldMT::ZigZagUnsigned(void * objMeshOctree_, void * meshGraph_)
116 #endif
117 #endif
118 {
119 Setup();
120
121 struct COMPUTEFIELDMT_STRUCTNAME * threadArgv = (struct COMPUTEFIELDMT_STRUCTNAME*) malloc (sizeof(struct COMPUTEFIELDMT_STRUCTNAME) * numThreads);
122
123 for(int i=0; i<numThreads; i++)
124 {
125 threadArgv[i].object = this;
126 threadArgv[i].objMeshOctree = objMeshOctree_;
127 threadArgv[i].meshGraph = meshGraph_;
128 threadArgv[i].rank = i;
129 threadArgv[i].startSlice = GetStartSlice(i);
130 threadArgv[i].endSlice = GetEndSlice(i);
131 }
132
133 #ifdef USE_MULTICORE_LIBRARY
134 Multicore * multicore = new Multicore(numThreads);
135 for(int i=0; i<numThreads; i++)
136 {
137 multicore->SetThreadTask(i, COMPUTEFIELDMT_WORKERTHREADNAME);
138 multicore->SetThreadTaskParameter(i, &threadArgv[i]);
139 }
140
141 //assigns equal z-range to every thread (weakness: can be non-even computational load)
142 //multicore->LaunchThreads(0, numThreads);
143
144 int zSlice = zMin;
145 while (zSlice <= zMax)
146 {
147 int availableThread;
148 multicore->WaitForAvailableThread(&availableThread);
149 threadArgv[availableThread].startSlice = zSlice;
150 threadArgv[availableThread].endSlice = zSlice + 1;
151 multicore->LaunchThread(availableThread);
152 zSlice++;
153 }
154
155 multicore->WaitForCompletionOfAllThreads();
156
157 delete(multicore);
158 #else
159 printf("Launching %d threads...\n", numThreads);
160 pthread_t * tid = (pthread_t*) malloc (sizeof(pthread_t) * numThreads);
161 for(int i=0; i<numThreads; i++)
162 {
163 if (pthread_create(&tid[i], NULL, COMPUTEFIELDMT_WORKERTHREADNAME, &threadArgv[i]) != 0)
164 {
165 printf("Error: unable to launch thread %d.\n", i);
166 exit(1);
167 }
168 }
169
170 for(int i=0; i<numThreads; i++)
171 {
172 if (pthread_join(tid[i], NULL) != 0)
173 {
174 printf("Error: unable to join thread %d.\n", i);
175 free(threadArgv);
176 free(tid);
177 free(startSlice);
178 free(endSlice);
179 return 1;
180 }
181 }
182 free(tid);
183 #endif
184
185 free(threadArgv);
186 free(startSlice);
187 free(endSlice);
188
189 return 0;
190 }
191
192 #undef ZIGZAGROUTINE
193 #undef COMPUTEFIELDMT_CLASSNAME
194 #undef COMPUTEFIELDMT_STRUCTNAME
195 #undef COMPUTEFIELDMT_WORKERTHREADNAME
196
197