MPI SEND and RECEIVE

let say we have a vector of vector of vector of type integer.
The out vector is referring to the number of processors. Let's say that this vector is something like Vec 2*3*10.
I want just send two inner vectors into all processors and receive them by all processors. but I get this error"Fatal error in MPI_Send: Other MPI error, error stack:
MPI_Send(buf=0x010FF358, count=3, MPI_INT, dest=0, tag=0, MPI_COMM_WORLD) failed
DEADLOCK: attempting to send a message to the local process without a prior matching receive"

my code is like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class MPI_CALL {

public:
	size_t sendto;
	size_t receive;
	VecIdx_t * Vector;

	MPI_CALL() = default;
	void Send_to(size_t sendto, VecIdx_t * Vector);
	void Receive_from(size_t receive, VecIdx_t * Vector);
};


void MPI_CALL::Send_to(size_t sendto, VecIdx_t * Vector)
{
	size_t Vector_size = Vector->size();
	MPI_Send(&Vector, Vector_size, MPI_INT, sendto, 0, MPI_COMM_WORLD);
}


void MPI_CALL::Receive_from(size_t receive, VecIdx_t * Vector)
{
	size_t Vector_size = Vector->size();
	MPI_Status status;
	MPI_Recv(&Vector, Vector_size, MPI_INT, receive, 0, MPI_COMM_WORLD, &status);
};

and in the main I say

	MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

if (myrank==0)
{
for (int i=0;i<2;i++){
vector<vector<int>Vec1;
Vec1=Vec[i];
for (int i_proc=0;i_proc<num_procs;i++){

                        MPI_CALL call_mpisend;
			call_mpisend.Send_to(i_proc, &Vec1[0]);
}
else
{
			MPI_CALL call_mpireceive;
			call_mpireceive.Receive_from(0, &Vec1[0]);

		}
      }
}
Last edited on
MPI_CALL call_mpisend;
call_mpisend.Send_to(i_proc, &Vec1[0]);
MPI_CALL call_mpireceive;
call_mpireceive.Receive_from(0, &Vec1[0]);
I know almost literally nothing about MPI, but this does not look right. Shouldn't the thread/process/whatever that you want to perform the computation on be calling Receive_from()? What purpose could it possibly serve to call Send_to() and Receive_from() in the same thread?
Thanks for your answer, yes in this case you are right,it was just my mistake when I was writing the short version of code here.i fixed this but still I have error
None of the member variables (line 4...6) are used. Hence the MPI_CALL is rather useless.

Line 17/25 You send/receive the pointer of the pointer to Vector (VecIdx_t **) which looks wrong.
Maybe you mean Vector->data()?

The same for &Vec1[0] (line 41/44); Vec1.data()?
Are you starting the slave processes before the master process?
@resabzr
You are making everything unnecessarily difficult

Just send a reference to the data buffer of std::vector and use standard MPI calls!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <vector>
#include "mpi.h"
using namespace std;

int main( int argc, char* argv[] )
{
   int rank, nproc;
   MPI_Status stat;

   MPI_Init( &argc, &argv );
   MPI_Comm_size( MPI_COMM_WORLD, &nproc );
   MPI_Comm_rank( MPI_COMM_WORLD, &rank  );

   int tag = 1;
   if ( rank == 0 )                                   // Root processor (0)
   {
      vector<double> A = { 10, 20, 30, 40, 50 };                           // Some data
      int n = A.size();
      MPI_Send( &n, 1, MPI_INT, 1, tag, MPI_COMM_WORLD );                  // Send size to 1
      MPI_Send( A.data(), n, MPI_DOUBLE, 1, tag, MPI_COMM_WORLD );         // Send data to 1
   }
   else if ( rank == 1 )                              // Next processor (1)
   {
      int n;
      MPI_Recv( &n, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &stat );           // Receive size from 0
      vector<double> B(n);                                                 // Allocate buffer
      MPI_Recv( B.data(), n, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD, &stat );  // Receive data from 0

      cout << "Processor " << rank << " received " << n << " pieces of data: ";
      for ( double x : B ) cout << x << " ";
      cout << '\n';
   }
   MPI_Finalize();
}


C:\c++>"C:\Program Files\Microsoft MPI\bin"\mpiexec -n 2 test 

Processor 1 received 5 pieces of data: 10 20 30 40 50 



And if you are sending to more processors use MPI_Bcast, not MPI_Send.
Last edited on
@ coder777
you mean something like this?
1
2
3
4
5
6
7
8
MPI_CALL call_mpisend;
VecIdx_t * Vec1 = call_mpisend.Vector;
call_mpisend.Send_to(i_proc, Connectivities.data());

and similarly for receive part
MPI_CALL call_mpireceive;
VecIdx_t *Vec1= call_mpireceive.Vector;
call_mpireceive.Receive_from(0, Vec1.data());


but it says function does not take 1 argument
@ lastchance thanks for your answer
@helios
No
Topic archived. No new replies allowed.