Voilà désolé de vous déranger mais je m'arrache les cheveux sur un problème, et comme je fais du OpenCL pour la première fois je ne sais pas si cela a un rapport ou non.
J'ai les erreurs suivantes données par mon compilateur :
g++ -Wall -std=c++11 -lOpenCL main.cpp YoUtil.cpp libIDAAOS.o -o main
/tmp/ccYhKM4y.o: In function `main':
main.cpp.text+0xb97): undefined reference to `computeDistances(cl::CommandQueue&, cl:
rogram&, int, int, _cl_mem*&, int, _cl_mem*&, _cl_mem*&)'
main.cpp.text+0xc42): undefined reference to `computeWeights(cl::CommandQueue&, cl:
rogram&, int, int, _cl_mem*&, _cl_mem*&, double)'
main.cpp.text+0xcf9): undefined reference to `computeInterpolation(cl::CommandQueue&, cl:
rogram&, int, int, int, _cl_mem*, _cl_mem*, _cl_mem*&, _cl_mem*)'
collect2: error: ld returned 1 exit status
Voici les fichiers qui sont à mon avis concernés par les erreurs mais n'hésitez-pas à demander les autres si j'ai tort :
main.cpp
libIDAAOS.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 #include <iostream> #include <fstream> #include <cmath> #include <cstdlib> #include "IDALib.h" #include "YoUtil.hpp" #include <string> #include <CL/cl.hpp> using namespace std; static void g1(const int NPOINTS, const int DIM, const double(*bounds)[2], const int nDiv, double *grids, const int whichDIM, double *X, int &where) { if (whichDIM == DIM) { // store the grid point & return for (int dim = 0; dim < DIM; ++dim) writeGrid(DIM, NPOINTS, where, dim, grids, X[dim]); // for (int dim = 0; dim < DIM; ++dim) cout << "*" << X[dim] << "* "; cout << endl; ++where; return; } const double inc = (bounds[whichDIM][1] - bounds[whichDIM][0]) / (nDiv - 1); X[whichDIM] = bounds[whichDIM][0]; for (int i = 0; i < nDiv; ++i) { g1(NPOINTS, DIM, bounds, nDiv, grids, whichDIM + 1, X, where); X[whichDIM] += inc; } } // x1, x2, x3, ... y1, y2, y3, ... z1, z1, z3, ... void computeGridCoordinates(const int DIM, const double(*bounds)[2], const int nDiv, double *grids) { const int NPOINTS = pow(nDiv, DIM); double *X = new double[DIM]; int where = 0; g1(NPOINTS, DIM, bounds, nDiv, grids, 0, X, where); delete[]X; } int main(int argc, char **argv) { if (argc < 3) { cerr << argv[0] << " [input filename] [output filename]" << endl; return 255; } ifstream inp(argv[1]); if (!inp.good()) { cerr << "\nError opening file: " << argv[1] << endl; return 254; } int DIM, nPoints, nValues, nDivisions; inp >> DIM >> nPoints >> nValues >> nDivisions; // Allocate memory for storing all necessary data double *knownCoords = new double[DIM * nPoints]; double *knownValues = new double[nPoints * nValues]; double (*bounds)[2] = new double[DIM][2]; // size of DIMS * 2 const int nGrids = (int)pow(nDivisions, DIM); // # of grid points double *gridCoords = new double[(size_t) pow(nDivisions, DIM) * DIM]; double *distances = new double[nGrids * nPoints]; double *weightSum = new double[nGrids]; double *gridValues = new double[nGrids * nValues]; // read data from the specified file and store data into appropriate data structures using write & writeAttribute functions for (int pt = 0; pt < nPoints; ++pt) { for (int dim = 0; dim < DIM; ++dim) { double tmp; inp >> tmp; write(DIM, nPoints, pt, dim, knownCoords, tmp); } for (int attr = 0; attr < nValues; ++attr) { double tmp; inp >> tmp; writeAttribute(nValues, nPoints, pt, attr, knownValues, tmp); } } inp.close(); // show data // for (int i = 0; i < nPoints * DIM; ++i) cout << knownCoords[i] << " "; cout << endl; // for (int i = 0; i < nPoints * nValues; ++i) cout << knownValues[i] << " "; cout << endl; // int where = 0; // find bounds of known data points // create context std::vector<cl::CommandQueue> cmdQueues = std::vector<cl::CommandQueue>(); cl::Context *context = getContext(CL_DEVICE_TYPE_GPU, cmdQueues, 0, true); // create buffers, 0 is the offset, TRUE means blocking cl_mem knownCoords_b = clCreateBuffer((*context)(), CL_MEM_READ_WRITE, sizeof(knownCoords), NULL, 0); clEnqueueWriteBuffer(cmdQueues[0](),knownCoords_b, CL_TRUE, 0, sizeof(knownCoords_b), knownCoords_b, 0, NULL, NULL); cl_mem knownValues_b = clCreateBuffer((*context)(), CL_MEM_READ_WRITE, sizeof(knownValues), NULL, 0); clEnqueueWriteBuffer(cmdQueues[0](), knownValues_b, CL_TRUE, 0, sizeof(knownValues_b), knownValues_b, 0, NULL, NULL); cl_mem gridCoords_b = clCreateBuffer((*context)(), CL_MEM_READ_WRITE, sizeof(gridCoords), NULL, 0); clEnqueueWriteBuffer(cmdQueues[0](), gridCoords_b, CL_TRUE, 0, sizeof(gridCoords_b), gridCoords_b, 0, NULL, NULL); cl_mem distances_b = clCreateBuffer((*context)(), CL_MEM_READ_WRITE, sizeof(distances), NULL, 0); clEnqueueWriteBuffer(cmdQueues[0](), distances_b, CL_TRUE, 0, sizeof(distances_b), distances, 0, NULL, NULL); cl_mem weightSum_b = clCreateBuffer((*context)(), CL_MEM_READ_WRITE, sizeof(weightSum), NULL, 0); clEnqueueWriteBuffer(cmdQueues[0](), weightSum_b, CL_TRUE, 0, sizeof(weightSum_b), weightSum, 0, NULL, NULL); cl_mem gridValues_b = clCreateBuffer((*context)(), CL_MEM_READ_WRITE, sizeof(gridValues), NULL, 0); clEnqueueWriteBuffer(cmdQueues[0](), gridValues_b, CL_TRUE, 0, sizeof(gridValues_b), gridValues_b, 0, NULL, NULL); // parse the source code and build the program std::string source_code = readSourceCode("shepard_extrapolation_kernels.cl"); cl::Program *program = compile(*context, source_code); stopWatch timer; double t1(0.0); timer.start(); computeBounds(DIM, nPoints, knownCoords, bounds); timer.stop(); t1 += timer.elapsedTime(); // for (int i = 0; i < DIM; ++i) cout << bounds[i][0] << ":" << bounds[i][1] << endl; cout << endl; // create grid points in unknownCoords computeGridCoordinates(DIM, bounds, nDivisions, gridCoords); // for (int i = 0; i < nGrids*DIM; ++i) cout << gridCoords[i] << " "; cout << endl; // step 3. compute distances between all grids points and all known data points double t2(0.0); timer.start(); computeDistances(cmdQueues[0], *program, DIM, nPoints, knownCoords_b, nGrids, gridCoords_b, distances_b); timer.stop(); t2 += timer.elapsedTime(); // for (int i = 0; i < nPoints*nGrids; ++i) cout << distances[i] << " "; cout << endl; // step 4. turn the distance array into weight array, and compute the total weight double t3(0.0); timer.start(); computeWeights(cmdQueues[0], *program, nGrids, nPoints, distances_b, weightSum_b); timer.stop(); t3 += timer.elapsedTime(); // for (int i = 0; i < nPoints*nGrids; ++i) cout << distances[i] << " "; cout << endl; // step 5 & 6. compute sum (weights * known Values) / totalWeight double t4(0.0); timer.start(); computeInterpolation(cmdQueues[0], *program, nValues, nGrids, nPoints, distances_b, weightSum_b, knownValues_b, gridValues_b); timer.stop(); t4 += timer.elapsedTime(); // read the results back to the host, CL_TRUE means blocking, 0 is the offset, we read from gridValues_b into gridValues, // 0 events, no events list, no event clEnqueueReadBuffer(cmdQueues[0](), gridValues_b, CL_TRUE, 0, sizeof(gridValues_b), gridValues, 0, NULL, NULL); /* std::cout << "computeBounds : " << t1 << std::endl; std::cout << "computeDistances : " << t2 << std::endl; std::cout << "computeWeights : " << t3 << std::endl; std::cout << "computeInterpolation : " << t4 << std::endl; */ std::cout << t1 << " " << t2 << " " << t3 << " " << t4 << " " << std::endl; // All calculations are finished. Write grid data to the specified output file. ofstream outp(argv[2]); // Output points if (outp.good()) { /* // This part writes scattered data points for (int i = 0; i < nPoints; ++i) { for (int dim = 0; dim < DIM; ++dim) { outp << read(DIM, nPoints, i, dim, knownCoords) << " "; } for (int attr = 0; attr < nValues; ++attr) { outp << readAttribute(nValues, nPoints, i, attr, knownValues); } outp << knownValues[i] << "\n"; } outp << "\n\n"; */ for (int i = 0; i < nGrids; ++i) { for (int dim = 0; dim < DIM; ++dim) { outp << readGrid(DIM, nGrids, i, dim, gridCoords) << " "; } for (int attr = 0; attr < nValues; ++attr) { outp << readGridAttribute(nValues, nGrids, i, attr, gridValues) << " "; } outp << "\n"; } outp.close(); } delete[] bounds; delete[] knownCoords; delete[] gridCoords; delete[] weightSum; delete[] distances; delete[] knownValues; delete[] gridValues; return 0; }
Je remercie tous ceux qui auront eu la gentillesse de lire jusqu'ici et ceux qui pourront éventuellement m'aider car je suis perdu.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329 #include "IDALib.h" #include <iostream> #include <utility> // pair #include <cmath> // sqrt #include <cstdlib> // EXIT_FAILURE #include <limits> #include <cl.hpp> /* Array of structs format */ double read(const int DIM, const int nPoints, const int whichPt, const int whichDim, const double *coords){ /* Read from known coordinates DIM - Dimensionality of coordinates nPoints - Number of known data points whichPt - which known data point is to be read whichDim - which dimension of coordinates is to be read coords - array containing all coordinates of known data points return the coordinate of the DIM dimension of the whichPt point */ if(whichPt > nPoints - 1) { std::cout << "The point that you want to read does not exist" << std::endl; exit(EXIT_FAILURE); } return coords[whichPt * DIM + whichDim]; } void write(const int DIM, const int nPoints, const int whichPt, const int whichDim, double *coords, const double val){ /* Write to known coordinates DIM - Dimensionality of coordinates nPoints - Number of known data points whichPt - which known data point is to be read whichDim - which dimension of coordinates is to be read coords - array containing all coordinates of known data points */ if(whichPt > nPoints - 1) { std::cout << "The point that you want to write does not exist" << std::endl; } coords[whichPt * DIM + whichDim] = val; } double readGrid(const int DIM, const int nGridPoints, const int whichGridPt, const int whichDim, const double *gridCoords){ /* Read grid coordinates DIM - Dimensionality of coordinates nGridPoints - Number of points in the grid whichGridPt - which point in the gread is to be read whichDim - which dimension of coordinates is to be read gridCoords - array containing all coordinates of grid points return the coordinate of the DIM dimension of the whichGridPt */ if(whichGridPt > nGridPoints - 1) { std::cout << "The point that you want to read does not exist in the grid" << std::endl; exit(EXIT_FAILURE); } return gridCoords[whichGridPt * DIM + whichDim]; } void writeGrid(const int DIM, const int nGridPoints, const int whichGridPt, const int whichDim, double *gridCoords, const double val){ /* Write grid coordinates DIM - Dimensionality of coordinates nGridPoints - Number of points in the grid whichGridPt - which point in the gread is to be read whichDim - which dimension of coordinates is to be read gridCoords - array containing all coordinates of grid points */ if(whichGridPt > nGridPoints - 1) { std::cout << "The point that you want to write does not exist in the grid" << std::endl; } gridCoords[whichGridPt * DIM + whichDim] = val; } double readAttribute(const int noAttr, const int nPoints, const int whichPt, const int whichAttr, const double *values){ /* Read known values noAttr - number of attributes at each point nPoints - Number of known data points whichPt - which known data point is to be read whichAttr - which attribute is to be read values - array containing all the values return the value of whichAttr of whichPt */ if(whichPt > nPoints - 1){ std::cout << "The point that you are trying to read does not exist" << std::endl; exit(EXIT_FAILURE); } return values[whichPt * noAttr + whichAttr]; } void writeAttribute(const int noAttr, const int nPoints, const int whichPt, const int whichAttr, double *values, const double val){ /* Write known values noAttr - number of attributes at each point nPoints - Number of known data points whichPt - which known data point is to be read whichAttr - which attribute is to be read values - array containing all the values */ if(whichPt > nPoints - 1){ std::cout << "The point that you are trying to write does not exist" << std::endl; exit(EXIT_FAILURE); } values[whichPt * noAttr + whichAttr] = val; } double readGridAttribute(const int noAttr, const int nPoints, const int whichPt, const int whichAttr, const double *values){ /* Read a grid attribute noAttr - number of attributes at each point nPoints - Number of known data points whichPt - which known data point is to be read whichAttr - which attribute is to be read values - array containing all the values return the value of whichAttr of whichPt */ if(whichPt > nPoints - 1){ std::cout << "The point that you are trying to read does not exist" << std::endl; exit(EXIT_FAILURE); } return values[whichPt * noAttr + whichAttr]; } void writeGridAttribute(const int noAttr, const int nPoints, const int whichPt, const int whichAttr, double *values, const double val){ /* Write known values noAttr - number of attributes at each point nPoints - Number of known data points whichPt - which known data point is to be read whichAttr - which attribute is to be read values - array containing all the values */ if(whichPt > nPoints - 1){ std::cout << "The point that you are trying to write does not exist" << std::endl; exit(EXIT_FAILURE); } values[whichPt * noAttr + whichAttr] = val; } void computeBounds(const int DIM, const int nPoints, const double *knownCoords, double(*bounds)[2]){ /* Find extremes in each dimension of a given set of scatter points DIM - Dimensionality of coordinates nPoints - Number of known data points knowCoords - array containing all coordinates of known data points bounds - 2D array to store the extremes, each row corresponds to a dimension */ for(int i = 0; i < DIM; i++){ double min = std::numeric_limits<double>::max(); double max = std::numeric_limits<double>::min(); for(int j = 0; j < DIM * nPoints; j+= DIM){ if(knownCoords[i + j] < min) min = knownCoords[i + j]; if(knownCoords[i + j] > max) max= knownCoords[i + j]; } bounds[i][0] = min; bounds[i][1] = max; } } void computeDistances(const int DIM, const int nPoints, const double *knownCoords, const int nGrids, const double *gridCoords, double *distances){ /* Compute distances between all known points and all grid points. DIM - Dimensionality of coordinates nPoints - Number of known data points nGrids - number of points in the grid knowCoords - array containing all coordinates of known data points gridCoords - containing all grid points distances - array containing all the distances all data points and all grid points */ for(int k = 0; k < nGrids; k++){ for(int i = 0; i < nPoints; i++){ double distance(0.0); for(int j = 0; j < DIM; j++){ distance += pow(knownCoords[i * DIM + j] - gridCoords[k * DIM + j], 2.0); } distances[k * nPoints + i] = sqrt(distance); } } } void computeWeights(const int nGrids, const int nPoints, double *distances, double *weightSum, const double p){ /* Compute weights from known points to each grid point nPoints - Number of known data points nGrids - number of points in the grid distances - array containing all the distances all data points and all grid points weightSum - array containing the weight sums of each grid point p - parameter to compute sums */ for(int i = 0; i < nGrids; i++){ double weight(0.0); for(int j = 0; j < nPoints; j++){ double this_weight(0.0); if(distances[i * nPoints + j] == 0){ weight = 0.0; break; } this_weight = 1.0 / pow(distances[i * nPoints + j], p); weight += this_weight; distances[i * nPoints + j] = this_weight; } weightSum[i] = weight; } } void computeInterpolation(const int nValues, const int nGrids, const int nPoints, const double *distances, const double *weightSum, const double *knownValues, double *gridValues){ /* Compute unknown values on grid points using weights and known values nValues - number of attributes nGrids - number of points in the grid nPoints - number of known points distances - distances between each pair (known_point, grid_point) weightSum - Sum of the weights for each grid point */ for(int i = 0; i < nGrids; i++){ for(int j = 0; j < nValues; j++){ double weigh_value_sum(0.0); bool to_change(true); for(int k = 0; k < nPoints; k++){ weigh_value_sum += distances[i * nPoints + k] * knownValues[nValues * k + j]; if(distances[i * nPoints + k] == 0){ writeGridAttribute(nValues, nGrids, i, j, gridValues, knownValues[nValues * k + j]); to_change = false; break; } } if(to_change) writeGridAttribute(nValues, nGrids, i, j, gridValues, weigh_value_sum / weightSum[i]); } } } // prepare kernel arguments, work-groups config and launch kernels - No data movements void computeDistances(cl::CommandQueue &cmdQueue, cl::Program &prog, const int DIM, const int nPoints, cl::Buffer &knownCoords, const int nGrids, cl::Buffer &gridCoords, cl::Buffer &distances){ cl_Kernel kernel = clCreateKernel(prog(), "compute_distances", NULL); kernel->setArg(0, DIM); kernel->setArg(1, nPoints); kernel->setArg(2, knownCoords); kernel->setArg(3, nGrids); kernel->setArg(4, gridCoords); kernel->setArg(5, distances); size_t group_size = 4; cl::NDRange local(group_size, group_size, group_size); cl::NDRange global(DIM*nPoints*nGrids + pow(group_size, 3.0) - 1 / pow(group_size, 3.0)); //clEnqueueNDRangeKernel(cmdQueue, kernel, 3, NULL, global, local, 0, NULL, NULL); kernel.bind(cmdQueue, 0, global, local); } void computeWeights(cl::CommandQueue &cmdQueue, cl::Program &prog, const int nGrids, const int nPoints, cl::Buffer &distances, cl::Buffer &weightSum, const MY_DATA_TYPE p = 2.0){ cl_Kernel kernel = clCreateKernel(prog(), "compute_weights", NULL); clSetKernelArg(kernel, 0, sizeof(cl_int), nGrids); clSetKernelArg(kernel, 1, sizeof(cl_int), nPoints); clSetKernelArg(kernel, 2, sizeof(cl_mem), distances); clSetKernelArg(kernel, 3, sizeof(cl_mem), weightSum; clSetKernelArg(kernel, 4, sizeof(cl_double), p); size_t group_size = 8; cl::NDRange local(group_size, group_size); cl::NDRange global(nGrids*nPoints + pow(group_size, 2.0) - 1 / pow(group_size, 2.0)); //clEnqueueNDRangeKernel(cmdQueue, kernel, 2, NULL, global, local, 0, NULL, NULL); kernel.bind(cmdQueue, 0, global, local); } void computeInterpolation(cl::CommandQueue &cmdQueue, cl::Program &prog, const int nValues, const int nGrids, const int nPoints, cl::Buffer &distances, cl::Buffer &weightSum, cl::Buffer &knownValues, cl::Buffer &gridValues){ cl_Kernel kernel = clCreateKernel(prog(), "compute_interpolation", NULL); kernel->setArg(0, nValues); kernel->setArg(1, nGrids); kernel->setArg(2, nPoints); kernel->setArg(3, distances); kernel->setArg(4, weightSum); kernel->setArg(5, knownValues); kernel->setArg(6, gridValues); size_t group_size = 4; cl::NDRange local(group_size, group_size, group_size); cl::NDRange global(nValues*nGrids*nPoints + pow(group_size, 3.0) - 1 / pow(group_size, 3.0)); //clEnqueueNDRangeKernel(cmdQueue, kernel, 3, NULL, global, local, 0, NULL, NULL); // 0 is the offset kernel.bind(cmdQueue, 0, global, local); } // page 111 pour enqueue un kernel // conversion page 137 // max and co 177
Immo
Partager