2011-09-07 11 views
5

मैं clCreateProgramWithBinary का उपयोग कर काम करने के लिए केवल एक बुनियादी प्रोग्राम प्राप्त करने की कोशिश कर रहा हूं। ऐसा इसलिए है कि मुझे "सत्य" एप्लिकेशन के बजाय इसका उपयोग कैसे करना है।ओपनसीएल में clCreateProgramWithBinary का उपयोग कैसे करें?

मुझे लगता है कि पैरामीटर में से एक बाइनरी की एक सूची है। परीक्षण के लिए बाइनरी बनाने के बारे में मैं वास्तव में कैसे जाऊं? मेरे पास कुछ टेस्ट कोड है जो स्रोत से एक प्रोग्राम बनाता है, बनाता है और इसे दबाता है। क्या इस प्रक्रिया के दौरान किसी बिंदु पर एक बाइनरी बनाई गई है जिसे मैं clCreateProgramWithBinary में खिला सकता हूं?

यहां मेरे कुछ कोड हैं, बस मेरे समग्र प्रवाह का विचार देने के लिए। मैंने सादगी के लिए टिप्पणियां और त्रुटि जांच छोड़ी है।

program = clCreateProgramWithSource(clctx, 1, &dumbkernelsource, NULL, &errcode); 
errcode = clBuildProgram(program, env->num_devices, env->device, NULL, NULL, NULL); 
mykernel = clCreateKernel(program, "flops", &errcode); 
errcode = clGetKernelWorkGroupInfo(mykernel, *(env->device), CL_KERNEL_WORK_GROUP_SIZE, sizeof(local), &local, NULL); 
global = num_workgroups * local; 
errcode = clEnqueueNDRangeKernel(commands, mykernel, 1, NULL, &global, &local, 0, NULL, NULL); 

उत्तर

2

आप अपने कार्यक्रम संकलन के बाद, आप clGetProgramInfo के साथ अपने बाइनरी कोड मिलता है, और फिर एक फाइल करने के लिए सहेज सकते हैं।

उदाहरण कोड (संकलन करने की कोशिश की नहीं है, लेकिन इन पंक्तियों के साथ कुछ होना चाहिए):

program = clCreateProgramWithSource(clctx, 1, &dumbkernelsource, NULL, &errcode); 
errcode = clBuildProgram(program, env->num_devices, env->device, NULL, NULL, NULL); 
int number_of_binaries; 
char **binary; 
int *binary_sizes; 
errcode = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, NULL, 0, &number_of_binaries); 
binary_sizes = new int[number_of_binaries]; 
binary = new char*[number_of_binaries]; 
errcode = clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, binary_sizes, number_of_binaries*sizeof(int), &number_of_binaries); 
for (int i = 0; i < number_of_binaries; ++i) binary[i] = new char[binary_sizes[i]]; 
errcode = clGetProgramInfo(program, CL_PROGRAM_BINARIES, binary, number_of_binaries*sizeof(char*), &number_of_binaries); 
0

आधिकारिक OpenCL प्रोग्रामिंग गाइड किताब इस का एक अच्छा उदाहरण है। एक Google कोड प्रोजेक्ट भी है, ओपनक्ल-बुक-नमूने, जिसमें पुस्तक से कोड शामिल है। उदाहरण जो आप खोज रहे हैं here है।

0

मिनिमल runnable उदाहरण

, सीएल सी स्रोत से एम्बेडेड वेक्टर वेतन वृद्धि शेडर संकलित a.bin को बाइनरी बचाने के लिए, बाइनरी शेडर लोड करते हैं, और इसे चलाने:

./a.out 

दावे पर किया जाता है कार्यक्रम का अंत

a.bin से सीएल सी शेडर, लोड द्विआधारी पर ध्यान न दें, और इसे चलाने:

./a.out 0 

संकलित करें और चलाने के साथ:

gcc -ggdb3 -std=c99 -Wall -Wextra a.c -lOpenCL && ./a.out 

उबंटू 16.10, NVIDIA NVS5400, ड्राइवर 375.39 में परीक्षण किया गया।

