Skip to content

Commit caa2e6b

Browse files
author
Thomas Koenig
committed
Add Makefile, chapter about SYNC images and wrapper for LaTeX.
1 parent 30c5c2f commit caa2e6b

File tree

3 files changed

+99
-6
lines changed

3 files changed

+99
-6
lines changed

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
all: tutorial.html tutorial.tex wrapper.pdf
2+
3+
tutorial.html: tutorial.md
4+
cmark --to html tutorial.md > tutorial.html
5+
6+
tutorial.tex: tutorial.md
7+
cmark --to latex tutorial.md > tutorial.tex
8+
9+
wrapper.pdf: wrapper.tex tutorial.tex
10+
pdflatex wrapper
11+
pdflatex wrapper

tutorial.md

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ This program will output something like
6161
Hello from image 3 of 4
6262
Hello from image 1 of 4
6363
```
64-
(depending on how many images you run) and shows the use of two
64+
depending on how many images you run and shows the use of two
6565
important functions: The number of images that is run can be found
6666
`num_images()` function and the current image via `this_image()`.
6767
Both of these are functions that are built into the language
@@ -286,7 +286,7 @@ or if you are a fan of Douglas Adams, you can use
286286
integer :: a[42:*]
287287
```
288288
Actually, declaring a coarray a `a[*]` is only a shortcut for
289-
declaring the coarray as `a[1:]` with a lower cobound of 1.
289+
declaring the coarray as `a[1:*]` with a lower cobound of 1.
290290
There is a subtlety to the use of `this_image()`: Without
291291
any arguments, it gives you the image number. When it has
292292
a coarray argument, it will give you the argument that you
@@ -377,21 +377,85 @@ An allocatable coarray can be declared with the syntax
377377
```
378378
real, dimension(:), codimension(:), allocatable :: a
379379
```
380-
(note the colons in the declarations) and allocated
380+
(note the colons in the declarations) and allocated with
381381
```
382382
allocate (a(n)[*])
383383
```
384384
Like a regular allocatable variable, it will be deallocated
385385
automatically when going out of scope. `SOURCE` and `MOLD`
386386
can also be specified.
387387

388-
# More advanced synchronization
388+
One important thing to notice is that coarray sizes have to
389+
agree on all images, otherwise unpredictable things will happen;
390+
at best, there will be an error message. If you want to, you
391+
can adjust the bounds. This, for example, would be legal:
392+
```
393+
from = (this_image() - 1) * n + 1
394+
to = this_image () * n
395+
allocate (a(from:to)[*])
396+
```
397+
and give you an index running from `1` to `num_images * n`, but
398+
you would still have to specify the correct coarray.
399+
400+
# More advanced synchronization -- `SYNC IMAGES`
401+
402+
`SYNC ALL` is not everything that may be needed for synchronization.
403+
Suppose not every image needs to communicate with every other image,
404+
but only with a specific set. It is possible to use `SYNC IMAGES`
405+
for this purpose.
389406

390-
Add `SYNC IMAGES` here.
407+
`SYNC IMAGES` takes as argument an image, or a list of the images
408+
with which it should synchronize, for example
409+
```
410+
if (this_image () == 2) sync_images ([1,3])
411+
```
412+
This will hold execution of image number two until a corresponding
413+
`SYNC IMAGES` statement has been executed on images 1 and 3:
414+
```
415+
if (this_image () == 1) sync_images (2)
416+
if (this_image () == 3) sync_images (2)
417+
```
418+
The following example uses `SYNC IMAGES` for a pairwise exchange of
419+
greetings between different images:
420+
```
421+
program main
422+
implicit none
423+
character (len=30) :: greetings[*]
424+
integer :: me, n, you
425+
me = this_image()
426+
n = num_images()
427+
if (mod(n,2) == 1 .and. me == n) then
428+
greetings = "Hello, myself"
429+
else
430+
you = me + 2 * modulo(me,2) - 1
431+
write (unit=greetings[you],fmt='(A,I0,A,I0)') &
432+
"Greetings from ", me, " to ", you
433+
sync images (you)
434+
end if
435+
write (*,'(A)') trim(greetings)
436+
end program main
437+
```
438+
Here is an idiom to have image 1 prepare something and
439+
have all images wait on image 1, plus have image 1
440+
wait on all other images:
441+
```
442+
program main
443+
implicit none
444+
if (this_image() == 1) then
445+
write (*,'(A)') "Preparing things on image 1"
446+
sync images(*)
447+
else
448+
sync images(1)
449+
end if
450+
write (*,'(A,I0)') "Using prepared things on image ", this_image()
451+
end program
452+
```
453+
Two images can issue `SYNC IMAGES` commands to each other multiple
454+
times. Execution will only continue if the numbers match.
391455

392456
# Coroutines
393457

394-
An alternative: Coroutines!
458+
Another method.
395459

396460
# Getting it to work
397461

wrapper.tex

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
\documentclass[10pt,a4paper]{article}
2+
\usepackage[utf8]{inputenc}
3+
\usepackage[T1]{fontenc}
4+
\usepackage{hyperref}
5+
\title{A Coarray Tutorial}
6+
\date{January 2021}
7+
\author{Thomas König}
8+
\usepackage[a4paper,bindingoffset=0.2in,%
9+
left=1in,right=1in,top=1in,bottom=1in,%
10+
footskip=.25in]{geometry}
11+
\begin{document}
12+
\maketitle
13+
\begingroup
14+
\let\clearpage\relax
15+
\include{tutorial}
16+
\endgroup
17+
\end{document}
18+

0 commit comments

Comments
 (0)