public void singlePass(Kernel kernel, FloatMap inMap, FloatMap outMap) { var clInImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.Luminance, ChannelType.Float); IMem inputMapBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clInImageFormat, (IntPtr)inMap.W, (IntPtr)inMap.H, new IntPtr(inMap.Stride * sizeof(float)), inMap._buf, out err); assert(err, "input img creation"); IMem outputMapBuffer = Cl.CreateImage2D(_context, MemFlags.WriteOnly, clInImageFormat, (IntPtr)outMap.W, (IntPtr)outMap.H, new IntPtr(outMap.Stride * sizeof(float)), outMap._buf, out err); assert(err, "output img creation"); // Set memory objects as parameters to kernel err = Cl.SetKernelArg(kernel, 0, intPtrSize, inputMapBuffer); assert(err, "input map setKernelArg"); err = Cl.SetKernelArg(kernel, 1, intPtrSize, outputMapBuffer); assert(err, "output map setKernelArg"); // write actual data into memory object IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] inRegionPtr = new IntPtr[] { (IntPtr)inMap.W, (IntPtr)inMap.H, (IntPtr)1 }; //x, y, z IntPtr[] outRegionPtr = new IntPtr[] { (IntPtr)outMap.W, (IntPtr)outMap.H, (IntPtr)1 }; //x, y, z IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)outMap.W, (IntPtr)outMap.H, (IntPtr)1 }; Event clevent; //err = Cl.EnqueueWriteImage(_commandsQueue, inputMapBuffer, Bool.True, originPtr, inRegionPtr, (IntPtr)0, (IntPtr)0, inMap._buf, 0, null, out clevent); //clevent.Dispose(); //assert(err, "write input img"); // execute err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2, originPtr, workGroupSizePtr, null, 0, null, out clevent); clevent.Dispose(); assert(err, "Cl.EnqueueNDRangeKernel"); // sync Cl.Finish(_commandsQueue); // read from output memory object into actual buffer err = Cl.EnqueueReadImage(_commandsQueue, outputMapBuffer, Bool.True, originPtr, outRegionPtr, new IntPtr(outMap.Stride * sizeof(float)), (IntPtr)0, outMap._buf, 0, null, out clevent); clevent.Dispose(); assert(err, "read output buffer"); Cl.ReleaseMemObject(inputMapBuffer); Cl.ReleaseMemObject(outputMapBuffer); }
public Event EnqueueWriteImage(Image image, bool blocking, Ibasa.Numerics.Vector3ul origin, Ibasa.Numerics.Vector3ul region, ulong rowPitch, ulong slicePitch, IntPtr source, Event[] events) { ClHelper.ThrowNullException(Handle); if (image == Image.Null) { throw new ArgumentNullException("image"); } if (source == IntPtr.Zero) { throw new ArgumentNullException("source"); } unsafe { int num_events_in_wait_list = events == null ? 0 : events.Length; IntPtr *wait_list = stackalloc IntPtr[num_events_in_wait_list]; for (int i = 0; i < num_events_in_wait_list; ++i) { wait_list[i] = events[i].Handle; } if (events == null) { wait_list = null; } IntPtr event_ptr = IntPtr.Zero; UIntPtr *origin_ptr = stackalloc UIntPtr[3]; origin_ptr[0] = new UIntPtr(origin.X); origin_ptr[1] = new UIntPtr(origin.Y); origin_ptr[2] = new UIntPtr(origin.Z); UIntPtr *region_ptr = stackalloc UIntPtr[3]; region_ptr[0] = new UIntPtr(region.X); region_ptr[1] = new UIntPtr(region.Y); region_ptr[2] = new UIntPtr(region.Z); ClHelper.GetError(Cl.EnqueueReadImage(Handle, image.Handle, blocking ? 1u : 0u, origin_ptr, region_ptr, new UIntPtr(rowPitch), new UIntPtr(slicePitch), source.ToPointer(), (uint)num_events_in_wait_list, wait_list, &event_ptr)); return(new Event(event_ptr)); } }
public override Bitmap Plot() { ErrorCode error; using (Kernel kernel = CompileKernel("mandelbrot")) { Bitmap plotImg = new Bitmap(Width, Height); int intPtrSize = Marshal.SizeOf(typeof(IntPtr)); int uint4size = Marshal.SizeOf(typeof(uint4)); // Buffer do OpenCL para manter os dados da imagem OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); //// Obtém o buffer de pixels //BitmapData data = plotImg.LockBits(new Rectangle(0, 0, plotImg.Width, plotImg.Height), ImageLockMode.WriteOnly, plotImg.PixelFormat); //int depth = Bitmap.GetPixelFormatSize(data.PixelFormat) / 8; // Tamanho de cada pixel em memória, em bytes int depth = Bitmap.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8; int stride = 4 * ((Width * depth + 3) / 4); byte[] buffer = new byte[Height * stride]; // Cria o buffer para se trabalhar na imagem //Marshal.Copy(data.Scan0, buffer, 0, buffer.Length); // Copia as informações da imagem no buffer // Cria o buffer do OpenCL para a imagem Mem image2dbuffer = (Mem)Cl.CreateImage2D(context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat, (IntPtr)Width, (IntPtr)Height, (IntPtr)0, buffer, out error); CheckErr(error, "Cl.CreateImage2D"); // Passa os parametros para o kernel error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, image2dbuffer); CheckErr(error, "Cl.SetKernelArg imageBuffer"); uint4 startColorUi = new uint4(Colors.StartColor.B, Colors.StartColor.G, Colors.StartColor.R, Colors.StartColor.A); error = Cl.SetKernelArg(kernel, 1, (IntPtr)uint4size, startColorUi); CheckErr(error, "Cl.SetKernelArg startColor"); uint4 endColorUi = new uint4(Colors.EndColor.B, Colors.EndColor.G, Colors.EndColor.R, Colors.EndColor.A); error = Cl.SetKernelArg(kernel, 2, (IntPtr)uint4size, endColorUi); CheckErr(error, "Cl.SetKernelArg endColor"); error = Cl.SetKernelArg(kernel, 3, (IntPtr)sizeof(int), Iterations); CheckErr(error, "Cl.SetKernelArg iterations"); // Cria uma fila de comandos, com todos os comandos a serem executados pelo kernel CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, 0, out error); CheckErr(error, "Cl.CreateCommandQueue"); // Copia a imagem para a GPU Event clevent; IntPtr[] imgOriginPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] imgRegionPtr = new IntPtr[] { (IntPtr)Width, (IntPtr)Height, (IntPtr)1 }; //x, y, z error = Cl.EnqueueWriteImage(cmdQueue, image2dbuffer, Bool.True, imgOriginPtr, imgRegionPtr, (IntPtr)0, (IntPtr)0, buffer, 0, null, out clevent); CheckErr(error, "Cl.EnqueueWriteImage"); // Executa o Kernel carregado pelo OpenCL (com múltiplos processadores :D) IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)Width, (IntPtr)Height, (IntPtr)1 }; // x, y, z error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); // Espera terminar a execução error = Cl.Finish(cmdQueue); CheckErr(error, "Cl.Finish"); // Lê a imagem processada pela GPU e coloca novamente no buffer error = Cl.EnqueueReadImage(cmdQueue, image2dbuffer, Bool.True, imgOriginPtr, imgRegionPtr, (IntPtr)0, (IntPtr)0, buffer, 0, null, out clevent); CheckErr(error, "Cl.clEnqueueReadImage"); // Limpa a memória Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(image2dbuffer); // Get a pointer to our unmanaged output byte[] array //GCHandle pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); //IntPtr bmpPointer = pinnedBuffer.AddrOfPinnedObject(); BitmapData data = plotImg.LockBits(new Rectangle(0, 0, plotImg.Width, plotImg.Height), ImageLockMode.WriteOnly, plotImg.PixelFormat); Marshal.Copy(buffer, 0, data.Scan0, buffer.Length); // Copia as informações no buffer de volta à imagem plotImg.UnlockBits(data); // Libera a imagem //pinnedBuffer.Free(); return(plotImg); } }
public HTTPResponse GetResponse(HTTPRequest request) { HTTPResponse response = new HTTPResponse(200); StringBuilder sb = new StringBuilder(); ErrorCode error; if (!_isInit) { init(); _isInit = true; } if (request.Method == HTTPRequest.METHOD_GET) { // Input form, this can be place by any HTML page sb.Append("<html><body>"); sb.Append(GenUploadForm()); sb.Append("</body></html>"); response.Body = Encoding.UTF8.GetBytes(sb.ToString()); return(response); } else if (request.Method == HTTPRequest.METHOD_POST) { // Get remote image from URL string url = Uri.UnescapeDataString(request.GetRequestByKey("imageUploadUrl")); byte[] data; try { data = DownloadImageFromUrl(url); } catch (Exception) { return(new HTTPResponse(400)); } // https://www.codeproject.com/Articles/502829/GPGPU-image-processing-basics-using-OpenCL-NET // Convert image to bitmap binary Image inputImage = Image.FromStream(new MemoryStream(data)); if (inputImage == null) { return(new HTTPResponse(500)); } int imagewidth = inputImage.Width; int imageHeight = inputImage.Height; Bitmap bmpImage = new Bitmap(inputImage); BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int inputImageByteSize = bitmapData.Stride * bitmapData.Height; byte[] inputByteArray = new byte[inputImageByteSize]; Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImageByteSize); // Load kernel source code string programPath = System.Environment.CurrentDirectory + "/Kernel.cl"; if (!System.IO.File.Exists(programPath)) { return(new HTTPResponse(404)); } string programSource = System.IO.File.ReadAllText(programPath); using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { // Create kernel LogError(error, "Cl.CreateProgramWithSource"); error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); LogError(error, "Cl.BuildProgram"); if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <OpenCL.Net.BuildStatus>() != BuildStatus.Success) { LogError(error, "Cl.GetProgramBuildInfo"); return(new HTTPResponse(404)); } Kernel kernel = Cl.CreateKernel(program, _parameters["KernelFunction"], out error); LogError(error, "Cl.CreateKernel"); // Create image memory objects OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); IMem inputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, inputByteArray, out error); LogError(error, "CreateImage2D input"); byte[] outputByteArray = new byte[inputImageByteSize]; IMem outputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, outputByteArray, out error); LogError(error, "CreateImage2D output"); // Set arguments int IntPtrSize = Marshal.SizeOf(typeof(IntPtr)); error = Cl.SetKernelArg(kernel, 0, (IntPtr)IntPtrSize, inputImage2DBuffer); error |= Cl.SetKernelArg(kernel, 1, (IntPtr)IntPtrSize, outputImage2DBuffer); LogError(error, "Cl.SetKernelArg"); // Create command queue CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); LogError(error, "Cl.CreateCommandQueue"); Event clevent; // Copy input image from the host to the GPU IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] regionPtr = new IntPtr[] { (IntPtr)imagewidth, (IntPtr)imageHeight, (IntPtr)1 }; IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)imagewidth, (IntPtr)imageHeight, (IntPtr)1 }; error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent); LogError(error, "Cl.EnqueueWriteImage"); // Run the kernel error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); LogError(error, "Cl.EnqueueNDRangeKernel"); // Wait for finish event error = Cl.Finish(cmdQueue); LogError(error, "Cl.Finish"); // Read the output image back from GPU error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); LogError(error, "Cl.EnqueueReadImage"); error = Cl.Finish(cmdQueue); LogError(error, "Cl.Finih"); // Release memory Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); // Convert binary bitmap to JPEG image and return as response GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); Bitmap outputBitmap = new Bitmap(imagewidth, imageHeight, bitmapData.Stride, PixelFormat.Format32bppArgb, outputBmpPointer); MemoryStream msOutput = new MemoryStream(); outputBitmap.Save(msOutput, System.Drawing.Imaging.ImageFormat.Jpeg); response.Body = msOutput.ToArray(); response.Type = "image/jpeg"; return(response); } } return(new HTTPResponse(501)); }
public void ImagingTest(string inputImagePath, string outputImagePath) { ErrorCode error; //Load and compile kernel source code. string programPath = System.Environment.CurrentDirectory + "/../../imagingtest.cl"; //The path to the source file may vary if (!System.IO.File.Exists(programPath)) { Console.WriteLine("Program doesn't exist at path " + programPath); return; } string programSource = System.IO.File.ReadAllText(programPath); using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { CheckErr(error, "Cl.CreateProgramWithSource"); //Compile kernel source error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); CheckErr(error, "Cl.BuildProgram"); //Check for any compilation errors if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>() != BuildStatus.Success && 1 == 0) { CheckErr(error, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error)); return; } //Create the required kernel (entry function) Kernel kernel = Cl.CreateKernel(program, "imagingTest", out error); CheckErr(error, "Cl.CreateKernel"); int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); //Image's RGBA data converted to an unmanaged[] array byte[] inputByteArray; //OpenCL memory buffer that will keep our image's byte[] data. Mem inputImage2DBuffer; OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); int inputImgWidth, inputImgHeight; int inputImgBytesSize; int inputImgStride; //Try loading the input image using (FileStream imageFileStream = new FileStream(inputImagePath, FileMode.Open)) { System.Drawing.Image inputImage = System.Drawing.Image.FromStream(imageFileStream); if (inputImage == null) { Console.WriteLine("Unable to load input image"); return; } inputImgWidth = inputImage.Width; inputImgHeight = inputImage.Height; System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage); //Get raw pixel data of the bitmap //The format should match the format of clImageFormat BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);//inputImage.PixelFormat); inputImgStride = bitmapData.Stride; inputImgBytesSize = bitmapData.Stride * bitmapData.Height; //Copy the raw bitmap data to an unmanaged byte[] array inputByteArray = new byte[inputImgBytesSize]; Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImgBytesSize); //Allocate OpenCL image memory buffer inputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context, OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.ReadOnly, clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, inputByteArray, out error); CheckErr(error, "Cl.CreateImage2D input"); } //Unmanaged output image's raw RGBA byte[] array byte[] outputByteArray = new byte[inputImgBytesSize]; //Allocate OpenCL image memory buffer OpenCL.Net.Mem outputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context, OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.WriteOnly, clImageFormat, (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error); CheckErr(error, "Cl.CreateImage2D output"); //Pass the memory buffers to our kernel function error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, inputImage2DBuffer); error |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, outputImage2DBuffer); CheckErr(error, "Cl.SetKernelArg"); //Create a command queue, where all of the commands for execution will be added CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); CheckErr(error, "Cl.CreateCommandQueue"); OpenCL.Net.Event clevent; //Copy input image from the host to the GPU. IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] regionPtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent); CheckErr(error, "Cl.EnqueueWriteImage"); //Execute our kernel (OpenCL code) // CommandQueue q = new OpenCL.Net.CommandQueue(); //enqueue nd range kernel // error = cmdQueue.EnqueueKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); // OpenCL.Net.Cl.EnqueueNDRangeKernel( OpenCL.Net.Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); //Wait for completion of all calculations on the GPU. error = Cl.Finish(cmdQueue); CheckErr(error, "Cl.Finish"); //Read the processed image from GPU to raw RGBA data byte[] array error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); CheckErr(error, "Cl.clEnqueueReadImage"); //Clean up memory Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); //Get a pointer to our unmanaged output byte[] array GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); //Create a new bitmap with processed data and save it to a file. Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight, inputImgStride, PixelFormat.Format32bppArgb, outputBmpPointer); outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png); pinnedOutputArray.Free(); } }
protected void EnqueueReadImage(IMem targetMemory, byte[] destination, out ErrorCode error) { error = Cl.EnqueueReadImage(commandQueue, targetMemory, Bool.True, origin, globalWorkGroupSize, (IntPtr)0, (IntPtr)0, destination, 0, null, out Event clEvent); }
// copypasted/modified from Map2Bmp public Bitmap Map2BmpFauxColors(FloatMap inMap, float k) { var kernel = _kernels["mapToFauxColorsBmp"]; int w = inMap.W; int h = inMap.H; var clInImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.Luminance, ChannelType.Float); IMem inputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clInImageFormat, (IntPtr)w, (IntPtr)h, new IntPtr(inMap.Stride * sizeof(float)), inMap._buf, out err); assert(err, "input img creation"); var clOutImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); IMem outputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.WriteOnly, clOutImageFormat, (IntPtr)w, (IntPtr)h, (IntPtr)0, (IntPtr)0, out err); assert(err, "output img creation"); err = Cl.SetKernelArg(kernel, 0, intPtrSize, inputImage2DBuffer); assert(err, "input img setKernelArg"); err = Cl.SetKernelArg(kernel, 1, intPtrSize, outputImage2DBuffer); assert(err, "output img setKernelArg"); err = Cl.SetKernelArg(kernel, 2, floatSize, k); assert(err, "k setKernelArg"); Event clevent; //x, y, z IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] regionPtr = new IntPtr[] { (IntPtr)w, (IntPtr)h, (IntPtr)1 }; IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)w, (IntPtr)h, (IntPtr)1 }; //err = Cl.EnqueueWriteImage(_commandsQueue, inputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent); //assert(err, "Cl.EnqueueWriteImage"); //Execute kernel err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); clevent.Dispose(); assert(err, "Cl.EnqueueNDRangeKernel"); //Wait for completion err = Cl.Finish(_commandsQueue); assert(err, "Cl.Finish"); // get data back var outputByteArray = new byte[w * h * 4]; err = Cl.EnqueueReadImage(_commandsQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); clevent.Dispose(); assert(err, "read output buffer"); Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); var bmp = new Bitmap(w, h, w * 4, PixelFormat.Format32bppArgb, outputBmpPointer); pinnedOutputArray.Free(); return(bmp); }
public FloatMap Bmp2Map(Bitmap bmpImage) { var kernel = _kernels["getLumaImg"]; int w = bmpImage.Width; int h = bmpImage.Height; BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int inputImgStride = bitmapData.Stride; int inputImgBytesSize = bitmapData.Stride * bitmapData.Height; //Copy the raw bitmap data to an unmanaged byte[] array byte[] inputByteArray = new byte[inputImgBytesSize]; Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImgBytesSize); var clInImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); //Allocate OpenCL image memory buffer IMem inputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clInImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, inputByteArray, out err); assert(err, "input img creation"); var clOutImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.Luminance, ChannelType.Float); FloatMap outMap = new FloatMap(w, h); IMem outputMapBuffer = Cl.CreateImage2D(_context, MemFlags.WriteOnly, clOutImageFormat, (IntPtr)outMap.W, (IntPtr)outMap.H, new IntPtr(outMap.Stride * sizeof(float)), outMap._buf, out err); assert(err, "output img creation"); err = Cl.SetKernelArg(kernel, 0, intPtrSize, inputImage2DBuffer); assert(err, "input img setKernelArg"); err = Cl.SetKernelArg(kernel, 1, intPtrSize, outputMapBuffer); assert(err, "output img setKernelArg"); Event clevent; //Copy input image from the host to the GPU. IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] regionPtr = new IntPtr[] { (IntPtr)w, (IntPtr)h, (IntPtr)1 }; //x, y, z IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)w, (IntPtr)h, (IntPtr)1 }; //err = Cl.EnqueueWriteImage(_commandsQueue, inputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent); //assert(err, "Cl.EnqueueWriteImage"); //Execute our kernel (OpenCL code) err = Cl.EnqueueNDRangeKernel(_commandsQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); clevent.Dispose(); assert(err, "Cl.EnqueueNDRangeKernel"); //Wait for completion of all calculations on the GPU. err = Cl.Finish(_commandsQueue); assert(err, "Cl.Finish"); err = Cl.EnqueueReadImage(_commandsQueue, outputMapBuffer, Bool.True, originPtr, regionPtr, new IntPtr(outMap.Stride * sizeof(float)), (IntPtr)0, outMap._buf, 0, null, out clevent); clevent.Dispose(); assert(err, "read output buffer"); Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputMapBuffer); return(outMap); }
/* Broken at the moment. */ public void GetStatGPU(string file) { var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); stopwatch.Restart(); ErrorCode err; using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(clInfo._context, 1, new[] { clInfo.KernelSrc }, null, out err)) { clInfo.CheckErr(err, "Cl.CreateProgramWithSource"); //Compile Kernels & check errors. err = Cl.BuildProgram(program, 1, new[] { clInfo._device }, string.Empty, null, IntPtr.Zero); clInfo.CheckErr(err, "Cl.BuildProgram"); if (Cl.GetProgramBuildInfo(program, clInfo._device, ProgramBuildInfo.Status, out err).CastTo <BuildStatus>() != BuildStatus.Success) { clInfo.CheckErr(err, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, clInfo._device, ProgramBuildInfo.Log, out err)); } //Specify the specific kernel for use Kernel kernel = Cl.CreateKernel(program, "satAvg", out err); clInfo.CheckErr(err, "Cl.CreateKernel"); int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); IMem image2DBuffer; OpenCL.Net.ImageFormat imageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); int imageWidth, imageHeight, imageBytesSize, imageStride; using (FileStream imgStream = new FileStream(file, FileMode.Open)) { Image image = Image.FromStream(imgStream); if (image == null) { Console.Error.WriteLine($"failed to open file {file}"); return; } imageWidth = image.Width; imageHeight = image.Height; //Create a bitmap from the file with the correct channel settings. Bitmap inputBitmap = new Bitmap(image); BitmapData bitmapDat = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); imageStride = bitmapDat.Stride; imageBytesSize = imageStride * bitmapDat.Height; byte[] inputByteArray = new byte[imageBytesSize]; Marshal.Copy(bitmapDat.Scan0, inputByteArray, 0, imageBytesSize); //Create & populate memory buffer for use in Kernel image2DBuffer = Cl.CreateImage2D(clInfo._context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, imageFormat, (IntPtr)inputBitmap.Width, (IntPtr)inputBitmap.Height, (IntPtr)0, inputByteArray, out err); clInfo.CheckErr(err, "Cl.CreateImage2D output"); } //Create an output buffer for the average saturation of the image. float saturation = 0; IMem sat = Cl.CreateBuffer(clInfo._context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, (IntPtr)intPtrSize, (object)saturation, out err); clInfo.CheckErr(err, "Cl.CreateBuffer saturation"); //Passing buffers to the CL kernel err = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, image2DBuffer); //TODO: Figure out how to pass a float to the kernel //err |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, sat ); clInfo.CheckErr(err, "Cl.SetKernelArg"); //Create & queue commands CommandQueue cmdQueue = Cl.CreateCommandQueue(clInfo._context, clInfo._device, CommandQueueProperties.None, out err); clInfo.CheckErr(err, "Cl.CreateCommandQueue"); Event @event; //Transfer image data to kernel buffers IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] regionPtr = new IntPtr[] { (IntPtr)imageWidth, (IntPtr)imageHeight, (IntPtr)1 }; IntPtr[] workGroupPtr = new IntPtr[] { (IntPtr)imageWidth, (IntPtr)imageHeight, (IntPtr)1 }; err = Cl.EnqueueReadImage(cmdQueue, image2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, null, 0, null, out @event); clInfo.CheckErr(err, "Cl.EnqueueReadImage"); //Execute the kerenl err = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupPtr, null, 0, null, out @event); clInfo.CheckErr(err, "Cl.EnqueueNDRangeKernel"); err = Cl.Finish(cmdQueue); clInfo.CheckErr(err, "Cl.Finish"); Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(image2DBuffer); } Console.WriteLine(stopwatch.Elapsed); stopwatch.Stop(); }
public Bitmap GPUMandel(Bitmap inputBitmap) { ErrorCode error; //Load and compile kernel source code. string programPath = System.Environment.CurrentDirectory + "/../../program.cl"; //The path to the source file may vary if (!System.IO.File.Exists(programPath)) { Console.WriteLine("Program doesn't exist at path " + programPath); return(inputBitmap); } string programSource = System.IO.File.ReadAllText(programPath); using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { CheckErr(error, "Cl.CreateProgramWithSource"); //Compile kernel source error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); CheckErr(error, "Cl.BuildProgram"); //Check for any compilation errors if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>() != BuildStatus.Success) { CheckErr(error, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error)); return(inputBitmap); } //Create the required kernel (entry function) Kernel kernel = Cl.CreateKernel(program, "Mandelbrot", out error); CheckErr(error, "Cl.CreateKernel"); //Unmanaged output image's raw RGBA byte[] array BitmapData bitmapData = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int inputImgBytesSize = bitmapData.Stride * bitmapData.Height; int inputImgWidth = inputBitmap.Width; int inputImgHeight = inputBitmap.Height; int intPtrSize = Marshal.SizeOf(typeof(IntPtr)); OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); //OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Float); byte[] outputByteArray = new byte[inputImgBytesSize]; //Allocate OpenCL image memory buffer Mem outputImage2DBuffer = (Mem)Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat, (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error); CheckErr(error, "Cl.CreateImage2D output"); //Pass the memory buffers to our kernel function error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, outputImage2DBuffer); CheckErr(error, "Cl.SetKernelArg"); //Create a command queue, where all of the commands for execution will be added CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); CheckErr(error, "Cl.CreateCommandQueue"); Event clevent; //Copy input image from the host to the GPU. IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] regionPtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; error = Cl.EnqueueWriteImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); CheckErr(error, "Cl.EnqueueWriteImage"); //Execute our kernel (OpenCL code) error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); //Wait for completion of all calculations on the GPU. error = Cl.Finish(cmdQueue); CheckErr(error, "Cl.Finish"); //Read the processed image from GPU to raw RGBA data byte[] array error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); CheckErr(error, "Cl.clEnqueueReadImage"); //Clean up memory Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); //Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); //Get a pointer to our unmanaged output byte[] array GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); //Create a new bitmap with processed data and save it to a file. Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight, bitmapData.Stride, PixelFormat.Format32bppArgb, outputBmpPointer); return(outputBitmap); //outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png); //pinnedOutputArray.Free(); } }
public static void SubmitImage2DRead(ComputeImage2D img, object dest) { Cl.EnqueueReadImage(_queue, img.img, Bool.False, new[] { IntPtr.Zero, IntPtr.Zero, IntPtr.Zero }, new[] { (IntPtr)img.Width, (IntPtr)img.Height, (IntPtr)1 }, IntPtr.Zero, IntPtr.Zero, dest, 0, null, out var ign); }