1

2

OpenMP Application
Program Interface

3

Version 2.5 May 2005

4
5
6
7
8

Copyright © 1997-2005 OpenMP Architecture Review Board.
Permission to copy without fee all or part of this material is granted,
provided the OpenMP Architecture Review Board copyright notice and thetitle of this document appear. Notice is given that copying is by permissionof OpenMP Architecture Review Board.

Introduction...............................................1

2

1.1

Scope

................................................13

1.2

Glossary11.

..............................................2

4

1.2.1

Threading Concepts..............................2

5

1.2.2

OpenMP language terminology

6

1.2.3

Data Terminology

7

1.2.4

Implementation Terminology......................2.................................7........................88

1.3

Execution Model........................................99

1.4

Memory Model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

10

1.4.1

Structure of the OpenMP Memory Model

11

1.4.2

The Flush Operation

12

1.4.3

OpenMP Memory Consistency. . . . . . . . . . . . . . 10

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
. . . . . . . . . . . . . . . . . . . . . . 12

13

1.5

OpenMP Compliance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

14

1.6

Normative References. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

15

1.7

Organization of this document

16
17

2.

Directives
2.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Directive Format. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

18

2.1.1

Fixed Source Form Directives. . . . . . . . . . . . . . . . . . . . . . . 19

19

2.1.2

Free Source Form Directives. . . . . . . . . . . . . . . . . . . . . . . . 20

20

2.2

Conditional Compilation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

21

2.2.1

Fixed Source Form Conditional Compilation Sentinels. . . . 22

22

2.2.2

Free Source Form Conditional Compilation Sentinel. . . . . . 23

23

2.3

Internal Control Variables

24

2.4

parallel Construct
2.4.1

25

27
28

29

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Determining the Number of Threads for aparallel Region

26

2.5

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Work-sharing Constructs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

2.5.1

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Loop Constructi2.5.1.1

1

Determining the Schedule of aWork-sharing Loop2

. . . . . . . . . . . . . . . . . . . . . . . 38

3

2.5.2

sections Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

4

2.5.3

single Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5

2.5.4

workshare Construct

2.6

6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

Combined Parallel Work-sharing Constructs. . . . . . . . . . . . . . . . . . 46

7

2.6.1

Parallel loop construct

8

2.6.2

parallel sections Construct. . . . . . . . . . . . . . . . . . . . . 48

9

2.6.3

parallel workshare Construct. . . . . . . . . . . . . . . . . . . . 50

2.7

10

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Master and Synchronization Constructs. . . . . . . . . . . . . . . . . . . . . . 51

11

2.7.1

master Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

12

2.7.2

critical Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

13

2.7.3

barrier Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

14

2.7.4

atomic Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

15

2.7.5

flush Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

16

2.7.6

ordered Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

2.8

17

Data Environment
2.8.1

18

Sharing Attribute Rules
2.8.1.1

19. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Sharing Attribute Rules for Variables Referenced
in a Construct20

2.8.1.2

21. . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Sharing Attribute Rules for Variables Referenced
in a Region, but not in a Construct

22
23

2.8.2

threadprivate Directive

24

2.8.3

Data-Sharing Attribute Clauses. . . . . . . . . . . 65

. . . . . . . . . . . . . . . . . . . . . . . . . 66
. . . . . . . . . . . . . . . . . . . . . . 70

25

2.8.3.1

default clause. . . . . . . . . . . . . . . . . . . . . . . . . 71

26

2.8.3.2

shared clause. . . . . . . . . . . . . . . . . . . . . . . . . . 72

27

2.8.3.3

private clause. . . . . . . . . . . . . . . . . . . . . . . . . 73

28

2.8.3.4

firstprivate clause. . . . . . . . . . . . . . . . . . . . 75

29

2.8.3.5

lastprivate clause. . . . . . . . . . . . . . . . . . . . . 77

30

2.8.3.6

reduction clause. . . . . . . . . . . . . . . . . . . . . . . 79

31

ii

OpenMP API • Version 2.5 May 2005

2.8.4

1

Data Copying Clauses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

2

2.8.4.1

copyin clause3

2.8.4.2

copyprivate clause

2.9

4

5

3.

Nesting of Regions. . . . . . . . . . . . . . . . . . . . . . . . . 84
. . . . . . . . . . . . . . . . . . . . 85

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

Runtime Library Routines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

6

3.1

Runtime Library Definitions

7

3.2

Execution Environment Routines. . . . . . . . . . . . . . . . . . . . . . . . . . . 91

8

3.2.1

omp_set_num_threads. . . . . . . . . . . . . . . . . . . . . . . . . . 91

9

3.2.2

omp_get_num_threads. . . . . . . . . . . . . . . . . . . . . . . . . . 93

10

3.2.3

omp_get_max_threads. . . . . . . . . . . . . . . . . . . . . . . . . . 94

11

3.2.4

omp_get_thread_num. . . . . . . . . . . . . . . . . . . . . . . . . . . 95

12

3.2.5

omp_get_num_procs. . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

13

3.2.6

omp_in_parallel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

14

3.2.7

omp_set_dynamic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

15

3.2.8

omp_get_dynamic. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

16

3.2.9

omp_set_nested. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

173.2.10 omp_get_nested. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

3.3

18

Lock Routines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

19

3.3.1

omp_init_lock and omp_init_nest_lock

20

3.3.2

omp_destroy_lock and omp_destroy_nest_lock

21

3.3.3

omp_set_lock and omp_set_nest_lock

22

3.3.4

omp_unset_lock and omp_unset_nest_lock

23

3.3.5

omp_test_lock and omp_test_nest_lock

3.4

24

Timing Routines. . . . . . . . . . 104. . . 105

. . . . . . . . . . . . 105. . . . . . . 106. . . . . . . . . . 107. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

25

3.4.1

omp_get_wtime. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

26

3.4.2

omp_get_wtick. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

Environment Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

28

4.1

OMP_SCHEDULE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

29

4.2

OMP_NUM_THREADS

27

30

4.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
iii

1

4.3

OMP_DYNAMIC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

2

4.4

OMP_NESTED. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

A. Examples

3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

4

A.1

A Simple Parallel Loop

5

A.2

The OpenMP Memory Model

6

A.3

Conditional Compilation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

7

A.4

The parallel Construct. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

8

A.5

The num_threads Clause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

9

A.6

Fortran Restrictions on the do Construct. . . . . . . . . . . . . . . . . . . . . 125

10

A.7

Fortran Private Loop Iteration Variables. . . . . . . . . . . . . . . . . . . . . . 127

11

A.8

The nowait clause

12

A.9

The parallel sections Construct13

A.10 The single Construct

14

A.11 The workshare Construct15

A.12 The master Construct16

A.13 The critical Construct17

A.14 Work-Sharing Constructs Inside a critical Construct18

A.15 Binding of barrier Regions19

A.16 The atomic Construct20

A.17 Restrictions on the atomic Construct21

A.18 The flush Construct with a List

22

A.19 The flush Construct without a List

23

A.20 Placement of flush and barrier Directives

24

A.21 The ordered Clause and the ordered Construct25

A.22 The threadprivate Directive

26

A.23 Fortran Restrictions on shared and private Clauses with
Common Blocks

27. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128. . . . . . . . . . . . . . . . . . . . . . . . 129. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138. . . . . . . . . 139. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142. . . . . . . . . . . . . . . . . . . . . . . 144. . . . . . . . . . . . . . . . . . . . . . . . . . . 147. . . . . . . . . . . . . . . . . . . . . . . . . 150. . . . . . . . . . . . . . . . . 153. . . . . . . . . . . . . 154. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

28

A.24 The default(none) Clause

29
30

A.25 Race Conditions Caused by Implied Copies of Shared Variables in
Fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

31

iv

OpenMP API • Version 2.5 May 2005

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

1

A.26 The private Clause2

A.27 Reprivatization

3

A.28 Fortran Restrictions on Storage Association with theprivate Clause4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

5A.29 C/C++ Arrays in a firstprivate Clause6

A.30 The lastprivate Clause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

7A.31 The reduction Clause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

8

A.32 The copyin Clause9

A.33 The copyprivate Clause10

A.34 Nested Loop Constructs

11

A.35 Restrictions on Nesting of Regions

12

A.36 The omp_set_dynamic and omp_set_num_threads
Routines

13. . . . . . . . . . . . . . . . . . . 174. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185. . . . . . . . . . . . . . . . . . . . . . . . . 187. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

14

A.37 The omp_get_num_threads Routine

15

A.38 The omp_init_lock Routine

16

A.39 Simple Lock Routines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198

17

A.40 Nestable Lock Routines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

18

B. Stubs for Runtime Library Routines. . . . . . . . . . . . . . . . . . . . . . 195. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197. . . . . . . . . . . . . . . . . . . . . . . . . . . . 203

19

B.1

C/C++ Stub routines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

20

B.2

Fortran Stub Routines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209

21

C. OpenMP C and C++ Grammar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

22

C.1

Notation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

23

C.2

Rules

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

24

D. Interface Declarations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223

25

D.1

Example of the omp.h Header File

26

D.2

Example of an Interface Declaration include File

27

D.3

Example of a Fortran 90 Interface Declaration module. . . . . . . . . . 227

28

D.4

Example of a Generic Interface for a Library Routine. . . . . . . . . . . . 232

29. . . . . . . . . . . . . . . . . . . . . . . . . 223. . . . . . . . . . . . . 225v

1

E. Implementation Defined Behaviors in OpenMP

2

F. Changes from Version 2.0 to Version 2.5

3

vi

OpenMP API • Version 2.5 May 2005

. . . . . . . . . . . . . . . . . . . 233. . . . . . . . . . . . . . . . . . . . . . . . 237

1

CHAPTER

1

2

Introduction

3
4
5
6
7
8
9

This document specifies a collection of compiler directives, library routines, andenvironment variables that can be used to specify shared-memory parallelism in C, C++
and Fortran programs. This functionality collectively defines the specification of the
OpenMP Application Program Interface (OpenMP API). This specification provides amodel for parallel programming that is portable across shared memory architecturesfrom different vendors. Compilers from numerous vendors support the OpenMP API.
More information about OpenMP can be found at the following web site:10

http://www.openmp.org

11
12
13
14
15
16
17
18

The directives, library routines, and environment variables defined in this document
allow users to create and manage parallel programs while permitting portability. The
directives extend the C, C++ and Fortran base languages with single program multiple
data (SPMD) constructs, work-sharing constructs, and synchronization constructs, andthey provide support for the sharing and privatization of data. The functionality tocontrol the runtime environment is provided by library routines and environment
variables. Compilers that support the OpenMP API often include a command line option
to the compiler that activates and allows interpretation of all OpenMP directives.

19

1.1

Scope

20
21
22
23
24
25
26
27

The OpenMP API covers only user-directed parallelization, wherein the user explicitly
specifies the actions to be taken by the compiler and runtime system in order to executethe program in parallel. OpenMP-compliant implementations are not required to checkfor dependencies, conflicts, deadlocks, race conditions, or other problems that result
from non-conforming programs. The user is responsible for using OpenMP in his
application to produce a conforming program. OpenMP does not cover compilergenerated automatic parallelization and directives to the compiler to assist suchparallelization.

28

1

1

1.2

Glossary2

1.2.1

Threading Concepts

3

thread4
5

thread-safe routine

6

1.2.2

A routine that performs the intended function even when executed
concurrently (by more than one thread).

OpenMP language terminology
base language

78

An execution entity having a serial flow of control and an associated stack.

A programming language that serves as the foundation of the OpenMP
specification.
COMMENT: Current base languages for OpenMP are C90, C99, C++,
Fortran 77, Fortran 90, and Fortran 95.

9
10
11

original program

A program written in a base language.

12
13

structured block

For C/C++, an executable statement, possibly compound, with a single entry
at the top and a single exit at the bottom.

14
15

For Fortran, a block of executable statements with a single entry at the top anda single exit at the bottom.

16

COMMENTS:

17
18

For both languages, the point of entry cannot be a labeled statement
and the point of exit cannot be a branch of any type.

19

For C/C++:

20•

The point of entry cannot be a call to setjmp().

21•

longjmp() and throw() must not violate the entry/exit criteria.

22•

Calls to exit() are allowed in a structured block.

23
24
25
26

•

An expression statement, iteration statement, selection statement,
or try block is considered to be a structured block if thecorresponding compound statement obtained by enclosing it in {and } would be a structured block.

27

2

OpenMP API • Version 2.5 May 2005

1

For Fortran:

2

•

3
4

OpenMP directive

STOP statements are allowed in a structured block.

In C/C++, a #pragma and in Fortran, a comment, that specifies OpenMP
program behavior.
COMMENT: See Section 2.1 on page 18 for a description of OpenMP
directive syntax.

5
6
7

white space

8
9

OpenMP program

A program that consists of an original program, annotated with OpenMP
directives.

10
11
12

declarative directive

An OpenMP directive that may only be placed in a declarative context. A
declarative directive has no associated executable user code, but instead has
one or more associated user declarations.
COMMENT: Only the threadprivate directive is a declarative directive.

13
14
15

executable directive

standalone directive

simple directive

26

An OpenMP executable directive whose associated user code must be asimple (single, non-compound) executable statement.
COMMENT: Only the atomic directive is a simple directive.

23
24
25

An OpenMP executable directive that has no associated executable user code.
COMMENT: Only the barrier and flush directives are standalone
directives.

19
20
21
22

An OpenMP directive that is not declarative, i.e., it may be placed in an
executable context.
COMMENT: All directives except the threadprivate directive are
executable directives.

16
17
18

A non-empty sequence of space and/or horizontal tab characters.

loop directive

An OpenMP executable directive whose associated user code must be a loopthat is a structured block.
COMMENTS:

27

For C/C++, only the for directive is a loop directive.

28
29

For Fortran, only the do directive and the optional end do directive
are loop directives.

30

Chapter 1

Introduction

3

structured directive

1
2

An OpenMP executable directive that is neither a standalone directive, a
simple directive nor a loop directive.

3
4

For C/C++, all structured directives have associated user code that is thefollowing structured block.

5
6
7
8

For Fortran, all structured directives are paired with an associated end
directive except section, whose end is marked either by the next section
or by the end sections. These structured directives bracket the associateduser code that forms a structured block.

9
10
11
12

construct

An OpenMP executable directive (and for Fortran, the paired end directive, ifany) and the associated statement, loop or structured block, if any, notincluding the code in any called routines, i.e., the lexical extent of an
executable directive.

13
14
15
16

regionAll code encountered during a specific instance of the execution of a given
construct or OpenMP library routine. A region includes any code in calledroutines as well as any implicit code introduced by the OpenMP
implementation.
COMMENTS:

17
18
19

A region may also be thought of as the dynamic or runtime extent of aconstruct or OpenMP library routine.

20
21

During the execution of an OpenMP program, a construct may giverise to many regions.
sequential part

22
23
24

All code encountered during the execution of an OpenMP program that is notenclosed by a parallel region corresponding to an explicit parallel
construct.
COMMENTS:

25
26
27

The sequential part executes as if it were enclosed by an inactive
parallel region called the implicit parallel region.

28
29
30

Executable statements in called routines may be in both the sequential
part and any number of explicit parallel regions at different points
in the program execution.

31

nested construct32
33

nested region

A region (dynamically) enclosed by another region, i.e., a region executed inits entirety during another region.
COMMENT: Some nestings are conforming and some are not. See Section 2.9
on page 87 for the rules specifying the conforming nestings.

34
35

36

A construct (lexically) enclosed by another construct.

4

OpenMP API • Version 2.5 May 2005

1
2

closely nested region

A region nested inside another region with no parallel region nested
between them.

3
4binding thread set

The set of threads that are affected by, or provide the context for, theexecution of a region.

5

The binding thread set for a given region can be one of the following:

6• all threads - all threads participating in the OpenMP program.

7
8• current team - all the threads in the team executing the innermost enclosing
parallel region.

910• encountering thread - the thread whose execution encountered theconstruct giving rise to the region.

11

COMMENTS:

12
13

•

The binding thread set for critical and atomic regions is all
threads.

14
15•

The binding thread set for parallel and flush regions is theencountering thread.

16
17

•

The binding thread set for all other regions arising from a construct
is the current team.

18
19
20

•

The binding thread set for the OpenMP library routines
omp_get_num_threads and omp_get_thread_num is thecurrent team.

21
22
23
24
25

•

The binding thread set for the OpenMP library routines
omp_set_num_threads, omp_get_max_threads,
omp_set_nested, omp_get_nested, omp_set_dynamic,
omp_get_dynamic, omp_get_wtime and omp_get_wtick
is the encountering thread.

26
27

•

The binding thread set for all other OpenMP library routines is all
threads.

28

Chapter 1

Introduction

5

binding region

12
3

For a region whose binding thread set is the current team, the enclosing region
that determines the execution context and limits the scope of the effects of thebound region.

4
5

Binding region is not defined for regions whose binding thread set is all
threads or the encountering thread.

6

COMMENTS:

7
8

The binding region for an ordered region is the innermost enclosing
loop region.

9
10
11
12
13

For all other regions with whose binding thread set is the current team,
the binding region is the innermost enclosing parallel region.
When such a region is encountered outside of any explicit parallel
region, the binding region is the implicit parallel region enclosing
the sequential part.

14

A parallel region need not be active to be a binding region.

15
16

A region never binds to any region outside of the innermost enclosing
parallel region.

17
18
19

orphaned construct

20
21
22

worksharing
construct

A construct that gives rise to a region whose binding thread set is the current
team, but that is not nested within another construct giving rise to the binding
region.
A construct that defines units of work, each of which is executed exactly onceby a thread in the team executing the construct.

23

For C, worksharing constructs are for, sections, and single.

24
25

For Fortran, worksharing constructs are do, sections, single andworkshare.
active parallel region

26

COMMENT: A missing if clause is equivalent to an if clause that evaluates
to true.

27
28

inactive parallel
region29
30
31

A parallel region that is not an active parallel region, i.e., a serialized
parallel region.
An inactive parallel region is always executed by a team of only one thread.

32

implicit parallel
region

33
34
35

36

A parallel region whose if clause evaluates to true.

6

The inactive parallel region that encloses the sequential part of an OpenMP
program.

OpenMP API • Version 2.5 May 2005

1

initial thread

The thread that executes the sequential part.

2

master thread

A thread that encounters (the start of) a parallel region and creates a team.

3
4

team

A set of one or more threads participating in the execution of a parallel
region.

5
6

For an active parallel region, the team comprises the master thread andadditional threads that may be launched.

7

For an inactive parallel region, the team only includes the master thread.
barrier

8
9
10

11
12
13

1.2.3

A point in the execution of a program encountered by a team, beyond which
no thread in the team may execute until all threads in the team have reachedthat point.

Data Terminology
variable

A named data object, whose value can be defined and redefined during theexecution of a program.
Only an object that is not part of another object is considered a variable. For
example, array elements, structure components, array sections and substrings
are not considered variables.

14
15
16
17
18

private variable

A variable whose name provides access to a different block of storage foreach thread in a team.

19
20

shared variable

A variable whose name provides access to the same block of storage for all
threads in a team.

21
22
23

global-lifetime
memory24
25
26

threadprivate
memory27

Memory locations that persist during the entire execution of the original
program, according to the base language specification.
Global-lifetime memory locations that are replicated, one per thread, by the
OpenMP implementation.

Chapter 1

Introduction

7

defined

1

For variables, the property of having a valid value.

2

For C:

3

For the contents of variables, the property of having a valid value.

4

For C++:

5
6

For the contents of variables of POD (plain old data) type, the property of
having a valid value.

78

For variables of non-POD class type, the property of having been constructed
but not subsequently destructed.

9For Fortran:

10
11
12

For the contents of variables, the property of having a valid value. For the
allocation or association status of variables, the property of having a valid
status.

13
14

COMMENT: Programs that rely upon variables that are not defined are nonconforming programs.

15

1.2.4

Implementation Terminology

16
17
18
19

supporting n levels ofparallelism

20

supporting OpenMP

Supporting at least one level of parallelism.

21
22

supporting nested
parallelism

Supporting more than one level of parallelism.

23
24

conforming program

25
26
27

compliant
implementation

An OpenMP program that follows all the rules and restrictions of the OpenMP
specification.
An implementation of the OpenMP specification that compiles and executes
any conforming program as defined by the specification.
COMMENT: A compliant implementation may exhibit unspecified behavior
when compiling or executing a non-conforming program.

28
29

30

Implies allowing an active parallel region to be enclosed by n-1 active
parallel regions, where the team associated with each active parallel region
has more than one thread.

8

OpenMP API • Version 2.5 May 2005

1
2

unspecified behavior

A behavior or result that is not specified by the OpenMP specification or not
known prior to the compilation or execution of an OpenMP program.

3

Such unspecified behavior may result from:4
5• Issues documented by the OpenMP specification as having unspecified
behavior.

6• A non-conforming program.

7• A conforming program exhibiting an implementation defined behavior.
implementation
defined

89
10
11

COMMENT: All such features are documented in Appendix E.

1213

Behavior that is allowed to vary among different compliant implementations,but must be documented by the implementation. An implementation isallowed to define this behavior as unspecified.

1.3

Execution Model

14
15
16
17
18
19
20
21
22
23
24
25
26

The OpenMP API uses the fork-join model of parallel execution. Although this fork-joinmodel can be useful for solving a variety of problems, it is somewhat tailored for large
array-based applications. OpenMP is intended to support programs that will executecorrectly both as parallel programs (multiple threads of execution and a full OpenMP
support library) and as sequential programs (directives ignored and a simple OpenMP
stubs library). However, it is possible and permitted to develop a program that executes
correctly as a parallel program but not as a sequential program, or that produces
different results when executed as a parallel program, compared to when it is executed
as a sequential program. Furthermore, using different numbers of threads may result indifferent numeric results because of changes in the association of numeric operations.
For example, a serial addition reduction may have a different pattern of addition
associations than a parallel reduction. These different associations may change theresults of floating-point addition.

27
28
29

An OpenMP program begins as a single thread of execution, called the initial thread.
The initial thread executes sequentially, as if enclosed in an implicit inactive parallel
region surrounding the whole program.

30
31
32
33
34
35

When any thread encounters a parallel construct, the thread creates a team of itself
and zero or more additional threads and becomes the master of the new team. All
members of the new team execute the code inside the parallel construct. There is an
implicit barrier at the end of the parallel construct. Only the master thread continues
execution of user code beyond the end of the parallel construct. Any number ofparallel constructs can be specified in a single program.

36

Chapter 1

Introduction

9

1
2
3
4
5

parallel regions may be arbitrarily nested inside each other. If nested parallelism isdisabled, or is not supported by the OpenMP implementation, then the new team that iscreated by a thread encountering a parallel construct inside a parallel region
will consist only of the encountering thread. However, if nested parallelism is supported
and enabled, then the new team can consist of more than one thread.

6
7
8
9
10

When any team encounters a work-sharing construct, the work inside the construct isdivided among the members of the team and executed co-operatively instead of being
executed by every thread. There is an optional barrier at the end of work-sharing
constructs. Execution of code by every thread in the team resumes after the end of thework-sharing construct.

11
12
13
14

Synchronization constructs and library routines are available in OpenMP to co-ordinate
threads and data in parallel and work-sharing constructs. In addition, libraryroutines and environment variables are available to control or query the runtime
environment of OpenMP programs.

15
16
17
18
19

OpenMP makes no guarantee that input or output to the same file is synchronous when
executed in parallel. In this case, the programmer is responsible for synchronizing input
and output statements (or routines) using the provided synchronization constructs orlibrary routines. For the case where each thread accesses a different file, no
synchronization by the programmer is necessary.

20

1.4

Memory Model

21

1.4.1

Structure of the OpenMP Memory Model

22
23
24
25
26
27
28
29
30

OpenMP provides a relaxed-consistency, shared-memory model. All OpenMP threads
have access to a place to store and retrieve variables, called the memory. In addition,
each thread is allowed to have its own temporary view of the memory. The temporary
view of memory for each thread is not a required part of the OpenMP memory model,
but can represent any kind of intervening structure, such as machine registers, cache, orother local storage, between the thread and the memory. The temporary view of memory
allows the thread to cache variables and thereby avoid going to memory for every
reference to a variable. Each thread also has access to another type of memory that mustnot be accessed by other threads, called threadprivate memory.

31
32
33

A parallel directive determines two kinds of access to variables used in theassociated structured block: shared and private. Each variable referenced in the
structured block has an original variable, which is the variable by the same name that

34

10

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7

exists in the program immediately outside the parallel construct. Each reference to ashared variable in the structured block becomes a reference to the original variable. For
each private variable referenced in the structured block, a new version of the originalvariable (of the same type and size) is created in memory for each thread of the teamformed to execute the parallel region associated with the parallel directive,
except possibly for the master thread of the team. References to a private variable in the
structured block refer to the current thread’s private version of the original variable.

8
9
10
11

If multiple threads write to the same shared variable without synchronization, theresulting value of the variable in memory is unspecified. If at least one thread reads froma shared variable and at least one thread writes to it without synchronization, the value
seen by any reading thread is unspecified.

12
13
14

It is implementation defined as to whether, and in what sizes, memory accesses bymultiple threads to the same variable without synchronization are atomic with respect toeach other.

15
16
17
18
19
20

A private variable in an outer parallel region belonging to, or accessible from, athread that eventually becomes the master thread of an inner nested parallel region,is permitted to be accessed by any of the threads of the team executing the innerparallel region, unless the variable is also private with respect to the innerparallel region. Any other access by one thread to the private variables of anotherthread results in unspecified behavior.

21

1.4.2

The Flush Operation

22
23
24
25
26
27

The memory model has relaxed-consistency because a thread’s temporary view ofmemory is not required to be consistent with memory at all times. A value written to avariable can remain in the thread’s temporary view until it is forced to memory at a latertime. Likewise, a read from a variable may retrieve the value from the thread’s
temporary view, unless it is forced to read from memory. The OpenMP flush operation
enforces consistency between the temporary view and memory.

28
29
30
31
32

The flush operation is applied to a set of variables called the flush-set. The flush
operation restricts reordering of memory operations that an implementation mightotherwise do. Implementations must not reorder the code for a memory operation for agiven variable, or the code for a flush operation for the variable, with respect to a flush
operation that refers to the same variable.

33
34
35
36
37
38

If a thread has captured the value of a write in its temporary view of a variable since its
last flush of that variable, then when it executes another flush of the variable, the flush
does not complete until the value of the variable has been written to the variable inmemory. A flush of a variable executed by a thread also causes its temporary view of thevariable to be discarded, so that if its next memory operation for that variable is a read,then the thread will read from memory and may capture the value in the temporary view.

39

Chapter 1

Introduction

11

1
2
3
4
5

When a thread executes a flush, no later memory operation by that thread for a variable
involved in that flush is allowed to start until the flush completes. The completion of aflush of a set of variables executed by a thread is defined as the point at which all writes
to those variables done by that thread are visible in memory to all other threads and thetemporary view, for that thread, of all variables involved, is discarded.

6
7
8
9
10
11

The flush operation provides a guarantee of consistency between a thread’s temporary
view and memory. Therefore, the flush operation can be used to guarantee that a value
written to a variable by one thread may be read by a second thread. To accomplish this,the programmer must ensure that the second thread has not written to the variable since
its last flush of the variable, and that the following sequence of events happens in thespecified order:

12

1. The value is written to the variable by the first thread.

13

2. The variable is flushed by the first thread.

14

3. The variable is flushed by the second thread.

15

4. The value is read from the variable by the second thread.

16
17
18
19
20
21

The volatile keyword in the C and C++ languages specifies a consistency
mechanism that is related to the OpenMP memory consistency mechanism in thefollowing way: a reference that reads the value of an object with a volatile-qualified type
behaves as if there were a flush operation on that object at the previous sequence point,
while a reference that modifies the value of an object with a volatile-qualified type
behaves as if there were a flush operation on that object at the next sequence point.

22

1.4.3

OpenMP Memory Consistency

23
24
25

The type of relaxed memory consistency provided by OpenMP is similar to weakordering1. OpenMP does not apply restrictions to the reordering of memory operations
executed by a single thread except for those related to a flush operation.

26
27

The restrictions in Section 1.4.2 on page 11 on reordering with respect to flush
operations guarantee the following:

28
29
30

• If the intersection of the flush-sets of two flushes performed by two different threads

31

1. Weak ordering is described in S. V. Adve and K. Gharachorloo, “Shared Memory Consistency Models: A Tutorial”, IEEE
Computer, 29(12), pp.66-76, December 1996. Weak ordering requires that some memory operations be defined assynchronization operations and that these be ordered with respect to each other. In the context of OpenMP, two flushes ofthe same variable are synchronization operations. The OpenMP memory model is slightly weaker than weak ordering,
however, because flushes whose flush-sets have an empty intersection are not ordered with respect to each other.

is non-empty, then the two flushes must be completed as if in some sequential order,
seen by all threads.

32
33

34

12

OpenMP API • Version 2.5 May 2005

1
2
3

• If the intersection of the flush-sets of two flushes performed by one thread is non-

4
5

• If the intersection of the flush-sets of two flushes is empty, the threads can observe

6
7
8

The flush operation can be specified using the flush directive, and is also implied atvarious locations in an OpenMP program: see Section 2.7.5 on page 58 for details. For
an example illustrating the memory model, see Section A.2 on page 120.

9empty, then the two flushes must appear to be completed in that thread’s program
order.
these flushes in any order.

1.5

OpenMP Compliance

10
11
12
13
14

An implementation of the OpenMP API is compliant if and only if it compiles andexecutes all conforming programs according to the syntax and semantics laid out in
Chapters 1, 2, 3 and 4. Appendices A, B, C, D, E and F and sections designated as Notes(see Section 1.7 on page 14) are for information purposes only and are not part of thespecification.

15
16
17
18
19
20

The OpenMP API defines constructs that operate in the context of the base language thatis supported by an implementation. If the base language does not support a language
construct that appears in this document, a compliant OpenMP implementation is not
required to support it, with the exception that for Fortran, the implementation must allow
case insensitivity for directive and API routines names, and must allow identifiers ofmore than six characters.

21
22
23
24
25
26

All library, intrinsic and built-in routines provided by the base language must be threadsafe in a compliant implementation. In addition, the implementation of the baselanguage must also be thread-safe (e.g., ALLOCATE and DEALLOCATE statements must
be thread-safe in Fortran). Unsynchronized concurrent use of such routines by different
threads must produce correct results (though not necessarily the same as serial execution
results, as in the case of random number generation routines).

27
28
29
30

In both Fortran 90 and Fortran 95, variables with explicit initialization have the SAVE
attribute implicitly. This is not the case in Fortran 77. However, a compliant OpenMP
Fortran implementation must give such a variable the SAVE attribute, regardless of theunderlying base language version.

31
32
33

Appendix E lists certain aspects of the OpenMP API that are implementation-defined. A
compliant implementation is required to define and document its behavior for each of
the items in Appendix E.

34

Chapter 1

Introduction

13

1

1.6

Normative References

2• ISO/IEC 9899:1990, Information Technology - Programming Languages - C.

3

This OpenMP API specification refers to ISO/IEC 9899:1990 as C90.

4• ISO/IEC 9899:1999, Information Technology - Programming Languages - C.

5

This OpenMP API specification refers to ISO/IEC 9899:1999 as C99.

6

• ISO/IEC 14882:1998, Information Technology - Programming Languages - C++.

7

This OpenMP API specification refers to ISO/IEC 14882:1998 as C++.

8

• ISO/IEC 1539:1980, Information Technology - Programming Languages - Fortran.

9

This OpenMP API specification refers to ISO/IEC 1539:1980 as Fortran 77.

10• ISO/IEC 1539:1991, Information Technology - Programming Languages - Fortran.

11

This OpenMP API specification refers to ISO/IEC 1539:1991 as Fortran 90.

12• ISO/IEC 1539-1:1997, Information Technology - Programming Languages - Fortran.

13

This OpenMP API specification refers to ISO/IEC 1539-1:1997 as Fortran 95.

1415

Where this OpenMP API specification refers to C, C++ or Fortran, reference is made to
the base language supported by the implementation.

16

1.7

Organization of this document

17

The remainder of this document is structured as follows:18• Chapter 2: Directives

19• Chapter 3: Runtime Library Routines

20

14

OpenMP API • Version 2.5 May 2005

1

• Chapter 4: Environment Variables

2• Appendix A: Examples

3• Appendix B: Stubs for Runtime Library Routines

4• Appendix C: OpenMP C and C++ Grammar

5• Appendix D: Interface Declarations

6• Appendix E: Implementation Defined Behaviors in OpenMP

7• Appendix F: Changes from Version 2.0 to Version 2.58910Some sections of this document only apply to programs written in a certain baselanguage. Text that applies only to programs whose base language is C or C++ is shownas follows:

11
12

C/C++ specific text....

C/C++

13

C/C++

14

Text that applies only to programs whose base language is Fortran is shown as follows:

15

Fortran16

Fortran specific text......

17

Fortran18
19
20

Where an entire page consists of, for example, Fortran specific text, a marker is shownat the top of the page like this:21
22

Some text is for information only, and is not part of the normative specification. Suchtext is designated as a note, like this:23

Note – Non-normative text....

24

Fortran (cont.)

Chapter 1

Introduction

15

1

16

OpenMP API • Version 2.5 May 2005

1

CHAPTER2

2

Directives

3
4This chapter describes the syntax and behavior of OpenMP directives, and is divided
into the following sections:5• The language-specific directive format (Section 2.1 on page 18)

6• Mechanisms to control conditional compilation (Section 2.2 on page 21)

7• Control of OpenMP API internal control variables (Section 2.3 on page 24)8• Details of each OpenMP directive (Section 2.4 on page 26 to Section 2.9 on page 87)

9
10
11

In C/C++, OpenMP directives are specified by using the #pragma mechanism provided
by the C and C++ standards.

12

C/C++

13

Fortran

14
15
16

In Fortran, OpenMP directives are specified by using special comments that are
identified by unique sentinels. Also, a special comment form is available for conditional
compilation.

17

Fortran

18
19
20
21
22
23

Compilers can therefore ignore OpenMP directives and conditionally compiled code if
support of OpenMP is not provided or enabled. A compliant implementation must
provide an option or interface that ensures that underlying support of all OpenMP
directives and OpenMP conditional compilation mechanisms is enabled. In theremainder of this document, the phrase OpenMP compilation is used to mean acompilation with these OpenMP features enabled.

24

Fortran

C/C++

25

Restrictions

26

The following restriction applies to all OpenMP directives:27

17• OpenMP directives may not appear in PURE or ELEMENTAL procedures.

1

Fortran2

3

2.1

Directive Format
C/C++

4
5
6
7

OpenMP directives for C/C++ are specified with the pragma preprocessing directive.
The syntax of an OpenMP directive is formally specified by the grammar in
Appendix C, and informally as follows:#pragma omp directive-name [clause[ [,] clause]...] new-line

8
9
10
11
12
13

Each directive starts with #pragma omp. The remainder of the directive follows theconventions of the C and C++ standards for compiler directives. In particular, whitespace can be used before and after the #, and sometimes white space must be used toseparate the words in a directive. Preprocessing tokens following the #pragma omp
are subject to macro replacement.

14

Directives are case-sensitive.

15
16

An OpenMP directive applies to at most one succeeding statement, which must be a
structured block.

17

C/C++

18

Fortran
OpenMP directives for Fortran are specified as follows:

19

sentinel directive-name [clause[[,] clause]...]

20
21
22
23

All OpenMP compiler directives must begin with a directive sentinel. The format of asentinel differs between fixed and free-form source files, as described in Section 2.1.1 on
page 19 and Section 2.1.2 on page 20.

24
25

Directives are case-insensitive. Directives cannot be embedded within continued
statements, and statements cannot be embedded within directives.

26
27

In order to simplify the presentation, free form is used for the syntax of OpenMP
directives for Fortran in the remainder of this document, except as noted.

Fortran

28

29

18

OpenMP API • Version 2.5 May 2005

1
2
3
4

Only one directive-name can be specified per directive (note that this includes combined
directives, see Section 2.6 on page 46). The order in which clauses appear on directives
is not significant. Clauses on directives may be repeated as needed, subject to therestrictions listed in the description of each clause.

5
6
7
8

Some data-sharing attribute clauses (Section 2.8.3 on page 70), data copying clauses(Section 2.8.4 on page 83), the threadprivate directive (Section 2.8.2 on page 66),
and the flush directive (Section 2.7.5 on page 58) accept a list. A list consists of acomma-separated collection of one or more list items.

9
10
11

A list item is a variable name, subject to the restrictions specified in each of the sections
describing clauses and directives for which a list appears.

12

C/C++

13

Fortran

14
15
16

A list item is a variable name or common block name (enclosed in slashes), subject tothe restrictions specified in each of the sections describing clauses and directives forwhich a list appears.

17

Fortran18

Fortran

19
20

21

C/C++

2.1.1

Fixed Source Form Directives
The following sentinels are recognized in fixed form source files:!$omp | c$omp | *$omp

22
23
24
25
26

Sentinels must start in column 1 and appear as a single word with no intervening
characters. Fortran fixed form line length, white space, continuation, and column rules
apply to the directive line. Initial directive lines must have a space or zero in column 6,
and continuation directive lines must have a character other than a space or a zero incolumn 6.

27
28
29
30

