MPI地址未映射到C中

时间:2015-05-31 21:21:53

标签: c parallel-processing malloc mpi openmpi

使用MPI_Recv时我遇到问题malloc?有没有建议接收使用malloc创建的二维数组?

感谢。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>

#define SIZE 2000
/* Tags defines message from_to */
#define TO_SLAVE_TAG 1
#define TO_MASTER_TAG 5

void createMatrices();
/* Matrices */
int** first;
/* MPI_WORLD rank and size */
int rank, size;

MPI_Status status;
/*
 * matrixSize: current matrix size
 * lower_bound: lower bound of the number of rows of [first matrix] allocated to a slave
 * upper_bound: upper bound of the number of rows of [first matrix] allocated to a slave
 * portion: number of the rows of [first matrix] allocated to a slave according to the number of processors
 * count: number of data will pass with mpi functions
 */
int matrixSize, lower_bound, upper_bound, portion, count;
int sum = 0;
clock_t t, start_time, end_time;

int main( int argc, char **argv ) {

  /* Initialize the MPI execution environment */
  MPI_Init( &argc, &argv );
  /* Determines the size of the group */
  MPI_Comm_size( MPI_COMM_WORLD, &size );
  /* Determines the rank of the calling process */
  MPI_Comm_rank( MPI_COMM_WORLD, &rank );

  if (rank == 0)
    {
      for (matrixSize = 500; matrixSize <= SIZE; matrixSize += 500) {
    createMatrices(matrixSize);
    /* 
     * Master processor divides [first matrix] elements
     * and send them to proper slave processors.
     * We can start time at this point.
     */
    start_time = clock();

    /* Define bounds for each processor except master */
    for (int i = 1; i < size; ++i)
      {
        /* Calculate portion for each slave */
        portion = (matrixSize / (size - 1));
        lower_bound = (i-1) * portion;
        if (((i+1)==size) && (matrixSize % (size-1) != 0)) {
          upper_bound = matrixSize;
        } else {
          upper_bound = lower_bound + portion;
        }
        /* send matrix size to ith slave */
        MPI_Send(&matrixSize, 1, MPI_INT, i, TO_SLAVE_TAG, MPI_COMM_WORLD);
        /* send lower bount to ith slave */
        MPI_Send(&lower_bound, 1, MPI_INT, i, TO_SLAVE_TAG + 1, MPI_COMM_WORLD);
        /* send upper bount to ith slave */
        MPI_Send(&upper_bound, 1, MPI_INT, i, TO_SLAVE_TAG + 2, MPI_COMM_WORLD);
        /* send allocated row of [first matrix] to ith slave */
        count = (upper_bound - lower_bound) * matrixSize;
        printf("Count: %d\n", count);
        MPI_Send(&(first[lower_bound][0]), count, MPI_DOUBLE, i, TO_SLAVE_TAG + 3, MPI_COMM_WORLD);
      }
      }
    }
  if (rank > 0)
    {
      //receive low bound from the master
      MPI_Recv(&matrixSize, 1, MPI_INT, 0, TO_SLAVE_TAG, MPI_COMM_WORLD, &status);
      printf("Matrix size: %d\n", matrixSize);
      //receive low bound from the master
      MPI_Recv(&lower_bound, 1, MPI_INT, 0, TO_SLAVE_TAG + 1, MPI_COMM_WORLD, &status);
      printf("Lower bound: %d\n", lower_bound);
      //next receive upper bound from the master
      MPI_Recv(&upper_bound, 1, MPI_INT, 0, TO_SLAVE_TAG + 2, MPI_COMM_WORLD, &status);
      printf("Upper bound: %d\n", upper_bound);
      //finally receive row portion of [A] to be processed from the master
      count = (upper_bound - lower_bound) * matrixSize;
      printf("Count: %d\n", count);

      MPI_Recv(&first[lower_bound][0], count, MPI_INT, 0, TO_SLAVE_TAG + 3, MPI_COMM_WORLD, &status);
      printf("first[0][0]: %d\n", first[0][0]);
    }
  MPI_Finalize();
  return 0;
}

void createMatrices(int mSize) {
  /* matrix cols */
  first = malloc(mSize * sizeof(int*));
  /* matrix rows */
  for (int i = 0; i < mSize; ++i)
    first[i] = malloc(mSize * sizeof(int));

  srand(time(NULL));
  for (int i = 0; i < mSize; ++i)
    for (int j = 0; j < mSize; ++j)
      first[i][j] = rand()%2;
}

问题是:

*** Process received signal ***
Signal: Segmentation fault: 11 (11)
Signal code: Address not mapped (1)
Failing at address: 0x0
[ 0] 0   libsystem_platform.dylib            0x00007fff89cc8f1a _sigtramp + 26
[ 1] 0   libsystem_c.dylib                   0x00007fff73857070 __stack_chk_guard + 0
[ 2] 0   libdyld.dylib                       0x00007fff90f535c9 start + 1
[ 3] 0   ???                                 0x0000000000000001 0x0 + 1
*** End of error message ***

1 个答案:

答案 0 :(得分:0)

为避免(可能很高)单独发送每一行的延迟成本,您需要在线性内存中创建矩阵。这是通过为整个矩阵分配足够的内存并设置指向每一行的指针来完成的。以下是您修改的功能。

void createMatrices(int mSize) {
  /* initialize enough linear memory to store whole matrix */
  raw_data=malloc(mSize*mSize*sizeof(int*));

  /* matrix row pointers i.e. they point to each consecutive row */
  first = malloc(mSize * sizeof(int*));

  /* set the pointers to the appropriate address */
  for (int i = 0; i < mSize; ++i)
    first[i] = raw_data + mSize*i;

  /* initialize with random values */
  srand(time(NULL));
  for (int i = 0; i < mSize; ++i)
    for (int j = 0; j < mSize; ++j)
      first[i][j] = rand()%2;
}

您面临的另一个主要问题是正确的内存处理。你应该在根等级上分配新矩阵之前释放你的矩阵。

在尝试复制数据之前,还需要为从属级别上的矩阵分配内存。这也需要在线性记忆中,就像在上面的函数中所做的那样。