GitHub नदी के ऊपर: https://github.com/cirosantilli/cpp-cheat/blob/b1e9696cb18a12c4a41e0287695a2a6591b04597/opencl/binary_shader.c

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

#define CL_USE_DEPRECATED_OPENCL_1_2_APIS 
#include <CL/cl.h> 

const char *source = 
    "__kernel void kmain(__global int *out) {\n" 
    " out[get_global_id(0)]++;\n" 
    "}\n" 
; 

#define BIN_PATH "a.bin" 

char* common_read_file(const char *path, long *length_out) { 
    char *buffer; 
    FILE *f; 
    long length; 

    f = fopen(path, "r"); 
    assert(NULL != f); 
    fseek(f, 0, SEEK_END); 
    length = ftell(f); 
    fseek(f, 0, SEEK_SET); 
    buffer = malloc(length); 
    if (fread(buffer, 1, length, f) < (size_t)length) { 
     return NULL; 
    } 
    fclose(f); 
    if (NULL != length_out) { 
     *length_out = length; 
    } 
    return buffer; 
} 

int main(int argc, char **argv) { 
    FILE *f; 
    char *binary; 
    cl_command_queue command_queue; 
    cl_context context; 
    cl_device_id device; 
    cl_int input[] = {1, 2}, errcode_ret, binary_status; 
    cl_kernel kernel, binary_kernel; 
    cl_mem buffer; 
    cl_platform_id platform; 
    cl_program program, binary_program; 
    const size_t global_work_size = sizeof(input)/sizeof(input[0]); 
    int use_cache; 
    long lenght; 
    size_t binary_size; 

    if (argc > 1) { 
     use_cache = !strcmp(argv[1], "0"); 
    } else { 
     use_cache = 0; 
    } 

    /* Get the binary, and create a kernel with it. */ 
    clGetPlatformIDs(1, &platform, NULL); 
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL); 
    context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL); 
    command_queue = clCreateCommandQueue(context, device, 0, NULL); 
    if (use_cache) { 
     binary = common_read_file(BIN_PATH, &lenght); 
     binary_size = lenght; 
    } else { 
     program = clCreateProgramWithSource(context, 1, &source, NULL, NULL); 
     clBuildProgram(program, 1, &device, "", NULL, NULL); 
     kernel = clCreateKernel(program, "kmain", NULL); 
     clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binary_size, NULL); 
     binary = malloc(binary_size); 
     clGetProgramInfo(program, CL_PROGRAM_BINARIES, binary_size, &binary, NULL); 
     f = fopen(BIN_PATH, "w"); 
     fwrite(binary, binary_size, 1, f); 
     fclose(f); 
    } 
    binary_program = clCreateProgramWithBinary(
     context, 1, &device, &binary_size, 
     (const unsigned char **)&binary, &binary_status, &errcode_ret 
    ); 
    free(binary); 
    clBuildProgram(binary_program, 1, &device, NULL, NULL, NULL); 
    binary_kernel = clCreateKernel(binary_program, "kmain", &errcode_ret); 

    /* Run the kernel created from the binary. */ 
    buffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(input), input, NULL); 
    clSetKernelArg(binary_kernel, 0, sizeof(buffer), &buffer); 
    clEnqueueNDRangeKernel(command_queue, binary_kernel, 1, NULL, &global_work_size, NULL, 0, NULL, NULL); 
    clFlush(command_queue); 
    clFinish(command_queue); 
    clEnqueueReadBuffer(command_queue, buffer, CL_TRUE, 0, sizeof(input), input, 0, NULL, NULL); 

    /* Assertions. */ 
    assert(input[0] == 2); 
    assert(input[1] == 3); 

    /* Cleanup. */ 
    clReleaseMemObject(buffer); 
    clReleaseKernel(kernel); 
    clReleaseKernel(binary_kernel); 
    clReleaseProgram(program); 
    clReleaseProgram(binary_program); 
    clReleaseCommandQueue(command_queue); 
    clReleaseContext(context); 
    return EXIT_SUCCESS; 
} 

मैं अत्यधिक cat a.bin है, जो इस लागू करने के लिए मानव पठनीय (और संपादन) PTX विधानसभा शामिल सलाह देते हैं।

संबंधित मुद्दे