在 class 中创建静态方法和字段
Make static methods and fields in class
我正在使用 Cudafy 将 algorithm 重写为 GPU。我需要调用 Execute() from 静态方法。需要在GPU上计算。我怎么能这样做?我应该将哪些字段或任何内容复制到静态中?
class 的对象是从非静态方法调用的,无法更改。它创建一个对象,执行(理想情况下),并得到三角形作为结果。
class代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using DICOMViewer.Helper;
using DICOMViewer.Volume;
using DICOMViewer.ImageFlow;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;
namespace DICOMViewer.GPU
{
class MarchingCubesOnGPU
{
private static List<Triangle> theTriangles;
// CPU fields
private Point3D[] points = new Point3D[8];
private int[] values = new int[8];
private double theIsoValue;
private List<Triangle> triangles;
// GPU fields
private static PointGPU[] pointsGpu = new PointGPU[8];
static int[] valsGpu = new int[8];
private static double[] isolevelGpu = new double[1];
private static TriangleGPU[] trianglesGpu;
public static int[] EdgeTableStatic = new int[256]
{
// here are the values for edgeTable from the algorithm link
};
public static int[,] TriTableStatic = new int[256, 16]
{
// here are the values for triTable from the algorithm link
};
public MarchingCubesOnGPU(GridCell grid, double isolevel, List<Triangle> theTriangleList)
{
points = grid.p;
values = grid.val;
this.theIsoValue = isolevel;
triangles = theTriangleList;
theTriangles = new List<Triangle>();
ConvertToStandardTypes();
Execute(); // ???
}
public List<Triangle> getTriangles()
{
return theTriangles;
}
// Convert fields for GPU
public void ConvertToStandardTypes()
{
for (int i = 0; i < points.Length; i++)
{
pointsGpu[i].x = points[i].X;
pointsGpu[i].y = points[i].Y;
pointsGpu[i].z = points[i].Z;
}
valsGpu = values;
isolevelGpu[0] = theIsoValue;
for (int i = 0; i < triangles.Count; i++)
{
trianglesGpu[i].p[i].x = triangles[i].p[i].X;
trianglesGpu[i].p[i].y = triangles[i].p[i].Y;
trianglesGpu[i].p[i].z = triangles[i].p[i].Z;
}
}
public static void Execute()
{
CudafyModule km = CudafyTranslator.Cudafy();
GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
TriangleGPU[] tris;
PointGPU[] dev_points = gpu.Allocate(pointsGpu);
int[] dev_values = gpu.Allocate(valsGpu);
double[] dev_iso = gpu.Allocate<double>();
TriangleGPU[] dev_triangles = gpu.Allocate(trianglesGpu);
int[] dev_edgeTable = gpu.Allocate<int>();
int[,] dev_triangleTable = gpu.Allocate(TriTableStatic);
gpu.CopyToDevice(pointsGpu, dev_points);
gpu.CopyToDevice(valsGpu, dev_values);
gpu.CopyToDevice(isolevelGpu, dev_iso);
gpu.CopyToDevice(trianglesGpu, dev_triangles);
gpu.CopyToDevice(EdgeTableStatic, dev_edgeTable);
gpu.CopyToDevice(TriTableStatic, dev_triangleTable);
gpu.Launch().PolygoniseOnGpu(dev_iso, dev_edgeTable, dev_triangleTable, dev_points, dev_values, dev_triangles);
for (int k = 0; k < dev_triangles.Length; k++)
{
gpu.CopyFromDevice(dev_triangles, out trianglesGpu[k]);
}
for (int i = 0; i < trianglesGpu.Length; i++)
{
theTriangles[i].p[i].X = trianglesGpu[i].p[i].x;
theTriangles[i].p[i].Y = trianglesGpu[i].p[i].y;
theTriangles[i].p[i].Z = trianglesGpu[i].p[i].z;
}
gpu.FreeAll();
}
[Cudafy]
public void PolygoniseOnGpu(double[] iso, int[] edgeT, int[,] triT, PointGPU[] p, int[] v, TriangleGPU[] tri)
{
int cubeindex = 0;
for (int i = 0; i < 8; ++i)
{
if (valsGpu[i] < iso[0])
cubeindex |= 1 << i;
}
if (EdgeTableStatic[cubeindex] == 0)
return;
PointGPU[] vertList = new PointGPU[12];
// Find the vertices where the surface intersects the cube
for (int id = 1, count = 0; id < 2048; id *= 2, count++)
{
if ((edgeT[cubeindex] & id) > 0)
vertList[count] = VertexInterpolation(iso[0], p[count], p[count + 1], v[count], v[count + 1]);
}
// Create the triangle
for (int i = 0; triT[cubeindex, i] != -1; i += 3)
{
TriangleGPU triangle = new TriangleGPU(3);
triangle.p[0] = vertList[triT[cubeindex, i]];
triangle.p[1] = vertList[triT[cubeindex, i + 1]];
triangle.p[2] = vertList[triT[cubeindex, i + 2]];
tri[i] = triangle;
}
}
}
[Cudafy]
public struct TriangleGPU
{
public PointGPU[] p;
public TriangleGPU(int t)
{
p = new PointGPU[t];
}
}
[Cudafy]
public struct PointGPU
{
public double x;
public double y;
public double z;
public PointGPU(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
}
ADDED:Execute 应该是一个静态方法,但它只能从静态调用。在其他情况下,行:
CudafyModule km = CudafyTranslator.Cudafy();
不起作用,因为它不受非静态调用 Execute.
的支持
换句话说,我应该创建和填充哪些字段或其他任何东西来拥有一个独立的静态实体来调用执行?
抱歉误传。问题出在 public void PolygoniseOnGpu(...) 中。它没有被标记为静态的。
我正在使用 Cudafy 将 algorithm 重写为 GPU。我需要调用 Execute() from 静态方法。需要在GPU上计算。我怎么能这样做?我应该将哪些字段或任何内容复制到静态中?
class 的对象是从非静态方法调用的,无法更改。它创建一个对象,执行(理想情况下),并得到三角形作为结果。
class代码是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using DICOMViewer.Helper;
using DICOMViewer.Volume;
using DICOMViewer.ImageFlow;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;
namespace DICOMViewer.GPU
{
class MarchingCubesOnGPU
{
private static List<Triangle> theTriangles;
// CPU fields
private Point3D[] points = new Point3D[8];
private int[] values = new int[8];
private double theIsoValue;
private List<Triangle> triangles;
// GPU fields
private static PointGPU[] pointsGpu = new PointGPU[8];
static int[] valsGpu = new int[8];
private static double[] isolevelGpu = new double[1];
private static TriangleGPU[] trianglesGpu;
public static int[] EdgeTableStatic = new int[256]
{
// here are the values for edgeTable from the algorithm link
};
public static int[,] TriTableStatic = new int[256, 16]
{
// here are the values for triTable from the algorithm link
};
public MarchingCubesOnGPU(GridCell grid, double isolevel, List<Triangle> theTriangleList)
{
points = grid.p;
values = grid.val;
this.theIsoValue = isolevel;
triangles = theTriangleList;
theTriangles = new List<Triangle>();
ConvertToStandardTypes();
Execute(); // ???
}
public List<Triangle> getTriangles()
{
return theTriangles;
}
// Convert fields for GPU
public void ConvertToStandardTypes()
{
for (int i = 0; i < points.Length; i++)
{
pointsGpu[i].x = points[i].X;
pointsGpu[i].y = points[i].Y;
pointsGpu[i].z = points[i].Z;
}
valsGpu = values;
isolevelGpu[0] = theIsoValue;
for (int i = 0; i < triangles.Count; i++)
{
trianglesGpu[i].p[i].x = triangles[i].p[i].X;
trianglesGpu[i].p[i].y = triangles[i].p[i].Y;
trianglesGpu[i].p[i].z = triangles[i].p[i].Z;
}
}
public static void Execute()
{
CudafyModule km = CudafyTranslator.Cudafy();
GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target, CudafyModes.DeviceId);
gpu.LoadModule(km);
TriangleGPU[] tris;
PointGPU[] dev_points = gpu.Allocate(pointsGpu);
int[] dev_values = gpu.Allocate(valsGpu);
double[] dev_iso = gpu.Allocate<double>();
TriangleGPU[] dev_triangles = gpu.Allocate(trianglesGpu);
int[] dev_edgeTable = gpu.Allocate<int>();
int[,] dev_triangleTable = gpu.Allocate(TriTableStatic);
gpu.CopyToDevice(pointsGpu, dev_points);
gpu.CopyToDevice(valsGpu, dev_values);
gpu.CopyToDevice(isolevelGpu, dev_iso);
gpu.CopyToDevice(trianglesGpu, dev_triangles);
gpu.CopyToDevice(EdgeTableStatic, dev_edgeTable);
gpu.CopyToDevice(TriTableStatic, dev_triangleTable);
gpu.Launch().PolygoniseOnGpu(dev_iso, dev_edgeTable, dev_triangleTable, dev_points, dev_values, dev_triangles);
for (int k = 0; k < dev_triangles.Length; k++)
{
gpu.CopyFromDevice(dev_triangles, out trianglesGpu[k]);
}
for (int i = 0; i < trianglesGpu.Length; i++)
{
theTriangles[i].p[i].X = trianglesGpu[i].p[i].x;
theTriangles[i].p[i].Y = trianglesGpu[i].p[i].y;
theTriangles[i].p[i].Z = trianglesGpu[i].p[i].z;
}
gpu.FreeAll();
}
[Cudafy]
public void PolygoniseOnGpu(double[] iso, int[] edgeT, int[,] triT, PointGPU[] p, int[] v, TriangleGPU[] tri)
{
int cubeindex = 0;
for (int i = 0; i < 8; ++i)
{
if (valsGpu[i] < iso[0])
cubeindex |= 1 << i;
}
if (EdgeTableStatic[cubeindex] == 0)
return;
PointGPU[] vertList = new PointGPU[12];
// Find the vertices where the surface intersects the cube
for (int id = 1, count = 0; id < 2048; id *= 2, count++)
{
if ((edgeT[cubeindex] & id) > 0)
vertList[count] = VertexInterpolation(iso[0], p[count], p[count + 1], v[count], v[count + 1]);
}
// Create the triangle
for (int i = 0; triT[cubeindex, i] != -1; i += 3)
{
TriangleGPU triangle = new TriangleGPU(3);
triangle.p[0] = vertList[triT[cubeindex, i]];
triangle.p[1] = vertList[triT[cubeindex, i + 1]];
triangle.p[2] = vertList[triT[cubeindex, i + 2]];
tri[i] = triangle;
}
}
}
[Cudafy]
public struct TriangleGPU
{
public PointGPU[] p;
public TriangleGPU(int t)
{
p = new PointGPU[t];
}
}
[Cudafy]
public struct PointGPU
{
public double x;
public double y;
public double z;
public PointGPU(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
}
ADDED:Execute 应该是一个静态方法,但它只能从静态调用。在其他情况下,行:
CudafyModule km = CudafyTranslator.Cudafy();
不起作用,因为它不受非静态调用 Execute.
的支持换句话说,我应该创建和填充哪些字段或其他任何东西来拥有一个独立的静态实体来调用执行?
抱歉误传。问题出在 public void PolygoniseOnGpu(...) 中。它没有被标记为静态的。