簡體   English   中英

在類中創建靜態方法和字段

[英]Make static methods and fields in class

我正在使用Cudafy將算法重寫為GPU。 我需要靜態方法調用Execute() 有必要在GPU上進行計算。 我該怎么辦? 我應將哪些字段或任何內容復制到靜態內容?

該類的對象是從非靜態方法調用的,無法更改。 它創建一個對象,使(理想情況下)執行,並獲得三角形作為結果。

類代碼為:

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;
        }
    }   
}

添加 :Execute是應該使用的靜態方法,但只能從靜態調用。 在其他情況下,該行:

CudafyModule km = CudafyTranslator.Cudafy();

不起作用,因為非靜態調用Execute不支持它。

換句話說,我應該創建哪些字段或其他任何內容並填寫新的靜態方法以具有獨立的靜態實體來調用execute?

很抱歉提供虛假信息。 問題出在公共無效的PolygoniseOnGpu(...)中 並沒有指出它是靜態的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM