static void Main(string[] args) { using (new MPI.Environment(ref args)) { Intracommunicator comm = Communicator.world; int root = 0; string[] nums = new string[5]; if (comm.Rank == root) { nums[1] = "Chapter 1: MPI"; nums[2] = "Chapter 2: BitCoins"; nums[3] = "Chapter 3: MongoDB"; nums[4] = "Chapter 4: How to Make a Sandwich"; comm.Scatter(nums, root); } else { string value = comm.Scatter(nums, root); Console.WriteLine(comm.Rank + " was assigned " + value); } } }
public override void synchronize() { Intracommunicator localComm = mpi.localComm(this); int root = mpi.ranksOf(this, "distribute")[0]; double[,] a_local = localComm.Scatter <double[, ]>(root); double[,] b_local = localComm.Scatter <double[, ]>(root); int number_of_jobs = a_local.GetLength(0); int dim_num = a_local.GetLength(1); for (int i = 0; i < number_of_jobs; i++) { IIntegralCase <F> ic = (IIntegralCase <F>)data.createElement(); ic.dim_num = dim_num; for (int j = 0; j < dim_num; j++) { ic.a[j] = a_local[i, j]; ic.b[j] = b_local[i, j]; } } // data.a = limits[0]; // data.b = limits[1]; } // end activate method
static void Main(string[] args) { using (MPI.Environment environment = new MPI.Environment(ref args)) { if (args[4].Equals("*")) { args[4] = "0"; } SectorInfo sectorinfo = new SectorInfo() { RealMinimum = Convert.ToDouble(args[0]), ImgMinimum = Convert.ToDouble(args[1]), Delta = Convert.ToDouble(args[2]), FromX = Convert.ToInt32(args[3]), FromY = Convert.ToInt32(args[4]), Width = Convert.ToInt32(args[5]), Height = Convert.ToInt32(args[6]), MaxIterations = Convert.ToInt32(args[7]), MaxValue = Convert.ToInt32(args[8]) }; Intracommunicator comm = Communicator.world; if (comm.Rank == 0) { SectorInfo[] sectors = new SectorInfo[comm.Size]; for (int k = 0; k < sectors.Length; k++) { SectorInfo newsector = new SectorInfo() { RealMinimum = sectorinfo.RealMinimum, ImgMinimum = sectorinfo.ImgMinimum, Delta = sectorinfo.Delta, FromX = sectorinfo.FromX, FromY = sectorinfo.FromY + k * (sectorinfo.Height / comm.Size), Width = sectorinfo.Width, Height = sectorinfo.Height / comm.Size, MaxIterations = sectorinfo.MaxIterations, MaxValue = sectorinfo.MaxValue }; sectors[k] = newsector; } SectorInfo si = comm.Scatter(sectors); CalculateSector(args, si); } else { SectorInfo si = comm.Scatter <SectorInfo>(0); CalculateSector(args, si); } } }
static void Main(string[] args) { using (MPI.Environment environment = new MPI.Environment(ref args)) { Intracommunicator comm = Communicator.world; rank = Communicator.world.Rank; size = Communicator.world.Size; Communicator.world.Barrier(); found = false; if (comm.Rank == 0) { int[] numbers = new int[comm.Size]; for (int k = 0; k < numbers.Length; k++) { numbers[k] = k + 1; } int r = comm.Scatter(numbers); Console.WriteLine("Received {0} at {1}", r, comm.Rank); } else { int r = comm.Scatter <int>(0); Console.WriteLine("Received {0} at {1}", r, comm.Rank); } nvalues = 50 / size; i = rank * nvalues; inrange = ((i <= ((rank + 1) * nvalues - 1)) & (i >= rank * nvalues)); while (inrange) { int p = 0; if (numbers[i] == nrToSearch) { temp = 23; for (j = 0; j < size; ++j) { Communicator.world.Send <int>(temp, j, 1); } Console.WriteLine("Process: " + rank + "has found " + numbers[i] + " at global index " + i + "\n"); found = true; } ++i; inrange = (i <= ((rank + 1) * nvalues - 1) && i >= rank * nvalues); } if (!found) { Console.WriteLine("Process: " + rank + " stopped at global index " + (i - 1) + "\n"); } } }
static void Main(string[] args) { using (MPI.Environment environment = new MPI.Environment(ref args)) { Intracommunicator comm = Communicator.world; if (comm.Rank == 0) { int [] numbers = new int[comm.Size]; for (int k = 0; k < numbers.Length; k++) { numbers[k] = k * k; } int r = comm.Scatter(numbers); Console.WriteLine("Received {0} at {1}", r, comm.Rank); } else { int r = comm.Scatter <int>(0); Console.WriteLine("Received {0} at {1}", r, comm.Rank); } } }
public void Scatter <T>(T[] workPackages) { communicator.Scatter(workPackages); }
static void Main(string[] args) { using (new MPI.Environment(ref args)) { Intracommunicator world = Communicator.world; if (world.Rank == 0) { System.Console.Write("Testing scatter of integers..."); int[] ranks = new int[world.Size]; for (int i = 0; i < world.Size; ++i) { ranks[i] = i; } int myRank = world.Scatter(ranks, 0); Debug.Assert(myRank == 0); System.Console.WriteLine(" done."); System.Console.Write("Testing scatter of strings..."); string[] rankStrings = new string[world.Size]; for (int i = 0; i < world.Size; ++i) { rankStrings[i] = i.ToString(); } string myRankString = world.Scatter(rankStrings, 0); Debug.Assert(myRankString == world.Rank.ToString()); System.Console.WriteLine(" done."); } else { int myRank = world.Scatter <int>(null, 0); Debug.Assert(myRank == world.Rank); string myRankString = world.Scatter <string>(null, 0); Debug.Assert(myRankString == world.Rank.ToString()); } if (world.Rank == 0) { System.Console.Write("Testing Scatter of bools..."); bool[] odds = new bool[world.Size]; for (int i = 0; i < world.Size; ++i) { odds[i] = i % 2 == 1; } bool amIOdd = world.Scatter(odds, 0); Debug.Assert(!amIOdd); System.Console.WriteLine(" done."); } else { bool amIOdd = world.Scatter <bool>(null, 0); Debug.Assert(amIOdd == (world.Rank % 2 == 1)); } world.Barrier(); if (world.Rank == 0) { int size = world.Size; System.Console.Write("Testing ScatterFromFlattened of integers..."); int[] inRanks = new int[(size * size - size) / 2]; int[] outRanks = null; int[] counts = new int[size]; int p = 0; for (int i = 0; i < world.Size; ++i) { counts[i] = i; for (int j = 0; j < i; j++) { inRanks[p + j] = i; } p += i; } world.ScatterFromFlattened(inRanks, counts, 0, ref outRanks); Debug.Assert(outRanks.Length == 0); System.Console.WriteLine(" done."); } else { int[] outRanks = null; int[] counts = new int[world.Size]; for (int i = 0; i < world.Size; ++i) { counts[i] = i; } world.ScatterFromFlattened(null, counts, 0, ref outRanks); for (int i = 0; i < world.Rank; i++) { Debug.Assert(outRanks[i] == world.Rank); } } if (world.Rank == 0) { int size = world.Size; System.Console.Write("Testing ScatterFromFlattened of strings..."); string[] inRanks = new string[(size * size - size) / 2]; string[] outRanks = null; int[] counts = new int[size]; int p = 0; for (int i = 0; i < world.Size; ++i) { counts[i] = i; for (int j = 0; j < i; j++) { inRanks[p + j] = i.ToString(); } p += i; } world.ScatterFromFlattened(inRanks, counts, 0, ref outRanks); Debug.Assert(outRanks.Length == 0); System.Console.WriteLine(" done."); } else { string[] outRanks = null; int[] counts = new int[world.Size]; for (int i = 0; i < world.Size; ++i) { counts[i] = i; } world.ScatterFromFlattened(null, counts, 0, ref outRanks); for (int i = 0; i < world.Rank; i++) { Debug.Assert(outRanks[i] == world.Rank.ToString()); } } } }
public override void synchronize() { Intracommunicator localComm = mpi.localComm(this); int[] peers = mpi.ranksOf(this, "receive"); Console.Write("[]"); foreach (int p in peers) { Console.Write("," + p); } Console.WriteLine("]"); double[] a_input = data.a; double[] b_input = data.b; int size = peers.Length; int dim_num = a_input.Length; int num_jobs = (int)Math.Pow(dim_partition_size, dim_num); int num_local_jobs = num_jobs / size; // Set/Divide the interval double[][,] a = new double[size + 1][, ]; double[][,] b = new double[size + 1][, ]; a[0] = new double[0, 0]; b[0] = new double[0, 0]; for (int r = 1; r < size + 1; r++) { a[r] = new double[num_local_jobs, dim_num]; b[r] = new double[num_local_jobs, dim_num]; } int[] dims = new int[dim_num]; for (int job = 0; job < num_jobs; job++) { int r = job % size + 1; int j = job / size; for (int i = 0; i < dim_num; i++) { a[r][j, i] = a_input[i] + dims[i] * ((b_input[i] - a_input[i]) / dim_partition_size); b[r][j, i] = a_input[i] + (dims[i] + 1) * ((b_input[i] - a_input[i]) / dim_partition_size); } // NEXT JOB int ii = 0; while (ii < dim_num) { dims[ii] = (dims[ii] + 1) % dim_partition_size; if (dims[ii] == 0) { ii++; } else { break; } } } // Distribute jobs. localComm.Scatter <double[, ]>(a); localComm.Scatter <double[, ]>(b); } // end activate method
// return true if it converges. Output: solution matrix, errors, loops it took public static Boolean solve(Matrix A, Matrix b, out Matrix x, out Matrix err, out int loops, Intracommunicator comm) { // check sanity. rank 0 only if (comm.Rank == 0 && (!A.isSquare || !b.isColumn || (A.Height != b.Height))) { Exception e = new Exception("Matrix A must be square! Matrix b must be a column matrix with the same height as matrix A!"); throw e; } // follow samples in Wikipedia step by step https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method benchmark bm = new benchmark(), bm2 = new benchmark(), bm3 = new benchmark(); double sequential = 0, parallel = 0, communication = 0; bm.start(); bm2.start(); // decompose A into the sum of a lower triangular component L* and a strict upper triangular component U int size = 0; Matrix L = null, U = null, L_1; if (comm.Rank == 0) { size = A.Height; Matrix.Decompose(A, out L, out U); } bm2.pause(); sequential += bm2.getElapsedSeconds(); bm2.start(); comm.Broadcast(ref size, 0); comm.Broadcast(ref U, 0); comm.Broadcast(ref b, 0); bm2.pause(); communication += bm2.getElapsedSeconds(); // Inverse matrix L* comm.Barrier(); L_1 = MatrixParallel.Inverse(L, comm, ref sequential, ref parallel, ref communication); // Main iteration: x (at step k+1) = T * x (at step k) + C // where T = - (inverse of L*) * U, and C = (inverse of L*) * b // split T & C into groups of rows, each for one slave, according to the nature of this algorithm // each slave will have one piece of T & one piece of C stored locally. the rest of T & C is not needed // there might be cases where jobs > slaves, so some might get no job at all // Changes: only split L_1. Slaves will calculate T & C (pieces) themselves bm2.start(); Matrix jobDistro = Utils.splitJob(size, comm.Size); int startRow = 0, endRow = 0, myJobSize = (int)jobDistro[0, comm.Rank]; for (int p = 0; p < comm.Size; p++) { if (p != comm.Rank) { startRow += (int)jobDistro[0, p]; } else { endRow = startRow + (int)jobDistro[0, p] - 1; break; } } Matrix[] L_1Ps = new Matrix[comm.Size]; if (comm.Rank == 0) { int slaveStart = 0; for (int p = 0; p < comm.Size; p++) { L_1Ps[p] = Matrix.extractRows(L_1, slaveStart, slaveStart + (int)jobDistro[0, p] - 1); slaveStart += (int)jobDistro[0, p]; } } bm2.pause(); sequential += bm2.getElapsedSeconds(); bm2.start(); Matrix L_1P = comm.Scatter(L_1Ps, 0); bm2.pause(); communication += bm2.getElapsedSeconds(); bm2.start(); Matrix T = -L_1P * U; Matrix C = L_1P * b; bm2.pause(); parallel += bm2.getElapsedSeconds(); // the actual iteration // if it still doesn't converge after this many loops, assume it won't converge and give up Boolean converge = false; int loopLimit = 100; x = Matrix.zeroLike(b); // at step k for (loops = 0; loops < loopLimit; loops++) { bm3.start(); // (re-)distributing x vector. Must be done every single loop // this loop needs x from the previous loop comm.Broadcast(ref x, 0); bm3.pause(); communication += bm3.getElapsedSeconds(); // calculation step bm3.start(); comm.Barrier(); Matrix new_x = T * x + C; // check convergence converge = Matrix.SomeClose(new_x, x, 1e-15, startRow); // collect result x comm.Barrier(); x = comm.Reduce(new_x, Matrix.Concatenate, 0); // collect convergence. consider converged if ALL slaves claim so converge = comm.Reduce(converge, bothTrue, 0); comm.Broadcast(ref converge, 0); // make sure EVERYONE breaks/coninues bm3.pause(); parallel += bm3.getElapsedSeconds(); if (converge) { loops++; break; } } bm2.start(); // round the result slightly err = null; if (comm.Rank == 0) { x.Round(1e-14); err = A * x - b; err.Round(1e-14); } bm2.pause(); sequential += bm2.getElapsedSeconds(); bm.pause(); if (showBenchmark) { Console.WriteLine("Sequential part took " + sequential + " secs."); Console.WriteLine("Parallel part took " + parallel + " secs."); Console.WriteLine("Communication took " + communication + " secs."); Console.WriteLine("Total: " + bm.getResult() + " (" + bm.getElapsedSeconds() + " secs). Seq + Parallel: " + (sequential + parallel)); } return(converge); }