private static void MemoryCopy(Context context, Device device) { try { using (CommandQueue commandQueue = context.CreateCommandQueue(device, CommandQueueProperties.ProfilingEnable)) { byte[] buffer = new byte[size]; for (int i = 0; i < size; i++) { buffer[i] = 0xFF; } using (NOpenCL.Buffer d_idata = context.CreateBuffer(MemoryFlags.ReadOnly, size), d_odata = context.CreateBuffer(MemoryFlags.WriteOnly, size)) { unsafe { fixed(byte *rawData = buffer) { using (commandQueue.EnqueueWriteBuffer(d_idata, true, 0, size, (IntPtr)rawData)) { } } } commandQueue.Finish(); using (commandQueue.EnqueueCopyBuffer(d_idata, d_odata, 0, 0, size)) { } commandQueue.Finish(); } } } catch (Exception ex) { throw new Exception(null, ex.InnerException ?? ex); } }
/// <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); } }
/// <summary> /// Creates and binds buffer to this kernel before execution /// </summary> /// <param name="ptr">Pointer to memory</param> /// <param name="size">Size of memory</param> /// <param name="readOnly">Bind as read-only</param> /// <returns>Current instance of kernel</returns> public unsafe OpenCLKernel BindBuffer(void *ptr, int size, bool readOnly) { try { NOpenCL.Buffer buffer = kernelSet.OwnerDevice.Context.CreateBuffer( MemoryFlags.UseHostPointer | (readOnly ? MemoryFlags.ReadOnly : MemoryFlags.ReadWrite), size, new IntPtr(ptr)); createdBuffers.Add(new OpenCLBuffer { Ptr = new IntPtr(ptr), Buffer = buffer, OwnerDevice = kernelSet.OwnerDevice }); kernel.Arguments[currentArg].SetValue(buffer); currentArg++; return(this); } catch (Exception ex) { throw new OpenCLException("Cannot create buffer. Buffer size is probably too high.", ex); } }
public unsafe void Execute() { var sw = new Stopwatch(); sw.Start(); Platform platform = Platform.GetPlatforms()[0]; var gpuDevice = platform.GetDevices(DeviceType.Gpu); this.DisplayDeviceInfo(gpuDevice); int localWorkSize = 1024; int globalWorkSize = localWorkSize * 10000; float[] srcA = new float[globalWorkSize]; float[] coeff = new float[4]; coeff[0] = 11; coeff[1] = 3; coeff[2] = 2; coeff[3] = 2; using (var context = Context.Create(gpuDevice[0])) { using (CommandQueue commandQueue = context.CreateCommandQueue(gpuDevice[0], CommandQueueProperties.None)) { using (Buffer bufferA = context.CreateBuffer(MemoryFlags.ReadWrite, srcA.Length * sizeof(float))) using (Buffer bufferCoeff = context.CreateBuffer(MemoryFlags.ReadOnly, coeff.Length * sizeof(float))) { string path = @"d:\Study\NUTS\GPU\Parallel-NUTS\OpenCl\kernels\example.cl"; var openClProgram = new OpenClProgram(context); string options = "-cl-fast-relaxed-math"; using (var program = openClProgram.LoadFromFile(path, options)) { using (Kernel kernel = program.CreateKernel("Calculate")) { sw.Stop(); Console.WriteLine($"Infrastructure time: {sw.Elapsed.TotalSeconds} sec."); sw.Restart(); for (int i = 0; i < 1000; i++) { Console.WriteLine($"Iteration: {i}"); kernel.Arguments[0].SetValue(bufferA); kernel.Arguments[1].SetValue(bufferCoeff); fixed(float *psrcA = srcA) fixed(float *psrcCoeff = coeff) { using (commandQueue.EnqueueWriteBuffer(bufferA, false, 0, sizeof(float) * globalWorkSize, (IntPtr)psrcA)) { } using (commandQueue.EnqueueWriteBuffer(bufferCoeff, false, 0, sizeof(float) * coeff.Length, (IntPtr)psrcCoeff)) { } using (commandQueue.EnqueueNDRangeKernel(kernel, (IntPtr)globalWorkSize, (IntPtr)localWorkSize)) { } // synchronous/blocking read of results, and check accumulated errors using (commandQueue.EnqueueReadBuffer(bufferA, true, 0, sizeof(float) * globalWorkSize, (IntPtr)psrcA)) { } } } sw.Stop(); Console.WriteLine($"Compute time: {sw.Elapsed.TotalSeconds} sec."); } } } } } }