因此,我正在从此类中进行作业,我们必须使用给定的算法制作cuda版本,而根据我的实际知识将无法正常工作。
我尝试这样做,但是结果Buffer充满了相同的数字。我认为问题在于如何获取每个点的索引,因为我不完全了解网格/块/线程ID和组织的工作方式。
给出的功能
int SimulacionTornoCPU(int pasossim, int vtotal, int utotal)
{
/* Parametros de mecanizado */
double incA = 360.0 / (double)PuntosVueltaHelicoide;
for (int u = 0; u < S.UPoints; u++) /* Para cada punto de la superficie */
{
for (int v = 0; v < S.VPoints; v++)
{
double AvanceMin = 1e10;
double angle = 0.0;
for (int i = 0; i < pasossim; i++) /* Giro del torno en el eje X */
{
// Se rota el punto actual (solo interesa la coordenada y)
double py = S.Buffer[v][u].y * cos(angle*M_PI_180) - S.Buffer[v][u].z * sin(angle*M_PI_180);
// Calcula la distancia al origen del punto transformado
// Si y es la menor se almacena
if (py < AvanceMin)
{
AvanceMin = py;
}
angle += incA;
}
int p = S.VPoints*u + v;
CPUBufferMenorY[p] = AvanceMin;
}
}
return OKSIM;
}
我试图解决的问题:
__global__
void calculo(double* GPUBufferMenorY, TSurf S, double* incremento, int* pasossim){
const int i = blockIdx.x * blockDim.x + threadIdx.x;
const int j = blockIdx.y * blockDim.y + threadIdx.y;
//printf(" ( %f , %f )\n", S.Buffer[i][j].y, S.Buffer[i][j].z);
if (i < S.UPoints && j < S.VPoints){
double angulo = 0.00;
double avance = 1<<20;
for (size_t w = 0; w < *pasossim; w++) /* Giro del torno en el eje X */
{
// Se rota el punto actual (solo interesa la coordenada y)
double py = S.Buffer[i][j].y * cos(angulo*M_PI_180) - S.Buffer[i][j].z * sin(angulo*M_PI_180);
// Calcula la distancia al origen del punto transformado
// Si y es la menor se almacena
if (py < avance)
{
avance = py;
}
angulo += *incremento;
}
GPUBufferMenorY[i*(S.VPoints)+j] = avance;
}
}
int SimulacionTornoGPU(int *pasossim, int *vtotal, int *utotal){
double *incA;
double aux = 360.0 / (double)PuntosVueltaHelicoide;
double* device_GPU;
incA = &aux;
cudaMallocManaged(&pasossim, sizeof(int));
cudaMallocManaged(&incA, sizeof(double));
cudaMalloc(&device_GPU, S.VPoints*S.UPoints * sizeof(double));
cudaMemcpy(device_GPU,GPUBufferMenorY, S.VPoints*S.UPoints * sizeof(double), cudaMemcpyHostToDevice);
int blockSize = 256;
int numBlocks = (S.VPoints*S.UPoints + blockSize - 1) / blockSize;
calculo<<<numBlocks, blockSize>>>(device_GPU,S,incA,pasossim);
cudaDeviceSynchronize();
cudaMemcpy( GPUBufferMenorY, device_GPU, S.VPoints*S.UPoints * sizeof(double), cudaMemcpyDeviceToHost);
cudaFree(pasossim);
cudaFree(incA);
cudaFree(vtotal);
cudaFree(utotal);
cudaFree(device_GPU);
return OKSIM;
}
这是使用的结构和变量(由老师完成):
struct sTPoint3D
{
double x;
double y;
double z;
};
typedef struct sTPoint3D TPoint3D;
typedef struct sTConf TConf;
struct sTSurf
{
int UPoints;
int VPoints;
TPoint3D** Buffer;
};
typedef struct sTSurf TSurf;
//GLOBAL VARIABLES
TSurf S;
double* GPUBufferMenorY;
double* CPUBufferMenorY;
double PasoHelicoide;
int PuntosVueltaHelicoide;
输出应该在-10到0之间,但应该是-6.2somethingx e22或1百万