初始化常量全局数组CUDA C.

时间:2014-10-03 19:56:08

标签: cuda

我有问题!我需要在cuda c中初始化一个常量全局数组。要初始化数组,我需要使用for!我需要这样做,因为我必须在某些内核中使用这个数组,而我的教授告诉我将其定义为只在设备中可见的常量。

我该怎么做?

我想做这样的事情:

#include <stdio.h>
#include <math.h>
#define N 8

__constant__ double H[N*N];

__global__ void prodotto(double *v, double *w){

        int k=threadIdx.x+blockDim.x*blockIdx.x;

        w[k]=0;
        for(int i=0;i<N;i++) w[k]=w[k]+H[k*N+i]*v[i];
}

int main(){

        double v[8]={1, 1, 1, 1, 1, 1, 1, 1};
        double *dev_v, *dev_w, *w;
        double *host_H;
        host_H=(double*)malloc((N*N)*sizeof(double));
        cudaMalloc((void**)&dev_v,sizeof(double));
        cudaMalloc((void**)&dev_w,sizeof(double));

        for(int k=0;k<N;k++){
            host_H[2*N*k+2*k]=1/1.414;
            host_H[2*N*k+2*k+1]=1/1.414;
            host_H[(2*k+1)*N+2*k]=1/1.414;
            host_H[(2*k+1)+2*k+1]=-1/1.414;

        }

        cudaMemcpyToSymbol(H, host_H, (N*N)*sizeof(double));
        cudaMemcpy(dev_v, v, N*sizeof(double), cudaMemcpyHostToDevice); 
        cudaMemcpy(dev_w, w, N*sizeof(double), cudaMemcpyHostToDevice); 

        prodotto<<<1,N>>>(dev_v, dev_w);

        cudaMemcpy(v, dev_v, N*sizeof(double), cudaMemcpyDeviceToHost); 
        cudaMemcpy(w, dev_w, N*sizeof(double), cudaMemcpyDeviceToHost); 


        for(int i=0;i<N;i++) printf("\n%f   %f", v[i], w[i]);

        return 0;
    }

但是输出是一个零数组......我希望输出数组用矩阵H(这里看作数组)和数组v的乘积填充。 谢谢!!!!!

1 个答案:

答案 0 :(得分:5)

这样的事情应该有效:

#define DSIZE 32
__constant__ int mydata[DSIZE];

int main(){
  ...
  int *h_mydata;
  h_mydata = new int[DSIZE];
  for (int i = 0; i < DSIZE; i++)
    h_mydata[i] = ....;   // initialize however you wish
  cudaMemcpyToSymbol(mydata, h_mydata, DSIZE*sizeof(int));
  ...
}

不难。然后,您可以直接在内核中使用__constant__数据:

__global__ void mykernel(...){
  ...
  int myval = mydata[threadIdx.x];
  ...
  }

您可以在programming guide中了解__constant__个变量。从设备代码(内核代码)的角度来看,__constant__变量是只读。但是从主持人那里可以使用cudaMemcpyToSymbol/cudaMemcpyFromSymbol API来阅读或写入。

编辑:根据您现在发布的代码,至少有2个错误:

  1. dev_vdev_w的分配大小不正确。
  2. 您没有w的主机分配。
  3. 以下代码似乎对我有正确的解决方法:

    $ cat t579.cu
    #include <stdio.h>
    #include <math.h>
    #define N 8
    
    __constant__ double H[N*N];
    
    __global__ void prodotto(double *v, double *w){
    
            int k=threadIdx.x+blockDim.x*blockIdx.x;
    
            w[k]=0;
            for(int i=0;i<N;i++) w[k]=w[k]+H[k*N+i]*v[i];
    }
    
    int main(){
    
            double v[N]={1, 1, 1, 1, 1, 1, 1, 1};
            double *dev_v, *dev_w, *w;
            double *host_H;
            host_H=(double*)malloc((N*N)*sizeof(double));
            w     =(double*)malloc(  (N)*sizeof(double));
            cudaMalloc((void**)&dev_v,N*sizeof(double));
            cudaMalloc((void**)&dev_w,N*sizeof(double));
    
            for(int k=0;k<N;k++){
                host_H[2*N*k+2*k]=1/1.414;
                host_H[2*N*k+2*k+1]=1/1.414;
                host_H[(2*k+1)*N+2*k]=1/1.414;
                host_H[(2*k+1)+2*k+1]=-1/1.414;
    
            }
    
            cudaMemcpyToSymbol(H, host_H, (N*N)*sizeof(double));
            cudaMemcpy(dev_v, v, N*sizeof(double), cudaMemcpyHostToDevice);
            cudaMemcpy(dev_w, w, N*sizeof(double), cudaMemcpyHostToDevice);
    
            prodotto<<<1,N>>>(dev_v, dev_w);
    
            cudaMemcpy(v, dev_v, N*sizeof(double), cudaMemcpyDeviceToHost);
            cudaMemcpy(w, dev_w, N*sizeof(double), cudaMemcpyDeviceToHost);
    
    
            for(int i=0;i<N;i++) printf("\n%f   %f", v[i], w[i]);
            printf("\n");
            return 0;
        }
    $ nvcc -arch=sm_20 -o t579 t579.cu
    $ cuda-memcheck ./t579
    ========= CUDA-MEMCHECK
    
    1.000000   0.000000
    1.000000   -0.707214
    1.000000   -0.707214
    1.000000   -1.414427
    1.000000   1.414427
    1.000000   0.707214
    1.000000   1.414427
    1.000000   0.707214
    ========= ERROR SUMMARY: 0 errors
    $
    

    一些注意事项:

    1. 如果您在使用CUDA代码时遇到问题,使用proper cuda error checking是一种很好的做法。
    2. 您可以使用cuda-memcheck运行代码(就像我上面一样),以快速了解是否遇到任何CUDA错误。
    3. 我没有验证数值结果或通过数学计算。如果它不是你想要的,我认为你可以解决它。
    4. 我没有对您的代码进行任何更改,除了我似乎明智的解决明显错误并使结果可用于教育目的。当然可以讨论首选分配方法,printfcout,以及你有什么。我在这个答案中主要关注CUDA主题。