Julia Grabovska Julia Grabovska -4 years ago 73
C# Question

Make static methods and fields in class

I'm rewriting algorithm to GPU with Cudafy. I need to call Execute() from a static method. It's necessary to calculate on GPU. How could I do this? What fields or anything should I copy into static?

Object of the class is called from non-static method and it couldn't be changed. It creates an objects, makes Execute (ideally), and gets triangles as result.

The class code is:

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 is a static method as it should be but it could be called only from static. In other case the line:

CudafyModule km = CudafyTranslator.Cudafy();


doesn't work because it is not supported from non-static calles Execute.

In other words, what fields or anything else should I create and fill in new static method to have an independent static entity to call execute?

Answer Source

Sorry for disinformation. The problem was in just public void PolygoniseOnGpu(...). It wasn't noted as static.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download