Click here to Skip to main content
15,881,898 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have been developing a project. it is developed with C#, OpenCL.NET. Aforge, OpenCV.

I have a big problem. it is I can't release Memory on OpenCL.NET. I tried release() and dispose() but there weren't released.

So I need the method that can release Memory on OpenCL.NET.

I attached Code. I really need your help out.

the code about what tries to release memory is under the attached code.

C#
<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();
        }


What I have tried:

I tried web search and used dispose() and release().
Posted
Comments
[no name] 6-Oct-20 12:02pm    
Maybe the "components" are leaking. You need to do more "memory profiling" and maybe some try ... finally's.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900