Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内部随机函数结构的CUDA移植_C++_Random_Cuda_Porting - Fatal编程技术网

C++ 内部随机函数结构的CUDA移植

C++ 内部随机函数结构的CUDA移植,c++,random,cuda,porting,C++,Random,Cuda,Porting,我必须在GPU上移植一个广泛使用随机数的结构。任何东西都可以移植,没有很多问题,但是随机生成器函数是这个类的所有函数中唯一被广泛调用的函数。 我想我可以简单地将其重新实现为类本身的内部设备函数。 下面我放了一个我需要的玩具模型(考虑到我工作的班级比较复杂)。 我还需要函数“rand”的每次调用都给出不同的随机数(即使在同一个对象中)。 然而,这里的玩具模型产生了错误的结果。谁能帮我改正一下吗 #include <cuda.h> #include <iostream> #i

我必须在GPU上移植一个广泛使用随机数的结构。任何东西都可以移植,没有很多问题,但是随机生成器函数是这个类的所有函数中唯一被广泛调用的函数。 我想我可以简单地将其重新实现为类本身的内部设备函数。 下面我放了一个我需要的玩具模型(考虑到我工作的班级比较复杂)。 我还需要函数“rand”的每次调用都给出不同的随机数(即使在同一个对象中)。 然而,这里的玩具模型产生了错误的结果。谁能帮我改正一下吗

#include <cuda.h>
#include <iostream>
#include <curand_kernel.h>
using namespace std;

struct test{

float value;

curandState B;

void __device__ rand(){value=curand_uniform(&B);}
void __device__ foo(){rand();}
};

__global__ void setup_kernel(curandState *state)
{
const int id=blockIdx.x;
curand_init(id, id, 0, &state[id]);
}

__global__ void fill_mat(struct test *anobj, curandState *state)
{
 const int Idx=blockIdx.x;
 curandState localState = state[Idx];
 anobj[Idx].B=localState;
 anobj[Idx].foo();
}

int main()
{
int num=10;
curandState *devStates;
cudaMalloc(  (void **)&devStates, num*sizeof(curandState) );

struct test *results = (struct test*)malloc(num*sizeof(struct test));
struct test *to_device;
cudaMalloc ( (void **)&to_device, num*sizeof(to_device));

setup_kernel<<<num, 1>>>(devStates);

fill_mat<<<num,1>>>(to_device, devStates);

cudaMemcpy(results,to_device,num*sizeof(struct test),cudaMemcpyDeviceToHost);

for(int i=0;i<num;i++)
 cout<<results[i].value<<endl; 
return 0;
}
#包括
#包括
#包括
使用名称空间std;
结构测试{
浮动值;
库兰州B;
void uuu device uuuu rand(){value=curand_uniform(&B);}
void uuu设备uuuuo(){rand();}
};
__全局\无效设置\内核(curandState*状态)
{
const int id=blockIdx.x;
curand_init(id,id,0和state[id]);
}
__全局填充材料(结构测试*anobj,库州*state)
{
const int Idx=blockIdx.x;
curandState localState=状态[Idx];
anobj[Idx].B=localState;
anobj[Idx].foo();
}
int main()
{
int num=10;
库兰州立大学*devStates;
Cudamaloc((void**)和devStates,num*sizeof(curandState));
结构测试*结果=(结构测试*)malloc(num*sizeof(结构测试));
结构测试*到_设备;
cudamaloc((void**)和to_设备,num*sizeof(to_设备));
设置内核(devStates);
填充垫(至设备、状态);
cudaMemcpy(结果,到_设备,num*sizeof(结构测试),cudaMemcpyDeviceToHost);
对于(inti=0;i感谢这个伟大(完整)的例子。在构建它之后,我发现了两个问题

当您cudamaloc到_设备时,您希望分配num*sizeof(struct test)字节

我假设您可能想多次调用fill_mat,或者您可能有其他内核,并且希望它们每次都得到不同的数字。如果是这样,请在fill_mat的末尾(或创建curandState副本的其他内核),您需要将本地状态复制回curandState。这是因为每次生成数字时,curandState都会推进状态

最后(这不一定是一个bug),我看到您在对curand_init的调用中使用线程id作为种子和序列curand的种子置乱算法可能会使您陷入序列中与其他线程重叠的部分。curand_init使用种子的置乱版本生成初始状态,然后应用2*67倍于序列的Skiphead。通常,目的是所有线程都使用相同的种子,以确保e在序列内,每个线程与前一个线程的距离为2*67


PaulS.

你能更详细地解释一下你得到的“错误结果”是什么吗?@harrism一开始我调用了anobj[Idx].rand(),后来我添加了foo(),我没有检查它是否编译,现在我无法检查我在这台计算机上没有nvcc(但我会在几个小时后检查)。不过我想如果你从内核调用anobj[Idx].rand(),那么“value”应该是一个随机数。相反,当我在最后一个for循环中打印输出时,我得到了一系列的零。谢谢你的回答。事实上,我发现如果不调用cudaMemcpy“host to device”,代码就不会给出正确的结果。对于其余部分,你完全正确。现在我转到下一个问题,when“value”是一个大小为“N”的数组(但您在主机上分配它!),您希望将其填充到内核中。