PDA

View Full Version : Chapter 2, example 4: Creating a program from file



Petr Schreiber
27-09-2012, 19:02
We have learned what platform (http://www.thinbasic.com/community/showthread.php?11863-Chapter-2-example-1-Testing-platform-extensions), device (http://www.thinbasic.com/community/showthread.php?11869-Chapter-2-example-2-Testing-device-extensions) and context (http://www.thinbasic.com/community/showthread.php?11872-Chapter-2-example-3-Checking-a-context-s-reference-count) is. The term I would like to present today is "program".

This name is a bit misleading, because in OpenCL, the "program" thing is more similar to what we know as "library of functions".
The OpenCL "program" does not get executed, does not have main function and other features you would expect.

Instead, it is collection of small functions, called kernels.

While the previous terms (platform/device/context) were managed using function calls, the OpenCL program is written in special form of something I would not hesitate call "C on steroids".
It is language based on C99 standard, but enhanced with goodies such as vector data types. The bad news for BASIC programmers is that even this version of C language still has semicolons and scary syntax for FOR cycles (gripe intented ;)).

The program needs to be built first to make possible to call computations stored inside (execute kernels).

As a source for building the program you can pass string, but it is more comfortable to store sources in separate file and load them from file.

I must admit in this part it was nice to see ThinBASIC does not complicate things. In C original, the code to load the program file looks like this:


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


In thinBASIC, this code does the job:


program_buffer(i) = FILE_Load(file_name(i))
program_size(i) = Len(program_buffer(i))

If(program_size(i) = 0) Then
Printl("Couldn't find the program file")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If


The code attached to this post takes two OpenCL C source code files, and tries to build one program from them.

For demonstrative purposes, this operation fails - to show, how you can read back the OpenCL C errors. This is a thing you will experience soon, so better to get ready for it right now :D
If you would like to see successful compilation, just rename the kernel function in file bad.cl to something other than "good", which will fix the name conflict.

You will need the latest ThinBASIC and OpenCL headers (http://www.thinbasic.com/community/showthread.php?10159-OpenCL-Headers-Updated-Sep-15-2011) to run it + of course modern GPU or CPU (http://www.thinbasic.com/community/showthread.php?10161-OpenCL-Supported-hardware).


Petr

kryton9
27-09-2012, 22:44
Petr, how did you get around the TB arrays starting with 1 and OpenCL arrays with 0? I see you are using varptr buffer(1).

Does OpenCL just see the varptr buffer(1), and doesn't care-- as far as it is concerned, it is at index 0?

ErosOlmi
28-09-2012, 08:15
Base 1 or base 0 indexes is just a convention between the programming language and the programmers using it. When you go internally (CPU, hardware memory) all is just a piece allocated memory.

instead what can make the difference (positively or negatively) is the way multi dimention arrays are phisically filled in memory: column major or row major. Thinbasic is column major.

kryton9
02-10-2012, 02:08
Thanks for the explanation Eros. I never even thought about implications like that in multi-dimensional arrays :)