如何在Windows上的cuda推力调用中指定OpenMP执行策略?

时间:2016-07-17 08:01:03

标签: c++ windows thrust visual-studio-2015

在将代码从Linux移植到Windows时,感谢Visual Studio C ++ 2015社区,我遇到了一个我无法理解的编译错误。 下面是一个展示此错误的示例程序,构建一个双打矢量,然后使用OpenMP对cuda推力进行排序。

# include <thrust/sort.h>
# include <thrust/system/omp/execution_policy.h>
# include <chrono>
# include <random>
# include <vector>

double unit_random()
{
  static std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
  static std::uniform_real_distribution<double> distribution(double(0), double(1));
  return distribution(generator);
}

int main(int argc, char* argv[])
{
  constexpr size_t input_size = 100000;
  std::vector< double > input(input_size, 0);
  for ( size_t i = 0; i < input_size; ++i)
    input[i] = unit_random() * 1000;

  thrust::sort(thrust::omp::par, input.begin(), input.end());
  return 0;
}

以下是Visual Studio控制台中出现的错误(缩短了文件名):

thrust/system/omp/detail/sort.inl(136): error C2146: syntax error: missing ';' before identifier 'nseg'
thrust/detail/sort.inl(83): note: see reference to function template instantiation 'void thrust::system::omp::detail::stable_sort<thrust::system::omp::detail::par_t,RandomAccessIterator,StrictWeakOrdering>(thrust::system::omp::detail::execution_policy<thrust::system::omp::detail::par_t> &,RandomAccessIterator,RandomAccessIterator,StrictWeakOrdering)' being compiled
  with
  [
    RandomAccessIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>,
    StrictWeakOrdering=thrust::less<value_type>
  ]
thrust/system/detail/generic/sort.inl(63): note: see reference to function template instantiation 'void thrust::stable_sort<DerivedPolicy,RandomAccessIterator,StrictWeakOrdering>(const thrust::detail::execution_policy_base<DerivedPolicy> &,RandomAccessIterator,RandomAccessIterator,StrictWeakOrdering)' being compiled
  with
  [
      DerivedPolicy=thrust::system::omp::detail::par_t,
      RandomAccessIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>,
      StrictWeakOrdering=thrust::less<value_type>
  ]
thrust/detail/sort.inl(56): note: see reference to function template instantiation 'void thrust::system::detail::generic::sort<Derived,RandomAccessIterator,StrictWeakOrdering>(thrust::execution_policy<Derived> &,RandomAccessIterator,RandomAccessIterator,StrictWeakOrdering)' being compiled
  with
  [
      Derived=thrust::system::omp::detail::par_t,
      RandomAccessIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>,
      StrictWeakOrdering=thrust::less<value_type>
  ]
thrust/system/detail/generic/sort.inl(49): note: see reference to function template instantiation 'void thrust::sort<DerivedPolicy,RandomAccessIterator,thrust::less<value_type>>(const thrust::detail::execution_policy_base<DerivedPolicy> &,RandomAccessIterator,RandomAccessIterator,StrictWeakOrdering)' being compiled
  with
  [
      DerivedPolicy=thrust::system::omp::detail::par_t,
      RandomAccessIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>,
      StrictWeakOrdering=thrust::less<value_type>
  ]
thrust/detail/sort.inl(41): note: see reference to function template instantiation 'void thrust::system::detail::generic::sort<Derived,RandomAccessIterator>(thrust::execution_policy<Derived> &,RandomAccessIterator,RandomAccessIterator)' being compiled
  with
  [
      Derived=thrust::system::omp::detail::par_t,
      RandomAccessIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>
  ]
windows_cuda_thrust_error.cc(24): note: see reference to function template instantiation 'void thrust::sort<DerivedPolicy,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>>(const thrust::detail::execution_policy_base<DerivedPolicy> &,RandomAccessIterator,RandomAccessIterator)' being compiled
  with
  [
      DerivedPolicy=thrust::system::omp::detail::par_t,
      RandomAccessIterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<double>>>
  ]
thrust/system/omp/detail/sort.inl(136): error C2275: 'IndexType': illegal use of this type as an expression
thrust/system/omp/detail/sort.inl(113): note: see declaration of 'IndexType'
thrust/system/omp/detail/sort.inl(136): error C2065: 'nseg': undeclared identifier
thrust/system/omp/detail/sort.inl(142): error C2065: 'nseg': undeclared identifier
thrust/system/omp/detail/sort.inl(159): error C2065: 'nseg': undeclared identifier
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

相同的代码在Linux上运行良好。

我们如何在Windows上的cuda推力调用中指定OpenMP执行策略?或者,我在这个特定的上下文中做错了什么?

使用的推力版本是1.8.1,这里是推力函数的摘录,文件推力/ system / omp / detail / sort.inl,引发了编译错误:

template<typename DerivedPolicy,
         typename RandomAccessIterator,
         typename StrictWeakOrdering>
void stable_sort(execution_policy<DerivedPolicy> &exec,
                 RandomAccessIterator first,
                 RandomAccessIterator last,
                 StrictWeakOrdering comp)
{
  // ...
  typedef typename thrust::iterator_difference<RandomAccessIterator>::type IndexType;

  if(first == last)
    return;

  #pragma omp parallel
  {
    thrust::system::detail::internal::uniform_decomposition<IndexType> decomp(last - first, 1, omp_get_num_threads());

    // process id
    IndexType p_i = omp_get_thread_num();

    // every thread sorts its own tile
    if(p_i < decomp.size())
    {
      thrust::stable_sort(thrust::seq,
                          first + decomp[p_i].begin(),
                          first + decomp[p_i].end(),
                          comp);
    }

    #pragma omp barrier

    IndexType nseg = decomp.size(); // line 136
    // ...
  }
}

1 个答案:

答案 0 :(得分:1)

根据@kangshiyin的建议,我在github上提交了一个问题(参见issue #817)并且推动开发人员找到了解决方法。问题来自MSVC目前处理OpenMP代码的方式,因此问题中提供的代码非常好。

如果出现类似问题,请先尝试更新到最新版本的推力。您也可以尝试应用相同的解决方法:只需在引发错误的行之前添加分号。