Вот «минимальный» нерабочий пример того, что я пытаюсь сделать.Использование полиморфного типа при восстановлении OpenMP
Этот код должен компилироваться с флагом -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 вида классов:
- действия:
A
(базовый класс), а такжеB
иC
(производный отA
) - Компьютер:
Bar
, реализующие параллельно вычисление (черезcompute()
) с использованием OpenMP и выполнение некоторых действий (отB
илиC
), позвонив по телефонуoperator()
. - Менеджер: который управляет запуском вычислений и устанавливает различные действия.
Сейчас у меня есть эта ошибка infortunate, что говорит мне, что я cannot declare variable 'omp_priv' to be of abstract type 'A'
. Это понятно. Мой класс A
на самом деле абстрактен, но я хочу, чтобы OpenMP смог понять, что мой атрибут A * action_
от Manager
класс - B
или C
. Но как я мог это сделать?
Странная вещь, что этот код работает, если:
- я обойти (раскомментируйте рабочую секцию в
main()
)Manager
класса
или если:
- Я отказываюсь от параллелизма и строки комментариев 34/35 (те, которые начинаются с
#pragma
)
Однако это не возможные варианты.
Спасибо за ваши ответы.