Task Construct. STMicroelectronics PGI
Below you will find brief information for PGI. Parallel Fortran, C and C++ compilers are designed for scientists and engineers. The guide provides details on optimizing and parallelizing code, using directives and pragmas, and more.
Advertisement
Advertisement
Tasks
• Beginning of a task.
At the beginning of a task, the task can be executed immediately or registered for later execution. A programmer-specified "if" clause that is FALSE forces immediate execution of the task. The implementation can also force immediate execution; for example, a task within a task is never registered for later execution, it executes immediately.
• End of a task
At the end of a task, the behavior of the scheduling point depends on how the task was executed. If the task was immediately executed, execution continues to the next statement. If it was previously registered and is being executed "out of sequence", control returns to where the task was executed.
• Taskwait
A taskwait executes all registered tasks at the time it is called. In addition to executing all tasks registered by the calling thread, it also executes tasks previously registered by other threads. Let’s take a quick look at this process; suppose the following is true:
• Thread 0 called taskwait and is executing tasks.
• Thread 1 is registering tasks.
Depending on the timing between thread 0 and thread 1, thread 0 may execute none of the tasks, all of the tasks, or some of tasks.
Note
Taskwait waits only for immediate children tasks, not for descendant tasks. You can achieve waiting on descendants but ensuring that each child also waits on its children.
• Barrier
A barrier can be explicit or implicit. An example of an implicit barrier is the end of a parallel region.
The barrier effectively contains taskwaits. All threads must arrive at the barrier for the barrier to complete.
This rule guarantees that all tasks have been executed at the completion of the barrier.
Task Construct
A task construct is a task directive plus a structured block, with the following syntax:
#pragma omp task [clause[[,]clause] ...]
structured-block where clause can be one of the following: if (expression) untied shared (list) private (list) firstprivate (list) default( shared | none )
Consider the following simple example of a program using tasks. This example illustrates the difference between registering tasks and executing tasks, a concept that is fundamental to understanding tasks.
290
Chapter 17. OpenMP Reference Information
This program contains a parallel region that contains a single region. The single region contains a loop that registers 10 tasks. Before reading the explanation that follows the example, consider what happens if you use four threads with this example.
Example 17.1. OpenMP Task C Example int main(int argc,char *argv[])
{
int i;
#pragma omp parallel private(i)
{
#pragma omp single
{
for(i=0;i<10;i++) {
sleep(i%2);
printf("task %2d registered by thread %d\n",i,
omp_get_thread_num());
#pragma omp task firstprivate(i)
{
sleep(i%5);
printf("task %2d executed by thread %d\n",i,
omp_get_thread_num());
} /* end task */
} /* end for */
} /* end single */
} /* end parallel */
} /* end main */
Example 17.2. OpenMP Task Fortran Example
PROGRAM MAIN
INTEGER I
INTEGER omp_get_thread_num
!$OMP PARALLEL PRIVATE(I)
!$OMP SINGLE
DO I = 1, 10
CALL SLEEP(MOD(I,2))
PRINT *,"TASK ",I," REGISTERED BY THREAD ",omp_get_thread_num()
!$OMP TASK FIRSTPRIVATE(I)
CALL SLEEP(MOD(I,5))
PRINT *,"TASK ",I," EXECUTED BY THREAD ",omp_get_thread_num()
!$OMP END TASK
ENDDO
!$OMP END SINGLE
!$OMP END PARALLEL
END
If you run this program with four threads, 0 through 3, one thread is in the single region registering tasks. The other three threads are in the implied barrier at the end of the single region executing tasks. Further, when the thread executing the single region completes registering the tasks, it joins the other threads and executes tasks.
The program includes calls to sleep
to slow the program and allow all threads to participate.
The output for the Fortran example is similar to the following. In this output, thread 1 was registering tasks while the other three threads - 0,2, and 3 - were executing tasks When all 10 tasks were registered, thread 1 began executing tasks as well.
291
Parallelization Directives and Pragmas
TASK 1 REGISTERED BY THREAD 1
TASK 2 REGISTERED BY THREAD 1
TASK 1 EXECUTED BY THREAD 0
TASK 3 REGISTERED BY THREAD 1
TASK 4 REGISTERED BY THREAD 1
TASK 2 EXECUTED BY THREAD 3
TASK 5 REGISTERED BY THREAD 1
TASK 6 REGISTERED BY THREAD 1
TASK 6 EXECUTED BY THREAD 3
TASK 5 EXECUTED BY THREAD 3
TASK 7 REGISTERED BY THREAD 1
TASK 8 REGISTERED BY THREAD 1
TASK 3 EXECUTED BY THREAD 0
TASK 9 REGISTERED BY THREAD 1
TASK 10 REGISTERED BY THREAD 1
TASK 10 EXECUTED BY THREAD 1
TASK 4 EXECUTED BY THREAD 2
TASK 7 EXECUTED BY THREAD 0
TASK 8 EXECUTED BY THREAD 3
TASK 9 EXECUTED BY THREAD 1
Parallelization Directives and Pragmas
Parallelization directives, as described in Chapter 5, “
, are comments in a program that are interpreted by the PGI Fortran compilers when the option
-mp
is specified on the command line. The form of a parallelization directive is: sentinel directive_name [clauses]
Parallelization pragmas are #pragma statements in a C or C++ program that are interpreted by the PGCC C and
C++ compilers when the option -mp is specified on the command line. The form of a parallelization pragma is:
#pragma omp pragma_name [clauses]
The examples given with each section use the routines omp_get_num_threads()
and omp_get_thread_num()
. They return the number of threads currently in the team executing the parallel region and the thread number within the team, respectively. For more information, refer to
.
Note
Directives which are presented in pairs must be used in pairs.
. For each directive and pragma, this section describes the overall purpose, the syntax, the clauses associated with it, the usage, and examples of how to use it.
ATOMIC and atomic
The OpenMP ATOMIC directive or the omp critical pragma is semantically equivalent to a single statement in a
CRITICAL...END CRITICAL directive or the omp critical pragma.
Syntax:
292
Chapter 17. OpenMP Reference Information
!$OMP ATOMIC #pragma omp atomic
< C/C++ expression statement >
Usage:
The ATOMIC directive is semantically equivalent to enclosing the following single statement in a CRITICAL /
END CRITICAL directive pair. The omp atomic pragma is semantically equivalent to subjecting the following single C/C++ expression statement to an omp critical pragma.
The statements must be one of the following forms:
For Directives: For Pragmas: x = x operator expr x <binary_operator>= expr x = expr operator x x = intrinsic (x, expr) x = intrinsic (expr, x) x++
++x x--
--x where x
is a scalar variable of intrinsic type, expr
is a scalar expression that does not reference x
, intrinsic is one of MAX, MIN, IAND, IOR, or IEOR, operator is one of +, *, -, /, .AND., .OR., .EQV., or .NEQV., and
<binary_operator> is not overloaded and is one of +, *, -, /, &, ^, |, << or >>.
BARRIER and barrier
The OpenMP BARRIER directive defines a point in a program where each thread waits for all other threads to arrive before continuing with program execution.
Syntax:
!$OMP BARRIER #pragma omp barrier
Usage:
There may be occasions in a parallel region when it is necessary that all threads complete work to that point before any thread is allowed to continue. The BARRIER directive or omp barrier pragma synchronizes all threads at such a point in a program. Multiple barrier points are allowed within a parallel region. The
BARRIER directive and omp barrier pragma must either be executed by all threads executing the parallel region or by none of them.
CRITICAL ... END CRITICAL and critical
The CRITICAL...END CRITICAL directive and omp critical pragma require a thread to wait until no other thread is executing within a critical section.
Syntax:
!$OMP CRITICAL [(name)]
< Fortran code executed in body of critical section >
!$OMP END CRITICAL [(name)]
#pragma omp critical [(name)]
< C/C++ structured block >
293
CRITICAL ... END CRITICAL and critical
294
Usage:
Within a parallel region, there may exist subregions of code that will not execute properly when executed by multiple threads simultaneously. This issue is often due to a shared variable that is written and then read again.
The CRITICAL... END CRITICAL directive pair and the omp critical pragma define a subsection of code within a parallel region, referred to as a critical section, which is executed one thread at a time.
The first thread to arrive at a critical section is the first to execute the code within the section. The second thread to arrive does not begin execution of statements in the critical section until the first thread exits the critical section. Likewise, each of the remaining threads waits to execute the statements in the critical section until the previous thread exits the critical section.
You can use the optional
name argument
to identify the critical region. Names that identify critical regions have external linkage and are in a name space separate from the name spaces used by labels, tags, members, and ordinary identifiers. If a name argument appears on a CRITICAL directive, the same name must appear on the END CRITICAL directive.
Note
Critical sections cannot be nested, and any such specifications are ignored. Branching into or out of a critical section is illegal.
Fortran Example of Critical...End Critical directive:
PROGRAM CRITICAL_USE
REAL A(100,100),MX, LMX
INTEGER I, J
MX = -1.0
LMX = -1.0
CALL RANDOM_SEED()
CALL RANDOM_NUMBER(A)
!$OMP PARALLEL PRIVATE(I), FIRSTPRIVATE(LMX)
!$OMP DO
DO J=1,100
DO I=1,100
LMX = MAX(A(I,J),LMX)
ENDDO
ENDDO
!$OMP CRITICAL
MX = MAX(MX,LMX)
!$OMP END CRITICAL
!$OMP END PARALLEL
PRINT *,"MAX VALUE OF A IS ", MX
END
C Example of
omp critical
pragma
#include <stdlib.h> main(){ int a[100][100], mx=-1,lmx=-1, i, j;
for (j=0; j<100; j++)
for (i=0; i<100; i++)
a[i][j]=1+(int)(10.0*rand()/(RAND_MAX+1.0));
#pragma omp parallel private(i) firstprivate(lmx)
{
#pragma omp for
Chapter 17. OpenMP Reference Information
for (j=0; j<100; j++)
for (i=0; i<100; i++)
lmx = (lmx > a[i][j]) ? lmx : a[i][j];
#pragma omp critical
mx = (mx > lmx) ? mx : lmx;
}
printf ("max value of a is %d\n",mx);
}
This program could also be implemented without the critical region by declaring
MX
as a reduction variable and performing the
MAX
calculation in the loop using
MX
directly rather than using
LMX
. Refer to
“PARALLEL ... END PARALLEL and parallel ”
for more information on how to use the REDUCTION clause on a parallel DO loop.
C$DOACROSS
The C$DOACROSS directive, while not part of the OpenMP standard, is supported for compatibility with programs parallelized using legacy SGI-style directives.
Syntax:
C$DOACROSS [ Clauses ]
< Fortran DO loop to be executed
in parallel >
#pragma omp parallel [clauses]
< C/C++ structured block >
Clauses:
For Directives:
[ {PRIVATE | LOCAL} (list) ]
[ {SHARED | SHARE} (list) ]
[ MP_SCHEDTYPE={SIMPLE | INTERLEAVE} ]
[ CHUNK=<integer_expression> ]
[ IF (logical_expression) ]
For Pragmas: private | local(list) shared | share(list) mp_schedule (simple | interleave) chunk=<integer_expression> if (logical_expression)
Usage:
The C$DOACROSS directive has the effect of a combined parallel region and parallel DO loop applied to the loop immediately following the directive. It is very similar to the OpenMP PARALLEL DO directive, but provides for backward compatibility with codes parallelized for SGI systems prior to the OpenMP standardization effort.
The C$DOACROSS directive must not appear within a parallel region. It is a shorthand notation that tells the compiler to parallelize the loop to which it applies, even though that loop is not contained within a parallel region. While this syntax is more convenient, it should be noted that if multiple successive DO loops are to be parallelized it is more efficient to define a single enclosing parallel region and parallelize each loop using the
OpenMP DO directive.
A variable declared PRIVATE or LOCAL to a C$DOACROSS loop is treated the same as a private variable in a parallel region or DO. A variable declared SHARED or SHARE to a C$DOACROSS loop is shared among the threads, meaning that only 1 copy of the variable exists to be used and/or modified by all of the threads. This is equivalent to the default status of a variable that is not listed as PRIVATE in a parallel region or DO. This same
295
DO...END DO and for
.
DO...END DO and for
The OpenMP DO...END DO directive and omp for pragma support parallel execution and the distribution of loop iterations across available threads in a parallel region.
Syntax:
!$OMP DO [Clauses]
< Fortran DO loop to be executed
in parallel
!$OMP END DO [NOWAIT]
#pragma omp for [Clauses]
< C/C++ for loop to be executed in parallel >
Clauses:
For Directives:
PRIVATE(list)
FIRSTPRIVATE(list)
LASTPRIVATE(list)
REDUCTION({operator | intrinsic } : list)
SCHEDULE (type [, chunk])
COLLAPSE (n)
ORDERED
Usage:
The real purpose of supporting parallel execution is the distribution of work across the available threads. The
DO... END DO directive pair and the omp for pragma provide a convenient mechanism for the distribution of loop iterations across the available threads in a parallel region.
While you can explicitly manage work distribution with constructs such as the following one, these constructs are not in the form of directives or pragmas.
Examples:
For Directives:
IF (omp_get_thread_num() .EQ. 0)
THEN
...
ELSE IF (omp_get_thread_num() .EQ. 1)
THEN
...
ENDIF
For Pragmas: if (omp_get_thread_num() == 0) {
...
} else if (omp_get_thread_num() == 1) {
...
}
Tips
For Pragmas: private(list) firstprivate(list) lastprivate(list) reduction(operator: list) schedule (kind[, chunk]) collapse (n) ordered nowait
296
Chapter 17. OpenMP Reference Information
Remember these items about clauses in the DO...END DO directives and omp for pragmas:
• Variables declared in a PRIVATE list are treated as private to each thread participating in parallel execution of the loop, meaning that a separate copy of the variable exists with each thread.
• Variables declared in a FIRSTPRIVATE list are PRIVATE, and are initialized from the original object existing before the construct.
• Variables declared in a LASTPRIVATE list are PRIVATE, and the thread that executes the sequentially last iteration updates the version of the object that existed before the construct.
• The REDUCTION clause for the directive is described in “REDUCTION,” on page 312
and the reduction
clause for the pragma is described in “Directive and Pragma Clauses,” on page 309
.
• The SCHEDULE clause specifies how iterations of the DO or for loop are divided up between threads. For
more information on this clause, refer to “SCHEDULE,” on page 313
.
• If ORDERED code blocks are contained in the dynamic extent of the DO directive, the ORDERED clause
must be present. For more information on ORDERED code blocks, refer to “ORDERED and ordered ”
.
• The DO... END DO directive pair directs the compiler to distribute the iterative DO loop immediately following the !$OMP DO directive across the threads available to the program. The DO loop is executed in parallel by the team that was started by an enclosing parallel region. If the !$OMP END DO directive is not specified, the !$OMP DO is assumed to end with the enclosed DO loop. DO... END DO directive pairs may not be nested. Branching into or out of a !$OMP DO loop is not supported.
• The
omp for
pragma directs the compiler to distribute the iterative for loop immediately following across the threads available to the program. The for loop is executed in parallel by the team that was started by an enclosing parallel region. Branching into or out of an omp for loop is not supported, and omp for pragmas may not be nested.
• By default, there is an implicit barrier after the end of the parallel loop; the first thread to complete its portion of the work waits until the other threads have finished their portion of work. If NOWAIT is specified, the threads will not synchronize at the end of the parallel loop.
In addition to the preceding items, remember these items about !$OMP DO loops and
omp for
loops:
• The DO loop index variable is always private.
• The for loop index variable is always private.
• !$OMP DO loops and omp for loops must be executed by all threads participating in the parallel region or none at all.
• The END DO directive is optional, but if it is present it must appear immediately after the end of the enclosed DO loop.
• The for loop must be a structured block and its execution must not be terminated by break.
• Values of the loop control expressions and the chunk expressions must be the same for all threads executing the loop.
Examples:
297
FLUSH and flush
Fortran Example of
DO...END DO
directive
PROGRAM DO_USE
REAL A(1000), B(1000)
DO I=1,1000
B(I) = FLOAT(I)
ENDDO
!$OMP PARALLEL
!$OMP DO
DO I=1,1000
A(I) = SQRT(B(I));
ENDDO
...
!$OMP END PARALLEL
...
END
C Example of
omp for
pragma
#include <stdio.h>
#include <math.h> main(){ float a[1000], b[1000]; int i;
for (i=0; i<1000; i++)
b[i] = i;
#pragma omp parallel
{
#pragma omp for
for (i=0; i<1000; i++)
a[i] = sqrt(b[i]);
...
}
...
}
FLUSH and flush
The OpenMP FLUSH directive and omp flush pragma ensure that processor-visible data item are written back to memory at the point at which the directive appears.
Syntax:
!$OMP FLUSH [(list)] #pragma omp flush [(list)]
Usage:
The OpenMP FLUSH directive ensures that all processor-visible data items, or only those specified in list
, when it is present, are written back to memory at the point at which the directive or pragma appears.
MASTER ... END MASTER and master
The MASTER...END MASTER directive and omp master pragma allow the user to designate code that must execute on a master thread and that is skipped by other threads in the team of threads.
Syntax:
!$OMP MASTER
< Fortran code executed in body of
MASTER section >
!$OMP END MASTER
#pragma omp master
< C/C++ structured block >
Usage:
A master thread is a single thread of control that begins an OpenMP program and which is present for the duration of the program. In a parallel region of code, there may be a sub-region of code that should execute only on the master thread. Instead of ending the parallel region before this subregion and then starting it up again after this subregion, the MASTER... END MASTER directive pair or omp master pragma allows the user to conveniently designate code that executes on the master thread and is skipped by the other threads.
• There is no implied barrier on entry to or exit from a master section of code.
• Nested master sections are ignored.
298
Chapter 17. OpenMP Reference Information
• Branching into or out of a master section is not supported.
Examples:
Example of Fortran
MASTER...END MASTER
directive
PROGRAM MASTER_USE
INTEGER A(0:1)
INTEGER omp_get_thread_num
A=-1
!$OMP PARALLEL
A(omp_get_thread_num()) = omp_get_thread_num()
!$OMP MASTER
PRINT *, "YOU SHOULD ONLY SEE THIS ONCE"
!$OMP END MASTER
!$OMP END PARALLEL
PRINT *, "A(0)=", A(0), " A(1)=", A(1)
END
Example of
omp master
pragma
#include <stdio.h>
#include <omp.h> main(){
int a[2]={-1,-1};
#pragma omp parallel
{
a[omp_get_thread_num()] = omp_get_thread_num();
#pragma omp master
printf("YOU SHOULD ONLY SEE THIS ONCE\n");
}
printf("a[0]=%d, a[1]=%d\n",a[0],a[1]);
}
ORDERED and ordered
The OpenMP ORDERED directive and omp ordered pragma allow the user to identify a portion of code within an ordered code block that must be executed in the original, sequential order, while allowing parallel execution of statements outside the code block.
Syntax:
!$OMP ORDERED
< Fortran code block executed
by processor >
!$OMP END ORDERED
#pragma omp ordered
< C/C++ structured block >
Usage:
The ORDERED directive can appear only in the dynamic extent of a DO or PARALLEL DO directive that includes the ORDERED clause. The ordered pragma can appear only in the dynamic extent of a for or parallel for pragma that includes the ordered clause. The structured code block between the ORDERED / END ORDERED directives or after the ordered pragma is executed by only one thread at a time, and in the order of the loop iterations. This sequentializes the ordered code block while allowing parallel execution of statements outside the code block. The following additional restrictions apply to the ORDERED directive and ordered pragma:
• The ordered code block must be a structured block.
299
PARALLEL ... END PARALLEL and parallel
• It is illegal to branch into or out of the block.
• A given iteration of a loop with a DO directive or omp for pragma cannot execute the same ORDERED directive or omp ordered pragma more than once, and cannot execute more than one ORDERED directive or omp ordered pragma.
PARALLEL ... END PARALLEL and parallel
The OpenMP PARALLEL...END PARALLEL directive and OpenMP omp parallel pragma support a fork/join execution model in which a single thread executes all statements until a parallel region is encountered.
Syntax:
!$OMP PARALLEL [Clauses]
< Fortran code executed in body
of parallel region >
!$OMP END PARALLEL
#pragma omp parallel [clauses]
< C/C++ structured block >
Clauses:
For Directives:
PRIVATE(list)
SHARED(list)
DEFAULT(PRIVATE | SHARED | NONE)
FIRSTPRIVATE(list)
REDUCTION([{operator | intrinsic}:] list)
COPYIN(list)
IF(scalar_logical_expression)
NUM_THREADS(scalar_integer_expression)
For Pragmas: private(list) shared(list) default(shared | none) firstprivate(list) reduction(operator: list) copyin (list) if (scalar_expression) num_threads(scalar_integer_expression)
Usage:
This directive pair or pragma declares a region of parallel execution. It directs the compiler to create an executable in which the statements within the structured block, such as between PARALLEL and PARALLEL END for directives, are executed by multiple lightweight threads. The code that lies within this structured block is called a
parallel region
.
The OpenMP parallelization directives or pragmas support a fork/join execution model in which a single thread executes all statements until a parallel region is encountered. At the entrance to the parallel region, a system-dependent number of symmetric parallel threads begin executing all statements in the parallel region redundantly. These threads share work by means of work-sharing constructs such as parallel DO loops or FOR loops.
• The number of threads in the team is controlled by the
OMP_NUM_THREADS
environment variable. If
OMP_NUM_THREADS
is not defined, the program executes parallel regions using only one processor.
• Branching into or out of a parallel region is not supported.
• All other shared-memory parallelization directives or pragmas must occur within the scope of a parallel region. Nested PARALLEL... END PARALLEL directive pairs or omp parallel pragmas are not supported and are ignored.
300
Chapter 17. OpenMP Reference Information
• There is an implicit barrier at the end of the parallel region, which, in the directive, is denoted by the END
PARALLEL directive. When all threads have completed execution of the parallel region, a single thread resumes execution of the statements that follow.
Note
By default, there is no work distribution in a parallel region. Each active thread executes the entire region redundantly until it encounters a directive or pragma that specifies work distribution. For work distribution, see the DO, PARALLEL DO, or DOACROSS directives or the omp for pragma.
Examples:
PARALLEL...END PARALLEL directive example:
PROGRAM WHICH_PROCESSOR_AM_I
INTEGER A(0:1)
INTEGER omp_get_thread_num
A(0) = -1
A(1) = -1
!$OMP PARALLEL
A(omp_get_thread_num())
= omp_get_thread_num()
!$OMP END PARALLEL
PRINT *, "A(0)=",A(0),
" A(1)=",A(1)
END omp parallel pragma example
#include <stdio.h>
#include <omp.h> main(){
int a[2]={-1,-1};
#pragma omp parallel
{
a[omp_get_thread_num()] =
omp_get_thread_num();
}
printf("a[0] = %d, a[1] = %d",a[0],a[1]);
}
Clause Usage:
COPYIN: The COPYIN clause applies only to THREADPRIVATE common blocks. In the presence of the COPYIN clause, data from the master thread’s copy of the common block is copied to the THREADPRIVATE copies upon entry to the parallel region.
IF: In the presence of an IF clause, the parallel region is executed in parallel only if the corresponding scalar_logical_expression
evaluates to .TRUE.. Otherwise, the code within the region is executed by a single processor, regardless of the value of the environment variable
OMP_NUM_THREADS
.
NUM_THREADS: If the NUM_THREADS clause is present, the corresponding scalar_integer_expression
must evaluate to a positive integer value. This value sets the maximum number of threads used during execution of the parallel region. A NUM_THREADS clause overrides either a previous call to the library routine omp_set_num_threads() or the setting of the OMP_NUM_THREADS environment variable.
PARALLEL DO
The OpenMP PARALLEL DO directive is a shortcut for a PARALLEL region that contains a single DO directive.
Note
The OpenMP PARALLEL DO or DO directive must be immediately followed by a DO statement (as defined by R818 of the ANSI Fortran standard). If you place another statement or an OpenMP directive between the PARALLEL DO or DO directive and the DO statement, the compiler issues a syntax error.
301
PARALLEL SECTIONS and parallel sections
Syntax:
!$OMP PARALLEL DO [CLAUSES]
< Fortran DO loop to be executed
in parallel >
[!$OMP END PARALLEL DO]
Clauses:
For Directives:
PRIVATE(list)
SHARED(list)
DEFAULT(PRIVATE | SHARED | NONE)
FIRSTPRIVATE(list)
LASTPRIVATE(list)
REDUCTION([{operator | intrinsic}:] list)
COPYIN(list)
IF(scalar_logical_expression)
NUM_THREADS(scalar_integer_expression)
SCHEDULE (type [, chunk])
COLLAPSE (n)
ORDERED
#pragma omp parallel [clauses]
< C/C++ structured block >
For Pragmas: private(list) shared(list) default(shared | none) firstprivate(list) reduction(operator: list) copyin (list) if (scalar_expression) num_threads(scalar_integer_expression)
Usage:
The semantics of the PARALLEL DO directive are identical to those of a parallel region containing only a single
PARALLEL and parallel ,” on page 300 and
Note
The END PARALLEL DO directive is optional.
PARALLEL SECTIONS and parallel sections
The OpenMP PARALLEL SECTIONS / END SECTIONS directive pair and the omp parallel sections pragma define tasks to be executed in parallel; that is, they define a non-iterative work-sharing construct without the need to define an enclosing parallel region.
Syntax:
!$OMP PARALLEL SECTIONS [CLAUSES]
[!$OMP SECTION]
< Fortran code block executed
by processor i >
[!$OMP SECTION]
< Fortran code block executed
by processor j >
...
!$OMP END SECTIONS [NOWAIT]
#pragma omp parallel sections [clauses]
{
[#pragma omp section]
< C/C++ structured block executed
by processor i >
[#pragma omp section]
< C/C++ structured block executed
by processor j >
...
}
Clauses:
302
Chapter 17. OpenMP Reference Information
For Directives:
PRIVATE(list)
SHARED(list)
DEFAULT(PRIVATE | SHARED | NONE)
FIRSTPRIVATE(list)
LASTPRIVATE(list)
REDUCTION({operator | intrinsic} : list)
COPYIN (list)
IF(scalar_logical_expression)
NUM_THREADS(scalar_integer_expression)
For Pragmas: private(list) shared(list) default(shared | none) firstprivate(list) lastprivate (list) reduction({operator: list) copyin (list) if (scalar_expression) num_threads(scalar_integer_expression) nowait
Usage:
The PARALLEL SECTIONS / END SECTIONS directive pair and the omp parallel sections pragma define a noniterative work-sharing construct without the need to define an enclosing parallel region. Each section is executed by a single processor. If there are more processors than sections, some processors will have no work and will jump to the implied barrier at the end of the construct. If there are more sections than processors, one or more processors will execute more than one section.
A SECTION directive may only appear within the lexical extent of the enclosing PARALLEL SECTIONS / END
SECTIONS directives. In addition, the code within the PARALLEL SECTIONS / END SECTIONS directives must be a structured block, and the code in each SECTION must be a structured block.
Semantics are identical to a parallel region containing only an omp sections pragma and the associated
.
PARALLEL WORKSHARE ... END PARALLEL WORKSHARE
The OpenMP PARALLEL WORKSHARE Fortran directive provides a short form method of including a
WORKSHARE directive inside a PARALLEL construct. The END PARALLEL WORKSHARE directive is optional.
Syntax:
!$OMP PARALLEL WORKSHARE [CLAUSES]
< Fortran structured block to be executed in parallel >
[!$OMP END PARALLEL WORKSHARE]
!$OMP PARALLEL DO [CLAUSES]
< Fortran DO loop to be executed in parallel >
[!$OMP END PARALLEL DO]
Clauses:
PRIVATE(list)
SHARED(list)
DEFAULT(PRIVATE | SHARED | NONE)
FIRSTPRIVATE(list)
LASTPRIVATE(list)
REDUCTION({operator | intrinsic} : list)
COPYIN (list)
IF(scalar_logical_expression)
NUM_THREADS(scalar_integer_expression)
SCHEDULE (type [, chunk])
COLLAPSE (n)
ORDERED
303
SECTIONS … END SECTIONS and sections
Usage:
The OpenMP PARALLEL WORKSHARE directive provides a short form method of including a WORKSHARE directive inside a PARALLEL construct. The semantics of the PARALLEL WORKSHARE directive are identical to those of a parallel region containing a single WORKSHARE construct.
The END PARALLEL WORKSHARE directive is optional, and NOWAIT may not be specified on an END PARALLEL
.
SECTIONS … END SECTIONS and sections
The OpenMP SECTIONS / END SECTIONS directive pair and the omp sections pragma define a non-iterative work-sharing construct within a parallel region in which each section is executed by a single processor.
Syntax:
!$OMP SECTIONS [ Clauses ]
[!$OMP SECTION]
< Fortran code block executed
by processor i >
[!$OMP SECTION]
< Fortran code block executed
by processor j >
...
!$OMP END SECTIONS [NOWAIT]
#pragma omp sections [ Clauses ]
{
[#pragma omp section]
< C/C++ structured block executed
by processor i >
[#pragma omp section]
< C/C++ structured block executed
by processor j >
...
}
Clauses:
For Directives:
PRIVATE(list)
FIRSTPRIVATE(list)
LASTPRIVATE(list)
REDUCTION({operator | intrinsic} : list)
For Pragmas: private(list) firstprivate(list) lastprivate (list) reduction({operator: list) nowait
Usage:
The SECTIONS / END SECTIONS directive pair and the omp sections pragma define a non-iterative worksharing construct within a parallel region. Each section is executed by a single processor. If there are more processors than sections, some processors have no work and thus jump to the implied barrier at the end of the construct. If there are more sections than processors, one or more processors must execute more than one section.
A SECTION directive or omp sections pragma may only appear within the lexical extent of the enclosing
SECTIONS / END SECTIONS directives or omp sections pragma. In addition, the code within the SECTIONS /
END SECTIONS directives or omp sections pragma must be a structured block.
The available clauses are as defined in “PARALLEL ... END PARALLEL and parallel ,” on page 300 and
.
304
Chapter 17. OpenMP Reference Information
SINGLE ... END SINGLE and single
The SINGLE...END SINGLE directive or omp single pragma designate code that executes on a single thread and that is skipped by the other threads.
Syntax:
!$OMP SINGLE [Clauses]
< Fortran code executed in body of
#pragma omp single [clauses]
< C/C++ structured block >
SINGLE processor section >
!$OMP END SINGLE [NOWAIT]
Clauses:
For Directives:
PRIVATE(list)
FIRSTPRIVATE(list)
COPYPRIVATE(list)
For Pragmas: private(list) firstprivate(list) copyprivate (list) nowait
Usage:
In a parallel region of code, there may be a sub-region of code that only executes correctly on a single thread.
Instead of ending the parallel region before this subregion and then starting it up again after this subregion, the SINGLE...END SINGLE directive pair lets you conveniently designate code that executes on a single thread and is skipped by the other threads. There is an implied barrier on exit from a SINGLE...END SINGLE section of code unless the optional NOWAIT clause is specified.
Nested single process sections are ignored. Branching into or out of a single process section is not supported.
Examples:
For Directives:
PROGRAM SINGLE_USE
INTEGER A(0:1)
INTEGER omp_get_thread_num()
!$OMP PARALLEL
A(omp_get_thread_num()) =
omp_get_thread_num()
!$OMP SINGLE
PRINT *, "YOU ONLY SEE THIS ONCE"
!$OMP END SINGLE
!$OMP END PARALLEL
PRINT *,"A(0)=",A(0),
" A(1)=", A(1)
END
For Pragmas: single_use() {
int a[2]={0,1};
#pragma omp parallel
{
a(omp_get_thread_num()) =
omp_get_thread_num();
#pragma omp single
{
printf("You only see this once"
} /* end single */
} /* end parallel */ printf("a[0] = %d, a[1] = %d",
a[0], a[1]);
} /* end single_use */
305
TASK and task
TASK and task
The OpenMP TASK directive and the omp task pragma define an explicit task.
Syntax:
!$OMP TASK [Clauses]
< Fortran code executed as task>
!$OMP END TASK
#pragma omp task [clauses]
< C/C++ structured block >
Clauses:
For Directives:
IF(scalar_logical_expression)
UNTIED
DEFAULT(private | firstprivate | shared | none)
PRIVATE(list)
FIRSTPRIVATE(list)
SHARED(list)
For Pragmas: if (scalar_expression) untied default(shared | none) private(list) firstprivate(list) shared(list)
Usage:
The TASK / END TASK directive pair and the omp task pragma define an explicit task.
When a thread encounters a task construct, a task is generated from the code for the associated structured block. The data environment of the task is created according to the data-sharing attribute clauses on the task construct and any defaults that apply. The encountering thread may immediately execute the task, or delay its execution. If the task execution is delayed, then any thread in the team may be assigned the task. Completion of the task can be guaranteed using task synchronization constructs.
A task construct may be nested inside an outer task, but the task region of the inner task is not a part of the task region of the outer task.
When an if clause is present on a task construct and the if clause expression evaluates to false, the encountering thread must suspend the current task region and begin execution of the generated task immediately, and the suspended task region may not be resumed until the generated task is completed.
The task still behaves as a distinct task region with respect to data environment, lock ownership, and synchronization constructs.
Note
Use of a variable in an if clause expression of a task construct causes an implicit reference to the variable in all enclosing constructs.
A thread that encounters a task scheduling point within the task region may temporarily suspend the task region. By default, a task is tied and its suspended task region can only be resumed by the thread that started its execution. If the untied clause is present on a task construct, any thread in the team can resume the task region after a suspension.
306
Chapter 17. OpenMP Reference Information
The task construct includes a task scheduling point in the task region of its generating task, immediately following the generation of the explicit task. Each explicit task region includes a task scheduling point at its point of completion. An implementation may add task scheduling points anywhere in untied task regions.
Note
When storage is shared by an explicit task region, it is the programmer's responsibility to ensure, by adding proper synchronization, that the storage does not reach the end of its lifetime before the explicit task region completes its execution.
Restrictions:
The following restrictions apply to the TASK directive or omp task pragma:
• A program that branches into or out of a task region is non-conforming.
• A program must not depend on any ordering of the evaluations of the clauses of the task directive, or on any side effects of the evaluations of the clauses.
• At most one
if
clause can appear on the directive.
• Unsynchronized use of Fortran I/O statements by multiple tasks on the same unit has unspecified behavior.
• In C/C++, a throw executed inside a task region must cause execution to resume within the same task region, and the same thread that threw the exception must catch it.
TASKWAIT and taskwait
The OpenMP TASKWAIT directive and the omp taskwait pragma specify a wait on the completion of child tasks generated since the beginning of the current task.
Syntax:
!$OMP TASKWAIT #pragma omp taskwait >
Clauses:
For Directives:
IF(scalar_logical_expression)
UNTIED
DEFAULT(private | firstprivate | shared | none)
PRIVATE(list)
FIRSTPRIVATE(list)
SHARED(list)
For Pragmas: if (scalar_expression) untied default(shared | none) private(list) firstprivate(list) shared(list)
Usage:
The OpenMP TASKWAIT directive and the omp taskwait pragma specify a wait on the completion of child tasks generated since the beginning of the current task.
307
THREADPRIVATE and threadprivate
Restrictions:
The following restrictions apply to the TASKWAIT directive or omp taskwait pragma:
• The TASKWAIT directive and the omp taskwait pragma may be placed only at a point where a base language statement is allowed.
• The taskwait directive may not be used in place of the statement following an
if
,
while
,
do
,
switch
, or
label
.
THREADPRIVATE and threadprivate
The OpenMP THREADPRIVATE directive identifies a Fortran common block as being private to each thread.
The omp threadprivate pragma identifies a global variable as being private to each thread.
Syntax:
!$OMP THREADPRIVATE (list) #pragma omp threadprivate (list)
Usage:
The list
is a list of variables to be made private to each thread but global within the thread. For directives, common block names must appear between slashes, such as
/common_block_name/
.
This directive or pragma must appear in the declarations section of a program unit after the declaration of any variables listed. On entry to a parallel region, data in a threadprivate variable is undefined unless copyin is specified on the parallel directive or pragma. When a variable appears in an threadprivate directive or pragma, each thread’s copy is initialized once at an unspecified point prior to its first use as the master copy would be initialized in a serial execution of the program.
Restrictions:
The following restrictions apply to the THREADPRIVATE directive or omp threadprivate pragma:
• The THREADPRIVATE directive must appear after every declaration of a thread private common block.
• The omp threadprivate pragma must appear after the declaration of every threadprivate variable included in list.
• Only named common blocks can be made thread private.
• It is illegal for a THREADPRIVATE common block or its constituent variables to appear in any clause other than a COPYIN clause.
• A variable can appear in a THREADRIVATE directive only in the scope in which it is declared. It must not be an element of a common block or be declared in an EQUIVALENCE statement.
• A variable that appears in a THREADPRIVATE directive and is not declared in the scope of a module must have the SAVE attribute.
• If a variable is specified in an omp threadprivate pragma in one translation unit, it must be specified in an omp threadprivate pragma in every translation unit in which it appears.
• The address of an omp threadprivate variable is not an address constant.
308
Download
Advertisement
Key features
Parallel Fortran, C, and C++ support
Optimization and parallelization tools
Directive and pragma usage
Interprocedural analysis (IPA)
Profile-feedback optimization (PFO)
Frequently asked questions
Use the appropriate command-line syntax and options as described in the manual.
They are used to guide the compiler for optimization and parallelization.
Refer to the sections on SMP parallel programs and data parallel HPF programs.