mirror of
https://github.com/fverdugo/XM_40017.git
synced 2025-11-09 00:14:23 +01:00
Changes after the lecture on Friday September 15th 2023
This commit is contained in:
parent
01c69ff310
commit
f6a3a677b2
@ -50,7 +50,6 @@ heatmap(x,y,(i,j)->mandel(i,j,max_iters))
|
|||||||
|
|
||||||
## Asynchronous programming in Julia
|
## Asynchronous programming in Julia
|
||||||
|
|
||||||
|
|
||||||
### NB2-Q1
|
### NB2-Q1
|
||||||
|
|
||||||
Evaluating `compute_π(100_000_000)` takes about 0.25 seconds. Thus, the loop would take about 2.5 seconds since we are calling the function 10 times.
|
Evaluating `compute_π(100_000_000)` takes about 0.25 seconds. Thus, the loop would take about 2.5 seconds since we are calling the function 10 times.
|
||||||
@ -71,4 +70,94 @@ It will take about 3 seconds. The channel has buffer size 4, thus the call to `p
|
|||||||
|
|
||||||
The channel is not buffered and therefore the call to `put!` will block. The cell will run forever, since there is no other task that calls `take!` on this channel.
|
The channel is not buffered and therefore the call to `put!` will block. The cell will run forever, since there is no other task that calls `take!` on this channel.
|
||||||
|
|
||||||
|
## Distributed computing in Julia
|
||||||
|
|
||||||
|
### NB3-Q1
|
||||||
|
|
||||||
|
We send the matrix (16 entries) and then we receive back the result (1 extra integer). Thus, the total number of transferred integers in 17.
|
||||||
|
|
||||||
|
### NB3-Q2
|
||||||
|
|
||||||
|
Even though we only use a single entry of the matrix in the remote worker, the entire matrix is captured and sent to the worker. Thus, we will transfer 17 integers like in Question 1.
|
||||||
|
|
||||||
|
### NB3-Q3
|
||||||
|
|
||||||
|
The value of `x` will still be zero since the worker receives a copy of the matrix and it modifies this copy, not the original one.
|
||||||
|
|
||||||
|
### NB3-Q4
|
||||||
|
|
||||||
|
In this case, the code `a[2]=2` is executed in the main process. Since the matrix is already in the main process, it is not needed to create and send a copy of it. Thus, the code modifies the original matrix and the value of `x` will be 2.
|
||||||
|
|
||||||
|
## Distributed computing with MPI
|
||||||
|
|
||||||
|
### Exercise 1
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using MPI
|
||||||
|
MPI.Init()
|
||||||
|
comm = MPI.Comm_dup(MPI.COMM_WORLD)
|
||||||
|
rank = MPI.Comm_rank(comm)
|
||||||
|
nranks = MPI.Comm_size(comm)
|
||||||
|
buffer = Ref(0)
|
||||||
|
if rank == 0
|
||||||
|
msg = 2
|
||||||
|
buffer[] = msg
|
||||||
|
println("msg = $(buffer[])")
|
||||||
|
MPI.Send(buffer,comm;dest=rank+1,tag=0)
|
||||||
|
MPI.Recv!(buffer,comm;source=nranks-1,tag=0)
|
||||||
|
println("msg = $(buffer[])")
|
||||||
|
else
|
||||||
|
dest = if (rank != nranks-1)
|
||||||
|
rank+1
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
|
MPI.Recv!(buffer,comm;source=rank-1,tag=0)
|
||||||
|
buffer[] += 1
|
||||||
|
println("msg = $(buffer[])")
|
||||||
|
MPI.Send(buffer,comm;dest,tag=0)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exercise 2
|
||||||
|
|
||||||
|
```julia
|
||||||
|
f = () -> Channel{Int}(1)
|
||||||
|
chnls = [ RemoteChannel(f,w) for w in workers() ]
|
||||||
|
@sync for (iw,w) in enumerate(workers())
|
||||||
|
@spawnat w begin
|
||||||
|
chnl_snd = chnls[iw]
|
||||||
|
if w == 2
|
||||||
|
chnl_rcv = chnls[end]
|
||||||
|
msg = 2
|
||||||
|
println("msg = $msg")
|
||||||
|
put!(chnl_snd,msg)
|
||||||
|
msg = take!(chnl_rcv)
|
||||||
|
println("msg = $msg")
|
||||||
|
else
|
||||||
|
chnl_rcv = chnls[iw-1]
|
||||||
|
msg = take!(chnl_rcv)
|
||||||
|
msg += 1
|
||||||
|
println("msg = $msg")
|
||||||
|
put!(chnl_snd,msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This is another possible solution.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
@everywhere function work(msg)
|
||||||
|
println("msg = $msg")
|
||||||
|
if myid() != nprocs()
|
||||||
|
next = myid() + 1
|
||||||
|
@fetchfrom next work(msg+1)
|
||||||
|
else
|
||||||
|
@fetchfrom 2 println("msg = $msg")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
msg = 2
|
||||||
|
@fetchfrom 2 work(msg)
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
@ -614,6 +614,27 @@
|
|||||||
"take!(chnl)"
|
"take!(chnl)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "ff0da45d",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### This will not work!\n",
|
||||||
|
"\n",
|
||||||
|
"You really need remote channels to communicate different processes. Standard Channels would not work. For instance, the following code would block at the `take!`. Worker 4 will receive a different copy of the channel and will put values in it. The channel defined in the main process will remain empty and this will make the take! to block. \n",
|
||||||
|
"\n",
|
||||||
|
"```julia\n",
|
||||||
|
"chnl = Channel{Int}()\n",
|
||||||
|
"@spawnat 4 begin\n",
|
||||||
|
" for i in 1:5\n",
|
||||||
|
" put!(chnl,i)\n",
|
||||||
|
" end\n",
|
||||||
|
" close(chnl)\n",
|
||||||
|
"end\n",
|
||||||
|
"take!(chnl)\n",
|
||||||
|
"```"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"id": "1b3f8dcc",
|
"id": "1b3f8dcc",
|
||||||
@ -769,7 +790,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"\n",
|
"\n",
|
||||||
"<div class=\"alert alert-block alert-success\">\n",
|
"<div class=\"alert alert-block alert-success\">\n",
|
||||||
"<b>Question (Q1):</b> How many integers are transferred between master and worker? Including both directions. \n",
|
"<b>Question (NB3-Q1):</b> How many integers are transferred between master and worker? Including both directions. \n",
|
||||||
"</div>\n",
|
"</div>\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
@ -803,7 +824,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"<div class=\"alert alert-block alert-success\">\n",
|
"<div class=\"alert alert-block alert-success\">\n",
|
||||||
"<b>Question (Q2):</b> How many integers are transferred between master and worker? Including both directions. \n",
|
"<b>Question (NB3-Q2):</b> How many integers are transferred between master and worker? Including both directions. \n",
|
||||||
"</div>\n",
|
"</div>\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
@ -838,7 +859,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"\n",
|
"\n",
|
||||||
"<div class=\"alert alert-block alert-success\">\n",
|
"<div class=\"alert alert-block alert-success\">\n",
|
||||||
"<b>Question (Q3):</b> Which value will be the value of `x` ? \n",
|
"<b>Question (NB3-Q3):</b> Which value will be the value of `x` ? \n",
|
||||||
"</div>\n"
|
"</div>\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -862,7 +883,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"<div class=\"alert alert-block alert-success\">\n",
|
"<div class=\"alert alert-block alert-success\">\n",
|
||||||
"<b>Question (Q4):</b> Which value will be the value of `x` ? \n",
|
"<b>Question (NB3-Q4):</b> Which value will be the value of `x` ? \n",
|
||||||
"</div>\n",
|
"</div>\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Which value will be the value of `x` ?"
|
"Which value will be the value of `x` ?"
|
||||||
@ -1309,7 +1330,7 @@
|
|||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"kernelspec": {
|
"kernelspec": {
|
||||||
"display_name": "Julia 1.9.3",
|
"display_name": "Julia 1.9.0",
|
||||||
"language": "julia",
|
"language": "julia",
|
||||||
"name": "julia-1.9"
|
"name": "julia-1.9"
|
||||||
},
|
},
|
||||||
@ -1317,7 +1338,7 @@
|
|||||||
"file_extension": ".jl",
|
"file_extension": ".jl",
|
||||||
"mimetype": "application/julia",
|
"mimetype": "application/julia",
|
||||||
"name": "julia",
|
"name": "julia",
|
||||||
"version": "1.9.3"
|
"version": "1.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user