Merge pull request #34 from fverdugo/francesc

Preparation work for 2024-25
This commit is contained in:
Francesc Verdugo authored and GitHub committed 2024-08-19 16:04:09 +02:00
commit e6474b1a8e
20 files changed
+26041 -29813

No files matched your search

+6 -6
View File
@@ -119,13 +119,13 @@ makedocs(;
"Julia Basics" => "julia_basics.md",
"Asynchronous programming in Julia" => "julia_async.md",
"Distributed computing in Julia" => "julia_distributed.md",
"Distributed computing with MPI" => "mpi_tutorial.md",
#"Distributed computing with MPI" => "mpi_tutorial.md",
"Matrix-matrix multiplication"=>"matrix_matrix.md",
"Jacobi method" => "jacobi_method.md",
"All pairs of shortest paths" => "asp.md",
"Gaussian elimination" => "LEQ.md",
"Traveling salesperson problem" => "tsp.md",
"Partial differential equations" => "pdes.md",
#"Jacobi method" => "jacobi_method.md",
#"All pairs of shortest paths" => "asp.md",
#"Gaussian elimination" => "LEQ.md",
#"Traveling salesperson problem" => "tsp.md",
#"Partial differential equations" => "pdes.md",
],
"Solutions" => "solutions_for_all_notebooks.md",
],
+20 -14
View File
@@ -129,7 +129,13 @@ If this runs without error and you see a version number, you are good to go!
In this tutorial, when a code snipped starts with `$`, it should be run in the terminal. Otherwise, the code is to be run in the Julia REPL.
!!! tip
Avoid calling Julia code from the terminal, use the Julia REPL instead! Each time you call Julia from the terminal, you start a fresh Julia session and Julia will need to compile your code from scratch. This can be time consuming for large projects. In contrast, if you execute code in the REPL, Julia will compile code incrementally, which is much faster. Running code in a cluster (like in DAS-5 for the Julia assignment) is among the few situations you need to run Julia code from the terminal.
Avoid calling Julia code from the terminal, use the Julia REPL instead!
Each time you call Julia from the terminal, you start a fresh Julia session and Julia will need to compile your code from scratch.
This can be time consuming for large projects.
In contrast, if you execute code in the REPL, Julia will compile code incrementally, which is much faster.
Running code in a cluster (like in DAS-5 for the Julia assignment) is among the few situations you need to run Julia code
from the terminal. Visit this link ([Julia workflow tips](https://docs.julialang.org/en/v1/manual/workflow-tips/))
from the official Julia documentation for further information about how to develop Julia code effectivelly.
### Running parallel code
@@ -199,11 +205,11 @@ To install a package, we need to enter *package* mode. Remember that we entered
```julia
julia> ]
```
At this point, the prompt should have changed to `(@v1.8) pkg>` indicating that we are in package mode. The text between the parentheses indicates which is the active *project*, i.e., where packages are going to be installed. In this case, we are working with the global project associated with our Julia installation (which is Julia 1.8 in this example, but it can be another version in your case).
At this point, the prompt should have changed to `(@v1.10) pkg>` indicating that we are in package mode. The text between the parentheses indicates which is the active *project*, i.e., where packages are going to be installed. In this case, we are working with the global project associated with our Julia installation (which is Julia 1.10 in this example, but it can be another version in your case).
To install the MPI package, type
```julia
(@v1.8) pkg> add MPI
(@v1.10) pkg> add MPI
```
Congrats, you have installed MPI!
@@ -230,7 +236,7 @@ $ mpiexec -np 4 julia hello_mpi.jl
But it will probably not work since the version of `mpiexec` needs to match with the MPI version we are using from Julia. Don't worry if you could not make it work! A more elegant way to run MPI code is from the Julia REPL directly, by using these commands:
```julia
julia> using MPI
julia> mpiexec(cmd->run(`$cmd -np 4 julia hello_mpi.jl`))
julia> run(`$(mpiexec()) -np 4 julia hello_mpi.jl`)
```
Now, you should see output from 4 ranks.
@@ -241,9 +247,9 @@ Now, you should see output from 4 ranks.
We have installed the `MPI` package globally and it will be available in all Julia sessions. However, in some situations, we want to work with different versions of the same package or to install packages in an isolated way to avoid potential conflicts with other packages. This can be done by using local projects.
A project is simply a folder in the hard disk. To use a particular folder as your project, you need to *activate* it. This is done by entering package mode and using the `activate` command followed by the path to the folder you want to activate.
A project is simply a folder in your file system. To use a particular folder as your project, you need to *activate* it. This is done by entering package mode and using the `activate` command followed by the path to the folder you want to activate.
```julia
(@v1.8) pkg> activate .
(@v1.10) pkg> activate .
```
The previous command will activate the current working directory. Note that the dot `.` is indeed the path to the current folder.
@@ -253,7 +259,7 @@ The prompt has changed to `(lessons) pkg>` indicating that we are in the project
You can activate a project directly when opening Julia from the terminal using the `--project` flag. The command `$ julia --project=.` will open Julia and activate a project in the current directory. You can also achieve the same effect by setting the environment variable `JULIA_PROJECT` with the path of the folder you want to activate.
!!! note
The active project folder and the current working directory are two independent concepts! For instance, `(@v1.8) pkg> activate folderB` and then `julia> cd("folderA")`, will activate the project in `folderB` and change the current working directory to `folderA`.
The active project folder and the current working directory are two independent concepts! For instance, `(@v1.10) pkg> activate folderB` and then `julia> cd("folderA")`, will activate the project in `folderB` and change the current working directory to `folderA`.
At this point all package-related operations will be local to the new project. For instance, install the `DataFrames` package.
@@ -271,7 +277,7 @@ Now, we can return to the global project to check that `DataFrames` has not been
```julia
(lessons) pkg> activate
```
The prompt is again `(@v1.8) pkg>`
The prompt is again `(@v1.10) pkg>`
Now, try to use `DataFrames`.
@@ -295,13 +301,13 @@ In other words, `Project.toml` contains the packages relevant for the user, wher
You can see the path to the current `Project.toml` file by using the `status` operator (or `st` in its short form) while in package mode
```julia
(@v1.8) pkg> status
(@v1.10) pkg> status
```
The information about the `Manifest.toml` can be inspected by passing the `-m` flag.
```julia
(@v1.8) pkg> status -m
(@v1.10) pkg> status -m
```
### Installing packages from a project file
@@ -325,7 +331,7 @@ julia> mkdir("newproject")
To install all the packages registered in this file you need to activate the folder containing your `Project.toml` file
```julia
(@v1.8) pkg> activate newproject
(@v1.10) pkg> activate newproject
```
and then *instantiating* it
```julia
@@ -339,12 +345,12 @@ The instantiate command will download and install all listed packages and their
You can get help about a particular package operator by writing `help` in front of it
```julia
(@v1.8) pkg> help activate
(@v1.10) pkg> help activate
```
You can get an overview of all package commands by typing `help` alone
```julia
(@v1.8) pkg> help
(@v1.10) pkg> help
```
### Package operations in Julia code
@@ -357,7 +363,7 @@ julia> Pkg.status()
```
is equivalent to calling `status` in package mode.
```julia
(@v1.8) pkg> status
(@v1.10) pkg> status
```
## Conclusion
+1 -1
View File
@@ -44,7 +44,7 @@ julia> notebook()
## Authors
This material is created by [Francesc Verdugo](https://github.com/fverdugo/) with the help of [Gelieza Kötterheinrich](https://www.linkedin.com/in/gelieza/). Part of the notebooks are based on the course slides by [Henri Bal](https://www.vuhpdc.net/henri-bal/).
This material is created by [Francesc Verdugo](https://github.com/fverdugo/) with the help of [Gelieza Kötterheinrich](https://www.linkedin.com/in/gelieza-k/). Part of the notebooks are based on the course slides by [Henri Bal](https://www.vuhpdc.net/henri-bal/).
## License
+32 -84
View File
@@ -2,19 +2,6 @@
## Julia Basics
### NB1-Q1
In the first, line we assign a variable to a value. In the second line, we assign another variable to the same value. Thus,we have 2 variables associated with the same value. In line 3, we associate `y` to a new value (re-assignment). Thus, we have 2 variables associated with 2 different values. Variable `x` is still associated with its original value. Thus, the value at the final line is `x=1`.
### NB1-Q2
It will be `1` for very similar reasons as in the previous questions: we are reassigning a local variable, not the global variable defined outside the function.
### NB1-Q3
It will be `6`. In the returned function `f2`, `x` is equal to `2`. Thus, when calling `f2(3)` we compute `2*3`.
### Exercise 1
```julia
@@ -50,77 +37,10 @@ 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.
### NB2-Q2
The time in doing the loop will be almost zero since the loop just schedules 10 tasks, which should be very fast.
### NB2-Q3
It will take 2.5 seconds, like in question 1. The `@sync` macro forces to wait for all tasks we have generated with the `@async` macro. Since we have created 10 tasks and each of them takes about 0.25 seconds, the total time will be about 2.5 seconds.
### NB2-Q4
It will take about 3 seconds. The channel has buffer size 4, thus the call to `put!`will not block. The call to `take!` will not block neither since there is a value stored in the channel. The taken value is 3 and therefore we will wait for 3 seconds.
### NB2-Q5
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() ]
@@ -160,6 +80,38 @@ end
msg = 2
@fetchfrom 2 work(msg)
```
## MPI (Point-to-point)
### 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
```
## Matrix-matrix multiplication
### Exercise 1
@@ -209,10 +161,6 @@ end
end
```
### Exercise 2
At each call to @spawnat we will communicate O(N) and compute O(N) in a worker process just like in algorithm 1. However, we will do this work N^2/P times on average at each worker. Thus, the total communication and computation on a worker will be O(N^3/P) for both communication and computation. Thus, the communication over computation ratio will still be O(1) and thus the communication will dominate in practice, making the algorithm inefficient.
## Jacobi method
### Exercise 1
+192 -63
View File
@@ -25,6 +25,35 @@
"- How to fix static load imbalance"
]
},
{
"cell_type": "markdown",
"id": "480af594",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to execute the cell below before starting this notebook! \n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7e93809a",
"metadata": {},
"outputs": [],
"source": [
"using Printf\n",
"function answer_checker(answer,solution)\n",
" if answer == solution\n",
" \"🥳 Well done! \"\n",
" else\n",
" \"It's not correct. Keep trying! 💪\"\n",
" end |> println\n",
"end\n",
"ge_par_check(answer) = answer_checker(answer, \"a\")\n",
"ge_dep_check(answer) = answer_checker(answer, \"b\")"
]
},
{
"cell_type": "markdown",
"id": "8dcee319",
@@ -33,7 +62,7 @@
"## Gaussian elimination\n",
"\n",
"\n",
"System of linear algebraic equations\n",
"[Gaussian elimination](https://en.wikipedia.org/wiki/Gaussian_elimination) is a method to solve systems of linear equations, e.g.\n",
"\n",
"$$\n",
"\\left[\n",
@@ -60,7 +89,7 @@
"\\right]\n",
"$$\n",
"\n",
"Elimination steps\n",
"The steps of the Gaussian elimination will transform the system into an upper triangular matrix. The system of linear equations can now easily be solved by backward substitution. \n",
"\n",
"\n",
"$$\n",
@@ -112,7 +141,10 @@
"id": "94c10106",
"metadata": {},
"source": [
"### Serial implementation\n"
"### Serial implementation\n",
"The following algorithm computes the Gaussian elimination on a matrix which represents a system of linear equations.\n",
"- The first inner loop in line 4 divides the current row by the value of the diagonal entry, thus transforming the diagonal to contain only ones. \n",
"- The second inner loop beginning in line 8 substracts the rows from one another such that all entries below the diagonal become zero. "
]
},
{
@@ -140,6 +172,24 @@
"end"
]
},
{
"cell_type": "markdown",
"id": "3763b000",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> This algorithm is not correct for all matrices: if any diagonal element <code>B[k,k]</code> is zero, the computation in the first inner loop fails. To get around this problem, another step can be added to the algorithm that swaps the rows until the diagonal entry of the current row is not zero. This process of finding a nonzero value is called <b>pivoting</b>. \n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "fbb3d1eb",
"metadata": {},
"source": [
"You can verify that the algorithm computes the upper triangular matrix correctly for the example in the introduction by running the following code cell. "
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -185,6 +235,32 @@
"```"
]
},
{
"cell_type": "markdown",
"id": "e52c4b38",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which of the loops can be parallelized?\n",
"</div>\n",
"\n",
" a) the inner loops, but not the outer loop\n",
" b) the outer loop, but not the inner loops\n",
" c) all loops\n",
" d) only the first inner loop"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "078e974e",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c, or d \n",
"ge_par_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "14d57c52",
@@ -193,70 +269,79 @@
"### Two possible data partitions"
]
},
{
"cell_type": "markdown",
"id": "6b17aee4",
"metadata": {},
"source": [
"The outer loop of the algorithm is not parallelizable, since the iterations depend on the results of the previous iterations. However, we can extract parallelism from the inner loops. Let's have a look at two different parallelization schemes. \n",
"\n",
"1. **Block-wise partitioning**: Each processor gets a block of subsequent rows. \n",
"2. **Cyclic partitioning**: The rows are alternately assigned to different processors. "
]
},
{
"attachments": {
"g23933.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABL4AAAI1CAYAAADYRTMtAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N13nB1V3cfx79yyfTeFFBICREoISEcQgyFggAQjIoYAtoCAIFIUIYB0EDQ+BFFUiiI8CfKoIE0REanSQ9UQSkCSkJCerXfbbfP8cbKyuXtuttzdOyeTz/v1mhdk9s7Mb+49O/fsd2bOSAA2V+Mk+TnTnwKoo8ZSxxMB1LE5OVZd37MrAq0IAAAAYTZHXfufk3q47EOWZbcegBqBARELugBscaol7StphOVnL0ha3k/bmSapopfLNEmql7Ra0gpJ7f1UCwAAAMKjStLekkZZfvaypCX9tJ0pMicYeyOhjfuzbf1UCwBstgi+MJA6OgWfkrTfhv+OkxTJ8/rjJN3TT9u+SdJ2BSyflbRU0tsygdw/JT0vKV14aQAAANhMVGjj/ux+ksZLiuZ5/cmS7uinbf9U0m4FLO/L9GffkenPPiPpWUmpwksDgM0HwRf621hJV8l0DnZR/k6B6yKSPrFh+vyGeetkbiW8SdKCgOoCAADAwBot6VqZkGtXbb5/M3kyffOxkqZumFcr6X6Z/uxrgVQFAEWW78oboK/GSpopc3Zqcw298hkm6duS/iVzn/suwZYDAACAATBa0kmS9tDmG3rlM1TSKZJelfSopN2DLQcABh7BF9B7nswYYv+WdMGGfwMAAACbk8MlvS7pSvF3IYAQ4wCHYkrIjC3wM5lBN4vtVJmQyjbFJG0laUdJB8pc2XW7pIWbWF+JpJ9I+oOk+IBVDQAAAFc0S3pO0o2S1gSw/e8pf382KnNF146SDpD0LUm3yZyszScm82TpBySVDljV2NydINO2Ok9BtH+gT8J26S7ckZA5g/Rqp+ldmUHjJenLkgYHU5pVRmbMg1pJH0h6SdKtG342XtIZMp2Hcsuyx2347wkyg4gCAABg89ci6Q1t3J99W6bfKEmHyf6k8qBkJdVtmD6QecLkbRt+tpOk02X6tJWWZY+SGcv2S/p4/4AOiaALAApB8IX+9m+Z8b06h1ybu3ckfVfSDTKdh8mW1xwnE/TNLmJdAAAA6H/vyYzv1Tnk2ty9L2mWzJ0Xv9bHD2/q7AsyD6m6tIh1AcCA41ZH9LdamU5CWEKvzpZImiLTWbC5WubJPwAAANh8NUh6U+EJvTr7SObqrhvy/PwHkvYtXjkAMPC44gvonYzMJeJDJM3I+Vlc0nUyZ8tcNFrSzjJjmbVLWi7pQ5nL4V3lSdpW0khJw2WOWWs3TEslpYpUR6mk7WTeu602/LtR0mpJi2TeTwAAgM1BVtJ5Mv3Zk3J+FpH0U0mHFLekbg2TtLU+7ou1S2qS6Q8uDbCugTRcpg+8JezzUEmj9PG+pmT29UOZiw8YTgYFIfgCei8r6TRJEyRtk/Ozz8vc6vlWsYvKY5Skc2RuxdzB8vOspH9K+j9JcyUli1daXhGZ8PBoSUfK7INNo6R/SHpI0h8ltfZzHZ+QCTcPk/RZ2cd3k0wYukjS45IekfR3Sel+rmVTviLpGMv8x/XxOHUAAACd+ZLOkjRRZjD8ziZJ2l9mjLCgRGT6YF/Y8N9N3VWRkDRfpl94v8yQKza/kAmSOrtE5tbWQl2lrjVeLzNucE9FZJ60OU3d73OTzD4/Juk+mb7oQLpIXa8EPE19f2CZJxOuHiWzr7tvmGfTLOkVmX19QOZqTADYLCyV+cLtPOVeQdXf6z+lH9cvmadE5m7DV/5Lx/vbOMu2/9Tp59+R+VK01WibFkj6dB/qqLGs64k+rEcyHa2Fvai5Y1opaWYft5lrjKS7ZMKr3tbhy9xC8KVutnGsZbkr+lDrxTLhZe665sk8dRQAAAwcW5/lmwO8/u/24/qljx/OlDv9pp+30xtflBk6pS/9sKykp2X6p7musbz++n6od4zMFUqd19sg+0ME8jlaZlzhvu7zU7Lvc2dzLMtO6mF9D1mW3bqHy+Y6XNK/LOvr6fS8ugaYAOCkMARfJTK33OVu54N+3k4+mwq+fmb5WU+mtHr/OfRX8HWpzNVTff0S9CX9ToU9inuGTEelkBp8mbN+m1Jo8BWTdEuebV+r/GfMAABA/wlD8BWVtMyynVUq/njQlTIn7wrth/nqeleGJG2vric216qwvqMkXW7Z/q96uGylpDsty/dlGt3NtoIOvkqVv//a22m3Xm4bWzhudQT6LilzOfW3cuZ/QmYsrf64bLovzlXXTlFS5szZcplb9rZX18vaJdP5uUtSm6S/DGCNua6RudQ8n5Uy9/inZb7Ux8oe7nxN0iCZW/96e7vh2ZJ+nme9kjmb9qGkNTKX1A/ZUEuxzzhVytzaOS1nfkbSmeL2RgAA0HMZSffI9B87GylpL5mnlhdDjaSHJR20idc0yfRl18mEckNk+t35hqPItXTDNo7qNG+YpOkyw370RVT2k+v5HobV2aAN9UzYxGsK3WdXlEt6UOZqr3yaZULYdRv+PUSmz9+bK+cAwClhuOJLkk60bMeXGXdpoNmu+Pq3TGjV8e96mTG+hlqW303SbbLfKlcv+5kym0Kv+JqWp4asTIizl2WZ7WWuqmq1LOfLnHnrjRPy1OBLek3SN2QGGLXZRmYMtT/KfGH7GrgrvkbKjLeRu2xC7j5UAQCAsArDFV+SCX5sfaDck7sDJSYzRqqthpRMiDRJ9os2YpL2lnSBzDhQm7riSzLjx+Zu46kCap9mWd8LPVguJulRy7Id+3yrNr3P+6jrPrt6xZcn6V7L8r5M8DpX0mTZh+mIStpDJph9QR/317niC8BmISzB186W7fiSfjwA28plC746T2/LPBGxO1+SuSIsd/n7e1hHIcHXcJlL6XOXb5T5AuzOrpIWW5ZPyQzK2hM7yD4WWlLS6erdZf6DZW7ZPLub1/Ul+NpF5jba3OVWq+f7CgAA+k9Ygq9Rlu34MoPBF8Mlebb/pjY9wLvNfjJDf+R7OFJE0n9ytpOVNL7XVRsPqmvdJ/Vgucssy/kyY+72tpb9ZIKl7oKooIKvsy3L+jJ3x9hOcG/KHjJ3p+zSy+UAIBBhCb482ceEumsAtpVrU8HXKpmronrqxDzrmdiDZQsJvv7HsmxKPQu9Ouws+1hrj/dw+Qcsy7bLnBEcKL0Nvj4rc9l37jLvyv60TgAAMPDCEnxJ0grLth4coG11tp3sV/C/LPsdC/3hAsv2+jLIvW1Q+zpJFd0st702vkOjY5ovc3vfQAki+Bohc0LbFvAxQD2KptgDFgJh40tab5nf3aXGA+1CmfCvp+ZK+ptl/un9U45VuaSTLfNvVM9DK8mcLZplmX+ozKORN2Vvmafo5LpC9vcjCMfKPJ57q5z5z8uMg1GshykAAIDwWmeZV4z+7IWSynLmNcqcEK8doG3eLnOSs7OZ6v0g9yer662Id0pq6Wa5iyzbapDZ57pe1uC6cyVV58xrlXS8zF0LQFEQfAGFs31B5R7gi+ktmSfi9NZFlnnTNXBnno5V1zCnUdKVfVjXXJnHInfmqfvg7lTLvAUyV6K54FyZscNyO4T3SzpM9k4qAABAbwXRny2T9HXL/MslLRnA7a6TGdC/s45B7nuqr4Pal8s8jCnXZerdSevNQVT2k9yzZf5eAYqG4AsonK2jEOSTVu6SuRKtt/6truFRmXp2u2NffM4y7x6Z8bZ6y5f0v5b5h3az3BTLvF/KjPUQJE/STyT9VF2P07+QCQ1bi10UAAAIrSD6s5+RGTKjs4SkOwZ4u5J0s2VebwbzP1LmNs3OnpMZl2xTJqhroNgkcxI3bPaSudWxs6R4AjkCQPAFFM4WkgT5u/WXApa1jeVwQAHr25QDLfPuK2B9uWfuJDMg6qA8rx8taaeceRmZK6yCVC4zKOsFOfOzks6XeUpn0MEcAAAIlyD6swdb5v1Z5g6Agfa8up7wnaSeDyxvC8l6EujY9vlBFWefi802ftij4hZHBIDgCyic7VbAoK7GaZN5mmNfvW6ZNxBPDKyR/Wksrxawzo9kBvXvLCLpU3lef5Bl3kKZMRaCMkzSY5K+nDO/XdJX1beBVwEAALpj6892N1ZVoWx9secHeJud3ZLzb089u+prG0mfz5lXK3PisjtB73MxTbDMC+u+wnEEX0DhBlvmJYpehfGepHQByy+0zBuIgU1HyHQuOlujws8A/dsyL98TZ2z79VqB2y/EDjKXyOd2EuokHaHgr0QDAADhZQu+mgd4m0H3xe5S1yutejLI/SnqOqj9PPXsxHfQ+1xMW9K+wnEEX0Dhcgdol8wjoYNQ6NNvbMsPxOD2trCwP57cY3vCZr76bY/IDnKw+JmSxuXMWyrps5L+WfxyAADAFsTWLxro/mzQfbEmmacwdtbdIPd9HdS+Q9D7XExb0r7CcQRfQGG2lT1YWV7sQjboy8DwndnGF7CFVIWyrbPQ2iX7bYq9Cb7q+6GG/tSmYG+9BAAA4TdU0hjL/IHuz9r6YsXu9+Te7ihJp23i9VPVdVD7f6rnQ424sM/FsiXtKxxH8AUU5jN55i8oahWbn748dbIncm+f7G0NvVm+vz0n86SbznaR6UyNLXo1AABgS/EZ2ftAtiEk+tNA9Qd7401Jz+TMmyRptzyvt4VivXlKoQv7DGxxCL6AwtgGbZSkV4paxcdyHwndW7YnINoeb10o25VVhdaebx35bqG0zc/3BMhi+IekL6nr+BA7yIRfOxe9IgAAsCXIdyK3kIcO9YStLzYQdxp052bLPNvtjLZB7ddJurcX23Jln4vBNgRJWPcVjiP4AvouIhNU5Fop6a0i19LBdklxb9jGKxuI2/9s67Rtu7eGWeblC+5sHY/h/VBDIf4maZq6PhxhW0lPS/pk0SsCAABhl/s0acn0n4IIvoLoi90r85ClzmyD3NsGLine truncated
"fig-asp-1d-partition.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "f06f0869",
"id": "c518f863",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g23933.png\" align=\"left\" width=\"400\"/>\n",
"<img src=\"attachment:fig-asp-1d-partition.png\" align=\"left\" width=\"400\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "102d6fa2",
"metadata": {},
"source": [
"## What is the work per process at iteration k?\n",
"To evaluate the efficiency of both partitioning schemes, consider how much work the processors do in the following example. \n",
"In any iteration k, which part of the matrix is updated in the inner loops? \n",
"\n",
"### Block-wise partition"
]
},
{
"attachments": {
"fig-asp-data-updated.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtcAAAJNCAYAAAD6c1l4AAAACXBIWXMAAB7CAAAewgFu0HU+AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAIABJREFUeJzs3XeYJFXVx/Hv6ZnZvLC7LGFZwrLkDIpECRJEEMVXl/waEQyor6IoBhAFEwZEBUFUVEREEQwgIkEyIkGQKJkl7i5h8+ykPu8ft4btrqmeTtVTNTO/z/P0A32n6tbZ6urqU7du3Wvujohkx8w6gXHR2053n5BlPKOFmc0GHi8pusvdd8ggjo2B24GpJcW3APu6+4qhjkdkuDCz04AvlhQd5+5nZxVP3pjZGGBtYDxQBJYBL7p7bw3rfhU4KVb8Pnf/ZeqBjkDtWQdQjZl9B5g8yCLdhANmafT/c4GHgYf1wyQieWZmqwB/pDyxvhk4sNL5y8zWAy6NFX/C3W9tTZTSKmb2e2CDkqJL3f3rWcUjw5uZjQPeARwI7AasD7TFFltuZr90948OVpe7n2xmHcCJJcXnmNmD7n5HmnGPRLlProF3A2s0sF7RzO4B/kQ4Yd2fbljpMrMdgXeWFN3g7ldmFY+Mbmb2JmD/kqK/uvuNWcUzgp0DbFHy/r/A2919ySDrjANeHytbtdLCZjaZ8ta9+e7+vXoDlXJmtivw9pKia9396jqr2YLyz//OpgOTUcfMJgL/BxwPrFZl8QnAZrXU6+6fN7OZhDwMwrnnEjPbxt0XNRrvaDAckutGFYDXRa+vmNkVwCnunteT13bA52JlSq4lK7tSfjy+BCi5TpGZHQIcUVK0kJBYv5rypiZR/lk+CCi5bt7rKd+vXUC9ybVIU8xsF+DXwOwWbeJYYBNgp+j9eoTzx9Et2t6IMByT6yVAaX+hVRh42yPJW4EDzOx04GR372lFcCIi1ZjZNOCsWPHH3P2RLOIRkeHHzOYQEuuxsT8VgbuAfwILCF1n1wVmAXvWsw13X2FmRwL3sLKL7gfM7HfuflXj0Y9swzG5PsDdbyktMDMDpgBrARsRWhTeDOxIeeJdIPQf2tbM5rj78qEJWUSkzMnA6iXvL3H3C2tc91lgv1jZv1OJSobaB4GJJe+fyyoQGV7MbF/gN0BHSXEn4aL92+4+v8J6HcDG9WzL3Z8ws+OB80qKv2dm29bycORoNByT6wE8DHnyavR6CPgLcIqZbQR8BvgA5QfgAcAfzexAHRgiMpTMbBOg9GGi5cAna10/ahS4Ju24ZOi5+21ZxyDDj5mtxcDE+ingIHd/YLB1o7v2Dzaw2Z8RuoLsHL3fgtBlRKOzJChkHUAruftj7v5h4A2EpLvUfsC3hj4qERnlTqT8R/EMd1eLpYjU6kzK73w9A+xaLbFuRtSI+ZlY8YlRS7jEjIiW62rc/V4z2w34O1A6ju0nzez37v7PWusys3ZC36X1CE/ljgH6CK1P8whDAC5NLfgmmNkkwjBPMwl9pdoIsb4CPA086e592UWYPTPbENgSWIewb54HbnP3l1KqfzPCFf46QA/h7sp/CMdJMYX6OwjH4rrAdMJ3uo8wNOWL0XY6m91OmsysDdieMEzUmoSL/JeBJwhjTTd9NynqKrY94UGcGYTv5wLg3+7+ZLP1NxHX2sCRJUULgdMzCicVZrYusA3hx34K4RhfQPgepf1wZt2ic3bpd6SD8B1Zxspz9rLsImyemW0AbEX4DCYT9v+zwL9aNSRttM2tCfvVCeeb29z9hVZsTwIz2wk4pKSoB5gzFPvd3W8xs8uBg6KidYHDgQtave3hZlQk1wDu/qqZHUzom9g/tF8B+C5hPMiKoocG9iK0gG9HSKgHW/4e4DLgR+7+yiDLTQRuiN5Oj/35vVGfqkqucvfS4bUws9WA90dxvoHy8VOTdJrZ1YQvxh98CGYUMrNbWbn/utx90H0fW/cA4NSSot+6+3cGWf47hM+t37HufneUkB4NHEMYTSau18yuAk5w9/gdj1ribAc+RLj1v0WFxZ43s4uBHzRQ/3sIx+wbCD+og7UcFM3sLuD3wI8Hu/Azs3UIYy5DSEhL/Z+ZHT7Idgb9LKL6NyIMCXcQA4/3fovM7BLgNHd/arD6KmxjInAC4XuwXoVlHiE8BPS3eutPwbGUP3z0C3dfXG8lZnYl5S1Xu7l7V2yZnxCO7/jxMdvMBhs1abm771Fl++OA44D3EBLrJH1m9k/gW+7+l8HqK6n357H65pQeB9Ht8P8Bdif8sI8jjGRzm7t/tWS5w4E9CN+RbRn8O+Jm9m/C2OFnufvCQeKbysoRQeJDxB5jZm8dZDuXu/spsfpOBOaUFH2x1ofEoglCjiN0e9yqwmLLomPlVHf/Ty31RnX/kdAg0G9vd18cndveTzi/xYeDhLAvrwc+l/exkM3sy8DbSoqcEPd1GYVUq88AVvL+Z+7+ryHc/pmsTK4BPoGS64HcPdcvQsuCl7x2a7K+98fqc2CXKus8kLBOLa+XCT8OlepdpcF6HfhNQn07N1HfLcDaQ/B5dpZsc3md6/5vLOYzqyx/WWz5PQkPuj5W4z7pBP63zhg3A+6rY7/3EJ7srnmfAPMb/IyfB/YbpN4Nmzh+Kn4WhDsmpxMmeaq1vi7gA3Xu+zcRWutq3UY8njuH4Ph/pGR7fcBGDdbzXCz28QnLXN/gZ7mkyrb3I9z5qqfOPwOTavh33RJbb7OofE3Cg1qVjqG7Y/U83uC/fT5w8CDxrd5gvQ6cn1DfWbFljqjx89+B2s9jThhh6/tAW431x+ueBuwTO36rfX8PG4Lv02mx7X60xvW+HFuvSJjdsaXxpvDvnRb7DvQC6wxxDEbos126/zbOet/k7TWi+1xXcAHhB7jUUS3a1jTgt2Z2aIvqT9OuwI1R6/dI9XlCa+WGNS4/Dji/SmvUa8zs9cBNVG5FStJOeStEK80A/lLljkiqopbkywityfHWw2eBewnPQ8QnJBgD/MzMPlHjdt5BGBd+Zh3hDWlfQTPbgfKn9G9298eGMoZmmdn7gSsYeFdgEeFzvIeB51cILYRXm1l8yLBatnkoYXKdj9L6z2x1wiQZB7d4Ow2LJni6juTzmBO6QMW1ESYZ+X0jnwHwVUK3ylpHmRgD/NLMtm5gWy1lZp8DTikpcsIwmPGhMfPorZR/B25y96TvW8t4yLDjU6AfNpQxDAejpltIP3fvNbPfUt4x/8AaV19OaFm5mdA6+QRh3O0xhOmL1yXManckITGDcFI7y8yudfeXY/V1sfKhym2Bt5T87XZCy1Ml91aJ9RngH8C/CC3v86LtTSIk/VsRLip2LllnwyieD1ape7gqnXGwmzDiwnWEZKBA+PcfSuhH2K8d+KmZbeqD3L6Pxi3+IwO7O9xIeKr7fkL/2tUIx8mmhBNlUreUWi2J6r8lqv9pQl/rsYTjcQPCsX0IK0/IY4HzzGxLHzgU5UJWHo+7EG6r9+s/liqpNPX2eZTfel1I6Ir1S3d/pr8w6oe9I6HbSOnFzLfN7FYfZPInM9sCuJDy7hZO+DwuJbTCLSFcXMwgdO16O2HYzqH05tj7mrpKNOEiwji3kwjdB/q9RHjyv5LupEIz2x/4KeUPwl9K+Dxv95LnN6K+5R8kTLIyISremXB81TwyCmGyigPqWD5uGeF83X/Oforyc/b6rDxn93dXaydM83y9D5yFbjkrvyOvB0ovVPt/Gyq5q+F/RcTM1ifs88klxYuB7xC6fj3q7n1mtgrhTt3/EVqc+/0P8E3gU3VuuvT46SV0jbmG8DvTRvguHUZ5w8JY4NuU/65lysw+Sfj393NCi/WPq6zXRjhWWqnTq/eb3jH2vuwcEnUV2pxwkTiVcNH7KvCgp/tcwZ8p349vJtxFkH5ZN53XcAsi1W4hUZ1vYeBtrOmDLP8V4GBgbI31b0N4oKS0/o9XWefY2PLfbODftTHwNWCbOtb5Umy73cCUFn6eWXYLccKP7enA6hXWKRASvPh6p1XZ1sWx5Tup4bYoIdErvc1XS7eQ/h+sjhr3266EpLs0vsOrrBPfB59p4LM+OlbHf4ENq6xjhGStdL2rBlm+jdBaWrr8i9XOE9F25sTWa2m3EEKLb+n2NmmirqrdQkqWnRFb9oEGtrcW5d2ReoH317DeTtF3rn+9HmD9QZaPdwspfT1F+AHfi3AhvD4hmTsIOCpWz9cIF3W1nrNfR3jQu3R7x1ZZ5+Ox5b/SwH6tq1sIA7v6PEyVbgGEu0al6xSBfaqsk9TlpAv4ETCjwjptwI9j6/QN9nmn8J2quVsI8BHKu+AVgQ/XuJ3VBjku03pdU0McN8fW2ZfQkPceQkNRZ4W6+wh3VT9AjV2Daojl0ZL6O2v9ro2WV+YB1PABtiK5Xjfh4Ns95bg/GKv/r1WWbzq5biLWW2PbPqSF28oyub6FGvuGJfxIPFvppES4mIqftN82FPukjm18Pvbv+VWV5ZtKrgmtVs+XrL+QKol1ybrtlCfMRWDzCsseFotzGbBVjduZHVu3Zck1IZl/tWRbzzVZ31An199p9HgAPh1b91uDLJuUXM8DPgy0t+rzibZ9XGy7f6yy/JAm14SW6NJllwKzatzOj2Lr3lBl+XhyfRewZQ3biX/vHXh3Cz+zmpJrQlIZP0d/qI7tZJ5cExp+lsTW+TL1PWfihHNrTefIKvGcF6t30GfXRttrNPa5hnAwxodBWzPlbfwx9r7ayB1Z+lPs/awsghgCX3D3R2tc9mSgdAirmYQRCpLEn96+0GscHWEIxY/HWS3e3pGUjzjyNXd/vJYVPQzF98OSImPgjIT9Toi9P83d7685yqGzBmGYun7VunXlhpmtShhZp9/9wBl1VHEu5f2A491jBnMV4U7cOd76Cb/yfh78WOz9d732EXW+QOg+0m8PM9u2jm3v7zWMoexhxJrLY8WVRpMZEmZ2FCER7D9HO6HF+tzsomrIaoQuXqVOob7nTCB0Qb3JzAYdEagG8XPYpk3WN6KMuj7XLine truncated
}
},
"cell_type": "markdown",
"id": "a67e0aad",
"metadata": {},
"source": [
"### Which is the work per process at iteration k ?\n",
"\n"
]
},
{
"attachments": {
"g26595.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "53a94ed3",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g26595.png\" align=\"left\" width=\"250\"/>\n",
"<img src=\"attachment:fig-asp-data-updated.png\" align=\"left\" width=\"250\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "d9d29899",
"metadata": {},
"source": [
"It is clear from the code that at any given iteration `k`, the matrix is updated from row `k` to `n` and from column `k` to `m`. If we look at how that reflects the distribution of work over the processes, we can see that CPU 1 does not have any work, whereas CPU 2 does a little work and CPU 3 and 4 do a lot of work. "
]
},
{
"attachments": {
"fig-asp-data-updated-2.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "d083cd53",
"metadata": {},
"source": [
"<div>\n",
" <br>\n",
" <br>\n",
" <br>\n",
" <br>\n",
"</div>"
]
},
{
"attachments": {
"g26786.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "0d80cd72",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g26786.png\" align=\"left\" width=\"250\"/>\n",
"<img src=\"attachment:fig-asp-data-updated-2.png\" align=\"left\" width=\"250\"/>\n",
"</div>"
]
},
@@ -267,51 +352,74 @@
"source": [
"### Load imbalance\n",
"\n",
"- CPUs with rows <k are idle during iteration k\n",
"- Bad load balance means bad speedups, as some CPUs are waiting instead of doing useful work\n",
"- Solution: cyclic partition "
"The block-wise partitioning scheme leads to load imbalance across the processes: CPUs with rows $<k$ are idle during any iteration $k$. The bad load balance leads to bad speedups, as some CPUs are waiting instead of doing useful work. \n",
" \n",
"### Data dependencies\n",
" \n",
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> What are the data dependencies in the block-wise partitioning?\n",
"</div>\n",
"\n",
" a) CPUs with rows >k need all rows <=k\n",
" b) CPUs with rows >k need part of row k\n",
" c) All CPUs need row k \n",
" d) CPUs with row k needs all rows >k \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0565e92",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c, or d \n",
"ge_dep_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "b90252f1",
"id": "51498a44",
"metadata": {},
"source": [
"### Cyclic partition\n",
"\n",
"- Less load imbalance\n",
"- Same data dependencies as 1d block partition\n",
"- Useful for some problems with predictable load imbalance\n",
"- A form of static load balancing\n",
"- Not suitable for all communication patterns (e.g. Jacobi)"
"In contrast, if we look at how the work is balanced for the same example and cyclic partitioning, we find that the processes have similar work load. "
]
},
{
"attachments": {
"g27009.png": {
"image/png": "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 truncated
"fig-asp-data-updated-cyclic.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "6a4c4051",
"id": "b90252f1",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g27009.png\" align=\"left\" width=\"250\"/>\n",
"<img src=\"attachment:fig-asp-data-updated-cyclic.png\" align=\"left\" width=\"250\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "866824c6",
"metadata": {},
"source": [
"## Conclusion\n",
"Cyclic partitioning tends to work well in problems with predictable load imbalance. It is a form of **static load balancing** which means using a pre-defined load schedule based on prior information about the algorithm (as opposed to **dynamic load balancing** which can schedule loads flexibly during runtime). The data dependencies are the same as for the 1d block partitioning.\n",
"\n",
"At the same time, cyclic partitioning is not suitable for all communication patterns. For example, it can lead to a large communication overhead in the parallel Jacobi method, since the computation of each value depends on its neighbouring elements."
]
},
{
"cell_type": "markdown",
"id": "20982b04",
"metadata": {},
"source": [
"## Exercise\n",
"\n",
"- The actual parallel implementation is let as an exercise\n",
"- Implement both 1d block and 1d cyclic partitions and compare performance\n",
"- Closely related with Floyd's algorithm\n",
"- Generate input matrix with function below (a random matrix is not enough, we need a non singular matrix that does not require pivoting)"
"The actual implementation of the parallel algorithm is left as an exercise. Implement both 1d block and 1d cyclic partitioning and compare their performance. The implementation is closely related to that of Floyd's algorithm. To test your algorithms, generate input matrices with the function below (a random matrix is not enough, we need a non singular matrix that does not require pivoting). "
]
},
{
@@ -343,16 +451,37 @@
"metadata": {},
"outputs": [],
"source": [
"n = 5\n",
"n = 12\n",
"C = tridiagonal_matrix(n)\n",
"b = ones(n)\n",
"gaussian_elimination!(C)"
"B = [C b]\n",
"gaussian_elimination!(B)"
]
},
{
"cell_type": "markdown",
"id": "f60d9ea0",
"metadata": {},
"source": [
"# License\n",
"\n",
"\n",
"\n",
"This notebook is part of the course [Programming Large Scale Parallel Systems](https://www.francescverdugo.com/XM_40017) at Vrije Universiteit Amsterdam and may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8ab22f67",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.9.1",
"language": "julia",
"name": "julia-1.9"
},
@@ -360,7 +489,7 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.9.1"
}
},
"nbformat": 4,
+237 -36
View File
@@ -28,19 +28,56 @@
},
{
"cell_type": "markdown",
"id": "ade31d26",
"id": "394d4b7a",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to run the next cell before starting studying this notebook. \n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1dc78750",
"metadata": {},
"outputs": [],
"source": [
"using Printf\n",
"\n",
"function answer_checker(answer,solution)\n",
" if answer == solution\n",
" \"🥳 Well done! \"\n",
" else\n",
" \"It's not correct. Keep trying! 💪\"\n",
" end |> println\n",
"end\n",
"floyd_check(answer) = answer_checker(answer,\"c\")\n",
"floyd_impl_check(answer) = answer_checker(answer, \"d\")"
]
},
{
"cell_type": "markdown",
"id": "24b5c21a",
"metadata": {},
"source": [
"## The All Pairs of Shortest Paths (ASP) problem\n",
"\n",
"Let us start by presenting the all pairs of shortest paths (ASP) problem and its solution with the [Floyd–Warshall algorithm](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm).\n",
"Let us start by presenting the all pairs of shortest paths (ASP) problem and its solution, the [Floyd–Warshall algorithm](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm).\n",
"\n",
"### Problem statement\n",
"\n",
"- Given a graph $G$ with a distance table $C$\n",
"- Compute the length of the shortest path between any two nodes in $G$\n",
"\n",
"We represent the distance table as a matrix, where $C_{ij}$ is the distance from node $i$ to node $j$. Next figure shows the input and solution (output) of the ASP problem for a simple 4-node directed graph. Note that the minimum distance from node 2 to node 3, which is $C_{23}=8$ as highlighted in the figure.\n"
"- Compute the length of the shortest path between any two nodes in \n",
"$G$"
]
},
{
"cell_type": "markdown",
"id": "ade31d26",
"metadata": {},
"source": [
"We represent the distance table as a matrix, where $C_{ij}$ is the distance from node $i$ to node $j$. The next figure shows the input and solution (output) of the ASP problem for a simple 4-node directed graph. Note that the minimum distance from node 2 to node 3, $C_{23}=8$, is highlighted in the figure."
]
},
{
@@ -229,7 +266,7 @@
"source": [
"### Serial performance\n",
"\n",
"This algorithm is memory bound, meaning that the main cost is in getting and setting data from the input matrix `C`. In this situations, the order in which we traverse the entries of matrix `C` has a significant performance impact.\n",
"This algorithm is memory bound, meaning that the main cost is in getting and setting data from the input matrix `C`. In this situation, the order in which we traverse the entries of matrix `C` has a significant performance impact.\n",
"\n",
"The following function computes the same result as for the previous function `floyd!`, but the nesting of loops over i and j is changed.\n"
]
@@ -282,7 +319,7 @@
"id": "ad811b10",
"metadata": {},
"source": [
"The performance difference is significant. Matrices in Julia are stored in memory in column-major order (like in Fortran, unlike in C). It means that it is more efficient to access the data also in column-major order (like in function `floyd!`). See this section of [Julia's performance tips](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-column-major) if you are interested in further details."
"The performance difference is significant. Matrices in Julia are stored in memory in column-major order (like in Fortran, unlike in C and Python). It means that it is more efficient to access the data also in column-major order (like in function `floyd!`). See this section of [Julia's performance tips](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-column-major) if you are interested in further details."
]
},
{
@@ -315,14 +352,29 @@
},
{
"cell_type": "markdown",
"id": "9a9e8c44",
"id": "5f26f9b5",
"metadata": {},
"source": [
"### Parallelization strategy\n",
"\n",
"As for the matrix-matrix product and Jacobi, any of the iterations over $i$ and $j$ are independent and could be computed on a different processor. However, we need a larger grain size for performance reason. Here, we adopt the same strategy as for algorithm 3 in the matrix-matrix product:\n",
"\n",
"- Each process will update a subset of consecutive rows of the distance table $C$ at each iteration $k$.\n"
"- Each process will update a subset of consecutive rows of the distance table $C$ at each iteration $k$."
]
},
{
"attachments": {
"fig-asp-partition.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "9a9e8c44",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig-asp-partition.png\" align=\"left\" width=\"250\"/>\n",
"</div>"
]
},
{
@@ -336,7 +388,7 @@
"\n",
"`C[i,j] = min(C[i,j],C[i,k]+C[k,j])`\n",
"\n",
"If each process updates a block of rows of matrix $C$, which data we need for this operation?\n"
"If each process updates a block of rows of matrix $C$, which data do we need for this operation?\n"
]
},
{
@@ -423,6 +475,32 @@
"</div>"
]
},
{
"cell_type": "markdown",
"id": "2cf55de3",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> How much data is communicated in each iteration in this parallel algorithm?\n",
"</div>\n",
"\n",
" a) O(N²/P)\n",
" b) O(N)\n",
" c) O(NP)\n",
" d) O(P)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1bf4de56",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c or d\n",
"floyd_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "eba45ea4",
@@ -433,40 +511,68 @@
},
{
"cell_type": "markdown",
"id": "e96eda2d",
"id": "a15bc34e",
"metadata": {},
"source": [
"- Each process updates $N^2/P$ entries per iteration\n",
"- 1 process broadcasts a message of length $N$ to $P-1$ processes per iteration\n",
"- The send cost in this process is $O(N P)$ per iteration (if we use send/receive instead of broadcast)\n",
"- $P-1$ processes receive one message of length $N$ per iteration\n",
"- The receive cost is $O(N)$ per iteration at each process\n",
"- The send/computation ratio is $O(P^2/N)$\n",
"- The receive/computation ratio is $O(P/N)$\n",
"- The algorithm is potentially scalable if $P<<N$"
"**Computation cost:** Each process updates $N^2/P$ entries per iteration. "
]
},
{
"attachments": {
"g20431.png": {
"image/png": "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 truncated
"fig-asp-efficiency-comp.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "96b3a09f",
"id": "cc2668c8",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g20431.png\" align=\"left\" width=\"225\"/>\n",
" <img src=\"attachment:fig-asp-efficiency-comp.png\" align=\"left\" width=\"225\"/>\n",
" </div>"
]
},
{
"cell_type": "markdown",
"id": "d89d2b45",
"metadata": {},
"source": [
"**Communication cost:** \n",
"- One process broadcasts a message of length $N$ to $P-1$ processes per iteration. Thus, the **send cost** is $O(N P)$ per iteration (if we use send/receive instead of broadcast).\n",
"- $P-1$ processes receive one message of length $N$ per iteration. Hence, the **receive cost** is $O(N)$ per iteration at each process. "
]
},
{
"attachments": {
"fig-asp-efficiency-comm-2.png": {
"image/png": "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p08fpkyZwsUXX0y7djFzq1atqqqKp556ittuu42PPvoo3rDdwK+AG909bsdeSQwlUCIiIiKSVGZ2EFBI2K7XNdaYgw8+mKuuuooJEyaQm5ub1PjSUWVlJUuXLuXOO+9kw4a4OdJWoBi4zd3jduyV5lECJSIiIiJJYWbtgcuAW4CYjZo6derEZZddxqRJk+jcuXMyw8sI27dvZ/HixSxYsIAtW+LmSJ8DdwL3uHvcjr3SNEqgRERERKRFmVkW8F1CL6cjY43p0KEDl156KZMnT6Z79+5JjS8Tbd68meLiYu6//3527oybI60lNB5+wN33JC+61k0JlIiIiIi0CAvVHsYSvokfGGtMTk4OBQUFTJ06lV69Yi5KSR3Wr19PcXExDz/8MLt374437B1CP61H3L0qedG1TkqgRERERCThzOwcworTybE+z8rKYvTo0UyfPp3+/fsnNbbWaO3atSxYsIAlS5awd+/eeMPeBG5192VJDK3VUQIlIiIiIgljZqcRVjtGxhszYsQIbrrpJo499tikxdVWvPPOO9x1112UlJTUNWwFMMPd/5KksFoVJVAiIiIi0mxmdhxwE3BRvDFDhgxh+vTpDB06NHmBtVGrVq1izpw5vPDCC3UNexYocvdXkxRWq6AESkRERESazMz6E8qRTwCyYo0ZNGgQU6ZMIT8/P4mRCUBpaSmzZs3ijTfeiDfEgceAme7+bvIiy1xKoERERESk0cysL3AjcDkQs8PtgAEDuP766xkzZgyhnoSkgrvz5JNPMnfuXN5///14wyqBxcAt7r4uedFlHiVQIiIiItJgZnYIcD0wCegQa0yfPn2YMmUKF198Me3axcytJAWqqqp46qmnmDVrFh9//HG8YbuBXwE3unvcjr1tmRIoEREREamXmR0EFBK263WNNebggw/mqquuYsKECeTm5iY1Pmm4yspKli5dyp133smGDXFzpK1AMXCbu8ft2NsWKYESERERkbjMrD1wGXALELNRU6dOnbjsssuYNGkSnTt3TmZ40gzbt29n8eLFLFiwgC1b4uZInwN3Ave4e9yOvW2JEigREREROYCZZQHfJfRyOjLWmA4dOnDppZcyefJkunfvntT4JHE2b95McXEx999/Pzt3xs2R1hIaIj/g7nuSF136UQIlIiIiIvtYqPYwlvDN8sBYY3JycigoKGDq1Kn06hVzUUoy0Pr16ykuLuahhx6isrIy3rC3CeXqH/M2mkgogRIRERERAMzsHMKK08mxPs/KymL06NFMnz6d/v37JzU2SZ61a9eyYMEClixZwt69e+MNexO41d2XJTG0tKAESkRERKSNM7PTgFnAWfHGjBgxghtvvJHjjjsueYFJSr3zzjvcddddlJSULine truncated
}
},
"cell_type": "markdown",
"id": "e96eda2d",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig-asp-efficiency-comm-2.png\" align=\"left\" width=\"300\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "6993b9d0",
"metadata": {},
"source": [
"In summary, the send/computation ratio is $O(P^2/N)$ and the receive/computation ratio is $O(P/N)$. The algorithm is potentially scalable if $P<<N$."
]
},
{
"cell_type": "markdown",
"id": "494aa965",
"metadata": {},
"source": [
"## Parallel Implementation\n"
"## Parallel Implementation\n",
"\n",
"Now, we will explore the parallel implementation of Floyd's algorithm using MPIClusterManagers."
]
},
{
@@ -511,7 +617,7 @@
"source": [
"### Code\n",
"\n",
"We split the code in two functions. The first function is called on the main process (the process running this notebook). It splits the input matrix into blocks of rows. Then, we call `floyd_worker!` (see below) remotely on each worker using the corresponding block of rows.\n"
"We split the code into two functions. The first function is called on the main process (the process running this notebook). It splits the input matrix into blocks of rows. Then, we use a remotecall to compute Floyd's algorithm in each worker with its corresponding block of rows.\n"
]
},
{
@@ -539,7 +645,7 @@
"id": "9fc3be11",
"metadata": {},
"source": [
"The second function is the one run on the workers. Note that we considered MPI for communication in this case."
"The second function is the one that runs on the workers. Note that we use MPI for communication in this case."
]
},
{
@@ -557,6 +663,7 @@
" C_k = similar(Cw,n)\n",
" for k in 1:n\n",
" if k in rows_w\n",
" # Send row k to other workers if I have it\n",
" myk = (k-first(rows_w))+1\n",
" C_k .= view(Cw,myk,:)\n",
" for proc in 0:(nranks-1)\n",
@@ -566,6 +673,7 @@
" MPI.Send(C_k,comm;dest=proc,tag=0)\n",
" end\n",
" else\n",
" # Wait until row k is received\n",
" MPI.Recv!(C_k,comm,source=MPI.ANY_SOURCE,tag=0)\n",
" end\n",
" for j in 1:n\n",
@@ -578,6 +686,38 @@
"end"
]
},
{
"cell_type": "markdown",
"id": "bc81a83d",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which of the following statements is true?\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "4ec6718c",
"metadata": {},
"source": [
" a) The processes are synchronized in each iteration due to the blocking send and receive of row k.\n",
" b) Receiving processes may overwrite the data in row k, which can lead to incorrect behavior.\n",
" c) The sending process can only continue the computation after the data are received in every other process.\n",
" d) The receiving process does not know the source of the received data."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4f4a57de",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # replace x with a, b, c or d\n",
"floyd_impl_check(answer)"
]
},
{
"cell_type": "markdown",
"id": "c624722a",
@@ -634,9 +774,8 @@
"source": [
"### Is this implementation correct?\n",
"\n",
"- Point-to-point messages are *non-overtaking* (i.e. FIFO order) according to section 3.5 of the MPI standard 4.0\n",
"\n",
"- Unfortunately this is not enough in this case"
"Point-to-point messages are *non-overtaking* (i.e. FIFO order) between the specified sender and receiver according to section 3.5 of the MPI standard 4.0.\n",
"Unfortunately this is not enough in this case. The messages can still arrive in the wrong order if messages from different processes overtake each other."
]
},
{
@@ -667,7 +806,7 @@
"id": "df60e4e7",
"metadata": {},
"source": [
"However, FIFO ordering is not enough. In the next figure communication between process 1 and process 3 is particularly slow. Note that process 3 receives messages from process 1 after the messages received from 2 even though FIFO order is satisfied between any two processors."
"However, FIFO ordering is not enough. In the next figure, communication between process 1 and process 3 is particularly slow. Note that process 3 receives messages from process 1 after it receives the messages from 2 even though FIFO ordering is satisfied between any two processors."
]
},
{
@@ -692,10 +831,72 @@
"source": [
"### Possible solutions\n",
"\n",
"- Use synchronous send MPI_SSEND (less efficient). Note that the blocking send MPI_SEND used above does not guarantee that the message was received.\n",
"- Barrier at the end of each iteration over $k$ (simple solution, but synchronization overhead)\n",
"- Order incoming messages (buffering and extra user code needed)\n",
"- Use a specific rank id instead of `MPI.ANY_SOURCE` or use `MPI.Bcast!` (one needs to know which are the rows owned by the other ranks)"
"1. **Synchronous sends**: Use synchronous send MPI_SSEND. This is less efficient because we spend time waiting until each message is received. Note that the blocking send MPI_SEND used above does not guarantee that the message was received. \n",
"2. **MPI.Barrier**: Use a barrier at the end of each iteration over $k$. This is easy to implement, but we get a synchronization overhead.\n",
"3. **Order incoming messages**: The receiver orders the incoming messages, e.g. according to MPI.Status or the sender rank. This requires buffering and extra user code.\n",
"4. **MPI.Bcast!**: Communicate row k using `MPI.Bcast!`. One needs to know which are the rows owned by the other ranks."
]
},
{
"cell_type": "markdown",
"id": "de96ad1b",
"metadata": {},
"source": [
"## Exercise \n",
"Rewrite the worker code of the parallel ASP algorithm so it runs correctly. Use the `MPI.Bcast!` to solve the problem of overtaking messages. Note: Only use `MPI.Bcast!`, do not use other MPI directives in addition. You can test your function with the following code cell. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "31194529",
"metadata": {},
"outputs": [],
"source": [
"function floyd_par!(C,N)\n",
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
" nranks = MPI.Comm_size(comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" T = eltype(C)\n",
" if rank == 0\n",
" buffer_root = Vector{T}(undef,N*N)\n",
" buffer_root[:] = transpose(C)[:]\n",
" else\n",
" buffer_root = Vector{T}(undef,0)\n",
" end \n",
" Nw = div(N,nranks)\n",
" buffer = Vector{T}(undef,Nw*N)\n",
" MPI.Scatter!(buffer_root,buffer,comm;root=0)\n",
" Cw = Matrix{T}(undef,Nw,N)\n",
" transpose(Cw)[:] = buffer\n",
" MPI.Barrier(comm)\n",
" floyd_worker_bcast!(Cw,comm)\n",
" buffer[:] = transpose(Cw)[:]\n",
" MPI.Gather!(buffer,buffer_root,comm;root=0)\n",
" if rank == 0\n",
" transpose(C)[:] = buffer_root[:]\n",
" end\n",
" C\n",
"end\n",
"\n",
"@everywhere function floyd_worker_bcast!(Cw,comm)\n",
" # Your implementation here\n",
"end\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1b7eb4c2",
"metadata": {},
"outputs": [],
"source": [
"load = 10\n",
"n = nworkers()*load\n",
"C = rand_distance_table(n)\n",
"C_seq = floyd!(copy(C))\n",
"C_par = floyd_par!(copy(C),n)\n",
"@test C_seq == C_par"
]
},
{
@@ -713,7 +914,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.9.1",
"language": "julia",
"name": "julia-1.9"
},
@@ -721,7 +922,7 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.9.1"
}
},
"nbformat": 4,
+21847 -29021
View File
File diff suppressed because it is too large. Load diff

