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 status = sr(profile->devices[i].score);
67 if (status != DS_SUCCESS)
70 free(profile->devices);
78 static ds_status initDSProfile(ds_profile** p,
const char* version) {
81 cl_platform_id* platforms =
NULL;
82 cl_device_id* devices =
NULL;
83 ds_status status = DS_SUCCESS;
84 ds_profile* profile =
NULL;
89 return DS_INVALID_PROFILE;
91 profile = (ds_profile*)malloc(
sizeof(ds_profile));
93 return DS_MEMORY_ERROR;
95 memset(profile, 0,
sizeof(ds_profile));
97 clGetPlatformIDs(0,
NULL, &numPlatforms);
98 if (numPlatforms == 0)
101 platforms = (cl_platform_id*)malloc(numPlatforms*
sizeof(cl_platform_id));
102 if (platforms ==
NULL) {
103 status = DS_MEMORY_ERROR;
106 clGetPlatformIDs(numPlatforms, platforms,
NULL);
109 for (i = 0; i < (
unsigned int)numPlatforms; i++) {
111 clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0,
NULL, &num);
117 devices = (cl_device_id*)malloc(numDevices*
sizeof(cl_device_id));
118 if (devices ==
NULL) {
119 status = DS_MEMORY_ERROR;
123 profile->numDevices = numDevices+1;
124 profile->devices = (ds_device*)malloc(profile->numDevices*
sizeof(ds_device));
125 if (profile->devices ==
NULL) {
126 profile->numDevices = 0;
127 status = DS_MEMORY_ERROR;
130 memset(profile->devices, 0, profile->numDevices*
sizeof(ds_device));
133 for (i = 0; i < (
unsigned int)numPlatforms; i++) {
136 clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, numDevices, devices, &num);
137 for (j = 0; j < num; j++, next++) {
138 char buffer[DS_DEVICE_NAME_LENGTH];
141 profile->devices[next].type = DS_DEVICE_OPENCL_DEVICE;
142 profile->devices[next].oclDeviceID = devices[j];
144 clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DEVICE_NAME
145 , DS_DEVICE_NAME_LENGTH, &buffer,
NULL);
146 length = strlen(buffer);
147 profile->devices[next].oclDeviceName = (
char*)malloc(length+1);
148 memcpy(profile->devices[next].oclDeviceName, buffer, length+1);
150 clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DRIVER_VERSION
151 , DS_DEVICE_NAME_LENGTH, &buffer,
NULL);
152 length = strlen(buffer);
153 profile->devices[next].oclDriverVersion = (
char*)malloc(length+1);
154 memcpy(profile->devices[next].oclDriverVersion, buffer, length+1);
157 profile->devices[next].type = DS_DEVICE_NATIVE_CPU;
158 profile->version = version;
161 if (platforms) free(platforms);
162 if (devices) free(devices);
163 if (status == DS_SUCCESS) {
168 if (profile->devices)
169 free(profile->devices);
180 typedef ds_status (*ds_perf_evaluator)(ds_device* device,
void* data);
184 ,DS_EVALUATE_NEW_ONLY
185 } ds_evaluation_type;
187 static ds_status profileDevices(ds_profile* profile,
188 const ds_evaluation_type type,
189 ds_perf_evaluator evaluator,
190 void* evaluatorData,
unsigned int* numUpdates) {
191 ds_status status = DS_SUCCESS;
193 unsigned int updates = 0;
195 if (profile ==
NULL) {
196 return DS_INVALID_PROFILE;
198 if (evaluator ==
NULL) {
199 return DS_INVALID_PERF_EVALUATOR;
202 for (i = 0; i < profile->numDevices; i++) {
203 ds_status evaluatorStatus;
206 case DS_EVALUATE_NEW_ONLY:
207 if (profile->devices[i].score !=
NULL)
210 case DS_EVALUATE_ALL:
211 evaluatorStatus = evaluator(profile->devices+i, evaluatorData);
212 if (evaluatorStatus != DS_SUCCESS) {
213 status = evaluatorStatus;
219 return DS_INVALID_PERF_EVALUATOR_TYPE;
224 *numUpdates = updates;
229 #define DS_TAG_VERSION "<version>"
230 #define DS_TAG_VERSION_END "</version>"
231 #define DS_TAG_DEVICE "<device>"
232 #define DS_TAG_DEVICE_END "</device>"
233 #define DS_TAG_SCORE "<score>"
234 #define DS_TAG_SCORE_END "</score>"
235 #define DS_TAG_DEVICE_TYPE "<type>"
236 #define DS_TAG_DEVICE_TYPE_END "</type>"
237 #define DS_TAG_DEVICE_NAME "<name>"
238 #define DS_TAG_DEVICE_NAME_END "</name>"
239 #define DS_TAG_DEVICE_DRIVER_VERSION "<driver>"
240 #define DS_TAG_DEVICE_DRIVER_VERSION_END "</driver>"
242 #define DS_DEVICE_NATIVE_CPU_STRING "native_cpu"
246 typedef ds_status (*ds_score_serializer)(ds_device* device,
247 void** serializedScore,
248 unsigned int* serializedScoreSize);
249 static ds_status writeProfileToFile(ds_profile* profile,
250 ds_score_serializer serializer,
252 ds_status status = DS_SUCCESS;
253 FILE* profileFile =
NULL;
257 return DS_INVALID_PROFILE;
259 profileFile = fopen(file,
"wb");
260 if (profileFile==
NULL) {
261 status = DS_FILE_ERROR;
267 fwrite(DS_TAG_VERSION,
sizeof(
char), strlen(DS_TAG_VERSION), profileFile);
268 fwrite(profile->version,
sizeof(
char), strlen(profile->version), profileFile);
269 fwrite(DS_TAG_VERSION_END,
sizeof(
char), strlen(DS_TAG_VERSION_END), profileFile);
270 fwrite(
"\n",
sizeof(
char), 1, profileFile);
272 for (i = 0; i < profile->numDevices && status == DS_SUCCESS; i++) {
273 void* serializedScore;
274 unsigned int serializedScoreSize;
276 fwrite(DS_TAG_DEVICE,
sizeof(
char), strlen(DS_TAG_DEVICE), profileFile);
278 fwrite(DS_TAG_DEVICE_TYPE,
sizeof(
char), strlen(DS_TAG_DEVICE_TYPE),
280 fwrite(&profile->devices[i].type,
sizeof(ds_device_type),1, profileFile);
281 fwrite(DS_TAG_DEVICE_TYPE_END,
sizeof(
char),
282 strlen(DS_TAG_DEVICE_TYPE_END), profileFile);
284 switch(profile->devices[i].type) {
285 case DS_DEVICE_NATIVE_CPU:
298 case DS_DEVICE_OPENCL_DEVICE:
300 fwrite(DS_TAG_DEVICE_NAME,
sizeof(
char), strlen(DS_TAG_DEVICE_NAME),
302 fwrite(profile->devices[i].oclDeviceName,
303 sizeof(
char),strlen(profile->devices[i].oclDeviceName), profileFile);
304 fwrite(DS_TAG_DEVICE_NAME_END,
sizeof(
char),
305 strlen(DS_TAG_DEVICE_NAME_END), profileFile);
307 fwrite(DS_TAG_DEVICE_DRIVER_VERSION,
sizeof(
char),
308 strlen(DS_TAG_DEVICE_DRIVER_VERSION), profileFile);
309 fwrite(profile->devices[i].oclDriverVersion,
sizeof(
char),
310 strlen(profile->devices[i].oclDriverVersion), profileFile);
311 fwrite(DS_TAG_DEVICE_DRIVER_VERSION_END,
sizeof(
char),
312 strlen(DS_TAG_DEVICE_DRIVER_VERSION_END), profileFile);
316 status = DS_UNKNOWN_DEVICE_TYPE;
320 fwrite(DS_TAG_SCORE,
sizeof(
char), strlen(DS_TAG_SCORE), profileFile);
321 status = serializer(profile->devices+i, &serializedScore,
322 &serializedScoreSize);
323 if (status == DS_SUCCESS && serializedScore!=
NULL && serializedScoreSize > 0) {
324 fwrite(serializedScore,
sizeof(
char), serializedScoreSize, profileFile);
325 free(serializedScore);
327 fwrite(DS_TAG_SCORE_END,
sizeof(
char), strlen(DS_TAG_SCORE_END), profileFile);
328 fwrite(DS_TAG_DEVICE_END,
sizeof(
char), strlen(DS_TAG_DEVICE_END), profileFile);
329 fwrite(
"\n",
sizeof(
char),1,profileFile);
337 static ds_status readProFile(
const char* fileName,
char** content,
338 size_t* contentSize) {
346 input = fopen(fileName,
"rb");
348 return DS_FILE_ERROR;
351 fseek(input, 0L, SEEK_END);
354 binary = (
char*)malloc(size);
357 return DS_FILE_ERROR;
359 fread(binary,
sizeof(
char), size, input);
368 static const char* findString(
const char* contentStart,
const char* contentEnd,
369 const char*
string) {
371 const char* currentPosition;
374 stringLength = strlen(
string);
375 currentPosition = contentStart;
376 for(currentPosition = contentStart; currentPosition < contentEnd; currentPosition++) {
377 if (*currentPosition ==
string[0]) {
378 if (currentPosition+stringLength < contentEnd) {
379 if (strncmp(currentPosition,
string, stringLength) == 0) {
380 found = currentPosition;
390 typedef ds_status (*ds_score_deserializer)(ds_device* device,
391 const unsigned char* serializedScore,
392 unsigned int serializedScoreSize);
393 static ds_status readProfileFromFile(ds_profile* profile,
394 ds_score_deserializer deserializer,
397 ds_status status = DS_SUCCESS;
398 char* contentStart =
NULL;
399 const char* contentEnd =
NULL;
403 return DS_INVALID_PROFILE;
405 status = readProFile(file, &contentStart, &contentSize);
406 if (status == DS_SUCCESS) {
407 const char* currentPosition;
408 const char* dataStart;
410 size_t versionStringLength;
412 contentEnd = contentStart + contentSize;
413 currentPosition = contentStart;
417 dataStart = findString(currentPosition, contentEnd, DS_TAG_VERSION);
418 if (dataStart ==
NULL) {
419 status = DS_PROFILE_FILE_ERROR;
422 dataStart += strlen(DS_TAG_VERSION);
424 dataEnd = findString(dataStart, contentEnd, DS_TAG_VERSION_END);
426 status = DS_PROFILE_FILE_ERROR;
430 versionStringLength = strlen(profile->version);
431 if (versionStringLength!=(dataEnd-dataStart)
432 || strncmp(profile->version, dataStart, versionStringLength)!=0) {
434 status = DS_PROFILE_FILE_ERROR;
437 currentPosition = dataEnd+strlen(DS_TAG_VERSION_END);
443 const char* deviceTypeStart;
444 const char* deviceTypeEnd;
445 ds_device_type deviceType;
447 const char* deviceNameStart;
448 const char* deviceNameEnd;
450 const char* deviceScoreStart;
451 const char* deviceScoreEnd;
453 const char* deviceDriverStart;
454 const char* deviceDriverEnd;
456 dataStart = findString(currentPosition, contentEnd, DS_TAG_DEVICE);
457 if (dataStart==
NULL) {
461 dataStart+=strlen(DS_TAG_DEVICE);
462 dataEnd = findString(dataStart, contentEnd, DS_TAG_DEVICE_END);
464 status = DS_PROFILE_FILE_ERROR;
469 deviceTypeStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_TYPE);
470 if (deviceTypeStart==
NULL) {
471 status = DS_PROFILE_FILE_ERROR;
474 deviceTypeStart+=strlen(DS_TAG_DEVICE_TYPE);
475 deviceTypeEnd = findString(deviceTypeStart, contentEnd,
476 DS_TAG_DEVICE_TYPE_END);
477 if (deviceTypeEnd==
NULL) {
478 status = DS_PROFILE_FILE_ERROR;
481 memcpy(&deviceType, deviceTypeStart,
sizeof(ds_device_type));
485 if (deviceType == DS_DEVICE_OPENCL_DEVICE) {
487 deviceNameStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_NAME);
488 if (deviceNameStart==
NULL) {
489 status = DS_PROFILE_FILE_ERROR;
492 deviceNameStart+=strlen(DS_TAG_DEVICE_NAME);
493 deviceNameEnd = findString(deviceNameStart, contentEnd,
494 DS_TAG_DEVICE_NAME_END);
495 if (deviceNameEnd==
NULL) {
496 status = DS_PROFILE_FILE_ERROR;
501 deviceDriverStart = findString(dataStart, contentEnd,
502 DS_TAG_DEVICE_DRIVER_VERSION);
503 if (deviceDriverStart==
NULL) {
504 status = DS_PROFILE_FILE_ERROR;
507 deviceDriverStart+=strlen(DS_TAG_DEVICE_DRIVER_VERSION);
508 deviceDriverEnd = findString(deviceDriverStart, contentEnd,
509 DS_TAG_DEVICE_DRIVER_VERSION_END);
510 if (deviceDriverEnd ==
NULL) {
511 status = DS_PROFILE_FILE_ERROR;
517 for (i = 0; i < profile->numDevices; i++) {
518 if (profile->devices[i].type == DS_DEVICE_OPENCL_DEVICE) {
519 size_t actualDeviceNameLength;
520 size_t driverVersionLength;
522 actualDeviceNameLength = strlen(profile->devices[i].oclDeviceName);
523 driverVersionLength = strlen(profile->devices[i].oclDriverVersion);
524 if (actualDeviceNameLength == (deviceNameEnd - deviceNameStart)
525 && driverVersionLength == (deviceDriverEnd - deviceDriverStart)
526 && strncmp(profile->devices[i].oclDeviceName, deviceNameStart,
527 actualDeviceNameLength)==0
528 && strncmp(profile->devices[i].oclDriverVersion, deviceDriverStart,
529 driverVersionLength)==0) {
530 deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
531 if (deviceNameStart==
NULL) {
532 status = DS_PROFILE_FILE_ERROR;
535 deviceScoreStart+=strlen(DS_TAG_SCORE);
536 deviceScoreEnd = findString(deviceScoreStart, contentEnd,
538 status = deserializer(profile->devices+i,
539 (
const unsigned char*)deviceScoreStart,
540 deviceScoreEnd-deviceScoreStart);
541 if (status != DS_SUCCESS) {
549 else if (deviceType == DS_DEVICE_NATIVE_CPU) {
550 for (i = 0; i < profile->numDevices; i++) {
551 if (profile->devices[i].type == DS_DEVICE_NATIVE_CPU) {
552 deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
553 if (deviceScoreStart==
NULL) {
554 status = DS_PROFILE_FILE_ERROR;
557 deviceScoreStart+=strlen(DS_TAG_SCORE);
558 deviceScoreEnd = findString(deviceScoreStart, contentEnd,
560 status = deserializer(profile->devices+i,
561 (
const unsigned char*)deviceScoreStart,
562 deviceScoreEnd-deviceScoreStart);
563 if (status != DS_SUCCESS) {
571 currentPosition = dataEnd+strlen(DS_TAG_DEVICE_END);
575 if (contentStart!=
NULL) free(contentStart);
579 static ds_status getNumDeviceWithEmptyScore(ds_profile* profile,
583 return DS_MEMORY_ERROR;
585 for (i = 0; i < profile->numDevices; i++) {
586 if (profile->devices[i].score ==
NULL) {