Member 12087553 Ответов: 0

Я не могу освободить память на opencl.net в C#


Я разрабатываю проект. он разработан с помощью C#, OpenCL.NET. Aforge, OpenCV.

У меня большая проблема. это я не могу освободить память на OpenCL.NET. Я попробовал release() и dispose (), но они не были выпущены.

Поэтому мне нужен метод, который может освободить память на OpenCL.NET.

Я приложил код. Мне действительно нужна твоя помощь.

код о том, что пытается освободить память, находится под прилагаемым кодом.

<pre>public void CalculateFeret(int CenterX, int CenterY, double[] XAxisArray, double[] YAxisArray, double[] AngleArray, ref double[] _WidthArray, ref double[] _HeightArray)
        {
            
            // Create and build a program from our OpenCL-C source code
            
            double[] WidthArray = new double[18];
            double[] HeightArray = new double[18];
            int AxisCount = XAxisArray.Length;

            string programSource = @"
            __kernel void doubleMe(__global int* CenterX, __global int* CenterY, __global double* XAxisArray, __global double* YAxisArray,
                                                                __global double* AngleArray, __global int* AxisCount, __global double* WidthArray, __global double* HeightArray)
            {
                size_t id = get_global_id(0);

                private int count;

                private double Xmin, Xmax;
                private double Ymin, Ymax;

                private int FindRectFirstTime;
                
                private double Width, Height;

                private double XAxisArraytmp[500];
                private double YAxisArraytmp[500];
            
                FindRectFirstTime = 1; 
                
                private double Y_Offsettmp1;
                private double Y_Offsettmp2;

                private double Y_Offset; 
                
                Y_Offsettmp1 = ((XAxisArray[count]) + 1 - (*CenterX)) * sin(AngleArray[id]) + ((YAxisArray[count] + 1) - (*CenterY)) * cos(AngleArray[id]) + (*CenterY); 
                Y_Offsettmp2 = ((XAxisArray[count]) + 2 - (*CenterX)) * sin(AngleArray[id]) + ((YAxisArray[count] + 2) - (*CenterY)) * cos(AngleArray[id]) + (*CenterY); 
                Y_Offset = Y_Offsettmp2 - Y_Offsettmp1;
                if(Y_Offset < 0) Y_Offset *= -1;

                for(count = 0; count < (*AxisCount); count++)
                {
                    XAxisArraytmp[count] = (XAxisArray[count] - (*CenterX)) * cos(AngleArray[id]) - (YAxisArray[count] - (*CenterY)) * sin(AngleArray[id]) + (*CenterX); 
                    YAxisArraytmp[count] = (XAxisArray[count] - (*CenterX)) * sin(AngleArray[id]) + (YAxisArray[count] - (*CenterY)) * cos(AngleArray[id]) + (*CenterY); 
                }          

                for(count = 0; count < (*AxisCount); count++)
                {
                    if (FindRectFirstTime == 1)
                    {
                        Xmin = XAxisArraytmp[count];
                        Xmax = XAxisArraytmp[count];
                        Ymin = YAxisArraytmp[count];
                        Ymax = YAxisArraytmp[count];

                        FindRectFirstTime = 0;
                    }
                    else
                    {
                        if (Xmin > XAxisArraytmp[count]) Xmin = XAxisArraytmp[count];
                        if (Xmax < XAxisArraytmp[count]) Xmax = XAxisArraytmp[count];
                        if (Ymin > YAxisArraytmp[count]) Ymin = YAxisArraytmp[count];
                        if (Ymax < YAxisArraytmp[count]) Ymax = YAxisArraytmp[count];
                    }
                }

                if (Xmin >= 0 && Xmax >= 0) WidthArray[id] = Xmax - Xmin + Y_Offset;
                else if (Xmin < 0 && Xmax < 0) WidthArray[id] = (Xmax * (-1)) - (Xmin * (-1)) + Y_Offset;
                else if (Xmin < 0 && Xmax > 0) WidthArray[id] = Xmax + (Xmin * (-1)) + Y_Offset;

                if (Ymin >= 0 && Ymax >= 0) HeightArray[id] = Ymax - Ymin + Y_Offset;
                else if (Ymin < 0 && Ymax < 0) HeightArray[id] = (Ymax * (-1)) - (Ymin * (-1)) + Y_Offset;
                else if (Ymin < 0 && Ymax > 0) HeightArray[id] = Ymax + (Ymin * (-1)) + Y_Offset;
                
            };";


            Program program = Cl.CreateProgramWithSource(context, 1, new[] { programSource }, null, out err);
            Cl.BuildProgram(program, 0, null, string.Empty, null, IntPtr.Zero);  //"-cl-mad-enable"

            // Check for any compilation errors
            if (Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out err).CastTo<BuildStatus>() != BuildStatus.Success)
            {
                if (err != ErrorCode.Success)
                    Console.WriteLine("ERROR: " + "Cl.GetProgramBuildInfo" + " (" + err.ToString() + ")");
                Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                Console.WriteLine(Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Log, out err));
            }
            
            // Create a kernel from our program
            Kernel kernel = Cl.CreateKernel(program, "doubleMe", out err);
            //메모리 할당 영역
            //중간에 I는 Input을 의미하며 O는 Output을 의미함
            //Input Parameter의 메모리를 할당
            Mem CenterXIMem = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly, sizeof(int), out err);
            Mem CenterYIMem = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly, sizeof(int), out err);

            Mem XAxisArraytmpIMem = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly, sizeof(double) * XAxisArray.Length, out err);
            Mem YAxisArraytmpIMem = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly, sizeof(double) * YAxisArray.Length, out err);

            Mem AngleArrayIMem = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly, sizeof(double) * AngleArray.Length, out err);

            Mem AxisCountMem = (Mem)Cl.CreateBuffer(context, MemFlags.ReadOnly, sizeof(int), out err);
            
            Cl.EnqueueWriteBuffer(cmdQueue, (IMem)CenterXIMem, Bool.True, IntPtr.Zero, new IntPtr(sizeof(int)), CenterX, 0, null, out event0);
            Cl.EnqueueWriteBuffer(cmdQueue, (IMem)CenterYIMem, Bool.True, IntPtr.Zero, new IntPtr(sizeof(int)), CenterY, 0, null, out event0);

            Cl.EnqueueWriteBuffer(cmdQueue, (IMem)XAxisArraytmpIMem, Bool.True, IntPtr.Zero, new IntPtr(sizeof(double) * XAxisArray.Length), XAxisArray, 0, null, out event0);
            Cl.EnqueueWriteBuffer(cmdQueue, (IMem)YAxisArraytmpIMem, Bool.True, IntPtr.Zero, new IntPtr(sizeof(double) * YAxisArray.Length), YAxisArray, 0, null, out event0);

            Cl.EnqueueWriteBuffer(cmdQueue, (IMem)AngleArrayIMem, Bool.True, IntPtr.Zero, new IntPtr(sizeof(double) * AngleArray.Length), AngleArray, 0, null, out event0);

            Cl.EnqueueWriteBuffer(cmdQueue, (IMem)AxisCountMem, Bool.True, IntPtr.Zero, new IntPtr(sizeof(int)), AxisCount, 0, null, out event0);
            //Output Parameter의 메모리를 할당
            Mem WidthArrayOMem = (Mem)Cl.CreateBuffer(context, MemFlags.WriteOnly, sizeof(double) * WidthArray.Length, out err);
            Mem HeightArrayOMem = (Mem)Cl.CreateBuffer(context, MemFlags.WriteOnly, sizeof(double) * HeightArray.Length, out err);
            
            IntPtr notused;
            InfoBuffer local = new InfoBuffer(new IntPtr(4));
            Cl.GetKernelWorkGroupInfo(kernel, device, KernelWorkGroupInfo.WorkGroupSize, new IntPtr(sizeof(int)), local, out notused);
            //Queue를 통해 Kernel에 메모리를 전달
            Cl.SetKernelArg(kernel, 0, new IntPtr(4), CenterXIMem);
            Cl.SetKernelArg(kernel, 1, new IntPtr(4), CenterYIMem);
            Cl.SetKernelArg(kernel, 2, new IntPtr(4), XAxisArraytmpIMem);
            Cl.SetKernelArg(kernel, 3, new IntPtr(4), YAxisArraytmpIMem);
            Cl.SetKernelArg(kernel, 4, new IntPtr(4), AngleArrayIMem);
            Cl.SetKernelArg(kernel, 5, new IntPtr(4), AxisCountMem);

            Cl.SetKernelArg(kernel, 6, new IntPtr(4), WidthArrayOMem);
            Cl.SetKernelArg(kernel, 7, new IntPtr(4), HeightArrayOMem);

            IntPtr[] workGroupSizePtr = new IntPtr[] { new IntPtr(AngleArray.Length) };
            Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, workGroupSizePtr, null, 0, null, out event0);
            
            Cl.Finish(cmdQueue);
            //Output 메모리를 Read하는 부분
            Cl.EnqueueReadBuffer(cmdQueue, (IMem)WidthArrayOMem, Bool.True, IntPtr.Zero, new IntPtr(WidthArray.Length * sizeof(double)), WidthArray, 0, null, out event0);
            Cl.EnqueueReadBuffer(cmdQueue, (IMem)HeightArrayOMem, Bool.True, IntPtr.Zero, new IntPtr(HeightArray.Length * sizeof(double)), HeightArray, 0, null, out event0);

            //Read한 데이터를 복사하는 부분
            Array.Copy(WidthArray, _WidthArray, WidthArray.Length);
            Array.Copy(HeightArray, _HeightArray, HeightArray.Length);

            //모든 메모리를 해제하는 부분
            CenterXIMem.Release();
            CenterYIMem.Release();
            XAxisArraytmpIMem.Release();
            YAxisArraytmpIMem.Release();
            AngleArrayIMem.Release();
            AxisCountMem.Release();

            WidthArrayOMem.Release();
            HeightArrayOMem.Release();

            program.Release();
            kernel.Release();
        }


Что я уже пробовал:

Я попробовал веб-поиск и использовал dispose() и release().

Gerry Schmitz

Может быть, "компоненты" протекают. Вам нужно сделать больше "профилирования памяти" и, возможно, некоторые попробуют ... наконец-то.

0 Ответов