
OpenCL interop AccessViolationException
Posted Monday, 23 August, 2010 - 06:19 by kwaegel inI am trying to setup a shared OpenGL/OpenCL system and I am getting several odd errors. My setup code is primarily based off this post and this article. The rest of the program is based off the standard game.cs sample file included with OpenTK.
The most annoying error at this point is an AccessViolationException that occurs when the program is closed. The specific error text is "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." The error occurs on line 171 of ComputeContext.cs in Cloo. Specificaly, the dispose method:
protected override void Dispose(bool manual) { if (manual) { //free managed resources } // free native resources if (Handle != IntPtr.Zero) { CL10.ReleaseContext(Handle); //--> Exception is thrown from this line Handle = IntPtr.Zero; } }
Building the OpenCL context with the default properties list (commented out in the code below) seems to have no issues. Only using properties list constructed with the sharing properties causes the problem. I am assuming it is a pointer issue, but I do not know enough about Cloo (or OpenGL for that matter) to know where to look.
I should probably note that I am not actually using any OpenCL kernels at this point. All that code is commented out while I try to resolve this issue. The kernels have their own set of bugs that I will need to deal with later...
My current shared context setup code is as follows:
private void openCLSharedInit() { // select OpenCL device and platform ComputePlatform platform = ComputePlatform.Platforms[0]; ComputeDevice device = platform.Devices[0]; IntPtr curDC = wglGetCurrentDC(); OpenTK.Graphics.IGraphicsContextInternal ctx = (OpenTK.Graphics.IGraphicsContextInternal)OpenTK.Graphics.GraphicsContext.CurrentContext; IntPtr raw_context_handle = ctx.Context.Handle; ComputeContextProperty p1 = new ComputeContextProperty(ComputeContextPropertyName.CL_GL_CONTEXT_KHR, raw_context_handle); ComputeContextProperty p2 = new ComputeContextProperty(ComputeContextPropertyName.CL_WGL_HDC_KHR, curDC); ComputeContextProperty p3 = new ComputeContextProperty(ComputeContextPropertyName.Platform, platform.Handle); List<ComputeContextProperty> props = new List<ComputeContextProperty>() { p1, p2, p3 }; ComputeContextPropertyList Properties = new ComputeContextPropertyList(props); // using this property list does not cause an error //ComputeContextPropertyList Properties = new ComputeContextPropertyList(platform); _computeContext = new ComputeContext(ComputeDeviceTypes.Gpu, Properties, null, IntPtr.Zero); //Create the command queue from the context and device _commandQueue = new ComputeCommandQueue(_computeContext, device, ComputeCommandQueueFlags.None); }
System setup:
nVidia 8600GT with driver version 258.96
AMD Phenom II 955 BE 3.2Ghz
Windows 7 x64 (running program in 64-bit mode)
.Net Framework 4 installed, targeting 3.5
OpenTK 1.0 rc1
Cloo latest trunk revision


Comments
Re: OpenCL interop AccessViolationException
This may be related to the GraphicsContext being freed before the ComputeContext. Put this into your application exit procedure and see what happens:
Re: OpenCL interop AccessViolationException
I tried putting that code in the Dispose method of the game (see below), but nothing seems to have changed. Oddly enough, I tried adding try...catch blocks around all the lines in the dispose method and nothing appears to have been thrown there. I did the same with the main method and I did not get any exceptions from there either. So either AccessViolationExceptions are not being caught by the catch block or it is being thrown when main() terminates.
Would it help if I posted the entire program code? It is only a relatively simple test program (~300 lines) contained in one class.
Updated dispose method:
Re: OpenCL interop AccessViolationException
Sure, I'll take a look. If this is one of those nasty GC-messing-with-my-stuff bugs other users will hit it too. Sooner or later.
Re: OpenCL interop AccessViolationException
Thanks. Here is the code. I should note that most of the kernel program code was commented out to simplify debugging. The original intent was to fill the screen with a textured quad after drawing to the texture with OpenCL.
Re: OpenCL interop AccessViolationException
This might take a bit longer since I don't have an OpenCL enabled GPU at the moment. Will return to this as soon as possible.
Re: OpenCL interop AccessViolationException
I found a workaround that stopped the error.
Everything seems to work if I manually dispose of all the ComputeMemory objects (ComputeBuffers, ComputeImages, etc) before the program is allowed to exit. I did this by placing dispose commands (or calls to objects that call dispose) in the
Dispose(bool manual)method that can be overridden from GameWindow.nythrix, any idea why manually disposing of everything works correctly, but the automatic cleanup does not?
Re: OpenCL interop AccessViolationException
This one got a bit lost in the woods.
It looks like the app has to manually dispose of shared CL/GL contexts. The GC cannot make a qualified decision. Also, does the GL context have to be current when releasing such ComputeContexts? I really don't know and I welcome any ideas on how to detect (and hopefully prevent) this situation through Cloo.
Note: The Dispose() you posted here will probably never get called.