Cuda 从设备函数调用推力设备_向量

Cuda 从设备函数调用推力设备_向量,cuda,gpu,thrust,Cuda,Gpu,Thrust,我有一个struct Cap,里面有另一个结构的推力::设备向量。当我编译代码时,我收到一个错误,该错误抱怨从设备函数调用主机函数(asch::device\u vector)。当我向成员函数和构造函数中添加\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu设备时,而不是仅添加\uuuuuuuuuuuuuuuuuuuuuu。我的问题是如何在我的类中访问设备向量,避免CPU和

我有一个
struct Cap
,里面有另一个结构的
推力::设备向量。当我编译代码时,我收到一个错误,该错误抱怨从设备函数调用主机函数(
asch::device\u vector
)。当我向成员函数和构造函数中添加
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu设备时,而不是仅添加
\uuuuuuuuuuuuuuuuuuuuuu。我的问题是如何在我的类中访问设备向量,避免CPU和GPU之间的任何数据传输

此后,您可以找到以下代码:

struct ParticleID {

Int solver;
Int ngb;
Int oldNgb;
LLInt no;
LLInt masterNo;

__device__ ParticleID() {
    solver = -8;
    ngb = 0;
    oldNgb = 0;
    no = 0;
    masterNo = -1;
}
};


struct BaseParticle {

Float h;
Float3 pos;
ParticleID id;

__device__ BaseParticle(const Float3& _pos, const Float& _h, const ParticleID& _id) :
     h(_h), pos(_pos), id(_id) { }

};


struct FloatIntPair{

Float first;
Int second;

__device__ FloatIntPair(const Float& _first, Int _second) : first(_first), second(_second) { }
__device__ FloatIntPair(const FloatIntPair& sample) : first(sample.first), second(sample.second) { }

static struct {
    __device__ bool operator()(const FloatIntPair& a, const FloatIntPair& b) {  return a.first < b.first; }
} LessOp;
};


struct Cap {

Float3 eX;
Float3 eY;
Float radius;
Float height;

Float3 center;
Float3 normal;

BaseParticle* aP;
BaseParticle* bP;

thrust::device_vector<FloatIntPair> vertices; // The ordered list of vertices generated from intersections by other circles

__device__ inline Float findAngle(const Float3& vertex) const {

    Float result;
    Float3 r = (vertex - center);
    result = atan2(r|eY,r|eX);
    return result += (result < 0.0) * (2.0 * _PI);
}

__device__ void insertVertex(const Float3& vertex, Int id) {

    Float theta;
    if (!vertices.empty())
        theta = findAngle(vertex);
    else {
        eX = normalVec(vertex - center);
        eY = normal ^ eX;
        theta = 0.0;
    }
    vertices.push_back(FloatIntPair(theta,id));
}

__device__ Cap(BaseParticle* _aP, BaseParticle* _bP) : aP(_aP), bP(_bP) {

    //Compute normal, center, radius
    Float d = mag(bP->pos - aP->pos);
    if(d == 0.0){
        normal = Vector1(0.0);
        center = aP->pos;
        radius = height = 0.0;
    } else {
        normal = (bP->pos - aP->pos) / d;
        Float x = (d * d - bP->h * bP->h + aP->h * aP->h) / (2.0 * d);
        center = aP->pos + normal * x;
        if (x >= aP->h) {
            radius = height = 0.0;
            return;
        }
        radius = sqrt(aP->h * aP->h - x * x);
        height = min(2.0 * aP->h, aP->h - x);

        Float3 vec001 = Vector(0.0,0.0,1.0);
            Float3 vec011 = Vector(0.0,1.0,1.0);

        eX = normalVec(vec001 ^ normal);
        if (mag2(eX) < geoEps()) {
            eX = eX = normalVec(vec011 ^ normal);
        }

        eY = normal ^ eX;
    }
}
};

class SphericalFaceManager {
BaseParticle* particle;
Int baseSigma;
public:
thrust::device_vector<Cap> caps;  
thrust::device_vector<Float3> vertexPool;    
__device__ void makeCaps();
};


__device__ void SphericalFaceManager::makeCaps() {

BaseParticle* aP;
BaseParticle* bP;
Cap aCap(aP,bP);
}
struct ParticleID{
整数解算器;
Int ngb;
Int oldNgb;
没有;
马斯特诺;
__设备粒子ID(){
解算器=-8;
ngb=0;
oldNgb=0;
否=0;
masterNo=-1;
}
};
结构基粒子{
浮动h;
浮动3个位置;
分词id;
__设备基本粒子(常量浮点3和\u位置、常量浮点和\u h、常量粒子id和\u id):
h(_h),pos(_pos),id(_id){
};
结构浮点对{
先浮;
Int秒;
__device_uuuuuFloatIntPair(常量Float&first,Int second):第一(first),第二(second){
__设备\uuuufloatintpair(constfloatintpair&sample):第一个(sample.first),第二个(sample.second){
静态结构{
__device_ubool操作符()(const FloatIntPair&a,const FloatIntPair&b){返回a.firstpos-aP->pos);
如果(d==0.0){
正常=矢量1(0.0);
中心=aP->pos;
半径=高度=0.0;
}否则{
正常=(bP->pos-aP->pos)/d;
浮动x=(d*d-bP->h*bP->h+aP->h*aP->h)/(2.0*d);
中心=aP->pos+正常*x;
如果(x>=aP->h){
半径=高度=0.0;
返回;
}
半径=sqrt(aP->h*aP->h-x*x);
高度=最小值(2.0*aP->h,aP->h-x);
Float3 vec001=向量(0.0,0.0,1.0);
Float3 vec011=向量(0.0,1.0,1.0);
eX=正常向量(vec001^正常);
if(mag2(eX)
不能在设备代码中直接使用推力矢量(或
std::vector
)。其他各种SO问题中都提到了这一点,例如

如果要在设备代码中使用
推力::设备\向量中的数据,应将指向该数据的指针作为函子初始化参数传递。其他各种问题都给出了这方面的例子,例如

同样,不能在设备代码中使用向量方法,例如
.empty()
.push_back()

您将需要用普通的C样式分配器和C样式索引数据访问来替换它们


对于设备代码中push_back的多线程实现,我建议使用类似的方法。这是一个完整的示例,演示了如何为向量分配空间,以及每个线程如何将其用于
insertVertex

@Robert Crovella感谢您的回答。我检查了链接,这里出现了两个东西:
.empty()
.push\u back()
在设备功能中编译得很好,但你说它无论如何都不工作,对吗?第二,你能用C风格的分配器和C风格的索引数据访问来修改部分代码吗?我添加了一个额外的链接到一个例子,展示了如何在设备代码中创建一个类似push_的函数,以及如何使用它和如何分配它。