7 Replies Latest reply on Apr 4, 2011 8:25 PM by krishnan

    Simple matrix initialisation kernel failing


      Hi folks

      I am doing some small test codes on OpenCL to get the hang of it before I use it for a larger project I have planned. I wrote a kernel that simply intializes two floats.

      I have some error handling in my test code, and I get the error "Error Building Program 1", which is immediately after `clBuildProgram(program, 0, NULL, NULL, NULL, NULL)'. I get no errors on creating contexts or program objects before this point. So I am assuming that the problem lies in my kernel. I have attached the kernel code to this post.

      To explain, I have two integers `m' and `n'. `n' is smaller than `m'. I have two floats `inputA' and `inputB' of size `m+2' and `n+2' respectively. The kernel takes these two floats, a float `h' as well as `n', and intializes `inputA' and `inputB'. The kernel is supposed to run over `m+2' iterations. (To clarify, `m' does not appear in the kernel itself. I mentioned it only to help understand the purpose of the kernel).

      Any help would be much appreciated.

      const char *KernelSource= "__kernel void initialize (__global float *inputA, __global float *inputB, float h, int n)\n"\ "{\n"\ " float id = get_global_id(0);\n"\ " inputA = h*((float)id-0.5);\n"\ " if(id<n+2);\n"\ " inputB = h*((float)id-0.5)-7.5'\n"\ "}\n"\ "\n";

        • Simple matrix initialisation kernel failing


          Its difficult to answer with such a information. Please your your system Info: CPU<GPU<SDK<DRIVER<OS.

          Also try getting the error codes returned by OpenCL API and see their meaning in cl.h.

          The line

          inputB= h * ....

          lacks a semicolon at the end, and typing a "\n" is of no importance AFAIT.

            • Simple matrix initialisation kernel failing

              This is pretty pro analysis.

              I really learn from this a lot. Thanks for sharing!

                  • Simple matrix initialisation kernel failing



                    I tried to compile your code and found some issues:


                    - There is no qualifier for h and n (are they in __global space?)
                    - You're not supposed to assign a float to a pointer as in inputA = h*((float)id-0.5);  did you mean something else?
                    - Same for inputB;
                    - If you use h as a pointer parameter with a single value it's convenient and less confusing to access it using h[0].


                    The attached code compiles, which doesn't mean it solves your problem, but I find that it may bring some light to what works.


                    I personally find it very useful to write the OpenCL code separately just to check if it compiles and only then copy and paste the kernel into the program itself. There are many tools out there but may I suggest OpenCLCodeChecker.


                    I hope this helps.

                    __kernel void initialize (__global float *inputA, __global float *inputB, __constant float* h, __constant int* n) { int id = get_global_id(0); inputA[id] = h[0]*((float)id-0.5f); if(id<n[0]+2) inputB[id] = h[0]*((float)id-0.5f)-7.5f; }

                      • Simple matrix initialisation kernel failing

                        Thanks everyone for your replies. I'll let you know if I run into any other problems.

                        @himanshu - that missing semicolon looks to be the problem. I can only compile my code when I get back to the lab, but it should work with that.

                        @Jawed and douglas125 - do you know if there are code checkers that work on linux?

                        @douglas125 - I don't know if the qualifers for h and n necessary. I have seen kernels that AMD has used some of its tutorials where it doesn't use qualifiers when passing constants to the kernel.

                          • Simple matrix initialisation kernel failing

                            [quote]do you know if there are code checkers that work on linux?[/quote]

                            When you build your program with the clBuildProgram command, pass a callback function to get the build log. If the code don't compile, the build log will tell you where is the problem.

                            Personnally, I think it is better to put the source code of the CL program alone in another file and write a simple function that read that file. Because in case of build failure, the no of line reported by the log will be the exact line in the CL file source code. That will not the case if the code is "embedded" in your C our C++ file. 





                            void build_notify(cl_program program,void *data); //callback signature ..... ..... clBuildProgram(mandelbrot_prog, sys.platforms[0].num_devices, sys.platforms[0].devices_id, NULL, build_notify, &sys.platforms[0].devices_id[1]); .... .... //Callback function definition void build_notify(cl_program program,void *data) { size_t param_value_size; char *string = NULL; cl_device_id *device = (cl_device_id*)data; clGetProgramBuildInfo(program, *device, CL_PROGRAM_BUILD_LOG,1,NULL,&param_value_size); // printf("Number of character %d\n",param_value_size); string = malloc(param_value_size); clGetProgramBuildInfo(program, *device, CL_PROGRAM_BUILD_LOG,param_value_size ,string,NULL); if(string != NULL) { printf("INFO LOG: %s\n",string); free(string); } }