Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xealits/87ceb0043e14d7652530 to your computer and use it in GitHub Desktop.
Save xealits/87ceb0043e14d7652530 to your computer and use it in GitHub Desktop.
Making enjalot script on OpenCL-OpenGL interoperability

The code: https://github.com/enjalot/adventures_in_opencl/tree/master/part2/

From the README:

We demonstrate OpenCL and OpenGL context sharing by making a simple particle system.

Build: make a build directory and build the tutorial

 mkdir build
 cd build
 cmake ..
 make

execute the example program

 ./part2.x

On cmake .. had:

CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
...
GLEW_INCLUDE_PATH
...
GLEW_LIBRARY

According to ubuntuforum from 2009 changed GLEW_LIBRARY to GLEW_LIBRARIES in the CMakeLists.txt. The plural ending of the variable was present at all the rest of GET_... variables in TARGET_LINK_LIBRARIES. Similar irregularity was present in GLEW_INCLUDE_PATH -- the rest of INCLUDE_DIRECTORIES had ..._DIR instead of ...PATH on the end. Corrected that. cmake .. worked fine.

make reported missing fatal error: GL/glew.h: No such file or directory. Found them (apt-file search GL/glew.h) in libglew-dev. Installed it. Now make has lots of undefined reference to __glewBindBuffer and alike.

Looking at title "Could NOT find GLEW (missing: GLEW_INCLUDE_DIR GLEW_LIBRARY)" of the issue, and getting that headers were found, but the function definitions were not, changed GLEW_LIBRARIES back to GLEW_LIBRARY in CMakeLists.txt.

Compiled!

@xealits
Copy link
Author

xealits commented Sep 23, 2015

The run failed with some custom error from enjalot:

  $ ./part2.x
  Hello, OpenCL
  Initialize OpenCL object and context
  cl::Platform::get(): CL_SUCCESS
  platforms.size(): 3
  terminate called after throwing an instance of 'cl::Error'
    what():  clGetDeviceIDs
  fish: Job 1, “./part2.x ” terminated by signal SIGABRT (Abort)

@xealits
Copy link
Author

xealits commented Sep 23, 2015

Running as sudo (according to):

$ sudo ./part2.x 
[sudo] password for : 
Hello, OpenCL
Initialize OpenCL object and context
modprobe: FATAL: Module nvidia not found.
cl::Platform::get(): CL_SUCCESS
platforms.size(): 3
terminate called after throwing an instance of 'cl::Error'
  what():  clGetDeviceIDs

@xealits
Copy link
Author

xealits commented Sep 23, 2015

I guess it means the interoperability does not work.
In pyopencl (example from) the common opencl-opengl buffer could not be created.
On neither platform, on CPU and Intel's HD 4000 GPU.
Probably the interoperability does not work on the GPU?

HD 4000 is supported only with beignet (version 0.3 on Ubuntu 14.04).
And probably the example selects some other platform.
(Currently there are 3: AMD's, Intel's and beignet by the name of "Experiment Intel Gen OCL Driver".)

More output from setting the correct number (2) in platforms(2) call:

$ sudo ./part2.x 
Hello, OpenCL
Initialize OpenCL object and context
modprobe: FATAL: Module nvidia not found.
cl::Platform::get(): CL_SUCCESS
platforms.size(): 3
getDevices: CL_SUCCESS
devices.size(): 1
type: device: 4 CL_DEVICE_TYPE_GPU: 4 
ERROR: clCreateContextFromType(CL_DEVICE_NOT_FOUND)
ERROR: clCreateCommandQueue(-34)
load the program
kernel size: 408
ERROR: clCreateProgramWithSource(CL_INVALID_CONTEXT)
build program
program.build: CL_INVALID_PROGRAM
done building program
terminate called after throwing an instance of 'cl::Error'
  what():  clGetProgramBuildInfo

Found one more hardcoded value for choice of the platform: platforms[0] in the code, if somebody is looking.
Changed it to beignet (2).
Output:

$ sudo ./part2.x 
Hello, OpenCL
Initialize OpenCL object and context
modprobe: FATAL: Module nvidia not found.
cl::Platform::get(): CL_SUCCESS
platforms.size(): 3
getDevices: CL_SUCCESS
devices.size(): 1
type: device: 4 CL_DEVICE_TYPE_GPU: 4 
(X) Before defining OS-specific context properties.
(X) Defining OS-specific context properties after Win32 if branch (final else?).
(X) Create command queue.
load the program
kernel size: 408
build program
fatal error: malformed or corrupted PCH file: 'could not find file '/build/buildd/beignet-0.3/obj-x86_64-linux-gnu/backend/src/ocl_stdlib.h' referenced by AST file'
1 error generated.
program.build: CL_INVALID_PROGRAM
done building program
Build Status: -1
Build Options:  
Build Log:   
gl interop!

@xealits
Copy link
Author

xealits commented Sep 23, 2015

The beignet 0.3 is broken in Ubuntu:
https://bugs.launchpad.net/ubuntu/+source/beignet/+bug/1255323

New versions exist on newer Ubuntus, no backport to Trusty.

@xealits
Copy link
Author

xealits commented Sep 23, 2015

installed 1.0.3-0pmjdebruijn1~trusty
(Maintainer: Debian OpenCL Maintainers pkg-opencl-devel@lists.alioth.debian.org and everything...)

$ ./capsbasic "Intel(R)"
Number of available platforms: 3
Platform names:
    [0] AMD Accelerated Parallel Processing
    [1] Intel Gen OCL Driver
    [2] Intel(R) OpenCL [Selected]
