Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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
s模式看起来非常类似于矩阵乘法。我将从一个很好的CUDA矩阵乘法实现开始,确保理解它为什么以这种方式实现,然后修改它以满足您的需要。这段代码实现了什么计算?您能发布一些M、N和D的指示性值吗?M和N的数量级为几千,D为3。这段代码实现的计算用于处理点云,但_C_Cuda_Thrust - Fatal编程技术网

s模式看起来非常类似于矩阵乘法。我将从一个很好的CUDA矩阵乘法实现开始,确保理解它为什么以这种方式实现,然后修改它以满足您的需要。这段代码实现了什么计算?您能发布一些M、N和D的指示性值吗?M和N的数量级为几千,D为3。这段代码实现的计算用于处理点云,但

s模式看起来非常类似于矩阵乘法。我将从一个很好的CUDA矩阵乘法实现开始,确保理解它为什么以这种方式实现,然后修改它以满足您的需要。这段代码实现了什么计算?您能发布一些M、N和D的指示性值吗?M和N的数量级为几千,D为3。这段代码实现的计算用于处理点云,但,c,cuda,thrust,C,Cuda,Thrust,s模式看起来非常类似于矩阵乘法。我将从一个很好的CUDA矩阵乘法实现开始,确保理解它为什么以这种方式实现,然后修改它以满足您的需要。这段代码实现了什么计算?您能发布一些M、N和D的指示性值吗?M和N的数量级为几千,D为3。这段代码实现的计算用于处理点云,但我不太确定这项技术的名称(或者它是否有名称)。谢谢你的建议。有没有一种方法可以合并内存访问而不将所有数据从行主格式更改为列主格式?有几个月的工作投入到代码中,这在很大程度上取决于此,我认为我无法重新安排所有数据。我删除了\uuu syncthr


s模式看起来非常类似于矩阵乘法。我将从一个很好的CUDA矩阵乘法实现开始,确保理解它为什么以这种方式实现,然后修改它以满足您的需要。

这段代码实现了什么计算?您能发布一些M、N和D的指示性值吗?M和N的数量级为几千,D为3。这段代码实现的计算用于处理点云,但我不太确定这项技术的名称(或者它是否有名称)。谢谢你的建议。有没有一种方法可以合并内存访问而不将所有数据从行主格式更改为列主格式?有几个月的工作投入到代码中,这在很大程度上取决于此,我认为我无法重新安排所有数据。我删除了
\uuu syncthreads()
,它工作正常,尽管我无法检测到速度上的任何差异。此外,英伟达计算可视化分析器说,第二个内核DYSUMP占用的时间是第一个内核的4倍,DYCOMPTEP。我强烈建议研究在 DySUP内核中使用的数组。你可以通过使用英伟达SDK中的转置内核编程,你可以很好地发现,计算转置的成本超过内存性能的增益。也就是说,如果您无法通过其他方式实现,那么可以使用共享内存实现内存合并。你应该可以在网上找到关于这项技术的信息。我设法合并了一些内存访问!在
d_computeP
I替换
Px[3*(N*m+N)+0]=x1*Pm*prbn
Px[m+m*(n+n*0)]=x1*Pm*prbn和在
d_集水坑中
I替换
Pxm1+=pxmtimessp[3*(N*m+N)+0]*spn带有
Pxm1+=pxmtimessp[m+m*(n+n*0)]*spn(当然还有另外两个,因为这些语句有三个)。我也为P1做了同样的事情。代码现在运行速度至少快15%!今天晚些时候,我将研究合并其余的内存访问。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define max(A, B)   ((A) > (B) ? (A) : (B))
#define min(A, B)   ((A) < (B) ? (A) : (B))

void cpd_comp(
        double* x,
        double* y, 
        double* prb,
        double* sigma2,
        double* outlier,
        double* P1,
        double* Pt1,
        double* Px,
        double* E,
        int N,
        int M,
        int D
        )

{
  int       n, m, d;
  double    ksig, diff, razn, outlier_tmp, sp;
  double    *P, *temp_x;

  P = (double*) calloc(M, sizeof(double));
  temp_x = (double*) calloc(D, sizeof(double));

  ksig = -2.0 * *sigma2;


  for (n=0; n < N; n++) {

      sp=0;
      for (m=0; m < M; m++) {
          razn=0;
          for (d=0; d < D; d++) {
             diff=*(x+n+d*N)-*(y+m+d*M);  diff=diff*diff;
             razn+=diff;
          }

          *(P+m)=exp(razn/ksig) ;
          sp+=*(P+m);
      }


      *(Pt1+n)=*(prb+n);
      for (d=0; d < D; d++) {
       *(temp_x+d)=*(x+n+d*N)/ sp;
      }

      for (m=0; m < M; m++) {
          *(P1+m)+=((*(P+m)/ sp) **(prb+n));

          for (d=0; d < D; d++) {
          *(Px+m+d*M)+= (*(temp_x+d)**(P+m)**(prb+n));
          }

      }

   *E +=  -log(sp);     
  }
  *E +=D*N*log(*sigma2)/2;


  free((void*)P);
  free((void*)temp_x);

  return;
}
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <thrust/device_ptr.h>
#include <thrust/reduce.h>

