private void TestContext(Context c) { Device[] devices = c.Devices; OpenCLNet.Program p = c.CreateProgramFromFile("OpenCL" + Path.DirectorySeparatorChar + "src" + Path.DirectorySeparatorChar + "MemoryTests.cl"); Dictionary<string, Kernel> kernelDictionary; try { p.Build(); } catch (OpenCLException ocle) { throw ocle; } kernelDictionary = p.CreateKernelDictionary(); NativeKernelCallRef = new NativeKernel(NativeKernelTest); for (int deviceIndex = 0; deviceIndex < devices.Length; deviceIndex++) { Device d; d = devices[deviceIndex]; using (CommandQueue cq = c.CreateCommandQueue(d)) { if ( (d.ExecutionCapabilities & (ulong)DeviceExecCapabilities.NATIVE_KERNEL)!=0 ) { Output("Testing native kernel execution"); cq.EnqueueNativeKernel(NativeKernelCallRef, this, null); cq.Finish(); if (NativeKernelCalled != 1) Error("EnqueueNativeKernel failed"); Interlocked.Decrement(ref NativeKernelCalled); } else { Output("Testing native kernel execution: Not supported"); } TestMem(c, cq, kernelDictionary); TestDevice(d); TestCommandQueue(c, cq); TestKernel(c, cq, kernelDictionary["ArgIO"]); TestUserEventCallbacks(c, cq); TestVecKernel(c, cq, kernelDictionary["TestVectorFloat2"]); } } }
internal NativeKernelCallbackData(NativeKernel nk,CommandQueue cq, object o, Mem[] buffers) { NativeKernel = nk; CQ = cq; O = o; Buffers = buffers; }
/// <summary> /// Enquque a user function. This function is only supported if /// DeviceExecCapabilities.NATIVE_KERNEL set in Device.ExecutionCapabilities /// </summary> /// <param name="nativeKernel"></param> public void EnqueueNativeKernel(NativeKernel nativeKernel, object userObject, Mem[] buffers) { ErrorCode result; int callbackId; callbackId = AddNativeKernelParams(nativeKernel, this, userObject, buffers); result = OpenCL.EnqueueNativeKernel(CommandQueueID, NativeKernelDelegate, &callbackId, (IntPtr)4, 0, null, null, 0, null, null); if (result != ErrorCode.SUCCESS) throw new OpenCLException("EnqueueNativeKernel failed with error code " + result, result); }
private static int AddNativeKernelParams( NativeKernel nk, CommandQueue cq, object o, Mem[] buffers) { int callbackId; NativeKernelCallbackData callbackData = new NativeKernelCallbackData(nk, cq, o, buffers); bool gotMutex = false; try { gotMutex = NativeKernelParamsMutex.WaitOne(); do { callbackId = NativeKernelParamsId++; } while (NativeKernelDispatch.ContainsKey(callbackId)); NativeKernelDispatch.Add(callbackId, callbackData); } finally { if (gotMutex) NativeKernelParamsMutex.ReleaseMutex(); } return callbackId; }
/// <summary> /// Enquque a user function. This function is only supported if /// DeviceExecCapabilities.NATIVE_KERNEL set in Device.ExecutionCapabilities /// </summary> /// <param name="nativeKernel"></param> /// <param name="numEventsInWaitList"></param> /// <param name="event_wait_list"></param> public void EnqueueNativeKernel(NativeKernel nativeKernel, object userObject, Mem[] buffers, int numEventsInWaitList, Event[] event_wait_list) { ErrorCode result; int callbackId; callbackId = AddNativeKernelParams(nativeKernel, this, userObject, buffers); result = OpenCL.EnqueueNativeKernel(CommandQueueID, NativeKernelDelegate, &callbackId, (IntPtr)4, 0, null, null, (uint)numEventsInWaitList, InteropTools.ConvertEventsToEventIDs( event_wait_list ), null); if (result != ErrorCode.SUCCESS) throw new OpenCLException("EnqueueNativeKernel failed with error code " + result, result); }