gpt4 book ai didi

c++ - 在 OpenMP 缩减中使用多态类型

转载 作者:行者123 更新时间:2023-11-30 05:26:24 25 4
gpt4 key购买 nike

这是我正在尝试做的“最小”非工作示例。

这段代码是用-fopenmp标志编译的。

#include <omp.h>
#include <iostream>

class A {
public:
virtual void operator() () = 0 ;

void combine(const A & rhs) {
// do reduction stuff
std::cout << "Combine thread : " << omp_get_thread_num() << std::endl;
}
};

class B : public A {
public:
void operator() () {
// do some B specific stuff
std::cout << "B " ;
}
} ;

class C: public A {
public:
void operator() () {
// do some C specific stuff
std::cout << "C " ;
}
} ;

class Computer {
public:
template<typename B_or_C_type>
void compute( B_or_C_type & action ) {
#pragma omp declare reduction (combine_actions : B_or_C_type : omp_out.combine(omp_in) ) initializer ( omp_priv(omp_orig) )
#pragma omp parallel for schedule(dynamic) reduction(combine_actions : action )
for( unsigned i = 0; i < 100; ++i ) {
// do long computation
action() ;
}
std::cout << std::endl;
}
} ;

class Manager {
public:
Manager(Computer * computer) : computer_(computer), action_(NULL)
{}

template<typename B_or_C_type>
void set_action(B_or_C_type * action)
{
action_ = action ;
}

void run()
{
computer_->compute(*action_) ;
}

private:
Computer * computer_ ;
A * action_ ;
} ;


int main() {
Computer computer;
B b ;
C c ;

// Not working
Manager manager(&computer) ;
manager.set_action(&b) ;
manager.run() ;
manager.set_action(&c) ;
manager.run() ;

//Working
// computer.compute(b) ;
// computer.compute(c) ;

return 0;
}

我有 3 种类型的类(class):

  • Actions:A(基类),BC(派生自 A )
  • Computer : Bar 使用 OpenMP 实现并行计算(通过 compute() 函数)并执行一些操作(来自 BC 类)通过调用 operator()
  • Manager:管理计算的启动并设置不同的操作。

现在我遇到了这个不幸的错误,告诉我我不能将变量“omp_priv”声明为抽象类型“A”。这是很好理解的。我的 A 类实际上是抽象的,但我希望 OpenMP 能够理解我的 Manager 类的 A * action_ 属性是 BC 类型。但是我该怎么做呢?


奇怪的是这段代码在以下情况下有效:

  • 我绕过 Manager 类(取消注释 main() 中的工作部分)

或者如果:

  • 我放弃并行性和注释行 34/35(以 #pragma 开头的那些)

但是,这些都不是可以想象的选项。

感谢您的回答。

最佳答案

使用 A& 不起作用,但使用 A* 可以:

B_or_C_type * action_ptr = &action;
#pragma omp declare reduction (combine_actions : B_or_C_type* : omp_out->combine(*omp_in) ) initializer ( omp_priv(omp_orig) )
#pragma omp parallel for schedule(dynamic) reduction(combine_actions : action_ptr )
for( unsigned i = 0; i < 100; ++i ) {
// do long computation
(*action_ptr)();
}

这样你就可以跳过整个 B_or_C_type 模板,只使用 A。作为更粗略的替代方法,您可以对 A 的所有已知子类使用 make a switch:

void compute( A & action ) {
B * pb = dynamic_cast<B*>( &action );
if ( pb ) compute( *pb );
C * pc = dynamic_cast<C*>( &action );
if ( pc ) compute( *pc );
}

我不太清楚为什么这不起作用。顺便说一句,它使用 Intel 编译器进行编译,但使用纯虚函数调用时会崩溃。我原以为应该这样做:

#pragma omp declare reduction (combine_actions : B_or_C_type& : omp_out->combine(*omp_in) ) initializer ( omp_priv(omp_orig) )

但事实并非如此。对于类型名称列表 中允许使用哪种类型名称,标准对我来说似乎有点模糊。在我看来,引用并未得到正确支持。

关于c++ - 在 OpenMP 缩减中使用多态类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37792426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com