The system cannot find the path specified in MPI - mpi

I am writing a sample program MPI in which one process send an integer to other process.
This is my source code
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
// Find out rank, size
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
}
else if (world_rank == 1) {
MPI_Recv(&number, 1, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process 1 received number %d from process 0\n",
number);
}
}
And this is the error when I run mpiexec in windows cmd line
ERROR: Error reported: failed to set work directory to 'D:\study_documents\Thesis\Nam 4\Demo\Sample Codes\MPI_HelloWorld\Debug' on DESKTOP-EKN1RD3
Error (3) The system cannot find the path specified.

Related

MPI_Test returning true flags for requests despite never sending?

I have some code that for testing purposes, I removed all sends and only have non-blocking receives. You can imagine my surprise when using MPI_Test the flags were indicating some of the requests were actually being completed. I have my code setup in a cartesian grid, with a small replica below, although this doesn't reproduce the error:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for sleep
#include <mpi.h>
void test(int pos);
MPI_Comm comm_cart;
int main(int argc, char *argv[])
{
int i, j;
int rank, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* code for mpi cartesian gird topology */
int dim[1];
dim[0] = 2;
int periods[1];
periods[0] = 0;
int reorder = 1;
int coords[1];
MPI_Cart_create(MPI_COMM_WORLD, 1, dim, periods, 1, &comm_cart);
MPI_Cart_coords(comm_cart, rank, 2, coords);
test(coords[0]);
MPI_Finalize();
return (0);
}
void test(int pos)
{
float placeholder[4];
int other = (pos+1) % 2;
MPI_Request reqs[8];
int flags[4];
for(int iter = 0; iter < 20; iter++){
// Test requests from previous time cycle
for(int i=0;i<4;i++){
if(iter == 0) break;
MPI_Test(&reqs[0], &flags[0] , MPI_STATUS_IGNORE);
printf("Flag: %d\n", flags[0]);
}
MPI_Irecv(&placeholder[0], 1, MPI_FLOAT, other, 0, comm_cart, &reqs[0]);
}
}
Any help would be appreciated.
The issue is with MPI_Test and MPI_PROC_NULLs. Quite often when using MPI_Cart_shift, you end up with MPI_PROC_NULLs as if you're on the edge of the grid, a neighbouring cell simply doesn't exist in some directions.
I can't find any documentation for this anywhere, so I had to discover it myself, but when you do an MPI_Irecv with an MPI_PROC_NULL source, it will instantly complete and when tested using MPI_Test, the flag will return true for a completed request. Example code below:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int t;
int flag;
MPI_Request req;
MPI_Irecv(&t, 1, MPI_INT, MPI_PROC_NULL, 0, MPI_COMM_WORLD, &req);
MPI_Test(&req, &flag, MPI_STATUS_IGNORE);
printf("Flag: %d\n", flag);
MPI_Finalize();
return (0);
}
Which returns the following when run:
Flag: 1
Flag: 1

MPI_Send does not fail with destination -1

I am encountering some strange behavior with MPICH. The following minimal example, which sends a message to the non-existing process with rank -1, causes a deadlock:
// Program: send-err
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
MPI_Init(NULL, NULL);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// We are assuming at least 2 processes for this task
if (world_size != 2) {
fprintf(stderr, "World size must be 2 for %s\n", argv[0]);
MPI_Abort(MPI_COMM_WORLD, 1);
}
int number;
if (world_rank == 0) {
number = -1;
MPI_Send(&number, // data buffer
1, // buffer size
MPI_INT, // data type
-1, //destination
0, //tag
MPI_COMM_WORLD); // communicator
} else if (world_rank == 1) {
MPI_Recv(&number,
1, // buffer size
MPI_INT, // data type
0, // source
0, //tag
MPI_COMM_WORLD, // communicator
MPI_STATUS_IGNORE);
}
MPI_Finalize();
}
If the call to the send function,
MPI_Send( start, count, datatype, destination_rank, tag, communicator )
uses destination_rank = -2, then the program fails with the error message:
> mpirun -np 2 send-err
Abort(402250246) on node 0 (rank 0 in comm 0): Fatal error in PMPI_Send: Invalid rank, error stack:
PMPI_Send(157): MPI_Send(buf=0x7fffeb411b44, count=1, MPI_INT, dest=MPI_ANY_SOURCE, tag=0, MPI_COMM_WORLD) failed
PMPI_Send(94).: Invalid rank has value -2 but must be nonnegative and less than 2
Based on the error message, I would expect a program that sends a message to the process with rank -1 to fail similarly to the program sending a message to the process with rank -2. What causes this difference in behavior?

Receiving data in slaves mpi spawn c

