clGetProgramInfo/CL_PROGRAM_BINARIES

Can you please give me an example for the usage of

  clGetProgramInfo(program, CL_PROGRAM_BINARIES, numDevices*Sizeof.POINTER, ???, null);

Thank you very much!
Roland.

Hello,

A small example that shows the basic workflow:

import static org.jocl.CL.*;

import org.jocl.*;

public class JOCLGetBinaryTest
{
    private static String programSource =
        "__kernel void "+
        "sampleKernel(__global const float *a,"+
        "             __global const float *b,"+
        "             __global float *c)"+
        "{"+
        "    int gid = get_global_id(0);"+
        "    c[gid] = a[gid] * b[gid];"+
        "}";

    private static int numDevices;
    private static cl_program program;
    private static cl_context context;
    
    public static void main(String args[])
    {
        defaultInitialization();
        
        // Obtain the length of the binary data that will be queried, for each device
        long binaryDataSizes[] = new long[numDevices];
        clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, 
            numDevices * Sizeof.size_t, Pointer.to(binaryDataSizes), null);
        
        // Allocate arrays that will store the binary data, each
        // with the appropriate size
        byte binaryDatas[][] = new byte[numDevices][];
        for (int i=0; i<numDevices; i++)
        {
            int binaryDataSize = (int)binaryDataSizes**;
            binaryDatas** = new byte[binaryDataSize];
        }
        
        // Create a pointer to an array of pointers which are pointing
        // to the binary data arrays
        Pointer binaryDataPointers[] = new Pointer[numDevices];
        for (int i=0; i<numDevices; i++)
        {
            binaryDataPointers** = Pointer.to(binaryDatas**);
        }

        // Query the binary data
        Pointer pointerToBinaryDataPointers = Pointer.to(binaryDataPointers);
        clGetProgramInfo(program, CL_PROGRAM_BINARIES, 
            numDevices * Sizeof.POINTER, pointerToBinaryDataPointers, null);

        // Print the binary data (for NVIDIA, this is the PTX data)
        for (int i=0; i<numDevices; i++)
        {
            System.out.println("Binary data for device "+i+":");
            System.out.println(new String(binaryDatas**));
        }
        
        clReleaseProgram(program);
        clReleaseContext(context);
    }
    
    
    private static void defaultInitialization()
    {
        long numBytes[] = {0};
        
        // Obtain the platform IDs and initialize the context properties
        cl_platform_id platforms[] = new cl_platform_id[1];
        clGetPlatformIDs(platforms.length, platforms, null);
        cl_context_properties contextProperties = new cl_context_properties();
        contextProperties.addProperty(CL_CONTEXT_PLATFORM, platforms[0]);
        
        // Create an OpenCL context on a GPU device
        context = clCreateContextFromType(
            contextProperties, CL_DEVICE_TYPE_GPU, null, null, null);
        if (context == null)
        {
            // If no context for a GPU device could be created,
            // try to create one for a CPU device.
            context = clCreateContextFromType(
                contextProperties, CL_DEVICE_TYPE_CPU, null, null, null);
            
            if (context == null)
            {
                System.out.println("Unable to create a context");
                return;
            }
        }

        // Enable exceptions and subsequently omit error checks in this sample
        CL.setExceptionsEnabled(true);
        
        // Get the list of GPU devices associated with the context
        clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, null, numBytes); 
        
        // Obtain the cl_device_id for the first device
        numDevices = (int) numBytes[0] / Sizeof.cl_device_id;
        cl_device_id devices[] = new cl_device_id[numDevices];
        clGetContextInfo(context, CL_CONTEXT_DEVICES, numBytes[0],  
            Pointer.to(devices), null);

        // Create the program from the source code
        program = clCreateProgramWithSource(context,
            1, new String[]{ programSource }, null, null);
        
        // Build the program
        clBuildProgram(program, 0, null, null, null, null);
    }
}

Note that during my last tests, the binary data that could be queried from AMD OpenCL contained just the name of some DLL file (while for NVIDIA, it is the actual PTX code), but maybe this has changed in the latest stream SDK releases.

bye
Marco

Hello Marco,

thank you very much - your example solves my problem perfectly!

BTW: The current AMD ati-stream-v2.2-lnx32 gives usable binaries. At http://developer.amd.com/support/KnowledgeBase/Lists/KnowledgeBase/DispForm.aspx?ID=115 you can find an Article about how to create binary kernels offline.

Best wishes!
Roland