MPI вычисляет знак разницы из двойного массива - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь вычислить знак различия из двойного массива с MPI, нет необходимости использовать внешние строки или столбцы, результат может выглядеть так:

В массиве

1 0 1 1 1

2 1 3 1 4

1 3 1 0 1

2 1 -1 1 2

из массива

0 0 0 0 0

0 -1 0 -1 0

0 1 -1 1 0

0 0 0 0 0

Я написал некоторый код, но когда я пытаюсь записать массив b в консоль, я получаю сообщение об ошибке «Доступ к нарушению чтения». Я новичок в MPI, и я не знаю, правильный ли этот код. Любые идеи, как заставить это работать?

#include <iostream>
#include <chrono>
#include <mpi.h>
#include <iomanip>
#include <cstdlib>

using namespace std;
int main(int argc, char *argv[])
{

int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

srand(time(NULL));

int R = 4;
int C = 8;


int **a = new int *[R];
a = new int *[R]; 
a[0] = new int[R*C];
for (int i = 1; i < R; i++)
{
    a[i] = &a[0][i*C];
}

if (rank == 0) {
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++) 
        {
            a[i][j] = (rand() % 10) - 5;
            cout << setw(5) << a[i][j] << " ";
        }
        cout << endl;
    }

}


int **b = new int *[R];
b = new int *[R]; 
b[0] = new int[R*C];
for (int i = 1; i < R; i++)
{
    b[i] = &b[0][i*C];
}


MPI_Bcast(a, R*C, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);

int partR = R / size;
int partC = C / size;
int part = partR * partC*size; 

int *c = new int[part];

int sumF = 0;
int sumS = 0;
int tmp = 0;
int x = 0;

auto start = chrono::high_resolution_clock::now();

for (int i = rank*partR; i <= rank*partR+partR; i++) {
    for (int j = rank*partC; j <= rank*partC + partC; j++) {
        if (i != 0 && i != R - 1 && j != 0 && j != C - 1) {
            sumF = a[i - 1][j - 1] + a[i + 1][j - 1] + a[i - 1][j + 1] + a[i + 1][j + 1];
            sumS = a[i - 1][j] + a[i + 1][j] + a[i][j - 1] + a[i][j + 1];
            if ((sumF - sumS) > 0)
                tmp = 1;
            if ((sumF - sumS) < 0)
                tmp = -1;
            if ((sumF - sumS) == 0)
                tmp = 0;
            c[x] = tmp;
            x++;
        }
    }
}

MPI_Gather(c, part, MPI_INT, &(b[0][0]), part, MPI_INT, 0, MPI_COMM_WORLD);


auto finish = chrono::high_resolution_clock::now();

chrono::duration<double> elapsed = finish - start;

if (rank == 0) {
    cout << endl << "Result: " << endl;
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            cout << b[i][j] << " ";
        }
        cout << endl;
    }

    cout << endl << "T: " << elapsed.count() << endl;
}


MPI_Finalize();
return 0;
system("PAUSE");
}

1 Ответ

0 голосов
/ 15 января 2019
MPI_Bcast(a, R*C, MPI_INT, 0, MPI_COMM_WORLD);

Это не трансляция 2D-массива. Это берет int**, преобразует его в void* и вы сообщаете компилятору, что он содержит R*C целых чисел. это не так. Содержит адреса к подмассивам.

Вместо этого используйте 1D массив в будущем рефакторинге. Доступ к 1D без косвенных указаний лучше.

Но чтобы исправить вашу проблему сейчас:

MPI_Bcast(a[0], R*C, MPI_INT, 0, MPI_COMM_WORLD);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...