Before

Width:  |  Height:  |  Size: 6.2 MiB

After

Width:  |  Height:  |  Size: 6.5 MiB

+515 -3
View File
@@ -365,6 +365,84 @@
id="path8527-8"
inkscape:connector-curvature="0" />
</marker>
<marker
style="overflow:visible"
id="marker8529-3-3"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true"
inkscape:collect="always">
<path
transform="scale(-0.6)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
id="path8527-8-6"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker4031-1"
style="overflow:visible"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path4029-0"
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
style="overflow:visible"
id="marker4223-6"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true">
<path
transform="scale(-0.6)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
id="path4221-3"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
inkscape:stockid="Arrow2Mend"
orient="auto"
refY="0"
refX="0"
id="marker4031-5"
style="overflow:visible"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path4029-3"
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="scale(-0.6)" />
</marker>
<marker
style="overflow:visible"
id="marker4223-5"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Mend"
inkscape:isstock="true">
<path
transform="scale(-0.6)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#0000ff;fill-opacity:1;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
id="path4221-6"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
@@ -373,9 +451,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.70000001"
inkscape:cx="4005.3666"
inkscape:cy="58.38566"
inkscape:zoom="0.98994951"
inkscape:cx="6863.501"
inkscape:cy="332.85381"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
@@ -2678,5 +2756,439 @@
y="194.96161"
x="1153.2484">20</tspan></text>
</g>
<g
transform="translate(192.3794,-112.09032)"
id="g5148-2"
inkscape:export-filename="/home/francesc/Downloads/g5148.png"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1359.9626,79.585912 h 20.9409"
id="path978-3-6-3-0"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc"
id="path1168-6-1-6-6"
d="m 1314.5268,79.585912 h 20.9408"
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
transform="translate(1155.5468,183.31702)"
id="g1148-7-5-75-1">
<path
inkscape:connector-curvature="0"
id="path1063-5-5-3-5"
d="m 129.89807,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
id="path1065-3-4-5-5"
d="m 142.88845,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
id="path1067-56-7-62-4"
d="m 129.89807,-136.23112 v 39.999996 l 12.99038,7.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1069-2-6-9-7"
d="m 147.21857,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1071-91-5-1-6"
d="m 145.48652,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1073-2-6-2-5"
d="m 145.48652,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1075-7-9-7-6"
d="m 145.48652,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
transform="translate(1163.1327,183.31701)"
id="g1157-09-3-0-9">
<path
inkscape:connector-curvature="0"
id="path1086-3-7-93-3"
d="m 169.05642,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
id="path1088-6-4-6-7"
d="m 182.0468,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
id="path1090-0-5-0-4"
d="m 169.05642,-136.23112 v 39.999996 l 12.99038,7.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1092-6-2-6-5"
d="m 186.37692,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1094-2-5-2-2"
d="m 184.64487,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1096-6-4-6-5"
d="m 184.64487,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1098-1-7-1-4"
d="m 184.64487,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<text
y="15.986771"
x="1244.8425"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);stroke-width:1.87007797"
id="text1128-7-8-4-8-7"
xml:space="preserve"><tspan
style="stroke-width:1.87007797"
id="tspan78-79-4-7-4"
y="103.6842"
x="1289.8303">worker 1</tspan></text>
<text
y="15.986771"
x="1294.8483"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1184);stroke-width:1.87007797"
id="text1182-0-0-2-3"
xml:space="preserve"><tspan
style="stroke-width:1.87007797"
id="tspan83-2-7-0-0"
y="103.6842"
x="1339.8361">worker 2</tspan></text>
<g
id="g970-7-6-3-8"
transform="translate(1209.6376,183.31701)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path956-5-8-7-6"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 182.0468,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path958-92-8-5-8"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 v 39.999996 l 12.99038,7.5"
id="path960-2-4-9-8"
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 186.37692,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path962-8-3-2-4"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path964-9-1-2-3"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path966-7-4-8-1"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path968-3-9-9-4"
inkscape:connector-curvature="0" />
</g>
<text
xml:space="preserve"
id="text976-6-2-7-9"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1184);stroke-width:1.87007797"
x="1342.9568"
y="15.986771"><tspan
x="1387.9445"
y="103.6842"
id="tspan974-1-0-3-2"
style="stroke-width:1.87007797">worker 3</tspan></text>
<text
y="-54.098297"
x="1247.6248"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);fill:#0000ff;stroke-width:1.87007797"
id="text1128-7-8-7-3-7-0-06"
xml:space="preserve"><tspan
style="fill:#0000ff;stroke-width:1.87007797"
id="tspan78-79-8-2-1-3-8"
y="33.599152"
x="1292.6124">msg</tspan></text>
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path1386-9"
d="m 1304.0316,27.773394 c 16.0706,-14.103005 27.5564,-13.085868 41.886,-0.615601"
style="fill:none;stroke:#0000ff;stroke-width:0.76499999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker8529-3-3)" />
<text
y="-54.561871"
x="1290.4174"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);fill:#0000ff;stroke-width:1.87007797"
id="text1128-7-8-7-3-7-0-0-2"
xml:space="preserve"><tspan
style="fill:#0000ff;stroke-width:1.87007797"
id="tspan78-79-8-2-1-3-6-6"
y="33.135578"
x="1335.405">msg+=1</tspan></text>
<text
y="-53.871326"
x="1338.3951"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);fill:#0000ff;stroke-width:1.87007797"
id="text1128-7-8-7-3-7-0-0-3-6"
xml:space="preserve"><tspan
style="fill:#0000ff;stroke-width:1.87007797"
id="tspan78-79-8-2-1-3-6-2-4"
y="33.826126"
x="1383.3828">msg+=1</tspan></text>
<path
style="fill:none;stroke:#0000ff;stroke-width:0.76499999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4031-1)"
d="m 1354.3024,27.773394 c 16.0706,-14.103005 27.5564,-13.085868 41.886,-0.615601"
id="path4027-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4219-5"
d="m 1402.8962,28.340358 c -14.7223,-30.9560949 -88.632,-34.6967981 -104.63,-1.371553"
style="fill:none;stroke:#0000ff;stroke-width:0.76499999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4223-6)" />
</g>
<g
id="g2038"
inkscape:export-xdpi="200"
inkscape:export-ydpi="200">
<path
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1861.8989,152.34405 h 20.9409"
id="path978-3-6-3-1"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc"
id="path1168-6-1-6-2"
d="m 1816.4631,152.34405 h 20.9408"
style="fill:none;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
transform="translate(1657.4831,256.07516)"
id="g1148-7-5-75-7">
<path
inkscape:connector-curvature="0"
id="path1063-5-5-3-0"
d="m 129.89807,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
id="path1065-3-4-5-9"
d="m 142.88845,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
id="path1067-56-7-62-3"
d="m 129.89807,-136.23112 v 39.999996 l 12.99038,7.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1069-2-6-9-6"
d="m 147.21857,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1071-91-5-1-0"
d="m 145.48652,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1073-2-6-2-6"
d="m 145.48652,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1075-7-9-7-2"
d="m 145.48652,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
transform="translate(1665.069,256.07515)"
id="g1157-09-3-0-6">
<path
inkscape:connector-curvature="0"
id="path1086-3-7-93-1"
d="m 169.05642,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
id="path1088-6-4-6-8"
d="m 182.0468,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
id="path1090-0-5-0-7"
d="m 169.05642,-136.23112 v 39.999996 l 12.99038,7.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1092-6-2-6-9"
d="m 186.37692,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1094-2-5-2-20"
d="m 184.64487,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1096-6-4-6-2"
d="m 184.64487,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1098-1-7-1-3"
d="m 184.64487,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<text
y="88.744911"
x="1746.7788"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);stroke-width:1.87007797"
id="text1128-7-8-4-8-75"
xml:space="preserve"><tspan
style="stroke-width:1.87007797"
id="tspan78-79-4-7-9"
y="176.44234"
x="1791.7666">rank 0<tspan
id="tspan76-2-3-9-2"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack;stroke-width:1.87007797" /></tspan></text>
<text
y="88.744911"
x="1796.7845"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1184);stroke-width:1.87007797"
id="text1182-0-0-2-2"
xml:space="preserve"><tspan
style="stroke-width:1.87007797"
id="tspan83-2-7-0-8"
y="176.44234"
x="1841.7723">rank 1<tspan
id="tspan81-3-8-2-9"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Hack;-inkscape-font-specification:Hack;stroke-width:1.87007797" /></tspan></text>
<g
id="g970-7-6-3-7"
transform="translate(1711.5739,256.07515)">
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 12.99038,7.5 17.32051,-10 -12.99038,-7.5 z"
id="path956-5-8-7-3"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 182.0468,-128.73112 v 39.999996 l 17.32051,-10 v -39.999996"
id="path958-92-8-5-6"
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 169.05642,-136.23112 v 39.999996 l 12.99038,7.5"
id="path960-2-4-9-1"
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 186.37692,-126.23112 v 15 l 4.33013,-2.5 v -15 l -4.33013,2.5"
id="path962-8-3-2-2"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-96.231123 v 1.999999 l 12.99038,-7.499996 v -2 z"
id="path964-9-1-2-9"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-100.23111 v 2.000003 l 12.99038,-7.500013 v -2 z"
id="path966-7-4-8-3"
inkscape:connector-curvature="0" />
<path
style="fill:#e6e6e6;stroke:#000000;stroke-width:0.529167;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 184.64487,-104.23111 v 2 l 12.99038,-7.50001 v -2 z"
id="path968-3-9-9-1"
inkscape:connector-curvature="0" />
</g>
<text
xml:space="preserve"
id="text976-6-2-7-94"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1184);stroke-width:1.87007797"
x="1844.8931"
y="88.744911"><tspan
x="1889.8807"
y="176.44234"
id="tspan974-1-0-3-7"
style="stroke-width:1.87007797">rank 2</tspan></text>
<text
y="-2.3611109"
x="1822.4244"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);fill:#0000ff;stroke-width:1.87007797"
id="text1128-7-8-7-3-7-0-0-3-61"
xml:space="preserve"><tspan
style="fill:#0000ff;stroke-width:1.87007797"
id="tspan78-79-8-2-1-3-6-2-0"
y="85.336334"
x="1867.4121">msg</tspan></text>
<path
style="fill:none;stroke:#0000ff;stroke-width:0.76499999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4031-5)"
d="m 1854.3678,99.061558 c 16.0706,-14.103008 27.5564,-13.085871 41.886,-0.615604"
id="path4027-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
y="18.408323"
x="1793.9163"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);fill:#0000ff;stroke-width:1.87007797"
id="text1128-7-8-7-3-7-0-0-3-61-2"
xml:space="preserve"><tspan
style="fill:#0000ff;stroke-width:1.87007797"
id="tspan78-79-8-2-1-3-6-2-0-0"
y="106.10577"
x="1838.9039">MPI_Send</tspan></text>
<text
xml:space="preserve"
id="text1992"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.93749809px;line-height:1.25;font-family:Hack;-inkscape-font-specification:Hack;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect1130-2);fill:#0000ff;stroke-width:1.87007797"
x="1841.223"
y="18.408323"><tspan
x="1886.2107"
y="106.10577"
id="tspan1990"
style="fill:#0000ff;stroke-width:1.87007797">MPI_Recv</tspan><tspan
id="tspan1994"
x="1886.2107"
y="106.10577"
style="fill:#0000ff;stroke-width:1.87007797" /></text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

