Newer
Older
1
2
3
4
5
6
7
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# OpenCoarrays
## Introduction
Coarray Fortran (CAF) is an extension of Fortran language and offers a simple interface for parallel processing and memory sharing.
The advantage is that only small changes are required to convert existing Fortran code to support a robust and potentially efficient parallelism.
A CAF program is interpreted as if it was replicated a number of times and all copies were executed asynchronously.
The number of copies is decided at execution time. Each copy (called *image*) has its own private variables.
The variable syntax of Fortran language is extended with indexes in square brackets (called *co-dimension*) representing a reference to data distributed across images.
By default, the CAF is using Message Passing Interface (MPI) for lower-level communication, so there are some similarities with MPI.
Read more on <http://www.opencoarrays.org/>
## Coarray Basics
### Indexing of Coarray Images
Indexing of individual images can be shown on the simple *Hello World* program:
```fortran
program hello_world
implicit none
print *, 'Hello world from image ', this_image() , 'of', num_images()
end program hello_world
```
* num_images() - returns the number of all images
* this_image() - returns the image index - numbered from 1 to num_images()
### Co-dimension Variables Declaration
Coarray variables can be declared with the **codimension[*]** attribute or by adding trailing index **[*]** after the variable name.
Notice, the ***** character always has to be in the square brackets.
```fortran
integer, codimension[*] :: scalar
integer :: scalar[*]
real, dimension(64), codimension[*] :: vector
real :: vector(64)[*]
```
### Images Synchronization
Because each image is running on its own, the image synchronization is needed to ensure, that all altered data are distributed to all images.
Synchronization can be done across all images or only between selected images. Be aware, that selective synchronization can lead to the race condition problems like deadlock.
Example program:
```fortran
program synchronization_test
implicit none
integer :: i ! Local variable
integer :: numbers[*] ! Scalar coarray
! Genereate random number on image 1
if (this_image() == 1) then
numbers = floor(rand(1) * 1000)
! Distribute information to other images
do i = 2, num_images()
numbers[i] = numbers
end do
end if
sync all ! Barrier to synchronize all images
print *, 'The random number is', numbers
end program synchronization_test
```
* sync all - Synchronize all images between each other
* sync images(*) - Synchronize this image to all other
* sync images(*index*) - Synchronize this image to image with *index*
!!! note
**number** is the local variable while **number[*index*]** accesses the variable in a specific image.
**number[this_image()]** is the same as **number**.
## Compile and Run
Currently, version 1.8.10 compiled with OpenMPI 1.10.7 library is installed on Cluster. The OpenCoarrays module can be load as follows:
```console
$ ml OpenCoarrays/1.8.10-GCC-6.3.0-2.27
```
### Compile CAF Program
The preferred method for compiling a CAF program is by invoking the *caf* compiler wrapper.
The above mentioned *Hello World* program can be compiled as follows:
```console
$ caf hello_world.f90 -o hello_world.x
```
!!! warning
The input file extension **.f90** or **.F90** are to be interpreted as *Fortran 90*.
If the input file extension is **.f** or **.F** the source code will be interpreted as *Fortran 77*.
Another method for compiling is by invoking the *mpif90* compiler wrapper directly:
```console
$ mpif90 hello_world.f90 -o hello_world.x -fcoarray=lib -lcaf_mpi
```
### Run CAF Program
A CAF program can be run by invoking the *cafrun* wrapper or directly by the *mpiexec*:
```console
$ cafrun -np 4 ./hello_world.x
Hello world from image 1 of 4
Hello world from image 2 of 4
Hello world from image 3 of 4
Hello world from image 4 of 4
$ mpiexec -np 4 ./synchronization_test.x
The random number is 242
The random number is 242
The random number is 242
The random number is 242
```
**-np 4** is number of images to run. The parameters of **cafrun** and **mpiexec** are the same.
For more information about running CAF program please follow [Running OpenMPI](../mpi/Running_OpenMPI.md)