opencl (sixteen) ---- MapReduce

MapReduce two parts:

  Mapping: generating key-value pairs

       Merge: deal with these key-value pairs

// kernel

__kernel void string_search(char16 pattern, __global char* text,
     int chars_per_item, __local int* local_result, 
     __global int* global_result) {

   char16 text_vector, check_vector;

   /* initialize local data */
   local_result[0] = 0;
   local_result[1] = 0;
   local_result[2] = 0;
   local_result[3] = 0;

   / * The Make Sure Processing Previous has Completed * / 
   Barrier (CLK_LOCAL_MEM_FENCE); // locally synchronous 

   int item_offset = get_global_id ( 0 ) * chars_per_item; // the global id × size of each processed data de 

   / * the Iterate through characters in text * / 
   // iterate the process de data 
   for ( int I = item_offset; I <item_offset + chars_per_item; I ++ ) { 

      / * Load text INTO Private Global Buffer * / 
      text_vector = vload16 ( 0 , text + I); 

      / * and the Vector pattern text the Compare * / 
      check_vector= text_vector == pattern;

      /* Check for 'that' */
      if(all(check_vector.s0123))
         atomic_inc(local_result);  //原子操作

      /* Check for 'with' */
      if(all(check_vector.s4567))
         atomic_inc(local_result + 1);

      /* Check for 'have' */
      if(all(check_vector.s89AB))
         atomic_inc(local_result + 2);

      /* Check for 'from' */
      if(all(check_vector.sCDEF))
         atomic_inc(local_result + 3);
   }

   /* Make sure local processing has completed */
   barrier(CLK_GLOBAL_MEM_FENCE);  // 全局同步

   /* Perform global reduction */
   if(get_local_id(0) == 0) {  //归并
      atomic_add(global_result, local_result[0]);  //原子操作
      atomic_add(global_result + 1, local_result[1]);
      atomic_add(global_result + 2, local_result[2]);
      atomic_add(global_result + 3, local_result[3]);
   }
}
View Code

 

#define _CRT_SECURE_NO_WARNINGS
#define PROGRAM_FILE "string_search.cl"
#define KERNEL_FUNC "string_search"
#define TEXT_FILE "kafka.txt"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef MAC
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif

