CUDA 5.0名称空间用于恒定内存变量使用

CUDA 5.0名称空间用于恒定内存变量使用,cuda,namespaces,Cuda,Namespaces,在我的程序中,我想使用一个包含常量变量的结构,并在程序执行到完成的整个过程中将其保持在设备上 我有几个头文件,其中包含“global”函数的声明以及它们各自的.cu”文件的定义。我保留了这个方案,因为它帮助我在一个地方包含类似的代码。e、 g.完成“内核1”所需的所有“设备”函数与完成“内核2”所需的那些“设备”函数以及内核定义分开 在编译和链接期间,我对该方案没有任何问题。直到我遇到常量变量。我想在所有内核和设备函数中使用相同的常量变量,但它似乎不起作用 ###################

在我的程序中,我想使用一个包含常量变量的结构,并在程序执行到完成的整个过程中将其保持在设备上

我有几个头文件,其中包含“global”函数的声明以及它们各自的.cu”文件的定义。我保留了这个方案,因为它帮助我在一个地方包含类似的代码。e、 g.完成“内核1”所需的所有“设备”函数与完成“内核2”所需的那些“设备”函数以及内核定义分开

在编译和链接期间,我对该方案没有任何问题。直到我遇到常量变量。我想在所有内核和设备函数中使用相同的常量变量,但它似乎不起作用

##########################################################################
                                CODE EXAMPLE
###########################################################################
filename: 'common.h'
--------------------------------------------------------------------------
typedef struct {
    double height;
    double weight;
    int age;
} __CONSTANTS;

__constant__ __CONSTANTS d_const;

---------------------------------------------------------------------------
filename: main.cu
---------------------------------------------------------------------------
#include "common.h"
#include "gpukernels.h"
int main(int argc, char **argv) {

    __CONSTANTS T;
    T.height   = 1.79;
    T.weight   = 73.2;
    T.age      = 26;

    cudaMemcpyToSymbol(d_const, &T, sizeof(__CONSTANTS));
    test_kernel <<< 1, 16 >>>();
    cudaDeviceSynchronize();
}

---------------------------------------------------------------------------
filename: gpukernels.h
---------------------------------------------------------------------------
__global__ void test_kernel();

---------------------------------------------------------------------------
filename: gpukernels.cu
---------------------------------------------------------------------------
#include <stdio.h>
#include "gpukernels.h"
#include "common.h"

__global__ void test_kernel() {
    printf("Id: %d, height: %f, weight: %f\n", threadIdx.x, d_const.height, d_const.weight);
}
##########################################################################
代码示例
###########################################################################
文件名:“common.h”
--------------------------------------------------------------------------
类型定义结构{
双高;
双倍重量;
智力年龄;
}_u_常数;
__常数d______常数d_常数;
---------------------------------------------------------------------------
文件名:main.cu
---------------------------------------------------------------------------
#包括“common.h”
#包括“gpukernels.h”
int main(int argc,字符**argv){
__常数T;
T.高度=1.79;
T.重量=73.2;
T.年龄=26岁;
cudaMemcpyToSymbol(d_常数,&T,sizeof(__常数));
测试内核>();
cudaDeviceSynchronize();
}
---------------------------------------------------------------------------
文件名:gpukernels.h
---------------------------------------------------------------------------
__全局无效测试内核();
---------------------------------------------------------------------------
文件名:gpukernels.cu
---------------------------------------------------------------------------
#包括
#包括“gpukernels.h”
#包括“common.h”
__全局无效测试内核(){
printf(“Id:%d,高度:%f,重量:%f\n”,threadIdx.x,d_const.height,d_const.weight);
}
当我执行这段代码时,内核执行,显示线程ID,但常量值显示为零。我怎样才能解决这个问题

建议的修改
filename:gpukernels.h
----------------------------------------------------------------------
__全局无效测试内核();
----------------------------------------------------------------------
文件名:gpukernels.cu
----------------------------------------------------------------------
#包括
#包括“common.h”
#包括“gpukernels.h”
外部“C”\uuuu常数\uuuu常数d\u常数;
__全局无效测试内核(){
printf(“Id:%d,高度:%f,重量:%f\n”,threadIdx.x,d_const.Height,d_const.Weight);
}
----------------------------------------------------------------------
文件名:common.h
----------------------------------------------------------------------
类型定义结构{
双高;
双倍重量;
智力年龄;
}_u_常数;
----------------------------------------------------------------------
文件名:main.cu
----------------------------------------------------------------------
#包括“common.h”
#包括“gpukernels.h”
__常数d______常数d_常数;
int main(int argc,字符**argv){
__常数T;
T.高度=1.79;
T.重量=73.2;
T.年龄=26岁;
cudaMemcpyToSymbol(d_常数,&T,sizeof(__常数));
测试内核>();
cudaDeviceSynchronize();
返回0;
}

