Purpose
The PARALLEL DO directive enables you to specify which loops the compiler should parallelize. This is semantically equivalent to:
!$OMP PARALLEL !$OMP DO ... !$OMP ENDDO !$OMP END PARALLEL
and is a convenient way of parallelizing loops. The END PARALLEL DO directive allows you to indicate the end of a DO loop that is specified by the PARALLEL DO directive.
The PARALLEL DO and END PARALLEL DO directives only take effect if you specify the -qsmp compiler option.
Format
.-------------------------------. V | >>-PARALLEL DO----+---------------------------+-+-------------->< '-+---+--parallel_do_clause-' '-,-' >>-parallel_do_loop-------------------------------------------->< >>-+-----------------+----------------------------------------->< '-END PARALLEL DO-' |
where parallel_do_clause is:
>>-+-copyin_clause----------------------+---------------------->< +-default_clause---------------------+ +-firstprivate_clause----------------+ +-IF--(--scalar_logical_expr--)------+ +-lastprivate_clause-----------------+ +-num_threads_clause-----------------+ +-ORDERED----------------------------+ +-private_clause---------------------+ +-reduction_clause-------------------+ +-SCHEDULE--(--sched_type--+----+--)-+ | '-,n-' | '-shared_clause----------------------' |
If you specify the IF clause, the run-time environment performs a test to determine whether to run the block in serial or parallel. If scalar_logical_expr is true, then the block is run in parallel; if not, then the block is run in serial.
Rules
The first noncomment line (not including other directives) that is following the PARALLEL DO directive must be a DO loop. This line cannot be an infinite DO or DO WHILE loop. The PARALLEL DO directive applies only to the DO loop that is immediately following the directive, and not to any nested DO loops.
If you specify a DO loop by a PARALLEL DO directive, the END PARALLEL DO directive is optional. If you use the END PARALLEL DO directive, it must immediately follow the end of the DO loop.
You may have a DO construct that contains several DO statements. If the DO statements share the same DO termination statement, and an END PARALLEL DO directive follows the construct, you can only specify a PARALLEL DO directive for the outermost DO statement of the construct.
You must not follow the PARALLEL DO directive by a DO (work-sharing) or DO SERIAL directive. You can specify only one PARALLEL DO directive for a given DO loop.
All work-sharing constructs and BARRIER directives that are encountered must be encountered in the same order by all threads in the team.
The PARALLEL DO directive must not appear with the INDEPENDENT directive for a given DO loop.
The IF clause may appear at most once in a PARALLEL DO directive.
An IF expression is evaluated outside of the context of the parallel construct. Any function reference in the IF expression must not have side effects.
By default, a nested parallel loop is serialized, regardless of the setting of the IF clause. You can change this default by using the -qsmp=nested_par compiler option.
The SCHEDULE clause may appear at most once in a PARALLEL DO directive.
If the REDUCTION variable of an inner DO loop appears in the PRIVATE or LASTPRIVATE clause of an enclosing DO loop or PARALLEL SECTIONS construct, the variable must be initialized before the inner DO loop.
A variable that appears in the REDUCTION clause of an INDEPENDENT directive of an enclosing DO loop must not also appear in the data_scope_entity_list of the PRIVATE or LASTPRIVATE clause.
You should be careful when you perform input/output operations in a parallel region. If multiple threads execute a Fortran I/O statement on the same unit, you should make sure that the threads are synchronized. If you do not, the behaviour is undefined. Also note that although in the XL Fortran implementation each thread has exclusive access to the I/O unit, the OpenMP specification does not require exclusive access.
Directives that bind to a parallel region will bind to that parallel region even if it is serialized.
Examples
Example 1: A valid example with the LASTPRIVATE clause.
!$OMP PARALLEL DO PRIVATE(I), LASTPRIVATE (X) DO I = 1,10 X = I * I A(I) = X * B(I) END DO PRINT *, X ! X has the value 100
Example 2: A valid example with the REDUCTION clause.
!$OMP PARALLEL DO PRIVATE(I), REDUCTION(+:MYSUM) DO I = 1, 10 MYSUM = MYSUM + IARR(I) END DO
Example 3: A valid example where more than one thread accesses a variable that is marked as SHARED, but the variable is used only in a CRITICAL construct.
!$OMP PARALLEL DO SHARED (X) DO I = 1, 10 A(I) = A(I) * I !$OMP CRITICAL X = X + A(I) !$OMP END CRITICAL END DO
Example 4: A valid example of the END PARALLEL DO directive.
REAL A(100), B(2:100), C(100) !$OMP PARALLEL DO DO I = 2, 100 B(I) = (A(I) + A(I-1))/2.0 END DO !$OMP END PARALLEL DO !$OMP PARALLEL DO DO J = 1, 100 C(J) = X + COS(J*5.5) END DO !$OMP END PARALLEL DO END
Related Information