2017-02-24 9 views
-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(); 

は動作しませんを実行します。

つまり、独立した静的なエンティティに実行を呼び出させるために、新しい静的メソッドを作成して入力する必要がありますか?

+1

非常に不明です。問題はどこだ? Cudafyはこの問題にも関係しているのですか、それとも単なるコードレビューですか?何がうまくいかない?これは本当にあなたが提供できる最小のコード例ですか? – Kilazur

+0

'Execute'のように見えます。それ自体はすでに静的なので、' MarchingCubesOnGPU.Execute() 'のように呼び出すことができます。 – Abion47

+0

@ Abion47 Executeは静的ですが、staticからのみ呼び出すことができます(他はCudafyでサポートされていません) –

答えて

0

申し訳ありません。問題はちょうどにありました。public void PolygoniseOnGpu(...)。それは静的ではなかった。

関連する問題