【问题标题】:Operating on thrust::complex types with thrust::transform使用推力::转换对推力::复杂类型进行操作
【发布时间】:2017-03-01 18:03:07
【问题描述】:

我正在尝试使用thrust::transformthrust:complex<float> 类型的向量进行操作,但没有成功。以下示例在编译过程中出现了几页错误。

#include <cuda.h>
#include <cuda_runtime.h>
#include <cufft.h>

#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/transform.h>
#include <thrust/complex.h>

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

  thrust::device_vector< thrust::complex<float> > d_vec1(4);
  thrust::device_vector<float> d_vec2(4);

  thrust::fill(d_vec1.begin(), d_vec1.end(), thrust::complex<float>(1,1));

  thrust::transform(d_vec1.begin(), d_vec1.end(), d_vec2.begin(), thrust::abs< thrust::complex<float> >() );
}

我在 Ubuntu Xenial 上使用 CUDA 8.0,并使用 nvcc --std=c++11 main.cpp -o main 使用 clang 3.8.0-2ubuntu4 进行编译。

主要错误似乎是:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:17:105: error: no matching function for call to ‘abs()’
 gin(), d_vec1.end(), d_vec2.begin(), thrust::abs< thrust::complex<float> >() );

/usr/local/cuda-8.0/bin/../targets/x86_64-linux/include/thrust/detail/complex/arithmetic.h:143:20: note:   template argument deduction/substitution failed:
main.cpp:17:105: note:   candidate expects 1 argument, 0 provided
 gin(), d_vec1.end(), d_vec2.begin(), thrust::abs< thrust::complex<float> >() );
                                                                            ^

处理真正的花车没问题,但处理复杂的花车就没有问题。我认为我遗漏了一个类型错误,但我仍然处于 Thrust 和模板学习曲线的陡峭部分。

【问题讨论】:

    标签: c++11 cuda thrust


    【解决方案1】:

    错误信息非常具有描述性:

    thrust::abs&lt;thrust::complex&lt;...&gt;&gt; 是一个函数,它需要恰好一个参数,参见thrust/detail/complex/arithmetic.h#L143

    template <typename ValueType>
      __host__ __device__
      inline ValueType abs(const complex<ValueType>& z){
      return hypot(z.real(),z.imag());
    }
    

    对于您的用例,您需要用 functor 包装该函数:

    struct complex_abs_functor
    {
        template <typename ValueType>
        __host__ __device__
        ValueType operator()(const thrust::complex<ValueType>& z)
        {
            return thrust::abs(z);
        }
    };
    

    最后,在这里使用那个函子:

    thrust::transform(d_vec1.begin(),
                      d_vec1.end(),
                      d_vec2.begin(),
                      complex_abs_functor());
    

    【讨论】:

    • 这可以解决问题,但为什么thrust::negate&lt;thrust::complex&lt;float&gt;&gt;() 会加入thrust::transform() 调用但thrust::abs() 需要包装在函子中?还有关于期望一个参数的抱怨——thrust::transform() 不是针对输入向量设置并行执行所提供的一元运算,将结果写入输出向量吗?
    • @AndreasYankopolus negate 已经是一个仿函数,因此不需要包装。你所做的是你在thrust::transform 中没有参数就调用thrust::abs(),但它要求你提供一个仿函数(=function object,一个提供operator() 的类/结构的实例) .
    • 查看了thrust/functional.h 和thrust/complex.h 中的定义——现在理解了。
    猜你喜欢
    • 2019-01-28
    • 2016-02-28
    • 2017-02-14
    • 1970-01-01
    • 2020-07-27
    • 2012-11-20
    • 2014-07-01
    • 2012-09-05
    相关资源
    最近更新 更多