From 97e771a75f92f5d540960b670b78e52cb7920d42 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Thu, 12 Sep 2024 17:50:26 +0200 Subject: [PATCH 1/3] Adding more solutions --- docs/src/solutions_for_all_notebooks.md | 125 ++++++++++++++++++++++++ notebooks/julia_mpi.ipynb | 1 - 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/docs/src/solutions_for_all_notebooks.md b/docs/src/solutions_for_all_notebooks.md index 2409ffc..c279b24 100644 --- a/docs/src/solutions_for_all_notebooks.md +++ b/docs/src/solutions_for_all_notebooks.md @@ -133,6 +133,60 @@ end ## MPI (Point-to-point) +### Exercise 1 + +```julia +function matmul_mpi_3!(C,A,B) + comm = MPI.COMM_WORLD + rank = MPI.Comm_rank(comm) + P = MPI.Comm_size(comm) + if rank == 0 + N = size(A,1) + myB = B + for dest in 1:(P-1) + MPI.Send(B,comm;dest) + end + else + source = 0 + status = MPI.Probe(comm,MPI.Status;source) + count = MPI.Get_count(status,eltype(B)) + N = Int(sqrt(count)) + myB = zeros(N,N) + MPI.Recv!(myB,comm;source) + end + L = div(N,P) + myA = zeros(L,N) + if rank == 0 + lb = L*rank+1 + ub = L*(rank+1) + myA[:,:] = view(A,lb:ub,:) + for dest in 1:(P-1) + lb = L*dest+1 + ub = L*(dest+1) + MPI.Send(view(A,lb:ub,:),comm;dest) + end + else + source = 0 + MPI.Recv!(myA,comm;source) + end + myC = myA*myB + if rank == 0 + lb = L*rank+1 + ub = L*(rank+1) + C[lb:ub,:] = myC + for source in 1:(P-1) + lb = L*source+1 + ub = L*(source+1) + MPI.Recv!(view(C,lb:ub,:),comm;source) + end + else + dest = 0 + MPI.Send(myC,comm;dest) + end + C +end +``` + ### Exercise 2 ```julia @@ -161,6 +215,77 @@ else MPI.Send(buffer,comm;dest,tag=0) end ``` +## MPI (collectives) + +### Exercise 1 + +```julia +function matmul_mpi_3!(C,A,B) + comm = MPI.COMM_WORLD + rank = MPI.Comm_rank(comm) + P = MPI.Comm_size(comm) + root = 0 + if rank == root + N = size(A,1) + Nref = Ref(N) + else + Nref = Ref(0) + end + MPI.Bcast!(Nref,comm;root) + N = Nref[] + if rank == root + myB = B + else + myB = zeros(N,N) + end + MPI.Bcast!(myB,comm;root) + L = div(N,P) + # Tricky part + # Scatter and gather work "row major" + # while Julia works "col major" + myAt = zeros(N,L) + At = collect(transpose(A)) + MPI.Scatter!(At,myAt,comm;root) + myCt = transpose(myB)*myAt + Ct = similar(C) + MPI.Gather!(myCt,Ct,comm;root) + C .= transpose(Ct) + C +end +``` + +This other solution uses a column partition instead of a row partition. +It is more natural to work with column partitions in Julia if possible since matrices are +in "col major" format. Note that we do not need all the auxiliary transposes anymore. + +```julia +function matmul_mpi_3_col!(C,A,B) + comm = MPI.COMM_WORLD + rank = MPI.Comm_rank(comm) + P = MPI.Comm_size(comm) + root = 0 + if rank == root + N = size(A,1) + Nref = Ref(N) + else + Nref = Ref(0) + end + MPI.Bcast!(Nref,comm;root) + N = Nref[] + if rank == root + myA = A + else + myA = zeros(N,N) + end + MPI.Bcast!(myA,comm;root) + L = div(N,P) + myB = zeros(N,L) + MPI.Scatter!(B,myB,comm;root) + myC = myA*myB + MPI.Gather!(myC,C,comm;root) + C +end +``` ## Jacobi method diff --git a/notebooks/julia_mpi.ipynb b/notebooks/julia_mpi.ipynb index cf5cb65..e218155 100644 --- a/notebooks/julia_mpi.ipynb +++ b/notebooks/julia_mpi.ipynb @@ -1535,7 +1535,6 @@ " end\n", "end\n", "testit(100)\n", - "end\n", "# ex1.jl (end)\n", "```" ] From f23deb153445a962652d5ec6e5a68d0b5f5972c0 Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Thu, 12 Sep 2024 17:52:30 +0200 Subject: [PATCH 2/3] minor --- docs/src/solutions_for_all_notebooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/solutions_for_all_notebooks.md b/docs/src/solutions_for_all_notebooks.md index c279b24..ca35702 100644 --- a/docs/src/solutions_for_all_notebooks.md +++ b/docs/src/solutions_for_all_notebooks.md @@ -259,7 +259,7 @@ It is more natural to work with column partitions in Julia if possible since mat in "col major" format. Note that we do not need all the auxiliary transposes anymore. ```julia -function matmul_mpi_3_col!(C,A,B) +function matmul_mpi_3!(C,A,B) comm = MPI.COMM_WORLD rank = MPI.Comm_rank(comm) P = MPI.Comm_size(comm) From 9a8783181de6170686b3aff794edd975f462a13c Mon Sep 17 00:00:00 2001 From: Francesc Verdugo Date: Thu, 12 Sep 2024 17:59:35 +0200 Subject: [PATCH 3/3] Minor --- docs/src/solutions_for_all_notebooks.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/solutions_for_all_notebooks.md b/docs/src/solutions_for_all_notebooks.md index ca35702..55d1831 100644 --- a/docs/src/solutions_for_all_notebooks.md +++ b/docs/src/solutions_for_all_notebooks.md @@ -241,8 +241,7 @@ function matmul_mpi_3!(C,A,B) MPI.Bcast!(myB,comm;root) L = div(N,P) # Tricky part - # Scatter and gather work "row major" - # while Julia works "col major" + # Julia works "col major" myAt = zeros(N,L) At = collect(transpose(A)) MPI.Scatter!(At,myAt,comm;root)