Как вывести матрицу, сохраненную в файле, с помощью MPI

Моя задача - прочитать файл, в котором записана матрица, и произвести определенные вычисления. Основная проблема заключается в том, что я не знаю, как правильно читать файл с помощью N процессов.

Матрица, записанная в файле выглядит следующим образом:

27.8 27.7 27.6 27.5 28.0
27.7 27.9 27.5 27.4 27.3
27.6 27.3 27.4 27.3 27.2
27.5 27.4 27.5 27.2 27.1
27.8 27.7 27.6 27.5 27.4
27.7 27.5 27.5 27.4 28.0
27.6 27.5 27.6 27.3 27.2
27.5 27.4 27.3 27.2 27.1

Поскольку я не знаю, как сделать правильное чтение файла, я использую готовую матрицу:

int32_t main(int32_t argc, char *argv[])
{
    int32_t processRank       = 0;
    int32_t numberOfProcesses = 2;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numberOfProcesses);
    MPI_Comm_rank(MPI_COMM_WORLD, &processRank);

    const uint32_t k = 2;
    const uint32_t n = 4;
    const uint32_t m = 5;
    const uint32_t countRows = k * n;

    srand(static_cast<uint32_t>(time(nullptr)));

    // Готовая матрица
    double inputArr[countRows][m] = {
        {27.8, 27.7, 27.6, 27.5, 28.0},
        {27.7, 27.9, 27.5, 27.4, 27.3},
        {27.6, 27.3, 27.4, 27.3, 27.2},
        {27.5, 27.4, 27.5, 27.2, 27.1},
        {27.8, 27.7, 27.6, 27.5, 27.4},
        {27.7, 27.5, 27.5, 27.4, 28.0},
        {27.6, 27.5, 27.6, 27.3, 27.2},
        {27.5, 27.4, 27.3, 27.2, 27.1}
    };

    MPI_Bcast(inputArr, n, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    double  localMaxSum    = 0;
    double  localMinSum    = 0;
    int32_t localMaxCount  = 0;
    int32_t localMinCount  = 0;
    int32_t rowsPerProcess = countRows / n;

    int32_t startLoop = processRank * rowsPerProcess;
    int32_t endLoop   = startLoop   + rowsPerProcess - 1;

    for (int32_t i = startLoop; i <= endLoop; i++) {

        for (int32_t j = 0; j < m; j++) {

            double neighbours[8]{};
            double current = inputArr[i][j];
            bool   isArrBeginning = i % n == 0;

            if (i > 0 && !isArrBeginning) {

                // first
                if (j > 0) {
                    neighbours[0] = inputArr[i - 1][j - 1];
                }

                // second
                neighbours[1] = inputArr[i - 1][j];

                // third
                if (j < m - 1) {
                    neighbours[2] = inputArr[i - 1][j + 1];
                }
            }

            // middle
            // fourth
            if (j > 0) {
                neighbours[3] = inputArr[i][j - 1];
            }

            // fifth
            if (j < m - 1) {
                neighbours[4] = inputArr[i][j + 1];
            }

            bool isArrEnd = i % n == n - 1;
            // down
            if (i < countRows - 1 && !isArrEnd) {
                // sixth
                if (j > 0) {
                    neighbours[5] = inputArr[i + 1][j - 1];
                }
                // seventh
                neighbours[6] = inputArr[i + 1][j];

                // eight
                if (j < m - 1) {
                    neighbours[7] = inputArr[i + 1][j + 1];
                }
            }

            bool isLocalMax = true;
            for (double neighbour : neighbours) {
                if (neighbour >= current) {
                    isLocalMax = false;
                    break;
                }
            }

            if (isLocalMax) {
                localMaxSum += current;
                localMaxCount++;
            }

            if (!isLocalMax) {
                bool isLocalMin = true;
                for (double neighbour : neighbours) {

                    if (neighbour <= current && neighbour > 0) {
                        isLocalMin = false;
                        break;
                    }
                }

                if (isLocalMin) {
                    localMinSum += current;
                    localMinCount++;
                }
            }
        }
    }

    double resultBufferMaxSum[numberOfProcesses];
    double resultBufferMinSum[numberOfProcesses];
    int32_t resultBufferMaxCount[numberOfProcesses];
    int32_t resultBufferMinCount[numberOfProcesses];

    MPI_Gather(&localMaxSum,   1, MPI_DOUBLE, resultBufferMaxSum,   1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Gather(&localMinSum,   1, MPI_DOUBLE, resultBufferMinSum,   1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Gather(&localMaxCount, 1, MPI_INT,    resultBufferMaxCount, 1, MPI_INT,    0, MPI_COMM_WORLD);
    MPI_Gather(&localMinCount, 1, MPI_INT,    resultBufferMinCount, 1, MPI_INT,    0, MPI_COMM_WORLD);

    if (processRank == 0) {

        double  localMaxSumTotal   = 0;
        double  localMinSumTotal   = 0;
        int32_t localMaxCountTotal = 0;
        int32_t localMinCountTotal = 0;

        int32_t step = 0;

        for (int32_t mk = 0; mk < numberOfProcesses; mk++) {

            step += rowsPerProcess;

            if (resultBufferMaxSum[mk] > 0) {
                localMaxSumTotal += resultBufferMaxSum[mk];
            }
            if (resultBufferMinSum[mk] > 0) {
                localMinSumTotal += resultBufferMinSum[mk];
            }
            if (resultBufferMaxCount[mk] > 0) {
                localMaxCountTotal += resultBufferMaxCount[mk];
            }
            if (resultBufferMinCount[mk] > 0) {
                localMinCountTotal += resultBufferMinCount[mk];
            }

            if (step == n) {

                const double localMaxAvg = localMaxSumTotal / localMaxCountTotal;
                const double localMinAvg = localMinSumTotal / localMinCountTotal;

                cout << localMaxAvg << " ";
                cout << localMinAvg << endl;

                step               = 0;
                localMaxSumTotal   = 0;
                localMinSumTotal   = 0;
                localMaxCountTotal = 0;
                localMinCountTotal = 0;
            }
        }
    }

    MPI_Finalize();
    return EXIT_SUCCESS;
}

Я попытался прочитать N значений (double) из файла с помощью MPI_Type_create_subarray, но ничего не работает. Я прошу помощи в поиске решения описанной проблемы.


Ответы (0 шт):