main.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <CL/cl.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #define CHECK_ERROR(err, msg) \
  6. if (err != CL_SUCCESS) { \
  7. fprintf(stderr, "āŒ %s failed (%d)\n", msg, err); \
  8. exit(EXIT_FAILURE); \
  9. }
  10. void print_platform_info(cl_platform_id platform) {
  11. char buffer[1024];
  12. printf("\nšŸŒ Platform Info:\n");
  13. clGetPlatformInfo(platform, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL);
  14. printf("šŸ·ļø Name: %s\n", buffer);
  15. clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, sizeof(buffer), buffer, NULL);
  16. printf("šŸ¢ Vendor: %s\n", buffer);
  17. clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof(buffer), buffer, NULL);
  18. printf("šŸ’æ Version: %s\n", buffer);
  19. clGetPlatformInfo(platform, CL_PLATFORM_PROFILE, sizeof(buffer), buffer, NULL);
  20. printf("🧩 Profile: %s\n", buffer);
  21. printf("\n");
  22. }
  23. void print_device_info(cl_device_id device) {
  24. char name[256], vendor[256], version[256];
  25. cl_uint compute_units;
  26. cl_ulong global_mem;
  27. cl_ulong local_mem;
  28. size_t max_wg;
  29. clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(name), name, NULL);
  30. clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(vendor), vendor, NULL);
  31. clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(version), version, NULL);
  32. clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);
  33. clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(global_mem), &global_mem, NULL);
  34. clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(local_mem), &local_mem, NULL);
  35. clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_wg), &max_wg, NULL);
  36. printf("šŸ”¹ Device: %s\n", name);
  37. printf(" Vendor: %s\n", vendor);
  38. printf(" Version: %s\n", version);
  39. printf(" Compute Units: %u\n", compute_units);
  40. printf(" Global Memory: %.2f MB\n", global_mem / (1024.0 * 1024.0));
  41. printf(" Local Memory: %.2f KB\n", local_mem / 1024.0);
  42. printf(" Max Work Group Size: %zu\n\n", max_wg);
  43. }
  44. int main(void) {
  45. cl_int err;
  46. printf("šŸš€ Starting OpenCL diagnostic + compute test\n");
  47. // 1. Get all platforms
  48. cl_uint num_platforms = 0;
  49. err = clGetPlatformIDs(0, NULL, &num_platforms);
  50. CHECK_ERROR(err, "clGetPlatformIDs(count)");
  51. cl_platform_id *platforms = malloc(sizeof(cl_platform_id) * num_platforms);
  52. err = clGetPlatformIDs(num_platforms, platforms, NULL);
  53. CHECK_ERROR(err, "clGetPlatformIDs(list)");
  54. printf("šŸŒ Found %u OpenCL platform(s)\n", num_platforms);
  55. // 2. List platforms and pick POCL if available
  56. cl_platform_id chosen_platform = NULL;
  57. char pname[256];
  58. for (cl_uint i = 0; i < num_platforms; i++) {
  59. print_platform_info(platforms[i]);
  60. clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
  61. if (strstr(pname, "Portable") || strstr(pname, "pocl") || strstr(pname, "POCL")) {
  62. chosen_platform = platforms[i];
  63. }
  64. }
  65. if (!chosen_platform) {
  66. printf("āš ļø No POCL platform found, using first available.\n");
  67. chosen_platform = platforms[0];
  68. }
  69. clGetPlatformInfo(chosen_platform, CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
  70. printf("āœ… Selected platform: %s\n", pname);
  71. // 3. Get devices
  72. cl_uint num_devices = 0;
  73. err = clGetDeviceIDs(chosen_platform, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
  74. CHECK_ERROR(err, "clGetDeviceIDs(count)");
  75. cl_device_id *devices = malloc(sizeof(cl_device_id) * num_devices);
  76. err = clGetDeviceIDs(chosen_platform, CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
  77. CHECK_ERROR(err, "clGetDeviceIDs(list)");
  78. printf("🧩 Found %u device(s)\n\n", num_devices);
  79. for (cl_uint i = 0; i < num_devices; i++) {
  80. print_device_info(devices[i]);
  81. }
  82. cl_device_id device = devices[0];
  83. // 4. Create context and queue
  84. cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
  85. CHECK_ERROR(err, "clCreateContext");
  86. cl_command_queue queue = clCreateCommandQueue(context, device, 0, &err);
  87. CHECK_ERROR(err, "clCreateCommandQueue");
  88. // 5. Example kernel
  89. const char *source =
  90. "__kernel void vector_add(__global const float* a, __global const float* b, __global float* c) {"
  91. " int id = get_global_id(0);"
  92. " c[id] = a[id] + b[id];"
  93. "}";
  94. cl_program program = clCreateProgramWithSource(context, 1, &source, NULL, &err);
  95. CHECK_ERROR(err, "clCreateProgramWithSource");
  96. err = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
  97. if (err != CL_SUCCESS) {
  98. size_t log_size;
  99. clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
  100. char *log = malloc(log_size);
  101. clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
  102. fprintf(stderr, "āŒ Build log:\n%s\n", log);
  103. free(log);
  104. CHECK_ERROR(err, "clBuildProgram");
  105. }
  106. printf("āœ… Program built successfully.\n");
  107. cl_kernel kernel = clCreateKernel(program, "vector_add", &err);
  108. CHECK_ERROR(err, "clCreateKernel");
  109. // 6. Prepare data
  110. const int N = 10;
  111. float A[N], B[N], C[N];
  112. for (int i = 0; i < N; i++) {
  113. A[i] = (float)i;
  114. B[i] = (float)(N - i);
  115. }
  116. cl_mem bufA = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(A), A, &err);
  117. CHECK_ERROR(err, "clCreateBuffer(A)");
  118. cl_mem bufB = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(B), B, &err);
  119. CHECK_ERROR(err, "clCreateBuffer(B)");
  120. cl_mem bufC = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(C), NULL, &err);
  121. CHECK_ERROR(err, "clCreateBuffer(C)");
  122. // 7. Set kernel args
  123. err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &bufA);
  124. err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &bufB);
  125. err |= clSetKernelArg(kernel, 2, sizeof(cl_mem), &bufC);
  126. CHECK_ERROR(err, "clSetKernelArg");
  127. // 8. Run kernel
  128. size_t global = N;
  129. err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, NULL, 0, NULL, NULL);
  130. CHECK_ERROR(err, "clEnqueueNDRangeKernel");
  131. clFinish(queue);
  132. // 9. Read results
  133. err = clEnqueueReadBuffer(queue, bufC, CL_TRUE, 0, sizeof(C), C, 0, NULL, NULL);
  134. CHECK_ERROR(err, "clEnqueueReadBuffer");
  135. printf("\nāœ… Kernel executed successfully. Results:\n");
  136. for (int i = 0; i < N; i++) {
  137. printf(" %.2f + %.2f = %.2f\n", A[i], B[i], C[i]);
  138. }
  139. // 10. Cleanup
  140. clReleaseMemObject(bufA);
  141. clReleaseMemObject(bufB);
  142. clReleaseMemObject(bufC);
  143. clReleaseKernel(kernel);
  144. clReleaseProgram(program);
  145. clReleaseCommandQueue(queue);
  146. clReleaseContext(context);
  147. free(platforms);
  148. free(devices);
  149. printf("\nšŸŽ‰ All done!\n");
  150. return 0;
  151. }