int main() {

   /* Host/device data structures */
   cl_platform_id platform;
   cl_device_id device;
   cl_context context;
   cl_command_queue queue;
   cl_int err;

   /* Program/kernel data structures */
   cl_program program;
   FILE *program_handle;
   char *program_buffer, *program_log;
   size_t program_size, log_size;
   cl_kernel kernel;
   size_t offset = 0;
   size_t global_size, local_size; // 全局大小 和局部大小

   /* Data and buffers */
   char pattern[16] = "thatwithhavefrom";
   FILE *text_handle;
   char *text;
   size_t text_size;
   int chars_per_item;//每个item 的大小
   int result[4] = {0, 0, 0, 0};
   cl_mem text_buffer, result_buffer;
   
   /* Identify a platform */   // 获取平台
   err = clGetPlatformIDs(1, &platform, NULL);
   if(err < 0) {
      perror("Couldn't identify a platform");
      exit(1);
   } 

   /* Access a device */ //Acquisition device 
   ERR = clGetDeviceIDs (Platform, CL_DEVICE_TYPE_GPU, . 1 , & Device, NULL);
    IF (ERR < 0 ) { 
      perror ( " Could Not the any Access Devices " ); 
      Exit ( . 1 );    
   } 

   / * the Determine size Global and local size * /   // determined, and the overall size of the local size
    // CL_DEVICE_MAX_COMPUTE_UNITS obtained number calculation unit (CU) OpcnCL apparatus 
   clGetDeviceInfo (device, CL_DEVICE_MAX_COMPUTE_UNITS,         
       the sizeof (global_size), & global_size, NULL);
    // CL_DEVICE_MAX_WORK_GROUP_SIZE work items workgroup de quantitative restrictions
   clGetDeviceInfo (Device, CL_DEVICE_MAX_WORK_GROUP_SIZE,         
       the sizeof (local_size), & local_size, NULL);
    // working global size × the number of each CU size workgroup 
   global_size * = local_size; 

   / * the Create A context * / 
   context = clCreateContext (NULL, . 1 , & Device, NULL, NULL, & ERR);
    IF (ERR < 0 ) { 
      perror ( " Could Not Create A context " ); 
      Exit ( . 1 );    
   } 

   / * the read File program and reading program Place Content INTO Buffer file * / 

   program_handle= fopen(PROGRAM_FILE, "r");
   if(program_handle == NULL) {
      perror("Couldn't find the program file");
      exit(1);
   }
   fseek(program_handle, 0, SEEK_END);
   program_size = ftell(program_handle);
   rewind(program_handle);
   program_buffer = (char*)calloc(program_size+1, sizeof(char));
   fread(program_buffer, sizeof(char), program_size, program_handle);
   fclose(program_handle);

   /* Read text file and place content into buffer 读取文本文件*/
   text_handle = fopen(TEXT_FILE, "r");
   if(text_handle == NULL) {
      perror("Couldn't find the text file");
      exit(1);
   }
   fseek(text_handle, 0, SEEK_END);
   text_size = ftell(text_handle)-1;
   rewind(text_handle);
   text = (char*)calloc(text_size, the sizeof ( char )); 
   fread (text, the sizeof ( char ), text_size, text_handle); 
   fclose (text_handle); 
   chars_per_item = text_size / global_size + . 1 ; // Text consignment oh ah / global size calculated for each item the data size 

   / * the Create Program from File * / 
   Program = clCreateProgramWithSource (context, . 1 , 
      ( const  char **) & program_buffer, & program_size, & ERR);
    IF (ERR < 0 ) { 
      perror ( " Could Not Create the Program");
      exit(1);
   }
   free(program_buffer);

   /* Build program */
   err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
   if(err < 0) {
            
      /* Find size of log and print to std output */
      clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 
            0, NULL, &log_size);
      program_log = (char*) calloc(log_size+1, sizeof(char));
      clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 
            log_size+1, program_log, NULL);
      printf("%s\n", program_log);
      free(program_log);
      exit(1);
   }

   /* Create a kernel 创建核*/
   kernel = clCreateKernel(program, KERNEL_FUNC, &err);
   if(err < 0) {
      perror("Couldn't create a kernel");
      exit(1);
   };

   /* Create buffers to hold the text characters and count */
   // 文本
   text_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY |
         CL_MEM_COPY_HOST_PTR, text_size, text, &err);
   if(err < 0) {
      perror("Couldn't create a buffer");
      exit(1);   
   };
   // 全局结果
   result_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE |
         CL_MEM_COPY_HOST_PTR, sizeof(result), result, NULL);

   /* Create kernel argument */
   err ClSetKernelArg = (Kernel, 0 , the sizeof (pattern), pattern); // mode entry 
   ERR | = clSetKernelArg (Kernel, . 1 , the sizeof (cl_mem), & text_buffer); // Text 
   ERR | = clSetKernelArg (Kernel, 2 , the sizeof ( chars_per_item), & chars_per_item); // for each size of the data entry process 
   ERR | = clSetKernelArg (Kernel, . 3 , . 4 * the sizeof ( int ), NULL); // local size of the result 
   ERR | = clSetKernelArg (Kernel, . 4 , the sizeof (cl_mem), & result_buffer); //全局结果
   if(err < 0) {
      printf("Couldn't set a kernel argument");
      exit(1);   
   };

   /* Create a command queue */
   queue = clCreateCommandQueue(context, device, 0, &err);
   if(err < 0) {
      perror("Couldn't create a command queue");
      exit(1);   
   };

   /* Enqueue kernel */
   /**
    * cl_int clEnqueueNDRangeKernel (
        cl_command_queue command_queue, // command queue 
     cl_kernel kernel, // nuclear 
     cl_uint work_dim, dimension data // 
     const size_t * global_work_offset, // global ID offset in each dimension 
     const size_t * global_work_size, // work items on each dimension number 
     const size_t * local_work_size, on // the dimensions of a working group the number of work items 
     cl_uint num_events_in_wait_list, 
     const cl_event * event_wait_list, 
     cl_event * Event 
) 
    * * * / 
   ERR = clEnqueueNDRangeKernel (Queue, Kernel, . 1 , & offset, & global_size, 
          local_size &, 0 , NULL, NULL); 
    IF(err < 0) {
      perror("Couldn't enqueue the kernel");
      printf("Error code: %d\n", err);
      exit(1);   
   }

   /* Read and print the result */
   // 读取数据命令
   err = clEnqueueReadBuffer(queue, result_buffer, CL_TRUE, 0, 
      sizeof(result), &result, 0, NULL, NULL);
   if(err < 0) {
      perror("Couldn't read the buffer");
      exit(1);   
   }

   printf("\nResults: \n");
   printf("Number of occurrences of 'that': %d\n", result[0]);
   printf("Number of occurrences of 'with': %d\n", result[1]);
   printf("Number of occurrences of 'have': %d\n", result[2]);
   printf("Number of occurrences of 'from': %d\n", result[3]);

   /* Deallocate resources */
   clReleaseMemObject (result_buffer); 
   clReleaseMemObject (text_buffer);   // release cached object 
   clReleaseKernel (Kernel);   // release core 
   clReleaseCommandQueue (Queue); // release command queue 
   clReleaseProgram (Program); // release procedure 
   clReleaseContext (context); // releasing the context 
   return  0 ; 
}

Guess you like

Origin www.cnblogs.com/feihu-h/p/12107356.html