【问题标题】:Simple MPI code to test MPI_Type_vector crashes with seg fault - why?用于测试 MPI_Type_vector 因 seg 错误而崩溃的简单 MPI 代码 - 为什么?
【发布时间】:2011-05-12 09:55:33
【问题描述】:

我有以下代码,我用它来测试我如何在另一个程序中使用 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, &new_type);
    MPI_Type_commit(&new_type);

    /* Do the send and receive to this process */
    MPI_Sendrecv(&start, 1, new_type, 0, 0, &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("%d\n", 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(&argc, &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 = %d\n", a, b, c);

    /* Do the communication and print results */
    print_data(&data[0][0][0], a, b, c);

    MPI_Finalize();
}

【问题讨论】:

    标签: c mpi parallel-processing hpc


    【解决方案1】:

    您希望接收 new 而不是 &new,并从 start 而非 &start 发送。我知道,习惯的力量也一直在影响着我。

    【讨论】:

    • 这修复了它。干杯。我能问一下为什么会这样吗?
    • 对于缓冲区,您希望向 MPI 发送一个指向数据所在位置(或您希望它去哪里)的指针。 sendnew 已经是分配内存的指针;您将send 作为&amp;(data[0][0][0]) 传入,这是指向内存中第一个元素的指针,new 是指向malloc()ed 块开头的指针。取消引用它们意味着您现在不再传递指向该数据的指针,而是指向指针本身的指针。在这种情况下,这两个指针实际上都存在于堆栈中(作为局部变量和参数),因此您最终会写入整个堆栈内容。
    猜你喜欢
    • 1970-01-01
    • 2013-01-31
    • 2017-08-21
    • 2015-01-15
    • 1970-01-01
    • 2014-03-03
    • 2014-01-30
    • 2014-01-30
    • 1970-01-01
    相关资源
    最近更新 更多