zak100 Ответов: 2

Блоки MPI_recv в небольшом коде


Привет,

Если я использую MPI_Send, я не получаю никаких проблем, но когда я использую как MPI_Send, так и MPI_Recv, мои программные блоки.
#include <iostream>
#include <fstream>
#include <cmath>
#include <mpi.h>
#include <ctime>
#include <vector>

//using namespace std;

// Sorts the input row into chunks to be scattered two all the processors.
//void sortByProcess(std::vector<double> list1, double* list2, int count);

// Swaps two rows.
//void swap(double** list, int count, int row1, int row2);

//int N=32;
int rank, size;
int tag = 99;
int main(int argc, char * argv[])
{
  double sTime, eTime, rTime;
  std::ifstream inFile;
  int num_rows = 3200;
  int num_cols = 3200;
  int cur_control = 0;
  double * send_buffer = NULL;
  double * recv_buffer = NULL;
  double ** data = NULL;
  double determinant;
  MPI_Status stat;
  std::vector<double> file_buffer;
  
  // Just get the initialization of the program going.
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

  // If the input file is not given, print message and exit.
  if(argc < 2)
  {
    std::cout << "No input file given." << std::endl;
    MPI_Finalize();
    return 0;
  }
  // If the root node (0), then open the input file and read in the
  // number of rows.
  if(!rank)
  {
    inFile.open(argv[1]);
    inFile >> num_rows;
    file_buffer.resize(num_rows);
  }

  send_buffer = new double[num_rows];
  // Broadcasts p2p the number of rows to each processor.
  //MPI_Bcast (&num_rows, 1, MPI_INT, 0, MPI_COMM_WORLD);
  if(!rank) {
  for(int i=1; i<size; ++i) {
     
     MPI_Send(&num_rows, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
  }
  }
  for(int i=1; i<size; ++i) {
     
     MPI_Recv(&num_rows, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &stat);
  }
  num_cols = num_rows / size;

  delete [] send_buffer;
  MPI_Finalize();
  return 0;

Какое-нибудь тело, пожалуйста, подскажите мне, как исправить эту ошибку?

Зульфи.

Что я уже пробовал:

Я проверил синтаксис MPI_recv(...). я не могу понять никакой причины блокировки.

MPI_Recv (...) - это блокирующий вызов, но он должен получить данные.

2 Ответов

Рейтинг:
2

Rick York

Вы пробовали вставить туда MPI_Barrier(MPI_COMM_WORLD); call?

Видеть этот вопрос и ответ[^]


Рейтинг:
1

KarstenK

Отправка и получение являются параллельными задачами и поэтому имеют всегда побочные эффекты и они требуют некоторого времени (в миллисекундах). Вам нужно синхронизировать прием и отправку вызовов.

Первая проблема, которую я вижу в вашем коде, заключается в том, что вы не проверяете коды возврата функций.


zak100

Я попробовал следующую программу. У него нет никакого барьера, но он прекрасно работает:

#include <mpi.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

int main(int argc, char **argv)
{
char idstr[100];
char buff[128];
int numprocs;
int myid;
int i;
MPI_Status stat;
/*********************************************
Begin program
*********************************************/
MPI_Init(&argc,&argv); // Initialize
MPI_Comm_size(MPI_COMM_WORLD, &numprocs); // Get # processors
MPI_Comm_rank(MPI_COMM_WORLD, &myid); // Get my rank (id)
if( myid == 0 )
{ // Master
printf("WE have %d processors\n", numprocs);
for( i = 1; i < numprocs; i++)
{
sprintf(buff, "Hello %d", i);
MPI_Send(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD);
}
for( i = 1; i < numprocs; i++)
{
MPI_Recv(buff, 128, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);
printf("%s\n", buff);
}
}
else
{ // Slave
MPI_Recv(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &stat);
sprintf(idstr, "Hello 0, Processor %d is present and accounted for !",myid);
MPI_Send(buff, 128, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
}


/*
$ mpicc -o SR sendRec.c
$ mpirun -np 4 ./SR
WE have 4 processors
Hello 1
Hello 2
Hello 3
$ 
*/

zak100

Нужна ли еще какая-то часть?

Зульфи.