因此,正如建议的那样,我尝试了代码,但仍然不起作用。我错过了什么吗?

下面,我报告了对我有效的解决方案。请记住,您使用的是单独编译,因此不要忘记使用生成可重定位设备代码(-rdc=true选项)

文件main.cu

#include <cuda.h>
#include <cuda_runtime.h>

typedef struct {
    double height;
    double weight;
    int age;
} __CONSTANTS;

__constant__ __CONSTANTS d_const;

__global__ void test_kernel();

#include <conio.h>
int main(int argc, char **argv) {

    __CONSTANTS T;
    T.height   = 1.79;
    T.weight   = 73.2;
    T.age      = 26;

    cudaMemcpyToSymbol(d_const, &T, sizeof(__CONSTANTS));
    test_kernel <<< 1, 16 >>>();
    cudaDeviceSynchronize();

    getch();
    return 0;
}
#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime.h>

typedef struct {
    double height;
    double weight;
    int age;
} __CONSTANTS;

extern __constant__ __CONSTANTS d_const;

__global__ void test_kernel() {
    printf("Id: %d, height: %f, weight: %f\n", threadIdx.x, d_const.height, d_const.weight);
}
#包括
#包括
类型定义结构{
双高;
双倍重量;
智力年龄;
}_u_常数;
__常数d______常数d_常数;
__全局无效测试内核();
#包括
int main(int argc,字符**argv){
__常数T;
T.高度=1.79;
T.重量=73.2;
T.年龄=26岁;
cudaMemcpyToSymbol(d_常数,&T,sizeof(__常数));
测试内核>();
cudaDeviceSynchronize();
getch();
返回0;
}
文件kernel.cu

#include <cuda.h>
#include <cuda_runtime.h>

typedef struct {
    double height;
    double weight;
    int age;
} __CONSTANTS;

__constant__ __CONSTANTS d_const;

__global__ void test_kernel();

#include <conio.h>
int main(int argc, char **argv) {

    __CONSTANTS T;
    T.height   = 1.79;
    T.weight   = 73.2;
    T.age      = 26;

    cudaMemcpyToSymbol(d_const, &T, sizeof(__CONSTANTS));
    test_kernel <<< 1, 16 >>>();
    cudaDeviceSynchronize();

    getch();
    return 0;
}
#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime.h>

typedef struct {
    double height;
    double weight;
    int age;
} __CONSTANTS;

extern __constant__ __CONSTANTS d_const;

__global__ void test_kernel() {
    printf("Id: %d, height: %f, weight: %f\n", threadIdx.x, d_const.height, d_const.weight);
}
#包括
#包括
#包括
类型定义结构{
双高;
双倍重量;
智力年龄;
}_u_常数;
外部常数d常数;
__全局无效测试内核(){
printf(“Id:%d,高度:%f,重量:%f\n”,threadIdx.x,d_const.height,d_const.weight);
}

我已经通过将
\uuuu global\uuuuuu
函数包含在与
main
函数相同的文件中来测试您的代码,只要您将
cudaMemcpyToSymbol
中打印错误的
d_u常量
符号更改为
d_u常量
符号是隐式静态的,它就可以工作。因为在您的例子中,您使用的是单独的编译,所以常量符号应该在每个编译单元中声明为
extern
(在您的例子中为
gpukernels.cu
),但包含定义的单元除外(在您的例子中为
main.cu
).@jackolanten但是如果是这样的话,我必须把所有的代码写回main.cu。这是我想要避免的。在我的代码中,我没有使用gpukernels.h,而是使用calculatepdf.h、calculatecdf.h等文件以及它们各自的“.cu”文件。我希望这些文件中的所有内核都能访问常量变量。@JackOLantern因此,对于每个其他内核头,我需要将其再次定义为
extern
,我已经给出了答案,请参见下文。我认为您的第二个版本是可以的,但也许您忘记了生成一个可重定位的代码?