#c #mpi #parallel-processing #hpc
#c #mpi #параллельная обработка #hpc
Вопрос:
У меня есть следующий код, который я использую, чтобы проверить, как я использую MPI_Type_vector в другой программе. Я написал эту небольшую тестовую программу, чтобы я мог проверить параметры, которые я предоставляю MPI_Type_vector, чтобы убедиться, что они извлекают правильные части массива. Однако, похоже, он не работает должным образом — при запуске он выдает ошибки сегментации (даже если сначала выполняет часть выходных данных), и я, похоже, не могу понять, почему.
Есть идеи?
Код приведен ниже. Первая функция ( alloc_3d_int
) была предоставлена мне кем-то другим, но была хорошо протестирована.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "array_alloc.h"
#include <mpi.h>
/* 3D array allocation program given to me by someone else */
int ***alloc_3d_int ( int ndim1, int ndim2, int ndim3 ) {
int *space = malloc( ndim1 * ndim2 * ndim3 * sizeof( int ) );
int ***array3 = malloc( ndim1 * sizeof( int ** ) );
int i, j;
if( space == NULL || array3 == NULL )
return NULL;
for( j = 0; j < ndim1; j ) {
array3[ j ] = malloc( ndim2 * sizeof( int * ) );
if( array3[ j ] == NULL )
return NULL;
for( i = 0; i < ndim2; i )
array3[ j ][ i ] = space j * ( ndim3 * ndim2 ) i * ndim3;
}
return array3;
}
void print_data(int *start, int count, int blocklen, int stride)
{
int i, j;
int *curr;
int *new;
MPI_Datatype new_type;
/* Create an array to store the output in - just a 1D array */
new = alloc_1d_int(count*blocklen);
/* Create the vector type using the parameters given to the function (came from the cmd line args) */
MPI_Type_vector(count, blocklen, stride, MPI_INT, amp;new_type);
MPI_Type_commit(amp;new_type);
/* Do the send and receive to this process */
MPI_Sendrecv(amp;start, 1, new_type, 0, 0, amp;new, count*blocklen, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
/* Loop through the array it was received into, printing values */
for (i = 0; i < count*blocklen; i )
{
printf("%dn", new[i]);
}
printf("Done loop");
}
int main(int argc, char ** argv)
{
int ***data;
int i, j, k;
int num;
int a, b, c;
MPI_Init(amp;argc, amp;argv);
/* Create a 3D array */
data = alloc_3d_int(2, 3, 4);
num = 1;
/* Fill array with test values */
for (i = 0; i < 2; i )
{
for (j = 0; j < 3; j )
{
for (k = 0; k < 4; k )
{
data[i][j][k] = num;
num ;
}
}
}
/* Get values from cmd line arguments */
a = atoi(argv[1]);
b = atoi(argv[2]);
c = atoi(argv[3]);
printf("Using count = %d, blocklength = %d and stride = %dn", a, b, c);
/* Do the communication and print results */
print_data(amp;data[0][0][0], a, b, c);
MPI_Finalize();
}
Ответ №1:
Вы хотите получать в new, а не amp; new, и отправлять из start, а не amp;start. Сила привычки, я знаю, тоже все время подводит меня.
Комментарии:
1. Это исправлено. Приветствия. Могу я просто спросить, почему это так?
2. Для буферов вы хотите отправить MPI указатель на то, где находятся данные (или куда вы хотите их переместить).
send
иnew
уже являются указателями на выделенную память; вы передалиsend
какamp;(data[0][0][0])
, который является указателем на первый элемент в памяти иnew
является указателем на началоmalloc()ed
блока. Разыменование их означает, что теперь вы больше не передаете указатели на эти данные, а указываете на сами указатели. В этом случае оба этих указателя фактически находятся в стеке (как локальная переменная и аргумент), и поэтому в конечном итоге вы записываете все содержимое стека.