ocl.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include <signal.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netdb.h>
  9. #include <time.h>
  10. #include <sys/time.h>
  11. #include <pthread.h>
  12. #include "findnonce.h"
  13. #include "ocl.h"
  14. char *file_contents(const char *filename, int *length)
  15. {
  16. FILE *f = fopen(filename, "r");
  17. void *buffer;
  18. if (!f) {
  19. fprintf(stderr, "Unable to open %s for reading\n", filename);
  20. return NULL;
  21. }
  22. fseek(f, 0, SEEK_END);
  23. *length = ftell(f);
  24. fseek(f, 0, SEEK_SET);
  25. buffer = malloc(*length+1);
  26. *length = fread(buffer, 1, *length, f);
  27. fclose(f);
  28. ((char*)buffer)[*length] = '\0';
  29. return (char*)buffer;
  30. }
  31. int clDevicesNum() {
  32. cl_int status = 0;
  33. cl_uint numPlatforms;
  34. cl_platform_id platform = NULL;
  35. status = clGetPlatformIDs(0, NULL, &numPlatforms);
  36. if(status != CL_SUCCESS)
  37. {
  38. printf("Error: Getting Platforms. (clGetPlatformsIDs)\n");
  39. return -1;
  40. }
  41. if(numPlatforms > 0)
  42. {
  43. cl_platform_id* platforms = (cl_platform_id *)malloc(numPlatforms*sizeof(cl_platform_id));
  44. status = clGetPlatformIDs(numPlatforms, platforms, NULL);
  45. if(status != CL_SUCCESS)
  46. {
  47. printf("Error: Getting Platform Ids. (clGetPlatformsIDs)\n");
  48. return -1;
  49. }
  50. unsigned int i;
  51. for(i=0; i < numPlatforms; ++i)
  52. {
  53. char pbuff[100];
  54. status = clGetPlatformInfo( platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);
  55. if(status != CL_SUCCESS)
  56. {
  57. printf("Error: Getting Platform Info. (clGetPlatformInfo)\n");
  58. free(platforms);
  59. return -1;
  60. }
  61. platform = platforms[i];
  62. if(!strcmp(pbuff, "Advanced Micro Devices, Inc."))
  63. {
  64. break;
  65. }
  66. }
  67. free(platforms);
  68. }
  69. if(platform == NULL) {
  70. perror("NULL platform found!\n");
  71. return -1;
  72. }
  73. cl_uint numDevices;
  74. status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
  75. if(status != CL_SUCCESS)
  76. {
  77. printf("Error: Getting Device IDs (num)\n");
  78. return -1;
  79. }
  80. return numDevices;
  81. }
  82. _clState *initCl(int gpu, char *name, size_t nameSize) {
  83. cl_int status = 0;
  84. _clState *clState = malloc(sizeof(_clState));;
  85. cl_uint numPlatforms;
  86. cl_platform_id platform = NULL;
  87. status = clGetPlatformIDs(0, NULL, &numPlatforms);
  88. if(status != CL_SUCCESS)
  89. {
  90. printf("Error: Getting Platforms. (clGetPlatformsIDs)\n");
  91. return NULL;
  92. }
  93. if(numPlatforms > 0)
  94. {
  95. cl_platform_id* platforms = (cl_platform_id *)malloc(numPlatforms*sizeof(cl_platform_id));
  96. status = clGetPlatformIDs(numPlatforms, platforms, NULL);
  97. if(status != CL_SUCCESS)
  98. {
  99. printf("Error: Getting Platform Ids. (clGetPlatformsIDs)\n");
  100. return NULL;
  101. }
  102. unsigned int i;
  103. for(i=0; i < numPlatforms; ++i)
  104. {
  105. char pbuff[100];
  106. status = clGetPlatformInfo( platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);
  107. if(status != CL_SUCCESS)
  108. {
  109. printf("Error: Getting Platform Info. (clGetPlatformInfo)\n");
  110. free(platforms);
  111. return NULL;
  112. }
  113. platform = platforms[i];
  114. if(!strcmp(pbuff, "Advanced Micro Devices, Inc."))
  115. {
  116. break;
  117. }
  118. }
  119. free(platforms);
  120. }
  121. if(platform == NULL) {
  122. perror("NULL platform found!\n");
  123. return NULL;
  124. }
  125. cl_uint numDevices;
  126. status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
  127. if(status != CL_SUCCESS)
  128. {
  129. printf("Error: Getting Device IDs (num)\n");
  130. return NULL;
  131. }
  132. cl_device_id *devices;
  133. if(numDevices > 0 ) {
  134. devices = (cl_device_id *)malloc(numDevices*sizeof(cl_device_id));
  135. /* Now, get the device list data */
  136. status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
  137. if(status != CL_SUCCESS)
  138. {
  139. printf("Error: Getting Device IDs (list)\n");
  140. return NULL;
  141. }
  142. printf("List of devices:\n");
  143. int i;
  144. for(i=0; i<numDevices; i++) {
  145. char pbuff[100];
  146. status = clGetDeviceInfo(devices[i], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL);
  147. if(status != CL_SUCCESS)
  148. {
  149. printf("Error: Getting Device Info\n");
  150. return NULL;
  151. }
  152. printf("\t%i\t%s\n", i, pbuff);
  153. }
  154. if (gpu >= 0 && gpu < numDevices) {
  155. char pbuff[100];
  156. status = clGetDeviceInfo(devices[gpu], CL_DEVICE_NAME, sizeof(pbuff), pbuff, NULL);
  157. if(status != CL_SUCCESS)
  158. {
  159. printf("Error: Getting Device Info\n");
  160. return NULL;
  161. }
  162. printf("Selected %i: %s\n", gpu, pbuff);
  163. strncpy(name, pbuff, nameSize);
  164. } else {
  165. printf("Invalid GPU %i\n", gpu);
  166. return NULL;
  167. }
  168. } else return NULL;
  169. cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 };
  170. clState->context = clCreateContextFromType(cps, CL_DEVICE_TYPE_GPU, NULL, NULL, &status);
  171. if(status != CL_SUCCESS)
  172. {
  173. printf("Error: Creating Context. (clCreateContextFromType)\n");
  174. return NULL;
  175. }
  176. /////////////////////////////////////////////////////////////////
  177. // Load CL file, build CL program object, create CL kernel object
  178. /////////////////////////////////////////////////////////////////
  179. //
  180. const char * filename = "oclminer.cl";
  181. int pl;
  182. char *source = file_contents(filename, &pl);
  183. size_t sourceSize[] = {(size_t)pl};
  184. clState->program = clCreateProgramWithSource(clState->context, 1, (const char **)&source, sourceSize, &status);
  185. if(status != CL_SUCCESS)
  186. {
  187. printf("Error: Loading Binary into cl_program (clCreateProgramWithBinary)\n");
  188. return NULL;
  189. }
  190. /* create a cl program executable for all the devices specified */
  191. status = clBuildProgram(clState->program, 1, &devices[gpu], NULL, NULL, NULL);
  192. if(status != CL_SUCCESS)
  193. {
  194. printf("Error: Building Program (clBuildProgram)\n");
  195. size_t logSize;
  196. status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);
  197. char *log = malloc(logSize);
  198. status = clGetProgramBuildInfo(clState->program, devices[gpu], CL_PROGRAM_BUILD_LOG, logSize, log, NULL);
  199. printf("%s\n", log);
  200. return NULL;
  201. }
  202. /* get a kernel object handle for a kernel with the given name */
  203. clState->kernel = clCreateKernel(clState->program, "oclminer", &status);
  204. if(status != CL_SUCCESS)
  205. {
  206. printf("Error: Creating Kernel from program. (clCreateKernel)\n");
  207. return NULL;
  208. }
  209. /////////////////////////////////////////////////////////////////
  210. // Create an OpenCL command queue
  211. /////////////////////////////////////////////////////////////////
  212. clState->commandQueue = clCreateCommandQueue( clState->context, devices[gpu], 0, &status);
  213. if(status != CL_SUCCESS)
  214. {
  215. printf("Creating Command Queue. (clCreateCommandQueue)\n");
  216. return NULL;
  217. }
  218. clState->inputBuffer = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, sizeof(dev_blk_ctx), NULL, &status);
  219. if(status != CL_SUCCESS) {
  220. printf("Error: clCreateBuffer (inputBuffer)\n");
  221. return NULL;
  222. }
  223. clState->outputBuffer = clCreateBuffer(clState->context, CL_MEM_READ_WRITE, sizeof(uint32_t) * MAXTHREADS, NULL, &status);
  224. if(status != CL_SUCCESS) {
  225. printf("Error: clCreateBuffer (outputBuffer)\n");
  226. return NULL;
  227. }
  228. return clState;
  229. }