Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Create program from a file and compile it */
- cl_program build_program(cl_context ctx, cl_device_id dev, const char *filename, const char *options) {
- cl_program program;
- FILE *program_handle;
- char *program_buffer, *program_log;
- size_t program_size, log_size;
- int err;
- /* Read program file and place content into buffer */
- program_handle = fopen(filename, "r");
- if (program_handle == NULL) {
- perror("Couldn't find the program file");
- client_cleanup(EXIT_FAILURE);
- }
- fseek(program_handle, 0, SEEK_END);
- program_size = ftell(program_handle);
- rewind(program_handle);
- program_buffer = (char *) malloc(program_size + 1);
- program_buffer[program_size] = '\0';
- fread(program_buffer, sizeof(char), program_size, program_handle);
- fclose(program_handle);
- /* Create program from file */
- program = clCreateProgramWithSource(ctx, 1,
- (const char **) &program_buffer, &program_size, &err);
- if (err < 0) {
- perror("Couldn't create the program");
- client_cleanup(EXIT_FAILURE);
- }
- free(program_buffer);
- /* Build program */
- err = clBuildProgram(program, 0, NULL, options, NULL, NULL);
- if (err < 0) {
- /* Find size of log and print to std output */
- clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG,
- 0, NULL, &log_size);
- program_log = (char *) malloc(log_size + 1);
- program_log[log_size] = '\0';
- clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG,
- log_size + 1, program_log, NULL);
- printf("%s\n", program_log);
- free(program_log);
- client_cleanup(EXIT_FAILURE);
- }
- return(program);
- }
- int str2ull(char *str, uint64_t *val)
- {
- char *end;
- uint64_t ret;
- if (!str)
- return(-1);
- int i = 0;
- while (isspace(str[i]))
- i++;
- if (str[i] == '-') { // BUG: -0001
- i++;
- if (!str[i] || str[i] != '0')
- return(-4);
- }
- errno = 0;
- ret = strtoull(str, &end, 10);
- if (*end)
- return(-2);
- if (ret == ULLONG_MAX && errno == ERANGE)
- return(-3);
- *val = ret;
- return(0);
- }
- size_t get_chunks(uint64_t begin, uint64_t end, size_t size)
- {
- size_t n;
- n = (end - begin +1) / size;
- if ((end - begin +1) % size > 0)
- n++;
- return(n);
- }
- int fill_array(cl_ulong2 *dst, chunk_t chunk, unsigned int packets)
- {
- unsigned int i;
- uint64_t packet_size;
- uint64_t last_packet;
- /*
- test input number range to be divisible by the packet count
- */
- if ((chunk.last - chunk.first +1) % packets == 0) {
- packet_size = (chunk.last - chunk.first +1) / packets;
- last_packet = packet_size;
- }
- else {
- packet_size = (chunk.last - chunk.first +1) / (packets -1);
- last_packet = (chunk.last - chunk.first +1) % (packets -1);
- }
- debug("packet_size: %llu\n", packet_size);
- debug("last_packet: %llu\n", last_packet);
- /*
- input range too small
- fill up the buffer with dummy data
- */
- if (packet_size == 0) {
- debug("packet_size = 0\n");
- debug("filling up %u packets with dummy data\n", packets -1);
- for (i = 0; i < packets -1; i++) {
- dst[i].s0 = 42;
- dst[i].s1 = 42;
- }
- }
- else {
- /* Initialize data */
- for (i = 0; i < packets -1; i++) {
- dst[i].s0 = chunk.first + i * packet_size;
- dst[i].s1 = chunk.first + i * packet_size + packet_size -1;
- }
- }
- /*
- assign last element in array
- */
- if (last_packet == 0) {
- debug("last_packet = 0\n");
- dst[i].s0 = 42;
- dst[i].s1 = 42;
- }
- else {
- dst[i].s0 = chunk.first + i * packet_size;
- dst[i].s1 = chunk.last;
- }
- debug("last_packet_begin: %llu\n", dst[i].s0);
- debug("last_packet_end: %llu\n", dst[i].s1);
- return(0);
- }
- void sleeptime(time_t sec, long int nsec)
- {
- struct timespec t;
- t.tv_sec = sec;
- t.tv_nsec = nsec;
- while (nanosleep(&t, &t) == -1 && errno == EINTR)
- ;
- }
- int main(int argc, char *argv[])
- {
- /* OpenCL structures */
- cl_device_id device;
- cl_context context;
- cl_program program;
- cl_kernel kernel;
- cl_command_queue queue;
- cl_int err;
- size_t local_size, global_size;
- unsigned int i;
- uint64_t begin;
- if (str2ull(strtok(argv[2], ";"), &begin) < 0) {
- printerr("begin invalid");
- client_cleanup(EXIT_FAILURE);
- }
- uint64_t end;
- if (str2ull(strtok(NULL, ";"), &end) < 0) {
- printerr("end invalid");
- client_cleanup(EXIT_FAILURE);
- }
- if (begin > end) {
- printerr("begin > end");
- client_cleanup(EXIT_FAILURE);
- }
- debug("begin: %llu\n", begin);
- debug("end: %llu\n", end);
- /* Data and buffers */
- cl_ulong2 input_data[PACKET_COUNT];
- cl_int output_data[PACKET_COUNT];
- cl_mem input_buffer, output_buffer;
- /* Get a Device */
- if (ocldevid(argv[1], &device)) {
- printerr("ocldevid() failed");
- client_cleanup(EXIT_FAILURE);
- }
- /* Create a context */
- context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
- if (err < 0) {
- perror("Couldn't create a context");
- client_cleanup(EXIT_FAILURE);
- }
- /* Build program */
- program = build_program(context, device, PROGRAM_FILE, "");
- /* Create a kernel */
- kernel = clCreateKernel(program, KERNEL_FUNC, &err);
- if (err < 0) {
- perror("Couldn't create a kernel");
- client_cleanup(EXIT_FAILURE);
- }
- /* Create a command queue */
- queue = clCreateCommandQueue(context, device, 0, &err);
- if (err < 0) {
- perror("Couldn't create a command queue");
- client_cleanup(EXIT_FAILURE);
- }
- input_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY,
- PACKET_COUNT * sizeof(cl_ulong2), NULL, &err);
- output_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY,
- PACKET_COUNT * sizeof(cl_int), NULL, &err);
- if (err < 0) {
- perror("Couldn't create a buffer");
- client_cleanup(EXIT_FAILURE);
- }
- local_size = GROUP_SIZE;
- global_size = PACKET_COUNT;
- debug("local_size: %zu\n", local_size);
- debug("global_size: %zu\n", global_size);
- chunk_t current_chunk = { .id = 0, };
- size_t chunk_count;
- chunk_count = get_chunks(begin, end, CHUNK_SIZE);
- debug("chunk_count: %zu\n", chunk_count);
- debug("NUM_PER_THREAD: %lu\n", NUM_PER_THREAD);
- debug("CHUNK_SIZE: %zu\n", CHUNK_SIZE);
- while (current_chunk.id != chunk_count) {
- /* Initialise output array */
- memset(output_data, -1, sizeof(output_data));
- debug("current_chunk: %zu\n", current_chunk.id);
- current_chunk.first = begin + current_chunk.id * CHUNK_SIZE;
- debug("current_chunk.first: %zu\n", current_chunk.first);
- /* Check for last chunk */
- if (current_chunk.id == chunk_count -1)
- current_chunk.last = current_chunk.first + (end - begin) % CHUNK_SIZE;
- else
- current_chunk.last = current_chunk.first + CHUNK_SIZE -1;
- debug("current_chunk.last: %zu\n", current_chunk.last);
- /* Fill input array with data*/
- if (fill_array(input_data, current_chunk, PACKET_COUNT) < 0) {
- printerr("fill_array() failed");
- client_cleanup(EXIT_FAILURE);
- }
- /* Copy input data to device */
- err = clEnqueueWriteBuffer(queue, input_buffer, CL_TRUE, 0,
- sizeof(input_data), input_data, 0, NULL, NULL);
- if (err < 0) {
- perror("Couldn't write the buffer");
- client_cleanup(EXIT_FAILURE);
- }
- /* Create kernel arguments */
- err = clSetKernelArg(kernel, 0, sizeof(input_buffer), &input_buffer);
- err |= clSetKernelArg(kernel, 1, sizeof(output_buffer), &output_buffer);
- if (err < 0) {
- perror("Couldn't create a kernel argument");
- client_cleanup(EXIT_FAILURE);
- }
- debug("enqueueing kernel\n");
- /* Enqueue kernel */
- err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_size,
- &local_size, 0, NULL, NULL);
- if (err < 0) {
- perror("Couldn't enqueue the kernel");
- client_cleanup(EXIT_FAILURE);
- }
- /* Read the kernel's output */
- err = clEnqueueReadBuffer(queue, output_buffer, CL_TRUE, 0,
- sizeof(output_data), output_data, 0, NULL, NULL);
- if (err < 0) {
- perror("Couldn't read the buffer");
- client_cleanup(EXIT_FAILURE);
- }
- /* Print packets */
- for (i = 0; i < PACKET_COUNT; i++) {
- switch (output_data[i]) {
- case -1:
- /* search failed */
- debug("[%llu,%llu]: failure\n", input_data[i].s0, input_data[i].s1);
- break;
- case 0:
- /* no solution found */
- break;
- case 1:
- /* solution found */
- debug("[%llu,%llu]: success\n", input_data[i].s0, input_data[i].s1);
- break;
- }
- }
- sleeptime(WAIT_SEC, WAIT_NSEC);
- current_chunk.id++;
- }
- /* Deallocate resources */
- clReleaseMemObject(output_buffer);
- clReleaseMemObject(input_buffer);
- clReleaseCommandQueue(queue);
- clReleaseKernel(kernel);
- clReleaseProgram(program);
- clReleaseContext(context);
- client_cleanup(EXIT_SUCCESS);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement