CUDA中不同内核之间的设备变量

时间:2019-11-28 00:45:11

标签: cuda gpu

我有一个包含两行的数组,并且我有两个内核来计算每一行的值。 第二个内核需要使用第一行来计算第二行。我认为这不会有问题,因为设备变量在整个应用程序中都有效,并在下面编写了代码。

#define IDX(x, y, N) (x * N + y)

__global__ void first_forward(int N, int K, float * alpha)
{
    int x = blockIdx.x * BLOCK_SIZE + threadIdx.x;
    alpha[IDX(0, x, N)] = tex1Dfetch(text_pi,x) + tex1Dfetch(text_B,IDX(x, tex1Dfetch(text_O, 0), K)); 
}

__global__ void forward_step(float * alpha, int N, int K, int step){
    int bx = blockIdx.x;
    int tx = threadIdx.x;
    int x = bx * BLOCK_SIZE + tx;
    float sum = logf(0);

    __shared__ float salpha[BLOCK_SIZE];
    __shared__ float sB[BLOCK_SIZE];

    int i,j;
    for(i = 0; i < N; i+= BLOCK_SIZE){
        // if i + tx < N

        salpha[tx] = alpha[IDX(step-1,i + tx, N)];

        sB[tx] = tex1Dfetch(text_B, IDX(x, tex1Dfetch(text_O, step), K));


        __syncthreads();
        printf("thread %x, loop %d , indexes: %d, %d ,salpha %.4f \n", x, i, step-1, i+ tx, exp(alpha[IDX(step-1,i + tx, N)]));


        for(j = 0; j < BLOCK_SIZE; j++)
            sum = add_logs(sum, salpha[j] + tex1Dfetch(text_A, IDX(i + j, x, N)) + sB[tx]);

        __syncthreads();
    }

    alpha[IDX(step, x, N)] = sum;
    printf("thread %d, step %d result %.4f \n", x, step, sum);



}

int main(int argc, char *argv[]){

float *A, *B, *pi, *alpha, *beta, *xi, *gamm;
float *dA, *dB, *dpi, *dbeta, *dalpha, *dxi, *dgamm;

....


checkCudaErrors( cudaMalloc((void**)&dalpha, sizeof(float) * N * L));
checkCudaErrors( cudaMalloc((void**)&dbeta, sizeof(float) * N * L));

first_forward<<<dimGrid, dimBlock, 0, stream_forw>>>(N,K, dalpha);
forward_step<<<dimGrid, dimBlock, 0, stream_forw>>>(dalpha, N, K, i);

checkCudaErrors(cudaMemcpyAsync(alpha + i * N,dalpha,N * sizeof(float),cudaMemcpyDeviceToHost, stream_forw));
checkCudaErrors(cudaMemcpyAsync(alpha,dalpha,N * sizeof(float),cudaMemcpyDeviceToHost, stream_forw));
}


当我在第二个内核(forward_step)中打印dalpha的第一行值时,所有值都打印为1.0s。但是,当我将变量dalpha复制到host并打印第一行值时,它们都是正确的。为什么会发生这种情况?由于我的第二个内核没有获得第一行的值,所以我所有的计算都是错误的。

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。由于某种原因,每当我试图以alpha[IDX(step-1,i + tx, N)]的形式到达内核中的alpha时,都无法获得正确的结果。我将其更改为alpha[IDX((step-1),(i + tx), N)],一切都很好。