I'm trying to implement the following scenario using mpi_comm_spawn & scatter :
1- Master spawns 2 processes with a job.
2- He scatters an array to those spawned processes.
3- The spawned processes receive the scattered array sort it then send it back.
4- The master receives the sorted parts of the array.
I'd like to know how to do the step 2, so far i've tried with send and receives, they work perfectly but i want to do it with the scatter function.
Edit : Here's what i'd like to do in the master code , i'm missing the part in the slave's where i receive the scattered array
/*Master Here*/
MPI_Comm_spawn(slave, MPI_ARGV_NULL, 2, MPI_INFO_NULL,0, MPI_COMM_WORLD, &inter_comm, array_of_errcodes);
printf("MASTER Sending a message to slaves \n");
MPI_Send(message, 50, MPI_CHAR,0 , tag, inter_comm);
MPI_Scatter(array, 10, MPI_INT, &array_r, 10, MPI_INT, MPI_ROOT, inter_comm);
Thanks.
master.c
#include "mpi.h"
int main(int argc, char *argv[])
{
int n_spawns = 2;
MPI_Comm intercomm;
MPI_Init(&argc, &argv);
MPI_Comm_spawn("worker_program", MPI_ARGV_NULL, n_spawns, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomm, MPI_ERRCODES_IGNORE);
int sendbuf[2] = {3, 5};
int recvbuf; // redundant for master.
MPI_Scatter(sendbuf, 1, MPI_INT, &recvbuf, 1, MPI_INT, MPI_ROOT, intercomm);
MPI_Finalize();
return 0;
}
worker.c
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
MPI_Init(&argc, &argv);
MPI_Comm intercomm;
MPI_Comm_get_parent(&intercomm);
int sendbuf[2]; // redundant for worker.
int recvbuf;
MPI_Scatter(sendbuf, 1, MPI_INT, &recvbuf, 1, MPI_INT, 0, intercomm);
printf("recvbuf = %d\n", recvbuf);
MPI_Finalize();
return 0;
}
Command line
mpicc master.c -o master_program
mpicc worker.c -o worker_program
mpirun -n 1 master_program

Sending data to a given communicator

I wonder if it is possible to send data to a 3rd party communicator by having its integer value.
In other words, I would like to send a MPI_Comm (int) to processes in a non-related communicator in order to establish a communication between them.
For example, this picture shows my goal:
For this purpose, I have developed testing codes which intend to transfer the MPI_Comm.
parent.c
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
MPI_Init(NULL, NULL);
int world_size, world_rank;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm children;
int err[world_size], msg;
MPI_Comm_spawn("./children", NULL, 2, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &children, err);
if (world_rank == 0) {
MPI_Send(&children, 1, MPI_INT, 0, 0, children);
MPI_Recv(&msg, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, children, MPI_STATUS_IGNORE);
}
MPI_Finalize();
return (0);
}
children.c
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
MPI_Init(NULL, NULL);
int world_size, world_rank;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm parent;
MPI_Comm_get_parent(&parent);
int comm, msg = 123;
if (world_rank == 0) {
MPI_Recv(&comm, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, parent, MPI_STATUS_IGNORE);
MPI_Comm children = (MPI_Comm) comm;
MPI_Send(&msg, 1, MPI_INT, 0, 0, children);
}
MPI_Finalize();
return (0);
}
Of course, the code does not work due to:
Fatal error in MPI_Send: Invalid communicator, error stack
Is there any way two establish that connection?
PS: This is an example, and I know that if I used "parent" comm in the send of "children.c", it would work. But my intention is to send data to a 3rd party communicator with only its integer id.

MPI_Waitall hangs

I have this MPI program which hangs without completing. Any idea where it is going wrong? May be I am missing something but I cannot think of a possible issue with the code. Changing the order of send and receive doesn't work either. (But I am guessing any order would do due to nonblocking nature of the calls.)
#include <mpi.h>
int main(int argc, char** argv) {
int p = 2;
int myrank;
double in_buf[1];
double out_buf[1];
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Status stat;
MPI_Init(&argc, &argv);
MPI_Comm_rank(comm, &myrank);
MPI_Comm_size(comm, &p);
MPI_Request requests[2];
MPI_Status statuses[2];
if (myrank == 0) {
MPI_Isend(out_buf,1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &requests[0]);
MPI_Irecv(in_buf, 1, MPI_DOUBLE, 1, 1, MPI_COMM_WORLD, &requests[1]);
} else {
MPI_Irecv(in_buf, 1, MPI_DOUBLE, 1, 1, MPI_COMM_WORLD, &requests[0]);
MPI_Isend(out_buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &requests[1]);
}
MPI_Waitall(2, requests, statuses);
printf("Done...\n");
}
Right of the bat it looks like your tags are mismatched.
You post isend from rank 0 with tag=0 but post irecv from rank 1 with tag=1.
I assume you launch two processes as well, right? the int p = 2 doesn't do anything useful.

Resources