Научно-образовательный IT-форум при КНИТУ-КАИ

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Научно-образовательный IT-форум при КНИТУ-КАИ » Задачи и вопросы » [+] Как создать пользовательскую функцию в MPI.NET


[+] Как создать пользовательскую функцию в MPI.NET

Сообщений 1 страница 4 из 4

1

РЕШЕНИЕ: http://landwatersun.ru/viewtopic.php?id=395#p1476

Как создать пользовательскую функцию для сложения матриц и применить ее к операции MPI.Communicator.world.Reduce?

using System;
using System.Text;
using MPI;
using System.Linq;
using System.Diagnostics;

class Hello
{
     static void Main(string[] args)
    {
        using (new MPI.Environment(ref args))
        {

            System.Console.WriteLine("Hello, from process number "
                + MPI.Communicator.world.Rank.ToString() + " of "
                + MPI.Communicator.world.Size.ToString() + ".");

            Intracommunicator comm = Communicator.world;

            int Size=2;
            double[,] MatrixA = new double[Size, Size];
            double[,] MatrixB = new double[Size, Size];
            double[,] MatrixC = new double[Size, Size];
            double[,] Result = new double[Size, Size];

            int i,j,k;

            //Инициализация//Инициализация//Инициализация
                for (i = 0; i < Size; i++){//строка
                    for (j=0; j< Size; j++){//столбец
                        MatrixA[i,j] = 2;
                        MatrixB[i,j]=3;
                        MatrixC[i,j] = MPI.Communicator.world.Rank;
                    }
                }

            Result = comm.Reduce<double[,]>(MatrixC, ???, 0);
            if (MPI.Communicator.world.Rank == 0)
            for (i = 0; i < Size; i++)
            {//строка                       
                for (j = 0; j < Size; j++)
                    System.Console.Write(Result[i, j]);
                System.Console.WriteLine();
            }
        }
    }
}

2

Определение пользовательской операции:

Код:
ReductionOperation<double[,]> doubleOperation = DoubleOperation;

Где DoubleOperation - пользовательская операция:

Код:
private static double[,] DoubleOperation(double[,] doubles, double[,] doubles1)
{
    double[,] result = new double[doubles.GetLength(0),doubles.GetLength(1)];
    for (int i = 0; i < doubles.GetLength(0); i++)
    {
        for (int j = 0; j < doubles.GetLength(1); j++)
        {
            result[i, j] = doubles[i, j] + doubles1[i, j];
        }
    }
    return result;
}

Соответственно использование:

Код:
Result = comm.Reduce<double[,]>(MatrixC, doubleOperation, 0);

Результат:
https://bitbucket.org/landwatersun/forum/downloads/201711222025.png

3

Роман, молодец! Очень оперативно и грамотно, спасибо! :)

Для методичности ниже демонстрирую код применения операции Gather и пользовательской функции в операции Reduce немного в другой редакции, опираясь на твой пример, Роман.

https://bitbucket.org/landwatersun/forum/downloads/201711222026.jpg

using System;
using System.Text;
using MPI;
using System.Linq;
using System.Diagnostics;

class mpi_example
{
    private static double[,] AddMatrix(double[,] x, double[,] y)
    {
        double[,] result = new double[x.GetLength(0), x.GetLength(1)];
        for (int i = 0; i < x.GetLength(0); i++)
             for (int j = 0; j < x.GetLength(1); j++)
                 result[i, j] = x[i, j] + y[i, j];
         return result;
    }

    static void Main(string[] args)
    {
        using (new MPI.Environment(ref args))
        {
            Intracommunicator comm = Communicator.world;
            int Size = 2;
            if (args.Length == 1) Size = int.Parse(args[0]);
            double[,] MatrixA = new double[Size, Size];
            for (int i = 0; i < Size; i++)
                for (int j = 0; j < Size; j++)
                    MatrixA[i, j] = MPI.Communicator.world.Rank;

            double[][,] Result_of_Gather = comm.Gather(MatrixA, 0);

            double[,] Result_of_Reduce = comm.Reduce(MatrixA, AddMatrix, 0);

            if (comm.Rank == 0)
                for (int k = 0; k < comm.Size; k++)
                {
                    Console.WriteLine("Result of gather from process #{0}:", k);
                    for (int i = 0; i < Size; i++)
                    {
                        for (int j = 0; j < Size; j++)
                            System.Console.Write(Result_of_Gather[k][i, j]+" ");
                        System.Console.WriteLine();
                    }
                }

            if (comm.Rank == 0)
            {
                Console.WriteLine("\r\nResult of reduce (ReductionOperation: AddMatrix):");
                for (int i = 0; i < Size; i++)
                {
                    for (int j = 0; j < Size; j++)
                        System.Console.Write(Result_of_Reduce[i, j]+" ");
                    System.Console.WriteLine();
                }
            }
        }
    }
}


https://bitbucket.org/landwatersun/forum/downloads/201711222027.jpg

4

А вот лаконичный пример по той же задаче с использованием лямбда-выражения:

double[,] Result_of_Reduce = comm.Reduce(MatrixA,
                (double[,] x, double[,] y) =>
                {
                    double[,] result = new double[x.GetLength(0), x.GetLength(1)];
                    for (int i = 0; i < x.GetLength(0); i++)
                        for (int j = 0; j < x.GetLength(1); j++)
                            result[i, j] = x[i, j] + y[i, j];
                    return result;
                }, 0);


Вы здесь » Научно-образовательный IT-форум при КНИТУ-КАИ » Задачи и вопросы » [+] Как создать пользовательскую функцию в MPI.NET