4.1.5.2.2 : Le fichier asterics_cuda.cpp
Développons le fichier asterics_cuda.cpp :
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 |
#include <stdlib.h> #include <cuda.h> #include <cuda_runtime.h> #include <sstream> #include <iomanip> #include <iostream> #include "asterics_cuda.h" ///Get the number of cuda device /** @return number of Cuda device */ int asterics_getNbCudaDevice(){ int deviceCount = 0; cudaError_t error_id = cudaGetDeviceCount(&deviceCount); if(error_id != cudaSuccess){ printf("asterics_getNbCudaDevice : cudaGetDeviceCount returned %d\n-> %s\n", (int)error_id, cudaGetErrorString(error_id)); printf("asterics_getNbCudaDevice : deviceCount = %d\n", deviceCount); printf("asterics_getNbCudaDevice : Result = FAIL\n"); exit(EXIT_FAILURE); } // This function call returns 0 if there are no CUDA capable devices. if(deviceCount == 0){ printf("asterics_getNbCudaDevice : There are no available device(s) that support CUDA\n"); }else{ printf("asterics_getNbCudaDevice : Detected %d CUDA Capable device(s)\n", deviceCount); } return deviceCount; } ///Get some usefull GPU info /** @param[out] maxNbThreadPerBlockX : maximum number of thread per block on X * @param[out] maxNbBlockX : maximum number of block in the grid on X * @param[out] warpSize : number of thread per warp * @param deviceIndex : index of the device to be used */ void asterics_getGpuInfo(int & maxNbThreadPerBlockX, int & maxNbBlockX, int & warpSize, int deviceIndex){ cudaSetDevice(deviceIndex); cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, deviceIndex); maxNbThreadPerBlockX = deviceProp.maxThreadsDim[0]; maxNbBlockX = deviceProp.maxGridSize[0]; warpSize = deviceProp.warpSize; } ///Get some usefull GPU info /** @param[out] maxNbThreadPerBlockX : maximum number of thread per block on X * @param[out] maxNbBlockX : maximum number of block in the grid on X * @param[out] memSize : number of bytes in the GPU memory * @param deviceIndex : index of the device to be used */ void asterics_getGpuInfoMem(size_t & maxNbThreadPerBlockX, size_t & maxNbBlockX, size_t & memSize, int deviceIndex){ cudaSetDevice(deviceIndex); cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, deviceIndex); maxNbThreadPerBlockX = deviceProp.maxThreadsDim[0]; maxNbBlockX = deviceProp.maxGridSize[0]; memSize = deviceProp.totalGlobalMem; } ///Get the UUID of the given Cuda Device /** @param deviceProp : Cuda Device to be used * @return corresponding UUID */ std::string asterics_getUuid(const cudaDeviceProp & deviceProp){ const unsigned char * tabByte = (const unsigned char *)deviceProp.uuid.bytes; std::stringstream out; for(int i(0); i < 16; ++i){ // printf("%02x,", (unsigned int)(tabByte[i])); out << std::hex << std::setfill('0') << std::setw(2) << (unsigned int)tabByte[i]; } return out.str(); } ///Check if two string start the same way /** @param str : string to be tested @param beginig : begining to be checked @return true if str starts as beginig */ bool asterics_isSameBegining(const std::string & str, const std::string & beginig){ if(str.size() < beginig.size()) return false; std::string::const_iterator it = str.begin(); std::string::const_iterator it2 = beginig.begin(); while(it != str.end() && it2 != beginig.end()){ if(*it != *it2){ return false;} it++; it2++; } return true; } ///copie la string str en effaçant le caractère ch /** @param str : chaîne à copier @param ch : caractère à effacer @return string sans le caractère ch */ std::string asterics_eraseCharInStr(const std::string& str, char ch){ std::string buffer = ""; for(std::string::const_iterator it = str.begin(); it != str.end(); it++){ if(*it != ch) buffer += *it; } return buffer; } ///copie la string str en effaçant les caractères rmchs /** @param str : chaîne à copier @param rmchs : caractères à effacer @return string sans les caractères rmchs */ std::string asterics_eraseCharsInStr(const std::string& str, const std::string & rmchs){ std::string buffer = str; for(std::string::const_iterator it = rmchs.begin(); it != rmchs.end(); it++){ buffer = asterics_eraseCharInStr(buffer, *it); } return buffer; } ///Set the cuda device /** @param uuidSelectedDevice : uuid of the device to be used (or the begining) * @return id of the choosen device */ int asterics_setDevice(const std::string & uuidSelectedDevice){ std::string onlyUuid(asterics_eraseCharsInStr(uuidSelectedDevice, "GPUMIG-")); int deviceCount = asterics_getNbCudaDevice(); for(int dev = 0; dev < deviceCount; ++dev){ cudaSetDevice(dev); cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, dev); std::string uuid(asterics_getUuid(deviceProp)); if(asterics_isSameBegining(uuid, onlyUuid)){ std::cout << "asterics_setDevice : set device " << dev << " with UUID = " << uuid << std::endl; cudaSetDevice(dev); return dev; } } return 0; } |
Le fichier asterics_cuda.cpp complet.
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 |
/*************************************** Auteur : Pierre Aubert Mail : pierre.aubert@lapp.in2p3.fr Licence : CeCILL-C ****************************************/ #include <stdlib.h> #include <cuda.h> #include <cuda_runtime.h> #include <sstream> #include <iomanip> #include <iostream> #include "asterics_cuda.h" ///Get the number of cuda device /** @return number of Cuda device */ int asterics_getNbCudaDevice(){ int deviceCount = 0; cudaError_t error_id = cudaGetDeviceCount(&deviceCount); if(error_id != cudaSuccess){ printf("asterics_getNbCudaDevice : cudaGetDeviceCount returned %d\n-> %s\n", (int)error_id, cudaGetErrorString(error_id)); printf("asterics_getNbCudaDevice : deviceCount = %d\n", deviceCount); printf("asterics_getNbCudaDevice : Result = FAIL\n"); exit(EXIT_FAILURE); } // This function call returns 0 if there are no CUDA capable devices. if(deviceCount == 0){ printf("asterics_getNbCudaDevice : There are no available device(s) that support CUDA\n"); }else{ printf("asterics_getNbCudaDevice : Detected %d CUDA Capable device(s)\n", deviceCount); } return deviceCount; } ///Get some usefull GPU info /** @param[out] maxNbThreadPerBlockX : maximum number of thread per block on X * @param[out] maxNbBlockX : maximum number of block in the grid on X * @param[out] warpSize : number of thread per warp * @param deviceIndex : index of the device to be used */ void asterics_getGpuInfo(int & maxNbThreadPerBlockX, int & maxNbBlockX, int & warpSize, int deviceIndex){ cudaSetDevice(deviceIndex); cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, deviceIndex); maxNbThreadPerBlockX = deviceProp.maxThreadsDim[0]; maxNbBlockX = deviceProp.maxGridSize[0]; warpSize = deviceProp.warpSize; } ///Get some usefull GPU info /** @param[out] maxNbThreadPerBlockX : maximum number of thread per block on X * @param[out] maxNbBlockX : maximum number of block in the grid on X * @param[out] memSize : number of bytes in the GPU memory * @param deviceIndex : index of the device to be used */ void asterics_getGpuInfoMem(size_t & maxNbThreadPerBlockX, size_t & maxNbBlockX, size_t & memSize, int deviceIndex){ cudaSetDevice(deviceIndex); cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, deviceIndex); maxNbThreadPerBlockX = deviceProp.maxThreadsDim[0]; maxNbBlockX = deviceProp.maxGridSize[0]; memSize = deviceProp.totalGlobalMem; } ///Get the UUID of the given Cuda Device /** @param deviceProp : Cuda Device to be used * @return corresponding UUID */ std::string asterics_getUuid(const cudaDeviceProp & deviceProp){ const unsigned char * tabByte = (const unsigned char *)deviceProp.uuid.bytes; std::stringstream out; for(int i(0); i < 16; ++i){ // printf("%02x,", (unsigned int)(tabByte[i])); out << std::hex << std::setfill('0') << std::setw(2) << (unsigned int)tabByte[i]; } return out.str(); } ///Check if two string start the same way /** @param str : string to be tested @param beginig : begining to be checked @return true if str starts as beginig */ bool asterics_isSameBegining(const std::string & str, const std::string & beginig){ if(str.size() < beginig.size()) return false; std::string::const_iterator it = str.begin(); std::string::const_iterator it2 = beginig.begin(); while(it != str.end() && it2 != beginig.end()){ if(*it != *it2){ return false;} it++; it2++; } return true; } ///copie la string str en effaçant le caractère ch /** @param str : chaîne à copier @param ch : caractère à effacer @return string sans le caractère ch */ std::string asterics_eraseCharInStr(const std::string& str, char ch){ std::string buffer = ""; for(std::string::const_iterator it = str.begin(); it != str.end(); it++){ if(*it != ch) buffer += *it; } return buffer; } ///copie la string str en effaçant les caractères rmchs /** @param str : chaîne à copier @param rmchs : caractères à effacer @return string sans les caractères rmchs */ std::string asterics_eraseCharsInStr(const std::string& str, const std::string & rmchs){ std::string buffer = str; for(std::string::const_iterator it = rmchs.begin(); it != rmchs.end(); it++){ buffer = asterics_eraseCharInStr(buffer, *it); } return buffer; } ///Set the cuda device /** @param uuidSelectedDevice : uuid of the device to be used (or the begining) * @return id of the choosen device */ int asterics_setDevice(const std::string & uuidSelectedDevice){ std::string onlyUuid(asterics_eraseCharsInStr(uuidSelectedDevice, "GPUMIG-")); int deviceCount = asterics_getNbCudaDevice(); for(int dev = 0; dev < deviceCount; ++dev){ cudaSetDevice(dev); cudaDeviceProp deviceProp; cudaGetDeviceProperties(&deviceProp, dev); std::string uuid(asterics_getUuid(deviceProp)); if(asterics_isSameBegining(uuid, onlyUuid)){ std::cout << "asterics_setDevice : set device " << dev << " with UUID = " << uuid << std::endl; cudaSetDevice(dev); return dev; } } return 0; } |
Vous pouvez télécharger le fichier ici.