Я не могу освободить память на 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
Может быть, "компоненты" протекают. Вам нужно сделать больше "профилирования памяти" и, возможно, некоторые попробуют ... наконец-то.