Cuda 窦函数推力复(双)向量使用故障

Cuda 窦函数推力复(双)向量使用故障,cuda,thrust,Cuda,Thrust,我在设备和主机上使用sin函数处理推力复杂双向量时遇到了一些问题:计算似乎是在浮点运算中完成的 通过推力::设备_向量和推力::主机_向量,我获得: sin( 1+0i ) == (0.8414709568023682,0) 带std::complex: 和std::complex: 我在代码中犯了什么错误?在编译过程中,我使用了 nvcc test.cu -o test 以下是完整的代码: #include <thrust/host_vector.h> #include <

我在设备和主机上使用
sin
函数处理
推力
复杂双向量时遇到了一些问题:计算似乎是在浮点运算中完成的

通过
推力::设备_向量<推力::复合体>
推力::主机_向量<推力::复合体>
,我获得:

sin( 1+0i ) == (0.8414709568023682,0)
std::complex

std::complex

我在代码中犯了什么错误?在编译过程中,我使用了

nvcc test.cu -o test
以下是完整的代码:

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/complex.h>
#include <iostream>
#include <iomanip>
#include <complex>
#include <cmath>

template <typename Vector> 
void Print(Vector &V){
  for (int i=0;i<V.size();i++)
    std::cout <<  V[i] << "  ";
  std::cout << "\n";
}

template <typename T>
struct sin_functor : public thrust::unary_function< T , T >
{
  __host__ __device__
  T operator()( T x) const
  {
    return sin( x );
  }
};

template <typename Vector> 
void ThrustComputation(){
  typedef typename Vector::value_type Tvec;
  Vector A(2);
  A[0]=Tvec(1.,0.);A[1]=Tvec(1.,1.);

  std::cout << "A: " << std::endl;
  std::cout << "  ";Print<Vector>(A);

  Vector B(A.size());

  thrust::transform(A.begin(),A.end(),B.begin(), sin_functor<Tvec>());
  std::cout << "B =sin(A): " << std::endl;
  std::cout << "  ";Print<Vector>(B);
}

template <typename T> 
void stdComputation(){
  std::complex<T> sA[2];
  sA[0]=std::complex<T>(1.,0.);
  sA[1]=std::complex<T>(1.,1.);

  std::cout << "sA: " << std::endl;
  std::cout << "  " << sA[0] << "  " << sA[1] << std::endl;
  std::cout << "sin(sA): " << std::endl;
  std::cout << "  " << sin(sA[0]) << "  " << sin(sA[1]) << std::endl;
}


int main(int argc, char **argv)
{  
  std::cout << std::setprecision(16); 
  std::cout << "Thrust: Computation on GPU device (double)\n";
  ThrustComputation<thrust::device_vector< thrust::complex<double> > >();
  std::cout << "Thrust: Computation on host (double)\n";
  ThrustComputation<thrust::host_vector< thrust::complex<double> > >();
  std::cout << "std: Computation (double)\n";
  stdComputation<double>();
  std::cout << "std: Computation (float)\n";
  stdComputation<float>();
  return 0;
}

这似乎是推力库中的一个真正的bug。快速扫描github上的代码,我发现了,这可能是罪魁祸首。看来,complex
sin
所依赖的推力的双精度
csinh
功能有一个意外的中间转换浮动,这可能导致您观察到的精度损失。正如评论中所建议的,您应该将其报告为一个bug。

这在推力库中似乎是一个真正的bug。快速扫描github上的代码,我发现了,这可能是罪魁祸首。看来,complex
sin
所依赖的推力的双精度
csinh
功能有一个意外的中间转换浮动,这可能导致您观察到的精度损失。正如评论中所建议的,您应该将此报告为bug。

您的实际问题是什么?类似于“为什么
std::complex
推力::complex
产生的输出不完全相同?对于我来说,使用推力::设备_向量<推力::complex>计算sin(1+0i)是错误的:精确解的错误是1e-8!您可以在这里提出错误报告:您的实际问题是什么?类似于”为什么
std::complex
推力::complex
产生的输出不完全相同?对于我来说,使用推力::设备_向量<推力::complex>计算sin(1+0i)是错误的:精确解的误差是1e-8!您可以在此处提出错误报告:
nvcc test.cu -o test
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/complex.h>
#include <iostream>
#include <iomanip>
#include <complex>
#include <cmath>

template <typename Vector> 
void Print(Vector &V){
  for (int i=0;i<V.size();i++)
    std::cout <<  V[i] << "  ";
  std::cout << "\n";
}

template <typename T>
struct sin_functor : public thrust::unary_function< T , T >
{
  __host__ __device__
  T operator()( T x) const
  {
    return sin( x );
  }
};

template <typename Vector> 
void ThrustComputation(){
  typedef typename Vector::value_type Tvec;
  Vector A(2);
  A[0]=Tvec(1.,0.);A[1]=Tvec(1.,1.);

  std::cout << "A: " << std::endl;
  std::cout << "  ";Print<Vector>(A);

  Vector B(A.size());

  thrust::transform(A.begin(),A.end(),B.begin(), sin_functor<Tvec>());
  std::cout << "B =sin(A): " << std::endl;
  std::cout << "  ";Print<Vector>(B);
}

template <typename T> 
void stdComputation(){
  std::complex<T> sA[2];
  sA[0]=std::complex<T>(1.,0.);
  sA[1]=std::complex<T>(1.,1.);

  std::cout << "sA: " << std::endl;
  std::cout << "  " << sA[0] << "  " << sA[1] << std::endl;
  std::cout << "sin(sA): " << std::endl;
  std::cout << "  " << sin(sA[0]) << "  " << sin(sA[1]) << std::endl;
}


int main(int argc, char **argv)
{  
  std::cout << std::setprecision(16); 
  std::cout << "Thrust: Computation on GPU device (double)\n";
  ThrustComputation<thrust::device_vector< thrust::complex<double> > >();
  std::cout << "Thrust: Computation on host (double)\n";
  ThrustComputation<thrust::host_vector< thrust::complex<double> > >();
  std::cout << "std: Computation (double)\n";
  stdComputation<double>();
  std::cout << "std: Computation (float)\n";
  stdComputation<float>();
  return 0;
}
Thrust: Computation on GPU device (double)
A: 
  (1,0)  (1,1)  
B =sin(A): 
  (0.8414709568023682,0)  (1.298457622528076,0.6349639296531677)  
Thrust: Computation on host (double)
A: 
  (1,0)  (1,1)  
B =sin(A): 
  (0.8414709568023682,0)  (1.298457622528076,0.6349639296531677)  
std: Computation (double)
sA: 
  (1,0)  (1,1)
sin(sA): 
  (0.8414709848078965,0)  (1.298457581415977,0.6349639147847361)
std: Computation (float)
sA: 
  (1,0)  (1,1)
sin(sA): 
  (0.8414709568023682,0)  (1.298457503318787,0.6349638700485229)