Hello everyone, I am trying to use CUDA to initial a signed distance function by forward Euler PDE method from a zero-contour SDF, here is my CUDA core code
texture<float, 3, cudaReadModeElementType> Tex3DRef;
#define M_PI 3.14159265358979323846f
__device__ float Heaviside(float Phi, float Eps)
{
if( Phi > Eps )
return 1.0f;
if( Phi < -Eps )
return 0.0f;
return 0.5f*(1.0f + Phi/Eps + 1.0f/M_PI*sin(M_PI*Phi/Eps));
}
__device__ float Sign(float Phi, float Eps)
{
return 2.0f*(Heaviside(Phi, Eps) - 0.5f);
}
__global__ void Reinitialization3D(float* Phi, float Eps, unsigned Res)
{
int BlockSize = blockDim.x*blockDim.y;
int BlockOffset = blockIdx.x*BlockSize;
int GridOffset = Res*Res*blockIdx.y;
int ThreadOffset = threadIdx.y*blockDim.x + threadIdx.x;
int Idx = ThreadOffset + BlockOffset + GridOffset;
int Z = blockIdx.y;
int XY = ThreadOffset + BlockOffset;
int X = XY % Res;
int Y = ( XY - X ) / Res;
float delta = 1.0f / (float)Res;
float dt = delta*0.001;
float3 Coord = make_float3( (float)X + 0.5, (float)Y + 0.5, (float)Z + 0.5 );
float C = tex3D( Tex3DRef, Coord.x, Coord.y, Coord.z );
float L = tex3D( Tex3DRef, Coord.x - 1.0, Coord.y, Coord.z );
float R = tex3D( Tex3DRef, Coord.x + 1.0, Coord.y, Coord.z );
float D = tex3D( Tex3DRef, Coord.x, Coord.y - 1.0, Coord.z );
float U = tex3D( Tex3DRef, Coord.x, Coord.y + 1.0, Coord.z );
float B = tex3D( Tex3DRef, Coord.x, Coord.y, Coord.z - 1.0 );
float F = tex3D( Tex3DRef, Coord.x, Coord.y, Coord.z + 1.0 );
float dPhidX = 0.5*(R - L)/delta;
float dPhidY = 0.5*(U - D)/delta;
float dPhidZ = 0.5*(F - B)/delta;
float Len = sqrt( dPhidX*dPhidX + dPhidY*dPhidY + dPhidZ*dPhidZ );
float S = Sign(C,Eps);
float Phi_one = C + S*(1.0f - Len)*dt;
Phi[Idx] = Phi_one;
}
In my main program, I will copy newer data from Phi back to texture reference memory at each new step,
CUDA_MEMCPY3D XchgDesc;
memset(&XchgDesc,0,sizeof(CUDA_MEMCPY3D));
XchgDesc.srcMemoryType = CU_MEMORYTYPE_DEVICE;
XchgDesc.srcPitch = Pitch;
XchgDesc.srcDevice = Phi;
XchgDesc.dstMemoryType = CU_MEMORYTYPE_ARRAY;
XchgDesc.dstArray = Tex3DArray;
XchgDesc.WidthInBytes = LineSize;
XchgDesc.Height = Height;
XchgDesc.Depth = Depth;
cuFuncSetBlockShape(Func,16,16,1);
while(k--)
{
cuLaunchGrid(Func,Width*Height/256,Depth);
cuMemcpy3D(&XchgDesc);
}
cuMemcpyDtoH(TentField.data(),Phi,TotalSize);
cuMemFree(Phi);
cuArrayDestroy(Tex3DArray);
But the 2D result seems a little wrong, because the size of each dimesion is 1.0, so the center distance should be -0.5 or some others larger values. Is there any experienced people would like to help me ? Thanks !