/// <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>Computes the inverse Discrete Fourier Transform of a float2 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 iFFT4(CLCalc.Program.Variable CLx) { if (CLScale == null) CLScale = new CLCalc.Program.Variable(new float[1]); //Trick: DFT-1 (x) = DFT(x*)*/N; //Conjugate float[] vx = new float[CLx.OriginalVarLength]; CLx.ReadFromDeviceTo(vx); float[] scale = new float[] { 1 }; CLScale.WriteToDevice(scale); kernelConjugate.Execute(new CLCalc.Program.Variable[] { CLx, CLScale }, CLx.OriginalVarLength >> 1); CLx.ReadFromDeviceTo(vx); CLy = FFT4(ref CLx); scale[0] = 1 / (float)(CLx.OriginalVarLength >> 1); CLScale.WriteToDevice(scale); kernelConjugate.Execute(new CLCalc.Program.Variable[] { CLy, CLScale }, CLy.OriginalVarLength >> 1); return CLy; }
/// <summary>Calculates LU decomposition of M matrix</summary> /// <param name="M">Matrix to decompose</param> /// <param name="n">Matrix dimension</param> /// <param name="varindx">Swap index</param> private CLCalc.Program.Variable LUDecomp(double[,] M, int n, out CLCalc.Program.Variable varindx) { //arguments and work_dim CLCalc.Program.Variable[] args; int[] max; //Matrix to vector double[] vecM = MatrixToVector(M, ref n, ref n); CLCalc.Program.Variable varM = new Program.Variable(vecM); //Scaling transformation double[] vv = new double[n]; CLCalc.Program.Variable varvv = new Program.Variable(vv); max = new int[1] { n }; args = new CLCalc.Program.Variable[] { varM, varvv }; doubleLUScale.Execute(args, max); //In order LU factorization (Crout) int[] J = new int[1] { 0 }; CLCalc.Program.Variable varJ = new Program.Variable(J); int[] N = new int[1] { n }; CLCalc.Program.Variable varN = new Program.Variable(N); int[] indx = new int[n]; varindx = new Program.Variable(indx); args = new Program.Variable[] { varM, varJ, varN, varindx, varvv }; for (J[0] = 0; J[0] < n; J[0]++) { varJ.WriteToDevice(J); max[0] = J[0]; doubleLUCalcBetas.Execute(args, max); max[0] = n - J[0]; doubleLUCalcAlphas.Execute(args, max); max[0] = 1; doubleLUCalcPivo.Execute(args, max); max[0] = n; doubleLUTrocaCols.Execute(args, max); if (J[0] != n - 1) { max[0] = n - J[0] - 1; doubleLUDivByPivot.Execute(args, max); } } return varM; }
/// <summary>Sets kernel arguments</summary> /// <param name="Variables">Variables to be set as arguments</param> private void SetArguments(CLCalc.Program.MemoryObject[] Variables) { //if (Variables.Length != nArgs) throw new Exception("Wrong number of arguments"); if (Vars != Variables) { Vars = Variables; for (int i = 0; i < Variables.Length; i++) { Variables[i].SetAsArgument(i, kernel); } } }
private CLCalc.Program.Variable LUBackSubstitute(CLCalc.Program.Variable MLUDecomp, double[] b, int n, CLCalc.Program.Variable varindx) { CLCalc.Program.Variable varx = new Program.Variable(b); CLCalc.Program.Variable varN = new Program.Variable(new int[1] { n }); int[] J = new int[1]; CLCalc.Program.Variable varJ = new Program.Variable(J); CLCalc.Program.Variable[] args = new Program.Variable[] { MLUDecomp, varx, varindx, varN, varJ }; int[] max = new int[1]; //ajeita o vetor com respeito as trocas de linha max[0] = 1; doubleLUUnscramble.Execute(args, max); //Forward subst for (int i = n - 1; i >= 1; i--) { max[0] = i; doubleLUForwardSubs.Execute(args, max); } //Backward subst for (int j = n - 1; j >= 1; j--) { max[0] = 1; J[0] = j; varJ.WriteToDevice(J); doubleLUDivide.Execute(args, max); max[0] = j; doubleLUBackSubs.Execute(args, max); } //Primeiro elemento max[0] = 1; J[0] = 0; varJ.WriteToDevice(J); doubleLUDivide.Execute(args, max); return varx; }
/// <summary>Execute this kernel</summary> /// <param name="Arguments">Arguments of the kernel function</param> /// <param name="GlobalWorkSize">Array of maximum index arrays. Total work-items = product(max[i],i+0..n-1), n=max.Length</param> /// <param name="LocalWorkSize">Local work sizes</param> /// <param name="WorkOffSet">Global offset</param> public void Execute(CLCalc.Program.MemoryObject[] Arguments, int[] GlobalWorkSize, int[] LocalWorkSize, int[] WorkOffSet) { Execute(CommQueues[DefaultCQ], Arguments, GlobalWorkSize, LocalWorkSize, WorkOffSet, null); }
/// <summary>Execute this kernel</summary> /// <param name="GlobalWorkSize">Array of maximum index arrays. Total work-items = product(max[i],i+0..n-1), n=max.Length</param> /// <param name="LocalWorkSize">Local work sizes</param> /// <param name="Arguments">Arguments of the kernel function</param> /// <param name="events">Events list</param> public void Execute(CLCalc.Program.MemoryObject[] Arguments, int[] GlobalWorkSize, int[] LocalWorkSize, ICollection<ComputeEventBase> events) { //CLEvent Event=new CLEvent(); Execute(CommQueues[DefaultCQ], Arguments, GlobalWorkSize, LocalWorkSize, events); //OpenCLDriver.clReleaseEvent(Event); }
/// <summary>Execute this kernel</summary> /// <param name="CQ">Command queue to use</param> /// <param name="Arguments">Arguments of the kernel function</param> /// <param name="GlobalWorkSize">Array of maximum index arrays. Total work-items = product(max[i],i+0..n-1), n=max.Length</param> /// <param name="events">Event of this command</param> public void Execute(ComputeCommandQueue CQ, CLCalc.Program.MemoryObject[] Arguments, int[] GlobalWorkSize, ICollection<ComputeEventBase> events) { SetArguments(Arguments); long[] globWSize=new long[GlobalWorkSize.Length]; for (int i=0;i<globWSize.Length;i++) globWSize[i]=GlobalWorkSize[i]; CQ.Execute(kernel, null, globWSize, null, events); }
/// <summary>Execute this kernel</summary> /// <param name="CQ">Command queue to use</param> /// <param name="Arguments">Arguments of the kernel function</param> /// <param name="GlobalWorkSize">Array of maximum index arrays. Total work-items = product(max[i],i+0..n-1), n=max.Length</param> /// <param name="LocalWorkSize">Local work sizes</param> /// <param name="events">Event of this command</param> public void Execute(ComputeCommandQueue CQ, CLCalc.Program.MemoryObject[] Arguments, int[] GlobalWorkSize, int[] LocalWorkSize, ICollection<ComputeEventBase> events) { SetArguments(Arguments); if (LocalWorkSize != null && GlobalWorkSize.Length != LocalWorkSize.Length) throw new Exception("Global and local work size must have same dimension"); long[] globWSize = new long[GlobalWorkSize.Length]; for (int i = 0; i < globWSize.Length; i++) globWSize[i] = GlobalWorkSize[i]; long[] locWSize = null; if (LocalWorkSize != null) { locWSize = new long[LocalWorkSize.Length]; for (int i = 0; i < locWSize.Length; i++) locWSize[i] = LocalWorkSize[i]; } CQ.Execute(kernel, null, globWSize, locWSize, events); }
/// <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; }
public Kernels(CLCalc.Program.Image2D CLGLRenderImage) { }
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); }
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 DoOCL(CLCalc.Program.Kernel VectorSum, CLCalc.Program.Variable[] args, int[] workers) { VectorSum.Execute(args, workers); }
/// <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>Execute this kernel using work_dim = 1</summary> /// <param name="GlobalWorkSize">Global work size in one-dimension. global_work_size = new int[1] {GlobalWorkSize}</param> /// <param name="Arguments">Arguments of the kernel function</param> public void Execute(CLCalc.Program.MemoryObject[] Arguments, int GlobalWorkSize) { //CLEvent Event=new CLEvent(); Execute(CommQueues[DefaultCQ], Arguments, new int[] { GlobalWorkSize }, null, null); //OpenCLDriver.clReleaseEvent(Event); }
/// <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>Execute this kernel</summary> /// <param name="CQ">Command queue to use</param> /// <param name="Arguments">Arguments of the kernel function</param> /// <param name="GlobalWorkSize">Array of maximum index arrays. Total work-items = product(max[i],i+0..n-1), n=max.Length</param> /// <param name="LocalWorkSize">Local work sizes</param> /// <param name="events">Event of this command</param> public void Execute(ComputeCommandQueue CQ, CLCalc.Program.MemoryObject[] Arguments, int[] GlobalWorkSize, int[] LocalWorkSize, ICollection<ComputeEventBase> events) { Execute(CQ, Arguments, GlobalWorkSize, LocalWorkSize, null, events); }