Skip to content

Commit eccfaf9

Browse files
authored
Add note on nested spmd (#116)
1 parent ae54578 commit eccfaf9

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

README.md

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,6 @@ consecutive `bcast` calls.
304304
import it explcitly, or prefix functions that can can only be used in spmd mode with `SPMD.`, for example,
305305
`SPMD.sendto`.
306306

307-
NOTE: It is not a good idea to instantiate `DArray` objects within an SPMD function/block, as this will
308-
result in `N` copies of the the object. Similarly calling `@everywhere` or `spmd` from within a an SPMD
309-
function/block will result in `N*N` parallel runs. In SPMD mode the function/block is executed concurrently
310-
on all workers.
311-
312307
Example
313308
-------
314309

@@ -375,3 +370,56 @@ which live only for the duration of the call. Explictly created context objects
375370
early by calling `close(stxt::SPMDContext)`. This will release the local storage dictionaries
376371
on all participating `pids`. Else they will be released when the context object is gc'ed
377372
on the node that created it.
373+
374+
375+
Nested `spmd` calls
376+
-------------------
377+
As `spmd` executes the the specified function on all participating nodes, we need to be careful with nesting `spmd` calls.
378+
379+
An example of an unsafe(wrong) way:
380+
```
381+
function foo(.....)
382+
......
383+
spmd(bar, ......)
384+
......
385+
end
386+
387+
function bar(....)
388+
......
389+
spmd(baz, ......)
390+
......
391+
end
392+
393+
spmd(foo,....)
394+
```
395+
In the above example, `foo`, `bar` and `baz` are all functions wishing to leverage distributed computation. However, they themselves may be currenty part of a `spmd` call. A safe way to handle such a scenario is to only drive parallel computation from the master process.
396+
397+
The correct way (only have the driver process initiate `spmd` calls):
398+
```
399+
function foo()
400+
......
401+
myid()==1 && spmd(bar, ......)
402+
......
403+
end
404+
405+
function bar()
406+
......
407+
myid()==1 && spmd(baz, ......)
408+
......
409+
end
410+
411+
spmd(foo,....)
412+
```
413+
414+
This is also true of functions which automatically distribute computation on DArrays.
415+
```
416+
function foo(d::DArray)
417+
......
418+
myid()==1 && map!(bar, d)
419+
......
420+
end
421+
spmd(foo,....)
422+
```
423+
Without the `myid()` check, the `spmd` call to `foo` would execute `map!` from all nodes, which is not what we probably want.
424+
425+
Similarly `@everywhere` from within a SPMD run should also be driven from the master node only.

0 commit comments

Comments
 (0)