/// <summary> /// Initialize specified OpenCL device /// </summary> /// <param name="device">Device</param> private static void InitializeDevice(OpenCLDevice device) { if (device.Context != null) { return; } Context context = null; CommandQueue commandQueue = null; try { context = Context.Create(device.InnerDevice); #if ENABLE_PROFILING commandQueue = context.CreateCommandQueue(device.InnerDevice, CommandQueueProperties.ProfilingEnable); #else commandQueue = context.CreateCommandQueue(device.InnerDevice, 0); #endif } catch (Exception ex) { if (commandQueue != null) { commandQueue.Dispose(); } if (context != null) { context.Dispose(); } throw new OpenCLException("Device is not available (" + ex.Message + ").", ex); } device.Context = context; device.CommandQueue = commandQueue; }
/// <summary> /// Compiles specified OpenCL program on specified device /// </summary> /// <param name="device">OpenCL device</param> /// <param name="programName">Program name</param> /// <param name="programReceiveCallback">Callback to receive program sources; or null to use default storage</param> /// <returns>Kernel set for program</returns> public OpenCLKernelSet Compile(OpenCLDevice device, string programName, Func <string, string> programReceiveCallback = null) { const string buildOptions = "-cl-fast-relaxed-math -cl-mad-enable -cl-no-signed-zeros"; InitializeDevice(device); OpenCLKernelSet kernelSet; if (device.CachedKernels == null) { device.CachedKernels = new Dictionary <string, OpenCLKernelSet>(); } else { if (device.CachedKernels.TryGetValue(programName, out kernelSet)) { return(kernelSet); } } string programSource; if (programReceiveCallback != null) { programSource = programReceiveCallback(programName); } else { programSource = LoadSourceFromResources(programName); } Program program = device.Context.CreateProgramWithSource(programSource); program.Build(UseRelaxedMath ? buildOptions : null); #if ENABLE_PROFILING Console.WriteLine("Using kernel {0}...", programName); Console.WriteLine("OpenCL Build log: " + program.GetBuildLog(device.InnerDevice)); #endif kernelSet = new OpenCLKernelSet { Program = program, Kernels = new Dictionary <string, NOpenCL.Kernel>(), OwnerDevice = device }; device.CachedKernels[programName] = kernelSet; return(kernelSet); }
/// <summary> /// Creates buffer on target device from memory /// </summary> /// <param name="device">Target device</param> /// <param name="ptr">Pointer to memory</param> /// <param name="size">Size of memory</param> /// <param name="readOnly">Bind as read-only</param> /// <returns>Buffer</returns> public unsafe OpenCLBuffer CreateBuffer(OpenCLDevice device, void *ptr, int size, bool readOnly) { try { NOpenCL.Buffer buffer = device.Context.CreateBuffer( MemoryFlags.UseHostPointer | (readOnly ? MemoryFlags.ReadOnly : MemoryFlags.ReadWrite), size, new IntPtr(ptr)); return(new OpenCLBuffer { Ptr = new IntPtr(ptr), Buffer = buffer, OwnerDevice = device, HasOwnership = true }); } catch (Exception ex) { throw new OpenCLException("Cannot create buffer. Buffer size is probably too high.", ex); } }