mirror of
https://github.com/fverdugo/XM_40017.git
synced 2026-11-15 02:57:17 +01:00
5 files changed
+1806
-723
No files matched your search
@@ -50,7 +50,6 @@ heatmap(x,y,(i,j)->mandel(i,j,max_iters))
|
||||
|
||||
## Asynchronous programming in Julia
|
||||
|
||||
|
||||
### 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.
|
||||
@@ -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.
|
||||
|
||||
## 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)
|
||||
```
|
||||
|
||||
+783
-263
File diff suppressed because it is too large.
Load diff
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 160 KiB |
@@ -614,6 +614,27 @@
|
||||
"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",
|
||||
"id": "1b3f8dcc",
|
||||
@@ -769,7 +790,7 @@
|
||||
"source": [
|
||||
"\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",
|
||||
"\n",
|
||||
"\n",
|
||||
@@ -803,7 +824,7 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<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",
|
||||
"\n",
|
||||
"\n",
|
||||
@@ -838,7 +859,7 @@
|
||||
"source": [
|
||||
"\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"
|
||||
]
|
||||
},
|
||||
@@ -862,7 +883,7 @@
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<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",
|
||||
"\n",
|
||||
"Which value will be the value of `x` ?"
|
||||
@@ -1309,7 +1330,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 1.9.3",
|
||||
"display_name": "Julia 1.9.0",
|
||||
"language": "julia",
|
||||
"name": "julia-1.9"
|
||||
},
|
||||
@@ -1317,7 +1338,7 @@
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "1.9.3"
|
||||
"version": "1.9.0"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
+448
-50
@@ -51,6 +51,36 @@
|
||||
"- There are Julia bindings via the package MPI.jl https://github.com/JuliaParallel/MPI.jl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "99c6febb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### What is MPI.jl ?\n",
|
||||
"\n",
|
||||
"- It is not a Julia implementation of the MPI standard\n",
|
||||
"- It is a wrapper to the C interface of MPI\n",
|
||||
"- You need a C MPI installation in your system\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"MPI.jl provides a convenient Julia API to access MPI. For instance, this is how you get the id (rank) of the current process.\n",
|
||||
"\n",
|
||||
"```julia\n",
|
||||
"comm = MPI.COMM_WORLD\n",
|
||||
"rank = MPI.Comm_rank(comm)\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Internally, MPI.jl uses `ccall` which is a mechanism that allows you to call C functions from Julia. In this, example we are calling the C function `MPI_Comm_rank` from the underlying MPI installation.\n",
|
||||
"\n",
|
||||
"```julia\n",
|
||||
"comm = MPI.COMM_WORLD \n",
|
||||
"rank_ref = Ref{Cint}()\n",
|
||||
"ccall((:MPI_Comm_rank, MPI.API.libmpi), Cint, (MPI.API.MPI_Comm, Ptr{Cint}), comm, rank_ref)\n",
|
||||
"rank = Int(rank_ref[])\n",
|
||||
"```\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "82e6e98f",
|
||||
@@ -81,6 +111,66 @@
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a534e3a2",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Basic information about MPI processes\n",
|
||||
"\n",
|
||||
"The following cells give information about MPI processes, such as the rank id, the total number of processes and the name of the host running the code respectively. Before calling this functions one needs to initialize MPI."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "96f7c14e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using MPI\n",
|
||||
"MPI.Init()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "bd8232f5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"comm = MPI.COMM_WORLD\n",
|
||||
"rank = MPI.Comm_rank(comm)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "0befa408",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nranks = MPI.Comm_size(comm)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ff01adcf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"MPI.Get_processor_name()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f1a502a3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Note that this note notebook is not running with different MPI processes (yet). So using MPI will only make sense later when we add more processes."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "133327e2",
|
||||
@@ -104,6 +194,32 @@
|
||||
"println(\"Hello, I am process $rank of $nranks processes!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "baddbba1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Hello world in C\n",
|
||||
"\n",
|
||||
"```C\n",
|
||||
"#include <mpi.h>\n",
|
||||
"#include <stdio.h>\n",
|
||||
"int main(int argc, char** argv) {\n",
|
||||
" MPI_Init(NULL, NULL);\n",
|
||||
" int world_size;\n",
|
||||
" MPI_Comm_size(MPI_COMM_WORLD, &world_size);\n",
|
||||
" int world_rank;\n",
|
||||
" MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);\n",
|
||||
" char processor_name[MPI_MAX_PROCESSOR_NAME];\n",
|
||||
" int name_len;\n",
|
||||
" MPI_Get_processor_name(processor_name, &name_len);\n",
|
||||
" printf(\"Hello from %s, I am rank %d of %d ranks!\\n\",\n",
|
||||
" processor_name, world_rank, world_size);\n",
|
||||
" MPI_Finalize();\n",
|
||||
"}\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e3901c57",
|
||||
@@ -311,63 +427,14 @@
|
||||
"\n",
|
||||
"MPI provides collective communication functions for communication involving multiple processes. Some usual collective directives are:\n",
|
||||
"\n",
|
||||
"- `MPI.Scatter`: Distributes data from one process to all processes.\n",
|
||||
"- `MPI.Gather`: Gathers data from all processes to a single process.\n",
|
||||
"- `MPI.Scatter`: Distributes data from one process to all processes.\n",
|
||||
"- `MPI.Bcast`: Broadcasts data from one process to all processes.\n",
|
||||
"- `MPI.Barrier`: Synchronizes all processes.\n",
|
||||
"\n",
|
||||
"See more collective directives available from Julia here: https://juliaparallel.org/MPI.jl/stable/reference/collective/\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8b4254d1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Scatter\n",
|
||||
"\n",
|
||||
"The \"root\" rank contains a buffer (e.g., a vector) of values (one value for each rank in a communicator). Scatter sends one value to each rank (the root rank also receives a value). The root rank can be any process in a communicator."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g13389.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "74d5b606",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g13389.png\" align=\"left\" width=\"350\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5ea413fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@everywhere workers() begin\n",
|
||||
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
|
||||
" nranks = MPI.Comm_size(comm)\n",
|
||||
" rank = MPI.Comm_rank(comm)\n",
|
||||
" root = 0\n",
|
||||
" rcv = Ref(0) \n",
|
||||
" if rank == root\n",
|
||||
" snd = [10*(i+1) for i in 1:nranks]\n",
|
||||
" println(\"I am sending: $snd\")\n",
|
||||
" else\n",
|
||||
" snd = nothing\n",
|
||||
" end \n",
|
||||
" MPI.Scatter!(snd,rcv,comm;root)\n",
|
||||
" println(\"I have received: $(rcv[])\")\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "97dc2886",
|
||||
@@ -414,6 +481,125 @@
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8b4254d1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Scatter\n",
|
||||
"\n",
|
||||
"The root rank contains a buffer (e.g., a vector) of values (one value for each rank in a communicator). Scatter sends one value to each rank (the root rank also receives a value). The root rank can be any process in a communicator."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g13389.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "74d5b606",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g13389.png\" align=\"left\" width=\"350\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5ea413fd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@everywhere workers() begin\n",
|
||||
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
|
||||
" nranks = MPI.Comm_size(comm)\n",
|
||||
" rank = MPI.Comm_rank(comm)\n",
|
||||
" root = 0\n",
|
||||
" rcv = Ref(0) \n",
|
||||
" if rank == root\n",
|
||||
" snd = [10*(i+1) for i in 1:nranks]\n",
|
||||
" println(\"I am sending: $snd\")\n",
|
||||
" else\n",
|
||||
" snd = nothing\n",
|
||||
" end \n",
|
||||
" MPI.Scatter!(snd,rcv,comm;root)\n",
|
||||
" println(\"I have received: $(rcv[])\")\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ed8da7f9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Bcast (broadcast)\n",
|
||||
"\n",
|
||||
"Similar to scatter, but we send the same message to all processes."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g1657.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "26b56c81",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g1657.png\" align=\"left\" width=\"350\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4de15781",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@everywhere workers() begin\n",
|
||||
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
|
||||
" nranks = MPI.Comm_size(comm)\n",
|
||||
" rank = MPI.Comm_rank(comm)\n",
|
||||
" root = 0\n",
|
||||
" buffer = Ref(0)\n",
|
||||
" if rank == root\n",
|
||||
" buffer[] = 20\n",
|
||||
" println(\"I am sending: $(buffer[])\")\n",
|
||||
" end \n",
|
||||
" MPI.Bcast!(buffer,comm;root)\n",
|
||||
" println(\"I have received: $(buffer[])\")\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6de37cc9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Barrier"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ff61f64a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@everywhere workers() begin\n",
|
||||
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
|
||||
" sleep(rand(1:3))\n",
|
||||
" MPI.Barrier(comm)\n",
|
||||
" println(\"Done!\")\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ac9a5b52",
|
||||
@@ -435,6 +621,218 @@
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "26879a46",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Blocking communication\n",
|
||||
"\n",
|
||||
"If we start a receive before a matching send, we will block in the call to `MPI.Recv!`. Run the next cell and note that the message is not printed since the process is blocked at `MPI.Recv!` waiting for a matching send."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "68aa9ada",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 4 begin\n",
|
||||
" buffer = Ref(0)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" MPI.Recv!(buffer,comm;source=2-2,tag=0)\n",
|
||||
" println(\"I have received $(buffer[]).\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ace9c787",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you run the next cell containing the corresponding send, the communication will take place."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e18347cd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 2 begin\n",
|
||||
" buffer = Ref(2)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" MPI.Send(buffer,comm;dest=4-2,tag=0)\n",
|
||||
" println(\"I have send $(buffer[]). It is now safe to overwite the buffer.\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0a038200",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### MPI does not integrate well with Julia Tasks\n",
|
||||
"\n",
|
||||
"MPI blocks without yielding (we cannot switch to other Julia tasks). Run next cell:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d7da7d27",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 4 begin\n",
|
||||
" buffer = Ref(0)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" MPI.Recv!(buffer,comm;source=2-2,tag=0)\n",
|
||||
" println(\"I have received $(buffer[]).\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "530b673b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now try to spawn other tasks on process 4 by running next cell. This task will not be served yet."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ae1165ac",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 4 println(\"Hello!\");"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c722d71e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We first need to unlock the receive with a matching send. Then the task printing \"Hello!\" will be finally served."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "9da6f76e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 2 begin\n",
|
||||
" buffer = Ref(2)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" MPI.Send(buffer,comm;dest=4-2,tag=0)\n",
|
||||
" println(\"I have send $(buffer[]). It is now safe to overwite the buffer.\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6f4fa1cd",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Non-blocking communication"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d6e2fbbf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 4 begin\n",
|
||||
" buffer = Ref(0)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" req = MPI.Irecv!(buffer,comm;source=2-2,tag=0)\n",
|
||||
" println(\"Not yet safe to read the buffer\")\n",
|
||||
" MPI.Wait(req)\n",
|
||||
" println(\"I have received $(buffer[]).\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4aa426ff",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 2 begin\n",
|
||||
" buffer = Ref(2)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" req = MPI.Isend(buffer,comm;dest=4-2,tag=0)\n",
|
||||
" println(\"Not yet safe to write the buffer\")\n",
|
||||
" MPI.Wait(req)\n",
|
||||
" println(\"I have send $(buffer[]). It is now safe to overwite the buffer.\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "30d9a970",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Combining Julia Tasks and non-blocking communication\n",
|
||||
"\n",
|
||||
"We can implement our own blocking mechanism that combines well with the Julia task scheduler. This can be done by testing on the request in a while loop. The `yield` in the loop provides the opportunity of other tasks to run.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "768b2439",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 4 begin\n",
|
||||
" buffer = Ref(0)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" req = MPI.Irecv!(buffer,comm;source=2-2,tag=0)\n",
|
||||
" while MPI.Test(req) == false\n",
|
||||
" yield()\n",
|
||||
" end\n",
|
||||
" println(\"I have received $(buffer[]).\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "073d138c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 4 println(\"Hello!\");"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "97bc403f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@spawnat 2 begin\n",
|
||||
" buffer = Ref(2)\n",
|
||||
" comm = MPI.COMM_WORLD\n",
|
||||
" req = MPI.Isend(buffer,comm;dest=4-2,tag=0)\n",
|
||||
" while MPI.Test(req) == false\n",
|
||||
" yield()\n",
|
||||
" end\n",
|
||||
" println(\"I have send $(buffer[]). It is now safe to overwite the buffer.\")\n",
|
||||
"end;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "750fdacb",
|
||||
|
||||
+458
-403
@@ -154,33 +154,36 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "40027c85",
|
||||
"id": "f2b70f85",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Input distance"
|
||||
"### Nearest-city first heuristic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"id": "a50706bc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function sort_neighbors(C)\n",
|
||||
" n = size(C,1)\n",
|
||||
" map(1:n) do i\n",
|
||||
" Ci = C[i,:]\n",
|
||||
" cities = sortperm(Ci)\n",
|
||||
" distances = Ci[cities]\n",
|
||||
" collect(zip(cities,distances))\n",
|
||||
" end\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "2eeecdd6",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"4×4 Matrix{Int64}:\n",
|
||||
" 0 2 3 2\n",
|
||||
" 2 0 4 1\n",
|
||||
" 3 4 0 3\n",
|
||||
" 2 1 3 0"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"C = [\n",
|
||||
" 0 2 3 2\n",
|
||||
@@ -190,73 +193,6 @@
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"id": "03cac0a1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"4-element Vector{Vector{Tuple{Int64, Int64}}}:\n",
|
||||
" [(1, 0), (2, 2), (3, 3), (4, 4)]\n",
|
||||
" [(2, 0), (4, 1), (1, 2), (3, 3)]\n",
|
||||
" [(3, 0), (1, 3), (2, 3), (4, 10)]\n",
|
||||
" [(4, 0), (2, 1), (1, 4), (3, 10)]"
|
||||
]
|
||||
},
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"C = [\n",
|
||||
" [(1,0), (2,2), (3,3), (4,4)],\n",
|
||||
" [(2,0), (4,1), (1,2), (3,3)],\n",
|
||||
" [(3,0), (1,3), (2,3), (4,10)], \n",
|
||||
" [(4,0), (2,1), (1,4), (3,10)]\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f2b70f85",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Nearest-city first heuristic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "a50706bc",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"sort_neighbors (generic function with 1 method)"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"function sort_neighbors(C)\n",
|
||||
" n = size(C,1)\n",
|
||||
" map(1:n) do i\n",
|
||||
" Ci = C[i,:]\n",
|
||||
" cities = sortperm(Ci)\n",
|
||||
" distances = Ci[cities]\n",
|
||||
" collect(zip(cities,distances))[2:end]\n",
|
||||
" end\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -264,7 +200,33 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"connections = sort_neighbors(C)"
|
||||
"C_sorted = sort_neighbors(C)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "00608e1d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"city = 3\n",
|
||||
"C_sorted[city]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g25091.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "7384a305",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g25091.png\" align=\"left\" width=\"525\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -272,261 +234,228 @@
|
||||
"id": "4f8cf018",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Implementation"
|
||||
"### Loop over all paths"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "d00beaba",
|
||||
"execution_count": null,
|
||||
"id": "2ddc2ec1",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(path, distance, min_distance) = ([1, 2, 4, 3], 13, 13)\n",
|
||||
"(path, distance, min_distance) = ([1, 3, 2, 4], 7, 7)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"7"
|
||||
]
|
||||
},
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function tsp_serial(C,city)\n",
|
||||
" #connections = sort_neighbors(C)\n",
|
||||
" num_cities = length(connections)\n",
|
||||
"function visital_all_paths(C_sorted,city)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" path=zeros(Int,num_cities)\n",
|
||||
" hops = 1\n",
|
||||
" path[hops] = city\n",
|
||||
" distance = 0\n",
|
||||
" min_distance = typemax(Int)\n",
|
||||
" tsp_serial_recursive!(connections,hops,path,distance,min_distance)\n",
|
||||
" visital_all_paths_recursive!(C_sorted,hops,path)\n",
|
||||
"end\n",
|
||||
"function tsp_serial_recursive!(connections,hops,path,distance,min_distance)\n",
|
||||
" num_cities = length(connections)\n",
|
||||
" if hops == num_cities\n",
|
||||
" min_distance = min(distance,min_distance)\n",
|
||||
" @show path, distance, min_distance\n",
|
||||
" return min_distance\n",
|
||||
" else\n",
|
||||
"function visital_all_paths_recursive!(C_sorted,hops,path)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops != num_cities\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" current_city = path[hops]\n",
|
||||
" for (next_city,distance_increment) in connections[current_city]\n",
|
||||
" if !visited(next_city,hops,path)\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" if ! already_visited\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" visital_all_paths_recursive!(C_sorted,next_hops,path)\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" return nothing\n",
|
||||
" else\n",
|
||||
" @show path\n",
|
||||
" return nothing\n",
|
||||
" end\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "723a0f1a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"city = 1\n",
|
||||
"visital_all_paths(C_sorted,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g25091.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "8cbc8597",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g25091.png\" align=\"left\" width=\"525\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "65e654df",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Serial implementation without pruning"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5989f0ac",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function tsp_serial_no_prune(C_sorted,city)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" path=zeros(Int,num_cities)\n",
|
||||
" hops = 1\n",
|
||||
" path[hops] = city\n",
|
||||
" distance=0\n",
|
||||
" min_distance = typemax(Int)\n",
|
||||
" tsp_serial_no_prune_recursive!(C_sorted,hops,path,distance,min_distance)\n",
|
||||
"end\n",
|
||||
"function tsp_serial_no_prune_recursive!(C_sorted,hops,path,distance,min_distance)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops != num_cities\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" if ! already_visited\n",
|
||||
" next_distance = distance + distance_increment\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" if next_distance < min_distance\n",
|
||||
" min_distance = tsp_serial_recursive!(connections,next_hops,path,next_distance,min_distance)\n",
|
||||
" end\n",
|
||||
" min_distance = tsp_serial_no_prune_recursive!(\n",
|
||||
" C_sorted,next_hops,path,next_distance,min_distance)\n",
|
||||
" end\n",
|
||||
" end \n",
|
||||
" end\n",
|
||||
" return min_distance\n",
|
||||
"end\n",
|
||||
"function visited(city,hops,path)\n",
|
||||
" for i = 1:hops\n",
|
||||
" if path[i] == city\n",
|
||||
" return true\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" return false\n",
|
||||
"end\n",
|
||||
"\n",
|
||||
"city = 1\n",
|
||||
"tsp_serial(C,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "505e00f7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function tsp_serial(C,city)\n",
|
||||
" connections = sort_neighbors(C)\n",
|
||||
" num_cities = length(connections)\n",
|
||||
" current_route = (;path=zeros(Int,num_cities),distance=Ref(0))\n",
|
||||
" min_route = (;path=zeros(Int,num_cities),distance=Ref(typemax(Int)))\n",
|
||||
" hops = 1\n",
|
||||
" current_route.path[hops] = city\n",
|
||||
" tsp_serial_recursive!(connections,hops,current_route,min_route)\n",
|
||||
" min_route\n",
|
||||
"end\n",
|
||||
"function tsp_serial_recursive(connections,hops,current_route,min_route)\n",
|
||||
" num_cities = length(connections)\n",
|
||||
" if hops == num_cities\n",
|
||||
" if current_route.distance < min_route.distance\n",
|
||||
" min_route.path .= current_route.path\n",
|
||||
" min_route.distance[] = current_route.distance \n",
|
||||
" return\n",
|
||||
" end\n",
|
||||
" return min_distance\n",
|
||||
" else\n",
|
||||
" min_distance = min(distance,min_distance)\n",
|
||||
" #@show path, distance, min_distance\n",
|
||||
" return min_distance\n",
|
||||
" end\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d1be2bfc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"city = 1\n",
|
||||
"min_distance = tsp_serial_no_prune(C_sorted,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3c160cf9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Final serial implementation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8241e0df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function tsp_serial(C_sorted,city)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" path=zeros(Int,num_cities)\n",
|
||||
" hops = 1\n",
|
||||
" path[hops] = city\n",
|
||||
" distance=0\n",
|
||||
" min_distance = typemax(Int)\n",
|
||||
" tsp_serial_recursive!(C_sorted,hops,path,distance,min_distance)\n",
|
||||
"end\n",
|
||||
"function tsp_serial_recursive!(C_sorted,hops,path,distance,min_distance)\n",
|
||||
" if distance >= min_distance\n",
|
||||
" return min_distance\n",
|
||||
" end\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops != num_cities\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" current_city = current_route.path[hops]\n",
|
||||
" for (next_city,distance_increment) in connections[current_city]\n",
|
||||
" if !visited(next_city,hops,current_route.path)\n",
|
||||
" \n",
|
||||
" next_distance = current_distance + distance_increment\n",
|
||||
" \n",
|
||||
" if next_distance < min_distance\n",
|
||||
" return tsp_serial_recursive(connections,hops+1,current_route,min_route)\n",
|
||||
" end\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" if ! already_visited\n",
|
||||
" next_distance = distance + distance_increment\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" min_distance = tsp_serial_recursive!(\n",
|
||||
" C_sorted,next_hops,path,next_distance,min_distance)\n",
|
||||
" end\n",
|
||||
" end \n",
|
||||
" end\n",
|
||||
" min_distance\n",
|
||||
"end\n",
|
||||
"\n",
|
||||
"function visited(city,hops,path)\n",
|
||||
" for i = 1:hops\n",
|
||||
" if path[i] == city\n",
|
||||
" return true\n",
|
||||
" end\n",
|
||||
" return min_distance\n",
|
||||
" else\n",
|
||||
" min_distance = min(distance,min_distance)\n",
|
||||
" #@show path, distance, min_distance\n",
|
||||
" return min_distance\n",
|
||||
" end\n",
|
||||
" return false\n",
|
||||
"end\n",
|
||||
"\n",
|
||||
"city = 1\n",
|
||||
"tsp_serial(C,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "94d8193f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Generating some test data\n",
|
||||
"\n",
|
||||
"The following function generates a random symmetric distance matrix, we have used a large. Note that the TSP problem at least requires that the underlying graph is connected (otherwise there is no route that visits all nodes). The next function does not guarantee this. In any case, we can still used a non-connected graph as input. The outcome of the search will be that there is no possible route."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "88fc4499",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function rand_symmetric_distance_table(n)\n",
|
||||
" threshold = 0.2\n",
|
||||
" mincost = 3\n",
|
||||
" maxcost = 10\n",
|
||||
" infinity = 10000*maxcost\n",
|
||||
" C = fill(infinity,n,n)\n",
|
||||
" for j in 1:n\n",
|
||||
" for i in 1:j\n",
|
||||
" if rand() > threshold\n",
|
||||
" C[i,j] = rand(mincost:maxcost)\n",
|
||||
" C[j,i] = C[i,j]\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" C[j,j] = 0\n",
|
||||
" end\n",
|
||||
" C,infinity\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d649cf80",
|
||||
"id": "998087f2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"n = 10000\n",
|
||||
"C, inf = rand_symmetric_distance_table(n)\n",
|
||||
"city = 1\n",
|
||||
"(;path,distance) = tsp_serial(C,city)\n",
|
||||
"if distance >= inf\n",
|
||||
" println(\"The input graph is nonconnected\")\n",
|
||||
"else\n",
|
||||
" (;path,distance)\n",
|
||||
"end"
|
||||
"min_distance = tsp_serial(C_sorted,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g23360.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "b0ea4b99",
|
||||
"id": "7f0a5d5c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g23360.png\" align=\"left\" width=\"300\"/>\n",
|
||||
"</div>"
|
||||
"### Performance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g22999.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "e734b6dc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g22999.png\" align=\"left\" width=\"300\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {
|
||||
"g22822.png": {
|
||||
"image/png": "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 truncated
|
||||
}
|
||||
},
|
||||
"cell_type": "markdown",
|
||||
"id": "c8f723c4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"<div>\n",
|
||||
"<img src=\"attachment:g22822.png\" align=\"left\" width=\"300\"/>\n",
|
||||
"</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6f8100ad",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bef63110",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "9f66ca90",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "88b90b22",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8850d90e",
|
||||
"id": "e1eb74d8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"n = 11\n",
|
||||
"using Random\n",
|
||||
"Random.seed!(1)\n",
|
||||
"C = rand(1:10,n,n)\n",
|
||||
"C_sorted = sort_neighbors(C)\n",
|
||||
"city = 1\n",
|
||||
"@time tsp_serial_no_prune(C_sorted,city)\n",
|
||||
"@time tsp_serial(C_sorted,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "733ce76e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Parallel implementation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "354f5abb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -536,137 +465,263 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5d4935ee",
|
||||
"id": "7f8f6702",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"if procs() == workers()\n",
|
||||
" addprocs(4)\n",
|
||||
"if workers() == procs()\n",
|
||||
" addprocs(3)\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4a2756ae",
|
||||
"id": "5c0603a1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@everywhere function visited(city,hops,path)\n",
|
||||
" for i = 1:hops\n",
|
||||
" if path[i] == city\n",
|
||||
" return true\n",
|
||||
"function enumerate_paths_dist(C_sorted,city,max_hops)\n",
|
||||
" T = typeof((0,Int[]))\n",
|
||||
" jobs_chnl = RemoteChannel(()->Channel{T}(1))\n",
|
||||
" @sync begin\n",
|
||||
" for w in workers()\n",
|
||||
" @spawnat w consume_jobs(C_sorted,jobs_chnl)\n",
|
||||
" end\n",
|
||||
" generate_jobs(C_sorted,city,max_hops,jobs_chnl)\n",
|
||||
" end\n",
|
||||
" return false\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "78095098",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"connections = [\n",
|
||||
" [(1,0),(4,39),(5,76), (6,78),(3,94),(2,97)],\n",
|
||||
" [(2,0),(5,25),(4,58),(3,62),(1,97),(6,109)],\n",
|
||||
" [(3,0),(6,58),(2,62),(4,68),(5,70),(1,94)],\n",
|
||||
" [(4,0),(5,38),(1,39),(2,58),(3,68),(6,78)],\n",
|
||||
" [(5,0),(2,25),(4,38),(3,70),(1,76),(6,104)],\n",
|
||||
" [(6,0),(3,58),(1,78),(4,78),(5,104),(2,109)]\n",
|
||||
"]\n",
|
||||
"city = 1\n",
|
||||
"tsp_serial(connections,city)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "03f0dd8e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@everywhere function tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,ftr_result)\n",
|
||||
" num_cities = length(connections)\n",
|
||||
" if hops == num_cities\n",
|
||||
" if current_distance < min_distance\n",
|
||||
" if ftr_result !== nothing\n",
|
||||
" @spawnat 1 begin\n",
|
||||
" result = fetch(ftr_result)\n",
|
||||
" result.path .= path\n",
|
||||
" result.min_distance_ref[] = current_distance\n",
|
||||
" end |> wait\n",
|
||||
" end\n",
|
||||
" return current_distance\n",
|
||||
" end\n",
|
||||
" elseif hops <= max_hops\n",
|
||||
" current_city = path[hops]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" for (next_city,distance_increment) in connections[current_city]\n",
|
||||
" if !visited(next_city,hops,path)\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" next_distance = current_distance + distance_increment\n",
|
||||
" if next_distance < min_distance\n",
|
||||
" return tsp_dist_impl(connections,next_hops,path,next_distance,min_distance,max_hops,jobs_chnl,ftr_result)\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" end \n",
|
||||
" else\n",
|
||||
" if jobs_chnl !== nothing\n",
|
||||
" put!(jobs_chnl,(;hops,path,current_distance))\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" min_distance\n",
|
||||
"end\n",
|
||||
"\n",
|
||||
"function tsp_dist(connections,city)\n",
|
||||
" max_hops = 2\n",
|
||||
" num_cities = length(connections)\n",
|
||||
"function generate_jobs(C_sorted,city,max_hops,jobs_chnl)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" path=zeros(Int,num_cities)\n",
|
||||
" hops = 1\n",
|
||||
" path[hops] = city\n",
|
||||
" current_distance = 0\n",
|
||||
" min_distance = typemax(Int)\n",
|
||||
" jobs_chnl = RemoteChannel(()->Channel{Any}(10))\n",
|
||||
" ftr_result = @spawnat 1 (;path,min_distance_ref=Ref(min_distance))\n",
|
||||
" task = @async begin\n",
|
||||
" tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_chnl,nothing)\n",
|
||||
" for w in workers()\n",
|
||||
" put!(jobs_chnl,nothing)\n",
|
||||
" end\n",
|
||||
" generate_jobs_recursive(C_sorted,hops,path,max_hops,jobs_chnl)\n",
|
||||
" for w in workers()\n",
|
||||
" put!(jobs_chnl,(0,Int[]))\n",
|
||||
" end\n",
|
||||
" @sync for w in workers()\n",
|
||||
" @spawnat w begin\n",
|
||||
" max_hops = typemax(Int)\n",
|
||||
" jobs_channel = nothing\n",
|
||||
" while true\n",
|
||||
" job = take!(jobs_chnl)\n",
|
||||
" if job == nothing\n",
|
||||
" break\n",
|
||||
" end\n",
|
||||
" hops = job.hops\n",
|
||||
" path = job.path\n",
|
||||
" current_distance = job.current_distance\n",
|
||||
" tsp_dist_impl(connections,hops,path,current_distance,min_distance,max_hops,jobs_channel,ftr_result)\n",
|
||||
" close(jobs_chnl)\n",
|
||||
"end\n",
|
||||
"function generate_jobs_recursive(C_sorted,hops,path,max_hops,jobs_chnl)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops == max_hops\n",
|
||||
" @show path\n",
|
||||
" put!(jobs_chnl,(hops,copy(path)))\n",
|
||||
" return nothing\n",
|
||||
" else\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" if ! already_visited\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" generate_jobs_recursive(C_sorted,next_hops,path,max_hops,jobs_chnl)\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" end \n",
|
||||
" result = fetch(ftr_result)\n",
|
||||
" (;path = result.path, distance = result.min_distance_ref[])\n",
|
||||
" return nothing\n",
|
||||
" end\n",
|
||||
"end\n",
|
||||
"city = 1\n",
|
||||
"tsp_dist(connections,city)"
|
||||
"@everywhere function consume_jobs(C_sorted,jobs_chnl)\n",
|
||||
" while true\n",
|
||||
" hops,path = take!(jobs_chnl)\n",
|
||||
" if hops == 0\n",
|
||||
" println(\"Done!\")\n",
|
||||
" break\n",
|
||||
" end\n",
|
||||
" consume_jobs_recursive(C_sorted,hops,path)\n",
|
||||
" end\n",
|
||||
"end\n",
|
||||
"@everywhere function consume_jobs_recursive(C_sorted,hops,path)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops != num_cities\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" if ! already_visited\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" consume_jobs_recursive(C_sorted,next_hops,path)\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" return nothing\n",
|
||||
" else\n",
|
||||
" @show path\n",
|
||||
" return nothing\n",
|
||||
" end\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "370a1205",
|
||||
"id": "02801b66",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"source": [
|
||||
"C = [\n",
|
||||
" 0 2 3 2\n",
|
||||
" 2 0 4 1\n",
|
||||
" 3 4 0 3\n",
|
||||
" 2 1 3 0 \n",
|
||||
"]\n",
|
||||
"C_sorted = sort_neighbors(C)\n",
|
||||
"city = 1\n",
|
||||
"max_hops = 2\n",
|
||||
"min_distance = enumerate_paths_dist(C_sorted,city,max_hops)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0d579e3d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### How to track the global minimum distance?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d0303392",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"buffer = 1 # very important\n",
|
||||
"min_distance_chnl = RemoteChannel(()->Channel{Int}(buffer))\n",
|
||||
"put!(min_distance_chnl,typemax(Int))\n",
|
||||
"@sync for w in workers()\n",
|
||||
" @spawnat w begin\n",
|
||||
" sleep(rand(1:3))\n",
|
||||
" min_distance = take!(min_distance_chnl)\n",
|
||||
" @show min_distance\n",
|
||||
" distance = rand(5:10)\n",
|
||||
" min_distance = min(distance,min_distance)\n",
|
||||
" @show distance\n",
|
||||
" put!(min_distance_chnl,min_distance)\n",
|
||||
" end\n",
|
||||
"end\n",
|
||||
"min_distance = take!(min_distance_chnl)\n",
|
||||
"@show min_distance\n",
|
||||
"close(min_distance_chnl)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1fabefcb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Final parallel implementation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "96c649b7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"function tsp_dist(C_sorted,city,max_hops)\n",
|
||||
" T = typeof((0,Int[],0))\n",
|
||||
" jobs_chnl = RemoteChannel(()->Channel{T}(1))\n",
|
||||
" min_distance_chnl = RemoteChannel(()->Channel{Int}(1))\n",
|
||||
" put!(min_distance_chnl,typemax(Int))\n",
|
||||
" @sync begin\n",
|
||||
" for w in workers()\n",
|
||||
" @spawnat w consume_jobs(C_sorted,jobs_chnl,min_distance_chnl)\n",
|
||||
" end\n",
|
||||
" generate_jobs(C_sorted,city,max_hops,jobs_chnl)\n",
|
||||
" end\n",
|
||||
" min_distance = take!(min_distance_chnl)\n",
|
||||
" close(min_distance_chnl)\n",
|
||||
" return min_distance\n",
|
||||
"end\n",
|
||||
"function generate_jobs(C_sorted,city,max_hops,jobs_chnl)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" path=zeros(Int,num_cities)\n",
|
||||
" hops = 1\n",
|
||||
" path[hops] = city\n",
|
||||
" distance = 0\n",
|
||||
" generate_jobs_recursive(C_sorted,hops,path,max_hops,jobs_chnl,distance)\n",
|
||||
" for w in workers()\n",
|
||||
" put!(jobs_chnl,(0,Int[],0))\n",
|
||||
" end\n",
|
||||
" close(jobs_chnl)\n",
|
||||
"end\n",
|
||||
"function generate_jobs_recursive(C_sorted,hops,path,max_hops,jobs_chnl,distance)\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops == max_hops\n",
|
||||
" @show path, distance\n",
|
||||
" put!(jobs_chnl,(hops,copy(path),distance))\n",
|
||||
" return nothing\n",
|
||||
" else\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" next_distance = distance + distance_increment\n",
|
||||
" if ! already_visited\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" generate_jobs_recursive(\n",
|
||||
" C_sorted,next_hops,path,max_hops,jobs_chnl,next_distance)\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" return nothing\n",
|
||||
" end\n",
|
||||
"end\n",
|
||||
"@everywhere function consume_jobs(C_sorted,jobs_chnl,min_distance_chnl)\n",
|
||||
" while true\n",
|
||||
" hops,path,distance = take!(jobs_chnl)\n",
|
||||
" if hops == 0\n",
|
||||
" println(\"Done!\")\n",
|
||||
" break\n",
|
||||
" end\n",
|
||||
" min_distance = take!(min_distance_chnl)\n",
|
||||
" put!(min_distance_chnl,min_distance)\n",
|
||||
" consume_jobs_recursive(C_sorted,hops,path,min_distance_chnl,distance,min_distance)\n",
|
||||
" end\n",
|
||||
"end\n",
|
||||
"@everywhere function consume_jobs_recursive(C_sorted,hops,path,min_distance_chnl,distance,min_distance)\n",
|
||||
" if distance >= min_distance\n",
|
||||
" return min_distance\n",
|
||||
" end\n",
|
||||
" num_cities = length(C_sorted)\n",
|
||||
" if hops != num_cities\n",
|
||||
" city = path[hops]\n",
|
||||
" connections = C_sorted[city]\n",
|
||||
" next_hops = hops + 1\n",
|
||||
" for (next_city,distance_increment) in connections\n",
|
||||
" already_visited = (next_city in view(path,1:hops))\n",
|
||||
" next_distance = distance + distance_increment\n",
|
||||
" if ! already_visited\n",
|
||||
" path[next_hops] = next_city\n",
|
||||
" min_distance = consume_jobs_recursive(\n",
|
||||
" C_sorted,next_hops,path,min_distance_chnl,next_distance,min_distance)\n",
|
||||
" end\n",
|
||||
" end\n",
|
||||
" return min_distance\n",
|
||||
" else\n",
|
||||
" min_distance = take!(min_distance_chnl)\n",
|
||||
" min_distance = min(min_distance,distance)\n",
|
||||
" put!(min_distance_chnl,min_distance)\n",
|
||||
" @show path, distance, min_distance\n",
|
||||
" return min_distance\n",
|
||||
" end\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "67888155",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"city = 1\n",
|
||||
"max_hops = 2\n",
|
||||
"min_distance = tsp_dist(C_sorted,city,max_hops)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
Reference in new issue
Block a user