Comments may appear on the same line as a directive. The exclamation point initiates acomment when it appears after column 6. The comment extends to the end of the sourceline and is ignored. If the first non-blank character after the directive sentinel of an
initial or continuation directive line is an exclamation point, the line is ignored.

31
32

Note – in the following example, the three formats for specifying the directive are
equivalent (the first line represents the position of the first 9 columns):

33

Chapter 2

Directives

19

Fortran (cont.)

12c23456789

3!$omp parallel do shared(a,b,c)4

c$omp parallel do

5

c$omp+shared(a,b,c)6

c$omp paralleldoshared(a,b,c)

7

2.1.2

Free Source Form Directives
The following sentinel is recognized in free form source files:

8

!$omp

9
10
11
12
13
14
15
16
17

The sentinel can appear in any column as long as it is preceded only by white space(spaces and tab characters). It must appear as a single word with no intervening
character. Fortran free form line length, white space, and continuation rules apply to thedirective line. Initial directive lines must have a space after the sentinel. Continued
directive lines must have an ampersand as the last nonblank character on the line, prior
to any comment placed inside the directive. Continuation directive lines can have anampersand after the directive sentinel with optional white space before and after theampersand.

18
19
20
21

Comments may appear on the same line as a directive. The exclamation point initiates acomment. The comment extends to the end of the source line and is ignored. If the firstnonblank character after the directive sentinel is an exclamation point, the line is
ignored.

22
23
24

One or more blanks or horizontal tabs must be used to separate adjacent keywords indirectives in free source form, except in the following cases, where white space is
optional between the given pair of keywords:

25

end critical26

end do27

end master

28

20

OpenMP API • Version 2.5 May 2005

1

end ordered2

end parallel3

end sections

4

end single

5

end workshare

6

parallel do7parallel sections

8

parallel workshare

910

Note – in the following example the three formats for specifying the directive are
equivalent (the first line represents the position of the first 9 columns):

11!23456789!$omp parallel do &12!$omp shared(a,b,c)

13!$omp parallel &14!$omp&do shared(a,b,c)

15!$omp paralleldo shared(a,b,c)

16

Fortran

17

18

2.2

Conditional Compilation

19
20
21

In implementations that support a preprocessor, the _OPENMP macro name is defined tohave the decimal value yyyymm where yyyy and mm are the year and month designationsof the version of the OpenMP API that the implementation supports.

22
23

If this macro is the subject of a #define or a #undef preprocessing directive, thebehavior is unspecified.

24

For examples of conditional compilation, see Section A.3 on page 122.

25

Chapter 2

Directives

21

1

Fortran

2
3

The OpenMP API requires Fortran lines to be compiled conditionally, as described in
the following sections.

5

Fixed Source Form Conditional Compilation
Sentinels

6
7

The following conditional compilation sentinels are recognized in fixed form source
files:

4

2.2.1!$ | *$ | c$8910

To enable conditional compilation, a line with a conditional compilation sentinel mustsatisfy the following criteria:

1112• The sentinel must start in column 1 and appear as a single word with no intervening

13
14• After the sentinel is replaced with two spaces, initial lines must have a space or zero

15
16
17

• After the sentinel is replaced with two spaces, continuation lines must have a18
19

If these criteria are met, the sentinel is replaced by two spaces. If these criteria are notmet, the line is left unchanged.

20
21
22

Note – in the following example, the two forms for specifying conditional compilationin fixed source form are equivalent (the first line represents the position of the first 9
columns):

23

c23456789

24!$ 10 iam = omp_get_thread_num() +

25

!$

26

#ifdef _OPENMP

white space.
in column 6 and only white space and numbers in columns 1 through 5.
character other than a space or zero in column 6 and only white space in columns 1
through 5.

index

10 iam = omp_get_thread_num() +

27

&

28

29

&

22

index

OpenMP API • Version 2.5 May 2005

#endif

1

3

Free Source Form Conditional Compilation
Sentinel

4

The following conditional compilation sentinel is recognized in free form source files:

2

5

2.2.2

!$

6
7

To enable conditional compilation, a line with a conditional compilation sentinel mustsatisfy the following criteria:

8• The sentinel can appear in any column but must be preceded only by white space.

9• The sentinel must appear as a single word with no intervening white space.

10• Initial lines must have a space after the sentinel.

11
12
13
14

• Continued lines must have an ampersand as the last nonblank character on the line,

15
16

If these criteria are met, the sentinel is replaced by two spaces. If these criteria are notmet, the line is left unchanged.

17
18
19

Note – in the following example, the two forms for specifying conditional compilationin free source form are equivalent (the first line represents the position of the first 9
columns):

20

c23456789

prior to any comment appearing on the conditionally compiled line. (Continued lines
can have an ampersand after the sentinel, with optional white space before and after
the ampersand.)21!$ iam = omp_get_thread_num() +

22

!$&

23
24

index

#ifdef _OPENMP
iam = omp_get_thread_num() +

27

28

&

index

25
26

&

#endif

Fortran
Chapter 2

Directives

23

1

2.3

Internal Control Variables

2
3
4
5
6
7
8
9

An OpenMP implementation must act as if there were internal control variables that
store the information for determining the number of threads to use for a parallel
region and how to schedule a work-sharing loop. The control variables are given values
at various times (described below) during execution of an OpenMP program. They are
initialized by the implementation itself and may be given values by using OpenMP
environment variables, and by calls to OpenMP API routines. The only way for the
program to retrieve the values of these control variables is by calling OpenMP API
routines.

10
11
12

For purposes of exposition, this document refers to the control variables by certain
names (below), but an implementation is not required to use these names or to offer any
way to access the variables other than through the ways shown in Table 2.1.

13
14

The following control variables store values that affect the operation of parallel
regions:15• nthreads-var - stores the number of threads requested for future parallel regions.

1617• dyn-var - controls whether dynamic adjustment of the number of threads to be used18
19

• nest-var - controls whether nested parallelism is enabled for future parallel

20

The following control variables store values that affect the operation of loop regions:21
22• run-sched-var - stores scheduling information to be used for loop regions using the23
24• def-sched-var - stores implementation defined default scheduling information for loop

25
26

Table 2-1 shows the methods for modifying and retrieving the values of each control
variable, as well as their initial values.

27

TABLE 2-1

28

Control variable

Ways to modify value

Way to retrieve value

Initial value

29

nthreads-var

OMP_NUM_THREADS
omp_set_num_threads()

omp_get_max_threads()

Implementation defined30

dyn-var

OMP_DYNAMIC
omp_set_dynamic()

omp_get_dynamic()

Implementation defined31

nest-var

OMP_NESTED
omp_set_nested()

omp_get_nested()

false

32

run-sched-var

OMP_SCHEDULE(none)

Implementation defined33

def-sched-var(none)(none)

Implementation defined34

for future parallel regions is enabled.
regions.

runtime schedule clause.
regions.

24

Control variables

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7
8

The effect of the API routines in Table 2-1 on the internal control variables described inthis specification applies only during the execution of the sequential part of the program.
During execution of the sequential part, only one copy of each internal control variable
may exist. The effect of these API routines on the internal control variables is
implementation defined when the API routines are executed from within any explicit
parallel region. Additionally, the number of copies of the internal control variables,
and their effects, during the execution of any explicit parallel region are implementation
defined.

9
10
11
12
13
14
15
16
17
18

The internal control variables are each given values before any OpenMP construct or
OpenMP API routine executes. The initial values of nthreads-var, dyn-var, run-schedvar, and def-sched-var are implementation defined. The initial value of nest-var is false.
After the initial values are assigned, but also before any OpenMP construct or OpenMP
API routine executes, the values of any OpenMP environment variables that were set by
the user are read and the associated control variables are modified accordingly. After thispoint, no changes to any OpenMP environment variables will be reflected in the control
variables. During execution of the user’s code, certain control variables can be further
modified by certain OpenMP API routine calls. An OpenMP construct clause does not
modify the value of any of these control variables.

19
20

Table 2-2 shows the override relationships between various construct clauses, OpenMP
API routines, environment variables, and initial values.

21

TABLE 2-2

22

construct clause,
if used...overrides previous call to
OpenMP API routine...overrides environment
variable, if set

num_threads clause

omp_set_num_threads()

OMP_NUM_THREADS

initial value ofnthreads-var

25(none)

omp_set_dynamic()

OMP_DYNAMIC

initial value of dyn-var

26(none)

omp_set_nested()

OMP_NESTED

initial value of nest-var

27
28(none)(none)OMP_SCHEDULE

initial value of
run-sched-var

23
24

Override relationships(only used whenschedule kind isruntime)29...overrides initial value

30
31

schedule clause

32

Cross References:

33• parallel construct, see Section 2.4 on page 26.

34• Loop construct, see Section 2.5.1 on page 33.

35• omp_set_num_threads routine, see Section 3.2.1 on page 91.

36• omp_set_dynamic routine, see Section 3.2.7 on page 97.

37(none)

initial value of
def-sched-var(none)

Chapter 2

Directives

25

1• omp_set_nested routine, see Section 3.2.9 on page 100.

2

• omp_get_max_threads routine, see Section 3.2.3 on page 94.

3• omp_get_dynamic routine, see Section 3.2.8 on page 99.

4• omp_get_nested routine, see Section 3.2.10 on page 101.

5

• OMP_NUM_THREADS environment variable, see Section 4.2 on page 115.

6

• OMP_DYNAMIC environment variable, see Section 4.3 on page 116.

7

• OMP_NESTED environment variable, see Section 4.4 on page 116.

8

• OMP_SCHEDULE environment variable, see Section 4.1 on page 114.

9

2.4

parallel Construct10

Summary

11
12This is the fundamental construct that starts parallel execution. See Section 1.3 on page
9 for a general description of the OpenMP execution model.

13

Syntax

14
15

The syntax of the parallel construct is as follows:

C/C++#pragma omp parallel [clause[ [, ]clause] ...] new-line
structured-block16
17

where clause is one of the following:18

19

if(scalar-expression)

20

private(list)

21

firstprivate(list)

22

default(shared | none)

23

shared(list)

24

copyin(list)

25

26

OpenMP API • Version 2.5 May 2005

1

reduction(operator: list)

2

num_threads(integer-expression)

3

C/C++

4

Fortran

5

6
7
8
9

The syntax of the parallel construct is as follows:!$omp parallel [clause[[,] clause]...]
structured-block!$omp end parallel
where clause is one of the following:10

if(scalar-logical-expression)11

private(list)

12

firstprivate(list)

13

default(private | shared | none)

14

shared(list)

15

copyin(list)

16

reduction({operator|intrinsic_procedure_name}:list)

17

num_threads(scalar-integer-expression)

18

The end parallel directive denotes the end of the parallel construct.

Fortran

19

20

Binding

21
22

The binding thread set for a parallel region is the encountering thread. The
encountering thread becomes the master thread of the new team.

23

Description

24
25
26
27

When a thread encounters a parallel construct, a team of threads is created to
execute the parallel region (see Section 2.4.1 on page 29 for more information about
how the number of threads in the team is determined, including the evaluation of the if
and num_threads clauses). The thread which encountered the parallel construct

28

Chapter 2

Directives

27

1
2
3
4

becomes the master thread of the new team, with a thread number of zero for theduration of the parallel region. All threads in the new team, including the masterthread, execute the region. Once the team is created, the number of threads in the teamremains constant for the duration of that parallel region.

5
6
7
8

Within a parallel region, thread numbers uniquely identify each thread. Thread
numbers are consecutive whole numbers ranging from zero for the master thread up to
one less than the number of threads within the team. A thread may obtain its own thread
number by a call to the omp_get_thread_num library routine.

910

The structured block of the parallel construct is executed by each thread, althougheach thread can execute a path of statements that is different from the other threads.

11
12

There is an implied barrier at the end of a parallel region. Only the master thread of
the team continues execution after the end of a parallel region.

13
14
15

If a thread in a team executing a parallel region encounters another parallel
directive, it creates a new team, according to the rules in Section 2.4.1 on page 29, andit becomes the master of that new team.

16
17
18
19
20

If execution of a thread terminates while inside a parallel region, execution of all
threads in all teams terminates. The order of termination of threads is unspecified. All
the work done by a team prior to any barrier which the team has passed in the programis guaranteed to be complete. The amount of work done by each thread after the last
barrier that it passed and before it terminates is unspecified.

21
22

For an example of the parallel construct, see Section A.4 on page 123. For an
example of the num_threads clause, see Section A.5 on page 125.

23

Restrictions

24

Restrictions to the parallel construct are as follows:25• A program which branches into or out of a parallel region is non-conforming.

26
27• A program must not depend on any ordering of the evaluations of the clauses of the28• At most one if clause can appear on the directive.

29
30• At most one num_threads clause can appear on the directive. The num_threads

parallel directive, or on any side effects of the evaluations of the clauses.

expression must evaluate to a positive integer value.

C/C++

31
32
33
34

• A throw executed inside a parallel region must cause execution to resume

within the same parallel region, and it must be caught by the same thread thatthrew the exception.

C/C++

35

36

28

OpenMP API • Version 2.5 May 2005

1

Fortran2
3• Unsynchronized use of Fortran I/O statements by multiple threads on the same unit

4

Fortranhas unspecified behavior.

5

Cross References

6
7• default, shared, private, firstprivate, and reduction clauses, see

8• copyin clause, see Section 2.8.4 on page 83.

9• omp_get_thread_num routine, see Section 3.2.4 on page 95.

Section 2.8.3 on page 70.

11

Determining the Number of Threads for aparallel Region

12
13
14
15
16
17
18
19
20

When execution encounters a parallel directive, the value of the if clause or
num_threads clause (if any) on the directive, the current parallel context, the numberof levels of parallelism supported, and the values of the nthreads-var, dyn-var and nestvar internal control variables are used to determine the number of threads to use in theregion. Figure 2-1 describes how the number of threads is determined. The if clause
expression and the num_threads clause expression are evaluated in the context
outside of the parallel construct, and no ordering of those evaluations is specified. It
is also unspecified whether, in what order, or how many times any side-effects of theevaluation of the num_threads or if clause expressions occur.

21
22
23

When a thread executing inside an active parallel region encounters a parallel
construct, the new team which is created will consist of only the encountering thread,when any of the following conditions hold:24• nested parallelism is disabled,

25• the if clause expression evaluates to false, or26• no further levels of parallelism are supported by the OpenMP implementation.

27
28

However, if nested parallelism is enabled and additional levels of parallelism aresupported, then the new team can consist of more than one thread.

29
30
31

The number of levels of parallelism supported is implementation defined. If only one
level of parallelism is supported (i.e. nested parallelism is not supported) then the valueof the nest-var internal control variable is always false.

32
33
34

If dynamic adjustment of the number of threads is enabled, the number of threads thatare used for executing subsequent parallel regions may be adjusted automatically by
the implementation. Once the number of threads is determined, it remains fixed for the

10

35

2.4.1

Chapter 2

Directives

29

1
2
3

duration of that parallel region. If dynamic adjustment of the number of threads is
disabled, the number of threads that are used for executing subsequent parallel
regions may not be adjusted by the implementation.

4
5
6

It is implementation defined whether the ability to dynamically adjust the number of
threads is provided. If this ability is not provided, then the value of the dyn-var internal
control variable is always false.

7
8
9
10

Implementations may deliver fewer threads than indicated in Figure 2-1, in exceptionalsituations, such as when there is a lack of resources, even if dynamic adjustment isdisabled. In these exceptional situations the behavior of the program is implementation
defined: this may, for example, include interrupting program execution.

11
12
13

Note – Since the initial value of the dyn-var internal control variable is implementation
defined, programs that depend on a specific number of threads for correct execution
should explicitly disable dynamic adjustment of the number of threads.

1430

OpenMP API • Version 2.5 May 2005

1

2
3

START

Yes

if clause
present?

4

All enclosing
parallel regions
inactive?

Nonest-var
value

false
Use 1 thread

true
Yes

11
12

14

Use 1 thread

true

9
10

13

false

No

5

6
7
8

if clause
value

Yes

dyn-varvalue

15

Another level ofparallelism supported?

false

No
num_threads
clause present?

YesNo
num_threads
clause present?

21

Yes

22
23

26

Use nthreads-var
threads

true

18
19
20

24
25

Use 1 thread

Use num_threads
value threads

16
17

No

FIGURE 2-1

Use between 1 andnthreads-var threads,
inclusive

Use between 1 andnum_threads value
threads, inclusive

Determining the number of threads for a parallel region. Note that no ordering ofevaluation of the if and num_threads clauses is implied.

Chapter 2

Directives

31

1

2.5

Work-sharing Constructs

2
3
4
5
6

A work-sharing construct distributes the execution of the associated region among themembers of the team that encounters it. A work-sharing region must bind to an active
parallel region in order for the work-sharing region to execute in parallel. If
execution encounters a work-sharing region in the sequential part, it is executed by the
initial thread.

7
8
9
10
11
12
13
14

A work-sharing construct does not launch new threads, and a work-sharing region has
no barrier on entry. However, an implied barrier exists at the end of the work-sharing
region, unless a nowait clause is specified. If a nowait clause is present, an
implementation may omit code to synchronize the threads at the end of the work-sharing
region. In this case, threads that finish early may proceed straight to the instructions
following the work-sharing region without waiting for the other members of the team tofinish the work-sharing region, and without performing a flush operation (seeSection A.8 on page 128 for an example.)

15
16

OpenMP defines the following work-sharing constructs, and these are described in thesections that follow:

17• loop construct18• sections construct19• single construct

Fortran20• workshare construct

21

Fortran

22

23

Restrictions

24

The following restrictions apply to work-sharing constructs:

25
26• Each work-sharing region must be encountered by all threads in a team or by none at

27
28• The sequence of work-sharing regions and barrier regions encountered must be

29

all.
the same for every thread in a team.

32

OpenMP API • Version 2.5 May 2005

1

2.5.1

Loop Construct2

Summary3
4
5

The loop construct specifies that the iterations of the associated loop will be executed inparallel. The iterations of the loop are distributed across threads that already exist in theteam executing the parallel region to which the loop region binds.

6

Syntax

7
8

The syntax of the loop construct is as follows:

9
10
11

C/C++

#pragma omp for [clause[[,] clause] ... ] new-line
for-loop
The clause is one of the following:

12

private(list)

13

firstprivate(list)

14

lastprivate(list)

15

reduction(operator: list)

16

ordered17

schedule(kind[, chunk_size])18

nowait19

Chapter 2

Directives

33

1
2

The for directive places restrictions on the structure of the corresponding for-loop.
Specifically, the corresponding for-loop must have the following canonical form:3

for (init-expr; var relational-op b; incr-expr) statement

4
5
6

init-expr

One of the following:var = lb
integer-type var = lb

7
8
9
10
11
12
13
14
15
16

incr-expr

One of the following:
++var
var++
--var
var-var += incrvar -= incr
var = var + incr
var = incr + var
var = var - incr

17
18
19
20
21
22
23

var

A signed integer variable, of type integer-type, as defined in thebase language. If this variable would otherwise be shared, it is
implicitly made private on the loop construct. This variablemust not be modified during the execution of the for-loop otherthan in incr-expr. Unless the variable is specified
lastprivate on the loop construct, its value after the loop is
undefined.

24
25
26
27
28

relational-op

One of the following:
<
<=
>
>=

29
30
31
32

lb, b, and incr

Loop invariant integer expressions. There is no impliedsynchronization during the evaluation of these expressions. It is
unspecified whether, in what order, or how many times any side
effects within the lb, b, or incr expressions occur.

33

statement

Defined according to the base language.

34
35
36
37
38

Note that the canonical form allows the number of loop iterations to be computed onentry to the loop. This computation is performed with values in the type of var, after
integral promotions. In particular, if the value of b - lb + incr, or any intermediate result
required to compute this value, cannot be represented in that type, the behavior isunspecified.

39

C/C++

40

34

OpenMP API • Version 2.5 May 2005

1

Fortran2

The syntax of the loop construct is as follows:

3
4
5
6

!$omp do [clause[[,] clause] ... ]do-loop[!$omp end do [nowait] ]The clause is one of the following:

7

private(list)

8

firstprivate(list)

9

lastprivate(list)

10

reduction({operator|intrinsic_procedure_name}:list)

11

ordered12

schedule(kind[, chunk_size])13
14

If an end do directive is not specified, an end do directive is assumed at the end of the
do-loop.

15
16
17
18

The do-loop must be a do-construct as defined in Section 8.1.4.1 of the Fortran 95
standard. If an end do directive follows a do-construct in which several DO statements
share a DO termination statement, then a do directive can only be specified for the first(i.e. outermost) of these DO statements. See Section A.6 on page 125 for examples.

19
20
21

If the loop iteration variable would otherwise be shared, it is implicitly made private on
the loop construct. See Section A.7 on page 127 for examples. Unless the variable is
specified lastprivate on the loop construct, its value after the loop is undefined.

22

Fortran23

Binding

24
25
26
27

The binding thread set for a loop region is the current team. A loop region binds to theinnermost enclosing parallel region. Only the threads of the team executing thebinding parallel region participate in the execution of the loop iterations and(optional) implicit barrier of the loop region.

28

Description

29
30

There is an implicit barrier at the end of a loop construct unless a nowait clause isspecified.

31

Chapter 2

Directives

35

1
2
3
4
5
6
7

The schedule clause specifies how iterations of the loop are divided into contiguous
non-empty subsets, called chunks, and how these chunks are assigned among threads ofthe team. Programs which depend on which thread executes a particular iteration are
non-conforming. The chunk_size expression is evaluated using the original list items ofany variables that are made private for the duration of the loop construct. It is
unspecified whether, in what order, or how many times, any side-effects of theevaluation of this expression occur.

8
9

See Section 2.5.1.1 on page 38 for details of how the schedule for a work-sharing loop
is determined.

10

The schedule kind can be one of those specified in Table 2-3.

11

TABLE 2-3

12
13
14
15
16

staticschedule clause kind values
When schedule(static, chunk_size) is specified, iterations are divided
into chunks of size chunk_size, and the chunks are statically assigned tothreads in the team in a round-robin fashion in the order of the thread number.
Note that the last chunk to be assigned may have a smaller number of
iterations.
When no chunk_size is specified, the iteration space is divided into chunks
which are approximately equal in size, and each thread is assigned at most one
chunk.

17
18
19
20
21
22
23

dynamic

When schedule(dynamic, chunk_size) is specified, the iterations are
assigned to threads in chunks as the threads request them. The thread executes
the chunk of iterations, then requests another chunk, until no chunks remain to
be assigned.

24
25

Each chunk contains chunk_size iterations, except for the last chunk to be
assigned, which may have fewer iterations.

26

When no chunk_size is specified, it defaults to 1.

27
28
29
30

guidedWhen schedule(guided, chunk_size) is specified, the iterations are
assigned to threads in chunks as the threads request them. The thread executes
the chunk of iterations, then requests another chunk, until no chunks remain to
be assigned.

31
32
33
34
35
36

For a chunk_size of 1, the size of each chunk is proportional to thenumber of unassigned iterations divided by the number of threads,
decreasing to 1. For a chunk_size with value k (greater than 1), thesize of each chunk is determined in the same way with the restrictionthat the chunks do not contain fewer than k iterations (except for the last chunk
to be assigned, which may have fewer than k iterations).

37

When no chunk_size is specified, it defaults to 1.

38

36

OpenMP API • Version 2.5 May 2005

1
2
3

runtime

4
5
6
7
8
9
10

Note – For a team of p threads and a loop of n iterations, let n ⁄ p be the integer q
which satisfies n = p*q - r, with 0 <= r < p. One compliant implementation of thestatic schedule (with no specified chunk_size) would behave as though chunk_size
had been specified with value q. Another compliant implementation would assign q
iterations to the first p-r threads, and q-1 iterations to the remaining r threads. Thisillustrates why a conforming program must not rely on the details of a particular
implementation.

11
12
13
14
15
16

A compliant implementation of the guided schedule with a chunk_size value of kwould assign q = n ⁄ p iterations to the first available thread and set n to the larger ofn-q and p*k. It would then repeat this process until q is greater than or equal to thenumber of remaining iterations, at which time the remaining iterations form the final
chunk. Another compliant implementation could use the same method, except with q =n ⁄ ( 2 p ) , and set n to the larger of n-q and 2*p*k.

17

Restrictions

18

Restrictions to the loop construct are as follows:

19
20• The values of the loop control expressions of the loop associated with the loop21

• Only a single schedule clause can appear on a loop directive.

22• chunk_size must be a loop invariant integer expression with a positive value.

23• The value of the chunk_size expression must be the same for all threads in the team.

24• When schedule(runtime) is specified, chunk_size must not be specified.

25• Only a single ordered clause can appear on a loop directive.

26
27• The ordered clause must be present on the loop construct if any ordered region

28• The loop iteration variable may not appear in a threadprivate directive.

29
30
31

• The for-loop must be a structured block, and in addition, its execution must not be

32• The for-loop iteration variable var must have a signed integer type.

33• Only a single nowait clause can appear on a for directive.

34

When schedule(runtime) is specified, the decision regarding schedulingis deferred until run time, and the schedule and chunk size are taken from therun-sched-var control variable.

directive must be the same for all the threads in the team.

ever binds to a loop region arising from the loop construct.

C/C++
terminated by a break statement.

Chapter 2

Directives

37

1
2
3

• If relational-op is < or <= then incr-expr must cause var to increase on each iteration

4

C/C++

5

Fortran

6
7• The do-loop must be a structured block, and in addition, its execution must not be

8• The do-loop iteration variable must be of type integer.

9• The do-loop cannot be a DO WHILE or a DO loop without loop control.

of the loop. Conversely, if relational-op is > or >= then incr-expr must cause var to
decrease on each iteration of the loop.

terminated by an EXIT statement.

Fortran10

11

Cross References1213• private, firstprivate, lastprivate, and reduction clauses, see

14• OMP_SCHEDULE environment variable, see Section 4.1 on page 114.

15

• ordered construct, see Section 2.7.6 on page 61.

16

Section 2.8.3 on page 70.

2.5.1.1

Determining the Schedule of a Work-sharing Loop

17
18
19
20
21
22
23
24
25

When execution encounters a loop directive, the schedule clause (if any) on the
directive, and the run-sched-var and def-sched-var internal control variables are used todetermine how loop iterations are assigned to threads. See Section 2.3 on page 24 fordetails of how the values of the internal control variables are determined. If noschedule clause is used on the work-sharing loop directive, then the schedule is takenfrom the current value of def-sched-var. If the schedule clause is used and specifies
the runtime schedule kind, then the schedule is taken from the run-sched-var control
variable. Otherwise, the schedule is taken from the value of the schedule clause.
Figure 2-2 describes how the schedule for a work-sharing loop is determined.

26

Cross References

27• Internal control variables, see Section 2.3 on page 24.

28

38

OpenMP API • Version 2.5 May 2005

START1

2
3

scheduleclause present?

No
Use def-sched-var schedule kind

Yes

4

5

schedule kindvalue is runtime?

6

No

Yes

7

Use run-sched-var schedule kind

8
9

10

Use schedule kind specified inschedule clause

FIGURE 2-2

2.5.2

Determining the schedule for a work-sharing loop.

sections Construct

11

Summary

12
13
14

The sections construct is a noniterative work-sharing construct that contains a set ofstructured blocks that are to be divided among, and executed by, the threads in a team.
Each structured block is executed once by one of the threads in the team.

15

Chapter 2

Directives

39

1

Syntax2
3

The syntax of the sections construct is as follows:

C/C++#pragma omp sections [clause[[,] clause] ...] new-line{[#pragma omp section new-line]
structured-block[#pragma omp section new-line
structured-block ]
...
}

4
5
6
7
8
9
10
11

The clause is one of the following:

12

13

private(list)

14

firstprivate(list)

15

lastprivate(list)

16

reduction(operator: list)17

nowait

18

C/C++

19

FortranThe syntax of the sections construct is as follows:20!$omp sections [clause[[,] clause] ...][!$omp section]
structured-block[!$omp section
structured-block ]...
!$omp end sections [nowait]

21
22
23
24
25
26
27

28

40

OpenMP API • Version 2.5 May 2005

1

The clause is one of the following:2

private(list)

3

firstprivate(list)

4

lastprivate(list)

5

reduction({operator|intrinsic_procedure_name}:list)

Fortran6

7

Binding

89
10
11The binding thread set for a sections region is the current team. A sections
region binds to the innermost enclosing parallel region. Only the threads of the teamexecuting the binding parallel region participate in the execution of the structured
blocks and (optional) implicit barrier of the sections region.

12

Description

13
14

Each structured block in the sections construct is preceded by a section directive
except possibly the first block, for which a preceding section directive is optional.

15
16

The method of scheduling the structured blocks among threads in the team is
implementation defined.

17
18

There is an implicit barrier at the end of a sections construct, unless a nowait
clause is specified.

19

Restrictions

20

Restrictions to the sections construct are as follows:21
22• The section directives must appear within the sections construct and may not

23• The code enclosed in a sections construct must be a structured block.

24
25• Only a single nowait clause can appear on a sections directive.

26

27

be encountered elsewhere in the sections region.

C/C++
C/C++

Chapter 2

Directives

41

1

Cross References2
3• private, firstprivate, lastprivate, and reduction clauses, see

4Section 2.8.3 on page 70.

2.5.3

single Construct5

Summary

6789The single construct specifies that the associated structured block is executed by only
one thread in the team (not necessarily the master thread). The other threads in the team
do not execute the block, and wait at an implicit barrier at the end of single construct,unless a nowait clause is specified.

10

Syntax11
12

The syntax of the single construct is as follows:

C/C++#pragma omp single [clause[[,] clause] ...] new-line
structured-block13
14

The clause is one of the following:

15

16

private(list)

17

firstprivate(list)

18

copyprivate(list)

19

nowait

20

C/C++

21

FortranThe syntax of the single construct is as follows:22!$omp single [clause[[,] clause] ...]
structured-block!$omp end single [end_clause[[,] end_clause] ...]

23
24
25

26

42

OpenMP API • Version 2.5 May 2005

1

The clause is one of the following:2

private(list)

3

firstprivate(list)4and end_clause is one of the following:5

copyprivate(list)

6

nowaitFortran78

Binding

9
10
11
12

The binding thread set for a single region is the current team. A single region
binds to the innermost enclosing parallel region. Only the threads of the teamexecuting the binding parallel region participate in the execution of the structured
block and (optional) implicit barrier of the single region.

13

Description

14
15
16

The method of choosing a thread to execute the structured block is implementation
defined. There is an implicit barrier after the single construct unless a nowait clauseis specified.

17

For an example of the single construct, see Section A.10 on page 130.

18

Restrictions

19

Restrictions to the single construct are as follows:20• The copyprivate clause must not be used with the nowait clause.

21• At most one nowait clause can appear on a single construct.

22

Cross References23• private and firstprivate clauses, see Section 2.8.3 on page 70.

24• copyprivate clause, see Section 2.8.4.2 on page 85.

25

Chapter 2

Directives

43Fortran

1
2

2.5.4

workshare Construct3

Summary

4
5
6

The workshare construct divides the execution of the enclosed structured block into
separate units of work, and causes the threads of the team to share the work such thateach unit is executed only once.

7

Syntax8

The syntax of the workshare construct is as follows:!$omp worksharestructured-block!$omp end workshare [nowait]

9
10
11
12

The enclosed structured block must consist of only the following:13• array assignments

14• scalar assignments

15• FORALL statements

16• FORALL constructs

17• WHERE statements

18• WHERE constructs

19• atomic constructs

20• critical constructs

21• parallel constructs

22
23Statements contained in any enclosed critical construct are also subject to theserestrictions. Statements in any enclosed parallel construct are not restricted.

24

Binding

25
26
27
28

The binding thread set for a workshare region is the current team. A workshareregion binds to the innermost enclosing parallel region. Only the threads of the teamexecuting the binding parallel region participate in the execution of the units ofwork and (optional) implicit barrier of the workshare region.

29

44

OpenMP API • Version 2.5 May 2005

Fortran (cont.)

1
2

Description

3
4

There is an implicit barrier at the end of a workshare construct unless a nowait
clause is specified.

5
6
7
8
9

An implementation of the workshare construct must insert any synchronization that isrequired to maintain standard Fortran semantics. For example, the effects of one
statement within the structured block must appear to occur before the execution of
succeeding statements, and the evaluation of the right hand side of an assignment must
appear to have been completed prior to the effects of assigning to the left hand side.

10

The statements in the workshare construct are divided into units of work as follows:

1112• For array expressions within each statement, including transformational array

13
14
15
16

intrinsic functions that compute scalar values from arrays:••

Evaluation of each element of the array expression, including any references to
ELEMENTAL functions, is a unit of work.
Evaluation of transformational array intrinsic functions may be freely subdivided
into any number of units of work.

17
18• If a workshare directive is applied to an array assignment statement, the1920• If a workshare directive is applied to a scalar assignment statement, the2122• If a workshare directive is applied to a WHERE statement or construct, the

23
24
25

• If a workshare directive is applied to a FORALL statement or construct, the26• For atomic constructs, the update of each scalar variable is a single unit of work.

27• For critical constructs, each construct is a single unit of work.

28
29
30

• For parallel constructs, each construct is a single unit of work with respect to the31
32• If none of the rules above apply to a portion of a statement in the structured block,

33
34
35

The transformational array intrinsic functions are MATMUL, DOT_PRODUCT, SUM,PRODUCT, MAXVAL, MINVAL, COUNT, ANY, ALL, SPREAD, PACK, UNPACK,RESHAPE, TRANSPOSE, EOSHIFT, CSHIFT, MINLOC, and MAXLOC.

36
37

It is unspecified how the units of work are assigned to the threads executing aworkshare region.

38

assignment of each element is a unit of work.
assignment operation is a single unit of work.
evaluation of the mask expression and the masked assignments are workshared.
evaluation of the mask expression, expressions occurring in the specification of theiteration space, and the masked assignments are workshared.

workshare construct. The statements contained in parallel constructs are
executed by new teams of threads formed for each parallel construct.
then that portion is a single unit of work.

Chapter 2

Directives

45

1
2
3

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 the samevalue would be computed by every thread.

4
5

If an array assignment, a scalar assignment, a masked array assignment, or a FORALL
assignment assigns to a private variable in the block, the result is unspecified.

6
7

The workshare directive causes the sharing of work to occur only in the workshareconstruct, and not in the remainder of the workshare region.

8

For examples of the workshare construct, see Section A.11 on page 132.

9

Restrictions

10

The following restrictions apply to the workshare directive:

11
12• The construct must not contain any user defined function calls unless the function is13

Fortran

ELEMENTAL.

15

Combined Parallel Work-sharing
Constructs

16
17
18
19

Combined parallel work-sharing constructs are shortcuts for specifying a work-sharing
construct nested immediately inside a parallel construct. The semantics of these
directives are identical to that of explicitly specifying a parallel construct containing
one work-sharing construct and no other statements.

20
21
22
23
24

The combined parallel work-sharing constructs allow certain clauses which arepermitted on both parallel constructs and on work-sharing constructs. If a program
would have different behavior depending on whether the clause were applied to theparallel construct or to the work-sharing construct, then the program’s behavior isunspecified.

25

The following sections describe the combined parallel work-sharing constructs:

26• The parallel loop construct.

27• The parallel sections construct.

14

2.6

Fortran28• The parallel workshare construct.

29

Fortran

30

31

46

OpenMP API • Version 2.5 May 2005

1

2.6.1

Parallel loop construct2

Summary

3
4

The parallel loop construct is a shortcut for specifying a parallel constructcontaining one loop construct and no other statements.

5

Syntax

6
7

The syntax of the parallel loop construct is as follows:

8
9

C/C++

#pragma omp parallel for [clause[[,] clause] ...] new-line
for-loop

1011

The clause can be any of the clauses accepted by the parallel or for directives,
except the nowait clause, with identical meanings and restrictions.

12

C/C++
Fortran

13
14

The syntax of the parallel loop construct is as follows:

15
16
17

!$omp parallel do [clause[[,] clause] ...]
do-loop[!$omp end parallel do]

18
19
20

The clause can be any of the clauses accepted by the parallel or do directives, withidentical meanings and restrictions. However, nowait may not be specified on an end
parallel do directive.

21
22

If an end parallel do directive is not specified, an end parallel do directive isassumed at the end of the do-loop.

23

Fortran24

Description

25
26
27

The semantics are identical to explicitly specifying a parallel directive immediately
followed by a for directive.

28

C/C++

29

C/C++

Chapter 2

Directives

47

1

Fortran2
3
4

The semantics are identical to explicitly specifying a parallel directive immediately
followed by a do directive, and an end do directive immediately followed by an end
parallel directive.

5

Fortran6

Restrictions

7

The restrictions for the parallel construct and the loop construct apply.

8

Cross References9• parallel construct, see Section 2.4 on page 26.

10• loop construct, see Section 2.5.1 on page 33.

11• Data attribute clauses, see Section 2.8.3 on page 70.

12

2.6.2

parallel sections Construct

13

Summary

14
15

The parallel sections construct is a shortcut for specifying a parallel
construct containing one sections construct and no other statements.

16

Syntax

17
18

The syntax of the parallel sections construct is as follows:

C/C++#pragma omp parallel sections [clause[[,] clause] ...] new-line{[#pragma omp section new-line]
structured-block[#pragma omp section new-line
structured-block ]
...
}

19
20
21
22
23
24
25
26

27

48

OpenMP API • Version 2.5 May 2005

1
2

The clause can be any of the clauses accepted by the parallel or sections
directives, except the nowait clause, with identical meanings and restrictions.

3

C/C++

4

Fortran

5

6
7
8
9
10
11
12

The syntax of the parallel sections construct is as follows:!$omp parallel sections [clause[[,] clause] ...][!$omp section]
structured-block[!$omp section
structured-block ]...
!$omp end parallel sections

13
14
15

The clause can be any of the clauses accepted by the parallel or sections
directives, with identical meanings and restrictions. However, nowait cannot be
specified on an end parallel sections directive.

16

The last section ends at the end parallel sections directive.

Fortran17

18

Description

19
20
21

The semantics are identical to explicitly specifying a parallel directive immediately
followed by a sections directive.

22

C/C++

23

Fortran

24
25
26

The semantics are identical to explicitly specifying a parallel directive immediately
followed by a sections directive, and an end sections directive immediately
followed by an end parallel directive.

27

Fortran

C/C++

28

For an example of the parallel sections construct, see Section A.9 on page 129.

29

Restrictions

30

The restrictions for the parallel construct and the sections construct apply.

31

Chapter 2

Directives

49

1

Cross References:2• parallel construct, see Section 2.4 on page 26.

3• sections construct, see Section 2.5.2 on page 39.

4• Data attribute clauses, see Section 2.8.3 on page 70.

Fortran

5
6

2.6.3

parallel workshare Construct

7

Summary

89The parallel workshare construct is a shortcut for specifying a parallel
construct containing one workshare construct and no other statements.

10

Syntax11

The syntax of the parallel workshare construct is as follows:!$omp parallel workshare [clause[[,] clause] ...]
structured-block!$omp end parallel workshare

12
13
14
15
16
17

The clause can be any of the clauses accepted by the parallel directive, withidentical meanings and restrictions. However, nowait may not be specified on an end
parallel workshare directive.

18

Description

19
20
21

The semantics are identical to explicitly specifying a parallel directive immediately
followed by a workshare directive, and an end workshare directive immediately
followed by an end parallel directive.

22

Restrictions

23

The restrictions for the parallel construct and the workshare construct apply.

24

Cross References

25• parallel construct, see Section 2.4 on page 26.

26• workshare construct, see Section 2.5.4 on page 44.

27

50

OpenMP API • Version 2.5 May 2005

• Data attribute clauses, see Section 2.8.3 on page 70.

1

Fortran23

2.7

Master and Synchronization Constructs

4

The following sections describe :5• the master construct.

6• the critical construct.

7• the barrier construct.

8• the atomic construct.

9• the flush construct.

10• the ordered construct.

11

2.7.1

master Construct

12

Summary

13
14

The master construct specifies a structured block that is executed by the master threadof the team.

15

Syntax

16
17

The syntax of the master construct is as follows:

18
19

20

21

C/C++

#pragma omp master new-line
structured-block

C/C++

Chapter 2

Directives

51

Fortran

1

The syntax of the master construct is as follows:2!$omp masterstructured-block!$omp end master345Fortran6

7

Binding

89
10
11The binding thread set for a master region is the current team. A master region
binds to the innermost enclosing parallel region. Only the master thread of the teamexecuting the binding parallel region participates in the execution of the structured
block of the master region.

12

Description

13
14

Other threads in the team do not execute the associated structured block. There is no
implied barrier either on entry to, or exit from, the master construct.

15

For an example of the master construct, see Section A.12 on page 136.

16

2.7.2

critical Construct

17

Summary

18
19

The critical construct restricts execution of the associated structured block to asingle thread at a time.

20

Syntax

21
22

The syntax of the critical construct is as follows:23
24#pragma omp critical [(name)] new-line
structured-block

C/C++

C/C++

25

26

52

OpenMP API • Version 2.5 May 2005

Fortran

1
2

3
4
5

The syntax of the critical construct is as follows:!$omp critical [(name)]
structured-block!$omp end critical [(name)]

Fortran6

7

Binding

8
9
10

The binding thread set for a critical region is all threads. Region execution isrestricted to a single thread at a time among all the threads in the program, without
regard to the team(s) to which the threads belong.

11

Description

12
13
14
15
16
17

An optional name may be used to identify the critical construct. All criticalconstructs without a name are considered to have the same unspecified name. A thread
waits at the beginning of a critical region until no other thread is executing a
critical region with the same name. The critical construct enforces exclusive
access with respect to all critical constructs with the same name in all threads, notjust in the current team.

18
19
20
21

Identifiers used to identify a critical construct have external linkage and are in a
name space which is separate from the name spaces used by labels, tags, members, andordinary identifiers.

22

C/C++

23

Fortran

24
25

C/C++

The names of critical constructs are global entities of the program. If a nameconflicts with any other entity, the behavior of the program is unspecified.

Fortran

26
27

For an example of the critical construct, see Section A.13 on page 138.

28

Restrictions

29
30

31

Fortran
The following restrictions apply to the critical construct:
Chapter 2

Directives

53

1
2

• If a name is specified on a critical directive, the same name must also be3
4• If no name appears on the critical directive, no name can appear on the end

5Fortran6

specified on the end critical directive.
critical directive.

2.7.3

barrier Construct

7

Summary

8
9The barrier construct specifies an explicit barrier at the point at which the constructappears.

10

Syntax11
12

The syntax of the barrier construct is as follows:

C/C++#pragma omp barrier new-line

13
14
15
16
17
18
19

Note that because the barrier construct does not have a C language statement as partof its syntax, there are some restrictions on its placement within a program. The
barrier directive may only be placed in the program at a position where ignoring ordeleting the directive would result in a program with correct syntax. See Appendix C for
the formal grammar. The examples in Section A.20 on page 153 illustrate theserestrictions.

20

C/C++

21

FortranThe syntax of the barrier construct is as follows:22!$omp barrier

23

Fortran

24

25

54

OpenMP API • Version 2.5 May 2005

1

Binding2
3
4

The binding thread set for a barrier region is the current team. A barrier region
binds to the innermost enclosing parallel region. See Section A.15 on page 140 for
examples.

5

Description

6
7

All of the threads of the team executing the binding parallel region must execute thebarrier region before any are allowed to continue execution beyond the barrier.

8

Restrictions

9

The following restrictions apply to the barrier construct:

10• Each barrier region must be encountered by all threads in a team or by none at all.

11
12

• The sequence of work-sharing regions and barrier regions encountered must be13

the same for every thread in a team.

2.7.4

atomic Construct

14

Summary

15
16

The atomic construct ensures that a specific storage location is updated atomically,rather than exposing it to the possibility of multiple, simultaneous writing threads.

17

Syntax

18
19

The syntax of the atomic construct is as follows:

20
21
22

C/C++

#pragma omp atomic new-line
expression-stmt
expression-stmt is an expression statement with one of the following forms:

23

x binop= expr

24

x++

25

Chapter 2

Directives

55

1

++x

2

x--

3

--x

4

In the preceding expressions:5• x is an lvalue expression with scalar type.

6
7• expr is an expression with scalar type, and it does not reference the object designated8• binop is not an overloaded operator and is one of +, *, -, /, &, ^, |, <<, or >>.

9

C/C++

10

Fortranby x.

The syntax of the atomic construct is as follows:11!$omp atomic
statement

12
13
14

where statement has one of the following forms:

15

x = x operator expr

16

x = expr operator x

17x = intrinsic_procedure_name (x, expr_list)

18

x = intrinsic_procedure_name (expr_list, x)

19

In the preceding statements:

20• x is a scalar variable of intrinsic type.

21• expr is a scalar expression that does not reference x.

22
23
24

• expr_list is a comma-separated, non-empty list of scalar expressions that do not25• intrinsic_procedure_name is one of MAX, MIN, IAND, IOR, or IEOR.

26• operator is one of +, *, -, /, .AND., .OR., .EQV., or .NEQV. .

27
28
29

• The operators in expr must have precedence equal to or greater than the precedence30
31• intrinsic_procedure_name must refer to the intrinsic procedure name and not to other32

reference x. When intrinsic_procedure_name refers to IAND, IOR, or IEOR, exactly
one expression must appear in expr_list.

of operator, x operator expr must be mathematically equivalent to x operator (expr),
and expr operator x must be mathematically equivalent to (expr) operator x.
program entities.

56

OpenMP API • Version 2.5 May 2005

1

• operator must refer to the intrinsic operator and not to a user-defined operator.

2• The assignment must be intrinsic assignment.

3

Fortran4

Binding

5
6
7
8

The binding thread set for an atomic region is all threads. atomic regions enforce
exclusive access with respect to other atomic regions that update the same storage
location x among all the threads in the program without regard to the team(s) to which
the threads belong.

9

Description

10
11
12
13
14

Only the load and store of the object designated by x are atomic; the evaluation of expr
is not atomic. To avoid race conditions, all updates of the location which could
potentially occur in parallel must be protected with an atomic directive. atomic
regions do not enforce exclusive access with respect to any critical or orderedregions which access the same storage location x.

15
16
17

A compliant implementation may enforce exclusive access between atomic regions
which update different storage locations. The circumstances under which this occurs are
implementation defined.

18

For an example of the atomic construct, see Section A.16 on page 142.

19

Restrictions

20
21

The following restriction applies to the atomic construct:

C/C++

22
23

• All atomic references to the storage location x throughout the program are required to

24

C/C++

25

Fortranhave a compatible type. See Section A.17 on page 144 for examples.

26

The following restriction applies to the atomic construct:

27
28
29

• All atomic references to the storage location of variable x throughout the program are30

Fortran31

required to have the same type and type parameters. See Section A.17 on page 144
for examples.

Chapter 2

Directives

57

1

Cross References2• critical construct, see Section 2.7.2 on page 52.

3

2.7.5

flush Construct4

Summary

5
6
7
8

The flush construct executes the OpenMP flush operation. This operation makes athread’s temporary view of memory consistent with memory, and enforces an order on
the memory operations of the variables explicitly specified or implied. See the memory
model description in Section 1.4 on page 10 for more details.

9

Syntax

1011The syntax of the flush construct is as follows:12#pragma omp flush [(list)] new-line

13

C/C++

14

FortranC/C++

The syntax of the flush construct is as follows:15!$omp flush [(list)]16

Fortran17

18

Binding

19
20
21
22

The binding thread set for a flush region is the encountering thread. Execution of aflush region only affects the view of memory from the thread which executes theregion. Other threads must themselves execute a flush operation in order to observe theeffects of the encountering thread’s flush operation.

23

58

OpenMP API • Version 2.5 May 2005

1

Description

2
3
4
5

A flush construct with a list applies the flush operation to the items in the list, anddoes not return until the operation is complete for all specified list items. A flush
construct without a list, executed on a given thread, operates as if the whole threadvisible data state of the program, as defined by the base language, is flushed.

6
7
8

If a pointer is present in the list, the pointer itself is flushed, not the object to which thepointer refers.

9

C/C++

C/C++

10

Fortran

11
12
13
14
15

If the list item or a subobject of the list item has the POINTER attribute, the allocation
or association status of the POINTER item is flushed, but the pointer target is not. If thelist item is a Cray pointer, the pointer is flushed, but the object to which it points is not.
If the list item has the ALLOCATABLE attribute and the list item is allocated, theallocated array is flushed; otherwise the allocation status is flushed.

16

Fortran17
18

For examples of the flush construct, see Section A.18 on page 147 and Section A.19
on page 150.

19
20
21
22
23

Note – the following examples illustrate the ordering properties of the flush operation.
In the following incorrect pseudocode example, the programmer intends to prevent
simultaneous execution of the critical section by the two threads, but the program does
not work properly because it does not enforce the proper ordering of the operations on
variables a and b.

24

Incorrect example:
a = b = 025
26

thread 1

thread 2

27
28
29
30
31
32

b = 1
flush(b)flush(a)if (a == 0) thencritical section
end ifa = 1
flush(a)flush(b)if (b == 0) thencritical section
end if33

Chapter 2

Directives

59

1
2
3
4
5
6

The problem with this example is that operations on variables a and b are not orderedwith respect to each other. For instance, nothing prevents the compiler from moving theflush of b on thread 1 or the flush of a on thread 2 to a position completely after thecritical section (assuming that the critical section on thread 1 does not reference b and thecritical section on thread 2 does not reference a). If either re-ordering happens, the criticalsection can be active on both threads simultaneously.

78
9

The following correct pseudocode example correctly ensures that the critical section is
executed by not more than one of the two threads at any one time. Notice that execution of
the critical section by neither thread is considered correct in this example.
Correct example:

10

a = b = 0

1112thread 1

thread 2

13
14
15
16
17

b = 1
flush(a,b)
if (a == 0) thencritical section
end ifa = 1
flush(a,b)
if (b == 0) thencritical section
end if

18
19
20

The compiler is prohibited from moving the flush at all for either thread, ensuring that therespective assignment is complete and the data is flushed before the if statement is
executed.

21
22
23
24
25
26
27

Note that because the flush construct does not have a C language statement as part of its
syntax, there are some restrictions on its placement within a program. The flush
directive may only be placed in the program at a position where ignoring or deleting thedirective would result in a program with correct syntax. See Appendix C for the formal
grammar. See Section A.20 on page 153 for an example that illustrates these placement
restrictions.

28

C/C++

C/C++

29

A flush region without a list is implied at the following locations:30• During a barrier region.

31• At entry to and exit from parallel, critical and ordered regions.

32• At exit from work-sharing regions, unless a nowait is present.

33• At entry to and exit from combined parallel work-sharing regions.

34

60

OpenMP API • Version 2.5 May 2005

1

• During omp_set_lock and omp_unset_lock regions.

234• During omp_test_lock, omp_set_nest_lock, omp_unset_nest_lock5

A flush region with a list is implied at the following locations:

67• At entry to and exit from atomic regions, where the list contains only the object

8Note – A flush region is not implied at the following locations:

9• At entry to work-sharing regions.

10• At entry to or exit from a master region.

11

and omp_test_nest_lock regions, if the region causes the lock to be set or
unset.

updated in the atomic construct.

2.7.6

ordered Construct

12

Summary13
14
15

The ordered construct specifies a structured block in a loop region which will be
executed in the order of the loop iterations. This sequentializes and orders the code
within an ordered region while allowing code outside the region to run in parallel.

16

Syntax

17
18

The syntax of the ordered construct is as follows:

19
20

21

22

C/C++

#pragma omp ordered new-line
structured-block

C/C++

Chapter 2

Directives

61Fortran

1

The syntax of the ordered construct is as follows:2!$omp orderedstructured-block!$omp end ordered3
4
5

Fortran6

7

Binding

8
9
10

The binding thread set for an ordered region is the current team. An ordered region
binds to the innermost enclosing loop region. ordered regions that bind to different
loop regions execute completely independently of each other.

11

Description

12
13
14
15
16
17
18

The threads in the team executing the loop region execute ordered regions
sequentially in the order of the loop iterations. When the thread executing the first
iteration of the loop encounters an ordered construct, it can enter the orderedregion without waiting. When a thread executing any subsequent iteration encounters anordered region, it waits at the beginning of that ordered region until each of theprevious iterations that contains an ordered region has completed the orderedregion.

19

For examples of the ordered construct, see Section A.21 on page 154.

20

Restrictions

21

Restrictions to the ordered construct are as follows:22
23• The loop region to which an ordered region binds must have an ordered clause

24
25
26

• During execution of an iteration of a loop within a loop region, the executing thread

27

Cross References28• loop construct, see Section 2.5.1 on page 33.

29• parallel loop construct, see Section 2.6.1 on page 47.

30

specified on the corresponding loop (or parallel loop) construct.
must not execute more than one ordered region which binds to the same loop
region.

62

OpenMP API • Version 2.5 May 2005

1

2.8

Data Environment23This section presents a directive and several clauses for controlling the data environment
during the execution of parallel regions.

45• Section 2.8.1 on page 63 describes how the sharing attributes of variables referenced

6
7• The threadprivate directive, which is provided to create threadprivate memory,

89
10• Clauses that may be specified on directives to control the sharing attributes of

11
12
13

• Clauses that may be specified on directives to copy data values from private or

14

in parallel regions are determined.
is described in Section 2.8.2 on page 66.
variables referenced in parallel or work-sharing constructs are described in
Section 2.8.3 on page 70.
threadprivate objects on one thread to the corresponding objects on other threads inthe team are described in Section 2.8.4 on page 83.

2.8.1

Sharing Attribute Rules

15
16This section describes how the sharing attributes of variables referenced in parallel
regions are determined. The following two cases are described separately:

17
18• Section 2.8.1.1 on page 63 describes the sharing attribute rules for variables

19
20• Section 2.8.1.2 on page 65 describes the sharing attribute rules for variables

referenced in a construct.
referenced in a region, but outside any construct.

22

Sharing Attribute Rules for Variables Referenced in a
Construct

23
24

The sharing attributes of variables which are referenced in a construct may be one of thefollowing: predetermined, explicitly determined, or implicitly determined.

25
26
27
28

Note that specifying a variable on a firstprivate, lastprivate, or
reduction clause of an enclosed construct causes an implicit reference to the variablein the enclosing construct. Such implicit references are also subject to the following
rules.

29

The following variables have predetermined sharing attributes:

30
31• Variables appearing in threadprivate directives are threadprivate.

21

32

2.8.1.1

C/C++

Chapter 2

Directives

63

1
2

• Variables with automatic storage duration which are declared in a scope inside the3• Variables with heap allocated storage are shared.

4• Static data members are shared.

5
6• The loop iteration variable in the for-loop of a for or parallel for construct is7• Variables with const-qualified type having no mutable member are shared.

construct are private.

private in that construct.

8

C/C++

9

Fortran1011• Variables and common blocks appearing in threadprivate directives are

12
13• The loop iteration variable in the do-loop of a do or parallel do construct is1415• Variables used as loop iteration variables in sequential loops in a parallel16• implied-do and forall indices are private.

17
18• Cray pointees inherit the sharing attribute of the storage with which their Cray

threadprivate.
private in that construct.
construct are private in the parallel construct.

pointers are associated.

Fortran

19
20
21

Variables with predetermined sharing attributes may not be listed in data-sharing
attribute clauses, with the following exceptions:

22
23
24

• The loop iteration variable in the for-loop of a for or parallel for construct

25

C/C++

26

Fortran27
28• The loop iteration variable in the do-loop of a do or parallel do construct may be

29
30
31

• Variables used as loop iteration variables in sequential loops in a parallel

C/C++
may be listed in a private or lastprivate clause.

listed in a private or lastprivate clause.
construct may be listed in private, firstprivate, lastprivate, shared,or reduction clauses.

Fortran32
33
34

Additional restrictions on the variables which may appear in individual clauses aredescribed with each clause in Section 2.8.3 on page 70.

35
36

Variables referenced in the construct are said to have an explicitly determined sharing
attribute if they are listed in a data-sharing attribute clause on the construct.

37

64

OpenMP API • Version 2.5 May 2005

Variables referenced in the construct whose sharing attribute is not predetermined or
explicitly determined will have their sharing attribute implicitly determined. In aparallel construct, the sharing attributes of these variables is determined by thedefault clause, if present (see Section 2.8.3.1 on page 71). If no default clause is present,
variables with implicitly determined sharing attributes are shared. For other constructs,
variables with implicitly determined sharing attributes inherit their sharing attributes
from the enclosing context.

1
2
3
4
5
6
7

9

Sharing Attribute Rules for Variables Referenced in a Region,
but not in a Construct10
11

The sharing attributes of variables which are referenced in a region, but not in aconstruct, are determined as follows:1213• Static variables declared in called routines in the region are shared.

8

2.8.1.2

C/C++

14
15

• Variables with const-qualified type having no mutable member, and that are declared

16
17• File-scope or namespace-scope variables referenced in called routines in the region

18• Variables with heap-allocated storage are shared.

19• Static data members are shared.

20
21• Formal arguments of called routines in the region that are passed by reference inherit

22• Other variables declared in called routines in the region are private.

in called routines, are shared.
are shared unless they appear in a threadprivate directive.

the data-sharing attributes of the associated actual argument.

23

C/C++

24

Fortran

25
26
27• Local variables declared in called routines in the region and that have the save

28
29
30

• Variables belonging to common blocks, or declared in modules, and referenced in

31
32• Dummy arguments of called routines in the region that are passed by reference inherit33• implied-do and forall indices are private.

34
35• Cray pointees inherit the sharing attribute of the storage with which their Cray36

attribute, or that are data initialized, are shared unless they appear in athreadprivate directive.
called routines in the region are shared unless they appear in a threadprivate
directive.
the data-sharing attributes of the associated actual argument.

pointers are associated.

Chapter 2

Directives

65• Other local variables declared in called routines in the region are private.

1

Fortran

2

3

2.8.2

threadprivate Directive

4

Summary

5
6

The threadprivate directive specifies that named global-lifetime objects are
replicated, with each thread having its own copy.

7

Syntax

89The syntax of the threadprivate directive is as follows:

C/C++#pragma omp threadprivate(list) new-line

10
11
12

where list is a comma-separated list of file-scope, namespace-scope, or static blockscope variables that do not have incomplete types.

13

C/C++

14

FortranThe syntax of the threadprivate directive is as follows:15!$omp threadprivate(list)

16
17
18

where list is a comma-separated list of named variables and named common blocks.
Common block names must appear between slashes.

19

Fortran20

Description

21
22
23

Each copy of a threadprivate object is initialized once, in the manner specified by the
program, but at an unspecified point in the program prior to the first reference to that
copy.

24

A thread may not reference another thread’s copy of a threadprivate object.

25

66

OpenMP API • Version 2.5 May 2005

1
2
3
4

During the sequential part, and in non-nested inactive parallel regions, references
will be to the initial thread’s copy of the object. In parallel regions, references by
the master thread will be to the copy of the object in the thread which encountered theparallel region.

5
6

The values of data in the initial thread’s copy of a threadprivate object are guaranteed topersist between any two consecutive references to the object in the program.

7
8
9

The values of data in the threadprivate objects of threads other than the initial thread are
guaranteed to persist between two consecutive active parallel regions only if all thefollowing conditions hold:10• Neither parallel region is nested inside another parallel region.

11• The number of threads used to execute both parallel regions is the same.

12
13• The value of the dyn-var internal control variable is false at entry to the first14
15• The value of the nthreads-var internal control variable is the same at entry to both

16
17
18

If these conditions all hold, and if a threadprivate object is referenced in both regions,then threads with the same thread number in their respective regions will reference thesame copy of that variable.

19
20
21
22
23

If the above conditions hold, the storage duration, lifetime, and value of a thread’s copyof a threadprivate variable that does not appear in any copyin clause on the second
region will be retained. Otherwise, the storage duration, lifetime, and value of a thread’s
copy of the variable in the second region is undefined.

24
25
26

If an object is referenced in an explicit initializer of a threadprivate variable, and thevalue of the object is modified prior to the first reference to a copy of the variable, thenthe behavior is unspecified.

27

C/C++

28

Fortranparallel region and remains false until entry to the second parallel region.
parallel regions and has not been modified between these points.

C/C++

29
30

A variable is said to be affected by a copyin clause if the variable appears in the
copyin clause or it is in a common block that appears in the copyin clause.

31
32
33
34
35
36

If the above conditions hold, the definition, association, or allocation status of a thread’s
copy of a threadprivate variable or a variable in a threadprivate common block, that is
not affected by any copyin clause that appears on the second region, will be retained.
Otherwise, the definition and association status of a thread’s copy of the variable in thesecond region is undefined, and the allocation status of an allocatable array will be
implementation defined.

37

Chapter 2

Directives

67

1
2

If a common block, or a variable that is declared in the scope of a module, appears in athreadprivate directive, it implicitly has the SAVE attribute.

3
4
5
6

If a threadprivate variable or a variable in a threadprivate common block is not affectedby any copyin clause that appears on the first parallel region in which it isreferenced, the variable or any subobject of the variable is initially defined or undefinedaccording to the following rules:

78• If it has the ALLOCATABLE attribute, each copy created will have an initial

9• If it has the POINTER attribute:

allocation status of not currently allocated.

10
11
12

•

13

•

if it has an initial association status of disassociated, either through explicit
initialization or default initialization, each copy created will have an association
status of disassociated;otherwise, each copy created will have an association status of undefined.

• If it does not have either the POINTER or the ALLOCATABLE attribute:

14
15
16

•

17

•

if it is initially defined, either through explicit initialization or default
initialization, each copy created is so defined;
otherwise, each copy created is undefined.

Fortran18
19

For examples of the threadprivate directive, see Section A.22 on page 158.

20

Restrictions

21

The restrictions to the threadprivate directive are as follows:

22
23• A threadprivate object must not appear in any clause except the copyin,

copyprivate, schedule, num_threads, and if clauses.

C/C++

24
25
26
27

• A threadprivate directive for file-scope variables must appear outside any

definition or declaration, and must lexically precede all references to any of thevariables in its list.

28
29
30

• A threadprivate directive for namespace-scope variables must appear outside

31
32
33

• Each variable in the list of a threadprivate directive at file or namespace scope

34
35
36

• A threadprivate directive for static block-scope variables must appear in the37

any definition or declaration other than the namespace definition itself, and must
lexically precede all references to any of the variables in its list.
must refer to a variable declaration at file or namespace scope that lexically precedes
the directive.
scope of the variable and not in a nested scope. The directive must lexically precede
all references to any of the variables in its list.

68

OpenMP API • Version 2.5 May 2005

1
2
3

• Each variable in the list of a threadprivate directive in block scope must refer to4
5
6• If a variable is specified in a threadprivate directive in one translation unit, it

7• The address of a threadprivate variable is not an address constant.

8• A threadprivate variable must not have an incomplete type or a reference type.

910• A threadprivate variable with non-POD class type must have an accessible,

a variable declaration in the same scope that lexically precedes the directive. The
variable declaration must use the static storage-class specifier.
must be specified in a threadprivate directive in every translation unit in which
it is declared.

unambiguous copy constructor if it is declared with an explicit initializer.

11

C/C++

12

Fortran

13
14
15
16
17
18

• The threadprivate directive must appear in the declaration section of a scoping

19
20
21
22

• If a threadprivate directive specifying a common block name appears in one

23• A blank common block cannot appear in a threadprivate directive.

24
25
26

• A variable can only appear in a threadprivate directive in the scope in which it

27
28• A variable that appears in a threadprivate directive and is not declared in the29

Fortranunit in which the common block or variable is declared. Although variables incommon blocks can be accessed by use association or host association, common
block names cannot. This means that a common block name specified in athreadprivate directive must be declared to be a common block in the same
scoping unit in which the threadprivate directive appears.
program unit, then such a directive must also appear in every other program unit that
contains a COMMON statement specifying the same name. It must appear after the lastsuch COMMON statement in the program unit.

is declared. It must not be an element of a common block or be declared in an
EQUIVALENCE statement.
scope of a module must have the SAVE attribute.

30

Cross References:

31• Dynamic adjustment of threads, see Section 2.4.1 on page 29.

32• copyin clause, see Section 2.8.4.1 on page 84.

33• Internal control variables, see Section 2.3 on page 24.

34

Chapter 2

Directives

69

1

2.8.3

Data-Sharing Attribute Clauses

2
3
4
5
6

Several constructs accept clauses that allow a user to control the sharing attributes ofvariables for the duration of the construct. Data-sharing attribute clauses apply only tovariables whose names are visible in the construct on which the clause appears, exceptthat formal arguments that are passed by reference inherit the data-sharing attributes of
the associated actual argument.

7
8

Not all of the clauses listed in this section are valid on all directives. The set of clausesthat is valid on a particular directive is described with the directive.

9
10
11
12
13
14

Most of the clauses accept a comma-separated list of list items (see Section 2.1 on page18). All list items appearing in a clause must be visible, according to the scoping rulesof the base language. With the exception of the default clause, clauses may berepeated as needed. A list item that specifies a given variable may not appear in morethan one clause on the same directive, except that a variable may be specified in both
firstprivate and lastprivate clauses.

15
16
17
18

If a variable referenced in a data-sharing attribute clause has a type derived from atemplate, and there are no other references to that variable in the program, then any
behavior related to that variable is undefined.

C/C++

19

C/C++

20

Fortran

21
22
23
24
25
26

A named common block may be specified in a list by enclosing the name in slashes.
When a named common block appears in a list, it has the same meaning as if every
explicit member of the common block appeared in the list. An explicit member of acommon block is a variable that is named in a COMMON statement that specifies thecommon block name and is declared in the same scoping unit in which the clauseappears.

27
28
29
30

Although variables in common blocks can be accessed by use association or hostassociation, common block names cannot. This means that a common block namespecified in a data-sharing attribute clause must be declared to be a common block in thesame scoping unit in which the data-sharing attribute clause appears.

31
32
33
34
35
36

When a named common block appears in a private, firstprivate,
lastprivate, or shared clause of a directive, none of its members may be declaredin another data-sharing attribute clause in that directive (see Section A.23 on page 163
for examples). When individual members of a common block are privatized, the storageof the specified variables is no longer associated with the storage of the common block
itself (see Section A.28 on page 171 for examples).

37

Fortran

38

70

OpenMP API • Version 2.5 May 2005

1

2.8.3.1

default clause

2

Summary3
4
5

The default clause allows the user to control the sharing attributes of variables which arereferenced in a parallel construct, and whose sharing attributes are implicitly
determined (see Section 2.8.1.1 on page 63).

6

Syntax

7
8

The syntax of the default clause is as follows:

9

C/C++

default(shared | none)

C/C++

10

Fortran

11
12

13

The syntax of the default clause is as follows:default(private | shared | none)

Fortran

14

15

Description

16
17

The default(shared) clause causes all variables referenced in the construct whichhave implicitly determined sharing attributes to be shared.

18
19
20

Fortran
The default(private) clause causes all variables referenced in the constructwhich have implicitly determined sharing attributes to be private.

21

Fortran

22
23
24
25

The default(none) clause requires that each variable which is referenced in theconstruct, and that does not have a predetermined sharing attribute, must have its sharing
attribute explicitly determined by being listed in a data-sharing attribute clause. See
Section A.24 on page 165 for examples.

26

Chapter 2

Directives

71

1

Restrictions

2

The restrictions to the default clause are as follows:3• Only a single default clause may be specified on a parallel directive.

4

2.8.3.2

shared clause

5

Summary

6
7

The shared clause declares one or more list items to be shared among all the threads
in a team.

8

Syntax9

The syntax of the shared clause is as follows:

10

shared(list)

11

Description

12

All threads within a team access the same storage area for each shared object.

13

Fortran

14
15
16
17

The association status of a shared pointer becomes undefined upon entry to and on exitfrom the parallel construct if it is associated with a target or a subobject of a target
that is in a private, firstprivate, lastprivate, or reduction clauseinside the parallel construct.

18
19
20
21
22

Under certain conditions, passing a shared variable to a non-intrinsic procedure may
result in the value of the shared variable being copied into temporary storage before theprocedure reference, and back out of the temporary storage into the actual argument
storage after the procedure reference. This situation will occur when the following three
conditions hold regarding an actual argument in a reference to a non-intrinsic procedure:

23

a. The actual argument is one of the following:24•

A shared variable.

25•

A subobject of a shared variable.

26•

An object associated with a shared variable.

27•

An object associated with a subobject of a shared variable.

28b. The actual argument is also one of the following:

29

•

30

72

An array section.

OpenMP API • Version 2.5 May 2005

1•

An array section with a vector subscript.

2•

An assumed-shape array.

3•

A pointer array.

45c. The associated dummy argument for this actual argument is an explicit-shapearray or an assumed-size array.

6
7
8
9

This effectively results in references to, and definitions of, the storage during theprocedure reference. Any references to (or definitions of) the shared storage that is
associated with the dummy argument by any other thread must be synchronized with theprocedure reference to avoid possible race conditions.

10
11

It is implementation defined whether this situation might occur under other conditions.
See Section A.25 on page 167 for an example of this behavior.

12

Fortran

13

2.8.3.3

private clause

14

Summary

15

The private clause declares one or more list items to be private to a thread.

16

Syntax17

The syntax of the private clause is as follows:18

private(list)

19

Description

20
21
22
23
24
25

Each thread in the team that references a list item that appears in a private clause inany statement in the construct receives a new list item whose language-specific attributes
are derived from the original list item. Inside the construct, all references to the originallist item are replaced by references to the new list item. If a thread does not reference alist item that appears in a private clause, it is unspecified whether that thread receives
a new list item.

26
27
28

The value of the original list item is not defined upon entry to the region. The originallist item must not be referenced within the region. The value of the original list item is
not defined upon exit from the region.

29

Chapter 2

Directives

73

1
2
3
4

List items that are privatized in a parallel region may be privatized again in an
enclosed parallel or work-sharing construct. As a result, list items that appear in a
private clause on a parallel or work-sharing construct may be either shared or
private in the enclosing context. See Section A.27 on page 170 for an example.

5
6
7
8
9

A new list item of the same type, with automatic storage duration, is allocated for theconstruct. The size and alignment of the new list item are determined by the type of thevariable. This allocation occurs once for each thread in the team that references the list
item in any statement in the construct.

10
11
12

The new list item is initialized, or has an undefined initial value, as if it had been locallydeclared without an initializer. The order in which any default constructors for different
private objects are called is unspecified.

13

C/C++

14

Fortran

15
16
17
18

A new list item of the same type is declared once for each thread in the team thatreferences the list item in any statement in the construct. The initial value of the new list
item is undefined. Within a parallel region, the initial status of a private pointeris undefined.

19
20
21
22
23

A list item that appears in a private clause may be storage-associated with othervariables when the private clause is encountered. Storage association may exist
because of constructs such as EQUIVALENCE, COMMON, etc. If A is a variableappearing in a private clause and B is a variable which is storage-associated with A,
then:

24
25

• The contents, allocation, and association status of B are undefined on entry to the2627• Any definition of A, or of its allocation or association status, causes the contents,

28
29• Any definition of B, or of its allocation or association status, causes the contents,

30

For examples, see Section A.28 on page 171.

C/C++

parallel region.
allocation, and association status of B to become undefined.
allocation, and association status of A to become undefined.

Fortran31
32

For examples of the private clause, see Section A.26 on page 168.

33

Restrictions

34

The restrictions to the private clause are as follows:

35

74

OpenMP API • Version 2.5 May 2005

• A list item that appears in the reduction clause of a parallel construct must

1
2
3
4

not appear in a private clause on a work-sharing construct if any of the worksharing regions arising from the work-sharing construct ever bind to any of theparallel regions arising from the parallel construct.

C/C++

5
6
7

• A variable of class type (or array thereof) that appears in a private clause requires

an accessible, unambiguous default constructor for the class type.

8
9• A variable that appears in a private clause must not have a const-qualified type10
11

• A variable that appears in a private clause must not have an incomplete type or a

12

C/C++

13

Fortranunless it is of class type with a mutable member.
reference type.

14
15• A variable that appears in a private clause must either be definable, or an

1617• An allocatable array that appears in a private clause must have an allocation status

18• Assumed-size arrays may not appear in a private clause.

1920• Variables that appear in namelist statements, in variable format expressions, and in21

Fortran

22

allocatable array.
of “not currently allocated” on entry to and on exit from the construct.

expressions for statement function definitions, may not appear in a private clause.

2.8.3.4

firstprivate clause

23

Summary

24
25
26

The firstprivate clause declares one or more list items to be private to a thread,and initializes each of them with the value that the corresponding original item has when
the construct is encountered.

27

Syntax28

The syntax of the firstprivate clause is as follows:

29

30

firstprivate(list)

Chapter 2

Directives

75

1

Description

2
3

The firstprivate clause provides a superset of the functionality provided by theprivate clause.

4
5
6
7
8
9

A list item that appears in a firstprivate clause is subject to the private clausesemantics described in Section 2.8.3.3 on page 73. In addition, the new list item is
initialized from the original list item existing before the construct. The initialization of
the new list item is done once for each thread in the team that references the list item inany statement in the construct. The initialization is done prior to the thread’s executionof the construct.

10
11
12
13
14
15
16

For a firstprivate clause on a parallel construct, the initial value of the newlist item is the value of the original list item that exists immediately prior to theparallel construct for the thread that encounters the construct. For afirstprivate clause on a work-sharing construct, the initial value of the new list
item for a thread that executes the work-sharing construct is the value of the original list
item that exists immediately prior to the point in time that the thread encounters thework-sharing construct.

17
18

If a list item appears in both firstprivate and lastprivate clauses, the update
required for lastprivate occurs after all the initializations for firstprivate.

19
20
21
22
23
24
25

For variables of non-array type, the initialization occurs as if by assignment. For a(possibly multi-dimensional) array of objects of non-array type, each element isinitialized as if by assignment from an element of the original array to the corresponding
element of the new array. For class types, a copy constructor is invoked to perform theinitialization. The order in which copy constructors for different objects are called isunspecified.

26

C/C++

27

FortranC/C++

The initialization of the new list items occurs as if by assignment.

28

Fortran29

30

Restrictions

31

The restrictions to the firstprivate clause are as follows:

32
33
34
35
36

• A list item that is private within a parallel region, or that appears in the37

reduction clause of a parallel construct, must not appear in a
firstprivate clause on a work-sharing construct if any of the work-sharing
regions arising from the work-sharing construct ever bind to any of the parallel
regions arising from the parallel construct.

76

OpenMP API • Version 2.5 May 2005

C/C++

1
2
3• A variable of class type (or array thereof) that appears in a firstprivate clauserequires an accessible, unambiguous copy constructor for the class type.

4
5• A variable that appears in a firstprivate clause must not have a const-

6
7• A variable that appears in a firstprivate clause must not have an incomplete

8

C/C++

9

Fortranqualified type unless it is of class type with a mutable member.
type or a reference type.

10• A variable that appears in a firstprivate clause must be definable.

1112• Fortran pointers, Cray pointers, assumed-size arrays and allocatable arrays may not

13
14
15

• Variables that appear in namelist statements, in variable format expressions, and in

16

Fortran17

appear in a firstprivate clause.
expressions for statement function definitions, may not appear in a firstprivate
clause.

2.8.3.5

lastprivate clause

18

Summary

19
20

The lastprivate clause declares one or more list items to be private to a thread, andcauses the corresponding original list item to be updated after the end of the region.

21

Syntax22

The syntax of the lastprivate clause is as follows:23

lastprivate(list)

24

Description

25
26

The lastprivate clause provides a superset of the functionality provided by theprivate clause.

27

Chapter 2

Directives

77

1
2
3
4
5

A list item that appears in a lastprivate clause is subject to the private clausesemantics described in Section 2.8.3.3 on page 73. In addition, when a lastprivate
clause appears on the directive that identifies a work-sharing construct, the value of each
new list item from the sequentially last iteration of the associated loop, or the lexicallylast section construct, is assigned to the original list item.

67
8

For a (possibly multi-dimensional) array of objects of non-array type, each element is
assigned to the corresponding element of the original array.

9

C/C++

10
11
12

List items that are not assigned a value by the sequentially last iteration of the loop, orby the lexically last section construct, have unspecified values after the construct.
Unassigned subobjects also have an unspecified value after the construct.

13
14
15
16

The original list item becomes defined at the end of the construct if there is an implicit
barrier at that point. Any concurrent uses or definitions of the original list item must be
synchronized with the definition that occurs at the end of the construct to avoid race
conditions.

17
18
19
20

If the lastprivate clause is used on a construct to which nowait is also applied,the original list item remains undefined until a barrier synchronization has been
performed to ensure that the thread that executed the sequentially last iteration, or thelexically last section construct, has stored that list item.

21
22

If a list item appears in both firstprivate and lastprivate clauses, the update
required for lastprivate occurs after all initializations for firstprivate.

23

For an example of the lastprivate clause, see Section A.30 on page 175.

24

Restrictions

25

The restrictions to the lastprivate clause are as follows:

26
27
28
29

• A list item that is private within a parallel region, or that appears in the

C/C++

reduction clause of a parallel construct, must not appear in a lastprivate
clause on a work-sharing construct if any of the corresponding work-sharing regions
ever binds to any of the corresponding parallel regions.

C/C++

30
31
32
33

• A variable of class type (or array thereof) that appears in a lastprivate clauserequires an accessible, unambiguous default constructor for the class type, unless thelist item is also specified in a firstprivate clause.
• A variable of class type (or array thereof) that appears in a lastprivate clause

34
35

requires an accessible, unambiguous copy assignment operator for the class type.The
order in which copy assignment operators for different objects are called isunspecified.

36
37

38

78

OpenMP API • Version 2.5 May 2005

1
2

• A variable that appears in a lastprivate clause must not have a const-qualified

3
4• A variable that appears in a lastprivate clause must not have an incomplete type

5

C/C++

6

Fortrantype unless it is of class type with a mutable member.
or a reference type.

7• A variable that appears in a lastprivate clause must be definable.

89• Fortran pointers, Cray pointers, assumed-size arrays and allocatable arrays may not

10
11
12

• Variables that appear in namelist statements, in variable format expressions, and in

13

Fortran

14

appear in a lastprivate clause.
expressions for statement function definitions, may not appear in a lastprivate
clause.

2.8.3.6

reduction clause

15

Summary

16
17
18
19

The reduction clause specifies an operator and one or more list items. For each list
item, a private copy is created on each thread, and is initialized appropriately for theoperator. After the end of the region, the original list item is updated with the values ofthe private copies using the specified operator.

20

Syntax

21
22

The syntax of the reduction clause is as follows:

23
24
25

26

C/C++

reduction(operator:list)
The following table lists the operators that are valid and their initialization values. The
actual initialization value depends on the data type of the reduction variable.

Chapter 2

Directives

79

1

Operator

Initialization value

2

+

0

3

*

1

4

-

0

5

&

~0

6

|

0

7

^

0

8

&&

1

9

||

0

10

C/C++

11

FortranThe syntax of the reduction clause is as follows:

12

reduction({operator | intrinsic_procedure_name}:list)

13
14
15
16

The following table lists the operators and intrinsic_procedure_names that are valid andtheir initialization values. The actual initialization value depends on the data type of the
reduction variable.

17

Operator/
Intrinsic

Initialization value

18

+

0

19

*

1

20

-

0

21

.and.

.true.

22.or.

.false.

23.eqv.

.true.

24.neqv.

.false.

25
26

max

Most negative representable number in the
reduction variable type27

80

OpenMP API • Version 2.5 May 2005

1
2

min

Largest representable number in the
reduction variable type

3

iand

All bits on

4

ior

0

5

ieor

0

Fortran6

7

Description

8
9

The reduction clause can be used to perform some forms of recurrence calculations(involving mathematically associative and commutative operators) in parallel.

10
11
12
13
14
15

A private copy of each list item is created, one for each thread, as if the private
clause had been used. The private copy is then initialized to the initialization value forthe operator, as specified above. At the end of the region for which the reduction
clause was specified, the original list item is updated by combining its original value
with the final value of each of the private copies, using the operator specified. (Thepartial results of a subtraction reduction are added to form the final value.)

16
17
18
19
20
21
22
23
24

The value of the original list item becomes undefined when the first thread reaches theconstruct that specifies the clause and remains so until the reduction computation iscomplete. Normally, the computation will be complete at the end of the construct;
however, if the reduction clause is used on a construct to which nowait is also
applied, the value of the original list item remains undefined until a barrier
synchronization has been performed to ensure that all threads have completed the
reduction. Any concurrent uses or definitions of the original list item must be
synchronized with the definition that occurs at the end of the construct, or at thesubsequent barrier, to avoid race conditions.

25
26
27
28

The order in which the values are combined is unspecified. Therefore, comparing
sequential and parallel runs, or comparing one parallel run to another (even if thenumber of threads used is the same), there is no guarantee that bit-identical results will
be obtained or that side effects (such as floating point exceptions) will be identical.

2930Note – List items specified in a reduction clause are typically used in the enclosed
region in certain forms.

31

Chapter 2

Directives81C/C++

1
2

A reduction is typically specified for statements of the form:x = x op expr
x binop= expr
x = expr op x
x++
++x
x---x

3
4
5
6
7
8
9

(except for subtraction)

10
11
12

where expr has scalar type and does not reference x, op is not an overloaded operator,
but one of +, *, -, &, ^, |, &&, or ||, and binop is not an overloaded operator, but oneof +, *, -, &, ^, or |.

13

C/C++

14

FortranA reduction using an operator is typically specified for statements of the form:

15

x = x op expr
x = expr op x (except for subtraction)

16
17
18
19

where op is +, *, -, .and., .or., .eqv., or .neqv., the expression does not involvex, and the reduction op is the last operation performed on the right hand side.

20

A reduction using an intrinsic is typically specified for statements of the form:
x = intr(x,expr_list)
x = intr(expr_list, x)

21
22
23
24

where intr is max, min, iand, ior, or ieor and expr_list is a comma separated list of
expressions not involving x.

25

Fortran26

For examples, see Section A.31 on page 176.

27

Restrictions

28

The restrictions to the reduction clause are as follows:

29

82

OpenMP API • Version 2.5 May 2005

1
2
3

• A list item that appears in a reduction clause of a work-sharing construct must be

4
5
6
7

• A list item that appears in a reduction clause of a parallel construct must not

89• Any number of reduction clauses can be specified on the directive, but a list item

shared in the parallel regions to which any of the work-sharing regions arisingfrom the work-sharing construct bind.
be privatized on any enclosed work-sharing construct if any of the work-sharing
regions arising from the work-sharing construct bind to any of the parallel
regions arising from the parallel construct.
can appear only once in the reduction clause(s) for that directive.

C/C++

10
11
12

• The type of a list item that appears in a reduction clause must be valid for the13• Aggregate types (including arrays), pointer types and reference types may not appear

reduction operator.
in a reduction clause.

14
15• A variable that appears in a reduction clause must not be const-qualified.

16
17• The operator specified in a reduction clause cannot be overloaded with respect to

18

C/C++

19

Fortran

20
21• The type of a list item that appears in a reduction clause must be valid for the22• A variable that appears in a reduction clause must be definable.

23
24• A list item that appears in a reduction clause must be a named variable of2526• Fortran pointers, Cray pointers, assumed-size arrays and allocatable arrays may not

27
28
29
30

• Operators specified must be intrinsic operators and any intrinsic_procedure_name31

Fortran

32
33
34
35

36

the variables that appear in that clause.

reduction operator or intrinsic.

intrinsic type.
appear in a reduction clause.
must refer to one of the allowed intrinsic procedures. Assignment to the reduction
variables must be via intrinsic assignment. See Section A.31 on page 176 forexamples.

2.8.4

Data Copying ClausesThis section describes the copyin clause (valid on the parallel directive andcombined parallel work-sharing directives) and the copyprivate clause (valid on the
single directive).

Chapter 2

Directives

83

1
2

These clauses support the copying of data values from private or threadprivate objects
on one thread, to the corresponding objects on other threads in the team.

3
4
5
6

The clauses accept a comma-separated list of list items (see Section 2.1 on page 18). Alllist items appearing in a clause must be visible, according to the scoping rules of thebase language. Clauses may be repeated as needed, but a list item that specifies a given
variable may not appear in more than one clause on the same directive.

7

2.8.4.1

copyin clause

8

Summary

910
11The copyin clause provides a mechanism to copy the value of the master thread’s
threadprivate variable to the threadprivate variable of each other member of the teamexecuting the parallel region.

12

Syntax13

The syntax of the copyin clause is as follows:14

copyin(list)

15

Description

16
17
18
19
20
21
22
23

The copy is done after the team is formed and prior to the start of execution of theparallel region. For variables of non-array type, the copy occurs as if by assignment.
For a (possibly multi-dimensional) array of objects of non-array type, each element iscopied as if by assignment from an element of the master thread’s array to thecorresponding element of the other thread’s array. For class types, the copy assignment
operator is invoked. The order in which copy assignment operators for different objects
are called is unspecified.

24

C/C++

25

Fortran

26
27

The copy is done, as if by assignment, after the team is formed and prior to the start of
execution of the parallel region.

28
29
30

On entry to any parallel region, each thread’s copy of a variable that is affected bya copyin clause for the parallel region will acquire the allocation, association, anddefinition status of the master thread’s copy, according to the following rules:

31• If it has the POINTER attribute:

32

C/C++

84

OpenMP API • Version 2.5 May 2005

1
2

•

if the master thread’s copy is associated with a target that each copy can become
associated with, each copy will become associated with the same target;3•

if the master thread’s copy is disassociated, each copy will become disassociated;4•

otherwise, each copy will have an undefined association status.

5
6• If it does not have the POINTER attribute, each copy becomes defined with the value

7

Fortranof the master thread’s copy as if by intrinsic assignment.

8

For an example of the copyin clause, see Section A.32 on page 180.

9

Restrictions

10

The restrictions on the copyin clause are as follows:

1112• A list item that appears in a copyin clause must be threadprivate.

C/C++

13
14

• A variable of class type (or array thereof) that appears in a copyin clause requires

15

C/C++

16

Fortran

17
18
19• A list item that appears in a copyin clause must be threadprivate. Named variables

20
21• A common block name that appears in a copyin clause must be declared to be a22

• Allocatable arrays may not appear in a copyin clause.

an accessible, unambiguous copy assignment operator for the class type.

appearing in a threadprivate common block may be specified: it is not necessary to
specify the whole common block.
common block in the same scoping unit in which the copyin clause appears.

Fortran

23

24

2.8.4.2

copyprivate clause

25

Summary

26
27

The copyprivate clause provides a mechanism to use a private variable to broadcast
a value from one member of a team to the other members of the team.

28

Chapter 2

Directives

85

1

Syntax2

The syntax of the copyprivate clause is as follows:
copyprivate(list)

3

4

Description

5
6
7
8

The effect of the copyprivate clause on the specified list items occurs after the
execution of the structured block associated with the single construct (seeSection 2.5.3 on page 42), and before any of the threads in the team have left the barrierat the end of the construct.

9
10
11
12
13
14
15
16
17

In all other threads in the team, each specified list item becomes defined with the valueof the corresponding list item in the thread that executed the structured block. For
variables of non-array type, the definition occurs as if by copy assignment. For a(possibly multi-dimensional) array of objects of non-array type, each element is copied
as if by copy assignment from an element of the array in the thread that executed thestructured block to the corresponding element of the array in the other threads. For classtypes, a copy assignment operator is invoked. The order in which copy assignment
operators for different objects are called is unspecified.

18

C/C++

19

Fortran

20
21
22
23
24

If a list item is not a pointer, then in all other threads in the team, the list item becomes
defined (as if by assignment) with the value of the corresponding list item in the threadthat executed the structured block. If the list item is a pointer, then in all other threads inthe team, the list item becomes pointer associated (as if by pointer assignment) with thecorresponding list item in the thread that executed the structured block.

25

Fortran

C/C++

26

For examples of the copyprivate clause, see Section A.33 on page 181.

27
28
29

Note – The copyprivate clause is an alternative to using a shared variable for thevalue when providing such a shared variable would be difficult (for example, in arecursion requiring a different variable at each level).

30

Restrictions

31

The restrictions to the copyprivate clause are as follows:

32

86

OpenMP API • Version 2.5 May 2005

1
2

• All list items that appear in the copyprivate clause must be either threadprivate,

3
4• A list item that appears in a copyprivate clause may not appear in a private oror private in the enclosing context.
firstprivate clause on the single construct.

C/C++

5
6
7

• A variable of class type (or array thereof) that appears in a copyprivate clause

8

C/C++

9

Fortran10• A common block that appears in a copyprivate clause must be threadprivate.

1112• Allocatable arrays and assumed-size arrays may not appear in a copyprivate

requires an accessible unambiguous copy assignment operator for the class type.

clause.

Fortran

13

14

2.9

Nesting of Regions

15
16

This section describes a set of restrictions on the nesting of regions. The restrictions on
nesting are as follows:

17
18• A work-sharing region may not be closely nested inside a work-sharing, critical,

19
20• A barrier region may not be closely nested inside a work-sharing, critical,

21• A master region may not be closely nested inside a work-sharing region.

22• An ordered region may not be closely nested inside a critical region.

23
24• An ordered region must be closely nested inside a loop region (or parallel loop

25
26
27

• A critical region may not be nested (closely or otherwise) inside a critical28
29

For examples illustrating these rules, see Section A.14 on page 139, Section A.34 on
page 185 and Section A.35 on page 187.

30

ordered, or master region.
ordered, or master region.

region) with an ordered clause.
region with the same name. Note that this restriction is not sufficient to prevent
deadlock.

Chapter 2

Directives

87

1

88

OpenMP API • Version 2.5 May 2005

1

CHAPTER

3

2

Runtime Library Routines

3
4This chapter describes the OpenMP API runtime library routines and is divided into thefollowing sections:5• Runtime library definitions (Section 3.1 on page 90).

6
7

• Execution environment routines that can be used to control and query the parallel

89• Lock routines that can be used to synchronize access to data (Section 3.3 on page10

• Portable timer routines (Section 3.4 on page 108).

11
12

Throughout this chapter, true and false are used as generic terms to simplify thedescription of the routines.

13
14

true means a nonzero integer value and false means an integer value of zero.

execution environment (Section 3.2 on page 91).
102).

C/C++

15

C/C++

16

Fortran17

true means a logical value of .TRUE. and false means a logical value of .FALSE..

18

Fortran19

Fortran20

Restrictions

21

The following restriction applies to all OpenMP runtime library routines:

22
23• OpenMP runtime library routines may not be called from PURE or ELEMENTAL

24

25

procedures.

Fortran
89

1

3.1

Runtime Library Definitions

2
3
4
5
6

For each base language, a compliant implementation must supply a set of definitions for
the OpenMP API runtime library routines and the special data types of their parameters.
The set of definitions must contain a declaration for each OpenMP API runtime libraryroutine and a declaration for the simple lock and nestable lock data types. In addition,
each set of definitions may specify other implementation specific values.

78

The library routines are external functions with “C” linkage.

9
10

Prototypes for the C/C++ runtime library routines described in this chapter shall be
provided in a header file named omp.h. This file defines the following:

11• The prototypes of all the routines in the chapter.

12• The type omp_lock_t.

13• The type omp_nest_lock_t.

14

See Section D.1 on page 223 for an example of this file.

C/C++

C/C++

15
16

Fortran

17
18

The OpenMP Fortran API runtime library routines are external procedures. The return
values of these routines are of default kind, unless otherwise specified.

19
20
21
22

Interface declarations for the OpenMP Fortran runtime library routines described in thischapter shall be provided in the form of a Fortran include file named omp_lib.h or
a Fortran 90 module named omp_lib. It is implementation defined whether the
include file or the module file (or both) is provided.

23

These files define the following:

24• The interfaces of all of the routines in this chapter.

25• The integer parameter omp_lock_kind.

26• The integer parameter omp_nest_lock_kind.

27
28
29
30
31

• The integer parameter openmp_version with a value yyyymm where yyyy

32

See Section D.2 on page 225 and Section D.3 on page 227 for examples of these files.

33

and mm are the year and month designations of the version of the OpenMP Fortran
API that the implementation supports. This value matches that of the C preprocessor
macro _OPENMP, when a macro preprocessor is supported (see Section 2.2 on page
21).

90

OpenMP API • Version 2.5 May 2005

1
2
3

It is implementation defined whether any of the OpenMP runtime library routines thattake an argument are extended with a generic interface so arguments of different KIND
type can be accommodated. See Appendix D.4 for an example of such an extension.

4

Fortran5

3.2

Execution Environment Routines

6
7

The routines described in this section affect and monitor threads, processors, and theparallel environment.

8• the omp_set_num_threads routine.

9• the omp_get_num_threads routine.

10• the omp_get_max_threads routine.

11• the omp_get_thread_num routine.

12• the omp_get_num_procs routine.

13• the omp_in_parallel routine.

14• the omp_set_dynamic routine.

15• the omp_get_dynamic routine.

16• the omp_set_nested routine.

17• the omp_get_nested routine.

18

3.2.1

omp_set_num_threads

19

Summary20
21
22

The omp_set_num_threads routine affects the number of threads to be used for
subsequent parallel regions that do not specify a num_threads clause, by setting
the value of the nthreads-var internal control variable.

23

Chapter 3

Runtime Library Routines91Format

1

C/C++

2

void omp_set_num_threads(int num_threads);

3
4

C/C++

5

Fortransubroutine omp_set_num_threads(num_threads)
integer num_threads

6
7

Fortran89Constraints on Arguments

10

The value of the argument passed to this routine must evaluate to a positive integer.

11

Binding

12
13
14
15

When called from the sequential part of the program, the binding thread set for an
omp_set_num_threads region is the encountering thread. When called from within
any explicit parallel region, the binding thread set (and binding region, if required)for the omp_set_num_threads region is implementation defined.

16

Effect17
18

The effect of this routine is to set the value of the nthreads-var internal control variable
to the value specified in the argument.

19
20

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

21
22

If the number of threads requested exceeds the number the implementation can support,
or is not a positive integer, the behavior of this routine is implementation defined.

23
24

For an example of the omp_set_num_threads routine, see Section A.36 on page
193.

25

Calling Context Rules

26
27
28

This routine has the described effect only when called from the sequential part of the
program. If it is called from any parallel region, the behavior of this routine is
implementation defined.

29

92

OpenMP API • Version 2.5 May 2005

1

Cross References

2• Internal control variables, see Section 2.3 on page 24.

3

3.2.2

omp_get_num_threads

4

Summary

5
6

The omp_get_num_threads routine returns the number of threads in the current
team.

7

FormatC/C++

8
9

int omp_get_num_threads(void);

10

C/C++

11

Fortran12

integer function omp_get_num_threads()

Fortran13
14

Binding

15
16
17
18

The binding thread set for an omp_get_num_threads region is the current team.The
binding region for an omp_get_num_threads region is the innermost enclosing
parallel region. The return value of this routine depends on the characteristics of theteam executing the binding parallel region.

19

Effect

20
21
22
23

The omp_get_num_threads routine returns the number of threads in the teamexecuting the parallel region to which the routine region binds. If called from thesequential part of a program, this routine returns 1. For examples, see Section A.37 on
page 195.

24
25

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

26

Cross References27• parallel construct, see Section 2.4 on page 26.

28

Chapter 3

Runtime Library Routines

93

1

3.2.3

omp_get_max_threads

2

Summary3
4
5
6The omp_get_max_threads routine returns the value of the nthreads-var internal
control variable, which is used to determine the number of threads that would form the
new team, if an active parallel region without a num_threads clause were to be
encountered at that point in the program.

7

FormatC/C++

8

int omp_get_max_threads(void);

9
10

C/C++

11

Fortraninteger function omp_get_max_threads()

12

Fortran13
14

Binding

15
16
17
18

When called from the sequential part of the program, the binding thread set for an
omp_get_max_threads region is the encountering thread. When called from within
any explicit parallel region, the binding thread set (and binding region, if required)for the omp_get_max_threads region is implementation defined.

19

Effect

20
21
22
23

The following expresses a lower bound on the value of omp_get_max_threads: thenumber of threads that would be used to form a team if an active parallel region
without a num_threads clause were to be encountered at that point in the program isless than or equal to the value returned by omp_get_max_threads.

24
25

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

26
27
28

Note – The return value of omp_get_max_threads routine can be used to
dynamically allocate sufficient storage for all threads in the team formed at thesubsequent active parallel region.

29

94

OpenMP API • Version 2.5 May 2005

1

Cross References

2• Internal control variables, see Section 2.3 on page 24.

3• parallel construct, see Section 2.4 on page 26.

4• num_threads clause, see Section 2.4 on page 26.

5

3.2.4

omp_get_thread_num

6Summary78
9The omp_get_thread_num routine returns the thread number, within the team, of
the thread executing the parallel region from which omp_get_thread_num iscalled.

10Format
C/C++

11
12

int omp_get_thread_num(void);

13

C/C++

14

Fortran15

integer function omp_get_thread_num()

Fortran16
17

Binding

18
19
20
21

The binding thread set for an omp_get_thread_num region is the current team.The
binding region for an omp_get_thread_num region is the innermost enclosing
parallel region. The return value of this routine depends on the characteristics of theteam executing the binding parallel region.

22

Effect

23
24
25
26
27

The omp_get_thread_num routine returns the thread number of the current thread,
within the team executing the parallel region to which the routine region binds. The
thread number is an integer between 0 and one less than the value returned by
omp_get_num_threads, inclusive. The thread number of the master thread of theteam is 0. The routine returns 0 if it is called from the sequential part of a program.

28

Chapter 3

Runtime Library Routines95

1

Cross References2• omp_get_num_threads routine, see Section 3.2.2 on page 93.

3

3.2.5

omp_get_num_procs

4

Summary

5
6

The omp_get_num_procs routine returns the number of processors available to theprogram.

7

FormatC/C++

8

int omp_get_num_procs(void);

9
10

C/C++

11

Fortraninteger function omp_get_num_procs()

12

Fortran13
14

Binding15
16
17

The binding thread set for an omp_get_num_procs region is all threads. The effectof executing this routine is not related to any specific region corresponding to any
construct or API routine.

18

Effect19
20

The omp_get_num_procs routine returns the number of processors that are available
to the program at the time the routine is called.

21

3.2.6

omp_in_parallel

22

Summary

23
24

The omp_in_parallel routine returns true if the call to the routine is enclosed by anactive parallel region; otherwise, it returns false.

25

96

OpenMP API • Version 2.5 May 2005

Format

1

C/C++

2

int omp_in_parallel(void);

3
4

C/C++

5

Fortranlogical function omp_in_parallel()

6

Fortran78

Binding

9
10
11

The binding thread set for an omp_in_parallel region is all threads. The effect ofexecuting this routine is not related to any specific parallel region but instead
depends on the state of all enclosing parallel regions.

12

Effect13
1415

omp_in_parallel returns the logical OR of the if clauses of all enclosing
parallel regions. If a parallel region does not have an if clause, this isequivalent to if(true).

16
17

If the routine is called from the sequential part of the program, thenomp_in_parallel returns false.

18

Cross References19• if clause, see Section 2.4.1 on page 29.

20

3.2.7

omp_set_dynamic

21

Summary

22
23
24

The omp_set_dynamic routine enables or disables dynamic adjustment of thenumber of threads available for the execution of parallel regions by setting the valueof the dyn-var internal control variable.

25

Chapter 3

Runtime Library Routines97Format

1

C/C++

2

void omp_set_dynamic(int dynamic_threads);

3
4

C/C++

5

Fortransubroutine omp_set_dynamic (dynamic_threads)
logical dynamic_threads

6
7

Fortran89Binding

10
11
12
13

When called from the sequential part of the program, the binding thread set for an
omp_set_dynamic region is the encountering thread. When called from within any
explicit parallel region, the binding thread set (and binding region, if required) for
the omp_set_dynamic region is implementation defined.

14

Effect15
16
17

For implementations that provide the ability to dynamically adjust the number of
threads, if the argument to omp_set_dynamic evaluates to true, dynamic adjustmentof the number of threads is enabled; otherwise, dynamic adjustment is disabled.

18
19

For implementations that do not provide the ability to dynamically adjust the number of
threads, this routine has no effect: the value of dyn-var remains false.

20

For an example of the omp_set_dynamic routine, see Section A.36 on page 193.

21
22

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

23

Calling Context Rules

24
25
26

The omp_set_dynamic routine has the described effect only when called from thesequential part of the program. If called from within any explicit parallel region, thebehavior of this routine is implementation defined.

27

Cross References:

28• Internal control variables, see Section 2.3 on page 24.

29• omp_get_num_threads routine, see Section 3.2.2 on page 93.

30

98

OpenMP API • Version 2.5 May 2005

1

3.2.8

omp_get_dynamic

2

Summary3
4
5The omp_get_dynamic routine returns the value of the dyn-var internal control
variable, which determines whether dynamic adjustment of the number of threads isenabled or disabled.

6

FormatC/C++

7
8

int omp_get_dynamic(void);

9

C/C++

10

Fortran11

logical function omp_get_dynamic()

Fortran12
13

Binding

14
15
16
17

When called from the sequential part of the program, the binding thread set for an
omp_get_dynamic region is the encountering thread. When called from within any
explicit parallel region, the binding thread set (and binding region, if required) for
the omp_get_dynamic region is implementation defined.

18

Effect19
20This routine returns true if dynamic adjustment of the number of threads is enabled; it
returns false, otherwise.

21
22

If the implementation does not provide the ability to dynamically adjust the number of
threads, then this routine always returns false.

23
24

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

25

Cross References

26• Internal control variables, see Section 2.3 on page 24.

27

Chapter 3

Runtime Library Routines

99

1

3.2.9

omp_set_nested

2

Summary3
4

The omp_set_nested routine enables or disables nested parallelism, by setting thenest-var internal control variable.

5

Format

6

C/C++

7

void omp_set_nested(int nested);

8

C/C++

9

Fortransubroutine omp_set_nested (nested)
logical nested

10
11

Fortran12
13

Binding

14
15
16
17

When called from the sequential part of the program, the binding thread set for an
omp_set_nested region is the encountering thread. When called from within any
explicit parallel region, the binding thread set (and binding region, if required) for
the omp_set_nested region is implementation defined.

18

Effect19
20
21

For implementations that support nested parallelism, if the argument to
omp_set_nested evaluates to true, nested parallelism is enabled; otherwise, nested
parallelism is disabled.

22
23

For implementations that do not support nested parallelism, this routine has no effect:
the value of nest-var remains false.

24
25

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

26

Calling Context Rules

27
28
29

The omp_set_nested routine has the described effect only when called from thesequential part of the program. If called from within any explicit parallel region, thebehavior of this routine is implementation defined.

30

100

OpenMP API • Version 2.5 May 2005

1

Cross References

2• Internal control variables, see Section 2.3 on page 24.

3

3.2.10

omp_get_nested

4

Summary

5
6

The omp_get_nested routine returns the value of the nest-var internal control
variable, which determines if nested parallelism is enabled or disabled.

7

FormatC/C++

8
9

int omp_get_nested(void);

10

C/C++

11

Fortran12

logical function omp_get_nested()

Fortran13
14

Binding

15
16
17
18

When called from the sequential part of the program, the binding thread set for an
omp_get_nested region is the encountering thread. When called from within any
explicit parallel region, the binding thread set (and binding region, if required) for
the omp_get_nested region is implementation defined.

19

Effect20

This routine returns true if nested parallelism is enabled; it returns false, otherwise.

21
22

If an implementation does not support nested parallelism, this routine always returns
false.

23
24

See Section 2.4.1 on page 29 for the rules governing the number of threads used to
execute a parallel region.

25

Cross References

26• Internal control variables, see Section 2.3 on page 24.

27

Chapter 3

Runtime Library Routines

101

1

3.3

Lock Routines

2
3
4
5

The OpenMP runtime library includes a set of general-purpose lock routines that can beused for synchronization. These general-purpose lock routines operate on OpenMP locks
that are represented by OpenMP lock variables. An OpenMP lock variable must beaccessed only through the routines described in this section.

6
7
8
9
10

An OpenMP lock may be in one of the following states: uninitialized, unlocked, or
locked. If a lock is in the unlocked state, a thread may set the lock, which changes its
state to locked. The thread which sets the lock is then said to own the lock. A threadwhich owns a lock may unset that lock, returning it to the unlocked state. A thread may
not set or unset a lock which is owned by another thread.

11
12
13
14
15
16

Two types of locks are supported: simple locks and nestable locks. A nestable lock may
be set multiple times by the same thread before being unset; a simple lock may not be
set if it is already owned by the thread trying to set it. Simple lock variables areassociated with simple locks and may only be passed to simple lock routines. Nestable
lock variables are associated with nestable locks and may only be passed to nestable
lock routines.

17
18
19

Constraints on the state and ownership of the lock accessed by each of the lock routines
are described with the routine. If these constraints are not met, the behavior of theroutine is unspecified.

20
21
22
23

The OpenMP lock routines access a lock variable in such a way that they always readand update the most current value of the lock variable. Therefore, it is not necessary for
an OpenMP program to include explicit flush directives to ensure that the lockvariable’s value is consistent among different threads.

24
25

See Section A.39 on page 198 and Section A.40 on page 200, for examples of using thesimple and the nestable lock routines, respectively.

26

Binding27
28
29

The binding thread set for all lock routine regions is all threads. For each OpenMP lock,the lock routine effects relate to all threads which execute the routines, without regard towhich team(s) the threads belong.

30

102

OpenMP API • Version 2.5 May 2005

1

Simple Lock Routines

2
3
4
5

The type omp_lock_t is an object type capable of representing a simple lock. For thefollowing routines, a lock variable must be of omp_lock_t type. All simple lockroutines require an argument that is a pointer to a variable of type omp_lock_t.

6

C/C++

7

Fortran

8
9

C/C++

For the following routines, svar must be an integer variable ofkind=omp_lock_kind.

Fortran

1011

The simple lock routines are as follows:12• The omp_init_lock routine initializes a simple lock.

13• The omp_destroy_lock routine uninitializes a simple lock.

14• The omp_set_lock routine waits until a simple lock is available, and then sets it.

15• The omp_unset_lock routine unsets a simple lock.

16• The omp_test_lock routine tests a simple lock, and sets it if it is available.

17

Nestable Lock Routines:

18
19
20
21
22

The type omp_nest_lock_t is an object type capable of representing a nestable lock.
For the following routines, a lock variable must be of omp_nest_lock_t type. All
nestable lock routines require an argument that is a pointer to a variable of type
omp_nest_lock_t.

23

C/C++

24

Fortran

25
26

C/C++

For the following routines, nvar must be an integer variable ofkind=omp_nest_lock_kind.

Fortran

27
28

The nestable lock routines are as follows:29• The omp_init_nest_lock routine initializes a nestable lock.

30• The omp_destroy_nest_lock routine uninitializes a nestable lock.

31• The omp_set_nest_lock routine waits until a nestable lock is available, and then32

33

sets it.
Chapter 3

Runtime Library Routines

103

1

• The omp_unset_nest_lock routine unsets a nestable lock.

2
3• The omp_test_nest_lock routine tests a nestable lock, and sets it if it is4

available.

3.3.1

omp_init_lock and omp_init_nest_lock5

Summary

6

These routines provide the only means of initializing an OpenMP lock.

7

FormatC/C++

8void omp_init_lock(omp_lock_t *lock);
void omp_init_nest_lock(omp_nest_lock_t *lock);

9
10
11

C/C++

12

Fortran13
14

subroutine omp_init_lock(svar)
integer (kind=omp_lock_kind) svar

15
16

subroutine omp_init_nest_lock(nvar)
integer (kind=omp_nest_lock_kind) nvar

Fortran17
18

Constraints on Arguments

19

A lock accessed by either routine must be in the uninitialized state.

20

Effect21
22

The effect of these routines is to initialize the lock to the unlocked state (that is, nothread owns the lock). In addition, the nesting count for a nestable lock is set to zero.

23

For an example of the omp_init_lock routine, see Section A.38 on page 197.

24

104

OpenMP API • Version 2.5 May 2005

2

omp_destroy_lock and
omp_destroy_nest_lock3

Summary

4

These routines ensure that the OpenMP lock is uninitialized.

5

Format

1

3.3.2

C/C++

6

void omp_destroy_lock(omp_lock_t *lock);
void omp_destroy_nest_lock(omp_nest_lock_t *lock);

7
8
9

C/C++

10

Fortran11
12

subroutine omp_destroy_lock(svar)
integer (kind=omp_lock_kind) svar

13
14

subroutine omp_destroy_nest_lock(nvar)
integer (kind=omp_nest_lock_kind) nvar

Fortran15
16

Constraints on Arguments

17

A lock accessed by either routine must be in the unlocked state.

18

Effect19

The effect of these routines is to change the state of the lock to uninitialized.

20

3.3.3

omp_set_lock and omp_set_nest_lock21

Summary

22
23

These routines provide a means of setting an OpenMP lock. The calling thread blocks
until the lock is set.

24

Chapter 3

Runtime Library Routines105Format

1

C/C++

2

void omp_set_lock(omp_lock_t *lock);
void omp_set_nest_lock(omp_nest_lock_t *lock);

3
4
5

C/C++

6

Fortran7
8subroutine omp_set_lock(svar)
integer (kind=omp_lock_kind) svar

910

subroutine omp_set_nest_lock(nvar)
integer (kind=omp_nest_lock_kind) nvar

Fortran11
12

Constraints on Arguments

13
14
15

A lock accessed by either routine must not be in the uninitialized state. A simple lockaccessed by omp_set_lock which is in the locked state must not be owned by thethread executing the routine.

16

Effect17
18

Each of these routines blocks the thread executing the routine until the specified lock isavailable and then sets the lock.

19
20

A simple lock is available if it is unlocked. Ownership of the lock is granted to thethread executing the routine.

21
22
23

A nestable lock is available if it is unlocked or if it is already owned by the thread
executing the routine. The thread executing the routine is granted, or retains, ownershipof the lock, and the nesting count for the lock is incremented.

24

3.3.4

omp_unset_lock and omp_unset_nest_lock25

Summary

26

These routines provide the means of unsetting an OpenMP lock.

27

106

OpenMP API • Version 2.5 May 2005

Format

1

C/C++

2

void omp_unset_lock(omp_lock_t *lock);
void omp_unset_nest_lock(omp_nest_lock_t *lock);

3
4
5

C/C++

6

Fortran7
8subroutine omp_unset_lock(svar)
integer (kind=omp_lock_kind) svar

910

subroutine omp_unset_nest_lock(nvar)
integer (kind=omp_nest_lock_kind) nvar

Fortran11
12

Constraints on Arguments

13
14

A lock accessed by either routine must be in the locked state and owned by the thread
executing the routine.

15

Effect16

For a simple lock, the omp_unset_lock routine causes the lock to become unlocked.

17
18

For a nestable lock, the omp_unset_nest_lock routine decrements the nesting
count, and causes the lock to become unlocked if the resulting nesting count is zero.

19
20

For either routine, if the lock becomes unlocked, and if one or more threads are waiting
for this lock, the effect is that one thread is chosen and given ownership of the lock.

21

3.3.5

omp_test_lock and omp_test_nest_lock22

Summary

23
24

These routines attempt to set an OpenMP lock but do not block execution of the thread
executing the routine.

25

Chapter 3

Runtime Library Routines107Format

1

C/C++

2

int omp_test_lock(omp_lock_t *lock);int omp_test_nest_lock(omp_nest_lock_t *lock);

3
4
5

C/C++

6

Fortran7
8

logical function omp_test_lock(svar)
integer (kind=omp_lock_kind) svar

910

integer function omp_test_nest_lock(nvar)
integer (kind=omp_nest_lock_kind) nvar

Fortran11
12

Constraints on Arguments

13
14
15

A lock accessed by either routine must not be in the uninitialized state. A simple lockaccessed by omp_test_lock which is in the locked state must not be owned by thethread executing the routine.

16

Effect17
18
19

These routines attempt to set a lock in the same manner as omp_set_lock andomp_set_nest_lock, except that they do not block execution of the thread
executing the routine.

20
21

For a simple lock, the omp_test_lock routine returns true if the lock is successfully
set; otherwise, it returns false.

22
23

For a nestable lock, the omp_test_nest_lock routine returns the new nesting count
if the lock is successfully set; otherwise, it returns zero.

24

3.4

Timing Routines25

The routines described in this section support a portable wall clock timer.

26• the omp_get_wtime routine.

27• the omp_get_wtick routine.

28

108

OpenMP API • Version 2.5 May 2005

1

3.4.1

omp_get_wtime

2

Summary3

The omp_get_wtime routine returns elapsed wall clock time in seconds.

4

FormatC/C++

5
6

double omp_get_wtime(void);

7

C/C++

8

Fortran9

double precision function omp_get_wtime()

Fortran1011

Binding

12
13

The binding thread set for an omp_get_wtime region is the encountering thread. The
routine’s return value is not guaranteed to be consistent across any set of threads.

14

Effect

15
16
17
18
19

The omp_get_wtime routine returns a value equal to the elapsed wall clock time inseconds since some “time in the past”. The actual “time in the past” is arbitrary, but it isguaranteed not to change during the execution of the application program. The times
returned are “per-thread times”, so they are not required to be globally consistent acrossall the threads participating in an application.

20

Chapter 3

Runtime Library Routines

109

1
2

Note – It is anticipated that the routine will be used to measure elapsed times as shownin the following example:

3

C/C++

4
5
6
7
8
9

double start;
double end;
start = omp_get_wtime();... work to be timed ...
end = omp_get_wtime();printf("Work took %f seconds\n", end - start);

10

C/C++

11

Fortran

12
13
14
15
16

DOUBLE PRECISION START, END
START = omp_get_wtime()... work to be timed ...
END = omp_get_wtime()
PRINT *, "Work took", END - START, "seconds"

Fortran

17

18

3.4.2

omp_get_wtick

19

Summary

20
21

The omp_get_wtick routine returns the precision of the timer used by
omp_get_wtime.

22

110

OpenMP API • Version 2.5 May 2005

1

FormatC/C++

2
3

double omp_get_wtick(void);

4

C/C++

5

Fortran6

double precision function omp_get_wtick()

Fortran78

Binding

910

The binding thread set for an omp_get_wtick region is the encountering thread. The
routine’s return value is not guaranteed to be consistent across any set of threads.

11

Effect12
13

The omp_get_wtick routine returns a value equal to the number of seconds between
successive clock ticks of the timer used by omp_get_wtime.

14

Chapter 3

Runtime Library Routines

111

1

112

OpenMP API • Version 2.5 May 2005

1

CHAPTER

4

2

Environment Variables

3
4
5
6
7
8
9
10
11

This chapter describes the OpenMP environment variables that specify the settings ofthe internal control variables that affect the execution of OpenMP programs (seeSection 2.3 on page 24). The names of the environment variables must be uppercase.
The values assigned to the environment variables are case insensitive and may haveleading and trailing white space. Modifications to the environment variables after the
program has started, even if modified by the program itself, are ignored by the OpenMP
implementation. However, the settings of the internal control variables can be modified
during the execution of the OpenMP program by the use of the appropriate directive
clauses or OpenMP API routines.

12

The environment variables are as follows:

13
14• OMP_SCHEDULE sets the run-sched-var internal control variable for the runtime

15
16• OMP_NUM_THREADS sets the nthreads-var internal control variable for the number

17
18• OMP_DYNAMIC sets the dyn-var internal control variable for the dynamic adjustment

19
20• OMP_NESTED sets the nest-var internal control variable to enable or disable nested

21
22
23

The examples in this chapter only demonstrate how these variables might be set in Unix
C shell (csh) environments. In Korn shell (ksh) and DOS environments the actions are
similar, as follows:24• csh:

25
26

27

28

schedule type and chunk size.
of threads to use for parallel regions.
of threads to use for parallel regions.
parallelism.

setenv OMP_SCHEDULE "dynamic"• ksh:

export OMP_SCHEDULE="dynamic"113

• DOS:1

set OMP_SCHEDULE="dynamic"

2

3

4.1

OMP_SCHEDULE

456The OMP_SCHEDULE environment variable controls the schedule type and chunk sizeof all loop directives that have the schedule type runtime, by setting the value of therun-sched-var internal control variable.

7

The value of this environment variable takes the form:

8

type[,chunk]

9

where

10

• type is one of static, dynamic or guided

11• chunk is an optional positive integer which specifies the chunk size

12
13

If chunk is present, there may be white space on either side of the “,”. See Section 2.5.1
on page 33 for a detailed description of the schedule types.

14
15

If OMP_SCHEDULE is not set, the initial value of the run-sched-var internal control
variable is implementation defined.

16

Example:setenv OMP_SCHEDULE "guided,4"setenv OMP_SCHEDULE "dynamic"

17
18

19

Cross References:

20• Internal control variables, see Section 2.3 on page 24.

21• Loop construct, see Section 2.5.1 on page 33.

22• Parallel loop construct, see Section 2.6.1 on page 47.

23

114

OpenMP API • Version 2.5 May 2005

1

4.2

OMP_NUM_THREADS

2
3
4
5
6

The OMP_NUM_THREADS environment variable sets the number of threads to use forparallel regions by setting the initial value of the nthreads-var internal control
variable. See Section 2.3 for a comprehensive set of rules about the interaction between
the OMP_NUM_THREADS environment variable, the num_threads clause, theomp_set_num_threads library routine and dynamic adjustment of threads.

7
8
9
10

The value of this environment variable must be a positive integer. The behavior of the
program is implementation defined if the requested value of OMP_NUM_THREADS isgreater than the number of threads an implementation can support, or if the value is nota positive integer.

11
12

If the OMP_NUM_THREADS environment variable is not set, the initial value of thenthreads-var internal control variable is implementation defined.

13
14
15
16
17

The nthreads-var internal control variable can be modified using the
omp_set_num_threads library routine. The number of threads in the current teamcan be queried using the omp_get_num_threads library routine. The maximum
number of threads in future teams can be queried using the omp_get_max_threads
library routine.

18

Example:19

setenv OMP_NUM_THREADS 16

20

Cross References:

21• Internal control variables, see Section 2.3 on page 24.

22• num_threads clause, Section 2.4 on page 26.

23• omp_set_num_threads routine, see Section 3.2.1 on page 91.

24• omp_get_num_threads routine, see Section 3.2.2 on page 93.

25• omp_get_max_threads routine, see Section 3.2.3 on page 94.

26• omp_get_dynamic routine, see Section 3.2.8 on page 99.

27

Chapter 4

Environment Variables

115

1

4.3

OMP_DYNAMIC

2
3
4
5
6
7
8

The OMP_DYNAMIC environment variable controls dynamic adjustment of the numberof threads to use for executing parallel regions by setting the initial value of thedyn-var internal control variable. The value of this environment variable must be trueor false. If the environment variable is set to true, the OpenMP implementation may
adjust the number of threads to use for executing parallel regions in order to
optimize the use of system resources. If the environment variable is set to false, thedynamic adjustment of the number of threads is disabled.

910

If the OMP_DYNAMIC environment variable is not set, the initial value of the dyn-var
internal control variable is implementation defined.

11
12
13

The dyn-var internal control variable can be modified by calling the
omp_set_dynamic library routine. The current value of dyn-var can be queried using
the omp_get_dynamic library routine.

14

Example:setenv OMP_DYNAMIC true

15

16

Cross References:

17• Internal control variables, see Section 2.3 on page 24.

18• omp_get_num_threads routine, see Section 3.2.2 on page 93.

19• omp_set_dynamic routine, see Section 3.2.7 on page 97.

20• omp_get_dynamic routine, see Section 3.2.8 on page 99.

21

4.4

OMP_NESTED

22
23
24
25

The OMP_NESTED environment variable controls nested parallelism by setting theinitial value of the nest-var internal control variable. The value of this environment
variable must be true or false. If the environment variable is set to true, nested
parallelism is enabled; if set to false, nested parallelism is disabled.

26
27

If the OMP_NESTED environment variable is not set, the initial value of the nest-var
internal control variable is false.

28

116

OpenMP API • Version 2.5 May 2005

1
2
3

The nest-var internal control variable can be modified by calling the
omp_set_nested library routine. The current value of nest-var can be queried using
the omp_get_nested library routine.

4

Example:5setenv OMP_NESTED false

6

Cross References:

7• Internal control variables, see Section 2.3 on page 24.

8• omp_set_nested routine, see Section 3.2.9 on page 100.

9Chapter 4

Environment Variables

117

1

118

OpenMP API • Version 2.5 May 2005

1

APPENDIXA

2

Examples3

The following are examples of the constructs and routines defined in this document.

4
5
6

A statement following a directive is compound only when necessary, and a noncompound statement is indented with respect to a directive preceding it.

C/C++

C/C++

7

8
9
10
11

A.1

A Simple Parallel Loop
The following example demonstrates how to parallelize a simple loop using the parallel
loop construct (Section 2.6.1 on page 47). The loop iteration variable is private by
default, so it is not necessary to specify it explicitly in a private clause.

C/C++

12
13

Example A.1.1c

14
15
16

void a1(int n, float *a, float *b){
int i;

17
18
19
20

#pragma omp parallel forfor (i=1; i<n; i++) /* i is private by default */b[i] = (a[i] + a[i-1]) / 2.0;
}

21

C/C++

22

Fortran

23
24

25

Example A.1.1f
SUBROUTINE A1(N, A, B)

119

1
2

INTEGER I, N
REAL B(N), A(N)

3
4
5
6
7

!$OMP PARALLEL DO !I is private by default
DO I=2,N
B(I) = (A(I) + A(I-1)) / 2.0
ENDDO!$OMP END PARALLEL DO

8

END SUBROUTINE A1

Fortran

9

10

A.2

The OpenMP Memory Model

11
12
13
14
15
16

In the following example, at Print 1, the value of x could be either 2 or 5, depending on
the timing of the threads, and the implementation of the assignment to x. There are two
reasons that the value at Print 1 might not be 5. First, Print 1 might be executed before
the assignment to x is executed. Second, even if Print 1 is executed after the assignment,
the value 5 is not guaranteed to be seen by thread 1 because a flush may not have been
executed by thread 0 since the assignment.

17
18
19

The barrier after Print 1 contains implicit flushes on all threads, as well as a threadsynchronization, so the programmer is guaranteed that the value 5 will be printed byboth Print 2 and Print 3.

C/C++

20
21

Example A.2.1c

22
23#include <stdio.h>#include <omp.h>

24
25

int main(){int x;

26
27
28

x = 2;#pragma omp parallel num_threads(2) shared(x)
{

29
30
31
32
33
34

35

if (omp_get_thread_num() == 0) {x = 5;} else {/* Print 1: the following read of x has a race */printf("1: Thread# %d: x = %d\n", omp_get_thread_num(),x );}120

OpenMP API • Version 2.5 May 2005

1

#pragma omp barrier

2
3
4
5
6
7
8
9
10
11

if (omp_get_thread_num() == 0) {/* Print 2 */printf("2: Thread# %d: x = %d\n", omp_get_thread_num(),x );} else {/* Print 3 */printf("3: Thread# %d: x = %d\n", omp_get_thread_num(),x );}}return 0;
}

12

C/C++

13

Fortran

14

Example A.2.1f

15
16
17

PROGRAM A2INCLUDE "omp_lib.h"
INTEGER X

18
19

X = 2
!$OMP PARALLEL NUM_THREADS(2) SHARED(X)

20
21
22
23
24
25
26
27
28
29
30
31
32
33

IF (OMP_GET_THREAD_NUM() .EQ. 0) THEN
X = 5
ELSE
! PRINT 1: The following read of x has a race
PRINT *,"1: THREAD# ", OMP_GET_THREAD_NUM(), "X = ", X
ENDIF!$OMP BARRIER
IF (OMP_GET_THREAD_NUM() .EQ. 0) THEN
! PRINT 2
PRINT *,"2: THREAD# ", OMP_GET_THREAD_NUM(), "X = ", XELSE
! PRINT 3
PRINT *,"3: THREAD# ", OMP_GET_THREAD_NUM(), "X = ", X
ENDIF

34

!$OMP END PARALLEL35

END PROGRAM A2

36

37! or USE OMP_LIB

FortranAppendix A

Examples

121

1

A.3

Conditional Compilation
C/C++

2
3
4
5

The following example illustrates the use of conditional compilation using the OpenMP
macro _OPENMP (Section 2.2 on page 21). With OpenMP compilation, the _OPENMP
macro becomes defined.

6

Example A.3.1c

7#include <stdio.h>

89

int main()
{

10
11
12

# ifdef _OPENMP
printf("Compiled by an OpenMP-compliant implementation.\n");# endif13
14}

return 0;

C/C++

15
16

Fortran

17
18
19
20

The following example illustrates the use of the conditional compilation sentinel (seeSection 2.2 on page 21). With OpenMP compilation, the conditional compilation
sentinel !$ is recognized and treated as two spaces. In fixed form source, statements
guarded by the sentinel must start after column 6.

21

Example A.3.1f

22

PROGRAM A3

23
24

C234567890!$
PRINT *, "Compiled by an OpenMP-compliant implementation."

25

END PROGRAM A3

Fortran

26

27

122

OpenMP API • Version 2.5 May 2005

1
2
3
4

A.4

The parallel Construct
The parallel construct (Section 2.4 on page 26) can be used in coarse-grain parallel
programs. In the following example, each thread in the parallel region decides whatpart of the global array x to work on, based on the thread number:

C/C++

5
6

Example A.4.1c

7#include <omp.h>8910void subdomain(float *x, int istart, int ipoints){
int i;

11
12
13

}

14
15
16

void sub(float *x, int npoints){
int iam, nt, ipoints, istart;

17
18
19
20
21
22
23
24
25
26
27

#pragma omp parallel default(shared) private(iam,nt,ipoints,istart){
iam = omp_get_thread_num();nt = omp_get_num_threads();
ipoints = npoints / nt;/* size of partition */istart = iam * ipoints; /* starting array index */if (iam == nt-1)/* last thread may do more */ipoints = npoints - istart;
subdomain(x, istart, ipoints);
}
}

28
29
30

int main(){float array[10000];31

sub(array, 10000);

32
33
34

35

for (i = 0; i < ipoints; i++)x[istart+i] = 123.456;

return 0;}

C/C++

Appendix A

Examples123Fortran

1

Example A.4.1f

2
3
4
5

SUBROUTINE SUBDOMAIN(X, ISTART, IPOINTS)
INTEGER ISTART, IPOINTSREAL X(*)

6

INTEGER I

7
8
9

DO 100 I=1,IPOINTS
X(ISTART+I) = 123.456
CONTINUE

100

10

END SUBROUTINE SUBDOMAIN

11
12

SUBROUTINE SUB(X, NPOINTS)
INCLUDE "omp_lib.h"! or USE OMP_LIB

13
14

REAL X(*)
INTEGER NPOINTS15

INTEGER IAM, NT, IPOINTS, ISTART!$OMP PARALLEL DEFAULT(PRIVATE) SHARED(X,NPOINTS)

16

IAM = OMP_GET_THREAD_NUM()
NT = OMP_GET_NUM_THREADS()IPOINTS = NPOINTS/NTISTART = IAM * IPOINTSIF (IAM .EQ. NT-1) THEN
IPOINTS = NPOINTS - ISTARTENDIFCALL SUBDOMAIN(X,ISTART,IPOINTS)

17
18
19
20
21
22
23
24

!$OMP END PARALLEL

25
26

END SUBROUTINE SUB

27

PROGRAM A4

28

REAL ARRAY(10000)

29

CALL SUB(ARRAY, 10000)

30

END PROGRAM A4

Fortran

31

32

124

OpenMP API • Version 2.5 May 2005

1

A.5

The num_threads Clause
The following example demonstrates the num_threads clause (Section 2.4 on page26). The parallel region is executed with a maximum of 10 threads.

2
3

C/C++

4
5

Example A.5.1c

6
7
8
9

#include <omp.h>
int main(){
omp_set_dynamic(1);

10
11
12
13
14
15

#pragma omp parallel num_threads(10){/* do work here */}return 0;
}

16

C/C++

17

Fortran

Example A.5.1f

18
19
20
21

PROGRAM A5INCLUDE "omp_lib.h"! or USE OMP_LIB
CALL OMP_SET_DYNAMIC(.TRUE.)

22
23
24
25

!$OMP

PARALLEL NUM_THREADS(10)! do work here!$OMP
END PARALLEL
END PROGRAM A5

26

Fortran27

Fortran

28
29
30
31
32

33

A.6

Fortran Restrictions on the do Construct
If an end do directive follows a do-construct in which several DO statements share a
DO termination statement, then a do directive can only be specified for the first (i.e.
outermost) of these DO statements. For more information, see Section 2.5.1 on page 33.
The following example contains correct usages of loop constructs:

Appendix A

Examples125Fortran (cont.)

1

Example A.6.1f

2
3
4
5

SUBROUTINE WORK(I, J)
INTEGER I,J
END SUBROUTINE WORK

67
8

SUBROUTINE A6_GOOD()INTEGER I, J
REAL A(1000)

9
10
11
12
13

!$OMP

100

DO 100 I = 1,10
DO
DO 100 J = 1,10
CALL WORK(I,J)
CONTINUE! !$OMP ENDDO implied here

14
15
16
17

!$OMP

18
19
20
21
22
23
24

!$OMP

25
26

The following example is non-conforming because the matching do directive for theend do does not precede the outermost loop:

27

Example A.6.2f

200
!$OMP

DO
DO 200 J = 1,10
A(I) = I + 1
ENDDO

DO
DO 300 I = 1,10
DO 300 J = 1,10
CALL WORK(I,J)
300
CONTINUE
!$OMP
ENDDO
END SUBROUTINE A6_GOOD

28
29
30

SUBROUTINE WORK(I, J)
INTEGER I,J
END SUBROUTINE WORK

31
32

SUBROUTINE A6_WRONG
INTEGER I, J

33
34
35
36
37

38

!$OMP

100

126

DO 100 I = 1,10
DO
DO 100 J = 1,10
CALL WORK(I,J)
CONTINUE

OpenMP API • Version 2.5 May 2005

1
2

!$OMP

ENDDO
END SUBROUTINE A6_WRONG

3

Fortran4

Fortran5

A.7

Fortran Private Loop Iteration Variables

6
7
8
9

In general loop iteration variables will be private, when used in the do-loop of a do andparallel do construct or in sequential loops in a parallel construct (seeSection 2.5.1 on page 33 and Section 2.8.1 on page 63). In the following example of asequential loop in a parallel construct the loop iteration variable I will be private.

10

Example A.7.1f

11
12

SUBROUTINE A7_1(A,N)
INCLUDE "omp_lib.h"

13
14

REAL A(*)
INTEGER I, MYOFFSET, N

15
16
17
18
19
20

!$OMP PARALLEL PRIVATE(MYOFFSET)MYOFFSET = OMP_GET_THREAD_NUM()*N
DO I = 1, N
A(MYOFFSET+I) = FLOAT(I)ENDDO!$OMP END PARALLEL

21

END SUBROUTINE A7_1

2223

In exceptional cases, loop iteration variables can be made shared, as in the following
example:24

Example A.7.2f

25
26
27

SUBROUTINE A7_2(A,B,N,I1,I2)
REAL A(*), B(*)
INTEGER I1, I2, N

28
29
30
31

!$OMP PARALLEL SHARED(A,B,I1,I2)!$OMP SECTIONS!$OMP SECTION
DO I1 = I1, N

32! or USE OMP_LIB

Appendix A

Examples

127

1
2
3
4
5
6
7
8
9
10
11
12

IF (A(I1).NE.0.0) EXIT
ENDDO!$OMP SECTION
DO I2 = I2, N
IF (B(I2).NE.0.0) EXIT
ENDDO!$OMP END SECTIONS!$OMP SINGLE
IF (I1.LE.N) PRINT *, ’ITEMS IN A UP TO ’, I1, ’ ARE ALL ZERO.’
IF (I2.LE.N) PRINT *, ’ITEMS IN B UP TO ’, I2, ’ ARE ALL ZERO.’!$OMP END SINGLE!$OMP END PARALLEL

13

END SUBROUTINE A7_2

1415

Note however that the use of shared loop iteration variables can easily lead to race
conditions.

Fortran

16

17

A.8

The nowait clause
If there are multiple independent loops within a parallel region, you can use the
nowait clause (see Section 2.5.1 on page 33) to avoid the implied barrier at the end of
the loop construct, as follows:

18
19
20

C/C++

21
22

Example A.8.1c

23#include <math.h>

24
25
26
27
28
29
30
31

void a8(int n, int m, float *a, float *b, float *y, float *z){
int i;#pragma omp parallel{#pragma omp for nowaitfor (i=1; i<n; i++)b[i] = (a[i] + a[i-1]) / 2.0;

32
33
34
35
36

#pragma omp for nowaitfor (i=0; i<m; i++)y[i] = sqrt(z[i]);
}
}

C/C++

37

38

128

OpenMP API • Version 2.5 May 2005

Fortran

1

Example A.8.1f

2
3

SUBROUTINE A8(N, M, A, B, Y, Z)

4
5

INTEGER N, M
REAL A(*), B(*), Y(*), Z(*)

6

INTEGER I

7!$OMP PARALLEL

8
9
10
11
12

!$OMP DO

13
14
15
16
17

!$OMP DO

18!$OMP END PARALLEL

DO I=2,N
B(I) = (A(I) + A(I-1)) / 2.0
ENDDO!$OMP END DO NOWAIT

DO I=1,M
Y(I) = SQRT(Z(I))
ENDDO!$OMP END DO NOWAIT

19

END SUBROUTINE A8

Fortran

20

21
22
23
24

A.9

The parallel sections Construct
In the following example (for Section 2.5.2 on page 39) routines xaxis, yaxis, and zaxis
can be executed concurrently. The first section directive is optional. Note that all
section directives need to appear in the parallel sections construct.

C/C++

25
26

Example A.9.1c

27
28
29

void XAXIS();
void YAXIS();
void ZAXIS();3031void a9(){32

Appendix A

Examples

129

1
2
3
4

#pragma omp parallel sections{#pragma omp section
XAXIS();

5
6#pragma omp section
YAXIS();

78
9
10#pragma omp section
ZAXIS();
}
}

11

C/C++

12

Fortran

Example A.9.1f

13
14

SUBROUTINE A9()

15
16
17

!$OMP PARALLEL SECTIONS!$OMP SECTIONCALL XAXIS()

18
19!$OMP SECTIONCALL YAXIS()

20
21!$OMP SECTIONCALL ZAXIS()

22!$OMP END PARALLEL SECTIONS

23

END SUBROUTINE A9

Fortran

24

25

A.10

The following example demonstrates the single construct (Section 2.5.3 on page 42).
In the example, only one thread prints each of the progress messages. All other threads
will skip the single region and stop at the barrier at the end of the single construct
until all threads in the team have reached the barrier. If other threads can proceedwithout waiting for the thread executing the single region, a nowait clause can be
specified, as is done in the third single construct in this example. The user must not
make any assumptions as to which thread will execute a single region.

26
27
28
29
30
31
32

33

The single Construct

130

OpenMP API • Version 2.5 May 2005

C/C++

1
2

Example A.10.1c

3#include <stdio.h>

45void work1() {}void work2() {}

6
7
8
9
10
11

void a10(){#pragma omp parallel{#pragma omp single
printf("Beginning work1.\n");12

work1();

13
14#pragma omp single
printf("Finishing work1.\n");15
16#pragma omp single nowait
printf("Finished work1 and beginning work2.\n");

17
18
19

work2();
}
}

20

C/C++

21

Fortran

22

Example A.10.1f

23
24

SUBROUTINE WORK1()END SUBROUTINE WORK1

25
26

SUBROUTINE WORK2()END SUBROUTINE WORK2

27
28

PROGRAM A10!$OMP PARALLEL

29
30
31

!$OMP SINGLE
print *, "Beginning work1."!$OMP END SINGLE

32
33
34
35

36

CALL WORK1()!$OMP SINGLE
print *, "Finishing work1."!$OMP END SINGLE

Appendix A

Examples

131

1
2
3

!$OMP SINGLE
print *, "Finished work1 and beginning work2."!$OMP END SINGLE NOWAIT

4CALL WORK2()

5!$OMP END PARALLEL

6

END PROGRAM A10

7

Fortran8

Fortran

9

A.11

The workshare Construct

10
11

The following are examples of the workshare construct (see Section 2.5.4 on page
44).

12
13
14

In the following example, workshare spreads work across the threads executing theparallel region, and there is a barrier after the last statement. Implementations must
enforce Fortran execution rules inside of the workshare block.

15

Example A.11.1f

16
17
18

SUBROUTINE A11_1(AA, BB, CC, DD, EE, FF, N)
INTEGER N
REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N), EE(N,N), FF(N,N)

19
20
21
22
23
24
25

!$OMP
!$OMP

!$OMP
!$OMP

26

END SUBROUTINE A11_1

In the following example, the barrier at the end of the first workshare region iseliminated with a nowait clause. Threads doing CC = DD immediately begin work on
EE = FF when they are done with CC = DD.

27
28
29

30

PARALLEL
WORKSHARE
AA = BB
CC = DD
EE = FF
END WORKSHAREEND PARALLEL

132

OpenMP API • Version 2.5 May 2005

Fortran (cont.)

1
2

Example A.11.2f

3
4
5
6

SUBROUTINE A11_2(AA, BB, CC, DD, EE, FF, N)
INTEGER N
REAL AA(N,N), BB(N,N), CC(N,N)
REAL DD(N,N), EE(N,N), FF(N,N)

7
8
9
10
11
12
13
14
15
16

!$OMP
!$OMP

17
18

The following example shows the use of an atomic directive inside a workshareconstruct. The computation of SUM(AA) is workshared, but the update to I is atomic.

19

Example A.11.3f

PARALLEL
WORKSHARE
AA = BB
CC = DD!$OMP
END WORKSHARE NOWAIT!$OMPWORKSHARE
EE = FF!$OMP
END WORKSHARE!$OMP
END PARALLELEND SUBROUTINE A11_2

20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37

38

SUBROUTINE A11_3(AA, BB, CC, DD, N)
INTEGER N
REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N)
REAL R

!$OMP
!$OMP
!$OMP

!$OMP
!$OMP

R=0
PARALLEL
WORKSHARE
AA = BBATOMICR = R + SUM(AA)CC = DD
END WORKSHAREEND PARALLELEND SUBROUTINE A11_3

Fortran WHERE and FORALL statements are compound statements, made up of a control
part and a statement part. When workshare is applied to one of these compoundstatements, both the control and the statement parts are workshared. The following
example shows the use of a WHERE statement in a workshare construct.
Appendix A

Examples133Fortran (cont.)

1
2

Each task gets worked on in order by the threads:

3

AA = BB then4

CC = DD then5

EE .ne. 0 then6

FF = 1 / EE then7

GG = HH

8

Example A.11.4f

9
10
11
12
13

SUBROUTINE A11_4(AA, BB, CC, DD, EE, FF, GG, HH, N)
INTEGER N
REAL AA(N,N), BB(N,N), CC(N,N)
REAL DD(N,N), EE(N,N), FF(N,N)
REAL GG(N,N), HH(N,N)

14
15
16
17
18
19
20
21

!$OMP
!$OMP

!$OMP
!$OMP

22

PARALLEL
WORKSHARE
AA = BB
CC = DD
WHERE (EE .ne. 0) FF = 1 / EE
GG = HH
END WORKSHAREEND PARALLELEND SUBROUTINE A11_4

23
24

In the following example, an assignment to a shared scalar variable is performed by one
thread in a workshare while all other threads in the team wait.

25

Example A.11.5f

26
27
28

SUBROUTINE A11_5(AA, BB, CC, DD, N)
INTEGER N
REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N)

29

INTEGER SHR

30
31
32
33
34

35

!$OMP
!$OMP

134

PARALLEL SHARED(SHR)
WORKSHARE
AA = BBSHR = 1CC = DD * SHROpenMP API • Version 2.5 May 2005

Fortran (cont.)

1
2
3

!$OMP
!$OMP

4

END WORKSHAREEND PARALLELEND SUBROUTINE A11_5

5
6
7
8

The following example contains an assignment to a private scalar variable, which is
performed by one thread in a workshare while all other threads wait. It is nonconforming because the private scalar variable is undefined after the assignment
statement.

9

Example A.11.6f

10
11
12

SUBROUTINE A11_6_WRONG(AA, BB, CC, DD, N)
INTEGER N
REAL AA(N,N), BB(N,N), CC(N,N), DD(N,N)

13
14
15
16
17
18
19
20

INTEGER PRI
!$OMP
!$OMP

!$OMP
!$OMP

21

PARALLEL PRIVATE(PRI)
WORKSHARE
AA = BB
PRI = 1CC = DD * PRI
END WORKSHAREEND PARALLELEND SUBROUTINE A11_6_WRONG

22
23
24
25

Fortran execution rules must be enforced inside a workshare construct. In thefollowing example, the same result is produced in the following program fragment
regardless of whether the code is executed sequentially or inside an OpenMP programwith multiple threads:

26

Example A.11.7f

27
28
29
30
31
32
33

34

SUBROUTINE A11_7(AA, BB, CC, N)
INTEGER N
REAL AA(N), BB(N), CC(N)
!$OMP
!$OMP

PARALLEL
WORKSHARE
AA(1:50) = BB(11:60)
CC(11:20) = AA(1:10)

Appendix A

Examples

135

1
2

!$OMP
!$OMP

3

END WORKSHAREEND PARALLELEND SUBROUTINE A11_7

Fortran

4

5

A.12

The master Construct
The following example demonstrates the master construct (Section 2.7.1 on page 51). In
the example, the master keeps track of how many iterations have been executed andprints out a progress report. The other threads skip the master region without waiting.

6
7
8

C/C++

9
10

Example A.12.1c

11#include <stdio.h>12extern float average(float,float,float);

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

void a12( float* x, float* xold, int n, float tol ){int c, i, toobig;
float error, y;c = 0;#pragma omp parallel{do{#pragma omp for private(i)for( i = 1; i < n-1; ++i ){xold[i] = x[i];}#pragma omp single{
toobig = 0;}
#pragma omp for private(i,y,error) reduction(+:toobig)for( i = 1; i < n-1; ++i ){y = x[i];x[i] = average( xold[i-1], x[i], xold[i+1] );error = y - x[i];if( error > tol || error < -tol ) ++toobig;}#pragma omp master{++c;printf( "iteration %d, toobig=%d\n", c, toobig );

40

136

OpenMP API • Version 2.5 May 2005

1
2
3
4

}
}while( toobig > 0 );
}
}

5

C/C++

6

Fortran

7

Example A.12.1f

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

SUBROUTINE A12( X, XOLD, N, TOL )REAL X(*), XOLD(*), TOL
INTEGER NINTEGER C, I, TOOBIGREAL ERROR, Y, AVERAGE
EXTERNAL AVERAGE
C = 0
TOOBIG = 1!$OMP PARALLEL
DO WHILE( TOOBIG > 0 )!$OMPDO PRIVATE(I)DO I = 2, N-1
XOLD(I) = X(I)
ENDDO
!$OMP
SINGLETOOBIG = 0!$OMP
END SINGLE!$OMPDO PRIVATE(I,Y,ERROR), REDUCTION(+:TOOBIG)
DO I = 2, N-1
Y = X(I)
X(I) = AVERAGE( XOLD(I-1), X(I), XOLD(I+1) )ERROR = Y-X(I)IF( ERROR > TOL .OR. ERROR < -TOL ) TOOBIG = TOOBIG+1
ENDDO
!$OMP
MASTERC = C + 1
PRINT *, ’Iteration ’, C, ’ TOOBIG=’, TOOBIG!$OMPEND MASTERENDDO!$OMP END PARALLELEND SUBROUTINE A12

39

Fortran

40

Appendix A

Examples

137

1

A.13

The critical Construct
The following example includes several critical constructs (Section 2.7.2 on page52). The example illustrates a queuing model in which a task is dequeued and worked
on. To guard against multiple threads dequeuing the same task, the dequeuing operationmust be in a critical region. Because the two queues in this example are
independent, they are protected by critical constructs with different names, xaxis
and yaxis.

2
3
4
5
6
7

C/C++

8
9

Example A.13.1c

10
11

int dequeue(float *a);void work(int i, float *a);

12
13
14

void a13(float *x, float *y){
int ix_next, iy_next;

15
16
17
18
19

#pragma omp parallel shared(x, y) private(ix_next, iy_next){#pragma omp critical (xaxis)
ix_next = dequeue(x);work(ix_next, x);

20
21
22
23

#pragma omp critical (yaxis)
iy_next = dequeue(y);work(iy_next, y);
}

24

}

25

C/C++

26

Fortran

Example A.13.1f

27
28

SUBROUTINE A13(X, Y)

29
30

REAL X(*), Y(*)
INTEGER IX_NEXT, IY_NEXT

31!$OMP PARALLEL SHARED(X, Y) PRIVATE(IX_NEXT, IY_NEXT)

32
33
34
35

!$OMP CRITICAL(XAXIS)CALL DEQUEUE(IX_NEXT, X)!$OMP END CRITICAL(XAXIS)CALL WORK(IX_NEXT, X)

36

138

OpenMP API • Version 2.5 May 2005

1
2
3
4

!$OMP CRITICAL(YAXIS)CALL DEQUEUE(IY_NEXT,Y)!$OMP END CRITICAL(YAXIS)CALL WORK(IY_NEXT, Y)

5!$OMP END PARALLEL

6

END SUBROUTINE A13

Fortran79Work-Sharing Constructs Inside a
critical Construct

10
11
12
13

The following example demonstrates using a work-sharing construct inside a
critical construct (see Section 2.7.2 on page 52). This example is conforming
because the single region and the critical region are not closely nested (seeSection 2.9 on page 87).

8

A.14

C/C++

14
15

Example A.14.1c

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

void a14(){
int i = 1;
#pragma omp parallel sections{#pragma omp section{#pragma omp critical (name){#pragma omp parallel{#pragma omp single
{
i++;
}
}
}
}
}
}

36

37

C/C++

Appendix A

Examples139Fortran

1

Example A.14.1f

2
3

SUBROUTINE A14()

4
5

INTEGER I
I = 1

6
7
8
9
10
11
12
13
14
15
16

!$OMP
!$OMP
!$OMP
!$OMP
!$OMP

PARALLEL SECTIONSSECTIONCRITICAL (NAME)PARALLELSINGLEI = I + 1!$OMP
END SINGLE!$OMPEND PARALLEL!$OMPEND CRITICAL (NAME)!$OMP
END PARALLEL SECTIONSEND SUBROUTINE A14

Fortran

17

18

A.15

Binding of barrier Regions

19
20

The binding rules call for a barrier region to bind to the closest enclosing
parallel region (see Section 2.7.3 on page 54).

21
22
23
24

In the following example, the call from the main program to sub2 is conforming because
the barrier region (in sub3) binds to the parallel region in sub2. The call fromthe main program to sub1 is conforming because the barrier region binds to theparallel region in subroutine sub2.

25
26
27
28

The call from the main program to sub3 is conforming because the barrier region
binds to the implicit inactive parallel region enclosing the sequential part. Also notethat the barrier region in sub3 when called from sub2 only synchronizes the team of
threads in the enclosing parallel region and not all the threads created in sub1.

C/C++

29
30

Example A.15.1c31void work(int n) {}

32
33
34
35

void sub3(int n){work(n);#pragma omp barrier

36

140

OpenMP API • Version 2.5 May 2005

1
2

}

3
4
5
6
7

void sub2(int k){#pragma omp parallel shared(k)sub3(k);
}

8
9
10
11
12
13
14
15
16
17

void sub1(int n){
int i;#pragma omp parallel private(i) shared(n){#pragma omp forfor (i=0; i<n; i++)sub2(i);
}
}

18
19
20
21
22
23
24

int main(){sub1(2);sub2(2);sub3(2);
return 0;}work(n);

25

C/C++

26

Fortran

27

Example A.15.1f

28
29
30

SUBROUTINE WORK(N)INTEGER N
END SUBROUTINE WORK

31
32
33
34
35
36

SUBROUTINE SUB3(N)INTEGER N
CALL WORK(N)!$OMPBARRIERCALL WORK(N)END SUBROUTINE SUB3

37
38
39
40
41
42

SUBROUTINE SUB2(K)INTEGER K!$OMPPARALLEL SHARED(K)CALL SUB3(K)!$OMP
END PARALLELEND SUBROUTINE SUB2

43

Appendix A

Examples

141

1
2
3
4
5
6
7
8
9
10

SUBROUTINE SUB1(N)INTEGER NINTEGER I!$OMPPARALLEL PRIVATE(I) SHARED(N)!$OMP
DO
DO I = 1, N
CALL SUB2(I)END DO!$OMP
END PARALLELEND SUBROUTINE SUB1

11
12
13
14
15

PROGRAM A15
CALL SUB1(2)CALL SUB2(2)CALL SUB3(2)END PROGRAM A15

Fortran

16

17

A.16

The atomic Construct

18
19

The following example avoids race conditions (simultaneous updates of an element of x
by multiple threads) by using the atomic construct (Section 2.7.4 on page 55).

20
21
22
23

The advantage of using the atomic construct in this example is that it allows updatesof two different elements of x to occur in parallel. If a critical construct (seeSection 2.7.2 on page 52) were used instead, then all updates to elements of x would beexecuted serially (though not in any guaranteed order).

24
25

Note that the atomic directive applies only to the statement immediately following it.
As a result, elements of y are not updated atomically in this example.

C/C++

26
27

Example A.16.1c

28
29
30
31

float work1(int i){
return 1.0 * i;
}

32
33
34
35

float work2(int i){
return 2.0 * i;
}

36

142

OpenMP API • Version 2.5 May 2005

1
2
3

void a16(float *x, float *y, int *index, int n){
int i;

4
5
6
7
8
9
10

}

11
12
13
14
15
16

int main(){float x[1000];
float y[10000];
int index[10000];
int i;#pragma omp parallel for shared(x, y, index, n)for (i=0; i<n; i++) {#pragma omp atomic
x[index[i]] += work1(i);y[i] += work2(i);
}

17
18
19
20

for (i = 0; i < 10000; i++) {index[i] = i % 1000;y[i]=0.0;}21
22

for (i = 0; i < 1000; i++)x[i] = 0.0;

23
24
25

a16(x, y, index, 10000);
return 0;
}

26

C/C++

27

Fortran

28

Example A.16.1f

29
30
31
32
33

REAL FUNCTION WORK1(I)INTEGER IWORK1 = 1.0 * I
RETURNEND FUNCTION WORK1

34
35
36
37
38

REAL FUNCTION WORK2(I)INTEGER IWORK2 = 2.0 * I
RETURNEND FUNCTION WORK2

39
40

SUBROUTINE SUBA16(X, Y, INDEX, N)
REAL X(*), Y(*)

41

Appendix A

Examples143

1

INTEGER INDEX(*), N

2

INTEGER I

3
4
5
6
7
8

!$OMP
!$OMP

PARALLEL DO SHARED(X, Y, INDEX, N)
DO I=1,N
ATOMIC
X(INDEX(I)) = X(INDEX(I)) + WORK1(I)Y(I) = Y(I) + WORK2(I)
ENDDO

9

END SUBROUTINE SUBA16

10
11
12
13

PROGRAM A16
REAL X(1000), Y(10000)
INTEGER INDEX(10000)
INTEGER I

14
15
16
17

DO I=1,10000
INDEX(I) = MOD(I, 1000) + 1
Y(I) = 0.0
ENDDO

18
19
20

DO I = 1,1000
X(I) = 0.0
ENDDO

21

CALL SUBA16(X, Y, INDEX, 10000)

22

END PROGRAM A16

Fortran

23

24

A.17

Restrictions on the atomic Construct

25
26

The following examples illustrate the restrictions on the atomic construct. For more
information, see Section 2.7.4 on page 55.

27
28
29
30

All atomic references to the storage location of each variable that appears on the lefthand side of an atomic assignment statement throughout the program are required tohave a compatible type.

31

C/C++

32

C/C++

144

OpenMP API • Version 2.5 May 2005

1

Fortran2
3
4

All atomic references to the storage location of each variable that appears on the lefthand side of an atomic assignment statement throughout the program are required tohave the same type and type parameters.

5

Fortran

6

The following are some non-conforming examples:

C/C++

7
8

Example A.17.1c

9
10
11

void a17_1_wrong (){union {int n; float x;} u;

12
13
14
15

#pragma omp parallel{#pragma omp atomic
u.n++;

16
17#pragma omp atomic
u.x += 1.0;

18
19
20
21

/* Incorrect because the atomic constructs reference the same location
through incompatible types */
}
}

22

C/C++

23

Fortran

24

Example A.17.1f

25
26
27
28
29
30
31
32
33
34
35
36

37

SUBROUTINE A17_1_WRONG()
INTEGER:: I
REAL:: R
EQUIVALENCE(I,R)
!$OMP
!$OMP

PARALLELATOMICI = I + 1!$OMP
ATOMICR = R + 1.0! incorrect because I and R reference the same location! but have different types!$OMP
END PARALLEL

Appendix A

Examples145

1

END SUBROUTINE A17_1_WRONG

Fortran

2

C/C++

3
4

Example A.17.2c

5
6
7
8
9

void a17_2_wrong (){int x;
int *i;
float
*r;

10
11

i = &x;r = (float *)&x;

12
13
14
15

#pragma omp parallel{#pragma omp atomic*i += 1;16
17

#pragma omp atomic*r += 1.0;

18
19/* Incorrect because the atomic constructs reference the same location
through incompatible types */

20
21

}

}

22

C/C++

23

Fortran

24
25

The following example is non-conforming because I and R reference the same location
but have different types.

26

Example A.17.2f

27
28
29

SUBROUTINE SUB()COMMON /BLK/ R
REAL R

30
31
32

!$OMP

33
34
35

36

ATOMICR = R + 1.0
END SUBROUTINE SUBSUBROUTINE A17_2_WRONG()
COMMON /BLK/ I
INTEGER I

146

OpenMP API • Version 2.5 May 2005

1

!$OMP

2
3
4
5
6

!$OMP

7
8

Although the following example might work on some implementations, this is also nonconforming:

9

Example A.17.3f

PARALLELATOMICI = I + 1
CALL SUB()!$OMP
END PARALLELEND SUBROUTINE A17_2_WRONG

10
11
12
13

SUBROUTINE A17_3_WRONG
INTEGER:: I
REAL:: R
EQUIVALENCE(I,R)

14
15
16
17
18
19

!$OMP
!$OMP

20
21
22
23
24
25

!$OMP
!$OMP

PARALLELATOMICI = I + 1
! incorrect because I and R reference the same location! but have different types!$OMP
END PARALLELPARALLELATOMICR = R + 1.0! incorrect because I and R reference the same location! but have different types!$OMP
END PARALLEL

26

END SUBROUTINE A17_3_WRONG

Fortran

27

28
29
30

A.18

The flush Construct with a List
The following example uses the flush construct (see Section 2.7.5 on page 58) for
point-to-point synchronization of specific objects between pairs of threads:

C/C++

31
32

Example A.18.1c

33#include <omp.h>34

Appendix A

Examples147C/C++ (cont.)

1
2#define NUMBER_OF_THREADS 256

3
4
5

int
synch[NUMBER_OF_THREADS];
float work[NUMBER_OF_THREADS];
float result[NUMBER_OF_THREADS];

6
7
8
9

float fn1(int i){
return i*2.0;
}

10
11
12
13

float fn2(float a, float b){
return a + b;
}

14
15
16

int main(){
int iam, neighbor;

17
18
19
20

#pragma omp parallel private(iam,neighbor) shared(work,synch){iam = omp_get_thread_num();
synch[iam] = 0;

21
22
23

#pragma omp barrier/*Do computation into my portion of work array */work[iam] = fn1(iam);

24
25
26
27

/* Announce that I am done with my work. The first flush* ensures that my work is made visible before synch.
* The second flush ensures that synch is made visible.
*/

28
29
30

#pragma omp flush(work,synch)
synch[iam] = 1;
#pragma omp flush(synch)

31
32
33
34
35

/* Wait for neighbor. The first flush ensures that synch is read* from memory, rather than from the temporary view of memory.
* The second flush ensures that work is read from memory, and* is done so after the while loop exits.
*/

36
37
38

neighbor = (iam>0 ? iam : omp_get_num_threads()) - 1;
while (synch[neighbor] == 0) {#pragma omp flush(synch)

39

148

OpenMP API • Version 2.5 May 2005

1

}

2

#pragma omp flush(work,synch)

3
45/* Read neighbor’s values of work array */result[iam] = fn2(work[neighbor], work[iam]);}6/* output result here */7
8

return 0;
}

9

C/C++

10

Fortran

11

Example A.18.1f

12
13
14
15
16

REAL FUNCTION FN1(I)INTEGER I
FN1 = I * 2.0
RETURNEND FUNCTION FN1

17
18
19
20
21

REAL FUNCTION FN2(A, B)
REAL A, B
FN2 = A + B
RETURNEND FUNCTION FN2

22PROGRAM A18

23
24
25
26

INCLUDE "omp_lib.h"
INTEGER ISYNC(256)REAL
WORK(256)REAL
RESULT(256)27

INTEGER IAM, NEIGHBOR

28
29
30

!$OMP

31

!$OMP BARRIER

32

C

35

PARALLEL PRIVATE(IAM, NEIGHBOR) SHARED(WORK, ISYNC)
IAM = OMP_GET_THREAD_NUM() + 1
ISYNC(IAM) = 0

Do computation into my portion of work array
WORK(IAM) = FN1(IAM)

33
34! or USE OMP_LIB

CAnnounce that I am done with my work.

Appendix A

Examples

149

1
2

C
C

The first flush ensures that my work is made visible before
synch. The second flush ensures that synch is made visible.

3
4
5

!$OMP
!$OMP

FLUSH(WORK,ISYNC)
ISYNC(IAM) = 1
FLUSH(ISYNC)

6
7
8
9

C
C
C
C

Wait until neighbor is done. The first flush ensures thatsynch is read from memory, rather than from the temporary
view of memory. The second flush ensures that work is readfrom memory, and is done so after the while loop exits.

10
11
12
13
14

IF (IAM .EQ. 1) THENNEIGHBOR = OMP_GET_NUM_THREADS()ELSENEIGHBOR = IAM - 1
ENDIF

15
16
17

!$OMP

!$OMP

18
19
20

!$OMP

21

DO WHILE (ISYNC(NEIGHBOR) .EQ. 0)
FLUSH(ISYNC)
END DOFLUSH(WORK, ISYNC)
RESULT(IAM) = FN2(WORK(NEIGHBOR), WORK(IAM))
END PARALLEL
END PROGRAM A18

Fortran

22

23

A.19

The flush Construct without a List
The following example (for Section 2.7.5 on page 58) distinguishes the shared objects
affected by a flush construct with no list from the shared objects that are not affected:

24
25

C/C++

26
27

Example A.19.1c

28

int x, *p = &x;

29
30
31
32
33
34
35

void f1(int *q){*q = 1;#pragma omp flush/* x, p, and *q are flushed *//* because they are shared and accessible *//* q is not flushed because it is not shared. */

36

150

OpenMP API • Version 2.5 May 2005

1

}

2
3
4
5
6

void f2(int *q){#pragma omp barrier*q = 2;#pragma omp barrier

7
8
9
10
11

}

12
13
14
15
16
17
18

int g(int n){
int i = 1, j, sum = 0;*p = 1;#pragma omp parallel reduction(+: sum) num_threads(10){f1(&j);/* a barrier implies a flush *//* x, p, and *q are flushed *//* because they are shared and accessible *//* q is not flushed because it is not shared. */

19
20
21
22

/* i, n and sum were not flushed *//* because they were not accessible in f1 *//* j was flushed because it was accessible */sum += j;23

f2(&j);

24
25
26
27
28

/* i, n, and sum were not flushed *//* because they were not accessible in f2 *//* j was flushed because it was accessible */sum += i + j + *p + n;}
return sum;

29
30

}

31
32
33
34
35

int main(){
int result = g(7);return result;
}

36

C/C++

37

Fortran

38
39

40

Example A.19.1f
SUBROUTINE F1(Q)Appendix A

Examples151Fortran (cont.)

1
2
3
4
5

COMMON /DATA/ X, P
INTEGER, TARGET :: X
INTEGER, POINTER :: P
INTEGER Q

6
7
8
9
10

!$OMP

11
12
13
14
15

SUBROUTINE F2(Q)COMMON /DATA/ X, P
INTEGER, TARGET :: X
INTEGER, POINTER :: P
INTEGER Q!$OMP

BARRIER
Q = 2!$OMP
BARRIER! a barrier implies a flush! X, P and Q are flushed! because they are shared and accessible
END SUBROUTINE F2

16
17
18
19
20
21
22

INTEGER FUNCTION G(N)COMMON /DATA/ X, P
INTEGER, TARGET :: X
INTEGER, POINTER :: P
INTEGER NINTEGER I, J, SUM

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

!$OMP

I = 1
SUM = 0
P = 1
PARALLEL REDUCTION(+: SUM) NUM_THREADS(10)CALL F1(J)! I, N and SUM were not flushed!
because they were not accessible in F1! J was flushed because it was accessible
SUM = SUM + J
CALL F2(J)! I, N, and SUM were not flushed!
because they were not accessible in f2! J was flushed because it was accessible
SUM = SUM + I + J + P + N

38
39
40
41
42

43

Q = 1
FLUSH
! X, P and Q are flushed! because they are shared and accessible
END SUBROUTINE F1

152

OpenMP API • Version 2.5 May 2005

1

!$OMP

END PARALLEL

2
3

G = SUM
END FUNCTION G

4
5
6
7
8

PROGRAM A19
COMMON /DATA/ X, P
INTEGER, TARGET :: X
INTEGER, POINTER :: P
INTEGER RESULT, G

9
10
11
12

P => XRESULT = G(7)PRINT *, RESULTEND PROGRAM A19

13

Fortran

14

C/C++

16

Placement of flush and barrier
Directives

17
18
19

The following example is non-conforming, because the flush and barrier directives
cannot be the immediate substatement of an if statement. See Section 2.7.3 on page 54
and Section 2.7.5 on page 58.

20

Example A.20.1c

21
22
23

void a20_wrong(){
int a = 1;

24
25
26
27
28
29

#pragma omp parallel{
if (a != 0)#pragma omp flush(a)/* incorrect as flush cannot be immediate substatementof if statement */

30
31
32
33

if (a != 0)#pragma omp barrier/* incorrect as barrier cannot be immediate substatementof if statement */

15

34

A.20

Appendix A

Examples

153

1
2

}

3
4

The following version of the above example is conforming because the flush andbarrier directives are enclosed in a compound statement.

5

Example A.20.2c6
78void a20(){
int a = 1;

}

9
10
11
12
13
14
15
16
17
18

#pragma omp parallel{
if (a != 0) {#pragma omp flush(a)}if (a != 0) {#pragma omp barrier
}
}
}

C/C++

19

21

The ordered Clause and the ordered
Construct

22
23
24

Ordered constructs (Section 2.7.6 on page 61) are useful for sequentially ordering theoutput from work that is done in parallel. The following program prints out the indicesin sequential order:

20

A.21

C/C++

25
26

Example A.21.1c

27#include <stdio.h>

28
29
30
31
32

void work(int k){#pragma omp orderedprintf(" %d\n", k);
}

33
34

void a21(int lb, int ub, int stride)
{

35

154

OpenMP API • Version 2.5 May 2005

1

int i;

2
3
4
5#pragma omp parallel for ordered schedule(dynamic)for (i=lb; i<ub; i+=stride)work(i);
}

6
7
8
9
10

int main(){a21(0, 100, 5);return 0;
}

11

C/C++

12

Fortran

13
14
15
16
17
18

Example A.21.1f
SUBROUTINE WORK(K)INTEGER k!$OMP ORDERED
WRITE(*,*) K!$OMP END ORDERED

19

END SUBROUTINE WORK

20
21
22

SUBROUTINE SUBA21(LB, UB, STRIDE)INTEGER LB, UB, STRIDEINTEGER I

23
24
25
26
27

!$OMP PARALLEL DO ORDERED SCHEDULE(DYNAMIC)
DO I=LB,UB,STRIDECALL WORK(I)END DO!$OMP END PARALLEL DO

28

END SUBROUTINE SUBA21

29
30
31

PROGRAM A21
CALL SUBA21(1,100,5)
END PROGRAM A21

32

Fortran

33
34
35
36

It is possible to have multiple ordered constructs within a loop region with theordered clause specified. The first example is non-conforming because all iterations
execute two ordered regions. An iteration of a loop must not execute more than one
ordered region:

37

Appendix A

Examples155C/C++

1
2

Example A.21.2c3void work(int i) {}

4
5
6
7
8
9
10
11
12
13
14
15
16

void a21_wrong(int n){
int i;#pragma omp for orderedfor (i=0; i<n; i++) {/* incorrect because an iteration may not execute more than one
ordered region */#pragma omp ordered
work(i);#pragma omp ordered
work(i+1);
}
}

17

C/C++

18

Fortran

Example A.21.2f

19
20
21
22

SUBROUTINE WORK(I)INTEGER IEND SUBROUTINE WORK

23
24

SUBROUTINE A21_WRONG(N)INTEGER N

25
26
27
28
29
30
31
32

INTEGER I
DO ORDERED
DO I = 1, N
! incorrect because an iteration may not execute more than one! ordered region!$OMP
ORDERED
CALL WORK(I)!$OMPEND ORDERED
!$OMP

33
34
35
36
37

!$OMP

ORDERED
CALL WORK(I+1)!$OMP
END ORDERED
END DOEND SUBROUTINE A21_WRONG

38

Fortran

39

The following is a conforming example with more than one ordered construct. Each
iteration will execute only one ordered region:

40

41

156

OpenMP API • Version 2.5 May 2005

C/C++

1
2

Example A.21.3c

3
45

void a21_good(int n){
int i;

6
7
8
9
10
11

#pragma omp for orderedfor (i=0; i<n; i++) {if (i <= 10) {#pragma omp ordered
work(i);
}

12
13
14
15
16
17

if (i > 10) {#pragma omp ordered
work(i+1);
}
}
}

18

C/C++

19

Fortran

20

Example A.21.3f

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38

SUBROUTINE A21_GOOD(N)INTEGER N
!$OMP

!$OMP
!$OMP

DO ORDERED
DO I = 1,N
IF (I <= 10) THEN
ORDERED
CALL WORK(I)END ORDERED
ENDIF

IF (I > 10) THEN
ORDERED
CALL WORK(I+1)!$OMP
END ORDERED
ENDIF
ENDDO
END SUBROUTINE A21_GOOD!$OMP

FortranAppendix A

Examples

157

1

A.22

The threadprivate Directive
The following examples demonstrate how to use the threadprivate directive(Section 2.8.2 on page 66) to give each thread a separate counter.

2
3

C/C++

4
5

Example A.22.1c

6
7

int counter = 0;
#pragma omp threadprivate(counter)

8
9
10
11
12

int increment_counter(){counter++;
return(counter);
}

13

C/C++

14

Fortran

15

Example A.22.1f

16
17
18

INTEGER FUNCTION INCREMENT_COUNTER()COMMON/A22_COMMON/COUNTER!$OMPTHREADPRIVATE(/A22_COMMON/)

19
20
21
22

COUNTER = COUNTER +1
INCREMENT_COUNTER = COUNTER
RETURNEND FUNCTION INCREMENT_COUNTER

23

Fortran
C/C++

24
25

The following example uses threadprivate on a static variable:

26

Example A.22.2c

27
28
29
30
31
32
33

int increment_counter_2(){
static int counter = 0;
#pragma omp threadprivate(counter)counter++;
return(counter);
}

34

158

OpenMP API • Version 2.5 May 2005

1
2
3

The following example illustrates how modifying a variable that appears in an initializer
can cause unspecified behavior, and also how to avoid this problem by using an auxiliary
object and a copy-constructor.

4

Example A.22.3c

5
6
7
8
9
10

class T {public:int val;T (int);T (const T&);
};

11
12
13

T :: T (int v){val = v;
}

14
15
16

T :: T (const T& t) {val = t.val;
}

17
18
19

void g(T a, T b){
a.val += b.val;
}

20
21
22
23
24

int x = 1;
T a(x);
const T b_aux(x); /* Capture value of x = 1 */T b(b_aux);#pragma omp threadprivate(a, b)

25
26
27
28
29
30
31

void f(int n) {x++;
#pragma omp parallel for/* In each thread:* Object a is constructed from x (with value 1 or 2?)* Object b is copy-constructed from b_aux
*/

32
33
34
35
36

37

for (int i=0; i<n; i++) {g(a, b); /* Value of a is unspecified. */
}
}

C/C++

Appendix A

Examples1591

Fortran

2
3
4

The following examples show non-conforming uses and correct uses of thethreadprivate directive. For more information, see Section 2.8.2 on page 66 andSection 2.8.4.1 on page 84.

5
6

The following example is non-conforming because the common block is not declared
local to the subroutine that refers to it:

7

Example A.22.4f

89
10

MODULE A22_MODULECOMMON /T/ A
END MODULE A22_MODULE

11
12
13
14
15

SUBROUTINE A22_4_WRONG()
USE A22_MODULE!$OMPTHREADPRIVATE(/T/)!non-conforming because /T/ not declared in A22_4_WRONGEND SUBROUTINE A22_4_WRONG

16
17

The following example is also non-conforming because the common block is notdeclared local to the subroutine that refers to it:

18

Example A.22.5f

19
20
21

SUBROUTINE A22_5_WRONG()
COMMON /T/ A!$OMP
THREADPRIVATE(/T/)

22
23
24
25
26
27
28

CONTAINSSUBROUTINE A22_5S_WRONG()!$OMP
PARALLEL COPYIN(/T/)!non-conforming because /T/ not declared in A22_5S_WRONG!$OMPEND PARALLELEND SUBROUTINE A22_5S_WRONGEND SUBROUTINE A22_5_WRONG

29

The following example is a correct rewrite of the previous example:

30

Example A.22.6f

31
32
33

34

!$OMP

160

SUBROUTINE A22_6_GOOD()COMMON /T/ A
THREADPRIVATE(/T/)

OpenMP API • Version 2.5 May 2005

Fortran (cont.)

1
2
3
4
5

!$OMP

CONTAINSSUBROUTINE A22_6S_GOOD()COMMON /T/ A
THREADPRIVATE(/T/)

6
7
8
9

!$OMP
!$OMP

10

The following is an example of the use of threadprivate for local variables:

11

Example A.22.7f

12
13
14
15
16
17
18

PROGRAM A22_7_GOOD
INTEGER, ALLOCATABLE, SAVE :: A(:)
INTEGER, POINTER, SAVE :: PTR
INTEGER, SAVE :: I
INTEGER, TARGET :: TARG
LOGICAL :: FIRSTIN = .TRUE.
!$OMPTHREADPRIVATE(A, I, PTR)

19
20
21
22
23
24
25
26
27
28
29
30

PARALLEL COPYIN(/T/)
END PARALLELEND SUBROUTINE A22_6S_GOOD
END SUBROUTINE A22_6_GOOD

ALLOCATE (A(3))
A = (/1,2,3/)
PTR => TARG
I = 5
!$OMP
!$OMP

PARALLEL COPYIN(I, PTR)CRITICAL
IF (FIRSTIN) THENTARG = 4! Update target of ptr
I = I + 10
IF (ALLOCATED(A)) A = A + 10
FIRSTIN = .FALSE.
END IF

31
32
33
34
35

IF (ALLOCATED(A)) THEN
PRINT *, ’a = ’, A
ELSE
PRINT *, ’A is not allocated’
END IF

36
37
38

PRINT *, ’ptr = ’, PTR
PRINT *, ’i = ’, I
PRINT *

39

Appendix A

Examples161Fortran (cont.)

1
2
3
4

!$OMP
!$OMP

5
6

The above program, if executed by two threads, will print one of the following two setsof output:

78
9

a = 11 12 13
ptr = 4i = 1510
11
12

A is not allocatedptr = 4
i = 5

13

or

14
15
16

A is not allocatedptr = 4i = 1517
18
19

a = 1 2 3
ptr = 4i = 5

20

The following is an example of the use of threadprivate for module variables:

21

Example A.22.8f

22
23
24
25
26

MODULE A22_MODULE8
REAL, POINTER :: WORK(:)
SAVE WORK!$OMPTHREADPRIVATE(WORK)END MODULE A22_MODULE8

27
28
29
30
31
32
33
34

SUBROUTINE SUB1(N)USE A22_MODULE8!$OMPPARALLEL PRIVATE(THE_SUM)
ALLOCATE(WORK(N))
CALL SUB2(THE_SUM)
WRITE(*,*)THE_SUM!$OMP
END PARALLELEND SUBROUTINE SUB1

35

162

END CRITICAL
END PARALLEL
END PROGRAM A22_7_GOOD

OpenMP API • Version 2.5 May 2005

1
2
3
4
5

SUBROUTINE SUB2(THE_SUM)
USE A22_MODULE8
WORK(:) = 10
THE_SUM=SUM(WORK)END SUBROUTINE SUB2

6
7
8
9

PROGRAM A22_8_GOOD
N = 10CALL SUB1(N)END PROGRAM A22_8_GOOD

10

Fortran11

Fortran13

Fortran Restrictions on shared andprivate Clauses with Common Blocks

14
15
16
17

When a named common block is specified in a private, firstprivate, or
lastprivate clause of a construct, none of its members may be declared in anotherdata-sharing attribute clause on that construct. The following examples illustrate thispoint. For more information, see Section 2.8.3 on page 70.

18

The following example is conforming:

19

Example A.23.1f

12

A.23

20
21
22

SUBROUTINE A23_1_GOOD()COMMON /C/ X,YREAL X, Y

23
24
25

!$OMP

26
27
28
29

!$OMP

30

The following example is also conforming:

31

!$OMP

PARALLEL PRIVATE (/C/)! do work here
END PARALLELPARALLEL SHARED (X,Y)! do work here!$OMP
END PARALLELEND SUBROUTINE A23_1_GOOD

Appendix A

Examples163

Fortran (cont.)

1

Example A.23.2f

2
3
4
5

SUBROUTINE A23_2_GOOD()COMMON /C/ X,YREAL X, Y

6

INTEGER I

7
8
9
10
11
12
13
14
15
16
17
18
19
20

!$OMP
!$OMP

21

The following example is conforming:

22

Example A.23.3f

!$OMP
!
!$OMP

PARALLELDO PRIVATE(/C/)
DO I=1,1000! do work here
ENDDO
END DODO PRIVATE(X)DO I=1,1000! do work here
ENDDO
!$OMP
END DO!$OMP
END PARALLELEND SUBROUTINE A23_2_GOOD

23
24

SUBROUTINE A23_3_GOOD()COMMON /C/ X,Y

25
26
27

!$OMP

28
29
30
31

!$OMP

32

The following example is non-conforming because x is a constituent element of c:

33

Example A.23.4f!$OMP

PARALLEL SHARED (/C/)! do work here!$OMP
END PARALLELEND SUBROUTINE A23_3_GOOD

34

35

PARALLEL PRIVATE (/C/)! do work here
END PARALLEL

SUBROUTINE A23_4_WRONG()

164

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6

COMMON /C/ X,Y! Incorrect because X is a constituent element of C!$OMPPARALLEL PRIVATE(/C/), SHARED(X)! do work here!$OMP
END PARALLELEND SUBROUTINE A23_4_WRONG

7
8

The following example is non-conforming because a common block may not be declaredboth shared and private:

9

Example A.23.5f

10
11
12
13
14
15
16

SUBROUTINE A23_5_WRONG()
COMMON /C/ X,Y! Incorrect: common block C cannot be declared both! shared and private!$OMP
PARALLEL PRIVATE (/C/), SHARED(/C/)! do work here!$OMP
END PARALLEL

17

END SUBROUTINE A23_5_WRONG

Fortran

18

19
20
21
22

A.24

The default(none) Clause
The following example distinguishes the variables that are affected by thedefault(none) clause from those that are not. For more information on thedefault clause, see Section 2.8.3.1 on page 71.

C/C++

23
24

Example A.24.1c

25
26
27

#include <omp.h>
int x, y, z[1000];#pragma omp threadprivate(x)

28
29
30

void a24(int a) {const int c = 1;
int i = 0;

31
32
33
34

35

#pragma omp parallel default(none) private(a) shared(z){int j = omp_get_num_threads();/* O.K. - j is declared within parallel region */Appendix A

Examples

165

1
2
3
4
5

a = z[j];

6
7
8
9
10

#pragma omp for firstprivate(y)for (i=0; i<10 ; i++) {z[i] = y; /* O.K. - i is the loop iteration variable *//* - y is listed in firstprivate clause */}x = c;
z[i] = y;

11
12
13

z[i] = y;/* O.K. - a is listed in private clause *//*- z is listed in shared clause *//* O.K. - x is threadprivate *//*- c has const-qualified type *//* Error - cannot reference i or y here *//* Error - cannot reference i or y here */

}
}

14

C/C++

15

Fortran

Example A.24.1f

16
17
18

SUBROUTINE A24(A)INCLUDE "omp_lib.h"19

INTEGER A

20
21
22
23
24

INTEGER X, Y, Z(1000)
COMMON/BLOCKX/XCOMMON/BLOCKY/YCOMMON/BLOCKZ/Z!$OMP THREADPRIVATE(/BLOCKX/)

25
26

INTEGER I, J
i = 1

! or USE OMP_LIB

27
28
29
30
31
32
33

!$OMP

PARALLEL DEFAULT(NONE) PRIVATE(A) SHARED(Z) PRIVATE(J)J = OMP_GET_NUM_THREADS();! O.K. - J is listed in PRIVATE clause
A = Z(J) ! O.K. - A is listed in PRIVATE clause!
- Z is listed in SHARED clause
X = 1! O.K. - X is THREADPRIVATE
Z(I) = Y ! Error - cannot reference I or Y here

34
35
36
37
38

!$OMP

DO firstprivate(y)DO I = 1,10
Z(I) = Y ! O.K. - I is the loop iteration variable! Y is listed in FIRSTPRIVATE clause
END DO

39

166

OpenMP API • Version 2.5 May 2005

1
2
3

!$OMP

Z(I) = Y! Error - cannot reference I or Y here
END PARALLELEND SUBROUTINE A24

4

Fortran5

Fortran

7

Race Conditions Caused by Implied
Copies of Shared Variables in Fortran

8
9
10
11
12
13
14

The following example contains a race condition, because the shared variable, which isan array section, is passed as an actual argument to a routine that has an assumed-size
array as its dummy argument (see Section 2.8.3.2 on page 72). The subroutine callpassing an array section argument may cause the compiler to copy the argument into a
temporary location prior to the call and copy from the temporary location into theoriginal variable when the subroutine returns. This copying would cause races in theparallel region.

15

Example A.25.1f

16

SUBROUTINE A25

6

A.25

17

INCLUDE "omp_lib.h"

18
19

REAL A(20)INTEGER MYTHREAD

20
21
22
23
24
25
26

!$OMP PARALLEL SHARED(A) PRIVATE(MYTHREAD)
MYTHREAD = OMP_GET_THREAD_NUM()
IF (MYTHREAD .EQ. 0) THENCALL SUB(A(1:10)) ! compiler may introduce writes to A(6:10)
ELSE
A(6:10) = 12
ENDIF

27

!$OMP END PARALLEL28

END SUBROUTINE A25

29
30
31

SUBROUTINE SUB(X)REAL X(*)
X(1:5) = 4

32! or USE OMP_LIB

Appendix A

Examples167

1

END SUBROUTINE SUB

Fortran

2

3

A.26

The private ClauseIn the following example, the values of i and j are undefined on exit from theparallel region. For more information on the private clause, see Section 2.8.3.3
on page 73.

4
5
6

C/C++

7
8

Example A.26.1c

9#include <stdio.h>

10
11
12

int main(){
int i, j;1314

i = 1;
j = 2;

15
16
17
18
19

#pragma omp parallel private(i) firstprivate(j){i = 3;
j = j + 2;}

20

printf("%d %d\n", i, j); /* i and j are undefined */return 0;

21
22

}

23

C/C++

24

Fortran

Example A.26.1f

25
26
27

PROGRAM A26
INTEGER I, J

28
29

I = 1
J = 2

30
31
32
33

34

!$OMP

!$OMP

168

PARALLEL PRIVATE(I) FIRSTPRIVATE(J)I = 3
J = J + 2
END PARALLEL

OpenMP API • Version 2.5 May 2005

1
2

PRINT *, I, J
END PROGRAM A26! I and J are undefined3

Fortran

4
5
6
7

The private clause of a parallel construct is only in effect inside the construct,and not for the rest of the region. Therefore, in the example that follows, any uses of thevariable a within the loop in the routine f refers to a private copy of a, while a usage inroutine g refers to the global a.

C/C++

8
9

Example A.26.2c

10

int a;

11
12
13

void g(int k) {a = k;/* The global "a", not the private "a" in f */
}

14
15

void f(int n) {int a = 0;

16
17
18
19
20
21

#pragma omp parallel for private(a)for (int i=1; i<n; i++) {a = i;g(a*2);/* Private copy of "a" */
}
}

22

C/C++

23

Fortran

24

Example A.26.2f

25
26

MODULE A26_2
REAL A

27

CONTAINS

28
29
30
31
32

SUBROUTINE G(K)REAL K
A = K ! This is A in module A26_2, not the private! A in F
END SUBROUTINE G

33
34
35

SUBROUTINE F(N)INTEGER N
REAL A

36

Appendix A

Examples

169

1
2
3
4
5
6
7
8

!$OMP

!$OMP

9

INTEGER IPARALLEL DO PRIVATE(A)DO I = 1,N
A = I
CALL G(A*2)
ENDDO
END PARALLEL DO
END SUBROUTINE F
END MODULE A26_2

Fortran

10

11

A.27

Reprivatization
The following example demonstrates the reprivatization of variables (see Section 2.8.3.3
on page 73). Private variables can be marked private again in a nested construct.
They do not have to be shared in the enclosing parallel region.

12
13
14

C/C++

15
16

Example A.27.1c

17
18
19

void a27(){
int i, a;

20
21
22
23
24
25
26
27
28

#pragma omp parallel private(a){#pragma omp parallel for private(a)for (i=0; i<10; i++){/* do work here */
}
}
}

29

C/C++

30

Fortran

Example A.27.1f

31
32
33

SUBROUTINE A27()
INTEGER I, A

34
35
36
37

38

!$OMP
!$OMP

170

PARALLEL PRIVATE(A)PARALLEL DO PRIVATE(A)DO I = 1, 10! do work here

OpenMP API • Version 2.5 May 2005

1
2
3
4

!$OMP
!$OMP

END DOEND PARALLEL DO
END PARALLELEND SUBROUTINE A27

5

Fortran6

Fortran8

Fortran Restrictions on Storage
Association with the private Clause

9
10

The following non-conforming examples illustrate the implications of the private
clause rules with regard to storage association (see Section 2.8.3.3 on page 73).

11

Example A.28.1f

7

A.28

12
13
14
15

SUBROUTINE SUB()COMMON /BLOCK/ X
PRINT *,X
END SUBROUTINE SUB

16
17
18
19
20
21
22
23

PROGRAM A28_1
COMMON /BLOCK/ X
X = 1.0!$OMP
PARALLEL PRIVATE (X)X = 2.0
CALL SUB()!$OMP
END PARALLEL
END PROGRAM A28_1

24

Example A.28.2f! X is undefined

25
26
27
28
29
30
31
32
33

34

PROGRAM A28_2
COMMON /BLOCK2/ X
X = 1.0
!$OMP

!$OMP

PARALLEL PRIVATE (X)X = 2.0
CALL SUB()END PARALLELCONTAINSSUBROUTINE SUB()

Appendix A

Examples171

Fortran (cont.)

1
2

COMMON /BLOCK2/ Y

3
4
5

PRINT *,X
PRINT *,YEND SUBROUTINE SUB

6

END PROGRAM A28_2

Example A.28.3f

7
8
9
10

PROGRAM A28_3
EQUIVALENCE (X,Y)
X = 1.0

11
12
13
14
15
16

!$OMP

17

Example A.28.4f

PARALLEL PRIVATE(X)PRINT *,YY = 10PRINT *,X!$OMP
END PARALLEL
END PROGRAM A28_3

18
19
20
21

! Y is undefined! X is undefined

PROGRAM A28_4
INTEGER I, J
INTEGER A(100), B(100)EQUIVALENCE (A(51), B(1))

22
23
24
25
26

!$OMP PARALLEL DO DEFAULT(PRIVATE) PRIVATE(I,J) LASTPRIVATE(A)DO I=1,100
DO J=1,100
B(J) = J - 1
ENDDO

27
28
29

DO J=1,100
A(J) = J
ENDDO

30
31
32
33
34
35
36

37

! X is undefined! Y is undefined! B becomes undefined at this point

DO J=1,50
B(J) = B(J) + 1 ! B is undefined! A becomes undefined at this point
ENDDO
ENDDO
!$OMP END PARALLEL DO! The LASTPRIVATE write for A has! undefined results

172

OpenMP API • Version 2.5 May 2005

1
2
3

4

PRINT *, B

! B is undefined since the LASTPRIVATE! write of A was not defined
END PROGRAM A28_4

Example A.28.5f

5
6

SUBROUTINE SUB1(X)DIMENSION X(10)

7
8
9
10
11

! This use of X does not conform to the! specification. It would be legal Fortran 90,! but the OpenMP private directive allows the! compiler to break the sequence association that
! A had with the rest of the common block.

12
13

FORALL (I = 1:10) X(I) = I
END SUBROUTINE SUB1

1415PROGRAM A28_5
COMMON /BLOCK5/ A

16
17

DIMENSION B(10)EQUIVALENCE (A,B(1))

1819! the common block has to be at least 10 words
A = 0

20

!$OMP

! Without the private clause,! we would be passing a member of a sequence! that is at least ten elements long.
! With the private clause, A may no longer be! sequence-associated.

21
22
23
24
25
26
27
28
29
30
31
32

33

PARALLEL PRIVATE(/BLOCK5/)

!$OMP
!$OMP
!$OMP

CALL SUB1(A)MASTER
PRINT *, A
END MASTER
END PARALLEL
END PROGRAM A28_5

FortranAppendix A

Examples173C/C++1

2

A.29

C/C++ Arrays in a firstprivate Clause

3
4
5
6

The following example illustrates the size and value of list items of array or pointer typein a firstprivate clause (Section 2.8.3.4 on page 75). The size of new list items isbased on the type of the corresponding original list item, as determined by the baselanguage.

7

In this example:

8•

The type of A is array of two arrays of two ints.

9
10

•

The type of B is adjusted to pointer to array of n ints, because it is a function
parameter.

11•

The type of C is adjusted to pointer to int, because it is a function parameter.

12•

The type of D is array of two arrays of two ints.

13•

The type of E is array of n arrays of n ints.

14

Note that B and E involve variable length array types.

15
16
17

The new items of array type are initialized as if each integer element of the originalarray is assigned to the corresponding element of the new array. Those of pointer typeare initialized as if by assignment from the original item to the new item.

18

Example A.29.1c

19#include <assert.h>20

int A[2][2] = {1, 2, 3, 4};

21
22
23
24

void f(int n, int B[n][n], int C[]){int D[2][2] = {1, 2, 3, 4};
int E[n][n];2526assert(n >= 2);
E[1][1] = 4;

27
28
29
30
31
32

#pragma omp parallel firstprivate(B, C, D, E){
assert(sizeof(B) == sizeof(int (*)[n]));assert(sizeof(C) == sizeof(int*));assert(sizeof(D) == 4 * sizeof(int));
assert(sizeof(E) == n * n * sizeof(int));

33

174

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7

}

8
9
10
11

int main() {f(2, A, A[0]);return 0;}/* Private B and C have values of original B and C. */assert(&B[1][1] == &A[1][1]);assert(&C[3] == &A[1][1]);assert(D[1][1] == 4);
assert(E[1][1] == 4);
}

C/C++

12

13
14
15
16
17

A.30

The lastprivate Clause
Correct execution sometimes depends on the value that the last iteration of a loop
assigns to a variable. Such programs must list all such variables in a lastprivate
clause (Section 2.8.3.5 on page 77) so that the values of the variables are the same as
when the loop is executed sequentially.

C/C++

18
19

Example A.30.1c

20
21
22

void a30 (int n, float *a, float *b){
int i;

23
24
25
26
27
28

#pragma omp parallel{#pragma omp for lastprivate(i)for (i=0; i<n-1; i++)a[i] = b[i] + b[i+1];
}

29
30

a[i]=b[i];/* i == n-1 here */

}

31

C/C++

32

Fortran

33
34
35
36

37

Example A.30.1f
SUBROUTINE A30(N, A, B)
INTEGER N
REAL A(*), B(*)

Appendix A

Examples175

1

INTEGER I

2
3!$OMP PARALLEL!$OMP DO LASTPRIVATE(I)456DO I=1,N-1
A(I) = B(I) + B(I+1)
ENDDO

7

!$OMP END PARALLEL

8

A(I) = B(I)9END SUBROUTINE A30

Fortran1011! I has the value of N here

A.31

The reduction Clause
The following example demonstrates the reduction clause (Section 2.8.3.6 on page
79):

12
13

C/C++

14
15

Example A.31.1c

16
17
18
19

void a31_1(float *x, int *y, int n){
int i, b;
float a;20
21

a = 0.0;
b = 0;

22
23
24#pragma omp parallel for private(i) shared(x, y, n) \reduction(+:a) reduction(^:b)
for (i=0; i<n; i++) {25
26

a += x[i];b ^= y[i];
}

27
28

}

C/C++

29

30

176

OpenMP API • Version 2.5 May 2005

Fortran

1
2

Example A.31.1f

3

SUBROUTINE A31_1(A, B, X, Y, N)

4
5
6
7

INTEGER N
REAL X(*), Y(*), A, B!$OMP PARALLEL DO PRIVATE(I) SHARED(X, N) REDUCTION(+:A)!$OMP& REDUCTION(MIN:B)

8

DO I=1,N

9

A = A + X(I)10

B = MIN(B, Y(I))

11
12
13
14
15

!
!
!

Note that some reductions can be expressed inother forms. For example, the MIN could be expressed as
IF (B > Y(I)) B = Y(I)END DOEND SUBROUTINE A31_1

Fortran

16
17
18

A common implementation of the preceding example is to treat it as if it had been
written as follows:

C/C++

19
20

Example A.31.2c

21
22
23
24

void a31_2(float *x, int *y, int n){
int i, b, b_p;
float a, a_p;2526

a = 0.0;
b = 0;

27
28
29
30
31

#pragma omp parallel shared(a, b, x, y, n) \private(a_p, b_p){a_p = 0.0;
b_p = 0;32
33

#pragma omp for private(i)for (i=0; i<n; i++) {34

Appendix A

Examples

177

1
2

a_p += x[i];b_p ^= y[i];

3

}

4
5
6
7
8

#pragma omp critical{a += a_p;b ^= b_p;
}

9
10

}

}

11

C/C++

12

Fortran

Example A.31.2f

13
14

SUBROUTINE A31_2 (A, B, X, Y, N)

15
16

INTEGER N
REAL X(*), Y(*), A, B, A_P, B_P

17!$OMP PARALLEL SHARED(X, Y, N, A, B) PRIVATE(A_P, B_P)

18
19

A_P = 0.0
B_P = HUGE(B_P)

20
21
22
23
24
25

!$OMP

26
27
28
29

!$OMP

30

!$OMP END PARALLEL

!$OMP

!$OMP

CRITICAL
A = A + A_P
B = MIN(B, B_P)
END CRITICALEND SUBROUTINE A31_2

31

The following program is non-conforming because the reduction is on the intrinsic
procedure name MAX but that name has been redefined to be the variable named MAX.

32
33

34

DO PRIVATE(I)DO I=1,N
A_P = A_P + X(I)
B_P = MIN(B_P, Y(I))
ENDDO
END DO

178

OpenMP API • Version 2.5 May 2005

Fortran (cont.)

1
2

Example A.31.3f

3
4

PROGRAM A31_3_WRONG
MAX = HUGE(0)

5

M = 0

6
7
8

!$OMP PARALLEL DO REDUCTION(MAX: M)

9
10
11

DO I = 1, 100
CALL SUB(M,I)
END DO

12END PROGRAM A31_3_WRONG

13
14
15

SUBROUTINE SUB(M,I)
M = MAX(M,I)
END SUBROUTINE SUB

16
17

The following conforming program performs the reduction using the intrinsic procedurename MAX even though the intrinsic MAX has been renamed to REN.

18

Example A.31.4f

19
20
21

MODULE M
INTRINSIC MAX
END MODULE M

22
23
24
25
26
27
28
29

PROGRAM A31_4
USE M, REN => MAX
N = 0!$OMP PARALLEL DO REDUCTION(REN: N)
DO I = 1, 100
N = MAX(N,I)
END DOEND PROGRAM A31_4

30
31

The following conforming program performs the reduction using intrinsic procedurename MAX even though the intrinsic MAX has been renamed to MIN.

32

Example A.31.5f

33

MODULE MOD

34! MAX is no longer the! intrinsic so this! is non-conforming! still does MAX

Appendix A

Examples

179

1
2

INTRINSIC MAX, MIN
END MODULE MOD

3
4
5
6

PROGRAM A31_5
USE MOD, MIN=>MAX, MAX=>MIN
REAL :: R
R = -HUGE(0.0)

7
8
9
10
11
12

!$OMP PARALLEL DO REDUCTION(MIN: R)
DO I = 1, 1000
R = MIN(R, SIN(REAL(I)))
END DOPRINT *, R
END PROGRAM A31_5

Fortran13

14! still does MAX

A.32

The copyin Clause
The copyin clause (see Section 2.8.4.1 on page 84) is used to initialize threadprivate
data upon entry to a parallel region. The value of the threadprivate variable in themaster thread is copied to the threadprivate variable of each other team member.

15
16
17

C/C++

18
19

Example A.32.1c

20#include <stdlib.h>

21
22
23

float* work;
int size;float tol;24

#pragma omp threadprivate(work,size,tol)

25
26
27
28
29
30
31
32
33

void a32( float t, int n ){tol = t;size = n;#pragma omp parallel copyin(tol,size){build();
}
}

34
35
36

void build(){
int i;

37

180

OpenMP API • Version 2.5 May 2005

1
2
3

work = (float*)malloc( sizeof(float)*size );for( i = 0; i < size; ++i ) work[i] = tol;
}

4

C/C++

5

Fortran

6

Example A.32.1f

7
8
9
10
11
12

MODULE M
REAL, POINTER, SAVE :: WORK(:)
INTEGER :: SIZEREAL :: TOL!$OMPTHREADPRIVATE(WORK,SIZE,TOL)
END MODULE M

13
14
15
16
17
18
19
20
21
22

SUBROUTINE A32( T, N )USE M
REAL :: T
INTEGER :: N
TOL = T
SIZE = N!$OMPPARALLEL COPYIN(TOL,SIZE)CALL BUILD!$OMPEND PARALLELEND SUBROUTINE A32

23
24
25
26
27

SUBROUTINE BUILD
USE M
ALLOCATE(WORK(SIZE))WORK = TOLEND SUBROUTINE BUILD

Fortran

28

29
30
31
32
33
34
35
36
37

38

A.33

The copyprivate Clause
The copyprivate clause (see Section 2.8.4.2 on page 85) can be used to broadcast
values acquired by a single thread directly to all instances of the private variables in theother threads. In this example, if the routine is called from the sequential part, its
behavior is not affected by the presence of the directives. If it is called from aparallel region, then the actual arguments with which a and b are associated must be
private. After the input routine has been executed by one thread, no thread leaves theconstruct until the private objects designated by a, b, x, and y in all threads have become
defined with the values read.

Appendix A

Examples181

C/C++

1
2

Example A.33.1c

3
45#include <stdio.h>
float x, y;#pragma omp threadprivate(x, y)

6
7
8
9
10
11

void init(float a, float b ) {#pragma omp single copyprivate(a,b,x,y){
scanf("%f %f %f %f", &a, &b, &x, &y);
}
}

12

C/C++

13

Fortran

14

Example A.33.1f

15
16
17
18

SUBROUTINE INIT(A,B)
REAL A, B
COMMON /XY/ X,Y!$OMPTHREADPRIVATE (/XY/)

19
20
21

!$OMP
!$OMP

22

SINGLEREAD (11) A,B,X,Y
END SINGLE COPYPRIVATE (A,B,/XY/)
END SUBROUTINE INIT

23

Fortran

24
25
26
27

In contrast to the previous example, suppose the input must be performed by a particularthread, say the master thread. In this case, the copyprivate clause cannot be used to
do the broadcast directly, but it can be used to provide access to a temporary sharedobject.

C/C++

28
29

Example A.33.2c

30
31#include <stdio.h>#include <stdlib.h>

32
33
34

float read_next( ) {float * tmp;
float return_val;

35
36
37
38

39

#pragma omp single copyprivate(tmp){tmp = (float *) malloc(sizeof(float));} /* copies the pointer only */182

OpenMP API • Version 2.5 May 2005

1
2
3
4

#pragma omp master{scanf("%f", tmp);
}

5
6
7

#pragma omp barrier
return_val = *tmp;#pragma omp barrier

8
9
10
11

#pragma omp single nowait{
free(tmp);
}

12
13

return return_val;
}

14

C/C++

15

Fortran

16

Example A.33.2f

17
18

REAL FUNCTION READ_NEXT()
REAL, POINTER :: TMP

19
20
21

!$OMP

22
23
24

!$OMP

25
26
27

!$OMP

28
29
30
31

!$OMP

!$OMP

!$OMP

!$OMP

SINGLE
ALLOCATE (TMP)
END SINGLE COPYPRIVATE (TMP)! copies the pointer only

MASTER
READ (11) TMP
END MASTERBARRIER
READ_NEXT = TMPBARRIERSINGLE
DEALLOCATE (TMP)!$OMP
END SINGLE NOWAIT
END FUNCTION READ_NEXT32

Fortran

33
34
35

Suppose that the number of lock objects required within a parallel region cannot
easily be determined prior to entering it. The copyprivate clause can be used toprovide access to shared lock objects that are allocated within that parallel region.

36

Appendix A

Examples183

C/C++

1
2

Example A.33.3c

3
45#include <stdio.h>#include <stdlib.h>#include <omp.h>678

omp_lock_t *new_lock(){
omp_lock_t *lock_ptr;

9
10
11
12
13

#pragma omp single copyprivate(lock_ptr){
lock_ptr = (omp_lock_t *) malloc(sizeof(omp_lock_t));
omp_init_lock( lock_ptr );
}

14
15

return lock_ptr;
}

16

C/C++

17

Fortran

Example A.33.3f

18
19
20
21

FUNCTION NEW_LOCK()USE OMP_LIB! or INCLUDE "omp_lib.h"
INTEGER(OMP_LOCK_KIND), POINTER :: NEW_LOCK

22
23
24
25
26

!$OMP

27
28

Note that the effect of the copyprivate clause on a variable with the allocatable
attribute is different than on a variable with the pointer attribute.

29

Example A.33.4f

SINGLE
ALLOCATE(NEW_LOCK)CALL OMP_INIT_LOCK(NEW_LOCK)!$OMPEND SINGLE COPYPRIVATE(NEW_LOCK)END FUNCTION NEW_LOCK30
31SUBROUTINE S(N)INTEGER N

32
33

REAL, DIMENSION(:), ALLOCATABLE :: A
REAL, DIMENSION(:), POINTER :: B

34
35
36

37

!$OMP

184

ALLOCATE (A(N))
SINGLE
ALLOCATE (B(N))

OpenMP API • Version 2.5 May 2005

1
2
3
4
5

!$OMP

6
7
8
9
10

READ (11) A,B
END SINGLE COPYPRIVATE(A,B)! Variable A designates a private object!
which has the same value in each thread! Variable B designates a shared object

!$OMP
!$OMP

BARRIERSINGLE
DEALLOCATE (B)!$OMPEND SINGLE NOWAIT
END SUBROUTINE S

Fortran

11

12
13
14
15

A.34

Nested Loop Constructs
The following example of loop construct nesting (see Section 2.9 on page 87) is
conforming because the inner and outer loop regions bind to different parallel
regions:

C/C++

16
17

Example A.34.1c

18void work(int i, int j) {}

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

void good_nesting(int n){
int i, j;#pragma omp parallel default(shared){#pragma omp forfor (i=0; i<n; i++) {#pragma omp parallel shared(i, n){#pragma omp forfor (j=0; j < n; j++)work(i, j);
}
}
}
}

35

C/C++

36

Fortran

37
38

39

Example A.34.1f
SUBROUTINE WORK(I, J)

Appendix A

Examples

185

1
2

INTEGER I, J
END SUBROUTINE WORK

3
4

SUBROUTINE GOOD_NESTING(N)INTEGER N

5
6
7
8
9
10
11
12
13
14
15
16
17

INTEGER IPARALLEL DEFAULT(SHARED)DO
DO I = 1, N!$OMP
PARALLEL SHARED(I,N)!$OMP
DO
DO J = 1, N
CALL WORK(I,J)
END DO!$OMP
END PARALLEL
END DO!$OMP
END PARALLELEND SUBROUTINE GOOD_NESTING
!$OMP
!$OMP

Fortran18

The following variation of the preceding example is also conforming:

19

C/C++

20
21

Example A.34.2c

22void work(int i, int j) {}

23
24
25
26
27
28
29
30
31
32

void work1(int i, int n){
int j;#pragma omp parallel default(shared){#pragma omp forfor (j=0; j<n; j++)work(i, j);
}
}

33
34
35
36
37
38
39
40

void good_nesting2(int n){
int i;#pragma omp parallel default(shared){#pragma omp forfor (i=0; i<n; i++)work1(i, n);

41

186

OpenMP API • Version 2.5 May 2005

1
2

}
}

3

C/C++

4

Fortran

Example A.34.2f

5
6
7
8

SUBROUTINE WORK(I, J)
INTEGER I, J
END SUBROUTINE WORK

9
10
11
12
13
14
15
16
17

SUBROUTINE WORK1(I, N)
INTEGER J!$OMP PARALLEL DEFAULT(SHARED)!$OMP DODO J = 1, N
CALL WORK(I,J)
END DO!$OMP END PARALLELEND SUBROUTINE WORK1

18
19
20
21
22
23
24
25
26

SUBROUTINE GOOD_NESTING2(N)INTEGER N!$OMP PARALLEL DEFAULT(SHARED)!$OMP DODO I = 1, N
CALL WORK1(I, N)
END DO!$OMP END PARALLELEND SUBROUTINE GOOD_NESTING2

Fortran

27

28

A.35

Restrictions on Nesting of Regions

29
30

The examples in this section illustrate the region nesting rules. For more information on
region nesting, see Section 2.9 on page 87.

31
32

The following example is non-conforming because the inner and outer loop regions areclosely nested:

C/C++

33
34

Example A.35.1c

35void work(int i, int j) {}36

void wrong1(int n)

37

Appendix A

Examples

187

1
2
3
4
5
6
7
8
9
10
11
12
13

{
#pragma omp parallel default(shared){
int i, j;#pragma omp forfor (i=0; i<n; i++) {/* incorrect nesting of loop regions */#pragma omp forfor (j=0; j<n; j++)work(i, j);
}
}
}

14

C/C++

15

Fortran

Example A.35.1f

16
17
18
19

SUBROUTINE WORK(I, J)
INTEGER I, J
END SUBROUTINE WORK

20
21

SUBROUTINE WRONG1(N)INTEGER N

22
23
24
25
26
27
28
29
30
31
32

INTEGER I,J
PARALLEL DEFAULT(SHARED)DO
DO I = 1, N!$OMP
DO! incorrect nesting of loop regions
DO J = 1, N
CALL WORK(I,J)
END DOEND DO!$OMP
END PARALLELEND SUBROUTINE WRONG1
!$OMP
!$OMP

Fortran

33

The following orphaned version of the preceding example is also non-conforming:

34

C/C++

35
36

Example A.35.2c

37
38
39
40
41
42
43

void work1(int i, int n){
int j;/* incorrect nesting of loop regions */#pragma omp forfor (j=0; j<n; j++)work(i, j);

44

188

OpenMP API • Version 2.5 May 2005

1

}

2
3
4
5
6
7
8
9
10
11

void wrong2(int n){#pragma omp parallel default(shared){
int i;#pragma omp forfor (i=0; i<n; i++)work1(i, n);
}
}

12

C/C++

13

Fortran

14

Example A.35.2f

15
16
17
18
19
20
21
22

SUBROUTINE WORK1(I,N)
INTEGER I, N

!$OMP

23
24
25
26
27
28
29
30
31
32

INTEGER J
DO! incorrect nesting of loop regions
DO J = 1, N
CALL WORK(I,J)
END DOEND SUBROUTINE WORK1
SUBROUTINE WRONG2(N)INTEGER NINTEGER IPARALLEL DEFAULT(SHARED)DO
DO I = 1, N
CALL WORK1(I,N)
END DO!$OMP
END PARALLELEND SUBROUTINE WRONG2
!$OMP
!$OMP

33

Fortran

34
35

The following example is non-conforming because the loop and single regions areclosely nested:

C/C++

36
37

Example A.35.3c

38
39void wrong3(int n){

40

Appendix A

Examples

189

1
2
3
4
5
6
7
8
9
10
11

#pragma omp parallel default(shared){
int i;#pragma omp forfor (i=0; i<n; i++) {/* incorrect nesting of regions */#pragma omp single
work(i, 0);
}
}
}

12

C/C++

13

Fortran

Example A.35.3f

14
15
16

SUBROUTINE WRONG3(N)INTEGER N

17
18
19
20
21
22
23
24
25
26

INTEGER IPARALLEL DEFAULT(SHARED)DO
DO I = 1, N!$OMP
SINGLE! incorrect nesting of regions
CALL WORK(I, 1)!$OMP
END SINGLE
END DO!$OMP
END PARALLELEND SUBROUTINE WRONG3
!$OMP
!$OMP

27

Fortran

28
29

The following example is non-conforming because a barrier region cannot be closely
nested inside a loop region:

C/C++

30
31

Example A.35.4c

32
33void wrong4(int n)
{

34
35
36
37
38
39
40
41

#pragma omp parallel default(shared){
int i;#pragma omp forfor (i=0; i<n; i++) {work(i, 0);/* incorrect nesting of barrier region in a loop region */#pragma omp barrier

42

190

OpenMP API • Version 2.5 May 2005

1
2
3
4

work(i, 1);
}
}
}

5

C/C++

6

Fortran

7

Example A.35.4f

8
9
10
11
12
13
14
15
16
17
18
19
20

SUBROUTINE WRONG4(N)INTEGER NINTEGER IPARALLEL DEFAULT(SHARED)DO
DO I = 1, N
CALL WORK(I, 1)! incorrect nesting of barrier region in a loop region!$OMP
BARRIERCALL WORK(I, 2)
END DO!$OMP
END PARALLELEND SUBROUTINE WRONG4
!$OMP
!$OMP

21

Fortran

22
23
24

The following example is non-conforming because the barrier region cannot be
closely nested inside the critical region. If this were permitted, it would result in
deadlock due to the fact that only one thread at a time can enter the critical region:

C/C++

25
26

Example A.35.5c

27
28
29
30
31
32
33
34
35
36
37
38
39

void wrong5(int n){#pragma omp parallel{#pragma omp critical{work(n, 0);/* incorrect nesting of barrier region in a critical region */#pragma omp barrier
work(n, 1);
}
}
}

40

41

C/C++

Appendix A

Examples191Fortran

1

Example A.35.5f

2
3
4

SUBROUTINE WRONG5(N)INTEGER N

5
6
7
8
9
10
11
12
13

!$OMP
!$OMP

PARALLEL DEFAULT(SHARED)CRITICALCALL WORK(N,1)! incorrect nesting of barrier region in a critical region!$OMP
BARRIERCALL WORK(N,2)!$OMP
END CRITICAL!$OMP
END PARALLELEND SUBROUTINE WRONG5

Fortran

14

The following example is non-conforming because the barrier region cannot be
closely nested inside the single region. If this were permitted, it would result in
deadlock due to the fact that only one thread executes the single region:

15
16
17

C/C++

18
19

Example A.35.6c

20
21
22
23
24
25
26
27
28
29
30
31
32

void wrong6(int n){#pragma omp parallel{#pragma omp single{
work(n, 0);/* incorrect nesting of barrier region in a single region */#pragma omp barrier
work(n, 1);
}
}
}

33

C/C++

34

Fortran

Example A.35.6f

35
36
37

SUBROUTINE WRONG6(N)INTEGER N

38
39
40
41

42

!$OMP
!$OMP

PARALLEL DEFAULT(SHARED)SINGLECALL WORK(N,1)! incorrect nesting of barrier region in a single region

192

OpenMP API • Version 2.5 May 2005

1
2
3
4
5

!$OMP

BARRIERCALL WORK(N,2)!$OMP
END SINGLE!$OMPEND PARALLELEND SUBROUTINE WRONG6

Fortran

6

8

The omp_set_dynamic andomp_set_num_threads Routines

9
10
11
12
13
14

Some programs rely on a fixed, prespecified number of threads to execute correctly.
Because the default setting for the dynamic adjustment of the number of threads is
implementation defined, such programs can choose to turn off the dynamic threads
capability and set the number of threads explicitly to ensure portability. The following
example shows how to do this using omp_set_dynamic (Section 3.2.7 on page 97),
and omp_set_num_threads (Section 3.2.1 on page 91).

15
16
17
18
19
20

In this example, the program executes correctly only if it is executed by 16 threads. If
the implementation is not capable of supporting 16 threads, the behavior of this example
is implementation defined. Note that the number of threads executing a parallel
region remains constant during the region, regardless of the dynamic threads setting.
The dynamic threads mechanism determines the number of threads to use at the start ofthe parallel region and keeps it constant for the duration of the region.

7

A.36

C/C++

21
22

Example A.36.1c

23
24#include <omp.h>#include <stdlib.h>25

void do_by_16(float *x, int iam, int ipoints) {}

26
27
28

void a36(float *x, int npoints){
int iam, ipoints;

2930

omp_set_dynamic(0);omp_set_num_threads(16);

31
32
33
34

#pragma omp parallel shared(x, npoints) private(iam, ipoints){
if (omp_get_num_threads() != 16)abort();

35

Appendix A

Examples

193

1
2
3
4
5

iam = omp_get_thread_num();
ipoints = npoints/16;
do_by_16(x, iam, ipoints);
}
}

6

C/C++

7

Fortran

Example A.36.1f

8
9
10
11
12

SUBROUTINE DO_BY_16(X, IAM, IPOINTS)
REAL X(*)
INTEGER IAM, IPOINTSEND SUBROUTINE DO_BY_16

13

SUBROUTINE SUBA36(X, NPOINTS)

14

INCLUDE "omp_lib.h"15
16

INTEGER NPOINTSREAL X(NPOINTS)

17

INTEGER IAM, IPOINTS

18
19

CALL OMP_SET_DYNAMIC(.FALSE.)
CALL OMP_SET_NUM_THREADS(16)

20

!$OMP

! or USE OMP_LIB

PARALLEL SHARED(X,NPOINTS) PRIVATE(IAM, IPOINTS)

21
22
23

IF (OMP_GET_NUM_THREADS() .NE. 16) THEN
STOP
ENDIF

24
25
26

IAM = OMP_GET_THREAD_NUM()
IPOINTS = NPOINTS/16
CALL DO_BY_16(X,IAM,IPOINTS)
!$OMP

27
28

END PARALLELEND SUBROUTINE SUBA36

Fortran

29

30

194

OpenMP API • Version 2.5 May 2005

1
2
3
4
5

A.37

The omp_get_num_threads Routine
In the following example, the omp_get_num_threads call (see Section 3.2.2 on
page 93) returns 1 in the sequential part of the code, so np will always be equal to 1. To
determine the number of threads that will be deployed for the parallel region, thecall should be inside the parallel region.

C/C++

6
7

Example A.37.1c

89#include <omp.h>
void work(int i);

10
11
12

void incorrect(){
int np, i;

13

np = omp_get_num_threads();

14
15
16
17

#pragma omp parallel for schedule(static)for (i=0; i < np; i++)work(i);/* misplaced */

}

18

C/C++

19

Fortran

20

Example A.37.1f

21
22
23
24

SUBROUTINE WORK(I)INTEGER I
I = I + 1
END SUBROUTINE WORK

25
26
27

SUBROUTINE INCORRECT()INCLUDE "omp_lib.h"
INTEGER I, NP

28
29
30
31
32
33
34
35

36

! or USE OMP_LIB

NP = OMP_GET_NUM_THREADS()!misplaced: will return 1
PARALLEL DO SCHEDULE(STATIC)DO I = 0, NP-1
CALL WORK(I)
ENDDO
!$OMP
END PARALLEL DO
END SUBROUTINE INCORRECT!$OMPFortranAppendix A

Examples195

The following example shows how to rewrite this program without including a query forthe number of threads:

1
2

C/C++

3
4

Example A.37.2c

56#include <omp.h>
void work(int i);

78
9void correct(){
int i;

10
11
12
13
14
15

#pragma omp parallel private(i){i = omp_get_thread_num();work(i);
}
}

16

C/C++

17

Fortran

Example A.37.2f

18
19
20

SUBROUTINE WORK(I)INTEGER I

21

I = I + 1

22

END SUBROUTINE WORK

23
24
25

SUBROUTINE CORRECT()INCLUDE "omp_lib.h"
INTEGER I

26
27
28
29

!$OMP

!$OMP

30

PARALLEL PRIVATE(I)I = OMP_GET_THREAD_NUM()
CALL WORK(I)END PARALLELEND SUBROUTINE CORRECT

Fortran

31

32! or USE OMP_LIB

196

OpenMP API • Version 2.5 May 2005

1
2
3

A.38

The omp_init_lock Routine
The following example demonstrates how to initialize an array of locks in a parallel
region by using omp_init_lock (Section 3.3.1 on page 104).

C/C++

4
5

Example A.38.1c

6#include <omp.h>

7
8
9
10

omp_lock_t *new_locks(){
int i;
omp_lock_t *lock = new omp_lock_t[1000];

11
12
13
14
15
16
17

#pragma omp parallel for private(i)for (i=0; i<1000; i++){
omp_init_lock(&lock[i]);}return lock;
}

18

C/C++

19

Fortran

20

Example A.38.1f

21
22
23

FUNCTION NEW_LOCKS()USE OMP_LIB! or INCLUDE "omp_lib.h"
INTEGER(OMP_LOCK_KIND), DIMENSION(1000) :: NEW_LOCKS

24
25
26
27
28
29
30
31

32

INTEGER I
!$OMP

!$OMP

PARALLEL DO PRIVATE(I)DO I=1,1000
CALL OMP_INIT_LOCK(NEW_LOCKS(I))
END DOEND PARALLEL DO
END FUNCTION NEW_LOCKS

FortranAppendix A

Examples

197

1

A.39

Simple Lock Routines

2
3
4
5

In the following example (for Section 3.3 on page 102), the lock routines cause thethreads to be idle while waiting for entry to the first critical section, but to do other work
while waiting for entry to the second. The omp_set_lock function blocks, but the
omp_test_lock function does not, allowing the work in skip to be done.

678Note that the argument to the lock routines should have type omp_lock_t, and that
there is no need to flush it.

9

Example A.39.1c

1011#include <stdio.h>#include <omp.h>12
13

void skip(int i) {}void work(int i) {}

14
15
16
17

int main(){
omp_lock_t lck;int id;C/C++

18

omp_init_lock(&lck);

19
20
21

#pragma omp parallel shared(lck) private(id){id = omp_get_thread_num();

22
23
24
25

omp_set_lock(&lck);/* only one thread at a time can execute this printf */printf("My thread id is %d.\n", id);
omp_unset_lock(&lck);

26
27
28
29

while (! omp_test_lock(&lck)) {skip(id);/* we do not yet have the lock,so we must do something else */
}

30
31

work(id);

omp_unset_lock(&lck);

32
33

34

/* we now have the lockand can do the work */}198

OpenMP API • Version 2.5 May 20051
2
3

omp_destroy_lock(&lck);
return 0;
}

4

C/C++

5

Fortran6Note that there is no need to flush the lock variable.

7

Example A.39.1f

8
9

SUBROUTINE SKIP(ID)
END SUBROUTINE SKIP

1011

SUBROUTINE WORK(ID)
END SUBROUTINE WORK

12

PROGRAM A39

13

INCLUDE "omp_lib.h"1415

INTEGER(OMP_LOCK_KIND) LCKINTEGER ID

16

CALL OMP_INIT_LOCK(LCK)

17
18
19
20
21

!$OMP

! or USE OMP_LIB

PARALLEL SHARED(LCK) PRIVATE(ID)ID = OMP_GET_THREAD_NUM()
CALL OMP_SET_LOCK(LCK)
PRINT *, ’My thread id is ’, ID
CALL OMP_UNSET_LOCK(LCK)

22
23
24
25

DO WHILE (.NOT. OMP_TEST_LOCK(LCK))CALL SKIP(ID)! We do not yet have the lock! so we must do something else
END DO

26
27

CALL WORK(ID)28

CALL OMP_UNSET_LOCK( LCK )

29
30

31

!$OMP

! We now have the lock! and can do the work

END PARALLELCALL OMP_DESTROY_LOCK( LCK )Appendix A

Examples199

1

END PROGRAM A39

Fortran

2

3

A.40

Nestable Lock Routines
The following example (for Section 3.3 on page 102) demonstrates how a nestable lockcan be used to synchronize updates both to a whole structure and to one of its members.

4
5

C/C++

6
7

Example A.40.1c

8#include <omp.h>

9
10
11

typedef struct {int a,b;omp_nest_lock_t lck; } pair;

12
13
14

int work1();
int work2();
int work3();

15
16
17
18
19

void incr_a(pair *p, int a){/* Called only from incr_pair, no need to lock. */p->a += a;
}

20
21
22
23

void incr_b(pair *p, int b){/* Called both from incr_pair and elsewhere, *//* so need a nestable lock. */omp_set_nest_lock(&p->lck);p->b += b;
omp_unset_nest_lock(&p->lck);

24
25
26
27

}

28
29
30
31
32
33
34
35
36

void incr_pair(pair *p, int a, int b){
omp_set_nest_lock(&p->lck);
incr_a(p, a);incr_b(p, b);
omp_unset_nest_lock(&p->lck);}
void a40(pair *p)
{

37

200

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7
8

#pragma omp parallel sections{#pragma omp section
incr_pair(p, work1(), work2());#pragma omp section
incr_b(p, work3());
}
}

9

C/C++

10

Fortran

11

Example A.40.1f

12
13
14
15
16
17
18
19

MODULE DATAUSE OMP_LIB, ONLY: OMP_NEST_LOCK_KIND
TYPE LOCKED_PAIR
INTEGER AINTEGER B
INTEGER (OMP_NEST_LOCK_KIND) LCKEND TYPE
END MODULE DATA

20
21
22
23
24
25
26

SUBROUTINE INCR_A(P, A)! called only from INCR_PAIR, no need to lock
USE DATATYPE(LOCKED_PAIR) :: P
INTEGER A
P%A = P%A + A
END SUBROUTINE INCR_A

27
28
29
30
31
32
33
34
35
36
37

SUBROUTINE INCR_B(P, B)! called from both INCR_PAIR and elsewhere,! so we need a nestable lock
USE OMP_LIB! or INCLUDE "omp_lib.h"
USE DATATYPE(LOCKED_PAIR) :: P
INTEGER B
CALL OMP_SET_NEST_LOCK(P%LCK)
P%B = P%B + B
CALL OMP_UNSET_NEST_LOCK(P%LCK)END SUBROUTINE INCR_B

38
39
40
41
42
43

SUBROUTINE INCR_PAIR(P, A, B)
USE OMP_LIB! or INCLUDE "omp_lib.h"
USE DATATYPE(LOCKED_PAIR) :: P
INTEGER AINTEGER B

44

Appendix A

Examples

201

1
2
3
4
5

CALL OMP_SET_NEST_LOCK(P%LCK)CALL INCR_A(P, A)
CALL INCR_B(P, B)
CALL OMP_UNSET_NEST_LOCK(P%LCK)END SUBROUTINE INCR_PAIR

6
7
8
9
10
11

SUBROUTINE A40(P)USE OMP_LIB! or INCLUDE "omp_lib.h"
USE DATATYPE(LOCKED_PAIR) :: P
INTEGER WORK1, WORK2, WORK3
EXTERNAL WORK1, WORK2, WORK3

12

!$OMP

PARALLEL SECTIONS

13
14
15
16
17

!$OMP

SECTIONCALL INCR_PAIR(P, WORK1(), WORK2())
SECTIONCALL INCR_B(P, WORK3())
END PARALLEL SECTIONS

!$OMP
!$OMP

18

END SUBROUTINE A40

Fortran

19

20

202

OpenMP API • Version 2.5 May 2005

1

APPENDIX

B

3

Stubs for Runtime Library
Routines

4
5
6
7
8

This section provides stubs for the runtime library routines defined in the OpenMP API.
The stubs are provided to enable portability to platforms that do not support theOpenMP API. On these platforms, OpenMP programs must be linked with a library
containing these stub routines. The stub routines assume that the directives in the
OpenMP program are ignored. As such, they emulate serial semantics.

9
10
11

Note that the lock variable that appears in the lock routines must be accessed exclusively
through these routines. It should not be initialized or otherwise modified in the user
program.

12

Fortran

13
14
15
16

For the stub routines written in Fortran, the lock variable is declared as a POINTER toguarantee that it is capable of holding an address. Alternatively, for Fortran 90
implementations, it could be declared as an INTEGER(OMP_LOCK_KIND) or
INTEGER(OMP_NEST_LOCK_KIND), as appropriate.

17

Fortran

18
19
20
21

In an actual implementation the lock variable might be used to hold the address of an
allocated object, but here it is used to hold an integer value. Users should not makeassumptions about mechanisms used by OpenMP implementations to implement locks
based on the scheme used by the stub procedures.

2

22

203

1

B.1

C/C++ Stub routines