Number of devices available for each type:
    CL_DEVICE_TYPE_CPU: 1
    CL_DEVICE_TYPE_GPU: 0
    CL_DEVICE_TYPE_ACCELERATOR: 0

[1] Intel Gen OCL Driver is beignet 1.0.3 and it sees the GPU:

$ ./capsbasic "Intel"
Number of available platforms: 3
Platform names:
    [0] AMD Accelerated Parallel Processing
    [1] Intel Gen OCL Driver [Selected]
    [2] Intel(R) OpenCL
Number of devices available for each type:
    CL_DEVICE_TYPE_CPU: 0
    CL_DEVICE_TYPE_GPU: 1
    CL_DEVICE_TYPE_ACCELERATOR: 0


$ sudo ./part2.x 
[sudo] password for alex: 
Hello, OpenCL
Initialize OpenCL object and context
modprobe: FATAL: Module nvidia not found.
cl::Platform::get(): CL_SUCCESS
platforms.size(): 3
getDevices: CL_SUCCESS
devices.size(): 1
type: device: 4 CL_DEVICE_TYPE_GPU: 4 
(X) Before defining OS-specific context properties.
(X) Defining OS-specific context properties after Win32 if branch (final else?).
ERROR: clCreateContextFromType(CL_DEVICE_NOT_FOUND)
(X) Create command queue.
ERROR: clCreateCommandQueue(-34)
load the program
kernel size: 408
ERROR: clCreateProgramWithSource(CL_INVALID_CONTEXT)
build program
program.build: CL_INVALID_PROGRAM
done building program
terminate called after throwing an instance of 'cl::Error'
  what():  clGetProgramBuildInfo

Changed the platform number in the cll.cpp couple times to 0 and 2 and 1.
Remade with 1:

$ sudo ./part2.x 
Hello, OpenCL
Initialize OpenCL object and context
modprobe: FATAL: Module nvidia not found.
cl::Platform::get(): CL_SUCCESS
platforms.size(): 3
getDevices: CL_SUCCESS
devices.size(): 1
type: device: 4 CL_DEVICE_TYPE_GPU: 4 
(X) Before defining OS-specific context properties.
(X) Defining OS-specific context properties after Win32 if branch (final else?).
(X) Create command queue.
load the program
kernel size: 408
build program
done building program
Build Status: 0
Build Options:  
Build Log:   /tmp/WETwsh.cl:1:316: warning: double precision constant requires cl_khr_fp64, casting to single precision
/tmp/WETwsh.cl:1:330: warning: double precision constant requires cl_khr_fp64, casting to single precision

gl interop!

@xealits
Copy link
Author

xealits commented Sep 23, 2015

Some window pops and disapears.
o_O how is it supposed to run?
Adding a getchar() at the end of main does not stop anything.

The crash point:

cl_vbos.push_back(cl::BufferGL(context, CL_MEM_READ_WRITE, p_vbo, &err));

btw without root everything breaks with fish: Job 1, “./part2.x ” terminated by signal SIGSEGV (Address boundary error)

#define NUM_PARTICLES 2 instead of 20000 does not help.

Put printf("p_vbo = %d", p_vbo); before cl_vbos.push_back(... p_vbo,...); -- the print breaks. p_vbo is not set.

Now the print works for some reason.
But cl_vbos.push_back( cl::BufferGL(context, CL_MEM_READ_WRITE, p_vbo, &err)); does not.
std::vector<cl::Memory> cl_vbos;

@xealits
Copy link
Author

xealits commented Sep 27, 2015

Yap

>>> gpu
<pyopencl.Device 'Intel(R) HD Graphics IvyBridge M GT2' on 'Intel Gen OCL Driver' at 0x7ff612fefdc0>
>>> gpu.extensions
'cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_icd'
>>> 'sharing' in gpu.extensions
False

no cl_khr_gl_sharing on HD4000

But!

>>> amd_cpu
<pyopencl.Device 'Intel(R) Core(TM) i5-3317U CPU @ 1.70GHz' on 'AMD Accelerated Parallel Processing' at 0x1689bd0>
>>> amd_cpu.extensions
'cl_khr_fp64 cl_amd_fp64 cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_3d_image_writes cl_khr_byte_addressable_store cl_khr_gl_sharing cl_ext_device_fission cl_amd_device_attribute_query cl_amd_vec3 cl_amd_printf cl_amd_media_ops cl_amd_media_ops2 cl_amd_popcnt '
>>> 'cl_khr_gl_sharing' in amd_cpu.extensions
True

(clinfo btw)

@xealits
Copy link
Author

xealits commented Sep 27, 2015

Ok, now the it runs.

$ ./part2.x 
Hello, OpenCL
Initialize OpenCL object and context
cl::Platform::get(): CL_SUCCESS
platforms.size(): 3
getDevices: CL_SUCCESS
devices.size(): 1
type: device: 2 CL_DEVICE_TYPE_CPU: 2 
(X) Before defining OS-specific context properties.
(X) Defining OS-specific context properties after Win32 if branch (final else, must be Linux?).
(X) Create command queue.
load the program
kernel size: 408
build program
done building program
Build Status: 0
Build Options:  
Build Log:   
Creating VBO
created VBO, activated, uploaded the data
checked the data is the same as in the input
bound buffer, id = 1
Creating VBO
created VBO, activated, uploaded the data
checked the data is the same as in the input
bound buffer, id = 2
gl interop!
LKAJFA
p_vbo = 1
c_vbo = 2
aaaaaaaaaaaaaa
created OpenCL buffer from GL VBO 1
created OpenCL buffer from GL VBO 2
create OpenCL only arrays
Pushing data to the GPU
push our CPU arrays to the CPU
in popCorn

But no particles in the window.
Does OpenGL run on CPU now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment