我有一个包含混合C ++,CUDA和Thrust的嵌套类的类。我想在多个文件中拆分成员定义。
// In cls.h:
#include <thrust/device_vector.h>
class cls {
class foo { // define in foo.cu (include "cls.h")
kernelWrapper();
}
class bar { // define in bar.cu (include "cls.h")
thrust::device_vector A;
thrustStuff();
}
thrust::device_vector B;
pureCPP(); // define in cls.cpp (include "cls.h")
moreThrust(); // define in cls.cu (include "cls.h")
}
在每个定义文件中,我只是#include "cls.h"
。但是,无论我尝试什么,我目前都会收到各种各样的编译器错误,例如pureCPP was referenced but not defined
。
我读过Thrust只能用于.cu
个文件。因为我的父类cls
声明了诸如B
之类的Thrust类型变量(因此#include
s thrust/device_vector.h
),这会强制所有文件#include
{{1要制作成cls.h
个文件?
在这种情况下,我在哪里使用.cu
?我认为extern "C"
会要求cls.cpp
文件中的所有功能都包含在.cu
中,但extern "C"
到.cu
次调用会怎样,例如.cu
致电moreThrust()
我也知道类的成员不能使用bar::thrustStuff()
,所以我是否必须为每个成员函数编写一个extern "C"
包装函数?
我对如何使这一切工作完全感到困惑 - 每个文件需要extern "C"
和#include
的鸡尾酒?
答案 0 :(得分:0)
以你的小例子为例,编译并运行正常
/*
Inside File cls.h
*/
#pragma once
#include <thrust/device_vector.h>
#include <stdio.h>
class cls {
public:
class foo { // define in foo.cu (include "cls.h")
public:
void kernelWrapper();
};
class bar { // define in bar.cu (include "cls.h")
thrust::device_vector<int> A;
public:
void thrustStuff();
};
public:
void pureCPP(); // define in cls.cpp (include "cls.h")
void moreThrust(); // define in cls.cu (include "cls.h")
private:
thrust::device_vector<int> B;
};
/*
Inside File foo.cu
*/
#include "cls.h"
void cls::foo::kernelWrapper()
{
printf("kernelWrapper\n");
}
/*
Inside File bar.cu
*/
#include "cls.h"
void cls::bar::thrustStuff()
{
printf("Thrust Stuff\n");
}
/*
Inside File cls.cpp
*/
#include "cls.h"
void cls::pureCPP()
{
printf("pureCPP\n");
}
/*
Inside File cls.cu
*/
#include "cls.h"
void cls::moreThrust()
{
printf("moreThrust\n");
}
/*
Inside File main.cpp
*/
#include "cls.h"
int main()
{
cls a_class;
a_class.pureCPP();
a_class.moreThrust();
cls::bar a_class_bar;
a_class_bar.thrustStuff();
cls::foo a_class_foo;
a_class_foo.kernelWrapper();
}
运行此打印
pureCPP
moreThrust
Thrust Stuff
KernelWrapper
如果有的话,我敢打赌您使用的是IDE而且它并没有填写您的所有文件,所以当您在头文件中有您的类成员声明时,但是&#&# 39; ll永远找不到相应的定义。您的确切编译命令会有所不同,但对于我(在Linux上),我使用了
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/bar.d" "../src/bar.cu"
nvcc --device-c -G -O0 -g -gencode arch=compute_20,code=sm_21 -x cu -o "src/bar.o" "../src/bar.cu"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/cls.d" "../src/cls.cu"
nvcc --device-c -G -O0 -g -gencode arch=compute_20,code=sm_21 -x cu -o "src/cls.o" "../src/cls.cu"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/foo.d" "../src/foo.cu"
nvcc --device-c -G -O0 -g -gencode arch=compute_20,code=sm_21 -x cu -o "src/foo.o" "../src/foo.cu"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/main.d" "../src/main.cpp"
nvcc -G -g -O0 --compile -x c++ -o "src/main.o" "../src/main.cpp"
nvcc -G -g -O0 -gencode arch=compute_20,code=sm_21 -odir "src" -M -o "src/clscpp.d" "../src/cls.cpp"
nvcc -G -g -O0 --compile -x c++ -o "src/clscpp.o" "../src/cls.cpp"
nvcc --relocatable-device-code=true -gencode arch=compute_20,code=sm_21 -link -o "split_compilation" ./src/bar.o ./src/cls.o ./src/foo.o ./src/clscpp.o ./src/main.o
这个想法只是编译所有源文件并将它们链接在一起。例如,如果我没有编译和链接cls.cpp文件,那么在对pureCPP
的任何调用中都会出现链接器错误。
另请注意,如果您使用的是实际的设备代码,则必须为您的会员功能指定__device__
和/或__host__
。见this other SO question