Hier ist ein "minimal" nicht funktionierendes Beispiel von dem, was ich versuche zu tun. Dieser Code wird mit -fopenmp
Flag kompiliert.Verwenden von polymorphe Typ in OpenMP-Reduktion
#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;
}
Ich habe 3 Arten von Klassen:
- Aktionen:
A
(Basisklasse) undB
undC
(abgeleitet vonA
) - Computer-:
Bar
, die parallel realisieren Berechnung (durchcompute()
Funktion) mit OpenMP und einige Aktionen (von einemB
oderC
Klasse) durch den Aufrufoperator()
. - Manager: Das verwaltet den Start der Berechnung und setzt die verschiedenen Aktionen.
Im Moment habe ich diesen infortunate Fehler, der mir, dass ich cannot declare variable 'omp_priv' to be of abstract type 'A'
erzählt. Das ist gut verständlich. Meine A
Klasse ist in der Tat abstrakt, aber ich wünschte, OpenMP konnte verstehen, dass mein A * action_
Attribut von Manager
Klasse B
oder C
Typ ist. Aber wie könnte ich das tun?
Das Seltsame ist, dass dieser Code funktioniert, wenn:
- ich umgehen die
Manager
Klasse (uncomment Arbeitsabschnitt inmain()
)
oder wenn:
- Ich verzichte auf Parallelismus und nenne die Zeile 34/35 (die mit
#pragma
)
Diese sind jedoch keine denkbaren Optionen.
Vielen Dank für Ihre Antworten.