@@ -61,7 +61,7 @@ This program will output something like
61
61
Hello from image 3 of 4
62
62
Hello from image 1 of 4
63
63
```
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
65
65
important functions: The number of images that is run can be found
66
66
` num_images() ` function and the current image via ` this_image() ` .
67
67
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
286
286
integer :: a[42:*]
287
287
```
288
288
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.
290
290
There is a subtlety to the use of ` this_image() ` : Without
291
291
any arguments, it gives you the image number. When it has
292
292
a coarray argument, it will give you the argument that you
@@ -377,21 +377,85 @@ An allocatable coarray can be declared with the syntax
377
377
```
378
378
real, dimension(:), codimension(:), allocatable :: a
379
379
```
380
- (note the colons in the declarations) and allocated
380
+ (note the colons in the declarations) and allocated with
381
381
```
382
382
allocate (a(n)[*])
383
383
```
384
384
Like a regular allocatable variable, it will be deallocated
385
385
automatically when going out of scope. ` SOURCE ` and ` MOLD `
386
386
can also be specified.
387
387
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.
389
406
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.
391
455
392
456
# Coroutines
393
457
394
- An alternative: Coroutines!
458
+ Another method.
395
459
396
460
# Getting it to work
397
461
0 commit comments