OpenCL Cookbook: Creating programs and reading kernels from a file

In OpenCL host programming, after platforms, devices and contexts in our OpenCL Cookbook series, comes the program data structure. Remember that a kernel represents a function in actual OpenCL code intended for execution on any given device as opposed to being written in a host language like C which can only execute on the CPU. In contrast a program is a container of kernels in the host programming language – in this case C though it could be C++, Java or Python. In order to execute a kernel function on a given device (CPU, GPU or accelerator) it must first be fed in to a host program to create a program data structure.

In the host program below, written in C, we take a small step further than last time to read in an OpenCL kernel function from a separate file into our host program and create a program data structure. We, then, retrieve the kernel source code from within the program data structure and verify that it is the same kernel function that we fed in earlier as a simple test. This can be valuable in the real world where you may be feeding in kernels from multiple files and want to make sure that all of them have been read into the program. When the program structure is queried for the kernel source it concatenates all kernel sources into one string so simply reading that will give you a global view of all kernel code previously fed in.

The host program which reads the kernel file in is as follows.

#include <stdio.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#include <CL/cl.h>

int main() {

    cl_platform_id platform;
    cl_device_id device;
    cl_context context;
    cl_program program;

    FILE* programHandle;
    size_t programSize, kernelSourceSize;
    char *programBuffer, *kernelSource;

    // get first available platform and gpu and create context
    clGetPlatformIDs(1, &platform, NULL);
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
    context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);

    // get size of kernel source
    programHandle = fopen("", "r");
    fseek(programHandle, 0, SEEK_END);
    programSize = ftell(programHandle);

    // read kernel source into buffer
    programBuffer = (char*) malloc(programSize + 1);
    programBuffer[programSize] = '\0';
    fread(programBuffer, sizeof(char), programSize, programHandle);

    // create program from buffer
    program = clCreateProgramWithSource(context, 1,
            (const char**) &programBuffer, &programSize, NULL);

    // read kernel source back in from program to check
    clGetProgramInfo(program, CL_PROGRAM_SOURCE, 0, NULL, &kernelSourceSize);
    kernelSource = (char*) malloc(kernelSourceSize);
    clGetProgramInfo(program, CL_PROGRAM_SOURCE, kernelSourceSize, kernelSource, NULL);
    printf("nKernel source:nn%sn", kernelSource);

    return 0;


The kernel code, saved in a file called, is as below.

_kernel void hello(__global char* string){

string[0] = 'H';
string[1] = 'e';
string[2] = 'l';
string[3] = 'l';
string[4] = 'o';
string[5] = ',';
string[6] = ' ';
string[7] = 'W';
string[8] = 'o';
string[9] = 'r';
string[10] = 'l';
string[11] = 'd';
string[12] = '!';
string[13] = '';


Save the host program as programs.c and then compile and run as follows. If you don’t have the clang command install it.

clang -framework OpenCL programs.c -o programs && ./programs

The output on my system (Macbook Air) is, as you would expect, the kernel source exactly as above.

Did this help you, did you face any issues or do you have any feedback for improvements? Let me know in the comments!

5 thoughts on “OpenCL Cookbook: Creating programs and reading kernels from a file”

  1. Thanks that helped me. It would be nice to see how an example would look for multiple kernels in multiple files. Coming from CUDA I am frustrated by the fact that I can’t just write kernels and call them by name…

Leave a Reply