diff --git a/dev/getting_started_with_julia/index.html b/dev/getting_started_with_julia/index.html index 01fb2af..fcf1549 100644 --- a/dev/getting_started_with_julia/index.html +++ b/dev/getting_started_with_julia/index.html @@ -14,4 +14,4 @@ julia> DataFrame(a=[1,2],b=[3,4])

You should get an error or a BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"

Copy the contents of previous code block into a file called Project.toml and place it in an empty folder named newproject. It is important that the file is named Project.toml. You can create a new folder from the REPL with

julia> mkdir("newproject")

To install all the packages registered in this file you need to activate the folder containing your Project.toml file

(@v1.8) pkg> activate newproject

and then instantiating it

(newproject) pkg> instantiate

The instantiate command will download and install all listed packages and their dependencies in just one click.

Getting help in package mode

You can get help about a particular package operator by writing help in front of it

(@v1.8) pkg> help activate

You can get an overview of all package commands by typing help alone

(@v1.8) pkg> help

Package operations in Julia code

In some situations it is required to use package commands in Julia code, e.g., to automatize installation and deployment of Julia applications. This can be done using the Pkg package. For instance

julia> using Pkg
-julia> Pkg.status()

is equivalent to calling status in package mode.

(@v1.8) pkg> status

Conclusion

We have learned the basics of how to work with Julia. If you want to further dig into the topics we have covered here, you can take a look at the following links:

+julia> Pkg.status()

is equivalent to calling status in package mode.

(@v1.8) pkg> status

Conclusion

We have learned the basics of how to work with Julia. If you want to further dig into the topics we have covered here, you can take a look at the following links:

diff --git a/dev/index.html b/dev/index.html index 08e83b4..265ba37 100644 --- a/dev/index.html +++ b/dev/index.html @@ -2,4 +2,4 @@ Home · XM_40017

Programming Large-Scale Parallel Systems (XM_40017)

Welcome to the interactive lecture notes of the Programming Large-Scale Parallel Systems course at VU Amsterdam!

What

This page contains part of the course material of the Programming Large-Scale Parallel Systems course at VU Amsterdam. We provide several lecture notes in jupyter notebook format, which will help you to learn how to design, analyze, and program parallel algorithms on multi-node computing systems. Further information about the course is found in the study guide (click here) and our Canvas page (for registered students).

Note

This page contains only a part of the course material. The rest is available on Canvas. In particular, the lecture notes in this public webpage do not fully cover all topics in the final exam.

How to use this page

You have two main ways of running the notebooks:

  • Download the notebooks and run them locally on your computer (recommended)
  • Run the notebooks on the cloud via mybinder.org (high startup time).

You also have the static version of the notebooks displayed in this webpage for quick reference. At each notebook page you will find a green box with links to download the notebook or to open in on mybinder.

How to run the notebooks locally

To run a notebook locally follow these steps:

  • Install Julia (if not done already). More information in Getting started.
  • Download the notebook.
  • Launch Julia. More information in Getting started.
  • Execute these commands in the Julia command line:
julia> using Pkg
 julia> Pkg.add("IJulia")
 julia> using IJulia
-julia> notebook()
  • These commands will open a jupyter in your web browser. Navigate in jupyter to the notebook file you have downloaded and open it.

Authors

This material is created by Francesc Verdugo with the help of Gelieza Kötterheinrich. Part of the notebooks are based on the course slides by Henri Bal.

License

All material on this page that is original to this course may be used under a CC BY 4.0 license.

Acknowledgment

This page was created with the support of the Faculty of Science of Vrije Universiteit Amsterdam in the framework of the project "Interactive lecture notes and exercises for the Programming Large-Scale Parallel Systems course" funded by the "Innovation budget BETA 2023 Studievoorschotmiddelen (SVM) towards Activated Blended Learning".

+julia> notebook()

Authors

This material is created by Francesc Verdugo with the help of Gelieza Kötterheinrich. Part of the notebooks are based on the course slides by Henri Bal.

