I'm a beginner to MPI. When I coded my first program, I came into a tough problem to me.
MPI_Init(&argc, &argv) ;
MPI_Comm_rank( MPI_COMM_WORLD, &rank) ;
MPI_Comm_size( MPI_COMM_WORLD, &size) ;
printf("Process: %d\n", rank);
printf("Procs_num: %d\n", size);
and:
mpicc main.c -o main
mpirun -np 8 main
But all I get is 8 duplicates of:
Process: 0
Procs_num: 1
What I expect to get is:
Process: 0~7
Procs_num: 8
I guess it is because there is no 8 processes in MPI_COMM_WORLD, but I cannot figure out the reason and have no idea about how to solve it.
And I hope you will catch what I want to express. Many thx!!
Apparently you forgot to call MPI_Finalize
Here is the correct code:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main (int argc, char *argv[]) {
int rank, size;
MPI_Init(&argc, &argv) ;
MPI_Comm_rank( MPI_COMM_WORLD, &rank) ;
MPI_Comm_size( MPI_COMM_WORLD, &size) ;
printf("Process: %d\n", rank);
printf("Procs_num: %d\n", size);
MPI_Finalize();
return(0);
}
Then you get your 8 fifferents ranks:
~/mpi_tests/examples > mpirun -np 8 ~/mpi_tests/examples/t
Process: 4
Procs_num: 8
Process: 5
Procs_num: 8
Process: 0
Procs_num: 8
Process: 1
Procs_num: 8
Process: 7
Procs_num: 8
Process: 2
Procs_num: 8
Process: 3
Procs_num: 8
Process: 6
Procs_num: 8
Related
I am trying to do the following with the help of MPI_reduce and MPI_groups. I have created 2 different groups, one having the odd rank processes and another having the even rank processes, but in the new groups they are all numbered from 0 to N. What I am doing is that I am reducing all the values in group 1 and 2 using MPI_SUM. Say group 1 has the following values like-> 1,2,3 and group 2 has the following values say--> 4,5,6 then after reducing in group 1 I am getting 6 and in group2 I am getting 15, I am storing them respectively in recv_val1 and recv_val2. Now what I want to do is that I want to add them together, but whenever I do so, I get some garbage values. Why is this happening?
#include <stdio.h>
#include "mpi.h"
int main( int argc, char *argv[])
{
int myrank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
MPI_Comm_size( MPI_COMM_WORLD, &size );
int color = myrank%2;
int newrank, newsize;
int sendval, maxval,recv_val1,recv_val2;
MPI_Status status;
MPI_Comm newcomm;
MPI_Comm_split (MPI_COMM_WORLD, color, myrank, &newcomm);
MPI_Comm_rank( newcomm, &newrank );
MPI_Comm_size( newcomm, &newsize );
//printf("color and newrank are %d and %d \n", color, newrank);
sendval = newrank;
if(color==0)
MPI_Reduce(&sendval, &recv_val1, 1, MPI_INT, MPI_SUM, 0, newcomm); // find sum
else
MPI_Reduce(&sendval, &recv_val2, 1, MPI_INT, MPI_SUM, 0, newcomm); // find sum
if(newrank == 0 && color == 0)
printf("%d\n", recv_val1);
if(newrank == 0 && color == 1)
printf("%d\n", recv_val2);
if(myrank==0)
printf(" sum is %d\n", recv_val1+recv_val2);
MPI_Comm_free(&newcomm);
MPI_Finalize();
return 0;
}
I use MPI_Put together with MPI_Win_create_dynamic, but it does not work, just stuck before MPI_Win_fence, could not go through, I do not know why?
But when I add MPI_Win_flush, I just got the following errors:
[susans-MacBook-Pro:05235] *** An error occurred in MPI_Win_flush
[susans-MacBook-Pro:05235] *** reported by process [3117416449,1]
[susans-MacBook-Pro:05235] *** on win pt2pt window 3
[susans-MacBook-Pro:05235] *** MPI_ERR_RMA_SYNC: error executing rma sync
[susans-MacBook-Pro:05235] *** MPI_ERRORS_ARE_FATAL (processes in this win will now abort,
[susans-MacBook-Pro:05235] *** and potentially your MPI job)
Is there anything wrong with MPI_Put call?
The source coe is as follows:
```mpi-c++
#include <stdio.h>
#include <iostream>
#include "mpi.h"
using namespace std;
#define NROWS 10
#define NCOLS 10
int main(int argc, char *argv[])
{
int rank, nprocs, A[NROWS][NCOLS], i, j;
MPI_Win win;
MPI_Datatype column, xpose;
int errs = 0;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Win_create_dynamic(MPI_INFO_NULL, MPI_COMM_WORLD, &win);
if(rank==0)
{ /* rank = 0*/
for (i=0; i<NROWS; i++)
for (j=0; j<NCOLS; j++)
A[i][j] = i*NCOLS + j;
MPI_Win_attach(win, A, NROWS*NCOLS*sizeof(int));
}
MPI_Win_fence(0, win);
if (rank > 0)
{
for (i=0; i<NROWS; i++)
for (j=0; j<NCOLS; j++)
A[i][j] = -1;
int target=0,disp=0;
MPI_Get(A, NROWS*NCOLS, MPI_INT, target, disp, NROWS*NCOLS, MPI_INT, win)!=MPI_SUCCESS)
MPI_Win_flush(target,win);
MPI_Win_fence(0, win);
}
else if(rank==0)
{ /* rank = 0 */
MPI_Win_fence(0, win);
MPI_Win_detach(win,A);
}
MPI_Win_free(&win);
MPI_Finalize();
return errs;
}
```
It seems that if I use MPI_Get_address to get the disp of the shared memory, then bcast it ,then it works well.
MPI_Get_address(buf_shared, &disp);
MPI_Bcast(&disp, 1, MPI_AINT, 0, comm);
Is it safe to pass function pointers via MPI as a way of telling another node to call a function? Someone may say that Passing any kind of pointers via MPI is meaningless, but I wrote some code to verify it.
//test.cpp
#include <cstdio>
#include <iostream>
#include <mpi.h>
#include <cstring>
using namespace std;
int f1(int a){return a + 1;}
int f2(int a){return a + 2;}
int f3(int a){return a + 3;}
using F=int (*)(int);
int main(int argc, char *argv[]){
MPI_Init(&argc, &argv);
int rank, size;
MPI_Status state;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//test
char data[10];
if( 0 == rank ){
*(reinterpret_cast<F*>(data))=&f2;
for(int i = 1 ; i < size ; ++i)
MPI_Send(data, 8, MPI_CHAR, i, 0, MPI_COMM_WORLD);
}else{
MPI_Recv(data, 8, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &state);
F* fp = reinterpret_cast<F*>(data);
int ans = (**fp)(10);
cout << ans << endl;
}
MPI_Finalize();
return 0;
}
Here is the output:
12
12
12
12
12
12
12
12
12
I ran it via MVAPICH, and it works well. But I just don't now why since separate address spaces means that the pointer value is USELESS in any process other than the one that generated it.
P.S. here is my hostfile
blade11:1
blade12:1
blade13:1
blade14:1
blade15:1
blade16:1
blade17:1
blade18:2
blade19:1
and I ran mpiexec -n 10 -f hostfile ./test, and compiled it using C++11
You are lucky in the sense that your cluster environment is homogeneous and no address space randomisation for ordinary executables is in place. As a consequence, all images are loaded at the same base address and laid out similarly in memory, hence functions have the same virtual addresses in all MPI ranks (note that this is rarely true for symbols from dynamically linked libraries as those are usually loaded at random addresses).
If you compile the source twice using different compilers or using the same compiler but with different compiler options, then have some ranks run the first executable and the rest run the second one, the program will definitely crash.
Try this:
$ mpicxx -std=c++11 -O0 -o test_O0 test.cpp
$ mpicxx -std=c++11 -O2 -o test_O2 test.cpp
$ mpiexec -f hostfile -n 5 ./test_O0 : -n 5 ./test_O2
12
12
12
12
<crash>
The different levels of optimisation result in function code of different size in test_O0 and test_O2. Consequently, f2 will no longer have the same virtual address in all ranks. The ranks that run the same executable as rank 0 will print 12, while the rest will segfault.
Is it safe to pass function pointers via MPI as a way of telling another node to call a function?
No, it is not. Address space is not shared among processes.
However, MPI processes which are the result of programs built from the same source can be organised to call a specific function when a certain message is received:
char data = 0;
MPI_Recv(data, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &state);
if (data == 255) {
f2(10); /* and so forth */
}
No.
However there is trick involving macros that map a certain codification of a function to a local function pointer/callback that can be recognized in all processes uniformly.
For example, this is used in HPX http://stellar.cct.lsu.edu/files/hpx_0.9.5/html/HPX_PLAIN_ACTION.html to run a function across inhomogeneous systems.
I am following a source code on my documents, but I encounter an error when I try to use MPI_Send() and MPI_Recv() from Open MPI library.
I have googled and read some threads in this site but I can not find the solution to resolve my error.
This is my error:
mca_oob_tcp_msg_recv: readv faled : Unknown error (108)
Here is details image:
And this is the code that I'm following:
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argv, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0/n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
I commented all of MPI_Send(), and MPI_Recv(), and my program worked. In other hand, I commented either MPI_Send() or MPI_Recv(), and I still got that error. So I think the problem are MPI_Send() and MPI_Recv() functions.
P.S.: I'm using Open MPI v1.6 on Windows 8.1 OS.
You pass in the wrong arguments to MPI_Init (two times argv, instead of argc and argv once each).
The sends and receives actually look fine, I think. But there is also one typo in one of your prints with a /n instead of \n.
Here is what works for me (on MacOSX, though):
int main(int argc, char **argv) {
int rank, size, mesg, tag = 123;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (size < 2) {
printf("Need at least 2 processes!\n");
} else if (rank == 0) {
mesg = 11;
MPI_Send(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD);
MPI_Recv(&mesg,1,MPI_INT,1,tag,MPI_COMM_WORLD,&status);
printf("Rank 0 received %d from rank 1\n",mesg);
} else if (rank == 1) {
MPI_Recv(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD,&status);
printf("Rank 1 received %d from rank 0\n",mesg);
mesg = 42;
MPI_Send(&mesg,1,MPI_INT,0,tag,MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
If this does not work, I'd guess your OS does not let the processes communicate with each other via the method chosen by OpenMPI.
Set MPI_STATUS_IGNORED instead of &status in MPI_Recv in both places.
There is a simple communication program that I used in MPICH2. when I execute the program by using
mpiexec.exe -hosts 2 o00 o01 -noprompt mesajlasma.exe
The program starts but does not end. I can see it is still running on the host computer "o01" by using resource monitor program. When I press CTRL + c, it is ended. Then I can see that my program ran properly
Why doesn't my program end. Where does it stuck? why does my program hang when I use MPI_Send and MPI_Recv?
Thanks in advance
// mesajlasma.cpp
#include "stdafx.h"
#include "string.h"
#include "mpi.h"
int main(int argc, char* argv[])
{
int nTasks, rank;
char mesaj[20];
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&nTasks);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
//printf ("\nNumber of threads = %d, My rank = %d\n", nTasks, rank);
if(rank == 1)
{
strcpy_s(mesaj, "Hello World");
if (MPI_SUCCESS==MPI_Send(mesaj, strlen(mesaj)+1, MPI_CHAR, 0, 99, MPI_COMM_WORLD)) printf("_OK!_\n");
}
if(rank == 0)
{
MPI_Recv(mesaj, 20, MPI_CHAR, 1, 99, MPI_COMM_WORLD, &status);
printf("Received Message:%s\n", mesaj);
}
MPI_Finalize();
return 0;
}
You probably also need to pass an argument like -n 2 to your mpiexec.exe command in order to instruct it to launch 2 processes. I believe that the -hosts argument is just an alternative way to specify the hosts on which your program can run, not how many processes will be created.