Cuda 使用推力进行统计,避免编译错误

Cuda 使用推力进行统计,避免编译错误,cuda,thrust,Cuda,Thrust,我想用推力计算平均值和标准差,我发现。 我试图使用复杂的值,但我遇到了一些问题 代码如下: #include <thrust/device_vector.h> #include <thrust/host_vector.h> #include <thrust/transform_reduce.h> #include <thrust/functional.h> #include <thrust/extrema.h> #include <

我想用推力计算平均值和标准差,我发现。 我试图使用复杂的值,但我遇到了一些问题

代码如下:

#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/transform_reduce.h>
#include <thrust/functional.h>
#include <thrust/extrema.h>
#include <cmath>
#include <float.h>

typedef struct
{
    float re,im;
} mycomplex;


// structure used to accumulate the moments and other
// statistical properties encountered so far.
template <typename T>
struct summary_stats_data
{
    T n;
    T min;
    T max;
    T mean;
    T M2;

    // initialize to the identity element
    void initialize()
    {
        n.re = mean.re = M2.re = 0;
        n.im = mean.im = M2.im = 0;
        min = std::numeric_limits<T>::max();
        max = std::numeric_limits<T>::min();
    }

    float varianceRe() { return M2.re / ( n.re - 1 ); }
    float varianceIm() { return M2.im / ( n.im - 1 ); }

    float variance_nRe() { return M2.re / n.re; }
    float variance_nIm() { return M2.im / n.im; }

};

// stats_unary_op is a functor that takes in a value x and
// returns a variace_data whose mean value is initialized to x.
template <typename T>
struct summary_stats_unary_op
{
    __host__ __device__
    summary_stats_data<T> operator()(const T& x) const
    {
        summary_stats_data<T> result;
        result.n.re = 1;
        result.n.im = 1;

        result.min = x;
        result.max = x;

        result.mean = x;

        result.M2.re = 0;
        result.M2.im = 0;

        return result;
    }

};

// summary_stats_binary_op is a functor that accepts two summary_stats_data
// structs and returns a new summary_stats_data which are an
// approximation to the summary_stats for
// all values that have been agregated so far
template <typename T>
struct summary_stats_binary_op
: public thrust::binary_function<const summary_stats_data<T>&,
const summary_stats_data<T>&,
summary_stats_data<T> >
{
    __host__ __device__
    summary_stats_data<T> operator()(const summary_stats_data<T>& x, const summary_stats_data <T>& y) const
    {
        summary_stats_data<T> result;

        // precompute some common subexpressions
        T n;
        n.re = x.n.re + y.n.re;
        n.im = x.n.im + y.n.im;

        T delta;
        delta.re = y.mean.re - x.mean.re;
        delta.im = y.mean.im - x.mean.im;

        T delta2;
        delta2.re = delta.re * delta.re;
        delta2.im = delta.im * delta.im;

        //Basic number of samples (n), min, and max
        result.n = n;

        result.min.re = thrust::min( x.min.re, y.min.re );
        result.min.im = thrust::min( x.min.im, y.min.im );

        result.max.re = thrust::max( x.max.re, y.max.re );
        result.max.im = thrust::max( x.max.im, y.max.im );

        result.mean.re = x.mean.re + delta.re * y.n.re / n.re;
        result.mean.im = x.mean.im + delta.im * y.n.im / n.im;


        result.M2.re = x.M2.re + y.M2.re;
        result.M2.im = x.M2.im + y.M2.im;

        result.M2.re += delta2.re * x.n.re * y.n.re / n.re;
        result.M2.im += delta2.im * x.n.im * y.n.im / n.im;

        return result;
    }
};

template <typename Iterator>
void print_range(const std::string& name, Iterator first, Iterator last)
{
    typedef typename std::iterator_traits<Iterator>::value_type T;

    std::cout << name << ": ";
    thrust::copy(first, last, std::ostream_iterator<T>(std::cout, " "));
    std::cout << "\n";
}


int main(void)
{
    typedef mycomplex T;

    const int N = 4;

    // initialize host array
    thrust::host_vector<T> h_x(N);

    h_x[ 0 ].re = h_x[ 0 ].im = 4.0f;
    h_x[ 1 ].re = h_x[ 1 ].im = 7.0f;
    h_x[ 2 ].re = h_x[ 2 ].im = 13.0f;
    h_x[ 3 ].re = h_x[ 3 ].im = 16.0f;


    // Copy host_vector H to device_vector D
    thrust::device_vector<T> d_x = h_x;

    // setup arguments
    summary_stats_unary_op<T> unary_op;
    summary_stats_binary_op<T> binary_op;
    summary_stats_data<T> init;

    init.initialize();

    // compute summary statistics
    summary_stats_data<T> result = thrust::transform_reduce( d_x.begin(), d_x.end(), unary_op, init, binary_op );

    std::cout <<"******Summary Statistics Example*****"<<std::endl;
    print_range("The data", d_x.begin(), d_x.end());

    std::cout <<"Count : "<< result.n.re << std::endl;
    std::cout <<"Minimum : "<< result.min.re <<std::endl;
    std::cout <<"Maximum : "<< result.max.re <<std::endl;
    std::cout <<"Mean : "<< result.mean.re << std::endl;
    std::cout <<"Variance : "<< result.varianceRe() << std::endl;
    std::cout <<"Standard Deviation : "<< std::sqrt(result.variance_nRe()) << std::endl;



return 0;
}
我收到错误信息:

..包括/c++/4.4.7/limits284:错误:没有合适的构造函数 存在以从int转换为mycomplex

..包括/c++/4.4.7/limits282:错误:没有合适的构造函数 存在以从int转换为mycomplex

…include/c++/4.4.7/bits/stream_iterator.h191:错误:无运算符
该代码最初不是设计用于处理复杂值,即任意结构。它被设计用于POD数据类型,对于这些数据类型,以下类型的分配是有意义的:

    min = std::numeric_limits<T>::max();
    max = std::numeric_limits<T>::min();
由于底层代码是推力代码,因此更明智的做法是使用推力::complex,而其函数在推力/complex.h中概述。这可能会影响您编写/修改的其余代码


我看到你已经将剩下的大部分算术转换成了你特定的结构定义,所以可能唯一剩下的事情就是处理:好的,我改变了数值限制,使用了FLT_MAX和FLT_MIN。现在我只收到最后一个错误。有没有办法让它工作?或者,正如您所说,我必须为每个函数实现自己的运算符?我不认为FLT_MIN最小正规范化浮点是您想要的,您可能想要-FLT_MAX最小浮点,相当于std::numeric_limits::lowest。为什么不使用std::complex呢?否则是的,正如答案所说,您必须实现operatorstd::complex可能无法在_设备_功能中工作,但推力::complex会工作。@Robert Crovella:如果您愿意,请添加您的答案,使用FLT_MAX和FLT_MIN以及使用f而不是cout解决了问题。谢谢
    min = make_cuFloatComplex(std::numeric_limits<float>::max(), std::numeric_limits<float>::max());