License

All material on this page that is original to this course may be used under a CC BY 4.0 license.

Acknowledgment

This page was created with the support of the Faculty of Science of Vrije Universiteit Amsterdam in the framework of the project "Interactive lecture notes and exercises for the Programming Large-Scale Parallel Systems course" funded by the "Innovation budget BETA 2023 Studievoorschotmiddelen (SVM) towards Activated Blended Learning".

diff --git a/dev/notebook-html/solutions.html b/dev/notebook-html/solutions.html index 196dff6..50b0a36 100644 --- a/dev/notebook-html/solutions.html +++ b/dev/notebook-html/solutions.html @@ -7776,6 +7776,209 @@ a.anchor-link { +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
diff --git a/dev/notebooks/jacobi_2D/index.html b/dev/notebooks/jacobi_2D/index.html index 4c607a0..f6c3c9b 100644 --- a/dev/notebooks/jacobi_2D/index.html +++ b/dev/notebooks/jacobi_2D/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/jacobi_method/index.html b/dev/notebooks/jacobi_method/index.html index b1ddb98..a9462b5 100644 --- a/dev/notebooks/jacobi_method/index.html +++ b/dev/notebooks/jacobi_method/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/julia_async/index.html b/dev/notebooks/julia_async/index.html index 0d401e8..fa7bdcb 100644 --- a/dev/notebooks/julia_async/index.html +++ b/dev/notebooks/julia_async/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/julia_basics/index.html b/dev/notebooks/julia_basics/index.html index 404fa1b..5d19e48 100644 --- a/dev/notebooks/julia_basics/index.html +++ b/dev/notebooks/julia_basics/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/julia_distributed/index.html b/dev/notebooks/julia_distributed/index.html index 3d6dae7..674cd92 100644 --- a/dev/notebooks/julia_distributed/index.html +++ b/dev/notebooks/julia_distributed/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/julia_intro/index.html b/dev/notebooks/julia_intro/index.html index 1ede87c..2bfa955 100644 --- a/dev/notebooks/julia_intro/index.html +++ b/dev/notebooks/julia_intro/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/julia_jacobi/index.html b/dev/notebooks/julia_jacobi/index.html index ed55715..bfc07e4 100644 --- a/dev/notebooks/julia_jacobi/index.html +++ b/dev/notebooks/julia_jacobi/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/julia_tutorial/index.html b/dev/notebooks/julia_tutorial/index.html index 8805fd7..e6da03b 100644 --- a/dev/notebooks/julia_tutorial/index.html +++ b/dev/notebooks/julia_tutorial/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/matrix_matrix/index.html b/dev/notebooks/matrix_matrix/index.html index 9964988..da2423c 100644 --- a/dev/notebooks/matrix_matrix/index.html +++ b/dev/notebooks/matrix_matrix/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/mpi_tutorial/index.html b/dev/notebooks/mpi_tutorial/index.html index a09e2d3..8d21c55 100644 --- a/dev/notebooks/mpi_tutorial/index.html +++ b/dev/notebooks/mpi_tutorial/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/notebook-hello/index.html b/dev/notebooks/notebook-hello/index.html index 4d7a3b8..658dfb1 100644 --- a/dev/notebooks/notebook-hello/index.html +++ b/dev/notebooks/notebook-hello/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/solutions.ipynb b/dev/notebooks/solutions.ipynb index 64b99de..779d2d7 100644 --- a/dev/notebooks/solutions.ipynb +++ b/dev/notebooks/solutions.ipynb @@ -291,6 +291,194 @@ "rmprocs(workers())" ] }, + { + "cell_type": "markdown", + "id": "19641daf", + "metadata": {}, + "source": [ + "## TSP Exercise: Measure search overhead" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f00557a0", + "metadata": {}, + "outputs": [], + "source": [ + "## TSP serial \n", + "function tsp_serial(connections,city)\n", + " num_cities = length(connections)\n", + " path=zeros(Int,num_cities)\n", + " hops = 1\n", + " path[hops] = city\n", + " min_path = zeros(Int, num_cities)\n", + " current_distance = 0\n", + " min_distance = typemax(Int)\n", + " # Collect search time \n", + " search_time = @elapsed min_path, min_distance = tsp_serial_impl(connections,hops,path,current_distance, min_path, min_distance)\n", + " (;path=min_path,distance=min_distance, search_time)\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "30784da2", + "metadata": {}, + "outputs": [], + "source": [ + "## TSP distributed\n", + "@everywhere function tsp_dist_impl(wait_time, connections,hops,path,current_distance,min_dist_chnl, max_hops,jobs_chnl,ftr_result)\n", + " num_cities = length(connections)\n", + " if hops == num_cities\n", + " min_distance = fetch(min_dist_chnl)\n", + " if current_distance < min_distance\n", + " take!(min_dist_chnl)\n", + " # Collect wait time to substract from overall search time \n", + " if ftr_result !== nothing\n", + " wait_time += @elapsed @spawnat 1 begin\n", + " result = fetch(ftr_result)\n", + " result.path .= path\n", + " result.min_distance_ref[] = current_distance\n", + " end |> wait\n", + " end\n", + " put!(min_dist_chnl, current_distance)\n", + " end\n", + " elseif hops <= max_hops\n", + " current_city = path[hops]\n", + " next_hops = hops + 1\n", + " for (next_city,distance_increment) in connections[current_city]\n", + " if !visited(next_city,hops,path)\n", + " path[next_hops] = next_city\n", + " next_distance = current_distance + distance_increment\n", + " # Collect wait time because fetch may block\n", + " wait_time += @elapsed min_distance = fetch(min_dist_chnl)\n", + " if next_distance < min_distance\n", + " tsp_dist_impl(wait_time, connections,next_hops,path,next_distance,min_dist_chnl,max_hops,jobs_chnl,ftr_result)\n", + " end\n", + " end\n", + " end \n", + " else\n", + " # Collect communication time and add to wait time\n", + " wait_time += @elapsed if jobs_chnl !== nothing \n", + " path_copy = copy(path) \n", + " put!(jobs_chnl,(;hops,path=path_copy,current_distance))\n", + " end\n", + " end\n", + " # Return wait time\n", + " wait_time\n", + "end\n", + "\n", + "function tsp_dist(connections,city)\n", + " max_hops = 2\n", + " num_cities = length(connections)\n", + " path=zeros(Int,num_cities)\n", + " result_path=zeros(Int, num_cities)\n", + " wait_time = 0\n", + " search_time = 0\n", + " hops = 1\n", + " path[hops] = city\n", + " current_distance = 0\n", + " min_distance = typemax(Int)\n", + " jobs_chnl = RemoteChannel(()->Channel{Any}(10))\n", + " min_dist_chnl = RemoteChannel(()->Channel{Int}(1))\n", + " put!(min_dist_chnl, min_distance)\n", + " ftr_result = @spawnat 1 (;path=result_path,min_distance_ref=Ref(min_distance))\n", + " @async begin\n", + " # Collect search time from master process\n", + " search_time += @elapsed wait_time += tsp_dist_impl(wait_time,connections,hops,path,current_distance,min_dist_chnl,max_hops,jobs_chnl,nothing)\n", + " for w in workers()\n", + " put!(jobs_chnl,nothing)\n", + " end\n", + " end\n", + " @sync for w in workers()\n", + " @spawnat w begin\n", + " path = zeros(Int, num_cities)\n", + " max_hops = typemax(Int)\n", + " while true\n", + " job = take!(jobs_chnl)\n", + " if job == nothing\n", + " break\n", + " end\n", + " hops = job.hops\n", + " path = job.path \n", + " current_distance = job.current_distance\n", + " min_distance = fetch(min_dist_chnl)\n", + " if current_distance < min_distance\n", + " # Collect search time from worker processes \n", + " search_time += @elapsed wait_time += tsp_dist_impl(wait_time,connections,hops,path,current_distance,min_dist_chnl,max_hops,nothing,ftr_result)\n", + " end\n", + " end\n", + " end\n", + " end \n", + " result = fetch(ftr_result)\n", + " (;path = result.path, distance = result.min_distance_ref[], search_time, wait_time)\n", + "end\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "694de934", + "metadata": {}, + "outputs": [], + "source": [ + "using Distributed\n", + "using RandomMatrix\n", + "using Plots\n", + "\n", + "function generate_rand_connections(city_range, distance_range)\n", + " # generate random connections matrix \n", + " n_cities = rand(city_range)\n", + " matrix = randTriangular(distance_range, n_cities; Diag=false)\n", + "\n", + " connections = Array{Array{Tuple{Int64,Int64},1},1}(undef, n_cities)\n", + " for i in 1:n_cities\n", + " connections[i] = Array{Tuple{Int64,Int64},1}(undef, n_cities)\n", + " end\n", + " for i in 1:n_cities\n", + " for j in i:n_cities\n", + " distance = matrix[i,j]\n", + " connections[i][j] = (j,distance)\n", + " connections[j][i] = (i,distance)\n", + " end\n", + " end\n", + " return connections\n", + "end\n", + "\n", + "# Run once so compile times are not measured\n", + "distance_range = 1:100\n", + "connections = generate_rand_connections(4:4, distance_range)\n", + "tsp_dist(connections,1)\n", + "tsp_serial(connections,1)\n", + "\n", + "# Measure runtimes of serial and parallel algorithm\n", + "n_it = 5\n", + "city_ranges = [4:4, 6:6, 8:8, 10:10]\n", + "search_overhead = zeros(Float64, length(city_ranges), n_it )\n", + "for (i, n) in enumerate(city_ranges)\n", + " for k in 1:n_it\n", + " connections = generate_rand_connections(n, distance_range)\n", + " @show n, k\n", + " path_dist, distance_dist, search_time_dist, wait_time_dist = tsp_dist(connections,1)\n", + " path_serial, distance_serial, search_time_serial = tsp_serial(connections,1)\n", + " # Compute search overhead as difference between distributed program and serial program\n", + " # (without time spent communicating or waiting)\n", + " search_overhead[i, k] = search_time_dist - wait_time_dist - search_time_serial\n", + " end\n", + "end\n", + "\n", + "min_search_oh = minimum(search_overhead, dims=2)\n", + "city_sizes = [4,6,8,10]\n", + "plot(city_sizes, min_search_oh, yaxis=:log, seriestype=:scatter,legend=false)\n", + "plot!(city_sizes, min_search_oh, yaxis=:log, legend=false)\n", + "\n", + "xlabel!(\"Number of cities\")\n", + "ylabel!(\"Search overhead (s)\")\n", + "title!(\"Minimum search overhead for different problem sizes\")" + ] + }, { "cell_type": "markdown", "id": "47d88e7a", @@ -314,7 +502,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Julia 1.9.0", + "display_name": "Julia 1.9.1", "language": "julia", "name": "julia-1.9" }, @@ -322,7 +510,7 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.9.0" + "version": "1.9.1" } }, "nbformat": 4, diff --git a/dev/notebooks/solutions/index.html b/dev/notebooks/solutions/index.html index 34f7940..4490046 100644 --- a/dev/notebooks/solutions/index.html +++ b/dev/notebooks/solutions/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/notebooks/tsp/index.html b/dev/notebooks/tsp/index.html index eac638e..428f164 100644 --- a/dev/notebooks/tsp/index.html +++ b/dev/notebooks/tsp/index.html @@ -18,4 +18,4 @@ var myIframe = document.getElementById("notebook"); iFrameResize({log:true}, myIframe); }); - + diff --git a/dev/search/index.html b/dev/search/index.html index 27817c0..e6d8bff 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · XM_40017

Loading search...

    +Search · XM_40017

    Loading search...