Cuda 由于双重运算而产生的无穷大

Cuda 由于双重运算而产生的无穷大,cuda,double-precision,Cuda,Double Precision,我会理解为什么结果是无穷大。我在下面写代码,结果总是收到inf。我的代码有精度问题吗 #include <stdio.h> #include <stdlib.h> #include "cuda.h" #include "curand_kernel.h" #define NDIM 30 #define NPAR 5 #define DIMPAR NDIM*NPAR __device__ double uniform(int index){ return (d

我会理解为什么结果是无穷大。我在下面写代码,结果总是收到inf。我的代码有精度问题吗

#include <stdio.h>
#include <stdlib.h>

#include "cuda.h"
#include "curand_kernel.h"

#define NDIM 30
#define NPAR 5

#define DIMPAR NDIM*NPAR

__device__ double uniform(int index){
    return (double) 0.767341;
}


__global__ void iteracao(double *pos){

    int thread = threadIdx.x + blockDim.x * blockIdx.x;
    double tvel;
    int i = 0;

    double l, r, t;

    if(thread < DIMPAR){
        do{
            t = (double) uniform(thread);
            l = (double) 2.05 * t * ( pos[thread] );
            r = (double) 2.05 * t * ( pos[thread] );
            tvel = (double) l+t+r;
            pos[thread] =  tvel;
            i++;
        }while(i < 10000);
    }

}


int main(int argc, char *argv[])
{

    double *d_pos,    *h_pos;


    h_pos = (double *) malloc(sizeof( double ) * DIMPAR);


    cudaMalloc((void**)&d_pos, DIMPAR   * sizeof( double ));


    int i, j, k, numthreadsperblock, numblocks;

    numthreadsperblock = 512;
    numblocks = (DIMPAR / numthreadsperblock) + ((DIMPAR % numthreadsperblock)?1:0);
    //
    printf("numthreadsperblock: %i;; numblocks:%i\n", numthreadsperblock, numblocks);

    cudaMemset(d_pos,  0.767341, DIMPAR   * sizeof( double ));
    iteracao<<<numblocks,numthreadsperblock>>>(d_pos);
    cudaMemcpy(h_pos, d_pos, DIMPAR * sizeof( double ), cudaMemcpyDeviceToHost);

    printf("\n");
    for(i = 0; i < NPAR; i++){
        for(j = i*NDIM, k = j; j < (k+30); j++){
            printf("%f,", h_pos[j]);
        }
        printf("***\n\n");
    }

    system("PAUSE");
    return 0;
}
#包括
#包括
#包括“cuda.h”
#包括“curand_kernel.h”
#定义NDIM 30
#定义NPAR 5
#定义DIMPAR NDIM*NPAR
__设备双均匀(整数索引){
返回(双)0.767341;
}
__全局无效iteracao(双*位置){
int thread=threadIdx.x+blockDim.x*blockIdx.x;
双tvel;
int i=0;
双l,r,t;
if(螺纹
输出总是这样的:

numthreadsperblock:512;;麻木:1

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf*

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf*

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf*

inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf*


inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf
cudaMemset()
只能逐字节设置内存。看见 更多细节

要按预期初始化数组,可以使用推力作为一种快捷方式

thrust::fill(
    thrust::device_pointer_cast(d_pos),
    thrust::device_pointer_cast(d_pos) + DIMPAR,
    0.767341);

你有两个问题。第一个是@Anycorn在评论中描述的
cudaMemset
,就像
memset
需要一个字节值并设置字节位置一样。您不能使用它初始化
浮点值

第二个是内核有一个循环,在每个
pos
数组元素上运行10000次。实际上,您正在查找复杂表达式的10000个阶乘。因为那句话总是肯定的,所以你的答案就夸张了。很可能您的内核编写不正确。它不是在做你想让它做的事。即使您解决了第一个问题并正确地将
pos
初始化为零,您的计算仍然会失败

您正在执行的算术是:

pos[idx] =  0.767341 + (3.1460981 * pos[idx]);

对于每个
idx
,执行上述操作10000次。即使对于初始的
pos[idx]
值等于零,到循环的第二次迭代时,它也将开始以几何方式启动。

最有可能的情况是,您将d_pos设置为垃圾。cudaMemset对字节值进行操作,您给出的浮点值很可能只产生一个零字节。