2 #ifndef DEVICE_SELECTION_H
3 #define DEVICE_SELECTION_H
7 #define _CRT_SECURE_NO_WARNINGS
15 #include <OpenCL/cl.h>
20 #define DS_DEVICE_NAME_LENGTH 256
24 DS_INVALID_PROFILE = 1000,
26 DS_INVALID_PERF_EVALUATOR_TYPE,
27 DS_INVALID_PERF_EVALUATOR,
28 DS_PERF_EVALUATOR_ERROR,
30 DS_UNKNOWN_DEVICE_TYPE,
31 DS_PROFILE_FILE_ERROR,
32 DS_SCORE_SERIALIZER_ERROR,
33 DS_SCORE_DESERIALIZER_ERROR
38 DS_DEVICE_NATIVE_CPU = 0,
39 DS_DEVICE_OPENCL_DEVICE
45 cl_device_id oclDeviceID;
47 char* oclDriverVersion;
53 unsigned int numDevices;
59 typedef ds_status (*ds_score_release)(
void* score);
60 static ds_status releaseDSProfile(ds_profile* profile, ds_score_release sr) {
61 ds_status status = DS_SUCCESS;
63 if (profile->devices!=NULL && sr!=NULL) {
65 for (i = 0; i < profile->numDevices; i++) {
66 if (profile->devices[i].oclDeviceName) free(profile->devices[i].oclDeviceName);
67 if (profile->devices[i].oclDriverVersion) free(profile->devices[i].oclDriverVersion);
68 status = sr(profile->devices[i].score);
69 if (status != DS_SUCCESS)
72 free(profile->devices);
80 static ds_status initDSProfile(ds_profile** p,
const char* version) {
83 cl_platform_id* platforms = NULL;
84 cl_device_id* devices = NULL;
85 ds_status status = DS_SUCCESS;
86 ds_profile* profile = NULL;
91 return DS_INVALID_PROFILE;
93 profile = (ds_profile*)malloc(
sizeof(ds_profile));
95 return DS_MEMORY_ERROR;
97 memset(profile, 0,
sizeof(ds_profile));
99 clGetPlatformIDs(0, NULL, &numPlatforms);
100 if (numPlatforms == 0)
103 platforms = (cl_platform_id*)malloc(numPlatforms*
sizeof(cl_platform_id));
104 if (platforms == NULL) {
105 status = DS_MEMORY_ERROR;
108 clGetPlatformIDs(numPlatforms, platforms, NULL);
111 for (i = 0; i < (
unsigned int)numPlatforms; i++) {
113 clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num);
119 devices = (cl_device_id*)malloc(numDevices*
sizeof(cl_device_id));
120 if (devices == NULL) {
121 status = DS_MEMORY_ERROR;
125 profile->numDevices = numDevices+1;
126 profile->devices = (ds_device*)malloc(profile->numDevices*
sizeof(ds_device));
127 if (profile->devices == NULL) {
128 profile->numDevices = 0;
129 status = DS_MEMORY_ERROR;
132 memset(profile->devices, 0, profile->numDevices*
sizeof(ds_device));
135 for (i = 0; i < (
unsigned int)numPlatforms; i++) {
138 clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, numDevices, devices, &num);
139 for (j = 0; j < num; j++, next++) {
140 char buffer[DS_DEVICE_NAME_LENGTH];
143 profile->devices[next].type = DS_DEVICE_OPENCL_DEVICE;
144 profile->devices[next].oclDeviceID = devices[j];
146 clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DEVICE_NAME
147 , DS_DEVICE_NAME_LENGTH, &buffer, NULL);
148 length = strlen(buffer);
149 profile->devices[next].oclDeviceName = (
char*)malloc(length+1);
150 memcpy(profile->devices[next].oclDeviceName, buffer, length+1);
152 clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DRIVER_VERSION
153 , DS_DEVICE_NAME_LENGTH, &buffer, NULL);
154 length = strlen(buffer);
155 profile->devices[next].oclDriverVersion = (
char*)malloc(length+1);
156 memcpy(profile->devices[next].oclDriverVersion, buffer, length+1);
159 profile->devices[next].type = DS_DEVICE_NATIVE_CPU;
160 profile->version = version;
163 if (platforms) free(platforms);
164 if (devices) free(devices);
165 if (status == DS_SUCCESS) {
170 if (profile->devices)
171 free(profile->devices);
182 typedef ds_status (*ds_perf_evaluator)(ds_device* device,
void* data);
186 ,DS_EVALUATE_NEW_ONLY
187 } ds_evaluation_type;
189 static ds_status profileDevices(ds_profile* profile,
190 const ds_evaluation_type type,
191 ds_perf_evaluator evaluator,
192 void* evaluatorData,
unsigned int* numUpdates) {
193 ds_status status = DS_SUCCESS;
195 unsigned int updates = 0;
197 if (profile == NULL) {
198 return DS_INVALID_PROFILE;
200 if (evaluator == NULL) {
201 return DS_INVALID_PERF_EVALUATOR;
204 for (i = 0; i < profile->numDevices; i++) {
205 ds_status evaluatorStatus;
208 case DS_EVALUATE_NEW_ONLY:
209 if (profile->devices[i].score != NULL)
212 case DS_EVALUATE_ALL:
213 evaluatorStatus = evaluator(profile->devices+i, evaluatorData);
214 if (evaluatorStatus != DS_SUCCESS) {
215 status = evaluatorStatus;
221 return DS_INVALID_PERF_EVALUATOR_TYPE;
226 *numUpdates = updates;
231 #define DS_TAG_VERSION "<version>"
232 #define DS_TAG_VERSION_END "</version>"
233 #define DS_TAG_DEVICE "<device>"
234 #define DS_TAG_DEVICE_END "</device>"
235 #define DS_TAG_SCORE "<score>"
236 #define DS_TAG_SCORE_END "</score>"
237 #define DS_TAG_DEVICE_TYPE "<type>"
238 #define DS_TAG_DEVICE_TYPE_END "</type>"
239 #define DS_TAG_DEVICE_NAME "<name>"
240 #define DS_TAG_DEVICE_NAME_END "</name>"
241 #define DS_TAG_DEVICE_DRIVER_VERSION "<driver>"
242 #define DS_TAG_DEVICE_DRIVER_VERSION_END "</driver>"
244 #define DS_DEVICE_NATIVE_CPU_STRING "native_cpu"
248 typedef ds_status (*ds_score_serializer)(ds_device* device,
249 void** serializedScore,
250 unsigned int* serializedScoreSize);
251 static ds_status writeProfileToFile(ds_profile* profile,
252 ds_score_serializer serializer,
254 ds_status status = DS_SUCCESS;
255 FILE* profileFile = NULL;
259 return DS_INVALID_PROFILE;
261 profileFile = fopen(file,
"wb");
262 if (profileFile==NULL) {
263 status = DS_FILE_ERROR;
269 fwrite(DS_TAG_VERSION,
sizeof(
char), strlen(DS_TAG_VERSION), profileFile);
270 fwrite(profile->version,
sizeof(
char), strlen(profile->version), profileFile);
271 fwrite(DS_TAG_VERSION_END,
sizeof(
char), strlen(DS_TAG_VERSION_END), profileFile);
272 fwrite(
"\n",
sizeof(
char), 1, profileFile);
274 for (i = 0; i < profile->numDevices && status == DS_SUCCESS; i++) {
275 void* serializedScore;
276 unsigned int serializedScoreSize;
278 fwrite(DS_TAG_DEVICE,
sizeof(
char), strlen(DS_TAG_DEVICE), profileFile);
280 fwrite(DS_TAG_DEVICE_TYPE,
sizeof(
char), strlen(DS_TAG_DEVICE_TYPE),
282 fwrite(&profile->devices[i].type,
sizeof(ds_device_type),1, profileFile);
283 fwrite(DS_TAG_DEVICE_TYPE_END,
sizeof(
char),
284 strlen(DS_TAG_DEVICE_TYPE_END), profileFile);
286 switch(profile->devices[i].type) {
287 case DS_DEVICE_NATIVE_CPU:
300 case DS_DEVICE_OPENCL_DEVICE:
302 fwrite(DS_TAG_DEVICE_NAME,
sizeof(
char), strlen(DS_TAG_DEVICE_NAME),
304 fwrite(profile->devices[i].oclDeviceName,
305 sizeof(
char),strlen(profile->devices[i].oclDeviceName), profileFile);
306 fwrite(DS_TAG_DEVICE_NAME_END,
sizeof(
char),
307 strlen(DS_TAG_DEVICE_NAME_END), profileFile);
309 fwrite(DS_TAG_DEVICE_DRIVER_VERSION,
sizeof(
char),
310 strlen(DS_TAG_DEVICE_DRIVER_VERSION), profileFile);
311 fwrite(profile->devices[i].oclDriverVersion,
sizeof(
char),
312 strlen(profile->devices[i].oclDriverVersion), profileFile);
313 fwrite(DS_TAG_DEVICE_DRIVER_VERSION_END,
sizeof(
char),
314 strlen(DS_TAG_DEVICE_DRIVER_VERSION_END), profileFile);
318 status = DS_UNKNOWN_DEVICE_TYPE;
322 fwrite(DS_TAG_SCORE,
sizeof(
char), strlen(DS_TAG_SCORE), profileFile);
323 status = serializer(profile->devices+i, &serializedScore,
324 &serializedScoreSize);
325 if (status == DS_SUCCESS && serializedScore!=NULL && serializedScoreSize > 0) {
326 fwrite(serializedScore,
sizeof(
char), serializedScoreSize, profileFile);
327 free(serializedScore);
329 fwrite(DS_TAG_SCORE_END,
sizeof(
char), strlen(DS_TAG_SCORE_END), profileFile);
330 fwrite(DS_TAG_DEVICE_END,
sizeof(
char), strlen(DS_TAG_DEVICE_END), profileFile);
331 fwrite(
"\n",
sizeof(
char),1,profileFile);
339 static ds_status readProFile(
const char* fileName,
char** content,
340 size_t* contentSize) {
348 input = fopen(fileName,
"rb");
350 return DS_FILE_ERROR;
353 fseek(input, 0L, SEEK_END);
356 binary = (
char*)malloc(size);
359 return DS_FILE_ERROR;
361 fread(binary,
sizeof(
char), size, input);
370 static const char* findString(
const char* contentStart,
const char* contentEnd,
371 const char*
string) {
373 const char* currentPosition;
376 stringLength = strlen(
string);
377 currentPosition = contentStart;
378 for(currentPosition = contentStart; currentPosition < contentEnd; currentPosition++) {
379 if (*currentPosition ==
string[0]) {
380 if (currentPosition+stringLength < contentEnd) {
381 if (strncmp(currentPosition,
string, stringLength) == 0) {
382 found = currentPosition;
392 typedef ds_status (*ds_score_deserializer)(ds_device* device,
393 const unsigned char* serializedScore,
394 unsigned int serializedScoreSize);
395 static ds_status readProfileFromFile(ds_profile* profile,
396 ds_score_deserializer deserializer,
399 ds_status status = DS_SUCCESS;
400 char* contentStart = NULL;
401 const char* contentEnd = NULL;
405 return DS_INVALID_PROFILE;
407 status = readProFile(file, &contentStart, &contentSize);
408 if (status == DS_SUCCESS) {
409 const char* currentPosition;
410 const char* dataStart;
412 size_t versionStringLength;
414 contentEnd = contentStart + contentSize;
415 currentPosition = contentStart;
419 dataStart = findString(currentPosition, contentEnd, DS_TAG_VERSION);
420 if (dataStart == NULL) {
421 status = DS_PROFILE_FILE_ERROR;
424 dataStart += strlen(DS_TAG_VERSION);
426 dataEnd = findString(dataStart, contentEnd, DS_TAG_VERSION_END);
428 status = DS_PROFILE_FILE_ERROR;
432 versionStringLength = strlen(profile->version);
433 if (versionStringLength!=(dataEnd-dataStart)
434 || strncmp(profile->version, dataStart, versionStringLength)!=0) {
436 status = DS_PROFILE_FILE_ERROR;
439 currentPosition = dataEnd+strlen(DS_TAG_VERSION_END);
445 const char* deviceTypeStart;
446 const char* deviceTypeEnd;
447 ds_device_type deviceType;
449 const char* deviceNameStart;
450 const char* deviceNameEnd;
452 const char* deviceScoreStart;
453 const char* deviceScoreEnd;
455 const char* deviceDriverStart;
456 const char* deviceDriverEnd;
458 dataStart = findString(currentPosition, contentEnd, DS_TAG_DEVICE);
459 if (dataStart==NULL) {
463 dataStart+=strlen(DS_TAG_DEVICE);
464 dataEnd = findString(dataStart, contentEnd, DS_TAG_DEVICE_END);
466 status = DS_PROFILE_FILE_ERROR;
471 deviceTypeStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_TYPE);
472 if (deviceTypeStart==NULL) {
473 status = DS_PROFILE_FILE_ERROR;
476 deviceTypeStart+=strlen(DS_TAG_DEVICE_TYPE);
477 deviceTypeEnd = findString(deviceTypeStart, contentEnd,
478 DS_TAG_DEVICE_TYPE_END);
479 if (deviceTypeEnd==NULL) {
480 status = DS_PROFILE_FILE_ERROR;
483 memcpy(&deviceType, deviceTypeStart,
sizeof(ds_device_type));
487 if (deviceType == DS_DEVICE_OPENCL_DEVICE) {
489 deviceNameStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_NAME);
490 if (deviceNameStart==NULL) {
491 status = DS_PROFILE_FILE_ERROR;
494 deviceNameStart+=strlen(DS_TAG_DEVICE_NAME);
495 deviceNameEnd = findString(deviceNameStart, contentEnd,
496 DS_TAG_DEVICE_NAME_END);
497 if (deviceNameEnd==NULL) {
498 status = DS_PROFILE_FILE_ERROR;
503 deviceDriverStart = findString(dataStart, contentEnd,
504 DS_TAG_DEVICE_DRIVER_VERSION);
505 if (deviceDriverStart==NULL) {
506 status = DS_PROFILE_FILE_ERROR;
509 deviceDriverStart+=strlen(DS_TAG_DEVICE_DRIVER_VERSION);
510 deviceDriverEnd = findString(deviceDriverStart, contentEnd,
511 DS_TAG_DEVICE_DRIVER_VERSION_END);
512 if (deviceDriverEnd ==NULL) {
513 status = DS_PROFILE_FILE_ERROR;
519 for (i = 0; i < profile->numDevices; i++) {
520 if (profile->devices[i].type == DS_DEVICE_OPENCL_DEVICE) {
521 size_t actualDeviceNameLength;
522 size_t driverVersionLength;
524 actualDeviceNameLength = strlen(profile->devices[i].oclDeviceName);
525 driverVersionLength = strlen(profile->devices[i].oclDriverVersion);
526 if (actualDeviceNameLength == (deviceNameEnd - deviceNameStart)
527 && driverVersionLength == (deviceDriverEnd - deviceDriverStart)
528 && strncmp(profile->devices[i].oclDeviceName, deviceNameStart,
529 actualDeviceNameLength)==0
530 && strncmp(profile->devices[i].oclDriverVersion, deviceDriverStart,
531 driverVersionLength)==0) {
532 deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
533 if (deviceNameStart==NULL) {
534 status = DS_PROFILE_FILE_ERROR;
537 deviceScoreStart+=strlen(DS_TAG_SCORE);
538 deviceScoreEnd = findString(deviceScoreStart, contentEnd,
540 status = deserializer(profile->devices+i,
541 (
const unsigned char*)deviceScoreStart,
542 deviceScoreEnd-deviceScoreStart);
543 if (status != DS_SUCCESS) {
551 else if (deviceType == DS_DEVICE_NATIVE_CPU) {
552 for (i = 0; i < profile->numDevices; i++) {
553 if (profile->devices[i].type == DS_DEVICE_NATIVE_CPU) {
554 deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
555 if (deviceScoreStart==NULL) {
556 status = DS_PROFILE_FILE_ERROR;
559 deviceScoreStart+=strlen(DS_TAG_SCORE);
560 deviceScoreEnd = findString(deviceScoreStart, contentEnd,
562 status = deserializer(profile->devices+i,
563 (
const unsigned char*)deviceScoreStart,
564 deviceScoreEnd-deviceScoreStart);
565 if (status != DS_SUCCESS) {
573 currentPosition = dataEnd+strlen(DS_TAG_DEVICE_END);
577 if (contentStart!=NULL) free(contentStart);
581 static ds_status getNumDeviceWithEmptyScore(ds_profile* profile,
584 if (profile == NULL || num==NULL)
585 return DS_MEMORY_ERROR;
587 for (i = 0; i < profile->numDevices; i++) {
588 if (profile->devices[i].score == NULL) {