/*headers*/
void cpd_comp(
    float * x,        //Points to register      [N*D]
    float * y,        //Points to be registered [M*D]
    float * prb,      //Vector of probabilities [N]
    float * sigma2,   //Square of sigma
    float ** P1,       //P1,  output, [M]
    float ** Pt1,      //Pt1, output, [N]
    float ** Px,       //Px,  output, [M*3]
    int N,            //Number of points, i.e. rows, in x
    int M             //Number of points, i.e. rows, in 
    );

__global__ void d_computeP(
    float * P,
    float * P1,
    float * Px,
    float * ProbabilityMatrix,
    float * x,
    float * y,
    float * prb,
    float ksig,
    const int N,
    const int M);

__global__ void d_sumP(
    float * sp,
    float * P1timessp,
    float * Pxtimessp,
    float * P1,
    float * Px,
    const int N,
    const int M);

/*implementations*/

void cpd_comp(
    float * x,        //Points to register      [N*D]
    float * y,        //Points to be registered [M*D]
    float * prb,      //Vector of probabilities [N]
    float * sigma2,   //Scalar
    float ** P1,       //P1,  output, [M]
    float ** Pt1,      //Pt1, output, [N]
    float ** Px,       //Px,  output, [M*3]
    int N,            //Number of points, i.e. rows, in x
    int M             //Number of points, i.e. rows, in y
    ){
    //X is generatedPointPos
    //Y is points

    float
        *P,
        *P1timessp,
        *Pxtimessp,
        ksig = -2.0 * (*sigma2),
        *h_sumofP = new float[N], //sum of P, on host
        *d_sumofP;                //sum of P, on device

    cudaMalloc((void**)&P,        sizeof(float)*M*N);
    cudaMalloc((void**)&P1timessp,sizeof(float)*M*N);
    cudaMalloc((void**)&Pxtimessp,sizeof(float)*M*N*3);
    cudaMalloc((void**)&d_sumofP, sizeof(float)*N);

    cudaMalloc((void**)P1,        sizeof(float)*M);
    cudaMalloc((void**)Px,        sizeof(float)*M*3);
    cudaMalloc((void**)Pt1,       sizeof(float)*N);

    d_computeP<<<dim3(N,M/1024+1),M>1024?1024:M>>>(P,P1timessp,Pxtimessp,NULL,x,y,prb,ksig,N,M);

    for(int n=0; n<N; n++){
        thrust::device_ptr<float>dev_ptr(P);
        h_sumofP[n] = thrust::reduce(dev_ptr+M*n,dev_ptr+M*(n+1),0.0f,thrust::plus<float>());
    }

    cudaMemcpy(d_sumofP,h_sumofP,sizeof(float)*N,cudaMemcpyHostToDevice);

    d_sumP<<<M/1024+1,M>1024?1024:M>>>(d_sumofP,P1timessp,Pxtimessp,*P1,*Px,N,M);

    cudaMemcpy(*Pt1,prb,sizeof(float)*N,cudaMemcpyDeviceToDevice);

    cudaFree(P);
    cudaFree(P1timessp);
    cudaFree(Pxtimessp);
    cudaFree(d_sumofP);
    delete[]h_sumofP;
}

/*kernels*/

__global__ void d_computeP(
    float * P,
    float * P1,
    float * Px,
    float * ProbabilityMatrix,
    float * x,
    float * y,
    float * prb,
    float ksig,
    const int N,
    const int M){
    //thread configuration: <<<dim3(N,M/1024+1),1024>>>
    int m = threadIdx.x+blockIdx.y*blockDim.x;
    int n = blockIdx.x;
    if(m>=M || n>=N) return;

    float 
        x1 = x[3*n],
        x2 = x[3*n+1],
        x3 = x[3*n+2],
        diff1 = x1 - y[3*m],
        diff2 = x2 - y[3*m+1],
        diff3 = x3 - y[3*m+2],
        razn = diff1*diff1+diff2*diff2+diff3*diff3,

        Pm = __expf(razn/ksig), //fast exponentiation
        prbn = prb[n];

    P[M*n+m] = Pm; 

    __syncthreads();

    P1[N*m+n] = Pm*prbn;
    Px[3*(N*m+n)+0] = x1*Pm*prbn;
    Px[3*(N*m+n)+1] = x2*Pm*prbn;
    Px[3*(N*m+n)+2] = x3*Pm*prbn;
}

__global__ void d_sumP(
    float * sp,
    float * P1timessp,
    float * Pxtimessp,
    float * P1,
    float * Px,
    const int N,
    const int M){
    //computes P1 and Px
    //thread configuration: <<<M/1024+1,1024>>>
    int m = threadIdx.x+blockIdx.x*blockDim.x;
    if(m>=M) return;
    float 
        P1m = 0,
        Pxm1 = 0,
        Pxm2 = 0,
        Pxm3 = 0;
    for(int n=0; n<N; n++){
        float spn = 1/sp[n];
        P1m += P1timessp[N*m+n]*spn;
        Pxm1 += Pxtimessp[3*(N*m+n)+0]*spn;
        Pxm2 += Pxtimessp[3*(N*m+n)+1]*spn;
        Pxm3 += Pxtimessp[3*(N*m+n)+2]*spn;
    }

    P1[m] = P1m;
    Px[3*m+0] = Pxm1;
    Px[3*m+1] = Pxm2;
    Px[3*m+2] = Pxm3;

}
int m = threadIdx.x+blockIdx.y*blockDim.x;
int n = blockIdx.x;
if(m>=M || n>=N) return;

diff1 = x1 - y[3*m],
diff2 = x2 - y[3*m+1],
diff3 = x3 - y[3*m+2],