Purpose
The WORKSHARE directive allows you to parallelize the execution of array operations. A WORKSHARE directive divides the tasks associated with an enclosed block of code into units of work. When a team of threads encounters a WORKSHARE directive, the threads in the team share the tasks, so that each unit of work executes exactly once.
The PARALLEL WORKSHARE construct provides a short form method for including a WORKSHARE directive inside a PARALLEL construct. All functionality and restrictions are retained. For more information on the PARALLEL WORKSHARE, see PARALLEL WORKSHARE / END PARALLEL WORKSHARE.
The WORKSHARE directive only takes effect if you specify the -qsmp compiler option.
Format
>>-WORKSHARE--------------------------------------------------->< >>-block------------------------------------------------------->< >>-END WORKSHARE--+--------+----------------------------------->< '-NOWAIT-' |
The transformational intrinsic functions you can use as part of an array
operation are:
ALL | MATMUL | PRODUCT |
ANY | MAXLOC | RESHAPE |
COUNT | MAXVAL | SPREAD |
CSHIFT | MINLOC | SUM |
DOT_PRODUCT | MINVAL | TRANSPOSE |
EOSHIFT | PACK | UNPACK |
The block can also contain statements bound to lexically enclosed PARALLEL constructs. These statements are not restricted.
Any user-defined function calls within the block must be elemental.
Statements enclosed in a WORKSHARE directive are divided into units of work. The definition of a unit of work varies according to the statement evaluated. A unit of work is defined as follows:
If none of the above definitions apply to a statement within the block, then that statement is a unit of work.
Rules
In order to ensure that the statements within a WORKSHARE construct execute in parallel, the construct must be enclosed within the dynamic extent of a parallel region. Threads encountering a WORKSHARE construct outside the dynamic extent of a parallel region will evaluate the statements within the construct serially.
A WORKSHARE directive binds to the closest dynamically enclosing PARALLEL directive if one exists.
You must not nest DO, SECTIONS, SINGLE and WORKSHARE directives that bind to the same PARALLEL directive
You must not specify a WORKSHARE directive within the dynamic extent of CRITICAL, MASTER, or ORDERED directives.
You must not specify BARRIER, MASTER, or ORDERED directives within the dynamic extent of a WORKSHARE construct.
If an array assignment, scalar assignment, a masked array assignment or a FORALL assignment assigns to a private variable in the block, the result is undefined.
If an array expression in the block references the value, association status or allocation status of private variables, the value of the expression is undefined unless each thread computes the same value.
If you do not specify a NO WAIT clause at the end of a WORKSHARE construct, a BARRIER directive is implied.
A WORKSHARE construct must be encountered by all threads in the team or by none at all.
Examples
Example 1: In the following example, the WORKSHARE directive evaluates the masked expressions in parallel..
!$OMP WORKSHARE FORALL (I = 1 : N, AA(1, I) = 0) AA(1, I) = I BB = TRANSPOSE(AA) CC = MATMUL(AA, BB) !$OMP ATOMIC S = S + SUM(CC) !$OMP END WORKSHARE
Example 2: The following example includes a user defined ELEMENTAL as part of a WORKSHARE construct.
!$OMP WORKSHARE WHERE (AA(1, :) /= 0.0) AA(1, :) = 1 / AA(1, :) DD = TRANS(AA(1, :)) !$OMP END WORKSHARE ELEMENTAL REAL FUNCTION TRANS(ELM) RESULT(RES) REAL, INTENT(IN) :: ELM RES = ELM * ELM + 4 END FUNCTION
Related Information
+----------------------------End of IBM Extension----------------------------+