2
3
4#include <stdio.h>#include <stdlib.h>#include "omp.h"5
6
7#ifdef __cplusplus
extern "C" {#endif8
910

void omp_set_num_threads(int num_threads)
{
}

11
12
13
14

int omp_get_num_threads(void){
return 1;
}

15
16
17
18

int omp_get_max_threads(void){
return 1;
}

19
20
21
22

int omp_get_thread_num(void){
return 0;
}

23
24
25
26

int omp_get_num_procs(void){
return 1;
}

27
28
29

void omp_set_dynamic(int dynamic_threads)
{
}

30

204

OpenMP API • Version 2.5 May 2005

1
2
3
4

int omp_get_dynamic(void){
return 0;
}

5
6
7
8

int omp_in_parallel(void){
return 0;
}

9
10
11

void omp_set_nested(int nested)
{
}

12
13
14
15

int omp_get_nested(void){
return 0;}

16

enum {UNLOCKED = -1, INIT, LOCKED};

17
18
19
20

void omp_init_lock(omp_lock_t *lock){*lock = UNLOCKED;
}

21
22
23
24

void omp_destroy_lock(omp_lock_t *lock){*lock = INIT;}

25

Appendix B

Stubs for Runtime Library Routines

205

1
2
3
4
5
6
7
8
9
10
11
12

void omp_set_lock(omp_lock_t *lock){if (*lock == UNLOCKED) {*lock = LOCKED;} else if (*lock == LOCKED) {fprintf(stderr, "error: deadlock in using lock variable\n");exit(1);} else {fprintf(stderr, "error: lock not initialized\n");exit(1);
}
}

13
14
15
16
17
18
19
20
21
22
23
24

void omp_unset_lock(omp_lock_t *lock){if (*lock == LOCKED) {*lock = UNLOCKED;} else if (*lock == UNLOCKED) {fprintf(stderr, "error: lock not set\n");exit(1);} else {fprintf(stderr, "error: lock not initialized\n");exit(1);
}
}

25
26
27
28
29
30
31
32
33
34
35
36

int omp_test_lock(omp_lock_t *lock){if (*lock == UNLOCKED) {*lock = LOCKED;
return 1;} else if (*lock == LOCKED) {return 0;} else {fprintf(stderr, "error: lock not initialized\n");exit(1);
}
}

37

206

OpenMP API • Version 2.5 May 2005

1

#ifndef OMP_NEST_LOCK_T

2
3
4
5

typedef struct { /* This really belongs in omp.h */int owner;
int count;} omp_nest_lock_t;

6#endif7

enum {NOOWNER=-1, MASTER = 0};

8
9
10
11
12

void omp_init_nest_lock(omp_nest_lock_t *nlock){nlock->owner = NOOWNER;
nlock->count = 0;
}

13
14
15
16
17

void omp_destroy_nest_lock(omp_nest_lock_t *nlock){nlock->owner = NOOWNER;
nlock->count = UNLOCKED;
}

18
19
20
21
22
23
24
25
26
27
28
29

void omp_set_nest_lock(omp_nest_lock_t *nlock){
if (nlock->owner == MASTER && nlock->count >= 1) {nlock->count++;} else if (nlock->owner == NOOWNER && nlock->count == 0) {nlock->owner = MASTER;
nlock->count = 1;
} else {fprintf(stderr, "error: lock corrupted or not initialized\n");exit(1);}}30

Appendix B

Stubs for Runtime Library Routines

207

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

void omp_unset_nest_lock(omp_nest_lock_t *nlock){
if (nlock->owner == NOOWNER && nlock->count >= 1) {nlock->count--;
if (nlock->count == 0) {nlock->owner = NOOWNER;}} else if (nlock->owner == NOOWNER && nlock->count == 0) {fprintf(stderr, "error: lock not set\n");exit(1);} else {fprintf(stderr, "error: lock corrupted or not initialized\n");exit(1);
}
}

16
17
18
19
20

int omp_test_nest_lock(omp_nest_lock_t *nlock){
omp_set_nest_lock(nlock);return nlock->count;
}

21
22
23
24
25
26
27
28

double omp_get_wtime(void){/* This function does not provide a working
wallclock timer. Replace it with a version
customized for the target machine.
*/
return 0.0;
}

29
30
31
32
33
34
35
36

double omp_get_wtick(void){/* This function does not provide a working
clock tick function. Replace it witha version customized for the target machine.
*/
return 365. * 86400.;}

37#ifdef __cplusplus

38

}

39

#endif

40

208

OpenMP API • Version 2.5 May 2005

1

B.2

Fortran Stub Routines

2
3
4
5

SUBROUTINE OMP_SET_NUM_THREADS(NUM_THREADS)INTEGER NUM_THREADS
RETURNEND SUBROUTINE

6
7
8
9

INTEGER FUNCTION OMP_GET_NUM_THREADS()OMP_GET_NUM_THREADS = 1
RETURNEND FUNCTION

10
11
12
13

INTEGER FUNCTION OMP_GET_MAX_THREADS()OMP_GET_MAX_THREADS = 1
RETURNEND FUNCTION

14
15
16
17

INTEGER FUNCTION OMP_GET_THREAD_NUM()
OMP_GET_THREAD_NUM = 0
RETURNEND FUNCTION

18
19
20
21

INTEGER FUNCTION OMP_GET_NUM_PROCS()OMP_GET_NUM_PROCS = 1
RETURNEND FUNCTION

22
23
24
25

SUBROUTINE OMP_SET_DYNAMIC(DYNAMIC_THREADS)LOGICAL DYNAMIC_THREADS
RETURNEND SUBROUTINE

26

Appendix B

Stubs for Runtime Library Routines

209

1
2
3
4

LOGICAL FUNCTION OMP_GET_DYNAMIC()OMP_GET_DYNAMIC = .FALSE.
RETURNEND FUNCTION

5
6
7
8

LOGICAL FUNCTION OMP_IN_PARALLEL()
OMP_IN_PARALLEL = .FALSE.
RETURNEND FUNCTION

9
10
11
12

SUBROUTINE OMP_SET_NESTED(NESTED)LOGICAL NESTEDRETURNEND SUBROUTINE

13
14
15
16

LOGICAL FUNCTION OMP_GET_NESTED()OMP_GET_NESTED = .FALSE.
RETURNEND FUNCTION

17
18
19
20
21
22

SUBROUTINE OMP_INIT_LOCK(LOCK)! LOCK is 0 if the simple lock is not initialized!
-1 if the simple lock is initialized but not set!
1 if the simple lock is set
POINTER (LOCK,IL)
INTEGER IL

23
24
25

LOCK = -1
RETURNEND SUBROUTINE

26
27
28

SUBROUTINE OMP_DESTROY_LOCK(LOCK)POINTER (LOCK,IL)
INTEGER IL

29
30
31

LOCK = 0
RETURNEND SUBROUTINE

32

210

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7
8
9
10
11
12

SUBROUTINE OMP_SET_LOCK(LOCK)POINTER (LOCK,IL)
INTEGER IL
IF (LOCK .EQ. -1) THENLOCK = 1
ELSEIF (LOCK .EQ. 1) THEN
PRINT *, ’ERROR: DEADLOCK IN USING LOCK VARIABLE’
STOP
ELSE
PRINT *, ’ERROR: LOCK NOT INITIALIZED’
STOP
ENDIF

13
14

RETURNEND SUBROUTINE

15
16
17

SUBROUTINE OMP_UNSET_LOCK(LOCK)POINTER (LOCK,IL)
INTEGER IL

18
19
20
21
22
23
24
25
26
27
28

29

IF (LOCK .EQ. 1) THENLOCK = -1
ELSEIF (LOCK .EQ. -1) THEN
PRINT *, ’ERROR: LOCK NOT SET’
STOP
ELSE
PRINT *, ’ERROR: LOCK NOT INITIALIZED’
STOP
ENDIF
RETURNEND SUBROUTINE

Appendix B

Stubs for Runtime Library Routines

211

1
2
3

LOGICAL FUNCTION OMP_TEST_LOCK(LOCK)POINTER (LOCK,IL)
INTEGER IL

4
5
6
7
8
9
10
11
12

IF (LOCK .EQ. -1) THENLOCK = 1
OMP_TEST_LOCK = .TRUE.
ELSEIF (LOCK .EQ. 1) THEN
OMP_TEST_LOCK = .FALSE.
ELSE
PRINT *, ’ERROR: LOCK NOT INITIALIZED’
STOP
ENDIF

13
14

RETURNEND FUNCTION

15
16
17
18
19
20
21

SUBROUTINE OMP_INIT_NEST_LOCK(NLOCK)! NLOCK is 0 if the nestable lock is not initialized!
-1 if the nestable lock is initialized but not set!
1 if the nestable lock is set! no use count is maintained
POINTER (NLOCK,NIL)
INTEGER NIL

22

NLOCK = -1

23
24

RETURNEND SUBROUTINE

25
26
27

SUBROUTINE OMP_DESTROY_NEST_LOCK(NLOCK)POINTER (NLOCK,NIL)
INTEGER NIL

28

NLOCK = 029
30

RETURNEND SUBROUTINE

31

212

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7
8
9
10
11
12

SUBROUTINE OMP_SET_NEST_LOCK(NLOCK)POINTER (NLOCK,NIL)
INTEGER NIL
IF (NLOCK .EQ. -1) THENNLOCK = 1
ELSEIF (NLOCK .EQ. 0) THEN
PRINT *, ’ERROR: NESTED LOCK NOT INITIALIZED’
STOP
ELSE
PRINT *, ’ERROR: DEADLOCK USING NESTED LOCK VARIABLE’
STOP
ENDIF

13
14

RETURNEND SUBROUTINE

15
16
17

SUBROUTINE OMP_UNSET_NEST_LOCK(NLOCK)POINTER (NLOCK,IL)
INTEGER IL

18
19
20
21
22
23
24
25
26
27
28

29

IF (NLOCK .EQ. 1) THENNLOCK = -1
ELSEIF (NLOCK .EQ. 0) THEN
PRINT *, ’ERROR: NESTED LOCK NOT INITIALIZED’
STOP
ELSE
PRINT *, ’ERROR: NESTED LOCK NOT SET’
STOP
ENDIF
RETURNEND SUBROUTINE

Appendix B

Stubs for Runtime Library Routines

213

1
2
3

INTEGER FUNCTION OMP_TEST_NEST_LOCK(NLOCK)POINTER (NLOCK,NIL)
INTEGER NIL

4
5
6
7
8
9
10
11
12

IF (NLOCK .EQ. -1) THENNLOCK = 1
OMP_TEST_NEST_LOCK = 1
ELSEIF (NLOCK .EQ. 1) THEN
OMP_TEST_NEST_LOCK = 0
ELSE
PRINT *, ’ERROR: NESTED LOCK NOT INITIALIZED’
STOP
ENDIF

13
14

RETURNEND SUBROUTINE

15
16
17
18

DOUBLE PRECISION FUNCTION OMP_GET_WTIME()! This function does not provide a working! wall clock timer. Replace it with a version! customized for the target machine.
OMP_WTIME = 0.0D0

19
20
21

RETURNEND FUNCTION

22
23
24
25
26
27

DOUBLE PRECISION FUNCTION OMP_GET_WTICK()! This function does not provide a working! clock tick function. Replace it with! a version customized for the target machine.
DOUBLE PRECISION ONE_YEAR
PARAMETER (ONE_YEAR=365.D0*86400.D0)
OMP_WTICK = ONE_YEAR

28

RETURNEND FUNCTION

29
30

31

214

OpenMP API • Version 2.5 May 2005

1

APPENDIXOpenMP C and C++ Grammar

2

3

C

C.1

Notation

4
5

The grammar rules consist of the name for a non-terminal, followed by a colon,
followed by replacement alternatives on separate lines.

6
7

The syntactic expression termopt indicates that the term is optional within thereplacement.

8
9

The syntactic expression termoptseq is equivalent to term-seqopt with the following
additional rules:

10

term-seq :

11

term

12

term-seq term

13

term-seq , term

14

215

1

C.2

Rules

2
3
4

The notation is described in Section 6.1 of the C standard. This grammar appendix
shows the extensions to the base language grammar for the OpenMP C and C++
directives.

5/* in C++ (ISO/IEC 14882:1998) */6

statement-seq:7

statement

8

openmp-directive

9

statement-seq statement

10

statement-seq openmp-directive

11/* in C90 (ISO/IEC 9899:1990) */12

statement-list:

13

statement

14

openmp-directive

15

statement-list statement

16

statement-list openmp-directive

17/* in C99 (ISO/IEC 9899:1999) */18

block-item:

19

declaration

20

statement

21

openmp-directive

22

216

OpenMP API • Version 2.5 May 2005

1

statement:

2/* standard statements */3

openmp-construct4

openmp-construct:5

parallel-construct6

for-construct7

sections-construct8

single-construct9

parallel-for-construct10

parallel-sections-construct11

master-construct12

critical-construct13

atomic-construct

14

ordered-construct15

openmp-directive:

16

barrier-directive

17

flush-directive

18

structured-block:19

statement

20
21
22
23
24

parallel-construct:parallel-directive structured-blockparallel-directive:# pragma omp parallel parallel-clauseoptseq new-line
parallel-clause:

25

unique-parallel-clause26

data-clause

27

Appendix C

OpenMP C and C++ Grammar

217

unique-parallel-clause:12

if ( expression )3

num_threads ( expression )for-construct:4

for-directive iteration-statement5

for-directive:

6# pragma omp for for-clauseoptseq new-line

7

for-clause:

89unique-for-clause10

data-clause11

nowait12

unique-for-clause:

13

ordered14

schedule ( schedule-kind )15

schedule ( schedule-kind , expression )schedule-kind:

16
17

static18

dynamic

19

guided20

runtimesections-construct:

21

sections-directive section-scope

22

sections-directive:

23# pragma omp sections sections-clauseoptseq new-line

24

sections-clause:25
26

data-clause27

nowaitsection-scope:

28

29

218

OpenMP API • Version 2.5 May 2005

1
2

{ section-sequence }section-sequence:3

section-directiveopt structured-block4

section-sequence section-directive structured-block

5
6
7
8
9
10
11

section-directive:# pragma omp section new-line
single-construct:
single-directive structured-block

single-directive:# pragma omp single single-clauseoptseq new-line
single-clause:12

data-clause13

nowait14

parallel-for-construct:

15
16
17
18

parallel-for-directive iteration-statement

parallel-for-directive:# pragma omp parallel for parallel-for-clauseoptseq new-line
parallel-for-clause:

19

unique-parallel-clause

20

unique-for-clause21

data-clause22

parallel-sections-construct:

23
24
25
26

parallel-sections-directive section-scope

parallel-sections-directive:# pragma omp parallel sections parallel-sections-clauseoptseq new-line
parallel-sections-clause:27

unique-parallel-clause28

data-clause

29

Appendix C

OpenMP C and C++ Grammar

219

master-construct:1

master-directive structured-block2

master-directive:3# pragma omp master new-line

4

critical-construct:5

critical-directive structured-block6

critical-directive:

7# pragma omp critical region-phraseopt new-line

8

region-phrase:9( identifier )10barrier-directive:

11# pragma omp barrier new-line

12

atomic-construct:13

atomic-directive expression-statement

14

atomic-directive:

15# pragma omp atomic new-line

16

flush-directive:

17# pragma omp flush flush-varsopt new-line

18

flush-vars:

19( variable-list )20

ordered-construct:

21

ordered-directive structured-block22

ordered-directive:

23# pragma omp ordered new-line

24

declaration:

25
26/* standard declarations */27

threadprivate-directive

threadprivate-directive:

28

29

220

OpenMP API • Version 2.5 May 2005

1
2

# pragma omp threadprivate ( variable-list ) new-line
data-clause:

3

private ( variable-list )4

copyprivate ( variable-list )5

firstprivate ( variable-list )6

lastprivate ( variable-list )7

shared ( variable-list )8

default ( shared )9default ( none )10

reduction ( reduction-operator : variable-list )11

copyin ( variable-list )12
13

reduction-operator:
One of: + * - & ^ | && ||14/* in C */15

variable-list:

16

identifier

17

variable-list , identifier

18/* in C++ */19

variable-list:

20

id-expression

21

variable-list , id-expression

22

Appendix C

OpenMP C and C++ Grammar

221

1

222

OpenMP API • Version 2.5 May 2005

1

APPENDIX

D

2Interface Declarations

3
4
5

This appendix gives examples of the C/C++ header file, the Fortran include file andFortran 90 module that shall be provided by implementations as specified in Chapter 3.
It also includes an example of a Fortran 90 generic interface for a library routine.

6

D.1

Example of the omp.h Header File78#ifndef _OMP_H_DEF#define _OMP_H_DEF

9
10
11
12
13
14
15

/*
* define the lock data types*/#ifndef _OMP_LOCK_T_DEF#
define _OMP_LOCK_T_DEF
typedef struct __omp_lock *omp_lock_t;#endif

16
17
18
19

#ifndef _OMP_NEST_LOCK_T_DEF#
define _OMP_NEST_LOCK_T_DEF
typedef struct __omp_nest_lock *omp_nest_lock_t;#endif

20

223

1
2
3
4
5
6

/*
* exported OpenMP functions*/#ifdef __cplusplus
extern "C" {#endif

7
8
9
10
11
12
13
14
15
16
17
18

#if defined(__stdc__) || defined(__STDC__) ||defined(__cplusplus)
extern void
omp_set_num_threads(int num_threads);
extern int
omp_get_num_threads(void);
extern int
omp_get_max_threads(void);
extern int
omp_get_thread_num(void);
extern int
omp_get_num_procs(void);
extern int
omp_in_parallel(void);
extern void
omp_set_dynamic(int dynamic_threads);
extern int
omp_get_dynamic(void);
extern void
omp_set_nested(int nested);
extern int
omp_get_nested(void);

19
20
21
22
23

extern voidextern voidextern voidextern voidextern int

omp_init_lock(omp_lock_t *lock);
omp_destroy_lock(omp_lock_t *lock);
omp_set_lock(omp_lock_t *lock);
omp_unset_lock(omp_lock_t *lock);
omp_test_lock(omp_lock_t *lock);

24
25
26
27
28

extern voidextern voidextern voidextern voidextern int

omp_init_nest_lock(omp_nest_lock_t *lock);
omp_destroy_nest_lock(omp_nest_lock_t *lock);
omp_set_nest_lock(omp_nest_lock_t *lock);
omp_unset_nest_lock(omp_nest_lock_t *lock);
omp_test_nest_lock(omp_nest_lock_t *lock);29
30

extern double
extern double

omp_get_wtime(void);
omp_get_wtick(void);#else
extern voidextern int
extern int
extern int
extern int
extern int
extern void

31
32
33
34
35
36
37
38

39

224

omp_set_num_threads();
omp_get_num_threads();
omp_get_max_threads();
omp_get_thread_num();
omp_get_num_procs();
omp_in_parallel();
omp_set_dynamic();

OpenMP API • Version 2.5 May 2005

1
2
3

extern int
extern voidextern int

omp_get_dynamic();
omp_set_nested();
omp_get_nested();

4
5
6
7
8

extern voidextern voidextern voidextern voidextern int

omp_init_lock();
omp_destroy_lock();
omp_set_lock();
omp_unset_lock();
omp_test_lock();

9
10
11
12
13

extern voidextern voidextern voidextern voidextern int

omp_init_nest_lock();
omp_destroy_nest_lock();
omp_set_nest_lock();
omp_unset_nest_lock();
omp_test_nest_lock();

14
15
16
17
18
19

extern double omp_get_wtime();extern double omp_get_wtick();#endif#ifdef __cplusplus}#endif20#endif

21
22

23
24
25
26
27

28

D.2

Example of an Interface Declaration include
FileC

the "C" of this comment starts in column 1
integer
omp_lock_kindparameter ( omp_lock_kind = 8 )integer
omp_nest_lock_kindparameter ( omp_nest_lock_kind = 8 )Appendix DInterface Declarations

225

1
2
3

C
C
C

default integer type assumed below
default logical type assumed below
OpenMP Fortran API v2.5

45integer
openmp_version
parameter ( openmp_version = 200505 )6external omp_destroy_lock7

external omp_destroy_nest_lock89external omp_get_dynamic
logical omp_get_dynamic

10
11

external omp_get_max_threads
integer omp_get_max_threads

12
13

external omp_get_nested
logical omp_get_nested

1415

external omp_get_num_procs
integer omp_get_num_procs

16

external omp_get_num_threads

17

integer

18
19

external omp_get_thread_num
integer omp_get_thread_num

2021

external omp_get_wtick
double precision omp_get_wtick

22
23

external omp_get_wtime
double precision omp_get_wtime

24

external omp_init_lock25

external omp_init_nest_lock

26
27

external omp_in_parallel
logical omp_in_parallel

28

external omp_set_dynamic

29

external omp_set_lock

30

226

omp_get_num_threads

OpenMP API • Version 2.5 May 2005

1

external omp_set_nest_lock2

external omp_set_nested

3external omp_set_num_threads

45

external omp_test_locklogical omp_test_lock

6
7

external omp_test_nest_lock
integer omp_test_nest_lock8

external omp_unset_lock9

external omp_unset_nest_lock

10
11

12
13
14
15
16
17
18

19

D.3

Example of a Fortran 90 Interface Declaration
module!

the "!" of this comment starts in column 1
module omp_lib_kinds
integer, parameter :: omp_integer_kind
integer, parameter :: omp_logical_kind
integer, parameter :: omp_lock_kind
integer, parameter :: omp_nest_lock_kind

= 4
= 4
= 8
= 8

end module omp_lib_kinds

Appendix DInterface Declarations

227

1

module omp_lib

2

use omp_lib_kinds

3
4!

OpenMP Fortran API v2.5
integer, parameter :: openmp_version = 200505

5
6
7
8
9
10

interfacesubroutine omp_destroy_lock ( var )use omp_lib_kinds
integer ( kind=omp_lock_kind ), intent(inout) :: var
end subroutine omp_destroy_lock
end interface

11
12
13
14
15
16

interfacesubroutine omp_destroy_nest_lock ( var )use omp_lib_kinds
integer ( kind=omp_nest_lock_kind ), intent(inout) :: var
end subroutine omp_destroy_nest_lock
end interface

17
18
19
20
21
22

interface
function omp_get_dynamic ()use omp_lib_kinds
logical ( kind=omp_logical_kind ) :: omp_get_dynamic
end function omp_get_dynamic
end interface

23
24
25
26
27
28

interface
function omp_get_max_threads ()use omp_lib_kinds
integer ( kind=omp_integer_kind ) :: omp_get_max_threads
end function omp_get_max_threads
end interface

29
30
31
32
33
34

interface
function omp_get_nested ()use omp_lib_kinds
logical ( kind=omp_logical_kind ) :: omp_get_nested
end function omp_get_nested
end interface

35

228

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6

interface
function omp_get_num_procs ()use omp_lib_kinds
integer ( kind=omp_integer_kind ) :: omp_get_num_procs
end function omp_get_num_procs
end interface

7
8
9
10
11
12

interface
function omp_get_num_threads ()use omp_lib_kinds
integer ( kind=omp_integer_kind ) :: omp_get_num_threads
end function omp_get_num_threads
end interface

13
14
15
16
17
18

interface
function omp_get_thread_num ()use omp_lib_kinds
integer ( kind=omp_integer_kind ) :: omp_get_thread_num
end function omp_get_thread_num
end interface

19
20
21
22
23

interface
function omp_get_wtick ()double precision :: omp_get_wtick
end function omp_get_wtick
end interface

24
25
26
27
28

interface
function omp_get_wtime ()double precision :: omp_get_wtime
end function omp_get_wtime
end interface

29
30
31
32
33
34

interfacesubroutine omp_init_lock ( var )use omp_lib_kinds
integer ( kind=omp_lock_kind ), intent(out) :: var
end subroutine omp_init_lock
end interface

35
36
37
38
39
40

interfacesubroutine omp_init_nest_lock ( var )use omp_lib_kinds
integer ( kind=omp_nest_lock_kind ), intent(out) :: var
end subroutine omp_init_nest_lock
end interface

41

Appendix DInterface Declarations

229

1
2
3
4
5
6

interface
function omp_in_parallel ()use omp_lib_kinds
logical ( kind=omp_logical_kind ) :: omp_in_parallelend function omp_in_parallelend interface

7
8
9
10
11
12
13

interfacesubroutine omp_set_dynamic ( enable_expr )use omp_lib_kinds
logical ( kind=omp_logical_kind ), intent(in) :: &enable_expr
end subroutine omp_set_dynamic
end interface

&

14
15
16
17
18
19

interfacesubroutine omp_set_lock ( var )use omp_lib_kinds
integer ( kind=omp_lock_kind ), intent(inout) :: var
end subroutine omp_set_lock
end interface

20
21
22
23
24
25

interfacesubroutine omp_set_nest_lock ( var )use omp_lib_kinds
integer ( kind=omp_nest_lock_kind ), intent(inout) :: var
end subroutine omp_set_nest_lock
end interface

26
27
28
29
30
31
32

interfacesubroutine omp_set_nested ( enable_expr )use omp_lib_kinds
logical ( kind=omp_logical_kind ), intent(in) :: &enable_expr
end subroutine omp_set_nested
end interface

33

&

230

OpenMP API • Version 2.5 May 2005

1
2
3
4
5
6
7

&

interfacesubroutine omp_set_num_threads ( number_of_threads_expr )use omp_lib_kinds
integer ( kind=omp_integer_kind ), intent(in) :: &number_of_threads_expr
end subroutine omp_set_num_threads
end interface

8
9
10
11
12
13
14

interface
function omp_test_lock ( var )use omp_lib_kinds
logical ( kind=omp_logical_kind ) :: omp_test_lock
integer ( kind=omp_lock_kind ), intent(inout) :: var
end function omp_test_lock
end interface

15
16
17
18
19
20
21

interface
function omp_test_nest_lock ( var )use omp_lib_kinds
integer ( kind=omp_integer_kind ) :: omp_test_nest_lock
integer ( kind=omp_nest_lock_kind ), intent(inout) :: var
end function omp_test_nest_lock
end interface

22
23
24
25
26
27

interfacesubroutine omp_unset_lock ( var )use omp_lib_kinds
integer ( kind=omp_lock_kind ), intent(inout) :: var
end subroutine omp_unset_lock
end interface

28
29
30
31
32
33

interfacesubroutine omp_unset_nest_lock ( var )use omp_lib_kinds
integer ( kind=omp_nest_lock_kind ), intent(inout) :: var
end subroutine omp_unset_nest_lock
end interface

34

35

end module omp_lib

Appendix DInterface Declarations

231

D.4

2

Example of a Generic Interface for a Library
Routine3
4

Any of the OMP runtime library routines that take an argument may be extended with ageneric interface so arguments of different KIND type can be accommodated.

5
6
7
8

Assume an implementation supports both default INTEGER as KIND =OMP_INTEGER_KIND and another INTEGER KIND, KIND = SHORT_INT. ThenOMP_SET_NUM_THREADS could be specified in the omp_lib module as thefollowing:

1

9
10

!

the "!" of this comment starts in column 1
interface omp_set_num_threads

11
12
13
14
15

subroutine omp_set_num_threads_1 ( number_of_threads_expr )use omp_lib_kinds
integer ( kind=omp_integer_kind ), intent(in) :: &&number_of_threads_expr
end subroutine omp_set_num_threads_1

16
17
18
19
20

subroutine omp_set_num_threads_2 ( number_of_threads_expr )use omp_lib_kinds
integer ( kind=short_int ), intent(in) :: &&number_of_threads_expr
end subroutine omp_set_num_threads_2

21

end interface omp_set_num_threads

22

232

OpenMP API • Version 2.5 May 2005

1

APPENDIX

E

3Implementation Defined
Behaviors in OpenMP

4
5
6
7

This appendix summarizes the behaviors that are described as implementation defined inthis API. Each behavior is cross-referenced back to its description in the main
specification. An implementation is required to define and document its behavior inthese cases.

8
910• Memory model: it is implementation defined as to whether, and in what sizes,

11
12
13
14

• Internal control variables: the number of copies of the internal control variables,

15
16• Nested parallelism: the number of levels of parallelism supported is implementation

17
18
19
20
21
22

• Dynamic adjustment of threads: it is implementation defined whether the ability to

23
24• sections construct: the method of scheduling the structured blocks among threads

25
26• single construct: the method of choosing a thread to execute the structured block

27
28
29
30

• atomic construct: a compliant implementation may enforce exclusive access2

31

memory accesses by multiple threads to the same variable without synchronization
are atomic with respect to each other (see Section 1.4.1 on page 10).
and their effects, during the execution of any explicit parallel region are
implementation defined. The initial values of nthreads-var, dyn-var, run-sched-var,
and def-sched-var are implementation defined (see Section 2.3 on page 24).
defined (see Section 1.2.4 on page 8 and Section 2.4.1 on page 29).
dynamically adjust the number of threads is provided. Implementations are allowed todeliver fewer threads (but at least one) than indicated in Figure 2-1 in exceptionalsituations, such as when there is a lack of resources, even if dynamic adjustment isdisabled. In these situations, the behavior of the program is implementation defined(see Section 2.4.1 on page 29).
in the team is implementation defined (see Section 2.5.2 on page 39).
is implementation defined (see Section 2.5.3 on page 42).
between atomic regions which update different storage locations. The
circumstances under which this occurs are implementation defined (see Section 2.7.4
on page 55).

233

1
2
3
4
5
6
7

• omp_set_num_threads routine: when called from within any explicit

8
9
10
11

• omp_get_max_threads routine: when called from within any explicit

12
13
14
15
16

• omp_set_dynamic routine: when called from within any explicit parallel

17
18
19
20

• omp_get_dynamic routine: when called from within any explicit parallel

21
22
23
24
25

• omp_set_nested routine: when called from within any explicit parallel

26
27
28
29

• omp_get_nested routine: when called from within any explicit parallel

30
31
32
33

• OMP_NUM_THREADS environment variable: if the requested value ofparallel region, the binding thread set (and binding region, if required) for the
omp_set_num_threads region is implementation defined. If the number of
threads requested exceeds the number the implementation can support, or is not a
positive integer, the behavior of this routine is implementation defined. If this routine
is called from within any explicit parallel region, the behavior of this routine is
implementation defined (see Section 3.2.1 on page 91).
parallel region, the binding thread set (and binding region, if required) for the
omp_get_max_threads region is implementation defined (see Section 3.2.3 on
page 94).
region, the binding thread set (and binding region, if required) for the
omp_set_dynamic region is implementation defined. If called from within any
explicit parallel region, the behavior of this routine is implementation defined(see Section 3.2.7 on page 97).
region, the binding thread set (and binding region, if required) for the
omp_get_dynamic region is implementation defined (see Section 3.2.8 on page99).
region, the binding thread set (and binding region, if required) for the
omp_set_nested region is implementation defined. If called from within any
explicit parallel region, the behavior of this routine is implementation defined(see Section 3.2.9 on page 100).
region, the binding thread set (and binding region, if required) for the
omp_get_nested region is implementation defined (see Section 3.2.10 on page101).
OMP_NUM_THREADS is greater than the number of threads an implementation can
support, or if the value is not a positive integer, the behavior of the program is
implementation defined (see Section 4.2 on page 115).

34

Fortran

35
36
37
38

• threadprivate directive: if the conditions for values of data in the threadprivate

39

objects of threads (other than the initial thread) to persist between two consecutive
active parallel regions do not all hold, the allocation status of an allocatable arrayin the second region is implementation defined (see Section 2.8.2 on page 66).

234

OpenMP API • Version 2.5 May 2005

1
2
3
4
5

• shared clause: passing a shared variable to a non-intrinsic procedure may result in

6
7
8
9
10

• Runtime library definitions: it is implementation defined whether the include file11

Fortran12

the value of the shared variable being copied into temporary storage before theprocedure reference, and back out of the temporary storage into the actual argument
storage after the procedure reference. Situations where this occurs other than thosespecified are implementation defined (see Section 2.8.3.2 on page 72).
omp_lib.h or the module file omp_lib (or both) is provided. It is
implementation defined whether any of the OpenMP runtime library routines thattake an argument are extended with a generic interface so arguments of different
KIND type can be accommodated (see Section 3.1 on page 90).

Chapter E

Implementation Defined Behaviors in OpenMP

235

1

236

OpenMP API • Version 2.5 May 2005

1

APPENDIX

F

3

Changes from Version 2.0 to
Version 2.5

4
5
6
7
8
9

This appendix summarizes the major changes between the OpenMP API Version 2.0
specifications and the OpenMP API Version 2.5 specification. There are no additional
language features in Version 2.5. However, large parts of the text have been rewritten
and restructured in order to accommodate all the base languages in a single document,
and a number of inconsistencies have been resolved. Only the major changes are listed
here.

10

Terminology

11
12

Many terms have been redefined, and the Glossary (Section 1.2 on page 2) has beensignificantly extended. In particular, readers should note the following changes:

1314• The Glossary contains new definitions of construct and region. The terms lexical

15
16• The term parallel region is no longer used. Instead, the terms parallel construct

17• The term serial region is no longer used: this has been replaced with sequential part.

18• The Glossary defines binding in terms of binding thread set and binding region.

19
20• The term serialize is no longer used. The terms active and inactive parallel

21• The definition of variable differs from the previous definitions.

22• The Glossary defines what is meant by supporting nested parallelism.

23

Memory model

24
25
26

Version 2.5 contains a description of the OpenMP memory model (see Section 1.4 on
page 10). This describes the underlying consistency model assumed by OpenMP, anddefines the flush operation. It also describes the circumstances under which it is2

27

extent and dynamic extent are no longer used.
and parallel region are used, as appropriate.

region are used instead.

237

1
2
3
4

permitted for one thread to access private variables belonging to another thread. The
memory model states that a race condition on a shared variable results in unspecified
behavior. The relationship between the flush operation and the volatile keyword in
the C and C++ languages is explained.

5

Fortran

6

PURE and ELEMENTAL Procedures

7
8

OpenMP directives and runtime library routine calls may not appear in PURE or
ELEMENTAL procedures.

Fortran910Internal Control Variables

11
12
13
14
15

Version 2.5 introduces the notion of internal control variables (see Section 2.3 on page24), that store the information for determining the number of threads to use for aparallel region and how to schedule a work-sharing loop. The behavior of certain
execution environment routines (see Section 3.2 on page 91) and environment variables(see Chapter 4) is described in terms of the internal control variables.

16

Determining the Number of Threads for a parallel Region

17
18

The rules which determine the number of threads to use for a parallel region havebeen clarified. See Section 2.4.1 on page 29.

19

Loop Construct

20
21
22

The definition of the guided schedule kind has been relaxed: the size of each chunk is
proportional to the number of unassigned iterations divided by the number of threads.
See Section 2.5.1 on page 33.

23

sections Construct24
25

The method of scheduling the structured blocks among threads in the team is
implementation defined in Version 2.5. See Section 2.5.2 on page 39.

26

single Construct27
28

The method of choosing a thread to execute the structured block is implementation
defined in Version 2.5. See Section 2.5.3 on page 42.

29

238

OpenMP API • Version 2.5 May 2005

1

critical Construct2
3

The term critical section is no longer used. Instead, the terms critical construct andcritical region are used, as appropriate.

4

flush Construct

5
6
7
8
9
10

In Version 2.5 it is stated that the flush operation does not imply any ordering between
itself and operations on variables not in the flush-set, nor does it imply any ordering
between two or more flush constructs if the intersection of their flush-sets is empty(see Section 2.7.5 on page 58). Such implied orderings were assumed in Version 2.0,
and as a result, the examples in Section A.18 on page 147 in Version 2.5 differ from theequivalent examples in Version 2.0.

11
12
13

In Version 2.0 no flush operation was implied by calls to OpenMP lock routines. In
Version 2.5 a flush without a list is implied whenever a lock is set or unset. See
Section 2.7.5 on page 58 and Section 3.3 on page 102.

14ordered Construct15
16

The description of the ordered construct has been modified to account for the casewhere not every iteration of the loop encounters an ordered region.

17

Sharing Attribute Rules

18
19

Version 2.5 clarifies the rules which determine the sharing attributes of variable. See
Section 2.8.1 on page 63.

20

threadprivate Directive

21
22
23

Version 2.5 clarifies the circumstances under which the values of data in thethreadprivate objects of threads other than the initial thread are guaranteed to persist
between two consecutive active parallel regions. See Section 2.8.2 on page 66.

24

Fortran25

private Clause

26
27

Version 2.5 confirms that variables that appear in expressions for statement function
definitions may not appear in a private clause. Section 2.8.3.3 on page 73.

28

Fortran

29

Chapter F

Changes from Version 2.0 to Version 2.5

239

C/C++

1
2

Private Arrays

34
5

The behavior of arrays which appear in private, firstprivate andlastprivate clauses has been clarified. See Section 2.8.3.3 on page 73,
Section 2.8.3.4 on page 75 and Section 2.8.3.5 on page 77.

6

C/C++

7

Fortran8

reduction Clause

9
10

Fortran pointers and Cray pointers are not permitted in a reduction clause. This
restriction was omitted in Version 2.0.

Fortran11

12

Data Copying Clauses

13
14

In Version 2.5, the copyin and copyprivate clauses are no longer considered datasharing attribute clauses, but are described as data copying clauses.

15

Nesting of Regions

16
17

The rules governing the nesting of regions are described using the concept of closely
nested regions. See Section 2.9 on page 87.

18

Execution Environment Routines

19
20
21
22

In Version 2.0, the behavior of the omp_set_num_threads, omp_set_dynamic
and omp_set_nested routines was undefined if called from an explicit parallel
region. In Version 2.5, their behavior in this case is implementation defined. See
Section 3.2.1 on page 91, Section 3.2.7 on page 97 and Section 3.2.9 on page 100.

23

Examples24
25

The examples in Appendix A have been extended, corrected and reordered in Version
2.5. Where appropriate, equivalent examples have been provided for C/C++ and Fortran.

26
27

Except for examples illustrating non-conforming programs, all the examples consist ofcompilable program units.

28

240

OpenMP API • Version 2.5 May 2005

1

Interface Declarations

2

An example of the omp.h header file has been included in Version 2.5.

3

Using the schedule Clause

4
5This material, which appeared in Appendix D in OpenMP C/C++ Version 2.0 and in
Appendix C in OpenMP Fortran Version 2.0, has been removed.

6

Chapter F

Changes from Version 2.0 to Version 2.5

241

1

242

OpenMP API • Version 2.5 May 2005