我写了一个数值积分代码:
#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,所以我知道一定发生了什么错误,但是在哪里呢?
1条答案
按热度按时间vaqhlq811#
由于问题只发生在
nvc++
上,而不是nvcc
上,因此这似乎是一个编译器问题。NVHPC SDK(以及
nvc++
编译器)尚未正式支持Windows或WSL,因为installation guide或发行说明中没有提到它们。