LCOV - code coverage report
Current view: top level - opencl/inc - opencl_device_selection.h (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 271 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #ifndef INCLUDED_OPENCL_INC_OPENCL_DEVICE_SELECTION_H
      11             : #define INCLUDED_OPENCL_INC_OPENCL_DEVICE_SELECTION_H
      12             : 
      13             : #ifdef _MSC_VER
      14             : #define _CRT_SECURE_NO_WARNINGS
      15             : #endif
      16             : 
      17             : #include <stdlib.h>
      18             : #include <stdio.h>
      19             : #include <string.h>
      20             : 
      21             : #include <clew/clew.h>
      22             : 
      23             : #define DS_DEVICE_NAME_LENGTH 256
      24             : 
      25             : enum ds_status
      26             : {
      27             :     DS_SUCCESS = 0
      28             :     ,DS_INVALID_PROFILE = 1000
      29             :     ,DS_MEMORY_ERROR
      30             :     , DS_INVALID_PERF_EVALUATOR_TYPE
      31             :     , DS_INVALID_PERF_EVALUATOR
      32             :     , DS_PERF_EVALUATOR_ERROR
      33             :     , DS_FILE_ERROR
      34             :     , DS_UNKNOWN_DEVICE_TYPE
      35             :     , DS_PROFILE_FILE_ERROR
      36             :     , DS_SCORE_SERIALIZER_ERROR
      37             :     , DS_SCORE_DESERIALIZER_ERROR
      38             : };
      39             : 
      40             : // device type
      41             : enum ds_device_type
      42             : {
      43             :     DS_DEVICE_NATIVE_CPU = 0
      44             :     ,DS_DEVICE_OPENCL_DEVICE
      45             : };
      46             : 
      47             : 
      48             : struct ds_device
      49             : {
      50             :     ds_device_type  type;
      51             :     cl_device_id    oclDeviceID;
      52             :     char*           oclPlatformVendor;
      53             :     char*           oclDeviceName;
      54             :     char*           oclDriverVersion;
      55             :     void*           score;            // a pointer to the score data, the content/format is application defined
      56             : };
      57             : 
      58             : struct ds_profile
      59             : {
      60             :     unsigned int  numDevices;
      61             :     ds_device*    devices;
      62             :     const char*   version;
      63             : };
      64             : 
      65             : // deallocate memory used by score
      66             : typedef ds_status(* ds_score_release)(void* score);
      67           0 : inline ds_status releaseDSProfile(ds_profile* profile, ds_score_release sr)
      68             : {
      69           0 :     ds_status status = DS_SUCCESS;
      70           0 :     if (profile != NULL)
      71             :     {
      72           0 :         if (profile->devices != NULL && sr != NULL)
      73             :         {
      74             :             unsigned int i;
      75           0 :             for (i = 0; i < profile->numDevices; i++)
      76             :             {
      77           0 :                 free(profile->devices[i].oclPlatformVendor);
      78           0 :                 free(profile->devices[i].oclDeviceName);
      79           0 :                 free(profile->devices[i].oclDriverVersion);
      80           0 :                 status = sr(profile->devices[i].score);
      81           0 :                 if (status != DS_SUCCESS) break;
      82             :             }
      83           0 :             free(profile->devices);
      84             :         }
      85           0 :         free(profile);
      86             :     }
      87           0 :     return status;
      88             : }
      89             : 
      90             : 
      91           0 : inline ds_status initDSProfile(ds_profile** p, const char* version)
      92             : {
      93             :     int numDevices;
      94             :     cl_uint numPlatforms;
      95           0 :     cl_platform_id* platforms = NULL;
      96           0 :     cl_device_id*   devices = NULL;
      97           0 :     ds_status status = DS_SUCCESS;
      98           0 :     ds_profile* profile = NULL;
      99             :     unsigned int next;
     100             :     unsigned int i;
     101             : 
     102           0 :     if (p == NULL) return DS_INVALID_PROFILE;
     103             : 
     104           0 :     profile = static_cast<ds_profile*>(malloc(sizeof(ds_profile)));
     105           0 :     if (profile == NULL) return DS_MEMORY_ERROR;
     106             : 
     107           0 :     memset(profile, 0, sizeof(ds_profile));
     108             : 
     109           0 :     clGetPlatformIDs(0, NULL, &numPlatforms);
     110           0 :     if (numPlatforms != 0)
     111             :     {
     112           0 :         platforms = static_cast<cl_platform_id*>(malloc(numPlatforms * sizeof(cl_platform_id)));
     113           0 :         if (platforms == NULL)
     114             :         {
     115           0 :             status = DS_MEMORY_ERROR;
     116           0 :             goto cleanup;
     117             :         }
     118           0 :         clGetPlatformIDs(numPlatforms, platforms, NULL);
     119             :     }
     120             : 
     121           0 :     numDevices = 0;
     122           0 :     for (i = 0; i < (unsigned int)numPlatforms; i++)
     123             :     {
     124           0 :         cl_uint num = 0;
     125           0 :         cl_int err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num);
     126           0 :         if (err != CL_SUCCESS)
     127             :         {
     128             :             /* we want to catch at least the case when the call returns
     129             :              * CL_DEVICE_NOT_FOUND (i.e. no devices), because some platforms
     130             :              * don't set num to 0 in this case; but in fact this is a good
     131             :              * thing to do for _any_ error returned by the call
     132             :              */
     133           0 :             num = 0;
     134             :         }
     135           0 :         numDevices += num;
     136             :     }
     137           0 :     if (numDevices != 0)
     138             :     {
     139           0 :         devices = static_cast<cl_device_id*>(malloc(numDevices * sizeof(cl_device_id)));
     140           0 :         if (devices == NULL)
     141             :         {
     142           0 :             status = DS_MEMORY_ERROR;
     143           0 :             goto cleanup;
     144             :         }
     145             :     }
     146             : 
     147           0 :     profile->numDevices = numDevices + 1;     // +1 to numDevices to include the native CPU
     148           0 :     profile->devices = static_cast<ds_device*>(malloc(profile->numDevices * sizeof(ds_device)));
     149           0 :     if (profile->devices == NULL)
     150             :     {
     151           0 :         profile->numDevices = 0;
     152           0 :         status = DS_MEMORY_ERROR;
     153           0 :         goto cleanup;
     154             :     }
     155           0 :     memset(profile->devices, 0, profile->numDevices * sizeof(ds_device));
     156             : 
     157           0 :     next = 0;
     158           0 :     for (i = 0; i < (unsigned int)numPlatforms; i++)
     159             :     {
     160           0 :         cl_uint num = 0;
     161             :         unsigned j;
     162             :         char vendor[256];
     163           0 :         if (clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(vendor), vendor, NULL) != CL_SUCCESS)
     164           0 :             vendor[0] = '\0';
     165           0 :         cl_int err = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, numDevices, devices, &num);
     166           0 :         if (err != CL_SUCCESS)
     167             :         {
     168             :             /* we want to catch at least the case when the call returns
     169             :              * CL_DEVICE_NOT_FOUND (i.e. no devices), because some platforms
     170             :              * don't set num to 0 in this case; but in fact this is a good
     171             :              * thing to do for _any_ error returned by the call
     172             :              */
     173           0 :             num = 0;
     174             :         }
     175           0 :         for (j = 0; j < num; j++, next++)
     176             :         {
     177             :             char buffer[DS_DEVICE_NAME_LENGTH];
     178             :             size_t length;
     179             : 
     180           0 :             profile->devices[next].type = DS_DEVICE_OPENCL_DEVICE;
     181           0 :             profile->devices[next].oclDeviceID = devices[j];
     182             : 
     183           0 :             profile->devices[next].oclPlatformVendor = strdup(vendor);
     184             : 
     185           0 :             clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DEVICE_NAME
     186           0 :                             , DS_DEVICE_NAME_LENGTH, &buffer, NULL);
     187           0 :             length = strlen(buffer);
     188           0 :             profile->devices[next].oclDeviceName = static_cast<char*>(malloc(length + 1));
     189           0 :             memcpy(profile->devices[next].oclDeviceName, buffer, length + 1);
     190             : 
     191           0 :             clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DRIVER_VERSION
     192           0 :                             , DS_DEVICE_NAME_LENGTH, &buffer, NULL);
     193           0 :             length = strlen(buffer);
     194           0 :             profile->devices[next].oclDriverVersion = static_cast<char*>(malloc(length + 1));
     195           0 :             memcpy(profile->devices[next].oclDriverVersion, buffer, length + 1);
     196             :         }
     197             :     }
     198           0 :     profile->devices[next].type = DS_DEVICE_NATIVE_CPU;
     199           0 :     profile->version = version;
     200             : 
     201             : cleanup:
     202           0 :     if (platforms)  free(platforms);
     203           0 :     if (devices)    free(devices);
     204           0 :     if (status == DS_SUCCESS)
     205             :     {
     206           0 :         *p = profile;
     207             :     }
     208             :     else
     209             :     {
     210           0 :         if (profile)
     211             :         {
     212           0 :             if (profile->devices) free(profile->devices);
     213           0 :             free(profile);
     214             :         }
     215             :     }
     216           0 :     return status;
     217             : }
     218             : 
     219             : // Pointer to a function that calculates the score of a device (ex: device->score)
     220             : // update the data size of score. The encoding and the format of the score data
     221             : // is implementation defined. The function should return DS_SUCCESS if there's no error to be reported.
     222             : typedef ds_status(* ds_perf_evaluator)(ds_device* device, void* data);
     223             : 
     224             : typedef enum {
     225             :     DS_EVALUATE_ALL
     226             :     , DS_EVALUATE_NEW_ONLY
     227             : } ds_evaluation_type;
     228             : 
     229           0 : inline ds_status profileDevices(ds_profile* profile, const ds_evaluation_type type,
     230             :                                 ds_perf_evaluator evaluator, void* evaluatorData, unsigned int* numUpdates)
     231             : {
     232           0 :     ds_status status = DS_SUCCESS;
     233             :     unsigned int i;
     234           0 :     unsigned int updates = 0;
     235             : 
     236           0 :     if (profile == NULL)
     237             :     {
     238           0 :         return DS_INVALID_PROFILE;
     239             :     }
     240           0 :     if (evaluator == NULL)
     241             :     {
     242           0 :         return DS_INVALID_PERF_EVALUATOR;
     243             :     }
     244             : 
     245           0 :     for (i = 0; i < profile->numDevices; i++)
     246             :     {
     247             :         ds_status evaluatorStatus;
     248             : 
     249           0 :         switch (type)
     250             :         {
     251             :             case DS_EVALUATE_NEW_ONLY:
     252           0 :                 if (profile->devices[i].score != NULL) break;
     253             :                 //  else fall through
     254             :             case DS_EVALUATE_ALL:
     255           0 :                 evaluatorStatus = evaluator(profile->devices + i, evaluatorData);
     256           0 :                 if (evaluatorStatus != DS_SUCCESS)
     257             :                 {
     258           0 :                     status = evaluatorStatus;
     259           0 :                     return status;
     260             :                 }
     261           0 :                 updates++;
     262           0 :                 break;
     263             :             default:
     264           0 :                 return DS_INVALID_PERF_EVALUATOR_TYPE;
     265             :                 break;
     266             :         };
     267             :     }
     268           0 :     if (numUpdates) *numUpdates = updates;
     269           0 :     return status;
     270             : }
     271             : 
     272             : 
     273             : #define DS_TAG_VERSION                      "<version>"
     274             : #define DS_TAG_VERSION_END                  "</version>"
     275             : #define DS_TAG_DEVICE                       "<device>"
     276             : #define DS_TAG_DEVICE_END                   "</device>"
     277             : #define DS_TAG_SCORE                        "<score>"
     278             : #define DS_TAG_SCORE_END                    "</score>"
     279             : #define DS_TAG_DEVICE_TYPE                  "<type>"
     280             : #define DS_TAG_DEVICE_TYPE_END              "</type>"
     281             : #define DS_TAG_DEVICE_NAME                  "<name>"
     282             : #define DS_TAG_DEVICE_NAME_END              "</name>"
     283             : #define DS_TAG_DEVICE_DRIVER_VERSION        "<driver>"
     284             : #define DS_TAG_DEVICE_DRIVER_VERSION_END    "</driver>"
     285             : 
     286             : #define DS_DEVICE_NATIVE_CPU_STRING  "native_cpu"
     287             : 
     288             : typedef ds_status(* ds_score_serializer)(ds_device* device, void** serializedScore, unsigned int* serializedScoreSize);
     289           0 : inline ds_status writeProfileToFile(ds_profile* profile, ds_score_serializer serializer, const char* file)
     290             : {
     291           0 :     ds_status status = DS_SUCCESS;
     292           0 :     FILE* profileFile = NULL;
     293             : 
     294             : 
     295           0 :     if (profile == NULL) return DS_INVALID_PROFILE;
     296             : 
     297           0 :     profileFile = fopen(file, "wb");
     298           0 :     if (profileFile == NULL)
     299             :     {
     300           0 :         status = DS_FILE_ERROR;
     301             :     }
     302             :     else
     303             :     {
     304             :         unsigned int i;
     305             : 
     306             :         // write version string
     307           0 :         fwrite(DS_TAG_VERSION, sizeof(char), strlen(DS_TAG_VERSION), profileFile);
     308           0 :         fwrite(profile->version, sizeof(char), strlen(profile->version), profileFile);
     309           0 :         fwrite(DS_TAG_VERSION_END, sizeof(char), strlen(DS_TAG_VERSION_END), profileFile);
     310           0 :         fwrite("\n", sizeof(char), 1, profileFile);
     311             : 
     312           0 :         for (i = 0; i < profile->numDevices && status == DS_SUCCESS; i++)
     313             :         {
     314             :             void* serializedScore;
     315             :             unsigned int serializedScoreSize;
     316             : 
     317           0 :             fwrite(DS_TAG_DEVICE, sizeof(char), strlen(DS_TAG_DEVICE), profileFile);
     318             : 
     319           0 :             fwrite(DS_TAG_DEVICE_TYPE, sizeof(char), strlen(DS_TAG_DEVICE_TYPE), profileFile);
     320           0 :             fwrite(&profile->devices[i].type, sizeof(ds_device_type), 1, profileFile);
     321           0 :             fwrite(DS_TAG_DEVICE_TYPE_END, sizeof(char), strlen(DS_TAG_DEVICE_TYPE_END), profileFile);
     322             : 
     323           0 :             switch (profile->devices[i].type)
     324             :             {
     325             :                 case DS_DEVICE_NATIVE_CPU:
     326             :                 {
     327             :                     // There's no need to emit a device name for the native CPU device.
     328             :                     /*
     329             :                     fwrite(DS_TAG_DEVICE_NAME, sizeof(char), strlen(DS_TAG_DEVICE_NAME), profileFile);
     330             :                     fwrite(DS_DEVICE_NATIVE_CPU_STRING,sizeof(char),strlen(DS_DEVICE_NATIVE_CPU_STRING), profileFile);
     331             :                     fwrite(DS_TAG_DEVICE_NAME_END, sizeof(char), strlen(DS_TAG_DEVICE_NAME_END), profileFile);
     332             :                     */
     333             :                 }
     334           0 :                     break;
     335             :                 case DS_DEVICE_OPENCL_DEVICE:
     336             :                 {
     337           0 :                     fwrite(DS_TAG_DEVICE_NAME, sizeof(char), strlen(DS_TAG_DEVICE_NAME), profileFile);
     338           0 :                     fwrite(profile->devices[i].oclDeviceName, sizeof(char), strlen(profile->devices[i].oclDeviceName), profileFile);
     339           0 :                     fwrite(DS_TAG_DEVICE_NAME_END, sizeof(char), strlen(DS_TAG_DEVICE_NAME_END), profileFile);
     340             : 
     341           0 :                     fwrite(DS_TAG_DEVICE_DRIVER_VERSION, sizeof(char), strlen(DS_TAG_DEVICE_DRIVER_VERSION), profileFile);
     342           0 :                     fwrite(profile->devices[i].oclDriverVersion, sizeof(char), strlen(profile->devices[i].oclDriverVersion), profileFile);
     343           0 :                     fwrite(DS_TAG_DEVICE_DRIVER_VERSION_END, sizeof(char), strlen(DS_TAG_DEVICE_DRIVER_VERSION_END), profileFile);
     344             :                 }
     345           0 :                     break;
     346             :                 default:
     347           0 :                     break;
     348             :             };
     349             : 
     350           0 :             fwrite(DS_TAG_SCORE, sizeof(char), strlen(DS_TAG_SCORE), profileFile);
     351           0 :             status = serializer(profile->devices + i, &serializedScore, &serializedScoreSize);
     352           0 :             if (status == DS_SUCCESS && serializedScore != NULL && serializedScoreSize > 0)
     353             :             {
     354           0 :                 fwrite(serializedScore, sizeof(char), serializedScoreSize, profileFile);
     355           0 :                 free(serializedScore);
     356             :             }
     357           0 :             fwrite(DS_TAG_SCORE_END, sizeof(char), strlen(DS_TAG_SCORE_END), profileFile);
     358           0 :             fwrite(DS_TAG_DEVICE_END, sizeof(char), strlen(DS_TAG_DEVICE_END), profileFile);
     359           0 :             fwrite("\n", sizeof(char), 1, profileFile);
     360             :         }
     361           0 :         fclose(profileFile);
     362             :     }
     363           0 :     return status;
     364             : }
     365             : 
     366             : 
     367           0 : inline ds_status readProFile(const char* fileName, char** content, size_t* contentSize)
     368             : {
     369           0 :     FILE* input = NULL;
     370           0 :     size_t size = 0;
     371           0 :     char* binary = NULL;
     372           0 :     long pos = -1;
     373             : 
     374           0 :     *contentSize = 0;
     375           0 :     *content = NULL;
     376             : 
     377           0 :     input = fopen(fileName, "rb");
     378           0 :     if (input == NULL)
     379             :     {
     380           0 :         return DS_FILE_ERROR;
     381             :     }
     382             : 
     383           0 :     fseek(input, 0L, SEEK_END);
     384           0 :     pos = ftell(input);
     385           0 :     if (pos < 0)
     386             :     {
     387           0 :         fclose(input);
     388           0 :         return DS_FILE_ERROR;
     389             :     }
     390             : 
     391           0 :     size = pos;
     392           0 :     rewind(input);
     393           0 :     binary = static_cast<char*>(malloc(size));
     394           0 :     if (binary == NULL)
     395             :     {
     396           0 :         fclose(input);
     397           0 :         return DS_FILE_ERROR;
     398             :     }
     399           0 :     size_t bytesRead = fread(binary, sizeof(char), size, input);
     400             :     (void) bytesRead; // avoid warning
     401           0 :     fclose(input);
     402             : 
     403           0 :     *contentSize = size;
     404           0 :     *content = binary;
     405           0 :     return DS_SUCCESS;
     406             : }
     407             : 
     408             : 
     409           0 : inline const char* findString(const char* contentStart, const char* contentEnd, const char* string)
     410             : {
     411             :     size_t stringLength;
     412             :     const char* currentPosition;
     413             :     const char* found;
     414           0 :     found = NULL;
     415           0 :     stringLength = strlen(string);
     416           0 :     currentPosition = contentStart;
     417           0 :     for (currentPosition = contentStart; currentPosition < contentEnd; currentPosition++)
     418             :     {
     419           0 :         if (*currentPosition == string[0])
     420             :         {
     421           0 :             if (currentPosition + stringLength < contentEnd)
     422             :             {
     423           0 :                 if (strncmp(currentPosition, string, stringLength) == 0)
     424             :                 {
     425           0 :                     found = currentPosition;
     426           0 :                     break;
     427             :                 }
     428             :             }
     429             :         }
     430             :     }
     431           0 :     return found;
     432             : }
     433             : 
     434             : 
     435             : typedef ds_status(* ds_score_deserializer)(ds_device* device, const unsigned char* serializedScore, unsigned int serializedScoreSize);
     436           0 : inline ds_status readProfileFromFile(ds_profile* profile, ds_score_deserializer deserializer, const char* file)
     437             : {
     438             : 
     439           0 :     ds_status status = DS_SUCCESS;
     440           0 :     char* contentStart = NULL;
     441           0 :     const char* contentEnd = NULL;
     442             :     size_t contentSize;
     443             : 
     444           0 :     if (profile == NULL) return DS_INVALID_PROFILE;
     445             : 
     446           0 :     status = readProFile(file, &contentStart, &contentSize);
     447           0 :     if (status == DS_SUCCESS)
     448             :     {
     449             :         const char* currentPosition;
     450             :         const char* dataStart;
     451             :         const char* dataEnd;
     452             :         size_t versionStringLength;
     453             : 
     454           0 :         contentEnd = contentStart + contentSize;
     455           0 :         currentPosition = contentStart;
     456             : 
     457             : 
     458             :         // parse the version string
     459           0 :         dataStart = findString(currentPosition, contentEnd, DS_TAG_VERSION);
     460           0 :         if (dataStart == NULL)
     461             :         {
     462           0 :             status = DS_PROFILE_FILE_ERROR;
     463           0 :             goto cleanup;
     464             :         }
     465           0 :         dataStart += strlen(DS_TAG_VERSION);
     466             : 
     467           0 :         dataEnd = findString(dataStart, contentEnd, DS_TAG_VERSION_END);
     468           0 :         if (dataEnd == NULL)
     469             :         {
     470           0 :             status = DS_PROFILE_FILE_ERROR;
     471           0 :             goto cleanup;
     472             :         }
     473             : 
     474           0 :         versionStringLength = strlen(profile->version);
     475           0 :         if (versionStringLength != static_cast<size_t>(dataEnd - dataStart)
     476           0 :             || strncmp(profile->version, dataStart, versionStringLength) != 0)
     477             :         {
     478             :             // version mismatch
     479           0 :             status = DS_PROFILE_FILE_ERROR;
     480           0 :             goto cleanup;
     481             :         }
     482           0 :         currentPosition = dataEnd + strlen(DS_TAG_VERSION_END);
     483             : 
     484             :         // parse the device information
     485             :         while (true)
     486             :         {
     487             :             unsigned int i;
     488             : 
     489             :             const char* deviceTypeStart;
     490             :             const char* deviceTypeEnd;
     491             :             ds_device_type deviceType;
     492             : 
     493             :             const char* deviceNameStart;
     494             :             const char* deviceNameEnd;
     495             : 
     496             :             const char* deviceScoreStart;
     497             :             const char* deviceScoreEnd;
     498             : 
     499             :             const char* deviceDriverStart;
     500             :             const char* deviceDriverEnd;
     501             : 
     502           0 :             dataStart = findString(currentPosition, contentEnd, DS_TAG_DEVICE);
     503           0 :             if (dataStart == NULL)
     504             :             {
     505             :                 // nothing useful remain, quit...
     506           0 :                 break;
     507             :             }
     508           0 :             dataStart += strlen(DS_TAG_DEVICE);
     509           0 :             dataEnd = findString(dataStart, contentEnd, DS_TAG_DEVICE_END);
     510           0 :             if (dataEnd == NULL)
     511             :             {
     512           0 :                 status = DS_PROFILE_FILE_ERROR;
     513           0 :                 goto cleanup;
     514             :             }
     515             : 
     516             :             // parse the device type
     517           0 :             deviceTypeStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_TYPE);
     518           0 :             if (deviceTypeStart == NULL)
     519             :             {
     520           0 :                 status = DS_PROFILE_FILE_ERROR;
     521           0 :                 goto cleanup;
     522             :             }
     523           0 :             deviceTypeStart += strlen(DS_TAG_DEVICE_TYPE);
     524           0 :             deviceTypeEnd = findString(deviceTypeStart, contentEnd, DS_TAG_DEVICE_TYPE_END);
     525           0 :             if (deviceTypeEnd == NULL)
     526             :             {
     527           0 :                 status = DS_PROFILE_FILE_ERROR;
     528           0 :                 goto cleanup;
     529             :             }
     530           0 :             memcpy(&deviceType, deviceTypeStart, sizeof(ds_device_type));
     531             : 
     532             : 
     533             :             // parse the device name
     534           0 :             if (deviceType == DS_DEVICE_OPENCL_DEVICE)
     535             :             {
     536             : 
     537           0 :                 deviceNameStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_NAME);
     538           0 :                 if (deviceNameStart == NULL)
     539             :                 {
     540           0 :                     status = DS_PROFILE_FILE_ERROR;
     541           0 :                     goto cleanup;
     542             :                 }
     543           0 :                 deviceNameStart += strlen(DS_TAG_DEVICE_NAME);
     544           0 :                 deviceNameEnd = findString(deviceNameStart, contentEnd, DS_TAG_DEVICE_NAME_END);
     545           0 :                 if (deviceNameEnd == NULL)
     546             :                 {
     547           0 :                     status = DS_PROFILE_FILE_ERROR;
     548           0 :                     goto cleanup;
     549             :                 }
     550             : 
     551             : 
     552           0 :                 deviceDriverStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_DRIVER_VERSION);
     553           0 :                 if (deviceDriverStart == NULL)
     554             :                 {
     555           0 :                     status = DS_PROFILE_FILE_ERROR;
     556           0 :                     goto cleanup;
     557             :                 }
     558           0 :                 deviceDriverStart += strlen(DS_TAG_DEVICE_DRIVER_VERSION);
     559           0 :                 deviceDriverEnd = findString(deviceDriverStart, contentEnd, DS_TAG_DEVICE_DRIVER_VERSION_END);
     560           0 :                 if (deviceDriverEnd == NULL)
     561             :                 {
     562           0 :                     status = DS_PROFILE_FILE_ERROR;
     563           0 :                     goto cleanup;
     564             :                 }
     565             : 
     566             : 
     567             :                 // check if this device is on the system
     568           0 :                 for (i = 0; i < profile->numDevices; i++)
     569             :                 {
     570           0 :                     if (profile->devices[i].type == DS_DEVICE_OPENCL_DEVICE)
     571             :                     {
     572             :                         size_t actualDeviceNameLength;
     573             :                         size_t driverVersionLength;
     574             : 
     575           0 :                         actualDeviceNameLength = strlen(profile->devices[i].oclDeviceName);
     576           0 :                         driverVersionLength = strlen(profile->devices[i].oclDriverVersion);
     577           0 :                         if (actualDeviceNameLength == static_cast<size_t>(deviceNameEnd - deviceNameStart)
     578           0 :                             && driverVersionLength == static_cast<size_t>(deviceDriverEnd - deviceDriverStart)
     579           0 :                             && strncmp(profile->devices[i].oclDeviceName, deviceNameStart, actualDeviceNameLength) == 0
     580           0 :                             && strncmp(profile->devices[i].oclDriverVersion, deviceDriverStart, driverVersionLength) == 0)
     581             :                         {
     582             : 
     583           0 :                             deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
     584           0 :                             if (deviceScoreStart == NULL)
     585             :                             {
     586           0 :                                 status = DS_PROFILE_FILE_ERROR;
     587           0 :                                 goto cleanup;
     588             :                             }
     589           0 :                             deviceScoreStart += strlen(DS_TAG_SCORE);
     590           0 :                             deviceScoreEnd = findString(deviceScoreStart, contentEnd, DS_TAG_SCORE_END);
     591           0 :                             status = deserializer(profile->devices + i, reinterpret_cast<const unsigned char*>(deviceScoreStart), deviceScoreEnd - deviceScoreStart);
     592           0 :                             if (status != DS_SUCCESS)
     593             :                             {
     594           0 :                                 goto cleanup;
     595             :                             }
     596             :                         }
     597             :                     }
     598             :                 }
     599             : 
     600             :             }
     601           0 :             else if (deviceType == DS_DEVICE_NATIVE_CPU)
     602             :             {
     603           0 :                 for (i = 0; i < profile->numDevices; i++)
     604             :                 {
     605           0 :                     if (profile->devices[i].type == DS_DEVICE_NATIVE_CPU)
     606             :                     {
     607           0 :                         deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
     608           0 :                         if (deviceScoreStart == NULL)
     609             :                         {
     610           0 :                             status = DS_PROFILE_FILE_ERROR;
     611           0 :                             goto cleanup;
     612             :                         }
     613           0 :                         deviceScoreStart += strlen(DS_TAG_SCORE);
     614           0 :                         deviceScoreEnd = findString(deviceScoreStart, contentEnd, DS_TAG_SCORE_END);
     615           0 :                         status = deserializer(profile->devices + i, reinterpret_cast<const unsigned char*>(deviceScoreStart), deviceScoreEnd - deviceScoreStart);
     616           0 :                         if (status != DS_SUCCESS)
     617             :                         {
     618           0 :                             goto cleanup;
     619             :                         }
     620             :                     }
     621             :                 }
     622             :             }
     623             : 
     624             :             // skip over the current one to find the next device
     625           0 :             currentPosition = dataEnd + strlen(DS_TAG_DEVICE_END);
     626           0 :         }
     627             :     }
     628             : cleanup:
     629           0 :     if (contentStart != NULL) free(contentStart);
     630           0 :     if (status != DS_SUCCESS)
     631           0 :         return status;
     632             : 
     633             :     // Check that all the devices present had valid cached scores. If
     634             :     // not, return DS_INVALID_PROFILE and let the caller re-evaluate
     635             :     // scores for present devices, and write a new profile file.
     636           0 :     for (unsigned int i = 0; i < profile->numDevices; i++)
     637           0 :         if (profile->devices[i].score == NULL)
     638           0 :             return DS_INVALID_PROFILE;
     639             : 
     640           0 :     return DS_SUCCESS;
     641             : }
     642             : 
     643             : inline ds_status getNumDeviceWithEmptyScore(ds_profile* profile, unsigned int* num)
     644             : {
     645             :     unsigned int i;
     646             :     if (profile == NULL || num == NULL) return DS_MEMORY_ERROR;
     647             :     *num = 0;
     648             :     for (i = 0; i < profile->numDevices; i++)
     649             :     {
     650             :         if (profile->devices[i].score == NULL)
     651             :         {
     652             :             (*num)++;
     653             :         }
     654             :     }
     655             :     return DS_SUCCESS;
     656             : }
     657             : 
     658             : #endif
     659             : 
     660             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11