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);
        }
Example #2
0
        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);
            }
        }
Example #4
0
        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));
        }
Example #5
0
        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();
            }
        }
Example #6
0
 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);
        }
Example #9
0
        /* 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();
        }
Example #10
0
    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();
        }
    }
Example #11
0
 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);
 }