2013-02-22 5 views
2

Я пытаюсь реализовать алгоритм пушками с использованием MPI, я использую этот пример кода:Реализация Пушки алгоритма в MPI

http://siber.cankaya.edu.tr/ozdogan/GraduateParallelComputing.old/ceng505/node133.html

Там есть раздел, который я не понимая. вот пример кода.

37 /* Perform the initial matrix alignment. First for A and then for B */ 
38 MPI_Cart_shift(comm_2d, 0, -mycoords[0], &shiftsource, &shiftdest); 
39 MPI_Sendrecv_replace(a, nlocal*nlocal, MPI_DOUBLE, shiftdest, 
40  1, shiftsource, 1, comm_2d, &status); 
41 
42 MPI_Cart_shift(comm_2d, 1, -mycoords[1], &shiftsource, &shiftdest); 
43 MPI_Sendrecv_replace(b, nlocal*nlocal, MPI_DOUBLE, 
44  shiftdest, 1, shiftsource, 1, comm_2d, &status); 

Это мой текущий код.

MPI_Comm_size(comm, &size); 
MPI_Comm_rank(comm, &rank); 
MPI_Cart_coords(comm, rank, 2, coordinates); 

MPI_Cart_shift(comm, 0, -1, &rightrank, &leftrank); 
MPI_Cart_shift(comm, 1, -1, &downrank, &uprank); 

MPI_Cart_shift(comm, 0, -coordinates[0], &shiftsource, &shiftdest); 
printf("coordinates[0] = %d for a shiftsource = %d, shiftdest = %d\n", coordinates[0], shiftsource, shiftdest); 
//MPI_Sendrecv_replace(a, a->rowNum * a->colNum, MPI_INT, shiftdest, 
    //1, shiftsource, 1, comm, &status); 

MPI_Cart_shift(comm, 1, -coordinates[1], &shiftsource, &shiftdest); 
printf("coordinates[1] = %d for b shiftsource = %d, shiftdest = %d\n", coordinates[1], shiftsource, shiftdest); 
//MPI_Sendrecv_replace(b, b->rowNum * b->colNum, MPI_INT, 
    // shiftdest, 1, shiftsource, 1, comm, &status); 

Я называю MPI_Cart_create в другой функции, но это тот же самый основной вызов, как и в примере кода.

MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */ 
    . 
    . 
    . 
if(is_perfect_square(size)) dim_size[0] = dim_size[1] = (int) sqrt(size); 
else 
{ //if size = 2 then dims = 2, 1; size = 4 then 2,2; 8 = 4, 2... 
    dim_size[0] = (int) sqrt(size + size); 
    dim_size[1] = dim_size[0]/2; 
} 
MPI_Cart_create(MPI_COMM_WORLD, 2, dim_size, periods, 1, &CannonsCart); 

прямо сейчас Я просто пытаюсь понять, что такое точка shiftsource и shiftdest. Я предполагаю, что это для инициативного сдвига, но когда я запускаю этот код, мои заявления printf говорят об этом.

coordinates[0] = 0 for a shiftsource = 0, shiftdest = 0 
coordinates[1] = 0 for b shiftsource = 0, shiftdest = 0 

coordinates[0] = 1 for a shiftsource = 1, shiftdest = 1 
coordinates[1] = 1 for b shiftsource = 2, shiftdest = 2 

coordinates[0] = 1 for a shiftsource = 0, shiftdest = 0 
coordinates[1] = 0 for b shiftsource = 2, shiftdest = 2 

coordinates[0] = 0 for a shiftsource = 1, shiftdest = 1 
coordinates[1] = 1 for b shiftsource = 0, shiftdest = 0 

Я не понимаю, почему сменный источник и shiftdest одинаковы. Он должен быть один слева и один для матриц a и b.

Число процессов для этого вызова (размер I.E.) составляет 4 для этого тестового примера. Если мне нужно, я просто возьму весь мой код.

ответ

2

Третий аргумент MPI_Cart_shift - это смещение по размеру (направлению), заданному вторым аргументом. Для всех процессов, которые имеют координату 0 по заданному размеру, смещение также будет 0 (поскольку оно указано как -coordinate[i]), поэтому исходная и целевая ранги будут соответствовать рангу вызывающего процесса.

Вы также получаете то же самое shiftsource и shiftdest, когда смещение 1, потому что ваша топология 2x2, и у вас есть периодические граничные условия вдоль обоих размеров. Координата по выбранному размеру предыдущего ранга будет (coordinates[i] - 1 + 2) % 2 (здесь (a - m + k) % k вычисляет a - m по модулю k). Но это равно (coordinate[i] + 1) % 2, что является точно координатой следующего ранга. Следовательно, координаты предыдущего и следующего процессов согласуются, и поэтому ранги становятся одинаковыми.

+0

В настоящее время у меня есть сетка 2 на 2, и она периодична в обоих направлениях. Я получаю, как cart_shift вычисляет его направления сейчас, я до сих пор не понимаю, почему алгоритм Cannons имеет этот раздел кода. – AlexLordThorsen

+1

Алгоритм использует круговые сдвиги. После последней итерации результат есть, но он неупорядочен. Для восстановления первоначального распределения данных необходим один дополнительный шаг, чтобы впоследствии его можно было собрать с использованием того же шаблона связи, что и для его рассеяния. –

Смежные вопросы