Blog‎ > ‎

OpenCL on Mac and Cell

posted Dec 12, 2009, 8:41 PM by Robbie McMahon
My previous post was a little light on details. I have been asked to expand on it. As a side note, please see the new Disclaimer section.

As I mentioned in the previous post, I was able to get the same source code compiled and running on both my Mac and the CellBuzz cluster. There are only two minor changes that need to be made. 
  1. Download the source code. The folder contains an Xcode project. You can launch the project and look at it, but that won't really help us in a shell on the cluster. 
  2. The two files we are interested in are "main.c" and "". Copy those two files out and put them together in another folder. On the Mac, you don't need to change anything.
  3. To compile: gcc -o main main.c -m32 -lm -lstdc++ -framework OpenCL -std=c99

The first part "gcc -o main main.c" is standard compiling. "-m32" compiles the code in 32-bit mode. You can try "-m64", but it doesn't seem to make much difference. "-lm" is the math library. "-lstdc++" loads the standard C++ libraries. "-framework OpenCL" is the important part. It inculdes the OpenCL framework. "-std=c99" is also important because lines 174 and 186 use the C99 standard. If all the options bother you, you can instead run "g++ -o main main.c -framework OpenCL". Same results, I just prefer gcc for whatever reason.

Important Note: This only works on Snow Leopard (10.6.x and higher). Earlier versions of Mac OS do not have OpenCL. Also, I believe users with ATI video cards require 10.6.2 or later.

Did you get the code to run on your Macintosh? Good. Now we move on to CellBuzz. Two changes to the source code are in order. Line 8 reads "#include <OpenCL/opencl.h>", it should read
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#include <CL/cl.h>
It is just a simple preprocessor. The other change, which isn't necessary but helps, is line 57 which reads 
err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 1, &device, NULL);

Change it to read 
#ifdef __APPLE__
err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ACCELERATOR, 1, &device, NULL);

The SPU is considered an accelerator in the IBM implementation, which I think is a pretty good idea. Compiling this code is almost identical, "gcc -o main main.c -m32 -lm -lstdc++ -lCL -std=c99". The library call for OpenCL is just different, "-lCL". Everything else is the same. You could also use the XLC compiler ppu-xlcl, but I couldn't get that to work. It gives me a bunch of library errors,
[user@cellbuzz]$ ppu-xlcl -o main main.c -lm -lstdc++ -lCL -pedantic
"/usr/include/sys/select.h", line 110.49: 1506-215 (E) Too many arguments specified for macro select.
"/usr/include/sys/select.h", line 109.12: 1506-275 (S) Unexpected text '__tg_builtin_gentype' encountered.
"/usr/include/sys/select.h", line 109.12: 1506-046 (S) Syntax error.
"/usr/include/stdlib.h", line 699.12: 1506-275 (S) Unexpected text '__tg_builtin_gentype' encountered.
"/usr/include/stdlib.h", line 699.12: 1506-046 (S) Syntax error.
"/usr/include/stdlib.h", line 699.21: 1506-963 (W) The attribute "const" is not a valid variable attribute and is ignored.

After the library errors, it complains about the pragmas, but that doesn't matter. I don't have a great yearning to use the XLC compiler. Maybe someone else can figure it out.

I've attached my modified source code that compiles and runs on both systems. Credit goes to MacResearch for the bulk of the source code. I plan to make a benchmarking program, but I may just use an existing one.
Robbie McMahon,
Dec 12, 2009, 9:18 PM