Troubleshooting OpenCL C/C++ libraries using an nVidia GPU on Ubuntu 14.04

Recently I found that getting OpenCL working on a linux box(and possibly windows also) is quite challenging.

The NVIDIA website wasn’t much help, and there seemed to be a fair few sources that claimed that installing the CUDA Toolkit from Nvidia would be sufficient.

It did install the .so file at: /usr/lib/x86_64-linux-gnu/libOpenCL.so

(might vary depending on the type of install used. I installed using a .deb file)

Indicating that the library was partially available, however attempting to include the OpenCL headers and compiling in C/C++ programs would result in the compiler not recognising them.

After some research I found that the CUDA toolkit did not include the openCL headers in the /usr/include folder.

Conveniently, this could be resolved with the command:

sudo apt-get install opencl-headers

This added the CL folder to the include directory:

liang@liang-EX58-UD3R:~$ ls -la /usr/include/ |grep CL
drwxr-xr-x 2 root root 4096 Jun 19 23:45 CL

After this I was able to compile .cl programs using g++ and gcc.

Determining the amount of Memory to allocate for a Text File to open in C

While first trying to determine the correct amount of memory to allocate for a large text file, my first instinct was to use a loop to the end of the file while keeping count of how many characters it traversed would be a good solution. (let’s call this Method 1)

Another obvious but incorrect solution may be to simply allocate a large chunk of memory and hope that it would be enough.

Both of the above are bad ideas for various reasons.

A better way of doing it is to use fseek and ftell

Lets look at 2 code snippets that illustrate the difference:

Method A

	while((ch = fgetc(fp)) != EOF ){
		charnum++;
	}
	char * data = malloc(charnum*sizeof(char));
	printf("filesize = %lu\n", charnum*sizeof(char));

This produces the following output:

filesize = 27912710

Method B

	fseek(fp, 0L, SEEK_END);
	int sz = ftell(fp);
	printf("filesize from ftell = %d\n", sz);
	char * data = malloc(sz);

This produces output:

filesize from ftell = 27912710

Verdict

As can be seen the results are close to identical except for one factor.
Method B is MUCH faster.

Here’s a small c program that’ll let you test it out for yourself, assuming a text file of significant size to test it on:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h> 

char *loadTextFile( char filename[] ); //Loads a file in pure sequential format in to Memory

char *loadTextFile( char filename[] ){
	char ch;
	FILE *fp;
	fp = fopen(filename,"r");

	if( fp == NULL )
	{
	  perror("Error while opening the file:\n");
	  printf("filename:%s  errno:%d\n", filename,errno);
	  exit(EXIT_FAILURE);
	}

	//Method A: loop through entire file to determine size
	/*
	int charnum = 0;
	while((ch = fgetc(fp)) != EOF ){
		charnum++;
	}
	char * data = malloc(charnum*sizeof(char));
	printf("firstpass: %d\n",charnum);
	printf("filesize = %lu\n", charnum*sizeof(char));
	*/
	//Method B: use fseek and estimate file size
	/*
	fseek(fp, 0L, SEEK_END);
	int sz = ftell(fp);
	printf("filesize from ftell = %d\n", sz);
	char * data = malloc(sz);
	//while((ch = fgetc(fp)) != EOF){}
	*/
	return data;
}

int main(){
	char file_name[]="data/test.csv";
	int i;
	for( i = 0; i < 99999 ; i++){
		char *p = loadTextFile(file_name);
	}
	return 0;
}

Try uncommenting the sections for Method A and Method B, then compiling and running, and the performance improvement is quite apparent.

Sources:

Post in this stack overflow thread: http://stackoverflow.com/questions/238603/how-can-i-get-a-files-size-in-c

http://www.tutorialspoint.com/c_standard_library/c_function_ftell.htm

http://www.tutorialspoint.com/c_standard_library/c_function_fseek.htm

New C programmer’s FAQ

I’ve made this blog post to document any unpleasant suprises I find while using the C programming language.

Additionally, if I’ve left something out, or if you have your own question, post something in the comments, and I’ll see if I can sort it out.

Pointers:

Can pointers be of the void type?

yes. Declare a void pointer as follows:

void * pointer

What is a void pointer?
Good question lol. So far my understanding is that it is a pointer that is not type checked when passed to other functions. However I’m consistently finding that this is not the case.

Does whitespace matter in a pointer asterisk syntax?

No. The following are all equivalent:

void *pointer
void* pointer
void * pointer
void *pointer
void                     *                  pointer

Does index syntax work with pointers (as similar to arrays)?
Yes. However it only seems to work in one dimension:
eg:

printf("%p", meow[i]);

is valid, however:

printf("%p", meow[i][1]);

will yield the following error during compilation:

pointertest4.c: In function ‘main’:</pre>
pointertest4.c:24:21: warning: dereferencing ‘void *’ pointer [enabled by default]
printf("%p", meow[i][1]);
^
pointertest4.c:24:24: error: subscripted value is neither array nor pointer nor vector
printf("%p", meow[i][1]);
^

Functions

Can functions be used in expressions?
yes, the following code will compile:

#include 
//#include 
//#include 

int main(){
	int moo = 1;
	int foo[6] = {1,2,3,4,5,6};
	int SIZEARITHMETIC = sizeof(foo)/sizeof(int);

	printf("size of moo: %d\nsize of foo: %d\nsizearithmetic: %d\n", SIZE_moo, SIZE_foo,SIZEARITHMETIC);

	return 0;

}

The output is as follows:

size of moo: 4
size of foo: 24
sizearithmetic: 6

Does it matter where a function is located in C?
Yes it does. Unlike python and java, declaring function after it has been used for the first time in a c program will result in the first usage not being recognised as calling it from later in the code. Hence functions must be listed in the correct order, or even more ideally declared at the beginning of .c file