-1
私はalgorithmをCudafyでGPUに書き直しています。 Execute()から静的メソッドを呼び出す必要があります。 GPUで計算する必要があります。どうすればこのことができますか?どのフィールドや何かを静的にコピーする必要がありますか?クラス内の静的メソッドとフィールドを作成
クラスのオブジェクトが非静的メソッドから呼び出され、変更できませんでした。オブジェクトを作成し、Execute(理想的には)を実行し、結果として三角形を取得します。
クラスコードは次のとおり
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:実行し、それがなければならないような静的メソッドであるが、それは唯一の静的から呼び出すことができます。他のケースで行:それは非静的callesからサポートされていないため、
CudafyModule km = CudafyTranslator.Cudafy();
は動作しませんを実行します。
つまり、独立した静的なエンティティに実行を呼び出させるために、新しい静的メソッドを作成して入力する必要がありますか?
非常に不明です。問題はどこだ? Cudafyはこの問題にも関係しているのですか、それとも単なるコードレビューですか?何がうまくいかない?これは本当にあなたが提供できる最小のコード例ですか? – Kilazur
'Execute'のように見えます。それ自体はすでに静的なので、' MarchingCubesOnGPU.Execute() 'のように呼び出すことができます。 – Abion47
@ Abion47 Executeは静的ですが、staticからのみ呼び出すことができます(他はCudafyでサポートされていません) –