MPI параллельное перемножение матриц - C#
Формулировка задачи:
Форумчане, помогите,чем можете.Самой никак не справиться...
Нужен код на C# MPI параллельного перемножения матриц (ленточным способом, блочным, или любым другим).
Главное,чтобы процессов использовалось не много,а матрицы -большие,размерностью 100 на 100.
Уже есть код , в котором каждый процесс вычисляет 1 элемент. Т.е. кол-во процессов=колву элементов.
А надо, чтобы после того, как на одном процессе вычислился элемент, сразу начинал вычисляться другой на том же процессе.
Решение задачи: «MPI параллельное перемножение матриц»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Linq; using System.Text; using MPI; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { using (new MPI.Environment(ref args)) { Intracommunicator comm = Communicator.world; int rank = comm.Rank; int size = comm.Size; //double[,] A = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }; //double[,] B = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }; double[,] A = SchitIzFaila("a.txt"); double[,] B = SchitIzFaila("b.txt"); int razmer = A.GetLength(0); double[,] C = new double[razmer, razmer]; double[] tempMatrix = new double [size]; if (rank == 0) { Console.WriteLine("Matrica A"); vyvodvconsol(A); Console.WriteLine("Matrica B"); vyvodvconsol(B); } if (rank == 0) { int IndexRank = 1; for (int i = 0; i < razmer; i++) { for (int j = 0; j < razmer; j++) { if (IndexRank % 2 != 0) { int[] koordinata = new int[2] { i, j }; comm.Send(koordinata, IndexRank, 0); IndexRank++; // comm.Barrier(); } //else //{ // int[] koordinata = new int[2] { i, j }; // comm.Send(koordinata, IndexRank, 0); // IndexRank--; // comm.Barrier(); //} } } comm.Gather(-1, 0, ref tempMatrix); comm.Barrier(); C = PoluchMatricuIzPosledovat(tempMatrix, razmer); Console.WriteLine("Matr C"); vyvodvconsol(C); } else { int[] koordinata = new int[2]; comm.Receive(0, 0, ref koordinata); double resultat = Element(PoluchitStroku(koordinata[0], A), PoluchitStolbec(koordinata[1], B)); comm.Gather(resultat, 0, ref tempMatrix); comm.Barrier(); } } } public static double[,] SchitIzFaila(string adress) { StreamReader sr = new StreamReader(adress); int columns = 0; int lines = 0; while (!sr.EndOfStream) { string temp = sr.ReadLine(); columns = temp.Split(' ').Count(); lines++; } double[,] result = new double[lines, columns]; sr = new StreamReader(adress); for (int i = 0; i < result.GetLength(0); i++) { string[] temp = sr.ReadLine().Split(' '); for (int j = 0; j < result.GetLength(1); j++) { result[i, j] = Convert.ToDouble(temp[j]); } } return result; } public static void vyvodvconsol(double[,] matrix) { Console.WriteLine(); for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { Console.Write(matrix[i, j]); Console.Write(" "); } Console.Write('\n'); } Console.WriteLine(); } public static double[] PoluchitStroku(int idLine, double[,] M) { double[] result = new double[M.GetLength(1)]; for (int i = 0; i < result.Length; i++) { result[i] = M[idLine, i]; } return result; } public static double[] PoluchitStolbec(int idColumn, double[,] M) { double[] result = new double[M.GetLength(0)]; for (int i = 0; i < result.Length; i++) { result[i] = M[i,idColumn]; } return result; } public static double Element(double[] line, double[] column) { double result = 0; for (int i = 0; i < line.Length; i++) { result += line[i] * column[i]; } return result; } public static double[,] PoluchMatricuIzPosledovat(double[] matrix, int size) { double[,] resmatrix = new double[size, size]; int matrixIndex = 1; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { resmatrix[i, j] = matrix[matrixIndex]; matrixIndex++; } } return resmatrix; } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д