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;
}
}
}