如何在多个.cpp和.cu文件之间拆分类定义?

时间:2013-05-09 18:20:05

标签: c++ class cuda gpgpu thrust

我有一个包含混合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的鸡尾酒?

1 个答案:

答案 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