CUDA 5.0名称空间用于恒定内存变量使用
在我的程序中,我想使用一个包含常量变量的结构,并在程序执行到完成的整个过程中将其保持在设备上 我有几个头文件,其中包含“global”函数的声明以及它们各自的.cu”文件的定义。我保留了这个方案,因为它帮助我在一个地方包含类似的代码。e、 g.完成“内核1”所需的所有“设备”函数与完成“内核2”所需的那些“设备”函数以及内核定义分开 在编译和链接期间,我对该方案没有任何问题。直到我遇到常量变量。我想在所有内核和设备函数中使用相同的常量变量,但它似乎不起作用CUDA 5.0名称空间用于恒定内存变量使用,cuda,namespaces,Cuda,Namespaces,在我的程序中,我想使用一个包含常量变量的结构,并在程序执行到完成的整个过程中将其保持在设备上 我有几个头文件,其中包含“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
,我已经给出了答案,请参见下文。我认为您的第二个版本是可以的,但也许您忘记了生成一个可重定位的代码?