Simpson的带有Thrust的积分代码在两台带有NVC++的机器上输出不同的结果

j0pj023g  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(158)

我写了一个数值积分代码:

#include <thrust/inner_product.h>
#include <thrust/transform.h>
#include <thrust/for_each.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/discard_iterator.h>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <array>

#include <iostream>

template<typename val_type, std::size_t n, std::size_t n_batch,
                template<typename...> typename Container>
struct Integrator {

    const val_type coeff;

    Integrator(val_type a, val_type b) :
        coeff((b-a)/3./static_cast<val_type>(n)) {}

    template <typename itor_type>
    void operator()(itor_type f_begin, itor_type dens_begin) {

        val_type C = this->coeff;
        auto zitor_begin = thrust::make_zip_iterator(
                            thrust::make_tuple(
                              thrust::make_counting_iterator(0),f_begin));

        auto titor_begin = make_transform_iterator(zitor_begin,
        [C](auto _tuple){ 
            
             return static_cast<val_type>(thrust::get<1>(_tuple) 
                          * (thrust::get<0>(_tuple)==0 ? C 
                                             : thrust::get<0>(_tuple)%2==0? 2.*C:4.*C)); 
        });

        auto binary_pred = [](int i,int j) { return i/n==j/n ; };

        thrust::reduce_by_key(thrust::make_counting_iterator(0),  // input key
                              thrust::make_counting_iterator(static_cast<int>(n*n_batch)),
                              titor_begin,                        // input value
                                                    thrust::make_discard_iterator(),    // output key
                              dens_begin,                         // output value
                              binary_pred);
    } // end of operator()

};

该算法是一个简单的辛普森积分。下面是main.cu

#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include "Integrator.hpp"

using Real = double;

constexpr std::size_t n = 1000, m = 4;
constexpr Real h = 2.*M_PI/(static_cast<Real>(n)-1.);

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

    Integrator<Real,n,m,thrust::device_vector> inttest(0,2.*M_PI);
    
    thrust::host_vector<Real> _fff(n*m), _x(n);
    thrust::device_vector<Real> fff(n*m), fint(m);
    for (int i=0; i<n; ++i)
        _x[i] = i*h;
    for (int I=0; I<m; ++I)
        for (int i=0; i<n; ++i)
            _fff[I*n+i] = std::sin(0.5*_x[i]);
    
    fff = _fff;
    inttest(fff.begin(),fint.begin());
    
    thrust::copy(fint.begin(),fint.end(),
                  std::ostream_iterator<Real>(std::cout," "));
    std::cout << std::endl;

}

我在Windows11系统的Windows Subsystem for Linux(WSL)和Ubuntu 22.4 Linux服务器上编译了此代码。在两台计算机上编译成功。(我只使用nvc++ main.cu
这两个系统(WSL和Ubuntu Linux)具有完全相同的

  • gcc版本(11.3),
  • cuda版本(12.0)和
  • nvc++版本(23.3)。

但是,只有Linux机器产生正确的结果(应该是3.99 3.99 3.99 3.99),而WSL Windows11机器产生0 0 0 0。可执行a.out文件的大小在WSL上是24Mb,在Linux机器上是8Mb,所以我知道一定发生了什么错误,但是在哪里呢?

vaqhlq81

vaqhlq811#

由于问题只发生在nvc++上,而不是nvcc上,因此这似乎是一个编译器问题。
NVHPC SDK(以及nvc++编译器)尚未正式支持Windows或WSL,因为installation guide或发行说明中没有提到它们。

相关问题