Учитывая сетка 10х10 размера, как это:Разброс сетки в одинаковых по размеру блоков
0,1,2,3,4, 5,6,7,8,9,
10,11,12,13,14, 15,16,17,18,19,
20,21,22,23,24, 25,26,27,28,29,
30,31,32,33,34, 35,36,37,38,39,
40,41,42,43,44, 45,46,47,48,49,
50,51,52,53,54, 55,56,57,58,59,
60,61,62,63,64, 65,66,67,68,69,
70,71,72,73,74, 75,76,77,78,79,
80,81,82,83,84, 85,86,87,88,89,
90,91,92,93,94, 95,96,97,98,99
, как рассеивают визуально разделенные блоки до четырех процессов?
Я попытался как описано here (или даже here) с Scatterv, и она работала, но я помню, что проект с точно такой же проблемой и не используя либо изменить размер или Scatterv, чтобы решить эту проблему.
Вот минимальный пример кода с тем, что у меня есть:
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <assert.h>
#include <memory.h>
#include <unistd.h>
void print_array(int* arr, int width, int height)
{
int i;
for (i = 0; i< width * height;i++)
{
if((i != 0) && (i % width == 0))
printf("\n");
printf("%4d ", arr[i]);
}
putchar('\n');
}
int main() {
int board[100] = {
0,1,2,3,4, 5,6,7,8,9,
10,11,12,13,14, 15,16,17,18,19,
20,21,22,23,24, 25,26,27,28,29,
30,31,32,33,34, 35,36,37,38,39,
40,41,42,43,44, 45,46,47,48,49,
50,51,52,53,54, 55,56,57,58,59,
60,61,62,63,64, 65,66,67,68,69,
70,71,72,73,74, 75,76,77,78,79,
80,81,82,83,84, 85,86,87,88,89,
90,91,92,93,94, 95,96,97,98,99
};
int numprocs, rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int* block = calloc(25, sizeof(int));
assert(block != NULL);
MPI_Datatype sent_block_t, resized_sent_block_t;
MPI_Type_vector(5, 5, 10, MPI_INT, &sent_block_t);
MPI_Type_create_resized(sent_block_t, 0, 5*sizeof(int), &resized_sent_block_t);
MPI_Type_commit(&sent_block_t);
MPI_Type_commit(&resized_sent_block_t);
if (rank == 0) {
print_array(board, 10, 10);
MPI_Scatter(&(board[0]), 1, resized_sent_block_t,
&(block[0]), 25, MPI_INT,
0, MPI_COMM_WORLD);
}
else {
MPI_Scatter(NULL, 0, resized_sent_block_t,
&(block[0]), 25, MPI_INT,
0, MPI_COMM_WORLD);
}
for (int i = 0; i < numprocs; i++) {
MPI_Barrier(MPI_COMM_WORLD);
sleep(1);
if (i == rank) {
printf("\nRank: %d\n", rank);
print_array(block, 5, 5);
}
}
MPI_Finalize();
free(block);
}
Запуск его с 4-мя процессами я получаю это:
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
Rank: 0
0 1 2 3 4
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34
40 41 42 43 44
Rank: 1
5 6 7 8 9
15 16 17 18 19
25 26 27 28 29
35 36 37 38 39
45 46 47 48 49
Rank: 2
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34
40 41 42 43 44
50 51 52 53 54
Rank: 3
15 16 17 18 19
25 26 27 28 29
35 36 37 38 39
45 46 47 48 49
55 56 57 58 59
Это рассеяние не так, обратите внимание на содержание 2-го ранга и 3.
Правильные из них будут:
Rank 0: Rank 1:
0,1,2,3,4, 5,6,7,8,9,
10,11,12,13,14, 15,16,17,18,19,
20,21,22,23,24, 25,26,27,28,29,
30,31,32,33,34, 35,36,37,38,39,
40,41,42,43,44, 45,46,47,48,49,
Rank 2: Rank 3:
50,51,52,53,54, 55,56,57,58,59,
60,61,62,63,64, 65,66,67,68,69,
70,71,72,73,74, 75,76,77,78,79,
80,81,82,83,84, 85,86,87,88,89,
90,91,92,93,94, 95,96,97,98,99
Вопрос
Есть ли способ, чтобы рассеять равные по размеру блоков сетки без использования Scatterv?
Итак, вы говорите, что ваш код работает, и вы прекрасно это понимаете. Какая у вас проблема? – Zulan
@ Zulan Нет, результат, который я опубликовал, не является правильным результатом. См. В начале сообщения указанную доску, которая визуально разделяет четыре блока. Я хочу, чтобы левый верхний, чтобы перейти к процессу 0, вверху справа, чтобы обработать 1, в левом нижнем углу для обработки 2 и в левом нижнем углу для обработки 3. (Я добавил ожидаемый результат.) – Chris
Извините, что я только ненадолго снял вывод. Существует [очень хорошее подробное объяснение] (http://stackoverflow.com/a/9271753/620382) о том, как правильно делать то, что вы хотите, используя 'MPI_Scatterv'. Я не могу представить правильную реализацию, используя только «MPI_Scatter», который не бесполезно взломан. – Zulan