使用c#和opencl时内存对象分配失败

使用c#和opencl时内存对象分配失败,c#,opencl,C#,Opencl,我正在写一个图像处理程序,目的是改变大图像,我正在处理的是8165像素乘4915像素。我被告知要实现gpu处理,所以经过一些研究后,我决定使用OpenCL。我开始实现OpenCLC#包装器OpenCLTemplate 我的代码接收位图并使用锁定位锁定其内存位置。然后,我将每个位的顺序复制到一个数组中,通过openCL内核运行该数组,并反转数组中的每个位。然后,我将反转的位运行回图像的内存位置。我把这个过程分成十个部分,这样我就可以增加一个进度条 我的代码可以很好地处理较小的映像,但是当我尝试使用

我正在写一个图像处理程序,目的是改变大图像,我正在处理的是8165像素乘4915像素。我被告知要实现gpu处理,所以经过一些研究后,我决定使用OpenCL。我开始实现OpenCLC#包装器OpenCLTemplate

我的代码接收位图并使用锁定位锁定其内存位置。然后,我将每个位的顺序复制到一个数组中,通过openCL内核运行该数组,并反转数组中的每个位。然后,我将反转的位运行回图像的内存位置。我把这个过程分成十个部分,这样我就可以增加一个进度条

我的代码可以很好地处理较小的映像,但是当我尝试使用较大的映像运行它时,在尝试执行内核时,我总是遇到一个MemoObjectAllocationFailure。我不知道它为什么要这样做,如果能帮我找出原因或如何修复它,我将不胜感激

    using OpenCLTemplate;

    public static void Invert(Bitmap image, ToolStripProgressBar progressBar)
    {
        string openCLInvert = @"
        __kernel void Filter(__global uchar *  Img0,
                             __global float *  ImgF)

        {
            // Gets information about work-item
            int x = get_global_id(0);
            int y = get_global_id(1);

            // Gets information about work size
            int width = get_global_size(0);
            int height = get_global_size(1);

            int ind = 4 * (x + width * y );

            // Inverts image colors
            ImgF[ind]= 255.0f - (float)Img0[ind];
            ImgF[1 + ind]= 255.0f - (float)Img0[1 + ind];
            ImgF[2 + ind]= 255.0f - (float)Img0[2 + ind];

            // Leave alpha component equal
            ImgF[ind + 3] = (float)Img0[ind + 3];
        }";

        //Lock the image in memory and get image lock data
        var imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

        CLCalc.InitCL();

        for (int i = 0; i < 10; i++)
        {
            unsafe
            {
                int adjustedHeight = (((i + 1) * imageData.Height) / 10) - ((i * imageData.Height) / 10);
                int count = 0;

                byte[] Data = new byte[(4 * imageData.Stride * adjustedHeight)];
                var startPointer = (byte*)imageData.Scan0;

                for (int y = ((i * imageData.Height) / 10); y < (((i + 1) * imageData.Height) / 10); y++)
                {
                    for (int x = 0; x < imageData.Width; x++)
                    {
                        byte* Byte = (byte*)(startPointer + (y * imageData.Stride) + (x * 4));

                        Data[count] = *Byte;
                        Data[count + 1] = *(Byte + 1);
                        Data[count + 2] = *(Byte + 2);
                        Data[count + 3] = *(Byte + 3);
                        count += 4;
                    }
                }

                CLCalc.Program.Compile(openCLInvert);
                CLCalc.Program.Kernel kernel = new CLCalc.Program.Kernel("Filter");
                CLCalc.Program.Variable CLData = new CLCalc.Program.Variable(Data);

                float[] imgProcessed = new float[Data.Length];

                CLCalc.Program.Variable CLFiltered = new CLCalc.Program.Variable(imgProcessed);
                CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLData, CLFiltered };

                kernel.Execute(args, new int[] { imageData.Width, adjustedHeight });
                CLCalc.Program.Sync();

                CLFiltered.ReadFromDeviceTo(imgProcessed);

                count = 0;

                for (int y = ((i * imageData.Height) / 10); y < (((i + 1) * imageData.Height) / 10); y++)
                {
                    for (int x = 0; x < imageData.Width; x++)
                    {
                        byte* Byte = (byte*)(startPointer + (y * imageData.Stride) + (x * 4));

                        *Byte = (byte)imgProcessed[count];
                        *(Byte + 1) = (byte)imgProcessed[count + 1];
                        *(Byte + 2) = (byte)imgProcessed[count + 2];
                        *(Byte + 3) = (byte)imgProcessed[count + 3];
                        count += 4;
                    }
                }
            }
            progressBar.Owner.Invoke((Action)progressBar.PerformStep);
        }

        //Unlock image
        image.UnlockBits(imageData);
    }
使用OpenCLTemplate;
公共静态无效反转(位图图像、ToolStripProgressBar progressBar)
{
字符串openCLInvert=@“
__内核无效筛选器(uu全局uchar*Img0,
__全局浮动*ImgF)
{
//获取有关工作项的信息
int x=获取全局id(0);
int y=获取全局id(1);
//获取有关工作大小的信息
int width=获取全局大小(0);
int height=获取全局大小(1);
int ind=4*(x+宽度*y);
//反转图像颜色
ImgF[ind]=255.0f-(浮点)Img0[ind];
ImgF[1+ind]=255.0f-(浮点)Img0[1+ind];
ImgF[2+ind]=255.0f-(浮点)Img0[2+ind];
//使α分量相等
ImgF[ind+3]=(float)Img0[ind+3];
}";
//将图像锁定在内存中并获取图像锁定数据
var imageData=image.LockBits(新矩形(0,0,image.Width,image.Height),ImageLockMode.ReadWrite,PixelFormat.Format32bppArgb);
CLCalc.InitCL();
对于(int i=0;i<10;i++)
{
不安全的
{
整数调整高度=((i+1)*imageData.Height)/10)-(i*imageData.Height)/10);
整数计数=0;
字节[]数据=新字节[(4*imageData.Stride*adjustedHeight)];
var startPointer=(字节*)imageData.Scan0;
对于(int y=((i*imageData.Height)/10);y<((i+1)*imageData.Height)/10);y++)
{
对于(int x=0;x
您可能已达到OpenCL驱动程序/设备的内存分配限制。检查返回的值。单个内存对象的大小有一个限制。OpenCL驱动程序可能允许所有分配内存对象的总大小超过设备上的内存大小,并在需要时将它们复制到主机内存或从主机内存复制

要处理较大的图像,您可能需要将它们分割为较小的部分,然后单独处理