Странное поведение программы CUDA, и я не могу найти ошибку cuda-dbg

Я хочу реализовать MonteCarlo, используя CUDA.

Я пишу свой код на ПК с Win8, используя Visual Studio2012/CUDA 5.5/GT 720M, и он работает хорошо.

Затем я попытался скомпилировать мой код в REHL5.3/Tesla C1060/CUDA 2.3, но результат оказался неверным.

Тогда я хочу использовать cuda-gdb для его отладки

но когда я компилирую свой код следующим образом:

nvcc -arch=sm_13 -o my_program my_program.cu

результат неверный. Однако я не могу отладить его, потому что это не отлаживаемый код.

Когда я собираю это так:

nvcc -g -G -arch=sm_13 -o my_program my_program.cu

Результат, на этот раз, исправьте... Так что я все еще не могу найти свою ошибку, отлаживая ее...

код выглядит так, функция __device__ double monte_carlo_try() не в реальном коде. проблема в том, что если я проверяю значение test[], я нахожу, что все значения верны. Так что должна быть какая-то ошибка в части сокращения.

#include<stdio.h>
#include<cuda_runtime.h>
#include<device_launch_parameters.h>
#include<cuda.h>
#include<malloc.h>
#include<time.h>

#define B 4 //block number
#define T 4 //number of threads per block
#define P 4 //number of paths per thread
__device__ float monte_carlo_try()
{
    return 3.0;
}
__global__ void monte_carlo(float*test,    float*result)
{
    int bid=blockIdx.x;
    int tid=threadIdx.x + blockIdx.x * blockDim.x;
    int idx=threadIdx.x;

    __shared__ float cache[T];
    cache[idx]=0;



    float temp=0;
    for(int i=0;i<P;i++)
    {
        temp+=monte_carlo_try();    //monte_carlo_try: __device__ function do monte carlo test
    }


    cache[idx]=temp;
    test[tid]=cache[idx];
    __syncthreads();
    //result[] is the output, and I use test[] to check whether I have got the right cache[idx]
    //and the value of test[] is same with what I expect

    int i=blockDim.x/2;
    while(i>0)
    {
        if(idx<i)
            cache[idx]+=cache[idx+i];
        __syncthreads();
        i/=2;
    }
    result[bid]=cache[0];
}

int main()
{
    void check_err(cudaError_t );


    cudaSetDevice(0);
    cudaError_t s_flag;
    float *dev_v;
    float *dev_test;

    s_flag=cudaMalloc((void**)&dev_v,B*sizeof(float));
    check_err(s_flag);


    cudaMalloc((void**)&dev_test,B*T*sizeof(float));
    check_err(s_flag);

    monte_carlo<<<B,T>>>(dev_test,dev_v);
    s_flag=cudaGetLastError();
    check_err(s_flag);

    float v[B];
    float test[B*T];
    s_flag=cudaMemcpy(v,dev_v,B*sizeof(float),cudaMemcpyDeviceToHost);
    check_err(s_flag);

    s_flag=cudaMemcpy(test,dev_test,B*T*sizeof(float),cudaMemcpyDeviceToHost);
    check_err(s_flag);

    float sum=0;
    for(int i=0;i<B;i++)
    {
        sum+=v[i];
    }
    printf("result:%f\n",sum/(B*T*P));
    for(int i=0;i<B*T;i++)
    {
        printf("test[%d]=%f\n",i,test[i]);
    }
    cudaFree(dev_v);
    cudaFree(dev_test);
    return 0;
}
void check_err(cudaError_t f)
{
    if(f != cudaSuccess)
        printf("error msg:%s\n",cudaGetErrorString(f));
}

1 ответ

Вы, вероятно, имеете в виду для этой строки в main():

cudaMalloc((void**)*dev_test,B*T*sizeof(float));

читать так вместо этого:

cudaMalloc((void**)&dev_test,B*T*sizeof(float));

Дополнительно звоните

monte_carlo(dev_test,dev_v);

поскольку monte_carlo Ядро CUDA, вы, вероятно, должны установить количество блоков и потоков, с которыми должно запускаться ядро:

monte_carlo<<<num_blocks, threads_per_block>>>(dev_test, dev_v);
Другие вопросы по тегам