#include <CL/cl.h> #include <stdio.h> #include <stdlib.h> #include <math.h> // OpenCL kernel to check if a number is prime const char* kernelSource = "__kernel void is_prime(__global const unsigned long* num, __global int* result) { \n" " unsigned long n = *num; \n" " int is_prime = 1; \n" " for (unsigned long i = 2; i <= sqrt((float)n); i++) { \n" " if (n % i == 0) { \n" " is_prime = 0; \n" " break; \n" " } \n" " } \n" " *result = is_prime; \n" "} \n"; int main() { // Number to test (example: 31, which is 2^5 - 1) unsigned long p = 5; unsigned long M_p = (1UL << p) - 1; // Initialize OpenCL cl_platform_id platform_id = NULL; cl_device_id device_id = NULL; cl_context context = NULL; cl_command_queue command_queue = NULL; cl_mem num_mem = NULL; cl_mem result_mem = NULL; cl_program program = NULL; cl_kernel kernel = NULL; cl_int ret; // Get platform and device information ret = clGetPlatformIDs(1, &platform_id, NULL); ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, NULL); // Create an OpenCL context context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret); // Create a command queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret); // Create memory buffers on the device for the number and result num_mem = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(unsigned long), NULL, &ret); result_mem = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(int), NULL, &ret); // Copy the number to the memory buffer ret = clEnqueueWriteBuffer(command_queue, num_mem, CL_TRUE, 0, sizeof(unsigned long), &M_p, 0, NULL, NULL); // Create a program from the kernel source program = clCreateProgramWithSource(context, 1, (const char**)&kernelSource, NULL, &ret); // Build the program ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); // Create the OpenCL kernel kernel = clCreateKernel(program, "is_prime", &ret); // Set the arguments of the kernel ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&num_mem); ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void*)&result_mem); // Execute the OpenCL kernel size_t global_item_size = 1; size_t local_item_size = 1; ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL); // Read the result from the device int result; ret = clEnqueueReadBuffer(command_queue, result_mem, CL_TRUE, 0, sizeof(int), &result, 0, NULL, NULL); // Display the result if (result) { printf("%lu is a Mersenne prime.\n", M_p); } else { printf("%lu is not a Mersenne prime.\n", M_p); } // Clean up ret = clFlush(command_queue); ret = clFinish(command_queue); ret = clReleaseKernel(kernel); ret = clReleaseProgram(program); ret = clReleaseMemObject(num_mem); ret = clReleaseMemObject(result_mem); ret = clReleaseCommandQueue(command_queue); ret = clReleaseContext(context); return 0; }