+14 -14
View File
@@ -39,7 +39,7 @@
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to run the next cell before starting studying this notebook. \n",
"<b>Note:</b> Do not forget to run the next cell before you start studying this notebook. \n",
"</div>"
]
},
@@ -614,10 +614,10 @@
"<b>Question:</b> At the end of function jacobi_mpi ...\n",
"</div>\n",
"\n",
" a) each rank holds the complete solution.\n",
" b) only the root process holds the solution. \n",
" c) the values of the ghost cells of u are not consistent with the neighbors\n",
" d) the ghost cells of u contain the initial values -1 and 1 in all ranks"
" a) each process holds the complete solution.\n",
" b) the complete solution is gathered in the root process. \n",
" c) each process contains the solution for the local partition. \n",
" d) the ghost cells of u contain the initial values -1 and 1 in all processes."
]
},
{
@@ -772,7 +772,7 @@
},
{
"cell_type": "markdown",
"id": "267ecd2a",
"id": "f93e2024",
"metadata": {},
"source": [
"### Parallelization strategies\n",
@@ -783,21 +783,21 @@
"- 2D block partition (each worker handles a subset of consecutive rows and columns)\n",
"- 2D cyclic partition (each workers handles a subset of alternating rows ans columns)\n",
"\n",
"The three partition types are depicted in the following figure for 4 processes.\n"
"The three partition types are depicted in the following figure for 4 processes."
]
},
{
"attachments": {
"fig18.png": {
"image/png": "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 truncated
"fig-jacobi-partitions.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "e52959a5",
"id": "267ecd2a",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig18.png\" align=\"left\" width=\"450\"/>\n",
"<img src=\"attachment:fig-jacobi-partitions.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
@@ -937,7 +937,7 @@
"\n",
"\n",
"- Both 1d and 2d block partitions are potentially scalable if $P<<N$\n",
"- The 2d block partition is with the lowest communication complexity\n",
"- The 2d block partition has the lowest communication complexity\n",
"- The 1d block partition requires to send less messages (It can be useful if the fixed cost of sending a message is high)\n",
"- The best strategy for a given problem size will thus depend on the machine, but the 2d block partition is the one used in practice since it has the lowest communication complexity.\n",
"- Cyclic partitions are impractical for this application (but they are useful in others) \n",
@@ -977,7 +977,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.9.1",
"language": "julia",
"name": "julia-1.9"
},
@@ -985,7 +985,7 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.9.1"
}
},
"nbformat": 4,
+114 -4
View File
@@ -28,6 +28,56 @@
"Understanding these concepts is important to learn distributed computing later."
]
},
{
"cell_type": "markdown",
"id": "cde5ee75",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to execute the next cell before starting this notebook! \n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0b0496c7",
"metadata": {},
"outputs": [],
"source": [
"function why_q1()\n",
" msg = \"\"\"\n",
" Evaluating compute_π(100_000_000) takes about 0.25 seconds on the teacher's laptop. Thus, the loop would take about 2.5 seconds since we are calling the function 10 times.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function why_q2()\n",
" msg = \"\"\"\n",
" The time in doing the loop will be almost zero since the loop just schedules 10 tasks, which should be very fast.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function why_q3()\n",
" msg = \"\"\"\n",
" It will take 2.5 seconds, like in question 1. The @sync macro forces to wait for all tasks we have generated with the @async macro. Since we have created 10 tasks and each of them takes about 0.25 seconds, the total time will be about 2.5 seconds.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function why_q4()\n",
" msg = \"\"\"\n",
" It will take about 3 seconds. The channel has buffer size 4, thus the call to put!will not block. The call to take! will not block neither since there is a value stored in the channel. The taken value is 3 and therefore we will wait for 3 seconds.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function why_q5()\n",
" msg = \"\"\"\n",
" 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.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"println(\"🥳 Well done! \")"
]
},
{
"cell_type": "markdown",
"id": "caf64254",
@@ -37,7 +87,7 @@
"\n",
"### Creating a task\n",
"\n",
"Technically, a task in Julia is a *symmetric co-routine*. More informally, a task is a piece of computation work that can be started (scheduled) at some point in the future, and that can be interrupted and resumed. To create a task, we first need to create a function that represents the work to be done in the task. In next cell, we generate a task that generates and sums two matrices."
"Technically, a task in Julia is a *symmetric* [*co-routine*](https://en.wikipedia.org/wiki/Coroutine). More informally, a task is a piece of computational work that can be started (scheduled) at some point in the future, and that can be interrupted and resumed. To create a task, we first need to create a function that represents the work to be done in the task. In next cell, we generate a task that generates and sums two matrices."
]
},
{
@@ -726,6 +776,16 @@
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d6b8382e",
"metadata": {},
"outputs": [],
"source": [
"why_q1()"
]
},
{
"cell_type": "markdown",
"id": "5f19d38c",
@@ -754,6 +814,16 @@
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "edff9747",
"metadata": {},
"outputs": [],
"source": [
"why_q2()"
]
},
{
"cell_type": "markdown",
"id": "5041c355",
@@ -781,6 +851,16 @@
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "87bc7c5c",
"metadata": {},
"outputs": [],
"source": [
"why_q3()"
]
},
{
"cell_type": "markdown",
"id": "841b690e",
@@ -821,6 +901,16 @@
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a18a0a7d",
"metadata": {},
"outputs": [],
"source": [
"why_q4()"
]
},
{
"cell_type": "markdown",
"id": "df663f11",
@@ -860,6 +950,26 @@
"end"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d8923fae",
"metadata": {},
"outputs": [],
"source": [
"why_q5()"
]
},
{
"cell_type": "markdown",
"id": "0ee77abe",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> If for some reason a cell keeps running forever, we can stop it with Kernel > Interrupt or Kernel > Restart (see tabs above).\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "a5d3730b",
@@ -873,15 +983,15 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.10.0",
"language": "julia",
"name": "julia-1.9"
"name": "julia-1.10"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.10.0"
}
},
"nbformat": 4,
+95 -3
View File
@@ -147,6 +147,44 @@
"foo()"
]
},
{
"cell_type": "markdown",
"id": "d18e679d",
"metadata": {},
"source": [
"### A very easy first exercise\n",
"\n",
"Run the following cell. It contains definitions used later in the notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "81678b3d",
"metadata": {},
"outputs": [],
"source": [
"function why_q1()\n",
" msg = \"\"\"\n",
" In the first line, we assign a variable to a value. In the second line, we assign another variable to the same value. Thus, we have 2 variables associated with the same value. In line 3, we associate y to a new value (re-assignment). Thus, we have 2 variables associated with 2 different values. Variable x is still associated with its original value. Thus, the value at the final line is x=1.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function why_q2()\n",
" msg = \"\"\"\n",
" It will be 1 for very similar reasons as in the previous questions: we are reassigning a local variable, not the global variable defined outside the function.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"function why_q3()\n",
" msg = \"\"\"\n",
" It will be 6. In the returned function f2, x is equal to 2. Thus, when calling f2(3) we compute 2*3.\n",
" \"\"\"\n",
" println(msg)\n",
"end\n",
"println(\"🥳 Well done! \")"
]
},
{
"cell_type": "markdown",
"id": "92112bd1",
@@ -467,6 +505,24 @@
"x"
]
},
{
"cell_type": "markdown",
"id": "a2f94960",
"metadata": {},
"source": [
"Run next cell to get an explanation of this question."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fc562337",
"metadata": {},
"outputs": [],
"source": [
"why_q1()"
]
},
{
"cell_type": "markdown",
"id": "4d2cb752",
@@ -586,6 +642,24 @@
"x"
]
},
{
"cell_type": "markdown",
"id": "f69108c2",
"metadata": {},
"source": [
"Run next cell to get an explanation of this question."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "05c62aa3",
"metadata": {},
"outputs": [],
"source": [
"why_q2()"
]
},
{
"cell_type": "markdown",
"id": "4fc5eb9b",
@@ -1068,6 +1142,24 @@
"x"
]
},
{
"cell_type": "markdown",
"id": "062ff145",
"metadata": {},
"source": [
"Run next cell to get an explanation of this question."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6bf7818e",
"metadata": {},
"outputs": [],
"source": [
"why_q3()"
]
},
{
"cell_type": "markdown",
"id": "bc8e9bcf",
@@ -1649,15 +1741,15 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.10.0",
"language": "julia",
"name": "julia-1.9"
"name": "julia-1.10"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.10.0"
}
},
"nbformat": 4,
+109 -8
View File
@@ -25,7 +25,7 @@
"source": [
"## Contents\n",
"\n",
"In this notebook, we will learn the basics of distributed computing in Julia. In particular, we will focus on the Distributed module available in the Julia standard library. The main topics we are going to cover are:\n",
"In this notebook, we will learn the basics of distributed computing in Julia. In particular, we will focus on the [Distributed](https://docs.julialang.org/en/v1/manual/distributed-computing/) module available in the Julia standard library. The main topics we are going to cover are:\n",
"\n",
"- How to create Julia processes\n",
"- How to execute code remotely\n",
@@ -60,7 +60,32 @@
" end |> println\n",
"end\n",
"q_1_check(answer) = answer_checker(answer,\"a\")\n",
"q_2_check(answer) = answer_checker(answer,\"b\")"
"q_2_check(answer) = answer_checker(answer,\"b\")\n",
"function why_q1()\n",
" msg = \"\"\"\n",
" 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.\n",
" \"\"\"\n",
" display(msg)\n",
"end\n",
"function why_q2()\n",
" msg = \"\"\"\n",
" 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.\n",
" \"\"\"\n",
" display(msg)\n",
"end\n",
"function why_q3()\n",
" msg = \"\"\"\n",
" 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.\n",
" \"\"\"\n",
" display(msg)\n",
"end\n",
"function why_q4()\n",
" msg = \"\"\"\n",
" 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.\n",
" \"\"\"\n",
" display(msg)\n",
"end\n",
"println(\"🥳 Well done! \")"
]
},
{
@@ -621,8 +646,6 @@
"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",
@@ -632,7 +655,10 @@
" close(chnl)\n",
"end\n",
"take!(chnl)\n",
"```"
"```\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"
]
},
{
@@ -818,6 +844,16 @@
"q_1_check(answer)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c4d4900",
"metadata": {},
"outputs": [],
"source": [
"why_q1()"
]
},
{
"cell_type": "markdown",
"id": "dbe373d1",
@@ -852,6 +888,16 @@
"q_2_check(answer)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e7c25fc4",
"metadata": {},
"outputs": [],
"source": [
"why_q2()"
]
},
{
"cell_type": "markdown",
"id": "c561a73d",
@@ -877,6 +923,16 @@
"x"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7b25a83f",
"metadata": {},
"outputs": [],
"source": [
"why_q3()"
]
},
{
"cell_type": "markdown",
"id": "835080aa",
@@ -903,6 +959,16 @@
"x"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "96b84cb5",
"metadata": {},
"outputs": [],
"source": [
"why_q4()"
]
},
{
"cell_type": "markdown",
"id": "9e985c61",
@@ -1317,6 +1383,41 @@
"We have seen the basics of distributed computing in Julia. The programming model is essentially an extension of tasks and channels to parallel computations on multiple machines. The low-level functions are `remotecall` and `RemoteChannel`, but there are other functions and macros like `pmap` and `@distributed` that simplify the implementation of parallel algorithms."
]
},
{
"cell_type": "markdown",
"id": "a75aa3bb",
"metadata": {},
"source": [
"## Exercises"
]
},
{
"cell_type": "markdown",
"id": "3153bd90",
"metadata": {},
"source": [
"### Exercise 1\n",
"\n",
"Implement this \"simple\" algorithm (the telephone game):\n",
"\n",
"Worker 1 generates a message (an integer). Worker 1 sends the message to worker 2. Worker 2 receives the message, increments the message by 1, and sends the result to worker 3. Worker 3 receives the message, increments the message by 1, and sends the result to worker 4. Etc. The last worker sends back the message to worker 1 closing the ring. See the next figure."
]
},
{
"attachments": {
"g5148-2.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "6a485db2",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g5148-2.png\" align=\"left\" width=\"320\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "9a49ad48",
@@ -1330,15 +1431,15 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.10.0",
"language": "julia",
"name": "julia-1.9"
"name": "julia-1.10"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.10.0"
}
},
"nbformat": 4,
File diff suppressed because it is too large. Load diff
+5 -106
View File
@@ -219,10 +219,10 @@
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> The matrix-matrix multiplication naively implemented with 3 nested loops as above is known to be very inefficient (memory bound). Libraries such as BLAS provide much more efficient implementations, which are the ones used in practice (e.g., by the `*` operator in Julia). We consider, our hand-written implementation as a simple way of expressing the algorithm we are interested in.\n",
"<b>Note:</b> The matrix-matrix multiplication naively implemented with 3 nested loops as above is known to be very inefficient (memory bound). Libraries such as BLAS provide much more efficient implementations, which are the ones used in practice (e.g., by the `*` operator in Julia). We consider our hand-written implementation as a simple way of expressing the algorithm we are interested in.\n",
"</div>\n",
"\n",
"Run the following cell to compare the performance of our hand-written function with respect to the built in function `mul!`\n"
"Run the following cell to compare the performance of our hand-written function with respect to the built in function `mul!`.\n"
]
},
{
@@ -1060,107 +1060,6 @@
"println(\"Efficiency = \", 100*(T1/TP)/P, \"%\")"
]
},
{
"cell_type": "markdown",
"id": "fa8d7f40",
"metadata": {},
"source": [
"### Exercise 2"
]
},
{
"cell_type": "markdown",
"id": "0e7c607e",
"metadata": {},
"source": [
"The implementation of algorithm 1 is very impractical. One needs as many processors as entries in the result matrix C. For 1000 times 1000 matrix one would need a supercomputer with one million processes! We can easily fix this problem by using less processors and spawning the computation of an entry in any of the available processes.\n",
"See the following code:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "023b20d1",
"metadata": {},
"outputs": [],
"source": [
"function matmul_dist_1_v2!(C, A, B)\n",
" m = size(C,1)\n",
" n = size(C,2)\n",
" l = size(A,2)\n",
" @assert size(A,1) == m\n",
" @assert size(B,2) == n\n",
" @assert size(B,1) == l\n",
" z = zero(eltype(C))\n",
" @sync for j in 1:n\n",
" for i in 1:m\n",
" Ai = A[i,:]\n",
" Bj = B[:,j]\n",
" ftr = @spawnat :any begin\n",
" Cij = z\n",
" for k in 1:l\n",
" @inbounds Cij += Ai[k]*Bj[k]\n",
" end\n",
" Cij\n",
" end\n",
" @async C[i,j] = fetch(ftr)\n",
" end\n",
" end\n",
" C\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "52005ca1",
"metadata": {},
"source": [
"With this new implementation, we can multiply matrices of arbitrary size with a fixed number of workers. Test it:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c1d3595b",
"metadata": {},
"outputs": [],
"source": [
"using Test\n",
"N = 50\n",
"A = rand(N,N)\n",
"B = rand(N,N)\n",
"C = similar(A)\n",
"@test matmul_dist_1_v2!(C,A,B) ≈ A*B"
]
},
{
"cell_type": "markdown",
"id": "ab609c18",
"metadata": {},
"source": [
"Run the next cell to check the performance of this implementation. Note that we are far away from the optimal speed up. Why? To answer this question compute the theoretical communication over computation ratio for this implementation and reason about the obtained result. Hint: the number of times a worker is spawned in this implementation is N^2/P on average."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d7d31710",
"metadata": {},
"outputs": [],
"source": [
"N = 100\n",
"A = rand(N,N)\n",
"B = rand(N,N)\n",
"C = similar(A)\n",
"P = nworkers()\n",
"T1 = @belapsed matmul_seq!(C,A,B)\n",
"C = similar(A)\n",
"TP = @belapsed matmul_dist_1_v2!(C,A,B)\n",
"println(\"Speedup = \", T1/TP)\n",
"println(\"Optimal speedup = \", P)\n",
"println(\"Efficiency = \", 100*(T1/TP)/P, \"%\")"
]
},
{
"cell_type": "markdown",
"id": "8e171362",
@@ -1175,15 +1074,15 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.10.0",
"language": "julia",
"name": "julia-1.9"
"name": "julia-1.10"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.10.0"
}
},
"nbformat": 4,
+379 -167
View File
@@ -28,6 +28,38 @@
"- Distributed sparse matrix-vector product"
]
},
{
"cell_type": "markdown",
"id": "a343cca6",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to execute the cell below before starting this notebook! \n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "821ac5e2",
"metadata": {},
"outputs": [],
"source": [
"using Printf\n",
"function answer_checker(answer,solution)\n",
" if answer == solution\n",
" \"🥳 Well done! \"\n",
" else\n",
" \"It's not correct. Keep trying! 💪\"\n",
" end |> println\n",
"end\n",
"pdes_check_0(answer)=answer_checker(answer,\"f\")\n",
"pdes_check_1(answer)=answer_checker(answer, \"b\")\n",
"pdes_check_2(answer)=answer_checker(answer, \"c\")\n",
"pdes_check_3(answer)=answer_checker(answer, \"d\")\n",
"pdes_check_4(answer)=answer_checker(answer, \"a\")"
]
},
{
"cell_type": "markdown",
"id": "da4d45cd",
@@ -35,7 +67,7 @@
"source": [
"## Mini project\n",
"\n",
"- Simulating the temperature distribution in a closed room"
"For the demonstration of different numberical methods we will use the example project of simulating the temperature distribution in a closed room. "
]
},
{
@@ -45,9 +77,9 @@
"source": [
"### Problem statement\n",
"\n",
"- Given the temperature at the boundary of a room (walls, window, heater)\n",
"- Predict the temperature at any point of the room\n",
"- Compute it in parallel"
"Given the temperature at the boundary of a room, predict the temperature at any point in the room. The illustration below shows the temperature at different intervals of the room boundary (including a window and a heater). \n",
"\n",
"We will discuss the serial implementation first and learn how to compute it in parallel afterwards."
]
},
{
@@ -72,7 +104,10 @@
"source": [
"### Laplace equation\n",
"\n",
"$\\dfrac{\\partial^2 u(x,y)}{\\partial x^2} + \\dfrac{\\partial^2 u(x,y)}{\\partial y^2} = 0$\n"
"Assuming that the room is isolated, it can be shown that the temperature in the room can be described using the [Laplace equation](https://en.wikipedia.org/wiki/Laplace%27s_equation)\n",
"\n",
"\n",
"$$\\dfrac{\\partial^2 u(x,y)}{\\partial x^2} + \\dfrac{\\partial^2 u(x,y)}{\\partial y^2} = 0.$$\n"
]
},
{
@@ -132,13 +167,15 @@
"source": [
"### Numerical methods for PDEs\n",
"\n",
"There are several methods for solving PDEs: \n",
"\n",
"- Finite difference method (FDM)\n",
"- Finite element method (FEM)\n",
"- Finite volume method (FVM)\n",
"- Boundary element method (BEM)\n",
"- Meshfree methods\n",
"\n",
"Main idea: Transform a PDE into a system of algebraic equations.\n"
"All of them follow the same main idea: to transform a PDE into a system of linear equations. The problem is first discretized into a computational mesh. The solution to the PDE at any point of the mesh is then given by the solution for vector x. \n"
]
},
{
@@ -164,8 +201,7 @@
"source": [
"### Finite Difference method\n",
"\n",
" - Pro: Easy to implement and computationally efficient\n",
" - Con: Difficult to handle complex geometries\n"
"To solve the temperature distribution in the room, we choose the Finite Difference method. The advantage of this method is that it is easy to implement and computationally efficient. On the other hand, it is not suitable for more complex geometries. "
]
},
{
@@ -188,9 +224,9 @@
"id": "54a8f290",
"metadata": {},
"source": [
"- Goal: Compute the temperature at each grid point\n",
"- The (unknown) values can be stored in a computer using an array\n",
"- `u[i,j]` is the temperature at point $(i,j)$"
"With the finite difference method, we first model the room as a grid, which can be stored using an array. Each entry of the matrix `u[i,j]` represents the temperature in the room at point $(i,j)$. The goal is now to compute the temperature at each grid point. \n",
"\n",
"Let's set up the grid matrix for our problem."
]
},
{
@@ -261,7 +297,9 @@
"id": "53231e30",
"metadata": {},
"source": [
"### Data Visualization"
"### Data Visualization\n",
"\n",
"To illustrate the solution, we also write a visualization function that plots the temperature of the room as a heatmap. "
]
},
{
@@ -307,31 +345,20 @@
},
{
"cell_type": "markdown",
"id": "8e683fe1",
"id": "7f7a0f7f",
"metadata": {},
"source": [
"### How to find the temperature at the interior points?\n",
"\n",
"- We have an unknown for each interior point\n",
"- We need an equation for each unknown\n",
"- How to define these equations?\n"
]
},
{
"cell_type": "markdown",
"id": "7f7a0f7f",
"metadata": {},
"source": [
"### Finite Difference stencil\n",
"To set up a system of linear equations, we have to find one equation for each unknown value in the grid. The Laplace equation can be approximated by the following linear equation:\n",
"\n",
"$$\\dfrac{\\partial^2 u}{\\partial x^2} + \\dfrac{\\partial^2 u}{\\partial y^2} = 0 $$\n",
"\n",
"$$\\downarrow$$\n",
"\n",
"$\\dfrac{\\partial^2 u}{\\partial x^2} + \\dfrac{\\partial^2 u}{\\partial y^2} = 0 $\n",
"$$u_{i-1,j} + u_{i+1,j} + u_{i,j-1} + u_{i,j+1} - 4u_{i,j} = 0.$$\n",
"\n",
"$\\downarrow$\n",
"\n",
"$u_{i-1,j} + u_{i+1,j} + u_{i,j-1} + u_{i,j+1} - 4u_{i,j} = 0$\n",
"\n"
"This approximation computes the value at point $(i,j)$ by combining the values of its neighbors. \n"
]
},
{
@@ -352,15 +379,44 @@
},
{
"cell_type": "markdown",
"id": "2a380c04",
"id": "406f9436",
"metadata": {},
"source": [
"### System of linear equations\n",
" \n",
" - At each interior point we have an equation\n",
" - All these equations can be arranged in array form\n",
"We can now obtain this kind of equation for every unknown point in the grid (= all the interior points). All these equations can be arranged in array form\n",
" \n",
"$Ax=b$"
"$$Ax=b.$$\n",
"\n",
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> For a grid of size NxN, how many rows does matrix A have? \n",
"</div>\n",
"\n",
" a) N\n",
" b) N²\n",
" c) N-1\n",
" d) (N-1)x(N-1)\n",
" e) N-2\n",
" f) (N-2)x(N-2)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b52c8b2f",
"metadata": {},
"outputs": [],
"source": [
"answer=\"x\" # Replace x with a,b,c,d,e, or f\n",
"pdes_check_0(answer)"
]
},
{
"cell_type": "markdown",
"id": "2a380c04",
"metadata": {},
"source": [
"Next we create the matrix $A$: "
]
},
{
@@ -421,6 +477,16 @@
"A"
]
},
{
"cell_type": "markdown",
"id": "1f4c98fd",
"metadata": {},
"source": [
"We created the matrix $A$ of the system of linear equations $Ax=b$ for a grid size $N=5$. For a grid of this size, we need 9 linear equations since there are 9 interior points. Note that we are using two types of numeration: one that defines the coordinates in the grid, e.g. $(2,3)$. The other numeration simply enumerates the interior values row-wise (1,2,...,9). The latter numeration is used to construct the matrix $A$. \n",
"\n",
"For any grid size, the equations matrix will only contain up to 5 nonzero values per row. Therefore, it is useful to store it as a sparse array which only stores the nonzero values under the hood. This is essential for the implementation because a lot of memory can be saved in this way. "
]
},
{
"cell_type": "markdown",
"id": "7e521df4",
@@ -453,8 +519,40 @@
"\n",
"Two possible solution methods have already been discussed in the course:\n",
"\n",
"- Jacobi\n",
"- Gaussian elimination"
"- Jacobi method\n",
"- Gaussian elimination\n",
"\n",
"To determine wether any of these methods are useful solvers for our problem, we analyze if they are _algorithmically scalable_. "
]
},
{
"cell_type": "markdown",
"id": "f29c756a",
"metadata": {},
"source": [
"### Algorithmically scalable solver\n",
"\n",
"A computation method is an _algorithmically scalable_ solver if the total cost scales at most linearly with respect to the total problem size.\n",
"\n",
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Let $R$ be our problem size, the number of rows in our matrix $A$. Because we have $N$ points in each dimension of the grid, $R=O(N^2)$. What is the complexity of the Jacobi method and Gaussian elimination with respect to the problem size $R$?\n",
"</div>\n",
"\n",
" a) Jacobi: O(N^2) = O(R) per iteration, GE: O(N^3) = O(R*sqrt(R))\n",
" b) Jacobi: O(N^2) = O(R) per iteration, GE: O(R^3)\n",
" c) Jacobi: O(R^2) per iteration, GE: O(R^3)\n",
" d) Jacobi: O(N^2) = O(R) per iteration, GE: O(R) "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0244f525",
"metadata": {},
"outputs": [],
"source": [
"answer=\"x\" # Replace x with a,b,c or d\n",
"pdes_check_1(answer)"
]
},
{
@@ -462,22 +560,7 @@
"id": "638b0ecc",
"metadata": {},
"source": [
"### Algorithmically scalable solver\n",
"\n",
"- If the total cost scales at most linearly with respect to the total problem size\n",
"\n",
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Are Gaussian elimination and Jacobi algorithmically scalable?\n",
"</div>\n",
"\n",
"- Answer: NO.\n",
"\n",
"- Problem size is R = O(N^2)\n",
"\n",
"- Gaussian Elimination: O(R^3) (more than linear)\n",
"\n",
"- Jacobi: O(N^2) = O(R) per iteration. Linear per iteration, but how many iterations?\n",
"\n"
"To conclude, we find that none of the two solvers are algorithmically scalable. The Jacobi method scales linearly with respect to the problem size per iteration. However, the number of iterations might increase with the problem size, as we will demonstrate in the next section."
]
},
{
@@ -485,7 +568,9 @@
"id": "4ca3d718",
"metadata": {},
"source": [
"### Complexity of Jacobi method\n"
"### Complexity of Jacobi method\n",
"\n",
"Next we implement the Jacobi method to solve the PDE. In addition to using a fixed maximum number of iterations, we introduce a relative tolerance threshold. The iterations stop when the relative error in an iteration subceeds this threshold."
]
},
{
@@ -518,6 +603,14 @@
"end"
]
},
{
"cell_type": "markdown",
"id": "a3b1b69d",
"metadata": {},
"source": [
"Run the following code cell several times with different values for $N$. For instance, $N=10$, $N=20$, $N=40$. Compare the number of iterations that are needed to converge for each problem size."
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -525,7 +618,7 @@
"metadata": {},
"outputs": [],
"source": [
"N = 40\n",
"N = 10\n",
"u = zeros(N,N)\n",
"fill_boundary!(u)\n",
"u, iter = jacobi!(u,reltol=1.0e-5,maxiters=1000000)\n",
@@ -538,7 +631,8 @@
"id": "791691b8",
"metadata": {},
"source": [
"### Convergence analysis"
"### Convergence analysis\n",
"We can observe that the number of iterations scales with the problem size. In the next step, we plot the number of iterations needed for convergence against the problem size. "
]
},
{
@@ -576,9 +670,7 @@
"id": "4886157c",
"metadata": {},
"source": [
"- The number of iterations to achieve a relative error of $10^{-s}$ increases as $O(s N^2)$\n",
"- Remember: The cost per iteration is $O(N^2)$\n",
"- Total cost is $O(N^4) = O((N^2)^2) $"
"It can be analytically proven that the number of iterations to achieve a relative error of $10^{-s}$ increases as $O(s N^2)$. Recall: The cost per iteration of the Jacobi method is $O(N^2) = O(R)$. Treating $s$ as a constant, the total cost of the Jacobi method will be $O((N^2)^2) = O(R^2) = O(N^4)$.\n"
]
},
{
@@ -588,7 +680,7 @@
"source": [
"### Complexity of some solvers\n",
"\n",
"Work to solve a Laplace equation on a regular mesh of $S$ points ($S=N^d$)"
"There exist several methods to solve a Laplace equation on a regular mesh of $S$ points ($S=N^d$). The following table compares the scalability of these solvers for different numbers of mesh dimensions."
]
},
{
@@ -608,25 +700,27 @@
"id": "d24408b4",
"metadata": {},
"source": [
"### Conjugate gradient method\n",
"## Conjugate gradient method\n",
"\n",
"- Idea: Transform the problem into an optimization problem\n",
"In this section, we will discuss the [Conjugate Gradient Method](https://en.wikipedia.org/wiki/Conjugate_gradient_method). Combined with the multi grid method, it achieves the best scalability for solving Laplace equations.\n",
"\n",
"$A x = b$\n",
"\n",
"equivalent to \n",
"The idea of the conjugate gradient method is to transform the problem into an optimization problem of the form\n",
"\n",
"$ x = \\text{arg }\\min_{y} f(y)$ with $ f(y)= \\frac{1}{2}( y^\\mathrm{T}Ay - y^\\mathrm{T} b )$\n",
"$$ x = \\text{arg }\\min_{y} f(y)$$ \n",
"\n",
"- We can use some sort of gradient descent to solve it\n",
"<p style=\"text-align:center\">with</p> \n",
"\n",
"$$ f(y)= \\frac{1}{2}( y^\\mathrm{T}Ay - y^\\mathrm{T} b ).$$\n",
"\n",
"Thus, the goal is to find vector $x$, the minimum of function $f(y)$. This vector is equivalent to the solution of the system of linear equations, $A x = b$. \n",
"\n",
"The conjugate gradient method is a gradient descent algorithm optimized for symmetic ($A^\\mathrm{T}=A$) positive-definite ($y^\\mathrm{T}Ay > 0$) matrices. The algorithm is applicable to our problem since the matrix $A$ is both symmetric and positive-definite.\n",
"\n",
"- The [Conjugate Gradient Method](https://en.wikipedia.org/wiki/Conjugate_gradient_method) is a gradient descent algorithm optimized for symmetic ($A^\\mathrm{T}=A$) positive-definite ($y^\\mathrm{T}Ay > 0$) matrices\n",
"- It is applicable to our problem\n",
"- It is a type of Krylov subspace method\n",
"\n",
"### Top 10 algorithms of the 20th century\n",
"\n",
"According to IEEE Computer Society\n",
"The conjugate gradient method is a type of Krylov subspace method, which is listed by the IEEE Computer Society as one of the top 10 algorithms of the past century:\n",
"\n",
"- Metropolis Algorithm for Monte Carlo\n",
"- Simplex Method for Linear Programming\n",
@@ -641,10 +735,20 @@
"\n"
]
},
{
"cell_type": "markdown",
"id": "a9f516e6",
"metadata": {},
"source": [
"### Convergence analysis\n",
"\n",
"For the following convergence analysis, we will use the implementation of the conjugate gradient method from the `IterativeSolvers` package."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb4068bb",
"id": "9f8dbf39",
"metadata": {},
"outputs": [],
"source": [
@@ -660,24 +764,6 @@
"visualize(u)"
]
},
{
"cell_type": "markdown",
"id": "a9f516e6",
"metadata": {},
"source": [
"### Convergence analysis"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "100f1b77",
"metadata": {},
"outputs": [],
"source": [
"#plt = plot(xlabel=\"N^2\",ylabel=\"Iterations\");"
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -700,6 +786,14 @@
"plt"
]
},
{
"cell_type": "markdown",
"id": "5396554c",
"metadata": {},
"source": [
"The number of iterations needed to converge is much lower with the conjugate gradient method than with the Jacobi method. However, the number of iterations still increases with the problem size, so there is still room for improvement. "
]
},
{
"cell_type": "markdown",
"id": "92bfd7d7",
@@ -707,11 +801,10 @@
"source": [
"### Number of iterations\n",
"\n",
"It can be shown that the number of iterations to achieve a relative error of $10^{-s}$ increases as $O(s \\sqrt{\\kappa(A)})$. As a reminder, the condition number of A $\\kappa(A)$ is ratio between the largest and smallest eigenvalues of A: \n",
"$$\\kappa(A)=\\dfrac{\\lambda_{max}(A)}{\\lambda_{min}(A)}$$\n",
"\n",
"- The number of iterations to achieve a relative error of $10^{-s}$ increases as $O(s \\sqrt{\\kappa(A)})$\n",
"- $\\kappa(A)=\\dfrac{\\lambda_{max}(A)}{\\lambda_{min}(A)}$ is the condition number of A (ratio between the largest and smallest eigenvalues)\n",
"- In our example, $\\kappa(A) = O(N^2)$\n",
"- Thus, the iterations number scales as $O(s N)$\n"
"It can also be shown that in our example $\\kappa(A) = O(N^2)$. Thus, the number of iterations scales as $O(s N)$ for the conjugate gradient method. Remember that the number of iterations scales as $O(sN^2)$ for the Jacobi method.\n"
]
},
{
@@ -721,7 +814,7 @@
"source": [
"### Goal\n",
"\n",
"- Find an iterative method whose number of iterations is independent of problem size"
"The conjugate gradient method provides some improvement to the Jacobi method, since the number of iterations increases more slowly with the problem size. However, the ultimate goal is to find an iterative method whose number of iterations is _independent_ of the problem size."
]
},
{
@@ -731,31 +824,25 @@
"source": [
"### Preconditioner\n",
"\n",
"A linear function $M$ such that\n",
"To achieve this goal, we will apply a [preconditioner](https://en.wikipedia.org/wiki/Preconditioner) to transform the original problem into a format that is easier to solve. \n",
"\n",
"$M(b) \\approx x$ with $Ax=b$ for any $b$\n",
"A preconditioner is simply a linear function $M$ such that \n",
"$$M(b) \\approx x, \\text{ with } Ax=b \\text{ for any } b.$$ \n",
"\n",
"$\\downarrow$\n",
"Once we have found such a function $M(b)$, we can solve the _preconditioned problem_ $(MA)x = Mb$, which is equivalent to $Ax=b$.\n",
"\n",
"$ M(b) \\approx A^{-1}b $\n",
"The way that preconditioning affects the number of iterations is that it reduces the condition number of $A$: \n",
"\n",
"$\\downarrow$\n",
"$$ \\begin{align}\n",
"&M(b) \\approx x, \\text{ with } Ax=b \\text{ for any } b \\\\\n",
"&\\rightarrow M(b) \\approx A^{-1}b \\\\\n",
"&\\rightarrow M \\approx A^{-1} \\\\\n",
"&\\rightarrow M A \\approx I \\text{ (Identity matrix)} \\\\\n",
"&\\rightarrow \\kappa (MA) \\approx 1 \\\\\n",
"\\end{align}$$\n",
"\n",
"$ M \\approx A^{-1}$\n",
"Recall that the number of iterations to achieve a relative error of $10^{-s}$ is $O(s\\sqrt{\\kappa (A)})$. With $\\kappa (MA) \\approx 1$, the number of iterations will scale as $O(s)$. Thus, the number of iterations will be independent of the problem size for the preconditioned problem. \n",
"\n",
"$\\downarrow$\n",
"\n",
"$ M A \\approx I$ (Identity matrix)\n",
"\n",
"$\\downarrow$\n",
"\n",
"$\\kappa (MA) \\approx 1$\n",
"\n",
"$\\downarrow$\n",
"\n",
"Conjugate gradients will be fast when solving\n",
"\n",
"$(MA)x = Mb \\Longleftrightarrow Ax=b$\n",
"\n"
]
},
@@ -766,9 +853,12 @@
"source": [
"### How to build a preconditioner ?\n",
"\n",
"- $M=A^{-1}$ (exact preconditioner, but as costly as solving the original problem)\n",
"- $M=I$ (no extra work, but slow convergence)\n",
"- We need a trade-off (maths + computer science problem)\n"
"Many ways of building a preconditioner can be found in the literature. The solutions range between two extremes: \n",
"\n",
"1. $M=A^{-1}$. This is the exact preconditioner. The CG method will converge in just one iteration. However, it is exactly as costly to compute the matrix $M$ as it is to find the solution to the original problem. \n",
"2. $M=I$. This is the other extreme where we do no extra work to find the matrix $M$. The preconditioned problem is identical to the original problem.\n",
"\n",
"The solution is to find a good trade-off such that we get a matrix $M$ that is accurate enough to approximate the original problem but also cheap enough to be computed quickly. "
]
},
{
@@ -776,7 +866,9 @@
"id": "4338ee30",
"metadata": {},
"source": [
"### Jacobi Preconditioner"
"### Jacobi Preconditioner\n",
"\n",
"Next we use the Jacobi method to construct a preconditioner for the CG method. The matrix $M$ is simply computed as the grid values after a certain number of iterations with the Jacobi method. In order for $M$ to be linear, we set a fixed maximum number of iterations in the `jacobi!` function and disable the relative error stopping criterion."
]
},
{
@@ -805,6 +897,14 @@
"end"
]
},
{
"cell_type": "markdown",
"id": "46b3883d",
"metadata": {},
"source": [
"Run the following cell for different values of `niters`. The larger the value of `niters`, the more matrix $M$ resembles the exact solution. The fewer iterations we use, the less accurate the approximation."
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -816,8 +916,10 @@
"u = zeros(N,N)\n",
"fill_boundary!(u)\n",
"A,b = generate_system_sparse(u)\n",
"M = jacobi_prec(N,niters=10)\n",
"# Generate preconditioner\n",
"M = jacobi_prec(N,niters=1000)\n",
"x = zeros(size(b))\n",
"# Compute solution as x=b/M\n",
"ldiv!(x,M,b)\n",
"u[2:end-1,2:end-1] = x\n",
"visualize(u)"
@@ -839,6 +941,7 @@
" A,b = generate_system_sparse(u)\n",
" M = jacobi_prec(N,niters=100)\n",
" x = zeros(length(b))\n",
" # Provide preconditioner to conjugate gradient method\n",
" _,ch = cg!(x, A, b, Pl=M, reltol=reltol,log=true)\n",
" iters[i] = ch.iters\n",
"end\n",
@@ -846,12 +949,22 @@
"plt"
]
},
{
"cell_type": "markdown",
"id": "26f7e342",
"metadata": {},
"source": [
"Observe that the Jacobi preconditioner achieves that the CG method needs fewer iterations. However, the number of iterations still increases with the problem size. "
]
},
{
"cell_type": "markdown",
"id": "43fb5082",
"metadata": {},
"source": [
"### How can we improve the Jacobi method?"
"### How can we improve the Jacobi method?\n",
"\n",
"We can optimize the Jacobi method to obtain a better preconditioner for the CG method. Run the following code cell again with a grid size of $N=10$ and $N=100$. "
]
},
{
@@ -861,7 +974,7 @@
"metadata": {},
"outputs": [],
"source": [
"N = 10\n",
"N = 100\n",
"u = zeros(N,N)\n",
"fill_boundary!(u)\n",
"A,b = generate_system_sparse(u)\n",
@@ -872,12 +985,24 @@
"visualize(u)"
]
},
{
"cell_type": "markdown",
"id": "bf76a64b",
"metadata": {},
"source": [
"The main reason that the preconditioner performs badly for larger problem sizes is that it takes more time to update the interior values of the grid. The larger the grid, the longer the Jacobi method needs to propagate the values from the outer boundary to the interior of the grid. "
]
},
{
"cell_type": "markdown",
"id": "c04df158",
"metadata": {},
"source": [
"### Multi-grid method\n"
"### Multi-grid method\n",
"\n",
"The [multi-grid method](https://en.wikipedia.org/wiki/Multigrid_method) is the second building block of the fast solver for our Laplace equation. \n",
"\n",
"The multi-grid method achieves a faster convergence of the Jacobi method by starting to solve the coarse problem first and then stepwise increasing the grid resolution. On each resolution level, a few steps of the Jacobi method are performed (only 2 steps per level in this example). Next, the resolution of the grid is increased and the Jacobi method is run again. This process is repeated until we reach the desired grid size. Since the Jacobi method converges after a few iterations on very small grids, the values are propagated to the center much more quickly than without using the multi-grid method."
]
},
{
@@ -933,7 +1058,9 @@
"id": "6122ac8b",
"metadata": {},
"source": [
"### Multi-grid preconditioner"
"### Multi-grid preconditioner\n",
"\n",
"Let's see what happens when we use the CG method in combination with a multi-grid preconditioner. In the following code cell, we use a multi-grid preconditioner from the package `Preconditioners`."
]
},
{
@@ -962,14 +1089,10 @@
},
{
"cell_type": "markdown",
"id": "ab13519f",
"id": "63c406e0",
"metadata": {},
"source": [
"### Number of iterations\n",
"\n",
"\n",
"- The number of iterations to achieve a relative error of $10^{-s}$ increases as $O(s)$\n",
"- The cost of each iteration is proportional to the number of grid points\n"
"The number of iterations is now constant for different problem sizes. Thus, we have finally achieved an algorithmically scalable solver by combining the conjugate gradient method and the multi-grid method!"
]
},
{
@@ -979,7 +1102,7 @@
"source": [
"### High-performance conjugate gradient (HPCG) benchmark\n",
"\n",
"- Alternative to HPL benchmark to rank the [top 500](https://www.top500.org/) computers\n"
"The HPCG benchmark is an alternative to the HPL benchmark to rank the [top 500](https://www.top500.org/) computers. It is based on the CG + multigrid method, whereas the HPL benchmark is a Gaussian elimination type of algorithm. The HPCG was introduced because the CG + multigrid method is more commonly run on supercomputers than Gaussian elimination. While HPL gives a good indication of the peak performance, the HPCG benchmark is orders of magnitude below the peak performance. \n"
]
},
{
@@ -1003,7 +1126,8 @@
"id": "b30f96ad",
"metadata": {},
"source": [
"## Parallel implementation"
"## Parallel implementation\n",
"In this section, we will discuss the parallel implementation of the CG method. "
]
},
{
@@ -1011,7 +1135,8 @@
"id": "b5eadafc",
"metadata": {},
"source": [
"### Conjugate gradient method"
"### Implementation of conjugate gradient method\n",
"First, let's analyze how to parallelize the individual parts of the serial implementation of the CG method."
]
},
{
@@ -1051,11 +1176,13 @@
"id": "e0bb3512",
"metadata": {},
"source": [
"The phases that are not trivially parallel are\n",
"The algorithm performs matrix multiplications and additions which are trivially parallelizable. The phases that are not trivially parallelizable are\n",
"\n",
"- Dot products\n",
"- Sparse matrix-vector products\n",
"- Preconditioners"
" - Dot products\n",
" - Sparse matrix-vector products\n",
" - Preconditioners\n",
" \n",
"If we find parallel implementations for these parts, we get a complete parallel implementation for the CG method. "
]
},
{
@@ -1065,8 +1192,10 @@
"source": [
"### Dot product\n",
"\n",
"The dot product is defined as \n",
"$$\\text{dot}(a,b)= \\sum_i a_i b_i$$. \n",
"\n",
"$\\text{dot}(a,b)= \\sum_i a_i b_i$\n"
"Imagine we have our data distributed on two CPUs as in the picture below. How can we implement the dot product computation in parallel? "
]
},
{
@@ -1080,31 +1209,58 @@
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:d1.png\" align=\"left\" width=\"350\"/>\n",
"<img src=\"attachment:d1.png\" align=\"left\" width=\"300\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "a8aa2ebd",
"id": "93ec2564",
"metadata": {},
"source": [
"### MPI implementation"
"### MPI implementation\n",
"For the parallel implementation, the processes can compute the dot product of their respective sub-vectors independently. But they have to send the result to the other processes so they can be combined for the final dot product. Each process needs the _global_ dot product, because further computations in the algorithm depend on it. For instance, the stopping criterion depends on the result of the global dot product, such that all processes stop at the same time. "
]
},
{
"attachments": {
"g2419.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA/EAAAF0CAYAAABrI7nXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N13nFTV/f/x19ld6SAIohSNXQF7V+z+bLGiosYSDboLakxiiiWVJF9rijEmCgsm9kYEe43YFRXsxK4oIqgUC1J35/z++Mw4d5adtntn7sze9/PxmAczO3fOfHZnuDOfUz4HRERWdQvgk5edI45FRERERESSaqIOQEREREREREQKoyReREREREREpEooiRcRERERERGpEkriRURERERERKqEkngRERERERGRKlEXdQASuZ7AXsAwoD/2nlgAvAc8BHwWWWRSafoDRwEbAc3AO8BdwKdRBiUiIiIiIhIHI4GHgeWktxJreWkGrgXWjihGiU7LLeZ+BCxj1ffIcuB3aFaPiIiIiIhISd3BqsnYx8BHwMoW970LDI4mTIlIMIm/KnD9G2yWxlIy3yNXRROmiIiIiIhIPNwBzAYuAHYCOgXuqwW2Ax4nnaQ9XO4AJVLBJN4DS4DTSL9PugBnkTmT47DyhykiIiIiIhIPu5KZuLemGzCLdJK2cYljksrRMon/QZbjfhI45tXyhCYiIiIiIiLZXEw6STs+4likfIJJ/FtkX/PeCZgXOHarskQnIiIiIhJTKkYl+bwfuK518fF0F5DIct8K4IHA7d1KH46IiIiISHxpiznpCRwEbAusk7zdNXD/gMD14M8lPl7Jc//rgetblDIQEREREZG4UxIfX52AXwM/w9a+F6Jz6cKRCja3iPv7ljIQEREREZG4UxIfTzXAJDKrib8NvAnMAb4K/Hxz4ODyhSYVaGkR93cvZSAiIiIiInGnJD6eTiKdwM8FTgSmZjm2HiXxcZdvBkaXwPUlpQxERERERCTuVNgunk5ucT1bAg+wZoljkcrXL8/9wSn0i0oZiIiIiIhI3CmJj6dhyX+/Af6b59htShyLVL5hee7fLHB9ZikDERERERGJOyXx8ZQqZFdL7vdAb6xyvcTbgTnuc8B+gdvTShyLiIiIiEisKYmPp4+T/3YBdsxx3MWoUJnATsCeWe47HNg4ef194LmyRCQiIiIiIhIjlwE+eXkd2LDF/d2BK5L3Lw8ce2EZY5Ro3UL6dffYrgXbtThmODA/cEx9OQMUERERERGJi4HA56STr2XAo8B1wL3YFnMeWAD8FiXxcRRM4h9O/tuMTZe/DXgBSASOeRDN7BERERERESmZHYHZZI62Bi/vAtti1euVxMdPMInfDevgyfZemQz0iCZMEREREZF4cVEHIJHqju0Zvy8wCJs6PxsbVZ2C7fm9HrBD8vg3gdfKHqVEYWdgneT1qdisjP2BY7E18CuBt4FJ5N6iUERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERETKx0UdgLRNQ0PDhs65HoUc65z7cty4cbPCfP4xY8b0994PKOTY5uZmP3HixFfDfH7J7dRTT12jrq5unUKPX7hw4euTJk1qDuv5x44dWzd37txhhR6/fPnyD6+55povwnp+EREREZGOqi7qAKRtvPfXAsMLPPYu4PAwn7+5uflU59yFhRxbU1PTjN5rZVVbW3uk935Cocf369dvDWBRWM//0Ucf9a+rq3u50OM7d+58EnBDWM8vIiIiItJRKbGqfguBZXmOWRD2kzrnvgY+yXNYDbB22M8tRVmGvUdyam5uToT5pMmOm3zvD4C+QOcwn1tEREREpCNTEl/lnHP148ePn1zu521sbPwH8I9cx4waNWpgXV3dnDKFJK17uLGx8bByP+nEiRM/BQblO66+vv4h59x+ZQhJRERERKRDqIk6ABEREREREREpjJJ4ERERERERkSqhJF5ERERERESkSiiJFxEREREREakSSuJFREREREREqoSSeBEREREREZEqoSReREREREREpEooiRcRERERERGpEnVRByAVYIwfRILDcGxOgkEAOGbjeRXPXUx0n0YcoUTpFN+FTuyLYy9gAJ41cHwKvEcz9zORF8H5iKMUEREREYkFJfFxVu+H4biQBIcCDg+4wP0OcIxjtP8PTfyKq9270QQqkTjD96CJs4GfA70Ipump6zX8kQbexPlfMZ4pSuZFREREREpL0+njqsH/CMfLwGFkpu4t1eA5hlpep96fUp7gJHJj/OY08QrwB6BXnqM3w3M7o7mdM3yPMkQnIiIiIhJbSuLjqN5fDFxOcTMxOuP4Nw3+vBJFJZWi3u9AgmeADYp6nGcEzTymRF5EREREpHSUxMdNvT8Fx7ntaOFC6v2I0OKRyjLKD8RxB9CzTY/3bEcz14HPNbtDRERERETaSEl8nDT4fjj+1s5WHI5xjPJtS/KkstXxJ2Bgu9rwjGA0R4UTkIiIiIiIBCmJjxMbgV89hJb6U8ePQmhHKkmD3wI4LpS2PBdqNF5EREREJHxK4mPDO3xICZo5IcS2pBI4vkd454SNaWDHkNoSEREREZEkJfFxMYatgcEhtjiE031xhc+ksnm+G3KLB4fcnoiIiIhI7CmJjwvPhqG3mShBmxKlcF9PV2R1exERERERyUtJfFwk6F+CVtcqQZsShQbfDQh3azjP2qG2JyIiIiIiSuJjo4avStDqlyVoU6LQyFJgRcitfhFyeyIiIiIisackPi48c6qiTYmI88DcUJv0fBJqeyIiIiIioiQ+Rp4DloTY3kIG8mqI7UnUPI+H3OKjIbcnIiIiIhJ7SuLjotEtAR4KscW7GeuaQmxPolbD5BBb+4Zlob7fREREREQEJfHx4rkQ8CG01Izj0hDakUoygLuBl0Jq7a9c774JqS0REREREUlSEh8nE9wLOK4NoaUrGO/+F0I7UknGugQJfg40t7Olj+jMn8MISUREREREMimJj5vlnI7n+Xa08BSLODe0eKSyTHRTgfPb0cJSHEdxhSvFbggiIiIiIrGnJD5urnHLSHAQjqltePQDrOBQJrmwtyKTStLo/oTnJxQ/Ij8fz0GMd9NLEZaIiIiIiCiJj6er3UI8BwK/Bb4u4BGLgJ8zkIO5xmnv7ziY4C4nwf7AawUc7XHcRoJtmODCrnAvIiIiIiIBdVEHIBFpdCuBPzLGjyfBCXgOw7ElsEbyiPnAy8CdNHMTV7uFkcUq0ZjopjLWb80cDscxAtgLGICdN5YC7wH3U8PNjHNhFcQTEREREZEclMTH3Tj3GXBZ8gJn+64swnONWxZpXFIZxroEMCV5gbG+hgX00Jp3EREREZFoKImXTJe5pVGHIBXMknol8CIiIiIiEdGaeBEREREREZEqoSReREREREREpEooiRcRERERERGpEkriRURERERERKqEkngRERERERGRKqEkXkRERERERKRKKIkXERERERERqRJK4kVERERERESqhJJ4ERERERERkSqhJF5ERERERESkSiiJFxEREREREakSSuJFREREREREqoSSeBEREREREZEqoSReREREREREpEooiRcRERERERGpEkriRURERERERKqEkngRERERERGRKqEkXkRERERERKRKKImXTCf57pzku0cdhlSoBr8ap/s+UYchIiIiIhJXdVEHIBFr8AOAk4DDga2A7smfLwZm4LgLz3U0uvnRBSmRGevrmMOROI4E9gTWphlo8CuAD4F7qeFmxrnnI41TRERERCQmNBIfV2f5ztT7PwLvAJcAu5JK4E0PYE88fwHeo8H/krFenT5xMtofyCe8iuNW4Fhg7cC9nYCNgZ+Q4Dka/BTG+PWiCFNEREREJE6UxMfRGN+fZTyC49dkJu7Z9AIu4BPu1VTqOPCOBv8rPPcCQwp80BEkeIF6v2cpIxMRERERiTsl8XFztu9KgntwDG/Do/enmXs4y3cOPS6pHA2cD/wfxZ8f+uF4gDF+xxJEJSIiIiIiKImPnyVMAHZoRwu7spw/hxWOVJgGvz/wx3a00IUEt9PgVw8rJBERERERSVMSHydj/I54jg+hpdOp98NCaEcqyUhfC/yV9p8XBgPntT8gERERERFpSUl8nCT4FeBCaKkWx7khtCOVpDeHAWF1zvyIM3yPkNoSEREREZEkJfFxYQnV/iG2eCgjfacQ25Oo2TZyYelGMweG2J6IiIiIiKAkPj5WsCPQJcQWe7M6W4TYnkRvj1Bb86hSvYiIiIhIyJTEx4VjUOht1jI49DYlGmN9DTAg1DZL8Z4TEREREYk5JfFx4SjF+uSeJWhTovAJXYDVQm3T0yvU9kREREREREl8bHg+C73NBPNCb1Oi0eiWAF+H3OrckNsTEREREYk9JfHx8V7oLfoStClRCvf1dLwfansiIiIiIqIkPjYm8AowO8QWZzLRfRBiexK9e0NtLcE9obYnIiIiIiJK4uPDeeDmEBu8KcS2pBJ4bgYSIbX2FhOYHlJbIiIiIiKSpCQ+Tmq5GFgYQktzWcrlIbQjlWSCmwncGEpbnvOTHUciIiIiIhIiJfFxcpVbhOPH7WwlgWM017tvQolJKksd5wAft7OVSUxwU8IIR0REREREMimJj5vx7gY8/9fmx3vOZby7O8SIpJJc6eaR4AjgyzY93vM8S/lBuEEVZBNgu+SlcwTPL9VhS+w9sm3UgZRAHbBB8qLtP00X0ueFjSOOJZsa0q/b6hHHIiIiVUJJfBxNcL/BcTqwsohHLcNzIhPcn0sVVhl1B7Yh/eVurWjDqTAT3QwS7AK8U+Qjb8Wxd0SzNMYB05OXQSVovwbYlPR7ZmgJnkNK7yHsPfJM1IGUwJnYDhNvAv0ijgWgG7A16f8zAyKI4Tukzwv/LNFz9MQ6hVK/55pFPj4BXIe9dvcBLtToRESkLine truncated
"fig-pdes-dot-product.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "f0260d7b",
"id": "a8aa2ebd",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g2419.png\" align=\"left\" width=\"550\"/>\n",
"</div>\n"
"<img src=\"attachment:fig-pdes-dot-product.png\" align=\"left\" width=\"550\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "42776d84",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which MPI directive best incorporates the communication of the local dot product among processes?\n",
"</div>\n",
"\n",
" a) MPI_Gather\n",
" b) MPI_Reduce\n",
" c) MPI_Allreduce\n",
" d) MPI_Bcast"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e0907af2",
"metadata": {},
"outputs": [],
"source": [
"answer=\"x\" # Replace x with a, b, c, or d\n",
"pdes_check_2(answer)"
]
},
{
@@ -1112,7 +1268,8 @@
"id": "759aefd1",
"metadata": {},
"source": [
"### Sparse matrix-vector product\n"
"### Sparse matrix-vector product\n",
"Next we will discuss how to parallelize the product of a sparse matrix $A$ with a vector $x$. "
]
},
{
@@ -1140,8 +1297,21 @@
"<b>Question:</b> Which parts of $A$ and $x$ are needed to compute the local values of $b$ in a worker? \n",
"</div>\n",
"\n",
"\n",
"- Answer: Only the entries of x associated with the non-zero columns of A stored in the worker."
" a) The local entries of A and all entries of x.\n",
" b) The local entries of A and the local entries of x. \n",
" c) All entries of A and the entries of x associated with local non-zero columns of A. \n",
" d) The local entries of A and the entries of x associated with the local non-zero columns of A. \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "53672399",
"metadata": {},
"outputs": [],
"source": [
"answer=\"x\" # Replace x with a, b, c, or d\n",
"pdes_check_3(answer)"
]
},
{
@@ -1149,7 +1319,8 @@
"id": "4afca5ab",
"metadata": {},
"source": [
"### Ghost (halo) columns"
"### Ghost (halo) columns\n",
"In our example, each CPU needs all local entries of $x$ plus two additional entries from another machine. If all entries in $A$ were non-zero, the whole vector $x$ would be required. Thus, the sparsity of $A$ allows to reduce the amount of communication. This pays off especially in larger problems. "
]
},
{
@@ -1174,7 +1345,11 @@
"source": [
"### Latency hiding\n",
"\n",
"A = A_own + A_ghost\n"
"We can also use latency hiding for this problem. The computations are split into two parts: \n",
"1. Multiplication with only local values of $x$ \n",
"2. Multiplication with the remaining communicated values of $x$\n",
"\n",
"The first part of the computations has no data dependencies, so it can be started immediately. During its computation, the communication of the values of $x$ can be started. "
]
},
{
@@ -1203,31 +1378,50 @@
},
{
"cell_type": "markdown",
"id": "a6433395",
"id": "149111fa",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> Which mesh partition does lead to less communication in the sparse matrix-vector product?\n",
"</div>\n",
"\n",
"- Answer: 2d block (as for Jacobi method)\n"
"</div>"
]
},
{
"attachments": {
"g20102.png": {
"image/png": "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 truncated
"fig-pdes-2d-partition.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "931e1fb6",
"id": "b2883efb",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g20102.png\" align=\"left\" width=\"400\"/>\n",
"<img src=\"attachment:fig-pdes-2d-partition.png\" align=\"left\" width=\"400\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "5e2926d0",
"metadata": {},
"source": [
" a) The 2D block partitioning\n",
" b) The 2D cyclic partitioning\n",
" c) Both are equally good"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7f67a66a",
"metadata": {},
"outputs": [],
"source": [
"answer=\"x\" # Replace x with a, b, or c \n",
"pdes_check_4(answer)"
]
},
{
"cell_type": "markdown",
"id": "a91edb5d",
@@ -1235,7 +1429,9 @@
"source": [
"Remember: The equation associated with point (i,j) is:\n",
"\n",
"$u_{i-1,j} + u_{i+1,j} + u_{i,j-1} + u_{i,j+1} - 4u_{i,j} = 0$"
"$u_{i-1,j} + u_{i+1,j} + u_{i,j-1} + u_{i,j+1} - 4u_{i,j} = 0$\n",
"\n",
"Each equation for a point corresponds with a row in the matrix $A$. Each row will have only 5 non-zero values, and it reduces communication if they are on the same CPU. Therefore, the 2D block partitioning is more suitable, since only the boundary values need to be communicated."
]
},
{
@@ -1261,10 +1457,7 @@
"source": [
"## How to partition unstructured meshes?\n",
"\n",
"- FEM methods work on unstructured meshes\n",
"- One equation per node\n",
"- Non-zero columns are associated with nodes connected by mesh edges\n",
"\n"
"Finite element methods also work on unstructured meshes. The grid of points can be modeled as a graph. Again, there will be one equation per node in the graph. The partition can be computed as the result of a k-way graph partitioning problem.\n"
]
},
{
@@ -1290,10 +1483,10 @@
"### k-way graph partitioning problem\n",
"\n",
"\n",
"Given a graph $G$ (i.e. the mesh)\n",
"Given a graph $G$ (i.e. the mesh),\n",
"\n",
"- Partition the vertices of $G$ into k disjoint parts of equal size (load balance)\n",
"- Minimize the number of edges with end vertices belonging to different parts (reduce communication)\n",
"- Partition the vertices of $G$ into $k$ disjoint parts of equal size (to achieve load balance)\n",
"- Minimize the number of edges with end vertices belonging to different parts (to reduce communication)\n",
"\n",
"\n",
"\n"
@@ -1311,18 +1504,37 @@
"source": [
"### Example\n",
"\n",
"- Partition of a mesh into 8 parts\n",
"- Computed with [METIS](https://github.com/KarypisLab/METIS)\n",
"The picture shows a partition of a mesh into 8 parts (computed with [METIS](https://github.com/KarypisLab/METIS)).\n",
"\n",
"<div>\n",
"<img src=\"attachment:sc3.png\" align=\"left\" width=\"350\"/>\n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"id": "b706b055",
"metadata": {},
"source": [
"# License\n",
"\n",
"\n",
"\n",
"This notebook is part of the course [Programming Large Scale Parallel Systems](https://www.francescverdugo.com/XM_40017) at Vrije Universiteit Amsterdam and may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "87beee72",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.9.1",
"language": "julia",
"name": "julia-1.9"
},
@@ -1330,7 +1542,7 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.9.1"
}
},
"nbformat": 4,
+318 -167
View File
@@ -381,6 +381,315 @@
"end"
]
},
{
"cell_type": "markdown",
"id": "48e594e7",
"metadata": {},
"source": [
"## LEQ: Exercise 1\n",
"### Blockwise partitioning: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5d890006",
"metadata": {},
"outputs": [],
"source": [
"function ge_par_block!(B,n,m,comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" # Init buffers\n",
" T = eltype(B)\n",
" if rank == 0\n",
" buffer_root = Vector{T}(undef,n*m)\n",
" buffer_root[:] = transpose(B)[:]\n",
" else\n",
" buffer_root = Vector{T}(undef,0)\n",
" end \n",
" nw = div(n,nranks)\n",
" buffer = Vector{T}(undef,nw*m)\n",
" # Send local matrices to workers\n",
" MPI.Scatter!(buffer_root,buffer,comm;root=0)\n",
" Bw = Matrix{T}(undef,nw,m)\n",
" transpose(Bw)[:] = buffer\n",
" MPI.Barrier(comm)\n",
" # time calcultation\n",
" t = @elapsed ge_block_worker!(Bw,n,comm)\n",
" # Gather results\n",
" buffer[:] = transpose(Bw)[:]\n",
" MPI.Gather!(buffer,buffer_root,comm;root=0)\n",
" Tf = typeof(t)\n",
" if rank == 0\n",
" transpose(B)[:] = buffer_root[:]\n",
" ts = Vector{Tf}(undef,nranks)\n",
" else\n",
" ts = Vector{Tf}(undef,0)\n",
" end\n",
" MPI.Gather!([t],ts,comm;root=0)\n",
" B, ts\n",
"end \n",
"\n",
"function ge_block_worker!(Bw,n,comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" nw,m = size(Bw)\n",
" B_k = similar(Bw,m)\n",
" lb = nw*rank + 1\n",
" ub = nw*(rank+1)\n",
" @inbounds for k in 1:n\n",
" # If I have row k\n",
" if k in lb:ub\n",
" myk = k - lb + 1\n",
" # Update just row k\n",
" #@show Bw[myk,k]\n",
" for t in (k+1):m\n",
" Bw[myk,t] = Bw[myk,t]/Bw[myk,k]\n",
" end\n",
" Bw[myk,k] = 1\n",
" # Send k to other procs\n",
" B_k .= view(Bw,myk,:)\n",
" MPI.Bcast!(B_k,comm;root=rank)\n",
" else\n",
" myk = 0\n",
" owner = div(k-1,nw)\n",
" MPI.Bcast!(B_k,comm;root=owner)\n",
" end\n",
" # Do nothing if I only have rows < k \n",
" if k <= ub\n",
" for i in (myk+1):nw\n",
" for j in (k+1):m\n",
" Bw[i,j] = Bw[i,j] - Bw[i,k]*B_k[j]\n",
" end\n",
" Bw[i,k] = 0\n",
" end\n",
" end\n",
" end\n",
" Bw\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "18c688ac",
"metadata": {},
"source": [
"### Cyclic partitioning: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6ba555b2",
"metadata": {},
"outputs": [],
"source": [
"function ge_par_cyclic!(B,n,m,comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" nw = div(n,nranks)\n",
" # Init buffers\n",
" T = eltype(B)\n",
" if rank == 0\n",
" buffer_root = Vector{T}(undef,n*m)\n",
" # Fill buffer cyclicly\n",
" for i in 1:n\n",
" ub = i * m \n",
" lb = ub - m + 1\n",
" j = mod(i-1,nw)*nranks + div(i-1,nw) +1\n",
" buffer_root[lb:ub] = transpose(B)[:,j]\n",
" end\n",
" else\n",
" buffer_root = Vector{T}(undef,0)\n",
" end \n",
" buffer = Vector{T}(undef,nw*m)\n",
" # Send local matrices to workers\n",
" MPI.Scatter!(buffer_root,buffer,comm;root=0)\n",
" Bw = Matrix{T}(undef,nw,m)\n",
" transpose(Bw)[:] = buffer\n",
" MPI.Barrier(comm)\n",
" # time calcultation\n",
" t = @elapsed ge_cyclic_worker!(Bw,n,comm)\n",
" # Gather results\n",
" buffer[:] = transpose(Bw)[:]\n",
" MPI.Gather!(buffer,buffer_root,comm;root=0)\n",
" Tf = typeof(t)\n",
" if rank == 0\n",
" for i in 1:n\n",
" ub = i * m \n",
" lb = ub - m + 1\n",
" j = mod(i-1,nw)*nranks + div(i-1,nw) +1\n",
" transpose(B)[:,j] = buffer_root[lb:ub]\n",
" end\n",
" ts = Vector{Tf}(undef,nranks)\n",
" else\n",
" ts = Vector{Tf}(undef,0)\n",
" end\n",
" MPI.Gather!([t],ts,comm;root=0)\n",
" B, ts\n",
"end\n",
"\n",
"function ge_cyclic_worker!(Bw,n,comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" nw,m = size(Bw)\n",
" B_k = similar(Bw,m)\n",
" my_rows = [i*nranks+(rank+1) for i in 0:(nw-1)]\n",
" @inbounds for k in 1:n\n",
" # If I have row k\n",
" if k in my_rows\n",
" myk = findfirst(my_rows .== k)[2]\n",
" # Update just row k\n",
" for t in (k+1):m\n",
" Bw[myk,t] = Bw[myk,t]/Bw[myk,k]\n",
" end\n",
" Bw[myk,k] = 1\n",
" # Send k to other procs\n",
" B_k .= view(Bw,myk,:)\n",
" MPI.Bcast!(B_k,comm;root=rank)\n",
" else\n",
" owner = mod(k-1,nranks)\n",
" MPI.Bcast!(B_k,comm;root=owner)\n",
" end\n",
" # Do nothing if I only have rows < k \n",
" if k < maximum(my_rows)\n",
" cutoff = findfirst(my_rows .> k)[2]\n",
" for i in cutoff:length(my_rows)\n",
" for j in (k+1):m\n",
" Bw[i,j] = Bw[i,j] - Bw[i,k]*B_k[j]\n",
" end\n",
" Bw[i,k] = 0\n",
" end\n",
" end\n",
" end\n",
" Bw\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "fe0bb4ab",
"metadata": {},
"source": [
"### Main Function to run code and test performance: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4d00c192",
"metadata": {},
"outputs": [],
"source": [
"using MPI\n",
"using Test\n",
"MPI.Init()\n",
"\n",
"\n",
"function tridiagonal_matrix(n)\n",
" C = zeros(n,n)\n",
" stencil = [(-1,2,-1),(-1,0,1)]\n",
" for i in 1:n\n",
" for (coeff,o) in zip((-1,2,-1),(-1,0,1))\n",
" j = i+o\n",
" if j in 1:n\n",
" C[i,j] = coeff\n",
" end\n",
" end\n",
" end\n",
" C\n",
"end\n",
"\n",
"function ge_seq!(B)\n",
" n,m = size(B)\n",
" @inbounds for k in 1:n\n",
" for t in (k+1):m\n",
" B[k,t] = B[k,t]/B[k,k]\n",
" end\n",
" B[k,k] = 1\n",
" for i in (k+1):n \n",
" for j in (k+1):m\n",
" B[i,j] = B[i,j] - B[i,k]*B[k,j]\n",
" end\n",
" B[i,k] = 0\n",
" end\n",
" end\n",
" B\n",
"end\n",
"\n",
"function main_check()\n",
" # Create communicator \n",
" comm = MPI.Comm_dup(MPI.COMM_WORLD)\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" n = 10*nranks\n",
" # create matrix B such that mod(n, nprocs) == 0\n",
" if rank == 0 \n",
" A = tridiagonal_matrix(n)\n",
" b = ones(n)\n",
" B = [A b]\n",
" else \n",
" B = tridiagonal_matrix(0)\n",
" end\n",
" # call parallel method \n",
" B_block, ts_block = ge_par_block!(copy(B),n,n+1,comm)\n",
" B_cyclic, ts_cyclic = ge_par_cyclic!(copy(B),n,n+1,comm)\n",
" # test if results is equal to sequential \n",
" if rank == 0\n",
" B_seq = ge_seq!(copy(B))\n",
" @test B_seq == B_block\n",
" @test B_seq == B_cyclic\n",
" # print timings\n",
" println(\"No workers: $nranks| Blockwise: min $(minimum(ts_block))| Cyclic: min $(minimum(ts_cyclic))\")\n",
" end\n",
"end\n",
"\n",
"main_check()"
]
},
{
"cell_type": "markdown",
"id": "cbbd3b8f",
"metadata": {},
"source": [
"## ASP : Exercise 1\n",
"Implementation of parallel ASP using only `MPI.Bcast!`. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ec5f932f",
"metadata": {},
"outputs": [],
"source": [
"@everywhere function floyd_worker_bcast!(Cw,comm)\n",
" rank = MPI.Comm_rank(comm)\n",
" nranks = MPI.Comm_size(comm)\n",
" Nw,N = size(Cw)\n",
" C_k = similar(Cw,N)\n",
" lb = Nw*rank + 1\n",
" ub = Nw*(rank+1)\n",
" for k in 1:N\n",
" if k in lb:ub\n",
" myk = k - lb + 1\n",
" C_k .= view(Cw,myk,:)\n",
" MPI.Bcast!(C_k,comm;root=rank)\n",
" else\n",
" owner = div(k-1,Nw)\n",
" MPI.Bcast!(C_k,comm;root=owner)\n",
" end\n",
" for j in 1:N\n",
" for i in 1:Nw\n",
" @inbounds Cw[i,j] = min(Cw[i,j],Cw[i,k]+C_k[j])\n",
" end\n",
" end\n",
" end\n",
" Cw\n",
"end"
]
},
{
"cell_type": "markdown",
"id": "19641daf",
@@ -401,7 +710,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": null,
"id": "a4d5ab70",
"metadata": {},
"outputs": [],
@@ -424,21 +733,10 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": null,
"id": "bcee99f0",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tsp_serial (generic function with 1 method)"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"## TSP serial \n",
"function tsp_serial_impl(connections,hops,path,current_distance, min_path, min_distance, node_count)\n",
@@ -482,21 +780,10 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": null,
"id": "327f5349",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tsp_dist (generic function with 1 method)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"## TSP distributed\n",
"@everywhere function tsp_dist_impl(connections,hops,path,current_distance,min_dist_chnl, max_hops,jobs_chnl,ftr_result,node_count)\n",
@@ -597,134 +884,10 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": null,
"id": "706242f2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"n = 4\n",
"n = 6\n",
"n = 8\n",
"n = 10\n",
"search_overhead_perc = [0.75 0.16666666666666666 0.3333333333333333 0.2727272727272727 0.14285714285714285 0.07692307692307693 0.0 0.16666666666666666 0.4 0.16666666666666666; 0.01092896174863388 0.005154639175257732 0.031578947368421054 0.05384615384615385 0.4672897196261682 0.10434782608695652 0.09917355371900827 0.06666666666666667 -0.0056179775280898875 0.2736842105263158; 0.0 -0.009295120061967466 -0.0032278889606197547 0.01906318082788671 0.028241335044929396 0.0011111111111111111 -0.008201892744479496 0.004958047292143402 -0.005873715124816446 -0.009497336113041464; 3.87551835057939e-5 -0.014818818265230451 7.133685261806249e-5 -0.03200184183262346 -0.01696773663002659 -0.004075168167420009 6.629541235746487e-5 -0.0033114074608037486 -0.016359150396910535 -0.0025293711126468557]\n"
]
},
{
"data": {
"image/png": "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 truncated
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"600\" height=\"400\" viewBox=\"0 0 2400 1600\">\n",
"<defs>\n",
" <clipPath id=\"clip070\">\n",
" <rect x=\"0\" y=\"0\" width=\"2400\" height=\"1600\"/>\n",
" </clipPath>\n",
"</defs>\n",
"<path clip-path=\"url(#clip070)\" d=\"M0 1600 L2400 1600 L2400 0 L0 0 Z\" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
"<defs>\n",
" <clipPath id=\"clip071\">\n",
" <rect x=\"480\" y=\"0\" width=\"1681\" height=\"1600\"/>\n",
" </clipPath>\n",
"</defs>\n",
"<path clip-path=\"url(#clip070)\" d=\"M266.9 1423.18 L2352.76 1423.18 L2352.76 183.952 L266.9 183.952 Z\" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
"<defs>\n",
" <clipPath id=\"clip072\">\n",
" <rect x=\"266\" y=\"183\" width=\"2087\" height=\"1240\"/>\n",
" </clipPath>\n",
"</defs>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"325.934,1423.18 325.934,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"653.899,1423.18 653.899,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"981.863,1423.18 981.863,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"1309.83,1423.18 1309.83,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"1637.79,1423.18 1637.79,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"1965.76,1423.18 1965.76,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"2293.72,1423.18 2293.72,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1423.18 2352.76,1423.18 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"325.934,1423.18 325.934,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"653.899,1423.18 653.899,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"981.863,1423.18 981.863,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"1309.83,1423.18 1309.83,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"1637.79,1423.18 1637.79,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"1965.76,1423.18 1965.76,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"2293.72,1423.18 2293.72,1404.28 \"/>\n",
"<path clip-path=\"url(#clip070)\" d=\"M328.943 1455.09 L317.138 1473.54 L328.943 1473.54 L328.943 1455.09 M327.716 1451.02 L333.596 1451.02 L333.596 1473.54 L338.526 1473.54 L338.526 1477.43 L333.596 1477.43 L333.596 1485.58 L328.943 1485.58 L328.943 1477.43 L313.341 1477.43 L313.341 1472.92 L327.716 1451.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M644.176 1451.02 L662.533 1451.02 L662.533 1454.96 L648.459 1454.96 L648.459 1463.43 Q649.477 1463.08 650.496 1462.92 Q651.514 1462.73 652.533 1462.73 Q658.32 1462.73 661.699 1465.9 Q665.079 1469.08 665.079 1474.49 Q665.079 1480.07 661.607 1483.17 Q658.135 1486.25 651.815 1486.25 Q649.639 1486.25 647.371 1485.88 Q645.125 1485.51 642.718 1484.77 L642.718 1480.07 Q644.801 1481.2 647.024 1481.76 Q649.246 1482.32 651.723 1482.32 Q655.727 1482.32 658.065 1480.21 Q660.403 1478.1 660.403 1474.49 Q660.403 1470.88 658.065 1468.77 Q655.727 1466.67 651.723 1466.67 Q649.848 1466.67 647.973 1467.08 Q646.121 1467.5 644.176 1468.38 L644.176 1451.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M982.268 1466.44 Q979.12 1466.44 977.268 1468.59 Q975.44 1470.74 975.44 1474.49 Q975.44 1478.22 977.268 1480.39 Q979.12 1482.55 982.268 1482.55 Q985.417 1482.55 987.245 1480.39 Q989.097 1478.22 989.097 1474.49 Q989.097 1470.74 987.245 1468.59 Q985.417 1466.44 982.268 1466.44 M991.551 1451.78 L991.551 1456.04 Q989.791 1455.21 987.986 1454.77 Q986.204 1454.33 984.444 1454.33 Q979.815 1454.33 977.361 1457.45 Q974.93 1460.58 974.583 1466.9 Q975.949 1464.89 978.009 1463.82 Q980.069 1462.73 982.546 1462.73 Q987.754 1462.73 990.764 1465.9 Q993.796 1469.05 993.796 1474.49 Q993.796 1479.82 990.648 1483.03 Q987.5 1486.25 982.268 1486.25 Q976.273 1486.25 973.102 1481.67 Q969.93 1477.06 969.93 1468.33 Q969.93 1460.14 973.819 1455.28 Q977.708 1450.39 984.259 1450.39 Q986.018 1450.39 987.801 1450.74 Q989.606 1451.09 991.551 1451.78 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M1298.72 1451.02 L1320.94 1451.02 L1320.94 1453.01 L1308.39 1485.58 L1303.51 1485.58 L1315.31 1454.96 L1298.72 1454.96 L1298.72 1451.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M1637.79 1469.17 Q1634.46 1469.17 1632.54 1470.95 Q1630.64 1472.73 1630.64 1475.86 Q1630.64 1478.98 1632.54 1480.77 Q1634.46 1482.55 1637.79 1482.55 Q1641.13 1482.55 1643.05 1480.77 Q1644.97 1478.96 1644.97 1475.86 Q1644.97 1472.73 1643.05 1470.95 Q1641.15 1469.17 1637.79 1469.17 M1633.12 1467.18 Q1630.11 1466.44 1628.42 1464.38 Q1626.75 1462.32 1626.75 1459.35 Q1626.75 1455.21 1629.69 1452.8 Q1632.65 1450.39 1637.79 1450.39 Q1642.95 1450.39 1645.89 1452.8 Q1648.83 1455.21 1648.83 1459.35 Q1648.83 1462.32 1647.14 1464.38 Q1645.48 1466.44 1642.49 1467.18 Q1645.87 1467.96 1647.75 1470.26 Q1649.64 1472.55 1649.64 1475.86 Q1649.64 1480.88 1646.57 1483.57 Q1643.51 1486.25 1637.79 1486.25 Q1632.08 1486.25 1629 1483.57 Q1625.94 1480.88 1625.94 1475.86 Q1625.94 1472.55 1627.84 1470.26 Q1629.74 1467.96 1633.12 1467.18 M1631.4 1459.79 Q1631.4 1462.48 1633.07 1463.98 Q1634.76 1465.49 1637.79 1465.49 Q1640.8 1465.49 1642.49 1463.98 Q1644.2 1462.48 1644.2 1459.79 Q1644.2 1457.11 1642.49 1455.6 Q1640.8 1454.1 1637.79 1454.1 Q1634.76 1454.1 1633.07 1455.6 Q1631.4 1457.11 1631.4 1459.79 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M1956.06 1484.86 L1956.06 1480.6 Q1957.82 1481.44 1959.62 1481.88 Q1961.43 1482.32 1963.16 1482.32 Q1967.79 1482.32 1970.23 1479.21 Q1972.68 1476.09 1973.03 1469.75 Q1971.68 1471.74 1969.62 1472.8 Q1967.56 1473.87 1965.06 1473.87 Q1959.88 1473.87 1956.85 1470.74 Q1953.84 1467.59 1953.84 1462.15 Q1953.84 1456.83 1956.98 1453.61 Q1960.13 1450.39 1965.36 1450.39 Q1971.36 1450.39 1974.51 1455 Q1977.68 1459.58 1977.68 1468.33 Q1977.68 1476.51 1973.79 1481.39 Q1969.92 1486.25 1963.37 1486.25 Q1961.61 1486.25 1959.81 1485.9 Q1958 1485.56 1956.06 1484.86 M1965.36 1470.21 Q1968.51 1470.21 1970.34 1468.06 Q1972.19 1465.9 1972.19 1462.15 Q1972.19 1458.43 1970.34 1456.27 Q1968.51 1454.1 1965.36 1454.1 Q1962.22 1454.1 1960.36 1456.27 Q1958.54 1458.43 1958.54 1462.15 Q1958.54 1465.9 1960.36 1468.06 Q1962.22 1470.21 1965.36 1470.21 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M2268.41 1481.64 L2276.05 1481.64 L2276.05 1455.28 L2267.74 1456.95 L2267.74 1452.69 L2276 1451.02 L2280.68 1451.02 L2280.68 1481.64 L2288.32 1481.64 L2288.32 1485.58 L2268.41 1485.58 L2268.41 1481.64 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M2307.76 1454.1 Q2304.15 1454.1 2302.32 1457.66 Q2300.52 1461.2 2300.52 1468.33 Q2300.52 1475.44 2302.32 1479.01 Q2304.15 1482.55 2307.76 1482.55 Q2311.4 1482.55 2313.2 1479.01 Q2315.03 1475.44 2315.03 1468.33 Q2315.03 1461.2 2313.2 1457.66 Line truncated
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"266.9,1045.62 2352.76,1045.62 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"266.9,749.362 2352.76,749.362 \"/>\n",
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"266.9,453.103 2352.76,453.103 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1423.18 266.9,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1341.88 285.798,1341.88 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1045.62 285.798,1045.62 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,749.362 285.798,749.362 \"/>\n",
"<polyline clip-path=\"url(#clip070)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,453.103 285.798,453.103 \"/>\n",
"<path clip-path=\"url(#clip070)\" d=\"M173.725 1327.68 Q170.113 1327.68 168.285 1331.24 Q166.479 1334.78 166.479 1341.91 Q166.479 1349.02 168.285 1352.59 Q170.113 1356.13 173.725 1356.13 Q177.359 1356.13 179.164 1352.59 Q180.993 1349.02 180.993 1341.91 Q180.993 1334.78 179.164 1331.24 Q177.359 1327.68 173.725 1327.68 M173.725 1323.97 Q179.535 1323.97 182.59 1328.58 Q185.669 1333.16 185.669 1341.91 Q185.669 1350.64 182.59 1355.25 Q179.535 1359.83 173.725 1359.83 Q167.914 1359.83 164.836 1355.25 Q161.78 1350.64 161.78 1341.91 Q161.78 1333.16 164.836 1328.58 Q167.914 1323.97 173.725 1323.97 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M193.886 1353.28 L198.771 1353.28 L198.771 1359.16 L193.886 1359.16 L193.886 1353.28 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M218.956 1327.68 Q215.345 1327.68 213.516 1331.24 Q211.71 1334.78 211.71 1341.91 Q211.71 1349.02 213.516 1352.59 Q215.345 1356.13 218.956 1356.13 Q222.59 1356.13 224.396 1352.59 Q226.224 1349.02 226.224 1341.91 Q226.224 1334.78 224.396 1331.24 Q222.59 1327.68 218.956 1327.68 M218.956 1323.97 Q224.766 1323.97 227.821 1328.58 Q230.9 1333.16 230.9 1341.91 Q230.9 1350.64 227.821 1355.25 Q224.766 1359.83 218.956 1359.83 Q213.146 1359.83 210.067 1355.25 Q207.011 1350.64 207.011 1341.91 Q207.011 1333.16 210.067 1328.58 Q213.146 1323.97 218.956 1323.97 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M174.951 1031.42 Q171.34 1031.42 169.512 1034.98 Q167.706 1038.53 167.706 1045.66 Q167.706 1052.76 169.512 1056.33 Q171.34 1059.87 174.951 1059.87 Q178.586 1059.87 180.391 1056.33 Q182.22 1052.76 182.22 1045.66 Q182.22 1038.53 180.391 1034.98 Q178.586 1031.42 174.951 1031.42 M174.951 1027.72 Q180.762 1027.72 183.817 1032.32 Q186.896 1036.91 186.896 1045.66 Q186.896 1054.38 183.817 1058.99 Q180.762 1063.57 174.951 1063.57 Q169.141 1063.57 166.063 1058.99 Q163.007 1054.38 163.007 1045.66 Q163.007 1036.91 166.063 1032.32 Q169.141 1027.72 174.951 1027.72 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M195.113 1057.02 L199.998 1057.02 L199.998 1062.9 L195.113 1062.9 L195.113 1057.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M210.993 1058.97 L218.632 1058.97 L218.632 1032.6 L210.322 1034.27 L210.322 1030.01 L218.585 1028.34 L223.261 1028.34 L223.261 1058.97 L230.9 1058.97 L230.9 1062.9 L210.993 1062.9 L210.993 1058.97 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M175.322 735.16 Q171.711 735.16 169.882 738.725 Q168.076 742.267 168.076 749.396 Q168.076 756.503 169.882 760.068 Q171.711 763.609 175.322 763.609 Q178.956 763.609 180.762 760.068 Q182.59 756.503 182.59 749.396 Q182.59 742.267 180.762 738.725 Q178.956 735.16 175.322 735.16 M175.322 731.457 Q181.132 731.457 184.187 736.063 Q187.266 740.646 187.266 749.396 Q187.266 758.123 184.187 762.73 Q181.132 767.313 175.322 767.313 Q169.512 767.313 166.433 762.73 Q163.377 758.123 163.377 749.396 Q163.377 740.646 166.433 736.063 Q169.512 731.457 175.322 731.457 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M195.484 760.762 L200.368 760.762 L200.368 766.642 L195.484 766.642 L195.484 760.762 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M214.581 762.707 L230.9 762.707 L230.9 766.642 L208.956 766.642 L208.956 762.707 Q211.618 759.952 216.201 755.322 Q220.808 750.67 221.988 749.327 Q224.234 746.804 225.113 745.068 Q226.016 743.308 226.016 741.619 Q226.016 738.864 224.071 737.128 Q222.15 735.392 219.048 735.392 Q216.849 735.392 214.396 736.156 Q211.965 736.92 209.187 738.471 L209.187 733.748 Q212.011 732.614 214.465 732.035 Q216.919 731.457 218.956 731.457 Q224.326 731.457 227.521 734.142 Q230.715 736.827 230.715 741.318 Q230.715 743.447 229.905 745.369 Q229.118 747.267 227.011 749.859 Q226.433 750.531 223.331 753.748 Q220.229 756.943 214.581 762.707 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M174.373 438.902 Q170.762 438.902 168.933 442.466 Q167.127 446.008 167.127 453.138 Q167.127 460.244 168.933 463.809 Q170.762 467.351 174.373 467.351 Q178.007 467.351 179.812 463.809 Q181.641 460.244 181.641 453.138 Q181.641 446.008 179.812 442.466 Q178.007 438.902 174.373 438.902 M174.373 435.198 Q180.183 435.198 183.238 439.804 Q186.317 444.388 186.317 453.138 Q186.317 461.865 183.238 466.471 Q180.183 471.054 174.373 471.054 Q168.563 471.054 165.484 466.471 Q162.428 461.865 162.428 453.138 Q162.428 444.388 165.484 439.804 Q168.563 435.198 174.373 435.198 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip070)\" d=\"M194.535 464.503 L199.419 464.503 L199.419 470.383 L194.535 470.383 L194.535 464Line truncated
"<polyline clip-path=\"url(#clip072)\" style=\"stroke:#009af9; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"325.934,608.39 981.863,1013.91 1637.79,1336.76 2293.72,1368.51 \"/>\n",
"<circle clip-path=\"url(#clip072)\" cx=\"325.934\" cy=\"608.39\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"<circle clip-path=\"url(#clip072)\" cx=\"981.863\" cy=\"1013.91\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"<circle clip-path=\"url(#clip072)\" cx=\"1637.79\" cy=\"1336.76\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"<circle clip-path=\"url(#clip072)\" cx=\"2293.72\" cy=\"1368.51\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"</svg>\n"
],
"text/html": [
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"600\" height=\"400\" viewBox=\"0 0 2400 1600\">\n",
"<defs>\n",
" <clipPath id=\"clip120\">\n",
" <rect x=\"0\" y=\"0\" width=\"2400\" height=\"1600\"/>\n",
" </clipPath>\n",
"</defs>\n",
"<path clip-path=\"url(#clip120)\" d=\"M0 1600 L2400 1600 L2400 0 L0 0 Z\" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
"<defs>\n",
" <clipPath id=\"clip121\">\n",
" <rect x=\"480\" y=\"0\" width=\"1681\" height=\"1600\"/>\n",
" </clipPath>\n",
"</defs>\n",
"<path clip-path=\"url(#clip120)\" d=\"M266.9 1423.18 L2352.76 1423.18 L2352.76 183.952 L266.9 183.952 Z\" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
"<defs>\n",
" <clipPath id=\"clip122\">\n",
" <rect x=\"266\" y=\"183\" width=\"2087\" height=\"1240\"/>\n",
" </clipPath>\n",
"</defs>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"325.934,1423.18 325.934,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"653.899,1423.18 653.899,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"981.863,1423.18 981.863,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"1309.83,1423.18 1309.83,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"1637.79,1423.18 1637.79,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"1965.76,1423.18 1965.76,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"2293.72,1423.18 2293.72,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1423.18 2352.76,1423.18 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"325.934,1423.18 325.934,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"653.899,1423.18 653.899,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"981.863,1423.18 981.863,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"1309.83,1423.18 1309.83,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"1637.79,1423.18 1637.79,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"1965.76,1423.18 1965.76,1404.28 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"2293.72,1423.18 2293.72,1404.28 \"/>\n",
"<path clip-path=\"url(#clip120)\" d=\"M328.943 1455.09 L317.138 1473.54 L328.943 1473.54 L328.943 1455.09 M327.716 1451.02 L333.596 1451.02 L333.596 1473.54 L338.526 1473.54 L338.526 1477.43 L333.596 1477.43 L333.596 1485.58 L328.943 1485.58 L328.943 1477.43 L313.341 1477.43 L313.341 1472.92 L327.716 1451.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M644.176 1451.02 L662.533 1451.02 L662.533 1454.96 L648.459 1454.96 L648.459 1463.43 Q649.477 1463.08 650.496 1462.92 Q651.514 1462.73 652.533 1462.73 Q658.32 1462.73 661.699 1465.9 Q665.079 1469.08 665.079 1474.49 Q665.079 1480.07 661.607 1483.17 Q658.135 1486.25 651.815 1486.25 Q649.639 1486.25 647.371 1485.88 Q645.125 1485.51 642.718 1484.77 L642.718 1480.07 Q644.801 1481.2 647.024 1481.76 Q649.246 1482.32 651.723 1482.32 Q655.727 1482.32 658.065 1480.21 Q660.403 1478.1 660.403 1474.49 Q660.403 1470.88 658.065 1468.77 Q655.727 1466.67 651.723 1466.67 Q649.848 1466.67 647.973 1467.08 Q646.121 1467.5 644.176 1468.38 L644.176 1451.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M982.268 1466.44 Q979.12 1466.44 977.268 1468.59 Q975.44 1470.74 975.44 1474.49 Q975.44 1478.22 977.268 1480.39 Q979.12 1482.55 982.268 1482.55 Q985.417 1482.55 987.245 1480.39 Q989.097 1478.22 989.097 1474.49 Q989.097 1470.74 987.245 1468.59 Q985.417 1466.44 982.268 1466.44 M991.551 1451.78 L991.551 1456.04 Q989.791 1455.21 987.986 1454.77 Q986.204 1454.33 984.444 1454.33 Q979.815 1454.33 977.361 1457.45 Q974.93 1460.58 974.583 1466.9 Q975.949 1464.89 978.009 1463.82 Q980.069 1462.73 982.546 1462.73 Q987.754 1462.73 990.764 1465.9 Q993.796 1469.05 993.796 1474.49 Q993.796 1479.82 990.648 1483.03 Q987.5 1486.25 982.268 1486.25 Q976.273 1486.25 973.102 1481.67 Q969.93 1477.06 969.93 1468.33 Q969.93 1460.14 973.819 1455.28 Q977.708 1450.39 984.259 1450.39 Q986.018 1450.39 987.801 1450.74 Q989.606 1451.09 991.551 1451.78 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M1298.72 1451.02 L1320.94 1451.02 L1320.94 1453.01 L1308.39 1485.58 L1303.51 1485.58 L1315.31 1454.96 L1298.72 1454.96 L1298.72 1451.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M1637.79 1469.17 Q1634.46 1469.17 1632.54 1470.95 Q1630.64 1472.73 1630.64 1475.86 Q1630.64 1478.98 1632.54 1480.77 Q1634.46 1482.55 1637.79 1482.55 Q1641.13 1482.55 1643.05 1480.77 Q1644.97 1478.96 1644.97 1475.86 Q1644.97 1472.73 1643.05 1470.95 Q1641.15 1469.17 1637.79 1469.17 M1633.12 1467.18 Q1630.11 1466.44 1628.42 1464.38 Q1626.75 1462.32 1626.75 1459.35 Q1626.75 1455.21 1629.69 1452.8 Q1632.65 1450.39 1637.79 1450.39 Q1642.95 1450.39 1645.89 1452.8 Q1648.83 1455.21 1648.83 1459.35 Q1648.83 1462.32 1647.14 1464.38 Q1645.48 1466.44 1642.49 1467.18 Q1645.87 1467.96 1647.75 1470.26 Q1649.64 1472.55 1649.64 1475.86 Q1649.64 1480.88 1646.57 1483.57 Q1643.51 1486.25 1637.79 1486.25 Q1632.08 1486.25 1629 1483.57 Q1625.94 1480.88 1625.94 1475.86 Q1625.94 1472.55 1627.84 1470.26 Q1629.74 1467.96 1633.12 1467.18 M1631.4 1459.79 Q1631.4 1462.48 1633.07 1463.98 Q1634.76 1465.49 1637.79 1465.49 Q1640.8 1465.49 1642.49 1463.98 Q1644.2 1462.48 1644.2 1459.79 Q1644.2 1457.11 1642.49 1455.6 Q1640.8 1454.1 1637.79 1454.1 Q1634.76 1454.1 1633.07 1455.6 Q1631.4 1457.11 1631.4 1459.79 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M1956.06 1484.86 L1956.06 1480.6 Q1957.82 1481.44 1959.62 1481.88 Q1961.43 1482.32 1963.16 1482.32 Q1967.79 1482.32 1970.23 1479.21 Q1972.68 1476.09 1973.03 1469.75 Q1971.68 1471.74 1969.62 1472.8 Q1967.56 1473.87 1965.06 1473.87 Q1959.88 1473.87 1956.85 1470.74 Q1953.84 1467.59 1953.84 1462.15 Q1953.84 1456.83 1956.98 1453.61 Q1960.13 1450.39 1965.36 1450.39 Q1971.36 1450.39 1974.51 1455 Q1977.68 1459.58 1977.68 1468.33 Q1977.68 1476.51 1973.79 1481.39 Q1969.92 1486.25 1963.37 1486.25 Q1961.61 1486.25 1959.81 1485.9 Q1958 1485.56 1956.06 1484.86 M1965.36 1470.21 Q1968.51 1470.21 1970.34 1468.06 Q1972.19 1465.9 1972.19 1462.15 Q1972.19 1458.43 1970.34 1456.27 Q1968.51 1454.1 1965.36 1454.1 Q1962.22 1454.1 1960.36 1456.27 Q1958.54 1458.43 1958.54 1462.15 Q1958.54 1465.9 1960.36 1468.06 Q1962.22 1470.21 1965.36 1470.21 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M2268.41 1481.64 L2276.05 1481.64 L2276.05 1455.28 L2267.74 1456.95 L2267.74 1452.69 L2276 1451.02 L2280.68 1451.02 L2280.68 1481.64 L2288.32 1481.64 L2288.32 1485.58 L2268.41 1485.58 L2268.41 1481.64 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M2307.76 1454.1 Q2304.15 1454.1 2302.32 1457.66 Q2300.52 1461.2 2300.52 1468.33 Q2300.52 1475.44 2302.32 1479.01 Q2304.15 1482.55 2307.76 1482.55 Q2311.4 1482.55 2313.2 1479.01 Q2315.03 1475.44 2315.03 1468.33 Q2315.03 1461.2 2313.2 1457.66 Line truncated
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"266.9,1045.62 2352.76,1045.62 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"266.9,749.362 2352.76,749.362 \"/>\n",
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"266.9,453.103 2352.76,453.103 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1423.18 266.9,183.952 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1341.88 285.798,1341.88 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,1045.62 285.798,1045.62 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,749.362 285.798,749.362 \"/>\n",
"<polyline clip-path=\"url(#clip120)\" style=\"stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"266.9,453.103 285.798,453.103 \"/>\n",
"<path clip-path=\"url(#clip120)\" d=\"M173.725 1327.68 Q170.113 1327.68 168.285 1331.24 Q166.479 1334.78 166.479 1341.91 Q166.479 1349.02 168.285 1352.59 Q170.113 1356.13 173.725 1356.13 Q177.359 1356.13 179.164 1352.59 Q180.993 1349.02 180.993 1341.91 Q180.993 1334.78 179.164 1331.24 Q177.359 1327.68 173.725 1327.68 M173.725 1323.97 Q179.535 1323.97 182.59 1328.58 Q185.669 1333.16 185.669 1341.91 Q185.669 1350.64 182.59 1355.25 Q179.535 1359.83 173.725 1359.83 Q167.914 1359.83 164.836 1355.25 Q161.78 1350.64 161.78 1341.91 Q161.78 1333.16 164.836 1328.58 Q167.914 1323.97 173.725 1323.97 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M193.886 1353.28 L198.771 1353.28 L198.771 1359.16 L193.886 1359.16 L193.886 1353.28 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M218.956 1327.68 Q215.345 1327.68 213.516 1331.24 Q211.71 1334.78 211.71 1341.91 Q211.71 1349.02 213.516 1352.59 Q215.345 1356.13 218.956 1356.13 Q222.59 1356.13 224.396 1352.59 Q226.224 1349.02 226.224 1341.91 Q226.224 1334.78 224.396 1331.24 Q222.59 1327.68 218.956 1327.68 M218.956 1323.97 Q224.766 1323.97 227.821 1328.58 Q230.9 1333.16 230.9 1341.91 Q230.9 1350.64 227.821 1355.25 Q224.766 1359.83 218.956 1359.83 Q213.146 1359.83 210.067 1355.25 Q207.011 1350.64 207.011 1341.91 Q207.011 1333.16 210.067 1328.58 Q213.146 1323.97 218.956 1323.97 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M174.951 1031.42 Q171.34 1031.42 169.512 1034.98 Q167.706 1038.53 167.706 1045.66 Q167.706 1052.76 169.512 1056.33 Q171.34 1059.87 174.951 1059.87 Q178.586 1059.87 180.391 1056.33 Q182.22 1052.76 182.22 1045.66 Q182.22 1038.53 180.391 1034.98 Q178.586 1031.42 174.951 1031.42 M174.951 1027.72 Q180.762 1027.72 183.817 1032.32 Q186.896 1036.91 186.896 1045.66 Q186.896 1054.38 183.817 1058.99 Q180.762 1063.57 174.951 1063.57 Q169.141 1063.57 166.063 1058.99 Q163.007 1054.38 163.007 1045.66 Q163.007 1036.91 166.063 1032.32 Q169.141 1027.72 174.951 1027.72 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M195.113 1057.02 L199.998 1057.02 L199.998 1062.9 L195.113 1062.9 L195.113 1057.02 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M210.993 1058.97 L218.632 1058.97 L218.632 1032.6 L210.322 1034.27 L210.322 1030.01 L218.585 1028.34 L223.261 1028.34 L223.261 1058.97 L230.9 1058.97 L230.9 1062.9 L210.993 1062.9 L210.993 1058.97 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M175.322 735.16 Q171.711 735.16 169.882 738.725 Q168.076 742.267 168.076 749.396 Q168.076 756.503 169.882 760.068 Q171.711 763.609 175.322 763.609 Q178.956 763.609 180.762 760.068 Q182.59 756.503 182.59 749.396 Q182.59 742.267 180.762 738.725 Q178.956 735.16 175.322 735.16 M175.322 731.457 Q181.132 731.457 184.187 736.063 Q187.266 740.646 187.266 749.396 Q187.266 758.123 184.187 762.73 Q181.132 767.313 175.322 767.313 Q169.512 767.313 166.433 762.73 Q163.377 758.123 163.377 749.396 Q163.377 740.646 166.433 736.063 Q169.512 731.457 175.322 731.457 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M195.484 760.762 L200.368 760.762 L200.368 766.642 L195.484 766.642 L195.484 760.762 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M214.581 762.707 L230.9 762.707 L230.9 766.642 L208.956 766.642 L208.956 762.707 Q211.618 759.952 216.201 755.322 Q220.808 750.67 221.988 749.327 Q224.234 746.804 225.113 745.068 Q226.016 743.308 226.016 741.619 Q226.016 738.864 224.071 737.128 Q222.15 735.392 219.048 735.392 Q216.849 735.392 214.396 736.156 Q211.965 736.92 209.187 738.471 L209.187 733.748 Q212.011 732.614 214.465 732.035 Q216.919 731.457 218.956 731.457 Q224.326 731.457 227.521 734.142 Q230.715 736.827 230.715 741.318 Q230.715 743.447 229.905 745.369 Q229.118 747.267 227.011 749.859 Q226.433 750.531 223.331 753.748 Q220.229 756.943 214.581 762.707 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M174.373 438.902 Q170.762 438.902 168.933 442.466 Q167.127 446.008 167.127 453.138 Q167.127 460.244 168.933 463.809 Q170.762 467.351 174.373 467.351 Q178.007 467.351 179.812 463.809 Q181.641 460.244 181.641 453.138 Q181.641 446.008 179.812 442.466 Q178.007 438.902 174.373 438.902 M174.373 435.198 Q180.183 435.198 183.238 439.804 Q186.317 444.388 186.317 453.138 Q186.317 461.865 183.238 466.471 Q180.183 471.054 174.373 471.054 Q168.563 471.054 165.484 466.471 Q162.428 461.865 162.428 453.138 Q162.428 444.388 165.484 439.804 Q168.563 435.198 174.373 435.198 Z\" fill=\"#000000\" fill-rule=\"nonzero\" fill-opacity=\"1\" /><path clip-path=\"url(#clip120)\" d=\"M194.535 464.503 L199.419 464.503 L199.419 470.383 L194.535 470.383 L194.535 464Line truncated
"<polyline clip-path=\"url(#clip122)\" style=\"stroke:#009af9; stroke-linecap:round; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"325.934,608.39 981.863,1013.91 1637.79,1336.76 2293.72,1368.51 \"/>\n",
"<circle clip-path=\"url(#clip122)\" cx=\"325.934\" cy=\"608.39\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"<circle clip-path=\"url(#clip122)\" cx=\"981.863\" cy=\"1013.91\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"<circle clip-path=\"url(#clip122)\" cx=\"1637.79\" cy=\"1336.76\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"<circle clip-path=\"url(#clip122)\" cx=\"2293.72\" cy=\"1368.51\" r=\"14.4\" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\" stroke=\"#000000\" stroke-opacity=\"1\" stroke-width=\"3.2\"/>\n",
"</svg>\n"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"using Distributed\n",
"using Plots\n",
@@ -800,18 +963,6 @@
"xlabel!(\"Number of cities\")"
]
},
{
"cell_type": "markdown",
"id": "47d88e7a",
"metadata": {},
"source": [
"# License\n",
"\n",
"TODO: replace link to website\n",
"\n",
"This notebook is part of the course [Programming Large Scale Parallel Systems](http://localhost:8000/) at Vrije Universiteit Amsterdam and may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license."
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -823,7 +974,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.9.1",
"language": "julia",
"name": "julia-1.9"
},
@@ -831,7 +982,7 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.9.1"
}
},
"nbformat": 4,
+309 -116
View File
@@ -14,7 +14,7 @@
},
{
"cell_type": "markdown",
"id": "1e74dfd9",
"id": "5d49d8e7",
"metadata": {},
"source": [
"## Contents\n",
@@ -28,7 +28,37 @@
},
{
"cell_type": "markdown",
"id": "bf3dd0e6",
"id": "480af594",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\">\n",
"<b>Note:</b> Do not forget to execute the cell below before starting this notebook! \n",
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7e93809a",
"metadata": {},
"outputs": [],
"source": [
"using Printf\n",
"function answer_checker(answer,solution)\n",
" if answer == solution\n",
" \"🥳 Well done! \"\n",
" else\n",
" \"It's not correct. Keep trying! 💪\"\n",
" end |> println\n",
"end\n",
"tsp_check_2(answer) = answer_checker(answer, 2)\n",
"tsp_check_3(answer) = answer_checker(answer, \"d\")\n",
"tsp_check_4(answer) = answer_checker(answer, \"a\")"
]
},
{
"cell_type": "markdown",
"id": "e1d637cb",
"metadata": {},
"source": [
"## The traveling sales person (TSP) problem\n",
@@ -36,22 +66,21 @@
"\n",
"### Problem statement\n",
"\n",
"- Given a graph $G$ with a distance table $C$ and an initial node (i.e. a city) in the graph\n",
"- Compute the shortest route that visits all cities exactly once, without returning to the initial city.\n"
"Given a graph $G$ with a distance table $C$ and an initial node (i.e. a city) in the graph, compute the shortest route that visits all cities exactly once, without returning to the initial city."
]
},
{
"attachments": {
"g22650.png": {
"image/png": "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 truncated
"fig-tsp-intro.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "dad0547d",
"id": "bf3dd0e6",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g22650.png\" align=\"left\" width=\"450\"/>\n",
"<img src=\"attachment:fig-tsp-intro.png\" align=\"left\" width=\"450\"/>\n",
"</div>"
]
},
@@ -60,12 +89,11 @@
"id": "c303dddf",
"metadata": {},
"source": [
"### Branch and bound algorithm\n",
"### Sequential algorithm (branch and bound)\n",
"\n",
"- The root is the initial city\n",
"- The children of a node are the neighbor cities not visited so-far\n",
"- **We sort the children using the nearest city first heuristic**\n",
"- A node will be a leaf of the tree when all neighbor cities are already visited\n"
"The sequential algorithm finds a shortest path by traversing the paths tree of the problem. The root of this tree is the initial city. The children of each node in the graph are the neighbour cities that have not been visited on the path so far. When all neighbour cities are already visited, the city becomes a leaf node in the tree.\n",
"\n",
"The possile solutions of the problem are the paths from the root of the tree to a leaf node. Note that we assume the children are sorted using the **nearest city first heuristic**. This allows to quickly find a minimum bound for the distance which will be used to prune the remaining paths (see next section). "
]
},
{
@@ -88,53 +116,68 @@
"id": "9da5f5ae",
"metadata": {},
"source": [
"- Number of possible paths might be up to O(N!)\n",
"- Visiting all paths is impractical (even in parallel)"
"Of course, visiting all paths in the tree is impractical for moderate and large numbers of cities. The number of possible paths might be up to $O(N!)$. Therefore, an essential part of the algorithm is to bound the search by remembering the current minimum distance. "
]
},
{
"cell_type": "markdown",
"id": "ecf89636",
"id": "8a40faff",
"metadata": {},
"source": [
"### Pruning the search tree\n"
]
},
{
"cell_type": "markdown",
"id": "239b7362",
"metadata": {},
"source": [
"- Only 3 out of 6 routes need to be visited"
"### Pruning the search tree\n",
"\n",
"The algorithm keeps track of the best solution of all paths visited so far. This allows to skip searching paths that already exceed this value. \n",
"\n",
"For example, in the following graph only 3 out of 6 possible routes need to be visted when we cut off the search after the minimum distance is exceeded. (The grey nodes are the ones we don't visit because the minimum distance had been exceeded at the previous node already.)"
]
},
{
"attachments": {
"g23181.png": {
"image/png": "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 truncated
"fig-tsp-pruning.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "d8218eaf",
"id": "ecf89636",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g23181.png\" align=\"left\" width=\"300\"/>\n",
"<img src=\"attachment:fig-tsp-pruning.png\" align=\"left\" width=\"700\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "f3c78a1d",
"metadata": {},
"source": [
"Note that it is not necessary that the graph be fully connected. Variations of this algorithm work for sparse graphs or directed graphs as well. \n",
"\n",
"In the previous example, the shortest route was also the leftmost path in the graph. Although it is more likely that the shortest route be found in the left part of the graph when using the nearest city first heuristic, the solution can be anywhere in the search tree."
]
},
{
"cell_type": "markdown",
"id": "85d771de",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b> Example:</b> Look at the following graph and its corresponding search tree. If $x\\leq 15$, the shortest route is the leftmost branch of the search tree. If $x > 16$, the route is situated on the right side of the search tree. \n",
"</div>"
]
},
{
"attachments": {
"g23549.png": {
"image/png": "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 truncated
"fig-tsp-question-1.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "0fbe1ee0",
"id": "d1df7878",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g23549.png\" align=\"left\" width=\"300\"/>\n",
"<img src=\"attachment:fig-tsp-question-1.png\" align=\"left\" width=\"800\"/>\n",
"</div>"
]
},
@@ -143,7 +186,9 @@
"id": "4fe017a4",
"metadata": {},
"source": [
"## Serial implementation"
"## Serial implementation\n",
"\n",
"Let's implement the serial algorithm. First, we sort the neighbours according to their distance. "
]
},
{
@@ -187,6 +232,14 @@
"]"
]
},
{
"cell_type": "markdown",
"id": "f769627c",
"metadata": {},
"source": [
"The data structure we will use for the connections table is a matrix of tuples of the form (destination, distance). The tuples are sorted by their distance in ascending order (per start city). "
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -197,11 +250,21 @@
"C_sorted = sort_neighbors(C)"
]
},
{
"cell_type": "markdown",
"id": "51ed8312",
"metadata": {},
"source": [
"The connections matrix can be indexed by a city. This returns a `Vector{Tuple}}` of all the destinations and their corresponding distances. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "00608e1d",
"metadata": {},
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"city = 3\n",
@@ -209,26 +272,34 @@
]
},
{
"attachments": {
"g25091.png": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABUcAAAHMCAYAAAD25xnyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAewgAAHsIBbtB1PgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N13uCRVmfjx751hBgaGIQ05CgIqGQRRQAxgQBF1F3FNGHH9gWtEMaC4BsCwiu6qKCYMu2KWRddFZUBERZLknDMIDMwMDMzM+f1xbi99q6q7b3dX1enw/TxPPbv3zr3nvI23qqvfOud9J5AkjZNVgWcAOwPbANsCmwBzgdUmj/uBJcBDwHXAVZPHn4BLgVB71JIkSZIkSZLUg02Bo4AzgUeIyc1ej7uBU4B/AubU+SIkSZIkSZIkaTpmAq8Afgssp7+EaKtjIXASsGNNr0mSJEmSJEmSWpoFvJG4Db6KhGjRsQL4BbBHDa9PkiRJkqTSTKQOQJJUmn2ALwPbT+Nn/w5cAlwN3Dj59UPAMmJd0rnAesS6pNsA2wErdxgzAN8DjgTu6jp6SZIkSZIkSerSPOCbxBWc7VZ3LgDeSdwG3+3DsVWB/YHjiMnUditJ7wfe3PvLkSRJkiRJkqTOdiWu/mzXQOmjwBYlzjkB7Av8gLjStNXcPwBWL3FeSZIkSZIkSQLgUFp3n7+LuEp0tYpj2IrYlKlV06ergK0rjkGSJEmSJEnSGHkHxQnJFcDJwPya49kF+FNBPAG4F9iz5ngkSZIkSZIkjaBPUpyEvBV4ZsK4ZgBHU7zV/kFg73ShSZIkSZIkSRp276E4Mfq/wLoJ42q2L3AnxY2adkgYlyRJkiRJkqQh9VqKO9KfDMxKGFeRrYBrycd6G7BZwrgkSZIkSZIkDZmdgIfJJxu/ROweP4jWBy4lH/OfGbxkriRJkiRJkqQBtBpwOfkk4/eJdT4H2UbADeRj/2zKoCRJkiRJkiQNhxPJJxd/y/CsvnwysJCp8a8AnpMyKEmSJEmSBnUrpiQp2p24Db15hehdwM7Epkf9mg88FdgOWKnp+4uA/yhh/IaDgVMy37sa2BFYWuI8kiRJkiRJkkbATOAC8isun93jePOAvYF3EJs4XUZxg6dG46SyfbVgnqMqmEeSJEmSJEnSkHsV+WTiST2O9YWCsdodVSRH502O2zzPQmDNCuaSJEmSJEmSNKQmgIuZmkj8O3EbfC++RfrkKMCrC+b6cEVzSZIkSZIkSRpCLyGfRPxAH+O1So4uB64EbqSe5OgEcFFmrnuAVSuaT5IkSZIkSdKQOZWpCcQH6G/7eSM5evvk2McABwLrTP77v1NPchTgEPJJ2ldXOJ8kSZIkSZKkIbEe8ChTk4fH9znmlsSan63UmRydAVyXme9/KpxPkiRJkqRCM1IHIEnKOQSYlfned/oc83rgwT7HKMsK4LuZ7+0HbJAgFkmSJEnSGDM5KkmD5wWZr88DLk8RSIW+S1wx2jAT2D9RLJIkSZKkMWVyVJIGy0rA3pnv/SJFIBW7jnzC99kpApEkSZIkjS+To5I0WJ5KvjboGSkCqcHvM18/J0kUkiRJkqSxZXJUkgbLjpmvlwDnpgikBgsyX28OrJkgDkmSJEnSmDI5KkmDZdvM11cDj6UIpAaXFXxvm9qjkCRJkiSNLZOjkjRYssnBq5JEUY/rySd+s8lhSZIkSZIqY3JUkgbLhpmvr08SRT0eA27JfC/7+iVJkiRJqozJUUkaLKtnvl6YJIr6ZF/f3CRRSJIkSZLGkslRSRos2eTooiRR1OehzNfzkkQhSZIkSRpLJkclabDMynz9aJIo6rM08/XsJFFIkiRJksaSyVFJGiyLM1+P+jbz7ErZ7EpSSZIkSZIqY3JUkgZLNjk46snR7DZ6k6OSJEmSpNqYHJWkwfJA5usNkkRRn/UyX496AypJkiRJ0gAxOSpJg+X6zNfbJImiHmsD8zPfuzZFIJIkSZKk8WRyVJIGy1WZr7dNEkU9il7b1bVHIUmSJEkaWyZHJWmwZJOjmwIbpQikBk/LfP0IcGOCOCRJkiRJY8rkqCQNlnOAkPnes1MEUoPnZr7+M7A8RSCSJEmSpPFkclSSBssdwJWZ7+2fIpCKzQaemfneGSkCkSRJkiSNL5OjkjR4fp/5+qXAnBSBVOhFwLzM97KvW5IkSZKkSpkclaTB85PM12sAL0kRSIVem/n6duBPKQKRJEmSJI0vk6OSNHguBO7LfO9tKQKpyKbElaPNfoL1RiVJkiRJkqSx9QTgBGARsSlT9tirwrn/PTPXbRXO9SXyr20xcCKwTYXzSpIkSZIkSRowuwInA49RnBRtHP/T5zxXANe1OBZm5lrW5mevA57VYwwbA0to/RqXA6cCT+9xfEmSJEmSJEkDbgaxjuiZtE+IZo+D+pjzkS7nancc0GMM/9XFHAuAFwMTPc4lSZIkSZIkaYDMBl4HXEbn5OBl5FeT3gis1uPcqZOj+xWMk12xWnRcA7wDmNPDnJIkSZIkSZISW4OY4LuNzsnAs4EDiSsmP1nw7yf1GEPK5OhawA2ZMZYBOwN7E7fSr+gw513AMcA6Xc4tSZIkSZIkKYEtad9kqXEsJdYd3T7z+3OINT6zP/+6GmIvywTwc/Kv4fOZn9ua+N/q4YKfbT4eIf632raG2CVJkiRJkiR1aTem12RpITEhuEmbsfYnNipq/r3FwDMqir1sx5F/3dcB81r8/PrEFaJ/L/i95qPRvGlY/jtIkiRJkiRJI2sGcTv86XTeln4D8H7idvvp+FTBGA8AO5UXfiX+H/m4HwX2nMbvzgUOA64uGCN7nEdcTTuz3PAlSZIkSZIktbMyMTF3OZ2TeBdM/uxKXc6xEnBWwXh3Arv0/Qqq8W6K64i+vctxGknnPxWMlT2uJdZ2XbX/8CVJkiRJkiS1Mp+4+rNTk6UVxNWkB/Y53zoUJ2AXAs/tc+wyzQA+Q/F/ixP6HHu6zZvuJm7Nn9/nfJIkSZIkSZKaNJosLWZ6TZa2K3HujYEbC+ZaRkwGzihxrl7MB35N8X+P/6S8+BrNm5a0mCvbvOlJJc0rSZIkSZIkjaVGk6VltE/IPUBM3G1cURxPpLiDfQB+Azyhonk7OZDWq2h/AMyuYM71iEnhe1vMm23etFcFMUiSJEmSJEkjqVHv8mw617u8nljvcrUa4toAuLBFHEuADwNzaogD4kraX7aIJQCfp/oVrasRmzdd1SYOmzdJkiRJkiRJ09BosnQFnZNt59Nbk6V+zQNOaRPXHcB7iV3fq7AN8C1i9/mi+R8G3lrR3K00ktnntIip+bgOmzdJkiRJkiRJ/2dd4jbte5jeNu39kkQ51duIich22/y/AexL/ys45wGHAr8j/jdoNedVwM59ztWvvYnJ405lEO4BjgM2ShPmqAsTENaF8BQIz4TwEgjPhvBkCK7elSRJkiRJGgBbMb0mS40GP09JE2ZL2wK/pfNqyb8DPwGOAJ4FbNhmzJWIjY8OBD5GLC3QapVo41gKfIp6SgtM1xPprnnTk9OEOUrCcyB8GMJpEP4OIbQ4FkH4JYQXpY5YkiRJkiRpHHXbZGnQVxceQutmTa2ORcRGSlcSSwRcB9xN50Ro9jiNwe4K323zpkFYFTykwuI2CdFWx6/jClNJkiRJkiRVqVGX8o90Tvg16lIO0krITmYABwOX0V1ys5djBTGRuEctr6wcjXqyV9L59TWaN9VdT3bI5ZKjSyFcCeGvEP4C4RoIywsSpJdCWDN19JIkSZIkSaNo3JJiE8Azga8TV76WmRS9AvgQsHltr6Z83STJr2f4kuQJhbuJW+rfBWF7CmuLhrUn//3+TIL0xPrjlSRJkiRJGl1up46J4WcDHycmAxfRXTL0duCnxFqlg1ZvtQyjVl4hsdDFQ4WwPYSHmpKjj0BYo7rYJEmSJEmSxoONeNrbFHgucYXsl8n/d3klsDswTomq6TbmWspgNuYaUuG4zOrRF6aOSJIkSZIkaVjtDZxC51WAdwPH0b5j+7h4Mfn/PsNcUqBf6wLvJ66Y7VRz9XTi9nz1LLwokxx9Q+qIJEmSJEmShkmjfuQ5dN4ifi2xfuSqSSIdTCZHizXq1F5B57+r8xn+OrWJhBdkkqOHpI5IkiRJkiSVKqwKYWMIG0JYJXU0I2QucBhwFZ2TV40mSwXNYcaeydH2Gsn3s+n8d2bzpq6FD2eSo09MHZEkSZIkSepL2BLC4RB+BuHGzAf/AOEmCN+fXDE1I3W0Q6jRZOnvtE9UNZos7ZUkyuFhcnT6ptu8aSGxfunGacIcFmETCPc0XRt/lzoiSZIkSZLUs/CPEP5UkAxtd5wLwcYu07M13TVZelKaMIeOydHubUl3zZu2SxPmoApzILwGwi1N18J7IGyTOjJJkiRJktSzcGqbJOgyCI+1+LeFEPZIHf0A25u4AnQF7RNRdxNXlM5PEuXwMjnau/nE5k230f5vc0ybN4V1IJzedJwJ4VIISzPXwL9C8GGGJEmSJEnDbUpy9AYIn4LwPAhNybqwCYQjINyWSQ7cCWHNdLEPnEadxz/RPukUsMlSv0yO9q/RvOlyOv+9XsDYNG8KG3VYOX8HhFdDmEgdqSRJ0pjZBHgu8DbgQ8BxwJeBr07+/x8GDgf2BzYHvF+TJE1HOBXCAgj70bGWaJgP4aJMouATtYQ52OYSE5030jnJdDZwMDZZ6pfJ0fI0kvqn0/nv9wbiqtMRfijSMTkaJlfUnwxhg9TRSpIkjbDtgXcCvwQeoPO9avZ4EDgNeC+wS82xS5KGR9iiy5/fOrO99JpKwhoO69Ndk6WnJ4lyNJkcrcauxHqjj9H+b7rRvGmTNGFWKaw8+bCocRwA4VAIJ7RYPW9tVkmSpPJsSExmXkz3ydBOx5XEFaeb1fZqJEmjKvxPJkGwWuqIarYNMTH0MO3ffB8mJpq2TRPmSDM5Wq0nEP/GF9H+b7zRvGn7NGHWLcyC8FEIK5quf9dBWD11ZJIkSUOuLine truncated
}
},
"cell_type": "markdown",
"id": "7384a305",
"id": "44025bd5",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:g25091.png\" align=\"left\" width=\"525\"/>\n",
"</div>"
"### Loop over all paths"
]
},
{
"cell_type": "markdown",
"id": "4f8cf018",
"id": "6c91a99f",
"metadata": {},
"source": [
"### Loop over all paths"
"Next, we write an algorithm that traverses the whole search tree and prints all the possible paths. The tree is traversed in depth-first order. Before we go to a neighbouring city, we also have to verify that it has not been visited on this path yet. If we reach a leaf node, we print the complete path and continue searching. "
]
},
{
"attachments": {
"fig-tsp-output-1.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "987a0273",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig-tsp-output-1.png\" align=\"left\" width=\"600\"/>\n",
"</div>"
]
},
{
@@ -238,29 +309,30 @@
"metadata": {},
"outputs": [],
"source": [
"function visital_all_paths(C_sorted,city)\n",
"function visit_all_paths(C_sorted,city)\n",
" # Initialize path\n",
" num_cities = length(C_sorted)\n",
" path=zeros(Int,num_cities)\n",
" hops = 1\n",
" path[hops] = city\n",
" visital_all_paths_recursive!(C_sorted,hops,path)\n",
" visit_all_paths_recursive!(C_sorted,hops,path)\n",
"end\n",
"function visital_all_paths_recursive!(C_sorted,hops,path)\n",
"function visit_all_paths_recursive!(C_sorted,hops,path)\n",
" num_cities = length(C_sorted)\n",
" if hops != num_cities\n",
" city = path[hops]\n",
" next_hops = hops + 1\n",
" connections = C_sorted[city]\n",
" for (next_city,distance_increment) in connections\n",
" # Check if next_city is already on path\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",
" visit_all_paths_recursive!(C_sorted,next_hops,path)\n",
" end\n",
" end\n",
" return nothing\n",
" else\n",
" #@show path\n",
" println(path)\n",
" return nothing\n",
" end\n",
@@ -275,32 +347,32 @@
"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>"
"visit_all_paths(C_sorted,city)"
]
},
{
"cell_type": "markdown",
"id": "65e654df",
"id": "0f68093d",
"metadata": {},
"source": [
"### Serial implementation without pruning\n",
"\n",
"- Now, we add the computation of the minimum distance"
"Now, we add the computation of the minimum distance. At each leaf node, we update the minimum distance. Furthermore, as we add another node to our path, we update the distance of the current path. That makes it necessary to include two more parameters in our recursive algorithm: `distance`, the distance of the current path, and `min_distance`, the best minimum distance found so far. "
]
},
{
"attachments": {
"fig-tsp-output-2.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "881076fa",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig-tsp-output-2.png\" align=\"left\" width=\"600\"/>\n",
"</div>"
]
},
{
@@ -328,6 +400,7 @@
" for (next_city,distance_increment) in connections\n",
" already_visited = (next_city in view(path,1:hops))\n",
" if ! already_visited\n",
" # Add new city to path\n",
" next_distance = distance + distance_increment\n",
" path[next_hops] = next_city\n",
" min_distance = tsp_serial_no_prune_recursive!(\n",
@@ -336,6 +409,7 @@
" end\n",
" return min_distance\n",
" else\n",
" # Set new minimum distance in leaf nodes\n",
" min_distance = min(distance,min_distance)\n",
" #@show path, distance, min_distance\n",
" return min_distance\n",
@@ -356,12 +430,27 @@
},
{
"cell_type": "markdown",
"id": "3c160cf9",
"id": "cb9b8353",
"metadata": {},
"source": [
"### Final serial implementation\n",
"\n",
"- Now, we add pruning"
"Finally, we add the pruning to our algorithm. Anytime the current distance exceeds the minimum distance, the search in this path is aborted and continued with another path. "
]
},
{
"attachments": {
"fig-tsp-output-3.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "3c160cf9",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:fig-tsp-output-3.png\" align=\"left\" width=\"600\"/>\n",
"</div>"
]
},
{
@@ -381,6 +470,7 @@
" 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",
" # Prune this path if its distance is too high already\n",
" if distance >= min_distance\n",
" return min_distance\n",
" end\n",
@@ -392,6 +482,7 @@
" for (next_city,distance_increment) in connections\n",
" already_visited = (next_city in view(path,1:hops))\n",
" if ! already_visited\n",
" # Add city to path \n",
" next_distance = distance + distance_increment\n",
" path[next_hops] = next_city\n",
" min_distance = tsp_serial_recursive!(\n",
@@ -400,6 +491,7 @@
" end\n",
" return min_distance\n",
" else\n",
" # Set new minimum distance in leaf nodes\n",
" min_distance = min(distance,min_distance)\n",
" #@show path, distance, min_distance\n",
" return min_distance\n",
@@ -423,7 +515,8 @@
"id": "7f0a5d5c",
"metadata": {},
"source": [
"### Performance"
"### Performance\n",
"Let's have a look at how well our code performs. In the following block, we create another random matrix and time the execution for both versions with and without pruning. "
]
},
{
@@ -433,7 +526,7 @@
"metadata": {},
"outputs": [],
"source": [
"n = 12 # It is safe to test up to 12\n",
"n = 12 # It is safe to test up to n=12\n",
"using Random\n",
"using Test\n",
"Random.seed!(1)\n",
@@ -445,12 +538,20 @@
"@test min_no_prune == min_prune"
]
},
{
"cell_type": "markdown",
"id": "6088ddc9",
"metadata": {},
"source": [
"You can observe that, especially for larger numbers of cities (n=11 or n=12), the performance of the algorithm with pruning is much better than the performance of the algorithm without pruning. "
]
},
{
"cell_type": "markdown",
"id": "733ce76e",
"metadata": {},
"source": [
"## Parallel implementation"
"## Parallel algorithm"
]
},
{
@@ -458,7 +559,8 @@
"id": "c6375465",
"metadata": {},
"source": [
"### Where can we extract parallelism ?"
"### Where can we extract parallelism ?\n",
"Unlike the previous algorithms we studied, in this problem we don't know beforehand how much work is performed since we don't know where the pruning cuts off part of the search tree. Still, we want to divide the workload among multiple processes to enhance the performance. "
]
},
{
@@ -483,8 +585,7 @@
"source": [
"### Option 1\n",
"\n",
"- We assign a branch to each worker\n",
"- Pros? Cons?\n"
"The first idea how to parallelize the TSP algorithm is to assign a branch of our search tree to each process. However, as mentioned in an earlier section, the number of branches in the search tree can be up to $O(N!)$. This would require an unfeasibly large amount of proecesses which each do only very little work. "
]
},
{
@@ -508,8 +609,7 @@
"metadata": {},
"source": [
"### Option 2\n",
"- We assign a fixed number of branches to each worker in advance\n",
"- Pros? Cons?"
"Instead of assigning one branch per worker, we can assign a fixed number of branches to each worker. This way, each worker can perform the pruning within their own subtree and less workers are needed. \n"
]
},
{
@@ -527,15 +627,27 @@
"</div>"
]
},
{
"cell_type": "markdown",
"id": "e3af7def",
"metadata": {},
"source": [
"### Performance issues\n",
"\n",
"#### Load balancing\n",
"However, this approach has a problem with load balancing. Since we don't know beforehand how much pruning can be done in each subtree, some workers might end up doing less work than others. This uneven distribution of workload leads to some workers being idle, which impairs the speedup. \n",
"\n",
"#### Search overhead \n",
"Another disadvantage of this kind of parallel search is that the pruning is now less effective. The workers each run their own version of the search algorithm and keep track of their local minimum distances. This means that less nodes will be pruned in the parallel version than in the serial version. This is called **search overhead**."
]
},
{
"cell_type": "markdown",
"id": "d9edf5c1",
"metadata": {},
"source": [
"<div>\n",
" <br>\n",
" <br>\n",
" <br>\n",
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> How many nodes are pruned in total when we assign two branches to each worker? Look at the illustration below.\n",
"</div>"
]
},
@@ -555,49 +667,116 @@
]
},
{
"cell_type": "markdown",
"id": "7d340c63",
"cell_type": "code",
"execution_count": null,
"id": "95e952af",
"metadata": {},
"outputs": [],
"source": [
"### Main performance issues\n",
"\n",
"- Dynamic load imbalance\n",
"- Search overhead"
"answer = -1 # Replace with any integer value \n",
"tsp_check_2(answer)"
]
},
{
"cell_type": "markdown",
"id": "c6d51e00",
"id": "d0bc4fdd",
"metadata": {},
"source": [
"### Dynamic load balancing with replicated workers model\n",
"In this example, the parallel algorithm prunes less nodes than the serial version because not all workers are able to use the global minimum distance as a pruning bound."
]
},
{
"cell_type": "markdown",
"id": "95643cd8",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
"<b>Question:</b> The previous example described positive search overhead. There is also negative search overhead, resulting in superlinear speedups. Can there be negative search overhead in this parallel TSP algorithm? (Provided the workers communicate the minimum distance with each other)\n",
"</div>\n",
"\n",
"- The coordinator searches up to a certain depth in the tree\n",
"- When the maximum depth is reached, the coordinator delegates the search to a worker\n",
"- Worker processes repeatedly get work and execute it\n"
" a) No, because we use the nearest city first heuristic. \n",
" b) No, because each worker has to search the whole subtree before the algorithm completes. \n",
" c) Yes, because the parallel algorithm does not need to search the whole search tree.\n",
" d) Yes, because the global minimum distance can be found more quickly, enabling the parallel version to do more pruning."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fff58498",
"metadata": {},
"outputs": [],
"source": [
"answer = \"x\" # Replace x with a,b,c or d\n",
"tsp_check_3(answer)"
]
},
{
"cell_type": "markdown",
"id": "6190b00a",
"metadata": {},
"source": [
"### Option 3: Dynamic load balancing with replicated workers model\n",
"In our parallel implementation, we will use a coordinator process and several worker processes. The coordinator process (or _master_) searches the tree up to a certain maximum depth _maxhops_. When _maxhops_ is reached, the coordinator creates a job and delegates it to a worker. The workers repeatedly get work from the master and execute it. This is an example of **dynamic load balancing**: the load is distributed among the workers during runtime."
]
},
{
"attachments": {
"Screenshot%20from%202023-09-25%2013-03-57.png": {
"image/png": "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 truncated
"fig-tsp-master-worker-2.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "a8f431d1",
"id": "c6d51e00",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:Screenshot%20from%202023-09-25%2013-03-57.png\" align=\"left\" width=\"600\"/>\n",
"<img src=\"attachment:fig-tsp-master-worker-2.png\" align=\"left\" width=\"600\"/>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "497bad13",
"metadata": {},
"source": [
"This avoids the performance issues of the previous approach: the workers are not idle since they get new work every time they finish a job. To avoid the search overhead, it is also important that the workers communicate the minimum distance each time they update their local minimum distance. "
]
},
{
"cell_type": "markdown",
"id": "81219a27",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-success\">\n",
" <b>Question:</b> To find the right <i> maxhops </i> level is a tradeoff between...\n",
"</div>\n",
" \n",
" a) Communication overhead (large maxhops) and load imbalance (small maxhops). \n",
" b) Search overhead (large maxhops) and load imbalance (small maxhops). \n",
" c) the number of workers (large maxhops) and the job size (small maxhops). \n",
" d) buffer for the job queue (large maxhops) and idle time of the coordinator process (small maxhops)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0cf1ec88",
"metadata": {},
"outputs": [],
"source": [
"answer=\"x\" #Replace x with a,b,c, or d\n",
"tsp_check_4(answer)"
]
},
{
"cell_type": "markdown",
"id": "5e4fdbe1",
"metadata": {},
"source": [
"### Code"
"## Implementation of the parallel algorithm \n",
"\n",
"First, let's add our worker processes. "
]
},
{
@@ -629,7 +808,7 @@
"source": [
"### Visit paths in parallel\n",
"\n",
"- We follow a produce-consumer model using a remote channel"
"Next we will write a simplified version of the algorithm which visits all paths in parallel. The communication between the workers and the coordinator is implemented using a `RemoteChannel`. The coordinator calls the function `generate_jobs` which recursively traverses the search tree until _maxhops_ is reached. Then, it copies the current path to the channel. The workers repeatedly take jobs from the channel until the channel is empty. The workers receive the path from the job and continue the search. When they reach a leaf node in the search tree, they print the path."
]
},
{
@@ -729,24 +908,24 @@
},
{
"cell_type": "markdown",
"id": "d85c8e7c",
"id": "d3bbf609",
"metadata": {},
"source": [
"### How to track the global minimum distance?\n"
"### How to track the global minimum distance?"
]
},
{
"attachments": {
"Screenshot%20from%202023-09-25%2013-03-57.png": {
"image/png": "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 truncated
"fig-tsp-master-worker.png": {
"image/png": "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 truncated
}
},
"cell_type": "markdown",
"id": "973ba501",
"id": "d85c8e7c",
"metadata": {},
"source": [
"<div>\n",
"<img src=\"attachment:Screenshot%20from%202023-09-25%2013-03-57.png\" align=\"left\" width=\"600\"/>\n",
"<img src=\"attachment:fig-tsp-master-worker.png\" align=\"left\" width=\"600\"/>\n",
"</div>"
]
},
@@ -758,7 +937,7 @@
"\n",
"### Simplified example\n",
"\n",
"- Each worker generates a random value and updates a globally shared minimum"
"We will demonstrate how the workers communicate the minimum distance with each other with a short example. Each worker generates a random value and updates a globally shared minimum. The variable for the global minimum is stored in a `RemoteChannel`. The buffer size of the channel is 1, such that only one channel can take and put new values to the channel at a time."
]
},
{
@@ -777,8 +956,8 @@
" 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",
" min_distance = min(distance,min_distance)\n",
" put!(min_distance_chnl,min_distance)\n",
" end\n",
"end\n",
@@ -792,7 +971,8 @@
"id": "1fabefcb",
"metadata": {},
"source": [
"### Final parallel implementation"
"### Final parallel implementation\n",
"Finally, we add the communication of the minimum distance to the first simplified version. Like in the serial implementation, the workers stop the search if the distance of their current path exceeds the global minimum distance. In total, we need two channels: one to communicate the jobs and one to communicate the minimum distance. "
]
},
{
@@ -901,6 +1081,15 @@
"min_distance = tsp_dist(C_sorted,city,max_hops)"
]
},
{
"cell_type": "markdown",
"id": "48b54da1",
"metadata": {},
"source": [
"## Testing the parallel implementation\n",
"Next, we will test the correctness and performance of our parallel implementation by comparing the results of the parallel algorithm to the results of the serial algorithm for multiple problem instances. "
]
},
{
"cell_type": "code",
"execution_count": null,
@@ -927,17 +1116,21 @@
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "edbea7ac",
"cell_type": "markdown",
"id": "c789dc7a",
"metadata": {},
"outputs": [],
"source": []
"source": [
"# License\n",
"\n",
"\n",
"\n",
"This notebook is part of the course [Programming Large Scale Parallel Systems](https://www.francescverdugo.com/XM_40017) at Vrije Universiteit Amsterdam and may be used under a [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.9.0",
"display_name": "Julia 1.9.1",
"language": "julia",
"name": "julia-1.9"
},
@@ -945,7 +1138,7 @@
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.9.0"
"version": "1.9.1"
}
},
"nbformat": 4,