@@ -766,46 +766,52 @@ CompoundRegionGeometricalBoolOperationNode::implement_bool (CompoundRegionOperat
766766 one_a.push_back (std::unordered_set<T1 > ());
767767
768768 shape_interactions<T, T> computed_a;
769- child (0 )->compute_local (cache, layout, cell, interactions_for_child (interactions, 0 , computed_a), one_a, proc);
770769
771- if (one_a.front ().empty ()) {
772-
773- if (m_op == GeometricalOp::And || m_op == GeometricalOp::Not) {
774-
775- // .. no results ..
770+ std::vector<std::unordered_set<T2 > > one_b;
771+ one_b.push_back (std::unordered_set<T2 > ());
776772
777- } else {
773+ shape_interactions<T, T> computed_b;
778774
779- std::vector<std::unordered_set<T2 > > one_b;
780- one_b.push_back (std::unordered_set<T2 > ());
775+ bool can_parallel = (m_op != GeometricalOp::And && m_op != GeometricalOp::Not);
781776
782- shape_interactions<T, T> computed_b;
777+ #if defined(_OPENMP)
778+ if (can_parallel && proc->threads () > 0 ) {
779+ #pragma omp task shared(one_a, computed_a, cache, layout, cell, interactions, proc)
780+ {
781+ child (0 )->compute_local (cache, layout, cell, interactions_for_child (interactions, 0 , computed_a), one_a, proc);
782+ }
783+ #pragma omp task shared(one_b, computed_b, cache, layout, cell, interactions, proc)
784+ {
785+ child (1 )->compute_local (cache, layout, cell, interactions_for_child (interactions, 1 , computed_b), one_b, proc);
786+ }
787+ #pragma omp taskwait
788+ } else
789+ #endif
790+ {
791+ child (0 )->compute_local (cache, layout, cell, interactions_for_child (interactions, 0 , computed_a), one_a, proc);
792+ if (!one_a.front ().empty ()) {
783793 child (1 )->compute_local (cache, layout, cell, interactions_for_child (interactions, 1 , computed_b), one_b, proc);
794+ } else {
795+ if (!can_parallel) { // And or Not and A is empty
796+ return ; // nothing to do, results remain empty
797+ }
798+ }
799+ }
784800
801+ if (one_a.front ().empty ()) {
802+ if (!can_parallel) {
803+ // .. no results ..
804+ } else {
785805 copy_results (results, one_b);
786-
787806 }
788-
789807 } else {
790-
791- std::vector<std::unordered_set<T2 > > one_b;
792- one_b.push_back (std::unordered_set<T2 > ());
793-
794- shape_interactions<T, T> computed_b;
795- child (1 )->compute_local (cache, layout, cell, interactions_for_child (interactions, 1 , computed_b), one_b, proc);
796-
797808 if (one_b.front ().empty ()) {
798-
799809 if (m_op != GeometricalOp::And) {
800810 copy_results (results, one_a);
801811 }
802-
803812 } else {
804-
805813 run_bool (m_op, layout, one_a.front (), one_b.front (), results.front ());
806-
807814 }
808-
809815 }
810816}
811817
@@ -934,30 +940,54 @@ void compound_region_generic_operation_node<TS, TI, TR>::implement_compute_local
934940 shape_interactions<TTS , TTI > self_interactions_heap;
935941 const shape_interactions<TTS , TTI > &self_interactions = interactions_for_child (interactions, 0 , self_interactions_heap);
936942
937- self->compute_local (cache, layout, cell, self_interactions, self_result, proc);
938-
939- db::generic_shape_iterator <TS > is (self_result.front ().begin (), self_result.front ().end ());
940-
941943 std::vector<db::generic_shape_iterator<TI > > iiv;
942944 std::vector<std::unordered_set<TI > > intruder_results;
943- intruder_results.reserve (children () - 1 ); // important, so that the memory layout will not change while we generate them
945+ intruder_results.resize (children () - 1 ); // allocate memory upfront
944946
945- for (unsigned int ci = 1 ; ci < children (); ++ci) {
947+ #if defined(_OPENMP)
948+ if (proc->threads () > 0 ) {
949+ #pragma omp task shared(self_result, self_interactions_heap, cache, layout, cell, interactions, proc)
950+ {
951+ self->compute_local (cache, layout, cell, self_interactions, self_result, proc);
952+ }
953+ for (unsigned int ci = 1 ; ci < children (); ++ci) {
954+ #pragma omp task shared(intruder_results, cache, layout, cell, interactions, proc) firstprivate(ci)
955+ {
956+ const CompoundRegionOperationNode *intruder = child (ci);
957+ std::vector<std::unordered_set<TI > > intruder_result;
958+ intruder_result.push_back (std::unordered_set<TI > ());
959+
960+ shape_interactions<TTS , TTI > intruder_interactions_heap;
961+ const shape_interactions<TTS , TTI > &intruder_interactions = interactions_for_child (interactions, ci, intruder_interactions_heap);
962+
963+ intruder->compute_local (cache, layout, cell, intruder_interactions, intruder_result, proc);
964+ intruder_results[ci - 1 ] = std::move (intruder_result.front ());
965+ }
966+ }
967+ #pragma omp taskwait
968+ } else
969+ #endif
970+ {
971+ self->compute_local (cache, layout, cell, self_interactions, self_result, proc);
946972
947- const CompoundRegionOperationNode *intruder = child (ci);
948- std::vector<std::unordered_set<TI > > intruder_result;
949- intruder_result.push_back (std::unordered_set<TI > ());
973+ for (unsigned int ci = 1 ; ci < children (); ++ci) {
950974
951- shape_interactions<TTS , TTI > intruder_interactions_heap;
952- const shape_interactions<TTS , TTI > &intruder_interactions = interactions_for_child (interactions, ci, intruder_interactions_heap);
975+ const CompoundRegionOperationNode *intruder = child (ci);
976+ std::vector<std::unordered_set<TI > > intruder_result;
977+ intruder_result.push_back (std::unordered_set<TI > ());
953978
954- intruder->compute_local (cache, layout, cell, intruder_interactions, intruder_result, proc);
979+ shape_interactions<TTS , TTI > intruder_interactions_heap;
980+ const shape_interactions<TTS , TTI > &intruder_interactions = interactions_for_child (interactions, ci, intruder_interactions_heap);
955981
956- intruder_results.push_back (std::unordered_set<TI > ());
957- intruder_results.back ().swap (intruder_result.front ());
982+ intruder->compute_local (cache, layout, cell, intruder_interactions, intruder_result, proc);
983+ intruder_results[ci - 1 ] = std::move (intruder_result.front ());
984+ }
985+ }
958986
959- iiv. push_back ( db::generic_shape_iterator< TI > (intruder_results. back ().begin (), intruder_results. back ().end () ));
987+ db::generic_shape_iterator < TS > is (self_result. front ().begin (), self_result. front ().end ());
960988
989+ for (unsigned int ci = 1 ; ci < children (); ++ci) {
990+ iiv.push_back (db::generic_shape_iterator <TI > (intruder_results[ci - 1 ].begin (), intruder_results[ci - 1 ].end ()));
961991 }
962992
963993 db::local_processor <TS , TI , TR > lproc (layout);
0 commit comments