C++ C++;CUDA指向成员的指针

C++ C++;CUDA指向成员的指针,c++,pointers,cuda,C++,Pointers,Cuda,我想知道在CUDA中是否有向设备函数传递成员指针的方法。由于指针实际上只是相对于结构/类的,所以它似乎没有任何理由不起作用,但我似乎无法编译代码 #include <stdio.h> struct S { int F1; int F2; int F3; }; __device__ S x; __global__ void initialize_S() { x.F1 = 100; x.F2 = 200; x.F3 = 300; }

我想知道在CUDA中是否有向设备函数传递成员指针的方法。由于指针实际上只是相对于结构/类的,所以它似乎没有任何理由不起作用,但我似乎无法编译代码

#include <stdio.h>


struct S {
    int F1;
    int F2;
    int F3;
};

__device__ S x;

__global__ void initialize_S() {
    x.F1 = 100;
    x.F2 = 200;
    x.F3 = 300;
}

__global__ void print_S(int S::* m) {
    printf("val: %d\n", x.*m);
}

int main() {

    initialize_S<<<1, 1>>>();
    print_S<<<1, 1>>>(&S::F1);

    cudaDeviceSynchronize();
}
任何帮助都将不胜感激。谢谢

编辑:在经过NVCC评定的代码版本后,它实际上看起来好像生成了错误的代码:

extern void __device_stub__Z7print_SM1Si(long);
void __device_stub__Z7print_SM1Si( long __par0) { if (cudaSetupArgument((void *)(char *)&__par0, sizeof(__par0), (size_t)0UL) !=
cudaSuccess) return; { volatile static char *__f __attribute__((unused)); __f = ((char *)((void ( *)(long))print_S)); (void)cudaL
aunch(((char *)((void ( *)(long))print_S))); }; }
# 18 "ptm.cu"
void print_S( long __cuda_0)
# 18 "ptm.cu"
{__device_stub__Z7print_SM1Si( __cuda_0);

}
通过修补生成的代码,将这些“long”s转换为“int s::*”s,它可以正确编译和运行

 extern void __device_stub__Z7print_SM1Si(int S::*);
 void __device_stub__Z7print_SM1Si(int S::* __par0) { if (cudaSetupArgument((void *)(char *)&__par0, sizeof(__par0), (size_t)0UL)
 != cudaSuccess) return; { volatile static char *__f __attribute__((unused)); __f = ((char *)((void ( *)(int S::*))print_S)); (voi
 d)cudaLaunch(((char *)((void ( *)(int S::*))print_S))); }; }
 # 18 "ptm.cu"
 void print_S(int S::* __cuda_0)
 # 18 "ptm.cu"
 {__device_stub__Z7print_SM1Si( __cuda_0);

 }

看起来这是目前NVCC的一个限制。我在英伟达DEV论坛,希望这得到解决! 这似乎是
nvcc
的一个限制,其他地方已经指出了这一点。我已经向编译团队提交了一个bug。他们意识到这个问题。我没有任何关于可能的更新或时间表的进一步信息

以下建议了一种可能的解决方法,仅适用于Linux/MacOS:

#include <stdio.h>

template <typename T>
struct dummy {
  T inner;
  T __host__ __device__ get(void) { return inner; };
  __host__ __device__ dummy(T in) : inner(in) { };
};



struct S {
    int F1;
    int F2;
    int F3;
};

__device__ S x;

__global__ void initialize_S() {
    x.F1 = 100;
    x.F2 = 200;
    x.F3 = 300;
}

__global__ void print_S(dummy<int S::*> m) {
    printf("val: %d\n", x.*(m.get()));
}

int main() {

    initialize_S<<<1, 1>>>();
    print_S<<<1, 1>>>(dummy<int S::*>(&S::F1));

    cudaDeviceSynchronize();
}
#包括
模板
结构虚拟{
T内;
T_uuu主机uuu设备uuuu获取(void){返回内部;};
__主机设备虚拟(T in):内部(in){};
};
结构{
int F1;
int F2;
int F3;
};
__设备x;
__全局无效初始化{
x、 F1=100;
x、 F2=200;
x、 F3=300;
}
__全局无效打印(虚拟m){
printf(“val:%d\n”,x.*(m.get());
}
int main(){
初始化_S();
打印(虚拟(&S::F1));
cudaDeviceSynchronize();
}
我无法评论上述的有用性。以上内容似乎在CUDA6.0上正确编译和运行


此外,在设备代码中使用指向成员的指针似乎也能正常工作。这里描述的限制是特定于它作为
\uuu global\uuu
函数参数传递时的用法。

F1-3是int,而不是代码中的函数指针……是的,我正在尝试将指向数据成员的指针传递到内核。看@ TomChittenden:这看起来像是CUDA C++前端的一个真正的限制。你能补充一下你的发现作为一个简短的回答吗?稍后,你将能够接受它,并从未回答的问题列表中删除该问题(我也将投票表决)。我还建议向NVIDIA提交一份bug报告,这似乎是他们应该解决的问题。
#include <stdio.h>

template <typename T>
struct dummy {
  T inner;
  T __host__ __device__ get(void) { return inner; };
  __host__ __device__ dummy(T in) : inner(in) { };
};



struct S {
    int F1;
    int F2;
    int F3;
};

__device__ S x;

__global__ void initialize_S() {
    x.F1 = 100;
    x.F2 = 200;
    x.F3 = 300;
}

__global__ void print_S(dummy<int S::*> m) {
    printf("val: %d\n", x.*(m.get()));
}

int main() {

    initialize_S<<<1, 1>>>();
    print_S<<<1, 1>>>(dummy<int S::*>(&S::F1));

    cudaDeviceSynchronize();
}