HPX transform_reduce

Posted

技术标签:

【中文标题】HPX transform_reduce【英文标题】: 【发布时间】:2019-02-03 14:47:18 【问题描述】:

我尝试使用答案https://***.com/a/54481320/11008404 中给出的来自hpx 的transform_reduce,但我无法编译它。到目前为止我的代码:

#include <hpx/hpx_main.hpp>
#include <hpx/hpx.hpp>
#include <hpx/include/parallel_transform_reduce.hpp>
#include <hpx/include/iostreams.hpp>

#include <vector>

class A 
public:
  double residual() 
    // Calculate actual local residual
    double i = 1.0;
    return i;
  
;

int main() 

  std::vector<A> vec(300);
  double res = hpx::parallel::transform_reduce(hpx::parallel::execution::par,        
                      vec.begin(), vec.end(),                         // (1)
                      [](A& a_ref) return a_ref.residual(); ,       // (2)
                      0, [](double a, double b) return a + b; );    // (3)

  hpx::cout << "residual: " << res << hpx::endl;

  return 0;

编译器会抛出这个错误:

hpx.cpp:23:65: error: no matching function for call to ‘transform_reduce(const hpx::parallel::execution::parallel_policy&, std::vector<A>::iterator, std::vector<A>::iterator, main()::<lambda(A&)>, int, main()::<lambda(double, double)>)’
                   0, [](double a, double b) return a + b; );    // (3)

.../include/hpx/parallel/algorithms/transform_reduce.hpp:255:22: error: no type named ‘type’ in ‘struct hpx::util::invoke_result<main()::<lambda(double, double)>, A>’

对于Parallel reduce (e.g. sum) a vector of hpx::futures<double> 中提出的问题,有人建议什么问题或其他解决方案吗?

【问题讨论】:

【参考方案1】:

transform_reduce 的签名在其标准化过程中已多次更改(请参阅此处了解实际标准化的内容:https://en.cppreference.com/w/cpp/algorithm/transform_reduce)。我认为为了编译你只需要正确的参数序列:

#include <hpx/hpx_main.hpp>
#include <hpx/hpx.hpp>
#include <hpx/include/parallel_transform_reduce.hpp>
#include <hpx/include/iostreams.hpp>

#include <vector>

class A 
public:
  double residual() 
    // Calculate actual local residual
    double i = 1.0;
    return i;
  
;

int main() 

  std::vector<A> vec(300);
  double res = hpx::parallel::transform_reduce(hpx::parallel::execution::par,        
                      vec.begin(), vec.end(),
                      0.,
                      [](double a, double b) return a + b; ,
                      [](A& a_ref) return a_ref.residual(); );

  hpx::cout << "residual: " << res << hpx::endl;

  return 0;

【讨论】:

我已经测试过这个解决方案,但它也不能编译。我得到了 hpx1.2 和 hpx1.3 与第一个代码相同的错误。也许注释:模板参数推导/替换失败,在 transform_reduce.hpp:265:5 中有所帮助,但我无法弄清楚。 抱歉,我(再次)成为 MSVC 光荣问题的牺牲品,它将 const 引用绑定到非 const 引用而不会发出错误。【参考方案2】:

如果我将 hkaiser 的答案更改为

#include <hpx/hpx_main.hpp>
#include <hpx/hpx.hpp>
#include <hpx/include/parallel_transform_reduce.hpp>
#include <hpx/include/iostreams.hpp>

#include <vector>

class A 
public:
  double residual() const 
    // Calculate actual local residual
    double i = 1.0;
    return i;
  
;

int main() 

  std::vector<A> vec(300);
  double res = hpx::parallel::transform_reduce(hpx::parallel::execution::par,        
                      vec.begin(), vec.end(),
                      0.,
                      [](double a, double b) return a + b; ,
                      [](const A& a_ref) return a_ref.residual(); ); // note: const!

  hpx::cout << "residual: " << res << hpx::endl;

  return 0;

代码编译。如果您通过值或作为指针传递 A,它也会编译。

我不知道这种行为是否有意,所以我在 HPX 的 github 上打开了一个问题 (https://github.com/STEllAR-GROUP/hpx/issues/3651)

【讨论】:

N4687(C++17 的最后一个草案)在 29.8.5 [transform.reduce] 中说:“unary_op 和 binary_op 都不会使子范围无效,或修改范围 [first, last] 中的元素。”【参考方案3】:

我想补充一点,并行 STL 已通过 -std=c++17 进入 gcc 9,只需要与 -ltbb 链接(即 Intel's Thread Building Blocks,可轻松安装在 Linux 上例如使用apt)。

#include <numeric>
#include <execution>
#include <vector>

class A 
public:
  double residual() 
    // Calculate actual local residual
    double i = 1.0;
    return i;
  
;

int main() 

  std::vector<A> vec(300);
  double res = std::transform_reduce(std::execution::par,        
                      vec.begin(), vec.end(),
                      0.,
                      [](double a, double b) return a + b; ,
                      [](A& a_ref) return a_ref.residual(); );

  std::cout << "residual: " << res << std::endl;

  return 0;

【讨论】:

以上是关于HPX transform_reduce的主要内容,如果未能解决你的问题,请参考以下文章

是否可以编写可以在 HPX 和 C++1x 线程之间切换的代码?

Q HPX 与“apache 云计算”(例如 vs spark)如何公平?

HPX 是不是提供具有粒度控制的基于任务的并行化迭代功能?

为啥 HPX 要求未来的“那么”成为 DAG(有向无环图)的一部分?

并行减少(例如求和)hpx::futures<double> 的向量

以PDF格式更改图像