private CLCalc.Program.Variable CLCalcVertexDisplacement(float[] ObjVertex, float[] ObjDisplacement) { CLCalc.Program.Variable variable1 = new CLCalc.Program.Variable(ObjVertex); CLCalc.Program.Variable variable2 = new CLCalc.Program.Variable(ObjDisplacement); CLCalc.Program.Variable variable3 = new CLCalc.Program.Variable(ObjVertex); float[] numArray = new float[9]; CLCalc.Program.Variable variable4 = new CLCalc.Program.Variable(numArray); int[] GlobalWorkSize = new int[1] { ObjVertex.Length }; if ((double)ObjDisplacement[3] != 0.0 || (double)ObjDisplacement[4] != 0.0 || (double)ObjDisplacement[5] != 0.0) { this.CalcRotMatrix(numArray, ObjDisplacement); variable4.WriteToDevice(numArray); this.kernelCalcRotacoes.Execute((CLCalc.Program.MemoryObject[]) new CLCalc.Program.Variable[3] { variable4, variable1, variable3 }, GlobalWorkSize); } this.kernelCalcTransl.Execute((CLCalc.Program.MemoryObject[]) new CLCalc.Program.Variable[2] { variable2, variable3 }, GlobalWorkSize); return(variable3); }
private void MassaMola(CLCalc.Program.Variable x, CLCalc.Program.Variable y, CLCalc.Program.Variable dydx) { CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[3] { x, y, dydx }; KernelDerivs.Execute(args, nMassas); }
/// <summary>Finds minimum E[i] in SVM and returns corresponding i (returns arg min E[i])</summary> /// <param name="svm">SVM to check</param> private static int CLFindMinError(SVM svm) { CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { svm.CLerr, svm.CLErrLen, svm.CLMaxMinErrs, svm.CLMaxMinInds }; lock (CLResource) { //Majority of Minimums kernelMinErr.Execute(args, MAXMINWORKSIZE); //Computes values args = new CLCalc.Program.Variable[] { svm.CLMaxMinErrs, svm.CLMaxMinInds }; int i = MAXMINWORKSIZE >> 1; while (i > 0) { kernelComputeMin.Execute(args, i); i = (i >> 1); } //Retrieves index args = new CLCalc.Program.Variable[] { svm.CLMaxMinInds, svm.CLResp }; kernelGetResp.Execute(args, 1); svm.CLResp.ReadFromDeviceTo(svm.HostResp); } return(svm.HostResp[0]); }
public bool DetectCollisions(CollisionDetector.CollisionObject Obj1, CollisionDetector.CollisionObject Obj2) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLCalc.Program.Variable variable1 = this.CLCalcVertexDisplacement(Obj1.Vertex, Obj1.Displacement); CLCalc.Program.Variable variable2 = this.CLCalcVertexDisplacement(Obj2.Vertex, Obj2.Displacement); int[] Values = new int[1]; CLCalc.Program.Variable variable3 = new CLCalc.Program.Variable(Values); CLCalc.Program.Variable variable4 = new CLCalc.Program.Variable(Obj1.Triangle); CLCalc.Program.Variable variable5 = new CLCalc.Program.Variable(Obj2.Triangle); int[] GlobalWorkSize = new int[2] { Obj1.Triangle.Length / 3, Obj2.Triangle.Length / 3 }; this.kernelCalcExactCollision.Execute((CLCalc.Program.MemoryObject[]) new CLCalc.Program.Variable[5] { variable1, variable4, variable2, variable5, variable3 }, GlobalWorkSize); variable3.ReadFromDeviceTo(Values); return(Values[0] > 0); } else { float[] Obj1Vertexes = this.CalcVertexDisplacement(Obj1.Vertex, Obj1.Displacement); float[] Obj2Vertexes = this.CalcVertexDisplacement(Obj2.Vertex, Obj2.Displacement); int[] numCollisions = new int[1]; this.CalcExactCollision(Obj1Vertexes, Obj1.Triangle, Obj2Vertexes, Obj2.Triangle, numCollisions); return(numCollisions[0] > 0); } }
/// <summary>Computes frame difference</summary> private void ComputeFrameDiff() { //Needs both images to compute if (CLBmp == null || CLBmpPrev == null || CLBmp.Width != CLBmpPrev.Width || CLBmp.Height != CLBmpPrev.Height) { return; } if (frameDiff == null || frameDiff.Length != ((CLBmp.Height * CLBmp.Width) >> 6)) { //Reduces image size by 8 frameDiff = new byte[(CLBmp.Height * CLBmp.Width) >> 6]; CLframeDiff = new CLCalc.Program.Variable(frameDiff); MovingRegionBoxes = new List <int>(); } CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { CLBmp, CLBmpPrev, CLframeDiff }; kernelComputeFrameDiff.Execute(args, new int[] { CLBmp.Width >> 3, CLBmp.Height >> 3 }); CLframeDiff.ReadFromDeviceTo(frameDiff); MovingRegionBoxes.Clear(); BracketMovingRegions(frameDiff, CLBmp.Width >> 3, CLBmp.Height >> 3, MovingRegionBoxes); }
private static int[] ExecuteStepDpq(Polynomial x, Polynomial y) { if (x.Degree != y.Degree) { throw new InvalidOperationException("Only works for polynomials of same degree!"); } var d = Math.Min(x.Degree, y.Degree); var n = d + 1; var dpq = new int[n * n]; CLCalc.InitCL(); CLCalc.Program.Compile(new[] { KernelCodeStepDpq }); var kernel = new CLCalc.Program.Kernel("StepDpq"); var nCl = new CLCalc.Program.Variable(new[] { n }); var xCl = new CLCalc.Program.Variable(x.Coefficients); var yCl = new CLCalc.Program.Variable(y.Coefficients); var dpqCl = new CLCalc.Program.Variable(dpq); CLCalc.Program.MemoryObject[] args = { nCl, xCl, yCl, dpqCl }; var workers = new[] { 2 * n - 2 }; kernel.Execute(args, workers); dpqCl.ReadFromDeviceTo(dpq); return(dpq); }
private void button6_Click(object sender, EventArgs e) { float[] x = new float[] { 0 }; float[] y = new float[] { 0 }; CLCalc.InitCL(); if (!string.IsNullOrWhiteSpace(textBox1.Text) && !string.IsNullOrWhiteSpace(textBox2.Text)) { x[0] = (float)Convert.ToDouble(textBox1.Text.Replace('.', ',')); y[0] = (float)Convert.ToDouble(textBox2.Text.Replace('.', ',')); } string s = @" __kernel void sum(global float4 *x, global float4 *y) { x[0] = x[0] + y[0]; }"; CLCalc.Program.Compile(new string[] { s }); CLCalc.Program.Kernel sum = new CLCalc.Program.Kernel("sum"); CLCalc.Program.Variable varx = new CLCalc.Program.Variable(x); CLCalc.Program.Variable vary = new CLCalc.Program.Variable(y); CLCalc.Program.Variable[] args = { varx, vary }; int[] max = new int[] { 1 }; sum.Execute(args, max); varx.ReadFromDeviceTo(x); textBox3.Text = Convert.ToString(x[0]); }
/// <summary>Calculates isosurface corresponding to a given isolevel</summary> /// <param name="isoLvl"></param> public void CalcIsoSurface(float isoLvl) { //Copies iso level to video memory if (isoLvl != isoLevel[0]) { isoLevel[0] = isoLvl; varIsoLevel.WriteToDevice(isoLevel); } //Interpolation CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLFuncVals, varIsoLevel, varEdgeCoords, varInitVals, varStep }; kernelInterpPts.Execute(args, max); if (ComputeNormals) { //Polygonization args = new CLCalc.Program.Variable[] { CLFuncVals, varIsoLevel, varEdgeCoords, varEdgePrelimNormals, varElemIndex }; int[] GlobalWorkSize = new int[] { max[0] - 1, max[1] - 1, max[2] - 1 }; kernelPolygonize.Execute(args, GlobalWorkSize); //Normal smoothing args = new CLCalc.Program.Variable[] { varEdgePrelimNormals, varEdgeNormals }; kernelSmoothNormals.Execute(args, max); } else { //Polygonization args = new CLCalc.Program.Variable[] { CLFuncVals, varIsoLevel, varEdgeCoords, varElemIndex }; int[] GlobalWorkSize = new int[] { max[0] - 1, max[1] - 1, max[2] - 1 }; kernelPolygonizeNoNormals.Execute(args, GlobalWorkSize); } }
/// <summary>Computes the Discrete Fourier Transform of a double2 vector x whose length is a power of 4. /// x = { Re[x0] Im[x0] Re[x1] Im[x1] ... Re[xn] Im[xn] }, n = power of 4 (Length = 2*pow(4,n))</summary> public static CLCalc.Program.Variable FFT4(ref CLCalc.Program.Variable CLx) { if (CLy == null || CLy.OriginalVarLength != CLx.OriginalVarLength) { CLy = new CLCalc.Program.Variable(new float[CLx.OriginalVarLength]); } if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL) { return(null); } int nn = (int)Math.Log(CLx.OriginalVarLength >> 1, 4); nn = 1 << ((nn << 1) + 1); if (nn != CLx.OriginalVarLength) { throw new Exception("Number of elements should be a power of 4 ( vector length should be 2*pow(4,n) )"); } if (kernelfft_radix4 == null) { InitKernels(); } CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLx, CLy, CLp }; CLCalc.Program.Variable[] args2 = new CLCalc.Program.Variable[] { CLy, CLx, CLp }; bool usar2 = true; int[] p = new int[] { 1 }; CLp.WriteToDevice(p); int n = CLx.OriginalVarLength >> 3; while (p[0] <= n) { usar2 = !usar2; if (usar2) { kernelfft_radix4.Execute(args2, n); } else { kernelfft_radix4.Execute(args, n); } p[0] = p[0] << 2; CLp.WriteToDevice(p); } if (usar2) { CLCalc.Program.Variable temp = CLx; CLx = CLy; CLy = temp; } return(CLy); }
/// <summary>Classifies multiple samples stored in OpenCL memory</summary> /// <param name="Samples">Samples data to classify</param> /// <param name="svm">SVM to use as classifier</param> public static float[] MultiClassify(SVM svm, CLCalc.Program.Image2D Samples) { float[] resp = new float[Samples.Height]; //svm.WriteToDevice(); if ((Samples.Width << 2) != svm.HostVLen[0]) { throw new Exception("Invalid Samples width, should be the same length of training features"); } if (svm.CLKernelValuesMultiClassify == null || svm.CLKernelValuesMultiClassify.OriginalVarLength != svm.alphaList.Count * Samples.Height) { svm.CLKernelValuesMultiClassify = new CLCalc.Program.Variable(new float[svm.alphaList.Count * Samples.Height]); } if (svm.CLAlphas == null || svm.CLAlphas.OriginalVarLength != svm.alphaList.Count) { svm.CLAlphas = new CLCalc.Program.Variable(svm.alphaList.ToArray()); float[] ys = new float[svm.TrainingSet.trainingArray.Count]; for (int i = 0; i < ys.Length; i++) { ys[i] = svm.TrainingSet.trainingArray[i].y; } svm.CLys = new CLCalc.Program.Variable(ys); } if (svm.CLb == null) { svm.CLb = new CLCalc.Program.Variable(new float[] { svm.b }); svm.CLQtdSupVecs = new CLCalc.Program.Variable(new int[] { svm.alphaList.Count }); CLMultiClassifSums = new CLCalc.Program.Variable(new float[Samples.Height]); } if (CLMultiClassifSums.OriginalVarLength != Samples.Height) { CLMultiClassifSums = new CLCalc.Program.Variable(new float[Samples.Height]); } //svm.CLAlphas.WriteToDevice(svm.alphaList.ToArray()); //svm.CLys.WriteToDevice(ys); //svm.CLb.WriteToDevice(new float[] { svm.b }); //svm.CLQtdSupVecs.WriteToDevice(new int[] { svm.alphaList.Count }); CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { svm.CLTrainingFeatures, svm.CLQtdSupVecs, svm.CLXVecLen, Samples, svm.CLKernelValuesMultiClassify, svm.CLLambda }; kernelComputeMultiKernelRBF.Execute(args, new int[] { svm.alphaList.Count, Samples.Height }); CLCalc.Program.Sync(); args = new CLCalc.Program.MemoryObject[] { svm.CLAlphas, svm.CLQtdSupVecs, svm.CLXVecLen, svm.CLys, svm.CLKernelValuesMultiClassify, svm.CLb, CLMultiClassifSums }; kernelSumKernels.Execute(args, Samples.Height); CLMultiClassifSums.ReadFromDeviceTo(resp); return(resp); }
/// <summary>Compiles code and initializes kernel for this svm stance</summary> private void CLSVMInit() { if (CLResource == null) { CLResource = new int[0]; } lock (CLResource) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { CLCalc.InitCL(); } if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { if (kernelComputeKernelRBF == null) { CLSVMSrc s = new CLSVMSrc(); CLCalc.Program.Compile(new string[] { s.srcKernels, s.srcFindMaxMinErr, s.srcMultClass }); //Kernel computation kernelComputeKernelRBF = new CLCalc.Program.Kernel("ComputeKernelRBF"); kernelMaxErr = new CLCalc.Program.Kernel("maxErr"); kernelComputeMax = new CLCalc.Program.Kernel("computeMax"); kernelMinErr = new CLCalc.Program.Kernel("minErr"); kernelComputeMin = new CLCalc.Program.Kernel("computeMin"); kernelGetResp = new CLCalc.Program.Kernel("getResp"); //Update error kernelUpdateErr = new CLCalc.Program.Kernel("UpdateErr"); //Multiple classification kernelComputeMultiKernelRBF = new CLCalc.Program.Kernel("ComputeMultiKernelRBF"); kernelSumKernels = new CLCalc.Program.Kernel("SumKernels"); } //Memory obbjects //Find max/min CLErrLen = new CLCalc.Program.Variable(new int[1]); HostResp = new int[1]; CLResp = new CLCalc.Program.Variable(HostResp); CLMaxMinErrs = new CLCalc.Program.Variable(new float[MAXMINWORKSIZE]); CLMaxMinInds = new CLCalc.Program.Variable(new int[MAXMINWORKSIZE]); //Update error CLUpdtErrParams = new CLCalc.Program.Variable(new float[3]); } } }
public int[] VertexCollision(float[] v1, float[] displacement1, float[] v2, float[] displacement2, float CollisionDistance, out float[] VertexDistances) { if ((double)CollisionDistance < 0.0) { throw new Exception("Collision distance should be positive"); } int[] numArray1 = new int[v1.Length / 3]; VertexDistances = new float[v1.Length / 3]; for (int index = 0; index < numArray1.Length; ++index) { numArray1[index] = -1; VertexDistances[index] = -1f; } float[] numArray2 = new float[1] { CollisionDistance }; if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL && (long)v1.Length * (long)v2.Length > 10000000L) { CLCalc.Program.Variable variable1 = this.CLCalcVertexDisplacement(v1, displacement1); CLCalc.Program.Variable variable2 = this.CLCalcVertexDisplacement(v2, displacement2); CLCalc.Program.Variable variable3 = new CLCalc.Program.Variable(numArray2); CLCalc.Program.Variable variable4 = new CLCalc.Program.Variable(numArray1); CLCalc.Program.Variable variable5 = new CLCalc.Program.Variable(VertexDistances); this.kernelCalcVertexCollision.Execute((CLCalc.Program.MemoryObject[]) new CLCalc.Program.Variable[5] { variable3, variable1, variable2, variable4, variable5 }, new int[2] { v1.Length / 3, v2.Length / 3 }); variable4.ReadFromDeviceTo(numArray1); variable5.ReadFromDeviceTo(VertexDistances); } else { float[] v1_1 = this.CalcVertexDisplacement(v1, displacement1); float[] v2_1 = this.CalcVertexDisplacement(v2, displacement2); this.CalcVertexCollisions(numArray2, v1_1, v2_1, numArray1, VertexDistances); } return(numArray1); }
/// <summary>Computes the Discrete Fourier Transform of a double2 vector x whose length is a power of 16. /// x = { Re[x0] Im[x0] Re[x1] Im[x1] ... Re[xn] Im[xn] }, n = power of 16 (Length = 2*pow(16,n))</summary> public static double[] FFT16(double[] x) { if (CLx == null || CLx.OriginalVarLength != x.Length) { CLx = new CLCalc.Program.Variable(x); CLy = new CLCalc.Program.Variable(x); } //Writes original content CLx.WriteToDevice(x); CLy = FFT16(ref CLx); double[] y = new double[x.Length]; CLy.ReadFromDeviceTo(y); return y; }
public Kernels(CLCalc.Program.Image2D CLGLRenderImage) { this.CLimg = CLGLRenderImage; dimensions = new int[CLimg.Width * CLimg.Height]; for (int y = 0; y < CLimg.Height; y++) { CLY.VarSize += 100; } for (int x = 0; x < CLimg.Width; x++) { CLX.VarSize += dimensions[CLimg.Height - 1 + CLimg.Height * x]; CLZ.VarSize += dimensions[CLimg.Height * x] = 240; } CLDimensions = new CLCalc.Program.Variable(dimensions); }
private static void InitKernels() { string s = new CLFFTSrc().s; CLCalc.InitCL(); try { CLCalc.Program.Compile(s); } catch { } kernelfft_radix16 = new CLCalc.Program.Kernel("fft_radix16"); kernelfft_radix4 = new CLCalc.Program.Kernel("fft_radix4"); kernelConjugate = new CLCalc.Program.Kernel("Conjugate"); CLp = new CLCalc.Program.Variable(new int[1]); }
/// <summary>ImageData constructor. Reads data from a bitmap</summary> /// <param name="bmp">Bitmap to read from</param> public ImageData(Bitmap bmp) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { CLCalc.InitCL(); } width = bmp.Width; height = bmp.Height; //Allocates space for data Data = new byte[3 * width * height]; //Reads bmp to local Data variable ReadToLocalData(bmp); //Transfer data to OpenCL device varData = new CLCalc.Program.Variable(Data); }
/// <summary>Computes the inverse Discrete Fourier Transform of a double2 vector x whose length is a power of 16. /// x = { Re[x0] Im[x0] Re[x1] Im[x1] ... Re[xn] Im[xn] }, n = power of 16 (Length = 2*pow(16,n))</summary> public static double[] iFFT16(double[] x) { if (CLx == null || CLx.OriginalVarLength != x.Length) { CLx = new CLCalc.Program.Variable(x); CLy = new CLCalc.Program.Variable(x); } //Writes original content CLx.WriteToDevice(x); CLy = iFFT16(CLx); double[] y = new double[x.Length]; CLy.ReadFromDeviceTo(y); return(y); }
/// <summary>Computes the Discrete Fourier Transform of a float2 vector x whose length is a power of 16. /// x = { Re[x0] Im[x0] Re[x1] Im[x1] ... Re[xn] Im[xn] }, n = power of 16 (Length = 2*pow(16,n))</summary> public static float[] FFT16(float[] x) { if (CLx == null || CLx.OriginalVarLength != x.Length) { CLx = new CLCalc.Program.Variable(x); CLy = new CLCalc.Program.Variable(x); } //Writes original content CLx.WriteToDevice(x); CLy = FFT16(ref CLx); float[] y = new float[x.Length]; CLy.ReadFromDeviceTo(y); return(y); }
/// <summary>Computes the Discrete Fourier Transform of a double2 vector x whose length is a power of 16. /// x = { Re[x0] Im[x0] Re[x1] Im[x1] ... Re[xn] Im[xn] }, n = power of 16 (Length = 2*pow(16,n))</summary> public static CLCalc.Program.Variable FFT16(ref CLCalc.Program.Variable CLx) { if (CLy == null || CLy.OriginalVarLength != CLx.OriginalVarLength) CLy = new CLCalc.Program.Variable(new float[CLx.OriginalVarLength]); if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL) return null; int nn = (int)Math.Log(CLx.OriginalVarLength >> 1, 16); nn = 1 << ((nn << 2) + 1); if (nn != CLx.OriginalVarLength) throw new Exception("Number of elements should be a power of 16 ( vector length should be 2*pow(16,n) )"); if (kernelfft_radix16 == null) { InitKernels(); } CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLx, CLy, CLp }; CLCalc.Program.Variable[] args2 = new CLCalc.Program.Variable[] { CLy, CLx, CLp }; bool usar2 = true; int[] p = new int[] { 1 }; CLp.WriteToDevice(p); int n = CLx.OriginalVarLength >> 5; while (p[0] <= n) { usar2 = !usar2; if (usar2) kernelfft_radix16.Execute(args2, n); else kernelfft_radix16.Execute(args, n); p[0] = p[0] << 4; CLp.WriteToDevice(p); } if (usar2) { CLCalc.Program.Variable temp = CLx; CLx = CLy; CLy = temp; } return CLy; }
/// <summary>Initialize kernels</summary> private void InitKernels() { if (kernelComputeHistograms == null || CLN == null) { CLSrc src = new CLSrc(); CLCalc.Program.Compile(src.src); kernelComputeHistograms = new CLCalc.Program.Kernel("ComputeHistogram"); kernelConsolidateHist = new CLCalc.Program.Kernel("ConsolidateHist"); kernelPerformNormalization = new CLCalc.Program.Kernel("PerformNormalization"); kernelComputeHue = new CLCalc.Program.Kernel("ComputeHue"); CLN = new CLCalc.Program.Variable(new int[] { NLumIntens }); CLWidth = new CLCalc.Program.Variable(new int[] { bmp.Width }); CLHeight = new CLCalc.Program.Variable(new int[] { bmp.Height }); CLbmp = new CLCalc.Program.Image2D(bmp); CLNewBmp = new CLCalc.Program.Image2D(bmp); } }
public void Initialize(BaseCameraApplication app) { try { CLCalc.Program.Compile(app.GetPrimaryDevice().GetPreprocessCode() + src); } catch (BuildProgramFailureComputeException ex) { System.Console.WriteLine(ex.Message); Environment.Exit(1); } int width = app.GetPrimaryDevice().GetDepthImage().Width; int height = app.GetPrimaryDevice().GetDepthImage().Height; pointBuffer = CLCalc.Program.Variable.Create(new ComputeBuffer<float>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, points = new float[width * height * 4])); colorBuffer = CLCalc.Program.Variable.Create(new ComputeBuffer<float>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, colors = new float[width * height * 4])); kernelCopyImage = new CLCalc.Program.Kernel("CopyToPoinCloud"); }
private void button3_Click(object sender, EventArgs e) { float[] x = new float[] { 1, 2, 3, 0.123f }; float[] y = new float[] { 1, 2, 1, 1 }; string s = @" kernel void sum (global float4 * x, global float4 * y) { x[0] = x[0] + y[0]; } "; CLCalc.Program.Compile(new string[] { s }); CLCalc.Program.Kernel sum = new CLCalc.Program.Kernel("sum"); CLCalc.Program.Variable varx = new CLCalc.Program.Variable(x); CLCalc.Program.Variable vary = new CLCalc.Program.Variable(y); CLCalc.Program.Variable[] args = { varx, vary }; int[] max = new int[] { 1 }; sum.Execute(args, max); varx.ReadFromDeviceTo(x); //float[] t = new float[1] { 0 }; //float[] pos = new float[] { 1, 2, 3, 4, 5, 6 }; //float[] vel = new float[] { 1, 0, 0, 0, 0, 0 }; //float[] forces = new float[] { 0, 1, 0, 0, 0, 0 }; //float[] masses = new float[] { 1, 1 }; //float[] colSizes = new float[] { 0.1f, 0.1f }; //CLCalc.InitCL(); //CLCalc.CLPrograms.floatBodyPhysics phys = new CLCalc.CLPrograms.floatBodyPhysics(10); //CLCalc.CLPrograms.floatBodyPhysics phys2 = new CLCalc.CLPrograms.floatBodyPhysics(20); //CLCalc.FinishCL(); }
private static void GPU() { string vecSum = @" __kernel void floatVectorSum(__global float * v1, __global float * v2) { // Vector element index int i = get_global_id(0); v1[i] = v1[i] + v2[i]; }"; //Initializes OpenCL Platforms and Devices and sets everything up CLCalc.InitCL(); //Compiles the source codes. The source is a string array because the user may want //to split the source into many strings. CLCalc.Program.Compile(new string[] { vecSum }); //Gets host access to the OpenCL floatVectorSum kernel CLCalc.Program.Kernel VectorSum = new CLCalc.Program.Kernel("floatVectorSum"); //We want to sum 2000 numbers int n = 20000000; //Create vectors with 2000 numbers float[] v1 = new float[n], v2 = new float[n]; //Creates population for v1 and v2 for (int i = 0; i < n; i++) { v1[i] = (float)i / 10; v2[i] = -(float)i / 8; } //Creates vectors v1 and v2 in the device memory CLCalc.Program.Variable varV1 = new CLCalc.Program.Variable(v1); CLCalc.Program.Variable varV2 = new CLCalc.Program.Variable(v2); //Arguments of VectorSum kernel CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { varV1, varV2 }; //How many workers will there be? We need "n", one for each element //int[] workers = new int[1] { n }; //Execute the kernel VectorSum.Execute(args, 20000000); //Read device memory varV1 to host memory v1 varV1.ReadFromDeviceTo(v1); }
private void button1_Click(object sender, EventArgs e) { CLCalc.InitCL(); double[] a = new double[] { 2, 147483647, 2, 7 }; double[] b = new double[] { 1, 2, 7, 4 }; double[] c = new double[4]; CLCalc.Program.Variable v1 = new CLCalc.Program.Variable(a); CLCalc.Program.Variable v2 = new CLCalc.Program.Variable(b); CLCalc.Program.Variable v3 = new CLCalc.Program.Variable(c); CLCalc.CLPrograms.VectorSum VecSum = new CLCalc.CLPrograms.VectorSum(); CLCalc.CLPrograms.MinDifs Mdifs = new CLCalc.CLPrograms.MinDifs(); //string[] s = new string[] { VecSum.intVectorSum, VecSum.floatVectorSum }; string[] s = new string[] { VecSum.doubleVectorSum }; CLCalc.Program.Compile(s); CLCalc.Program.Kernel k = new CLCalc.Program.Kernel("doubleVectorSum"); //CLCalc.Program.Kernel k2 = new CLCalc.Program.Kernel("intVectorSum"); //CLCalc.Program.Kernel k = new CLCalc.Program.Kernel("floatMinDifs"); CLCalc.Program.Variable[] vv = new CLCalc.Program.Variable[3] { v1, v2, v3 }; int[] max = new int[1] { a.Length }; k.Execute(vv, max); CLCalc.Program.Sync(); v3.ReadFromDeviceTo(c); CLCalc.FinishCL(); }
/// <summary>Constructor.</summary> public SparseLinalg() { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { try { CLCalc.InitCL(); } catch { } } if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { //Creates control variables dprod = new float[SparseLinalg.GLOBALWORKSIZE]; dotProd = new CLCalc.Program.Variable(dprod); dotProdSum = new CLCalc.Program.Variable(new float[1]); int[] i = new int[1]; vLenBy4 = new CLCalc.Program.Variable(i); CLNonZeroElemsPerRow = new CLCalc.Program.Variable(new int[1]); } }
public void DoubleSumTest() { string text = File.ReadAllText("Examples/SumTest.cl"); CLCalc.InitCL(); CLCalc.Program.Compile(new string[] { text }); int count = 2000; var a = new double[count]; var b = new double[count]; var ab = new double[count]; for (int i = 0; i < count; i++) { a[i] = i / 10.0; b[i] = -i / 9.0; } using (CLCalc.Program.Kernel Kernel = new CLCalc.Program.Kernel("doubleVectorSum")) { using (CLCalc.Program.Variable varA = new CLCalc.Program.Variable(a), varB = new CLCalc.Program.Variable(b)) { var args = new CLCalc.Program.Variable[] { varA, varB }; var workers = new int[1] { count }; Kernel.Execute(args, workers); varA.ReadFromDeviceTo(ab); } } for (int i = 0; i < count; i++) { Assert.AreEqual(-i / 90.0, ab[i], 1E-13); } }
/// <summary>Computes the inverse Discrete Fourier Transform of a double2 vector x whose length is a power of 16. /// x = { Re[x0] Im[x0] Re[x1] Im[x1] ... Re[xn] Im[xn] }, n = power of 16 (Length = 2*pow(16,n))</summary> public static CLCalc.Program.Variable iFFT16(CLCalc.Program.Variable CLx) { if (CLScale == null) { CLScale = new CLCalc.Program.Variable(new double[1]); } //Trick: DFT-1 (x) = DFT(x*)*/N; //Conjugate double[] vx = new double[CLx.OriginalVarLength]; CLx.ReadFromDeviceTo(vx); double[] scale = new double[] { 1 }; CLScale.WriteToDevice(scale); kernelConjugate.Execute(new CLCalc.Program.Variable[] { CLx, CLScale }, CLx.OriginalVarLength >> 1); CLx.ReadFromDeviceTo(vx); CLy = FFT16(ref CLx); scale[0] = 1 / (double)(CLx.OriginalVarLength >> 1); CLScale.WriteToDevice(scale); kernelConjugate.Execute(new CLCalc.Program.Variable[] { CLy, CLScale }, CLy.OriginalVarLength >> 1); return(CLy); }
public static Polynomial MultiplyKaratsubaOpenCl(Polynomial x, Polynomial y) { if (x.Degree != y.Degree) { throw new InvalidOperationException("Only works for polynomials of same degree!"); } var d = Math.Min(x.Degree, y.Degree); var n = d + 1; var di = ExecuteStepDi(x, y); var dpq = ExecuteStepDpq(x, y); var z = new int[2 * n - 1]; z[0] = di[0]; z[2 * n - 2] = di[n - 1]; CLCalc.InitCL(); CLCalc.Program.Compile(new[] { KernelCodeStepKaratsuba }); var kernel = new CLCalc.Program.Kernel("StepKaratsuba"); var nCl = new CLCalc.Program.Variable(new[] { n }); var xCl = new CLCalc.Program.Variable(x.Coefficients); var yCl = new CLCalc.Program.Variable(y.Coefficients); var diCl = new CLCalc.Program.Variable(di); var dpqCl = new CLCalc.Program.Variable(dpq); var zCl = new CLCalc.Program.Variable(z); CLCalc.Program.MemoryObject[] args = { nCl, xCl, yCl, diCl, dpqCl, zCl }; var workers = new[] { 2 * n - 3 }; kernel.Execute(args, workers); zCl.ReadFromDeviceTo(z); return(new Polynomial(z)); }
/// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL /// if not using OpenCL/GL interop.</summary> /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param> /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param> private void InitMarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) CLCalc.InitCL(); if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { //Reads maximum lengths int maxX = FuncValues.GetLength(0); int maxY = FuncValues.GetLength(1); int maxZ = FuncValues.GetLength(2); max = new int[] { maxX, maxY, maxZ }; #region Creating variables //Isolevel isoLevel = new float[1] { 1.32746E-5f }; varIsoLevel = new CLCalc.Program.Variable(isoLevel); //Step size and x0,y0,z0 varStep = new CLCalc.Program.Variable(step); varInitVals = new CLCalc.Program.Variable(initVals); //Create and copy function values funcVals = new float[maxX * maxY * maxZ]; CLFuncVals = new CLCalc.Program.Variable(funcVals); SetFuncVals(FuncValues); //Edge coordinates - 3 coords * 3 possible directions * number of points edgeCoords = new float[9 * maxX * maxY * maxZ]; if (CLEdgeCoords != null) { varEdgeCoords = CLEdgeCoords; varEdgeCoords.WriteToDevice(edgeCoords); } else varEdgeCoords = new CLCalc.Program.Variable(edgeCoords); //4 preliminary normals per edge - has to be averaged afterwards edgePrelimNormals = new float[36 * maxX * maxY * maxZ]; varEdgePrelimNormals = new CLCalc.Program.Variable(edgePrelimNormals); //Edge normals edgeNormals = new float[9 * maxX * maxY * maxZ]; if (CLEdgeNormals != null) { varEdgeNormals = CLEdgeNormals; varEdgeNormals.WriteToDevice(edgeNormals); } else varEdgeNormals = new CLCalc.Program.Variable(edgeNormals); //Number of cubes: (maxX-1)*(maxY-1)*(maxZ-1) //Marching cube algorithm: each cube can have 5 triangles drawn, 3 vertexes per triangle //q-th vertex of p-th triangle of the ijk-th cube: [(5*(i+(maxX-1)*j+k*(maxX-1)*(maxY-1))+p)*3+q] elementIndex = new int[5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)]; if (CLElementArrayIndex != null) { varElemIndex = CLElementArrayIndex; varElemIndex.WriteToDevice(elementIndex); } else varElemIndex = new CLCalc.Program.Variable(elementIndex); //Edge remapping to build output edges = new int[edgeCoords.Length / 3]; for (int i = 0; i < edges.Length; i++) edges[i] = -1; #endregion #region Compile code and create kernels CLMarchingCubesSrc cmsrc = new CLMarchingCubesSrc(); CLCalc.Program.Compile(new string[] { cmsrc.definitions, cmsrc.src }); kernelInterpPts = new CLCalc.Program.Kernel("interpPts"); kernelPolygonize = new CLCalc.Program.Kernel("Polygonize"); kernelSmoothNormals = new CLCalc.Program.Kernel("SmoothNormals"); kernelPolygonizeNoNormals = new CLCalc.Program.Kernel("PolygonizeNoNormals"); #endregion } else throw new Exception("OpenCL not available"); }
/// <summary>Calculates isosurface corresponding to a given isolevel</summary> /// <param name="isoLvl"></param> public void CalcIsoSurface(float isoLvl) { //Copies iso level to video memory if (isoLvl != isoLevel[0]) { isoLevel[0] = isoLvl; varIsoLevel.WriteToDevice(isoLevel); } //Interpolation CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLFuncVals, varIsoLevel, varEdgeCoords, varInitVals, varStep }; kernelInterpPts.Execute(args, max); if (ComputeNormals) { //Polygonization args = new CLCalc.Program.Variable[] { CLFuncVals, varIsoLevel, varEdgeCoords, varEdgePrelimNormals, varElemIndex }; int[] GlobalWorkSize = new int[] { max[0] - 1, max[1] - 1, max[2] - 1 }; kernelPolygonize.Execute(args, GlobalWorkSize); //Normal smoothing args = new CLCalc.Program.Variable[] { varEdgePrelimNormals, varEdgeNormals }; kernelSmoothNormals.Execute(args, max); } else { //Polygonization args = new CLCalc.Program.Variable[] { CLFuncVals, varIsoLevel, varEdgeCoords, varElemIndex }; int[] GlobalWorkSize = new int[] { max[0] - 1, max[1] - 1, max[2] - 1 }; kernelPolygonizeNoNormals.Execute(args, GlobalWorkSize); } }
public ImageColorMixer(int xpos, int ypos, int width, int height) { this.xpos = xpos; this.ypos = ypos; this.width = width; this.height = height; this.scrollWidth = width / 2 - 40; this.controlXpos = xpos + scrollWidth + 40; hueScroll = new ImageScrollButton("Hue", xpos, ypos, scrollWidth, 20, 0, 1.0f); saturationScroll = new ImageScrollButton("Saturation", xpos, ypos + 30, scrollWidth, 20, 0, 1.0f); valueScroll = new ImageScrollButton("Brightness", xpos, ypos + 60, scrollWidth, 20, 0, 1.0f); hueImage = new CLCalc.Program.Image2D(hueBuffer = new float[scrollWidth * 4], scrollWidth, 1); saturationImage = new CLCalc.Program.Image2D(saturationBuffer = new float[scrollWidth * 4], scrollWidth, 1); valueImage = new CLCalc.Program.Image2D(valueBuffer = new float[scrollWidth * 4], scrollWidth, 1); mixedImage = new CLCalc.Program.Image2D(mixedBuffer = new float[scrollWidth * 4], scrollWidth, 1); controlColors = CLCalc.Program.Variable.Create(new ComputeBuffer<float>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite, controlColorsBuffer = new float[4 * NUM_CONTROL_PTS])); controlAmps = CLCalc.Program.Variable.Create(new ComputeBuffer<float>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite, controlAmpsBuffer = new float[NUM_CONTROL_PTS])); hueScroll.sliderTrack.SetDynamicImage(hueImage); saturationScroll.sliderTrack.SetDynamicImage(saturationImage); valueScroll.sliderTrack.SetDynamicImage(valueImage); mixedColor = new ImageButton("Mixture", false, controlXpos, ypos + 90, scrollWidth, 20); chosenColor = new ImageButton("Chosen", false, xpos, ypos + 90, scrollWidth, 20); mixedColor.SetDynamicImage(mixedImage); controlPoints = new ImageButton[NUM_CONTROL_PTS]; stems = new ImageButton[NUM_CONTROL_PTS]; controlPointsBorder = new ImageButton[NUM_CONTROL_PTS]; Bitmap bitmap = new Bitmap(20, 20); using (Graphics gfx = Graphics.FromImage(bitmap)) { gfx.Clear(Color.FromArgb(0, 0, 0, 0)); gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; gfx.FillEllipse(new SolidBrush(Color.White), 1, 1, 17, 17); } hueScroll.SetValue(0.1f); valueScroll.SetValue(0.5f); saturationScroll.SetValue(0.5f); float4 currentColor = HSVtoRGB(new float4(hueScroll.GetValue(), saturationScroll.GetValue(), valueScroll.GetValue(), 1.0f)); colorIndex = NUM_CONTROL_PTS / 2; for (int i = 0; i < NUM_CONTROL_PTS; i++) { controlPoints[i] = new ImageButton("control_" + i, bitmap, true, (int)(controlXpos + (i + 0.5f) * (scrollWidth) / (float)NUM_CONTROL_PTS), ypos + ((i == colorIndex) ? 50 : 70), 20, 20); controlPointsBorder[i] = new ImageButton("control_" + i, new Bitmap(20, 20), false, (int)(controlXpos + i * (scrollWidth) / (float)NUM_CONTROL_PTS), ypos + 70, 20, 20); controlPoints[i].SetDragAndDrop(true); controlPoints[i].SetDragBoundingBox(controlXpos - 10, ypos, controlXpos + scrollWidth - 10, ypos + 70); stems[i] = new ImageButton("stem_" + i, false, (int)(controlXpos + i * (scrollWidth) / (float)NUM_CONTROL_PTS), 90, 2, 20); stems[i].SetBackgroundColor(Color4.White); controlPoints[i].SetForegroundColor(HSVtoRGB(new float4(i / (float)(NUM_CONTROL_PTS), saturationScroll.GetValue(), valueScroll.GetValue(), 1.0f))); UpdateControlPoint(i); controlPoints[i].AddObserver(this); } }
/// <summary>Specific function when SVM contains only one object, such as faces</summary> /// <param name="bmp">Next frame to process</param> public List<int> FindSingleObj(Bitmap bmp) { //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(), sw2 = new System.Diagnostics.Stopwatch(); //sw.Start(); if (SVM == null) return null; if (imgWidth != bmp.Width || imgHeight != bmp.Height) { imgWidth = bmp.Width; imgHeight = bmp.Height; SubFramePos = 0; List<int> subFrames = new List<int>(); ComputeSubFrames(0, 0, bmp.Width, bmp.Height, subFrames); SubFrames = subFrames.ToArray(); SubFeatures = new float[(SubFrames.Length / 3) * 364]; if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLSubFrames = new CLCalc.Program.Variable(SubFrames); CLSubFeatures = new CLCalc.Program.Image2D(SubFeatures, 91, SubFrames.Length / 3); CLBmp = new CLCalc.Program.Image2D(bmp); //CLBmpTemp = new CLCalc.Program.Image2D(bmp); CLBmpPrev = new CLCalc.Program.Image2D(bmp); } } //Swaps current and previous bitmap pointers CLCalc.Program.Image2D temp = CLBmp; CLBmp = CLBmpPrev; CLBmpPrev = temp; //Computes frame difference ComputeFrameDiff(); //Replaces subFrames based on moving regions for (int k = 0; k < MovingRegionBoxes.Count >> 2; k++) { List<int> sframes = new List<int>(); int ind = 4 * k; ComputeSubFrames(MovingRegionBoxes[ind] << 3, MovingRegionBoxes[ind + 2] << 3, MovingRegionBoxes[ind + 1] << 3, MovingRegionBoxes[ind + 3] << 3, sframes); for (int p = 0; p < sframes.Count; p += 3) { SubFrames[SubFramePos] = sframes[p]; SubFrames[SubFramePos + 1] = sframes[p + 1]; SubFrames[SubFramePos + 2] = sframes[p + 2]; SubFramePos += 3; if (SubFramePos > SubFrames.Length - 1) SubFramePos = 0; } } CLSubFrames.WriteToDevice(SubFrames); CLBmp.WriteBitmap(bmp); ////Segments skin //kernelSegregateSkin.Execute(new CLCalc.Program.MemoryObject[] { CLBmpTemp, CLBmp }, new int[] { bmp.Width, bmp.Height }); //Extract features using OpenCL CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { CLSubFrames, CLSubFeatures, CLBmp }; kernelExtractFeatures.Execute(args, SubFrames.Length / 3); #region No OpenCL //float[] testSubFeats = new float[364 * (SubFrames.Length / 3)]; //CLSubFeatures.ReadFromDeviceTo(testSubFeats); //Extract features without OpenCL //ExtractFeatures(SubFrames, SubFeatures, bmp); //CLSubFeatures.WriteToDevice(SubFeatures); #endregion //sw2.Start(); float[] maxvals = OpenCLTemplate.MachineLearning.SVM.MultiClassify(SVM.SVMs[0], CLSubFeatures); //SVM.Classify(CLSubFeatures, out maxvals); //sw2.Stop(); List<int> FacesPos = new List<int>(); List<float> MaxVals = new List<float>(); //Goes in decreasing window size order for (int kk = Config.WINDOWSIZES.Length - 1; kk >= 0; kk--) { for (int i = maxvals.Length - 1; i >= 0; i--) { if (SubFrames[3 * i + 2] == Config.WINDOWSIZES[kk] && maxvals[i] > Config.REQCERTAINTY) { //Checks if a face already has been found in that region bool contido = false; int i3 = 3 * i; int kmax = FacesPos.Count / 3; for (int k = 0; k < kmax; k++) { int k3 = 3 * k; if ( (FacesPos[k3] <= SubFrames[i3] && SubFrames[i3] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] && SubFrames[i3 + 1] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) || (FacesPos[k3] <= SubFrames[i3] + SubFrames[i3 + 2] && SubFrames[i3] + SubFrames[i3 + 2] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] + SubFrames[i3 + 2] && SubFrames[i3 + 1] + SubFrames[i3 + 2] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) || (FacesPos[k3] <= SubFrames[i3] && SubFrames[i3] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] + SubFrames[i3 + 2] && SubFrames[i3 + 1] + SubFrames[i3 + 2] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) || (FacesPos[k3] <= SubFrames[i3] + SubFrames[i3 + 2] && SubFrames[i3] + SubFrames[i3 + 2] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] && SubFrames[i3 + 1] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) ) { contido = true; //Replaces if better if (maxvals[i] > MaxVals[k] && SubFrames[3 * i + 2] == FacesPos[3 * k + 2]) { FacesPos[k3] = SubFrames[i3]; FacesPos[k3 + 1] = SubFrames[i3 + 1]; FacesPos[k3 + 2] = SubFrames[i3 + 2]; MaxVals[k] = maxvals[i]; } k = FacesPos.Count; } } if (!contido) { FacesPos.Add(SubFrames[3 * i]); FacesPos.Add(SubFrames[3 * i + 1]); FacesPos.Add(SubFrames[3 * i + 2]); MaxVals.Add(maxvals[i]); } } } } //sw.Stop(); Random rnd = new Random(); //Updates frame search region if (MovingRegionBoxes.Count > 0) { for (int i = 0; i < maxvals.Length; i++) { if (maxvals[i] > Config.REFINEUNCERTAINTY) { int i3 = 3 * i; List<int> sframes = new List<int>(); int cx = SubFrames[i3] + (SubFrames[i3 + 2] >> 1) + rnd.Next(7) - 3; int cy = SubFrames[i3 + 1] + (SubFrames[i3 + 2] >> 1) + rnd.Next(7) - 3; int bigwSize = Config.WINDOWSIZES[Config.WINDOWSIZES.Length - 1]; try { ComputeSubFrames(cx - (bigwSize >> 1), cy - (bigwSize >> 1), cx + (bigwSize >> 1), cy + (bigwSize >> 1), sframes); for (int p = 0; p < sframes.Count; p += 3) { SubFrames[SubFramePos] = sframes[p]; SubFrames[SubFramePos + 1] = sframes[p + 1]; SubFrames[SubFramePos + 2] = sframes[p + 2]; SubFramePos += 3; if (SubFramePos > SubFrames.Length - 1) SubFramePos = 0; } } catch { } } } } return FacesPos; }
public void Initialize(BaseCameraApplication capture) { DepthCameraFrame depthImage = capture.GetPrimaryDevice().GetDepthImage(); this.width = depthImage.Width; this.height = depthImage.Height; this.filter = ((AdaptiveTemporalFilter)capture.GetImageFilter()); CvSize sz = new CvSize(depthImage.Width, depthImage.Height); gray = new IplImage(sz, BitDepth.U8, 1); erode = new IplImage(sz, BitDepth.U8, 1); dilate = new IplImage(sz, BitDepth.U8, 1); tmp = new IplImage(sz, BitDepth.U8, 1); mask = new IplImage(sz, BitDepth.U8, 1); imgLabel = new IplImage(sz, BitDepth.F32, 1); faceDetectionBuffer = CLCalc.Program.Variable.Create(new ComputeBuffer<FaceLandmarks>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite, 1)); try { CLCalc.Program.Compile(capture.GetPrimaryDevice().GetPreprocessCode() + src); } catch (BuildProgramFailureComputeException ex) { System.Console.WriteLine(ex.Message); Environment.Exit(1); } irImageBuffer = CLCalc.Program.Variable.Create(new ComputeBuffer<byte>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, ir = new byte[width * height])); kernelCopyIRImage = new CLCalc.Program.Kernel("CopyIRImage"); kernelFindFaceLandmarks = new CLCalc.Program.Kernel("FindFaceLandmarks"); }
/// <summary>Creates the diagonal matrix D(v) with elements associated to those of vector v. Uses the same objects.</summary> /// <param name="v">Reference vector</param> public floatDiag(floatVector v) { nRows = v.Length; nCols = v.Length; this.Values = v.Values; this.CLValues = v.CLValues; }
/// <summary>Compiles code and initializes kernel for this svm stance</summary> private void CLSVMInit() { if (CLResource == null) CLResource = new int[0]; lock (CLResource) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) CLCalc.InitCL(); if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { if (kernelComputeKernelRBF == null) { CLSVMSrc s = new CLSVMSrc(); CLCalc.Program.Compile(new string[] { s.srcKernels, s.srcFindMaxMinErr, s.srcMultClass }); //Kernel computation kernelComputeKernelRBF = new CLCalc.Program.Kernel("ComputeKernelRBF"); kernelMaxErr = new CLCalc.Program.Kernel("maxErr"); kernelComputeMax = new CLCalc.Program.Kernel("computeMax"); kernelMinErr = new CLCalc.Program.Kernel("minErr"); kernelComputeMin = new CLCalc.Program.Kernel("computeMin"); kernelGetResp = new CLCalc.Program.Kernel("getResp"); //Update error kernelUpdateErr = new CLCalc.Program.Kernel("UpdateErr"); //Multiple classification kernelComputeMultiKernelRBF = new CLCalc.Program.Kernel("ComputeMultiKernelRBF"); kernelSumKernels=new CLCalc.Program.Kernel("SumKernels"); } //Memory obbjects //Find max/min CLErrLen = new CLCalc.Program.Variable(new int[1]); HostResp = new int[1]; CLResp = new CLCalc.Program.Variable(HostResp); CLMaxMinErrs = new CLCalc.Program.Variable(new float[MAXMINWORKSIZE]); CLMaxMinInds = new CLCalc.Program.Variable(new int[MAXMINWORKSIZE]); //Update error CLUpdtErrParams = new CLCalc.Program.Variable(new float[3]); } } }
/// <summary>Creates vector from M elements sequentially</summary> /// <param name="symM">Symmetric matrix to use</param> public floatVector(floatSymPosDefMatrix symM) { this.CLValues = symM.CLValues; this.Values = symM.Values; //Since I'm probably going to modify the matrix, I want a new Cholesky factorization //if I ever call a LinearSolve symM.IsCholeskyFactorized = false; if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLCoef = new CLCalc.Program.Variable(new float[1]); } }
private void LocalInitCL() { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) CLCalc.InitCL(); if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLoffSet = new CLCalc.Program.Variable(new int[1]); CLValues = new CLCalc.Program.Variable(this.Values); invL11 = new float[(SUBMATRIXSIZE * (SUBMATRIXSIZE + 1)) >> 1]; CLinvl11 = new CLCalc.Program.Variable(invL11); int NMultiple = N; if (N % SUBMATRIXSIZE != 0) { NMultiple = N / SUBMATRIXSIZE; NMultiple = SUBMATRIXSIZE * (NMultiple + 1); cholDec = new float[(NMultiple * (NMultiple + 1)) >> 1]; for (int i = 0; i < Values.Length; i++) cholDec[i] = Values[i]; } else { cholDec = (float[])this.Values.Clone(); } CLcholDec = new CLCalc.Program.Variable(cholDec); CLprevVals = new CLCalc.Program.Variable(new float[N]); CLb = new CLCalc.Program.Variable(new float[N]); CLy = new CLCalc.Program.Variable(new float[N]); CLn = new CLCalc.Program.Variable(new int[] { N }); } }
private void linsolveCL(floatVector CLbb, ref floatVector resp) { if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL) { linsolve(CLbb.Values, ref resp); return; } //int NMultiple = N; ////float[] bAugm; //if (N % SUBMATRIXSIZE != 0) //{ // NMultiple = N / SUBMATRIXSIZE; // NMultiple = SUBMATRIXSIZE * (NMultiple + 1); //} ////bAugm = new float[NMultiple]; ////for (int i = 0; i < bb.Length; i++) bAugm[i] = bb[i]; if (resp == null) resp = new floatVector(new float[N]); //Copy elements to CLb if (CLb == null || CLb.OriginalVarLength < CLbb.Length) CLb = new CLCalc.Program.Variable(CLbb.Values); kernelCopyBuffer.Execute(new CLCalc.Program.MemoryObject[] { CLbb.CLValues, CLb }, CLbb.Length); CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLcholDec, CLy, CLb, CLoffSet, CLn }; int[] offset = new int[1]; //float[] yDebug = new float[N]; //float[] bDebug = new float[N]; //Forward substitution int i; for (i = 0; i < N; i += SUBMATRIXSIZE) { offset[0] = i; CLoffSet.WriteToDevice(offset); int size = Math.Min(SUBMATRIXSIZE, N - i); kernelFwdUpperBackSubs.Execute(args, new int[] { size }, new int[] { size }); ////DEBUG //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); //propagation if (i + SUBMATRIXSIZE < N) { kernelFwdPropag.Execute(args, N - i - SUBMATRIXSIZE); } ////DEBUG //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); //CLcholDec.ReadFromDeviceTo(cholDec); } //Backward subst. Stores answer in CLb args = new CLCalc.Program.Variable[] { CLcholDec, CLb, CLy, CLoffSet, CLn }; //Backward substitution for (i = N - SUBMATRIXSIZE; i >= 0; i -= SUBMATRIXSIZE) { offset[0] = i; CLoffSet.WriteToDevice(offset); int size = SUBMATRIXSIZE; kernelBkLowerBackSubs.Execute(args, new int[] { size }, new int[] { size }); ////DEBUG //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); if (i > 0) { kernelBackPropag.Execute(args, i); } //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); } if (SUBMATRIXSIZE + i > 0) { offset[0] = 0; CLoffSet.WriteToDevice(offset); kernelBkLowerBackSubs.Execute(args, new int[] { SUBMATRIXSIZE + i }, new int[] { SUBMATRIXSIZE + i }); } //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); kernelCopyBuffer.Execute(new CLCalc.Program.Variable[] { CLb, resp.CLValues }, N); }
/// <summary>Classifies multiple samples stored in OpenCL memory</summary> /// <param name="Samples">Samples data to classify</param> /// <param name="svm">SVM to use as classifier</param> public static float[] MultiClassify(SVM svm, CLCalc.Program.Image2D Samples) { float[] resp = new float[Samples.Height]; //svm.WriteToDevice(); if ((Samples.Width << 2) != svm.HostVLen[0]) throw new Exception("Invalid Samples width, should be the same length of training features"); if (svm.CLKernelValuesMultiClassify == null || svm.CLKernelValuesMultiClassify.OriginalVarLength != svm.alphaList.Count * Samples.Height) { svm.CLKernelValuesMultiClassify = new CLCalc.Program.Variable(new float[svm.alphaList.Count * Samples.Height]); } if (svm.CLAlphas == null || svm.CLAlphas.OriginalVarLength != svm.alphaList.Count) { svm.CLAlphas = new CLCalc.Program.Variable(svm.alphaList.ToArray()); float[] ys = new float[svm.TrainingSet.trainingArray.Count]; for (int i = 0; i < ys.Length; i++) ys[i] = svm.TrainingSet.trainingArray[i].y; svm.CLys = new CLCalc.Program.Variable(ys); } if (svm.CLb==null) { svm.CLb = new CLCalc.Program.Variable(new float[] { svm.b }); svm.CLQtdSupVecs = new CLCalc.Program.Variable(new int[] { svm.alphaList.Count }); CLMultiClassifSums = new CLCalc.Program.Variable(new float[Samples.Height]); } if (CLMultiClassifSums.OriginalVarLength != Samples.Height) { CLMultiClassifSums = new CLCalc.Program.Variable(new float[Samples.Height]); } //svm.CLAlphas.WriteToDevice(svm.alphaList.ToArray()); //svm.CLys.WriteToDevice(ys); //svm.CLb.WriteToDevice(new float[] { svm.b }); //svm.CLQtdSupVecs.WriteToDevice(new int[] { svm.alphaList.Count }); CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { svm.CLTrainingFeatures, svm.CLQtdSupVecs, svm.CLXVecLen, Samples, svm.CLKernelValuesMultiClassify, svm.CLLambda }; kernelComputeMultiKernelRBF.Execute(args, new int[] { svm.alphaList.Count, Samples.Height }); CLCalc.Program.Sync(); args = new CLCalc.Program.MemoryObject[] { svm.CLAlphas, svm.CLQtdSupVecs, svm.CLXVecLen, svm.CLys, svm.CLKernelValuesMultiClassify, svm.CLb, CLMultiClassifSums }; kernelSumKernels.Execute(args, Samples.Height); CLMultiClassifSums.ReadFromDeviceTo(resp); return resp; }
/// <summary>Writes Training Set into device memory</summary> private void WriteToDevice() { //Vector length if (HostVLen == null) { HostVLen = new int[1]; HostVLen[0] = (1 + ((TrainingSet.trainingArray[0].xVector.Length - 1) >> 2)) << 2; } //Populates OpenCL buffer if (TrainingFeatures == null) // || TrainingFeatures.Length != TrainingSet.getN * HostVLen[0]) { TrainingFeatures = new float[TrainingSet.getN * HostVLen[0]]; } for (int i = 0; i < TrainingSet.getN; i++) { for (int j = 0; j < TrainingSet.trainingArray[0].xVector.Length; j++) { TrainingFeatures[j + i * HostVLen[0]] = TrainingSet.trainingArray[i].xVector[j]; } } if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL) return; lock (CLResource) { //Writes to OpenCL memory //if (CLTrainingFeatures != null) CLTrainingFeatures.Dispose(); if (CLTrainingFeatures == null || CLTrainingFeatures.OriginalVarLength != TrainingFeatures.Length) { if (CLTrainingFeatures != null) CLTrainingFeatures.Dispose(); CLTrainingFeatures = new CLCalc.Program.Variable(TrainingFeatures); } else CLTrainingFeatures.WriteToDevice(TrainingFeatures); //if (CLXVecLen != null) CLXVecLen.Dispose(); if (CLXVecLen == null) CLXVecLen = new CLCalc.Program.Variable(HostVLen); else CLXVecLen.WriteToDevice(HostVLen); HostSample = new float[HostVLen[0]]; //if (CLSample != null) CLSample.Dispose(); if (CLSample == null) CLSample = new CLCalc.Program.Image2D(HostSample, HostVLen[0] >> 2, 1); else CLSample.WriteToDevice(HostSample); //if (CLKernelValues != null) CLKernelValues.Dispose(); if (CLKernelValues == null || CLKernelValues.OriginalVarLength != TrainingSet.getN) CLKernelValues = new CLCalc.Program.Variable(new float[TrainingSet.getN]); else CLKernelValues.WriteToDevice(new float[TrainingSet.getN]); //if (CLLambda != null) CLLambda.Dispose(); if (CLLambda == null) CLLambda = new CLCalc.Program.Variable(new float[] { this.ProblemCfg.lambda }); else CLLambda.WriteToDevice(new float[] { this.ProblemCfg.lambda }); } }
/// <summary>Constructor.</summary> /// <param name="InitialState">Initial state of system</param> /// <param name="StepSize">Desired step per integration pass</param> /// <param name="InitialIndepVarValue">Initial independent variable value</param> /// <param name="DerivativeCalculator">Function to calculate derivatives vector</param> public doubleODE46(double InitialIndepVarValue, double StepSize, double[] InitialState, DerivCalcDeleg DerivativeCalculator) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { CLCalc.InitCL(); } if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.NotUsingCL) throw new Exception("OpenCL not available"); if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { ODE46Source Source = new ODE46Source(); string[] s = new string[] { @" #pragma OPENCL EXTENSION cl_khr_fp64 : enable ", Source.doubleStep2, Source.doubleStep3, Source.doubleStep4, Source.doubleStep5, Source.doubleStep6, Source.doubleFinalizeCalc }; CLCalc.Program.Compile(s); //Calculador de derivada Derivs = DerivativeCalculator; //Scalars double[] xx = new double[1] { InitialIndepVarValue }; x = new CLCalc.Program.Variable(xx); xsav = new CLCalc.Program.Variable(xx); //Sets initial values to Device and local variables hdid = new CLCalc.Program.Variable(xx); currentX = InitialIndepVarValue; SetStep(StepSize); //Vectors yy = new double[InitialState.Length]; for (int i = 0; i < InitialState.Length; i++) yy[i] = InitialState[i]; ysav = new CLCalc.Program.Variable(yy); k1 = new CLCalc.Program.Variable(InitialState); k2 = new CLCalc.Program.Variable(InitialState); k3 = new CLCalc.Program.Variable(InitialState); k4 = new CLCalc.Program.Variable(InitialState); k5 = new CLCalc.Program.Variable(InitialState); k6 = new CLCalc.Program.Variable(InitialState); absError = new CLCalc.Program.Variable(new double[InitialState.Length]); y = new CLCalc.Program.Variable(yy); //Kernels KernelFinalizeCalc = new CLCalc.Program.Kernel("doubleFinalizeCalc"); KernelUpdateX = new CLCalc.Program.Kernel("doubleUpdateX"); KernelRK46YStep2 = new CLCalc.Program.Kernel("doubleYStep2"); KernelRK46XStep2 = new CLCalc.Program.Kernel("doubleXStep2"); KernelRK46YStep3 = new CLCalc.Program.Kernel("doubleYStep3"); KernelRK46XStep3 = new CLCalc.Program.Kernel("doubleXStep3"); KernelRK46YStep4 = new CLCalc.Program.Kernel("doubleYStep4"); KernelRK46XStep4 = new CLCalc.Program.Kernel("doubleXStep4"); KernelRK46YStep5 = new CLCalc.Program.Kernel("doubleYStep5"); KernelRK46XStep5 = new CLCalc.Program.Kernel("doubleXStep5"); KernelRK46YStep6 = new CLCalc.Program.Kernel("doubleYStep6"); KernelRK46XStep6 = new CLCalc.Program.Kernel("doubleXStep6"); //Kernel arguments ArgsFinalize = new CLCalc.Program.Variable[] { x, hdid, y, ysav, absError, k1, k2, k3, k4, k5, k6 }; ArgsRK46Y = new CLCalc.Program.Variable[] { x, hdid, y, ysav, k1, k2, k3, k4, k5, k6 }; ArgsRK46X = new CLCalc.Program.Variable[] { x, hdid, xsav }; NStates = new int[1] { InitialState.Length }; NScalar = new int[1] { 1 }; //Data retrieving yerr = new double[NStates[0]]; xRet = new double[NScalar[0]]; } }
/// <summary>Computes transpose(A)*A and transpose(A)*b weighted by W using OpenCL. Lambda is regularization term</summary> private static floatSymPosDefMatrix AuxLSAtACL(floatMatrix A, floatDiag W, floatVector lambda, ref floatSymPosDefMatrix AtA) { if (AtA == null || AtA.CLValues.OriginalVarLength != (A.Cols * (A.Cols + 1)) >> 1) { AtA = new floatSymPosDefMatrix(new float[(A.Cols * (A.Cols + 1)) >> 1]); } CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { A.CLValues, A.CLDim, W.CLValues, AtA.CLValues, lambda.CLValues }; kernelComputeAtWA.Execute(args, AtA.CLValues.OriginalVarLength); //Just modified values in CL memory, matrix is no longer Cholesky factorized AtA.IsCholeskyFactorized = false; return AtA; }
/// <summary>Solves linear system Mx = b using conjugate gradient method. Doesn't try to improve the solution obtained.</summary> /// <param name="M">Matrix M</param> /// <param name="b">Vector b</param> /// <param name="tol">Error tolerance</param> public void LinSolveCLStep(CLImgSparseMatrix M, CLImgVector b, float tol) { int n = b.Length; int nBy4 = 1 + ((n - 1) >> 2); if (lambda == null) { lambda = new float[1]; CLlambda = new CLCalc.Program.Variable(lambda); } if (r == null || r.Length != n) { r = new CLImgVector(n); p = new CLImgVector(n); x = new CLImgVector(n); Ap = new CLImgVector(n); temp = new CLImgVector(n); } if (temp == null) { temp = new CLImgVector(n); } float alpha, beta, RDotROld, RDotR; //Initialization Multiply(M, x, Ap); CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { b.CLVector, Ap.CLVector, r.CLVector, p.CLVector }; kernelInitRP.Execute(args, nBy4); //Loop int count = 0; RDotR = DotProduct(r, r); while ((RDotR > tol) && (count < n * MAXITER)) { RDotROld = RDotR; //if ((count & 0x0080) == 0) //{ // Multiply(M, x, Ap); // args = new CLCalc.Program.MemoryObject[] { b.CLVector, Ap.CLVector, r.CLVector, p.CLVector }; // kernelInitRP.Execute(args, nBy4); //} Multiply(M, p, Ap); alpha = RDotROld / DotProduct(Ap, p); //Update x kernelCopyToTemp.Execute(new CLCalc.Program.MemoryObject[] { x.CLVector, temp.CLVector }, nBy4); lambda[0] = alpha; CLlambda.WriteToDevice(lambda); kernelMultiplyAdd.Execute(new CLCalc.Program.MemoryObject[] { CLlambda, p.CLVector, temp.CLVector, x.CLVector }, nBy4); //Update r kernelCopyToTemp.Execute(new CLCalc.Program.MemoryObject[] { r.CLVector, temp.CLVector }, nBy4); lambda[0] = -alpha; CLlambda.WriteToDevice(lambda); kernelMultiplyAdd.Execute(new CLCalc.Program.MemoryObject[] { CLlambda, Ap.CLVector, temp.CLVector, r.CLVector }, nBy4); RDotR = DotProduct(r, r); beta = RDotR / RDotROld; //Update p kernelCopyToTemp.Execute(new CLCalc.Program.MemoryObject[] { p.CLVector, temp.CLVector }, nBy4); lambda[0] = beta; CLlambda.WriteToDevice(lambda); kernelMultiplyAdd.Execute(new CLCalc.Program.MemoryObject[] { CLlambda, temp.CLVector, r.CLVector, p.CLVector }, nBy4); count++; } }
/// <summary>Finds minimum E[i] in SVM and returns corresponding i (returns arg min E[i])</summary> /// <param name="svm">SVM to check</param> private static int CLFindMinError(SVM svm) { CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { svm.CLerr, svm.CLErrLen, svm.CLMaxMinErrs, svm.CLMaxMinInds }; lock (CLResource) { //Majority of Minimums kernelMinErr.Execute(args, MAXMINWORKSIZE); //Computes values args = new CLCalc.Program.Variable[] { svm.CLMaxMinErrs, svm.CLMaxMinInds }; int i = MAXMINWORKSIZE >> 1; while (i > 0) { kernelComputeMin.Execute(args, i); i = (i >> 1); } //Retrieves index args = new CLCalc.Program.Variable[] { svm.CLMaxMinInds, svm.CLResp }; kernelGetResp.Execute(args, 1); svm.CLResp.ReadFromDeviceTo(svm.HostResp); } return svm.HostResp[0]; }
/// <summary>Cholesky decomposition using OpenCL with Blocks</summary> public void CLBlockCholesky() { //If matrix dimension is not a multiple of SUBMATRIXSIZE //pad with zeros. int NMultiple = N; if (N % SUBMATRIXSIZE != 0) { NMultiple = N / SUBMATRIXSIZE; NMultiple = SUBMATRIXSIZE * (NMultiple + 1); } if (!IsMatrixInClMemoryUpdated) { for (int i = 0; i < Values.Length; i++) cholDec[i] = Values[i]; CLcholDec.WriteToDevice(cholDec); } else { kernelCopyBuffer.Execute(new CLCalc.Program.MemoryObject[] { CLValues, CLcholDec }, CLValues.OriginalVarLength); } int SubMatrixSize = SUBMATRIXSIZE; int GlobalSize; //Important. Set offset to zero CLoffSet.WriteToDevice(new int[] { 0 }); CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLcholDec, CLoffSet, CLinvl11 }; GlobalSize = (SubMatrixSize * (SubMatrixSize + 1)) >> 1; for (int i = 0; i < NMultiple; i += SubMatrixSize) { //Computes Cholesky factor L11 and its inverse kernelCholeskyDiagBlock.Execute(args, new int[] { GlobalSize }, new int[] { GlobalSize }); //CLcholDec.ReadFromDeviceTo(cholDec); //Computes column panel L21 //Note: offSet has been updated, kernel should use its value-1 //Number of submatrices to update: (N-i)/SubMatrixSize int nSubMatrices = (NMultiple - i) / SubMatrixSize - 1; if (nSubMatrices > 0) { //Computes panels and updates main diagonals kernelCholeskyComputePanel.Execute(args, new int[] { nSubMatrices * SubMatrixSize, SubMatrixSize }, new int[] { SubMatrixSize, SubMatrixSize }); //CLcholDec.ReadFromDeviceTo(cholDec); //Still need to update nSubMatrices*(nSubMatrices-1)/2 full matrices in the Cholesky decomposition //They start at indexes [i+SubMatrixSize i], and they are the offdiagonal block matrices int totalSubMatricesToUpdate = ((nSubMatrices - 1) * nSubMatrices) >> 1; if (totalSubMatricesToUpdate > 0) { kernelCholeskyForwardProp.Execute(args, new int[] { totalSubMatricesToUpdate * SubMatrixSize, SubMatrixSize }, new int[] { SubMatrixSize, SubMatrixSize }); } } //CLcholDec.ReadFromDeviceTo(cholDec); } //CLcholDec.ReadFromDeviceTo(cholDec); this.IsCholeskyFactorized = true; }
public void Initialize(BaseCameraApplication capture) { DepthCameraFrame frame = capture.GetDevices()[0].GetDepthImage(); try { StreamReader reader = new StreamReader(new MemoryStream(Perceptual.Foundation.Properties.Resources.AdaptiveTemporalFilter)); string text = reader.ReadToEnd(); CLCalc.Program.Compile(capture.GetPrimaryDevice().GetPreprocessCode() + "\n#define HISTORY_SIZE " + historySize + "\n" + text); reader.Close(); } catch (Exception ex) { System.Console.WriteLine(ex.Message); System.Console.WriteLine("Could not find AdaptiveTemporalFilter.cl"); Environment.Exit(1); } historyIndex = new CLCalc.Program.Value<int>(historySize - 1); updateBuffer = new CLCalc.Program.Kernel("UpdateFilter"); copyToTemporalBuffer = new CLCalc.Program.Kernel("CopyToTemporalBuffer"); depthBuffer = CLCalc.Program.Variable.Create(new ComputeBuffer<float>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite, 4 * frame.Width * frame.Height)); depthCopyBuffer = new CLCalc.Program.Variable(new float[4 * frame.Width * frame.Height]); depthTemporalBuffer = CLCalc.Program.Variable.Create(new ComputeBuffer<float>(CLCalc.Program.Context, ComputeMemoryFlags.ReadWrite, historySize * 4 * frame.Width * frame.Height)); depthImage = new CLCalc.Program.Image2D(new float[frame.Height * frame.Width * 4], frame.Width, frame.Height); uvImage = new CLCalc.Program.Image2D(new float[frame.Height * frame.Width * 4], frame.Width, frame.Height); kernelErodeFilter = new CLCalc.Program.Kernel("ErodeFilter"); kernelDilateFilter = new CLCalc.Program.Kernel("DilateFilter"); kernelCopyImage = new CLCalc.Program.Kernel("CopyImage"); kernelCopyBuffer = new CLCalc.Program.Kernel("CopyDepth"); kernelMedianFilter1 = new CLCalc.Program.Kernel("SmallFilter"); kernelMedianFilter2 = new CLCalc.Program.Kernel("LargeFilter"); }
/// <summary>Backsubstitutes to solve a linear system with a matrix right hand size</summary> private void LinsolveCLMatrix(floatMatrix M, ref floatMatrix resp) { //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); //System.Diagnostics.Stopwatch sw1 = new System.Diagnostics.Stopwatch(); //sw.Start(); //number of RHS as multiple of SUBMATRIXSIZE int nRHSMult = M.Rows / SUBMATRIXSIZE; int nRHSleftOver = M.Rows - SUBMATRIXSIZE*nRHSMult; if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL) { linsolveMatrix(M, ref resp); return; } //Copy elements to CLb if (CLb == null || CLb.OriginalVarLength < M.Values.Length) { CLb = new CLCalc.Program.Variable(M.Values); CLy = new CLCalc.Program.Variable(M.Values); } kernelCopyBuffer.Execute(new CLCalc.Program.MemoryObject[] { M.CLValues, CLb }, M.Values.Length); int nEqs = M.Rows; CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLcholDec, CLy, CLb, CLoffSet, CLn }; int[] offset = new int[1]; //DEBUG //float[] yDebug = new float[M.Values.Length]; //float[] bDebug = new float[M.Values.Length]; //this.CLcholDec.ReadFromDeviceTo(cholDec); //Forward substitution int i; for (i = 0; i < N; i += SUBMATRIXSIZE) { offset[0] = i; CLoffSet.WriteToDevice(offset); int size = Math.Min(SUBMATRIXSIZE, N - i); kernelFwdUpperBackSubs.Execute(args, new int[] { size, nEqs }, new int[] { size, 1 }); ////DEBUG //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); //sw1.Start(); //propagation if (i + SUBMATRIXSIZE < N) { if (nRHSMult > 0) kernelFwdPropag.Execute(args, new int[] { N - i - SUBMATRIXSIZE, nRHSMult * SUBMATRIXSIZE }, new int[] { 1, SUBMATRIXSIZE }); if (nRHSleftOver > 0) kernelFwdPropag2.Execute(args, new int[] { N - i - SUBMATRIXSIZE, nRHSleftOver }, new int[] { 1, nRHSleftOver }, new int[] { 0, nRHSMult * SUBMATRIXSIZE }); } //OpenCLTemplate.CLCalc.Program.CommQueues[OpenCLTemplate.CLCalc.Program.DefaultCQ].Finish(); //sw1.Stop(); ////DEBUG //CLy.ReadFromDeviceTo(yDebug); //CLb.ReadFromDeviceTo(bDebug); } //Backward subst. Stores answer in CLb args = new CLCalc.Program.Variable[] { CLcholDec, CLb, CLy, CLoffSet, CLn }; //Backward substitution for (i = N - SUBMATRIXSIZE; i >= 0; i -= SUBMATRIXSIZE) { offset[0] = i; CLoffSet.WriteToDevice(offset); int size = SUBMATRIXSIZE; kernelBkLowerBackSubs.Execute(args, new int[] { size, nEqs }, new int[] { size, 1 }); if (i > 0) { //Propagation using __local storage if (nRHSMult > 0) kernelBackPropag.Execute(args, new int[] { i, nRHSMult * SUBMATRIXSIZE }, new int[] { 1, SUBMATRIXSIZE }); //leftovers (not multiples of SUBMATRIXSIZE) if (nRHSleftOver > 0) kernelBackPropag2.Execute(args, new int[] { i, nRHSleftOver }, new int[] { 1, nRHSleftOver }, new int[] { 0, nRHSMult * SUBMATRIXSIZE }); } } if (SUBMATRIXSIZE + i > 0) { offset[0] = 0; CLoffSet.WriteToDevice(offset); kernelBkLowerBackSubs.Execute(args, new int[] { SUBMATRIXSIZE + i, nEqs }, new int[] { SUBMATRIXSIZE + i, 1 }); } kernelCopyBuffer.Execute(new CLCalc.Program.Variable[] { CLb, resp.CLValues }, resp.Values.Length); //OpenCLTemplate.CLCalc.Program.CommQueues[OpenCLTemplate.CLCalc.Program.DefaultCQ].Finish(); //sw.Stop(); }
/// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL /// if not using OpenCL/GL interop.</summary> /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param> /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param> public MarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex) { InitMarchingCubes(FuncValues, CLEdgeCoords, CLEdgeNormals, CLElementArrayIndex); }
/// <summary>OpenCL vector constructor</summary> /// <param name="Vals">Vector elements</param> public floatVector(float[] Vals) { this.Values = (float[])Vals.Clone(); if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLValues = new CLCalc.Program.Variable(Values); CLCoef = new CLCalc.Program.Variable(new float[1]); } }
/// <summary>Creates a new isosurface calculator. You may pass variables created from a OpenGL context to the CL variables if you are using interop or NULL /// if not using OpenCL/GL interop.</summary> /// <param name="FuncValues">Values of the evaluated 3D function f(x,y,z). FuncValues=float[maxX,maxY,maxZ]</param> /// <param name="CLEdgeCoords">OpenCL variable (float) to hold edge coordinates. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLEdgeNormals">OpenCL variable (float) to hold edge normals. Dimension has to be 9 * maxX * maxY * maxZ</param> /// <param name="CLElementArrayIndex">OpenCL variable (int) to hold element array index. Dimension has to be 5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)</param> private void InitMarchingCubes(float[, ,] FuncValues, CLCalc.Program.Variable CLEdgeCoords, CLCalc.Program.Variable CLEdgeNormals, CLCalc.Program.Variable CLElementArrayIndex) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { CLCalc.InitCL(); } if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { //Reads maximum lengths int maxX = FuncValues.GetLength(0); int maxY = FuncValues.GetLength(1); int maxZ = FuncValues.GetLength(2); max = new int[] { maxX, maxY, maxZ }; #region Creating variables //Isolevel isoLevel = new float[1] { 1.32746E-5f }; varIsoLevel = new CLCalc.Program.Variable(isoLevel); //Step size and x0,y0,z0 varStep = new CLCalc.Program.Variable(step); varInitVals = new CLCalc.Program.Variable(initVals); //Create and copy function values funcVals = new float[maxX * maxY * maxZ]; CLFuncVals = new CLCalc.Program.Variable(funcVals); SetFuncVals(FuncValues); //Edge coordinates - 3 coords * 3 possible directions * number of points edgeCoords = new float[9 * maxX * maxY * maxZ]; if (CLEdgeCoords != null) { varEdgeCoords = CLEdgeCoords; varEdgeCoords.WriteToDevice(edgeCoords); } else { varEdgeCoords = new CLCalc.Program.Variable(edgeCoords); } //4 preliminary normals per edge - has to be averaged afterwards edgePrelimNormals = new float[36 * maxX * maxY * maxZ]; varEdgePrelimNormals = new CLCalc.Program.Variable(edgePrelimNormals); //Edge normals edgeNormals = new float[9 * maxX * maxY * maxZ]; if (CLEdgeNormals != null) { varEdgeNormals = CLEdgeNormals; varEdgeNormals.WriteToDevice(edgeNormals); } else { varEdgeNormals = new CLCalc.Program.Variable(edgeNormals); } //Number of cubes: (maxX-1)*(maxY-1)*(maxZ-1) //Marching cube algorithm: each cube can have 5 triangles drawn, 3 vertexes per triangle //q-th vertex of p-th triangle of the ijk-th cube: [(5*(i+(maxX-1)*j+k*(maxX-1)*(maxY-1))+p)*3+q] elementIndex = new int[5 * 3 * (maxX - 1) * (maxY - 1) * (maxZ - 1)]; if (CLElementArrayIndex != null) { varElemIndex = CLElementArrayIndex; varElemIndex.WriteToDevice(elementIndex); } else { varElemIndex = new CLCalc.Program.Variable(elementIndex); } //Edge remapping to build output edges = new int[edgeCoords.Length / 3]; for (int i = 0; i < edges.Length; i++) { edges[i] = -1; } #endregion #region Compile code and create kernels CLMarchingCubesSrc cmsrc = new CLMarchingCubesSrc(); CLCalc.Program.Compile(new string[] { cmsrc.definitions, cmsrc.src }); kernelInterpPts = new CLCalc.Program.Kernel("interpPts"); kernelPolygonize = new CLCalc.Program.Kernel("Polygonize"); kernelSmoothNormals = new CLCalc.Program.Kernel("SmoothNormals"); kernelPolygonizeNoNormals = new CLCalc.Program.Kernel("PolygonizeNoNormals"); #endregion } else { throw new Exception("OpenCL not available"); } }
/// <summary>Sums the components of a vector using __local memory and coalesced access</summary> /// <param name="CLv">Vector whose components should be summed</param> public static float SumVectorElements(floatVector CLv) { float resp = 0; if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { /* The idea here is to create a reduction in which the access pattern to the vectors is coalesced. The first step is to reduce the number of non-summed items to a multiple of NWORKITEMS and then coalesce the access */ int LOCALWORKSIZE = Math.Min(256, (int)CLCalc.Program.CommQueues[CLCalc.Program.DefaultCQ].Device.MaxWorkGroupSize); int NWORKITEMS = 16 * LOCALWORKSIZE; int n = CLv.Length; float[] resps = new float[NWORKITEMS]; if (CLv.CLresps == null) { CLv.CLresps = new CLCalc.Program.Variable(resps); CLv.CLn = new CLCalc.Program.Variable(new int[1]); } CLv.CLn.WriteToDevice(new int[] { n }); CLCalc.Program.Variable[] args = new CLCalc.Program.Variable[] { CLv.CLValues, CLv.CLresps, CLv.CLn }; //Write n = k*NWORKITEMS + p. Preprocess to eliminate p`s and leave summation only to a multiple of NWORKITEMS int k = n / NWORKITEMS; int p = n - k * NWORKITEMS; //Clears partial responses kernelClear.Execute(args, NWORKITEMS); //Sums the p last elements into the p first elements kernelPreSum.Execute(args, p); //Use CLn to inform each work-item its workload. Each one will access and sum k numbers CLv.CLn.WriteToDevice(new int[] { k }); kernelCoalLocalSum.Execute(args, new int[] { NWORKITEMS }, new int[] { LOCALWORKSIZE }); CLv.CLresps.ReadFromDeviceTo(resps); //Serial part int imax = NWORKITEMS / LOCALWORKSIZE; for (int i = 0; i < imax; i++) resp += resps[i]; } else { double sum = 0; for (int i = 0; i < CLv.Length; i++) sum += CLv.Values[i]; resp = (float)sum; } return resp; }
public void Initialize(BaseCameraApplication app, OpenTKWrapper.CLGLInterop.GLAdvancedRender glw) { try { CLCalc.Program.Compile(app.GetPrimaryDevice().GetPreprocessCode() + src); } catch (BuildProgramFailureComputeException ex) { System.Console.WriteLine(ex.Message); Environment.Exit(1); } kernelCopyImage = new CLCalc.Program.Kernel("CopyImageToMesh"); BoundingBox bbox = app.GetPrimaryDevice().GetBoundingBox(); int w = app.GetPrimaryDevice().GetDepthImage().Width; int h = app.GetPrimaryDevice().GetDepthImage().Height; int size = w * h; ColorData = new float[16 * size]; PositionData = new float[16 * size]; NormalData = new float[12 * size]; for (int i = 0; i < size; i++) { PositionData[4 * i] = (i / w) - w / 2; PositionData[4 * i + 2] = i % w - h / 2; PositionData[4 * i + 1] = i % 7; PositionData[4 * i + 3] = 1.0f; } GL.GenBuffers(3, QuadMeshBufs); GL.BindBuffer(BufferTarget.ArrayBuffer, QuadMeshBufs[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(ColorData.Length * sizeof(float)), ColorData, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, QuadMeshBufs[1]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(PositionData.Length * sizeof(float)), PositionData, BufferUsageHint.StreamDraw);//Notice STREAM DRAW GL.BindBuffer(BufferTarget.ArrayBuffer, QuadMeshBufs[2]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(NormalData.Length * sizeof(float)), NormalData, BufferUsageHint.StreamDraw);//Notice STREAM DRAW colorBuffer = new CLCalc.Program.Variable(QuadMeshBufs[0], typeof(float)); positionBuffer = new CLCalc.Program.Variable(QuadMeshBufs[1], typeof(float)); normalBuffer = new CLCalc.Program.Variable(QuadMeshBufs[2], typeof(float)); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.Enable(EnableCap.Blend); }
/// <summary>OpenCL diagonal matrix constructor</summary> /// <param name="Vals">Main diagonal elements</param> public floatDiag(float[] Vals) { this.Values = (float[])Vals.Clone(); if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLValues = new CLCalc.Program.Variable(Values); } nRows = Vals.Length; nCols = Vals.Length; }
/// <summary>Constructor.</summary> public SparseLinalg() { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { try { CLCalc.InitCL(); } catch { } } if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { //Creates control variables dprod = new float[SparseLinalg.GLOBALWORKSIZE]; dotProd = new CLCalc.Program.Variable(dprod); dotProdSum = new CLCalc.Program.Variable(new float[1]); int[] i = new int[1]; vLenBy4 = new CLCalc.Program.Variable(i); CLNonZeroElemsPerRow = new CLCalc.Program.Variable(new int[1]); } }
/// <summary>New matrix constructor</summary> /// <param name="Vals">Matrix values</param> public floatMatrix(float[,] Vals) { nRows = Vals.GetLength(0); nCols = Vals.GetLength(1); Values = new float[nRows * nCols]; if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLValues = new CLCalc.Program.Variable(Values); CLDim = new CLCalc.Program.Variable(new int[] { nRows, nCols }); CLCoef = new CLCalc.Program.Variable(new float[1]); } SetValues(Vals); }
/// <summary>Solves linear system Mx = b using conjugate gradient method. Doesn't try to improve the solution obtained.</summary> /// <param name="M">Matrix M</param> /// <param name="b">Vector b</param> /// <param name="tol">Error tolerance</param> /// <param name="x">Initial guess</param> public void LinSolveCLStep(CLImgSparseMatrix M, CLImgVector b, float tol, ref CLImgVector x) { int n = b.Length; int nBy4 = 1 + ((n - 1) >> 2); if (lambda == null) { lambda = new float[1]; CLlambda = new CLCalc.Program.Variable(lambda); } if (r == null || r.Length != n) { r = new CLImgVector(n); p = new CLImgVector(n); //x = new CLImgVector(n); Ap = new CLImgVector(n); temp = new CLImgVector(n); } if (temp == null) temp = new CLImgVector(n); if (x == null || x.Length != n) x = new CLImgVector(n); float alpha, beta, RDotROld, RDotR; //Initialization Multiply(M, x, Ap); CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { b.CLVector, Ap.CLVector, r.CLVector, p.CLVector }; kernelInitRP.Execute(args, nBy4); //Loop int count = 0; RDotR = DotProduct(r, r); while (count<1 || ((RDotR > tol) && (count < n*MAXITER))) { RDotROld = RDotR; //if ((count & 0x0080) == 0) //{ // Multiply(M, x, Ap); // args = new CLCalc.Program.MemoryObject[] { b.CLVector, Ap.CLVector, r.CLVector, p.CLVector }; // kernelInitRP.Execute(args, nBy4); //} Multiply(M, p, Ap); alpha = RDotROld / DotProduct(Ap, p); //Update x kernelCopyToTemp.Execute(new CLCalc.Program.MemoryObject[] { x.CLVector, temp.CLVector }, nBy4); lambda[0] = alpha; CLlambda.WriteToDevice(lambda); kernelMultiplyAdd.Execute(new CLCalc.Program.MemoryObject[] { CLlambda, p.CLVector, temp.CLVector, x.CLVector }, nBy4); //Update r kernelCopyToTemp.Execute(new CLCalc.Program.MemoryObject[] { r.CLVector, temp.CLVector }, nBy4); lambda[0] = -alpha; CLlambda.WriteToDevice(lambda); kernelMultiplyAdd.Execute(new CLCalc.Program.MemoryObject[] { CLlambda, Ap.CLVector, temp.CLVector, r.CLVector }, nBy4); RDotR = DotProduct(r, r); beta = RDotR / RDotROld; //Update p kernelCopyToTemp.Execute(new CLCalc.Program.MemoryObject[] { p.CLVector, temp.CLVector }, nBy4); lambda[0] = beta; CLlambda.WriteToDevice(lambda); kernelMultiplyAdd.Execute(new CLCalc.Program.MemoryObject[] { CLlambda, temp.CLVector, r.CLVector, p.CLVector }, nBy4); count++; } }
/// <summary>Equalizes image histogram using OpenCL</summary> private void CLEqualizeHistogram(ref Bitmap bmp) { if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.Unknown) { CLCalc.InitCL(); } if (CLCalc.CLAcceleration != CLCalc.CLAccelerationType.UsingCL) { return; } float[] PartialHistograms = new float[NLumIntens * bmp.Width]; float[] histLuminance = new float[NLumIntens]; if (kernelComputeHistograms == null || CLN == null || CLHistogram == null) { CLHistogram = new CLCalc.Program.Variable(histLuminance); CLPartialHistograms = new CLCalc.Program.Variable(PartialHistograms); } InitKernels(); System.Diagnostics.Stopwatch swTotal = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch swCopyBmp = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch swRescaling = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch swComputeHistPartial = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch swComputeHistConsolid = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch swHistIntegral = new System.Diagnostics.Stopwatch(); swTotal.Start(); swCopyBmp.Start(); if (CLbmp == null || CLbmp.Height != bmp.Height || CLbmp.Width != bmp.Width) { CLbmp = new CLCalc.Program.Image2D(bmp); CLNewBmp = new CLCalc.Program.Image2D(bmp); CLPartialHistograms = new CLCalc.Program.Variable(PartialHistograms); } else { CLbmp.WriteBitmap(bmp); CLN.WriteToDevice(new int[] { NLumIntens }); CLWidth.WriteToDevice(new int[] { bmp.Width }); CLHeight.WriteToDevice(new int[] { bmp.Height }); } swCopyBmp.Stop(); swComputeHistPartial.Start(); //Partial histograms CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { CLbmp, CLPartialHistograms, CLHeight, CLN }; kernelComputeHistograms.Execute(args, bmp.Width); CLCalc.Program.Sync(); swComputeHistPartial.Stop(); swComputeHistConsolid.Start(); args = new CLCalc.Program.MemoryObject[] { CLPartialHistograms, CLHistogram, CLHeight, CLN }; kernelConsolidateHist.Execute(args, NLumIntens); CLHistogram.ReadFromDeviceTo(histLuminance); swComputeHistConsolid.Stop(); swHistIntegral.Start(); //Perform histogram integration - better performance in CPU //Compute histogram integrals in-place for (int i = 1; i < NLumIntens; i++) { histLuminance[i] += histLuminance[i - 1]; } float scale = 0.9f / histLuminance[NLumIntens - 1]; //Scales histograms for (int i = 0; i < NLumIntens; i++) { histLuminance[i] *= scale; } //Writes histogram integral CLHistogram.WriteToDevice(histLuminance); swHistIntegral.Stop(); swRescaling.Start(); //Computes equalized image args = new CLCalc.Program.MemoryObject[] { CLbmp, CLNewBmp, CLHistogram, CLN }; kernelPerformNormalization.Execute(args, new int [] { bmp.Width, bmp.Height }); bmp = CLNewBmp.ReadBitmap(); swRescaling.Stop(); swTotal.Stop(); }
public void Initialize(BaseCameraApplication capture, GLAdvancedRender glw) { try { CLCalc.Program.Compile(capture.GetPrimaryDevice().GetPreprocessCode() + src); } catch (BuildProgramFailureComputeException ex) { System.Console.WriteLine(ex.Message); Environment.Exit(1); } DepthCameraFrame frame = capture.GetDevices()[0].GetDepthImage(); kernelCopyBmp = new CLCalc.Program.Kernel("CopyImageToPointCloud"); int size = frame.Width * frame.Height; bufs = new int[4]; ColorData = new float[4 * size]; PositionData = new float[4 * size]; GL.GenBuffers(2, bufs); GL.BindBuffer(BufferTarget.ArrayBuffer, bufs[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(ColorData.Length * sizeof(float)), ColorData, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, bufs[1]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(PositionData.Length * sizeof(float)), PositionData, BufferUsageHint.StreamDraw);//Notice STREAM DRAW GL.Enable(EnableCap.PointSmooth); GL.PointSize(4.0f); positions = new CLCalc.Program.Variable(bufs[1], typeof(float)); colors = new CLCalc.Program.Variable(bufs[0], typeof(float)); }
/// <summary>Computes frame difference</summary> private void ComputeFrameDiff() { //Needs both images to compute if (CLBmp == null || CLBmpPrev == null || CLBmp.Width != CLBmpPrev.Width || CLBmp.Height != CLBmpPrev.Height) return; if (frameDiff == null || frameDiff.Length != ((CLBmp.Height * CLBmp.Width) >> 6)) { //Reduces image size by 8 frameDiff = new byte[(CLBmp.Height * CLBmp.Width) >> 6]; CLframeDiff = new CLCalc.Program.Variable(frameDiff); MovingRegionBoxes = new List<int>(); } CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { CLBmp, CLBmpPrev, CLframeDiff }; kernelComputeFrameDiff.Execute(args, new int[] { CLBmp.Width >> 3, CLBmp.Height >> 3 }); CLframeDiff.ReadFromDeviceTo(frameDiff); MovingRegionBoxes.Clear(); BracketMovingRegions(frameDiff, CLBmp.Width >> 3, CLBmp.Height >> 3, MovingRegionBoxes); }
/// <summary>Specific function when SVM contains only one object, such as faces</summary> /// <param name="bmp">Next frame to process</param> public List <int> FindSingleObj(Bitmap bmp) { //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(), sw2 = new System.Diagnostics.Stopwatch(); //sw.Start(); if (SVM == null) { return(null); } if (imgWidth != bmp.Width || imgHeight != bmp.Height) { imgWidth = bmp.Width; imgHeight = bmp.Height; SubFramePos = 0; List <int> subFrames = new List <int>(); ComputeSubFrames(0, 0, bmp.Width, bmp.Height, subFrames); SubFrames = subFrames.ToArray(); SubFeatures = new float[(SubFrames.Length / 3) * 364]; if (CLCalc.CLAcceleration == CLCalc.CLAccelerationType.UsingCL) { CLSubFrames = new CLCalc.Program.Variable(SubFrames); CLSubFeatures = new CLCalc.Program.Image2D(SubFeatures, 91, SubFrames.Length / 3); CLBmp = new CLCalc.Program.Image2D(bmp); //CLBmpTemp = new CLCalc.Program.Image2D(bmp); CLBmpPrev = new CLCalc.Program.Image2D(bmp); } } //Swaps current and previous bitmap pointers CLCalc.Program.Image2D temp = CLBmp; CLBmp = CLBmpPrev; CLBmpPrev = temp; //Computes frame difference ComputeFrameDiff(); //Replaces subFrames based on moving regions for (int k = 0; k < MovingRegionBoxes.Count >> 2; k++) { List <int> sframes = new List <int>(); int ind = 4 * k; ComputeSubFrames(MovingRegionBoxes[ind] << 3, MovingRegionBoxes[ind + 2] << 3, MovingRegionBoxes[ind + 1] << 3, MovingRegionBoxes[ind + 3] << 3, sframes); for (int p = 0; p < sframes.Count; p += 3) { SubFrames[SubFramePos] = sframes[p]; SubFrames[SubFramePos + 1] = sframes[p + 1]; SubFrames[SubFramePos + 2] = sframes[p + 2]; SubFramePos += 3; if (SubFramePos > SubFrames.Length - 1) { SubFramePos = 0; } } } CLSubFrames.WriteToDevice(SubFrames); CLBmp.WriteBitmap(bmp); ////Segments skin //kernelSegregateSkin.Execute(new CLCalc.Program.MemoryObject[] { CLBmpTemp, CLBmp }, new int[] { bmp.Width, bmp.Height }); //Extract features using OpenCL CLCalc.Program.MemoryObject[] args = new CLCalc.Program.MemoryObject[] { CLSubFrames, CLSubFeatures, CLBmp }; kernelExtractFeatures.Execute(args, SubFrames.Length / 3); #region No OpenCL //float[] testSubFeats = new float[364 * (SubFrames.Length / 3)]; //CLSubFeatures.ReadFromDeviceTo(testSubFeats); //Extract features without OpenCL //ExtractFeatures(SubFrames, SubFeatures, bmp); //CLSubFeatures.WriteToDevice(SubFeatures); #endregion //sw2.Start(); float[] maxvals = OpenCLTemplate.MachineLearning.SVM.MultiClassify(SVM.SVMs[0], CLSubFeatures); //SVM.Classify(CLSubFeatures, out maxvals); //sw2.Stop(); List <int> FacesPos = new List <int>(); List <float> MaxVals = new List <float>(); //Goes in decreasing window size order for (int kk = Config.WINDOWSIZES.Length - 1; kk >= 0; kk--) { for (int i = maxvals.Length - 1; i >= 0; i--) { if (SubFrames[3 * i + 2] == Config.WINDOWSIZES[kk] && maxvals[i] > Config.REQCERTAINTY) { //Checks if a face already has been found in that region bool contido = false; int i3 = 3 * i; int kmax = FacesPos.Count / 3; for (int k = 0; k < kmax; k++) { int k3 = 3 * k; if ( (FacesPos[k3] <= SubFrames[i3] && SubFrames[i3] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] && SubFrames[i3 + 1] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) || (FacesPos[k3] <= SubFrames[i3] + SubFrames[i3 + 2] && SubFrames[i3] + SubFrames[i3 + 2] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] + SubFrames[i3 + 2] && SubFrames[i3 + 1] + SubFrames[i3 + 2] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) || (FacesPos[k3] <= SubFrames[i3] && SubFrames[i3] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] + SubFrames[i3 + 2] && SubFrames[i3 + 1] + SubFrames[i3 + 2] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) || (FacesPos[k3] <= SubFrames[i3] + SubFrames[i3 + 2] && SubFrames[i3] + SubFrames[i3 + 2] <= FacesPos[k3] + FacesPos[k3 + 2] && FacesPos[k3 + 1] <= SubFrames[i3 + 1] && SubFrames[i3 + 1] <= FacesPos[k3 + 1] + FacesPos[k3 + 2]) ) { contido = true; //Replaces if better if (maxvals[i] > MaxVals[k] && SubFrames[3 * i + 2] == FacesPos[3 * k + 2]) { FacesPos[k3] = SubFrames[i3]; FacesPos[k3 + 1] = SubFrames[i3 + 1]; FacesPos[k3 + 2] = SubFrames[i3 + 2]; MaxVals[k] = maxvals[i]; } k = FacesPos.Count; } } if (!contido) { FacesPos.Add(SubFrames[3 * i]); FacesPos.Add(SubFrames[3 * i + 1]); FacesPos.Add(SubFrames[3 * i + 2]); MaxVals.Add(maxvals[i]); } } } } //sw.Stop(); Random rnd = new Random(); //Updates frame search region if (MovingRegionBoxes.Count > 0) { for (int i = 0; i < maxvals.Length; i++) { if (maxvals[i] > Config.REFINEUNCERTAINTY) { int i3 = 3 * i; List <int> sframes = new List <int>(); int cx = SubFrames[i3] + (SubFrames[i3 + 2] >> 1) + rnd.Next(7) - 3; int cy = SubFrames[i3 + 1] + (SubFrames[i3 + 2] >> 1) + rnd.Next(7) - 3; int bigwSize = Config.WINDOWSIZES[Config.WINDOWSIZES.Length - 1]; try { ComputeSubFrames(cx - (bigwSize >> 1), cy - (bigwSize >> 1), cx + (bigwSize >> 1), cy + (bigwSize >> 1), sframes); for (int p = 0; p < sframes.Count; p += 3) { SubFrames[SubFramePos] = sframes[p]; SubFrames[SubFramePos + 1] = sframes[p + 1]; SubFrames[SubFramePos + 2] = sframes[p + 2]; SubFramePos += 3; if (SubFramePos > SubFrames.Length - 1) { SubFramePos = 0; } } } catch { } } } } return(FacesPos); }