@@ -40,20 +40,35 @@ struct TestParallelFirstprivate2 : public TestBase<4, 1, 3, TestParallelFirstpri
4040 T* jobResults = new T[N];
4141
4242 #ifndef BUILD_REFERENCE
43- /* This workaround ensures that firstprivate copy operations that are missed by the correct tapes
44- * are at least recorded on the default tapes so that they can be moved later. */
45- bool active = T::getTape ().isActive ();
46- #pragma omp parallel
47- {
48- if (active) {
49- T::getTape ().setActive ();
43+ /* Set activity of default tapes. They might record copy operations due to firstprivate. OpDiLib's AD approach
44+ * for parallel regions moves these recordings to the correct tapes. */
45+ if (T::getTape ().isActive ()) {
46+ opdi::logic->beginSkippedParallelRegion ();
47+ OPDI_PARALLEL ()
48+ {
49+ /* due to skipping, OpDiLib has not exchanged the tapes */
50+ if (omp_get_thread_num () != 0 ) {
51+ T::getTape ().setActive ();
52+ }
5053 }
54+ OPDI_END_PARALLEL
55+ opdi::logic->endSkippedParallelRegion ();
5156 }
5257 #endif
5358
5459 T helper = in[0 ] * in[1 ] * in[2 ] * in[3 ];
5560
56- T::getTape ().setPassive ();
61+ bool wasActive = T::getTape ().isActive ();
62+
63+ /* set this thread's tape as well as the default tapes passive */
64+ opdi::logic->beginSkippedParallelRegion ();
65+ OPDI_PARALLEL ()
66+ {
67+ T::getTape ().setPassive ();
68+ }
69+ OPDI_END_PARALLEL
70+ opdi::logic->endSkippedParallelRegion ();
71+
5772 OPDI_PARALLEL (firstprivate (helper))
5873 {
5974 int nThreads = omp_get_num_threads ();
@@ -66,7 +81,17 @@ struct TestParallelFirstprivate2 : public TestBase<4, 1, 3, TestParallelFirstpri
6681 }
6782 }
6883 OPDI_END_PARALLEL
69- T::getTape ().setActive ();
84+
85+ /* reactive this thread's tape and default tapes if applicable */
86+ if (wasActive) {
87+ opdi::logic->beginSkippedParallelRegion ();
88+ OPDI_PARALLEL ()
89+ {
90+ T::getTape ().setActive ();
91+ }
92+ OPDI_END_PARALLEL
93+ opdi::logic->endSkippedParallelRegion ();
94+ }
7095
7196 OPDI_PARALLEL (firstprivate (helper))
7297 {
0 commit comments