Reputation: 3
i need to create a father process which will create 10 child processes with mpi_comm_spawn
. Then I have to create two intercommunicators.
One between the father and child processes multiples of two.
Other between the father and child processes multiples of three.
So there are processes such 5,7, etc that they wont belong to any intercommunicator.
There could be a problem with the NULL comunicator returned by MPI_comm_split
wiht the color parameter MPI_UNDEFINED
.
I've tried to remove this in the two else parts in the child code:
MPI_Comm_split(MPI_COMM_WORLD, MPI_UNDEFINED, rank, &paresImpares);
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 2, &pares);
but I must call mpi_comm_split becouse it's a collective function.
Another try was remove only MPI_Intercomm_create in the else child's parts and i get this result:
juan@um18:~/Documentos/EjemplosMPI$ mpirun -np 1 ejecutables/exfeb2019f2-1
Valor = 0 del proceso con rango 0 en MPI_COMM_WORLD y rango 0 en Pares
Valor = 0 del proceso con rango 8 en MPI_COMM_WORLD y rango 4 en Pares
Valor = 0 del proceso con rango 4 en MPI_COMM_WORLD y rango 2 en Pares
Valor = 0 del proceso con rango 2 en MPI_COMM_WORLD y rango 1 en Pares
Valor = 0 del proceso con rango 6 en MPI_COMM_WORLD y rango 3 en Pares
^C[warn] Epoll ADD(4) on fd 68 failed. Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
[warn] Epoll ADD(4) on fd 47 failed. Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
[warn] Epoll ADD(4) on fd 52 failed. Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
[warn] Epoll ADD(4) on fd 70 failed. Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
[warn] Epoll ADD(4) on fd 62 failed. Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
juan@um18:~/Documentos/EjemplosMPI$
Any ideas ?
Code
#include "stdio.h"
#include "mpi.h"
#define PROCESOS 10
int main(int argc, char *argv[])
{
int rank, localrank, size, color, color3, aleatorios2[PROCESOS], aleatorios3[PROCESOS], valor;
MPI_Comm intercom, iguales, paresImpares, pares, m3;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_get_parent(&intercom); // Para conocer si tiene padre o no
if (intercom == MPI_COMM_NULL)
{
if (size > 1)
{
printf("No puede haber mas de un padre\n");
MPI_Finalize();
return 0;
}
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESOS, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercom, MPI_ERRCODES_IGNORE);
MPI_Intercomm_merge(intercom, 0, &iguales);
MPI_Intercomm_create(MPI_COMM_SELF, 0, iguales, 1, 2, &pares);
MPI_Intercomm_create(MPI_COMM_SELF, 0, iguales, 2, 1, &m3);
int cont2 = 0;
int cont3 = 0;
//generamos los aleatorios
for (int i = 0; i < PROCESOS; i++)
{
if (i % 2 == 0)
{
aleatorios2[cont2] = i;
cont2 += 1;
}
/*
else
{
aleatorios3[cont3] = i;
cont3 += i;
}*/
if (i % 3 == 0)
{
aleatorios3[cont3] = i;
cont3 += i;
}
}
}
else
{
valor = 0;
/* code */
MPI_Intercomm_merge(intercom, 1, &iguales);
color = rank % 2;
/*
MPI_Comm_split(MPI_COMM_WORLD, color, rank, &paresImpares);
if (color == 0)
{
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 2, &pares);
//MPI_Scatter(aleatorios2, 1, MPI_INT, &valor, 1, MPI_INT, 0, pares);
MPI_Comm_rank(pares, &localrank);
printf("Valor = %d del proceso con rango %d en MPI_COMM_WORLD y rango %d en Pares \n", valor, rank, localrank);
}
else
{
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 1, &m3);
//MPI_Scatter(aleatorios3, 1, MPI_INT, &valor, 1, MPI_INT, 0, m3);
MPI_Comm_rank(m3, &localrank);
printf("Valor = %d del proceso con rango %d en MPI_COMM_WORLD y rango %d en impares \n", valor, rank, localrank);
}
*/
if (color == 0)
{
MPI_Comm_split(MPI_COMM_WORLD, color, rank, &paresImpares);
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 2, &pares);
//MPI_Scatter(aleatorios2, 1, MPI_INT, &valor, 1, MPI_INT, 0, pares);
MPI_Comm_rank(pares, &localrank);
printf("Valor = %d del proceso con rango %d en MPI_COMM_WORLD y rango %d en Pares \n", valor, rank, localrank);
}
else
{
MPI_Comm_split(MPI_COMM_WORLD, MPI_UNDEFINED, rank, &paresImpares);
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 2, &pares);
}
color3 = rank % 3;
if (color3 == 0)
{
MPI_Comm_split(MPI_COMM_WORLD, color3, rank, &paresImpares);
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 1, &m3);
//MPI_Scatter(aleatorios3, 1, MPI_INT, &valor, 1, MPI_INT, 0, m3);
MPI_Comm_rank(m3, &localrank);
printf("Valor = %d del proceso con rango %d en MPI_COMM_WORLD y rango %d en Pares \n", valor, rank, localrank);
}
else
{
MPI_Comm_split(MPI_COMM_WORLD, MPI_UNDEFINED, rank, &paresImpares);
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 1, &m3);
}
}
MPI_Finalize();
return 0;
}
Upvotes: 0
Views: 543
Reputation: 8380
You can directly split the inter communicator as in the code below
#include <stdbool.h>
#include "stdio.h"
#include "mpi.h"
#define PROCESOS 10
int main(int argc, char *argv[])
{
int rank, localrank, size, color;
MPI_Comm intercom, pares, m3;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
bool parent = false;
MPI_Comm_get_parent(&intercom); // Para conocer si tiene padre o no
if (intercom == MPI_COMM_NULL)
{
parent = true;
if (size > 1)
{
printf("No puede haber mas de un padre\n");
MPI_Finalize();
return 0;
}
MPI_Comm_spawn(argv[0], MPI_ARGV_NULL, PROCESOS, MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercom, MPI_ERRCODES_IGNORE);
}
if (parent) {
color = 0;
} else if (0 == rank%2) {
color = 0;
} else {
color = MPI_UNDEFINED;
}
MPI_Comm_split(intercom, color, rank, &pares);
if (!parent && MPI_COMM_NULL != pares) {
MPI_Comm_rank(pares, &localrank);
printf("Child with rank %d in MPI_COMM_WORLD and rank %d in pares\n", rank, localrank);
}
if (MPI_COMM_NULL != pares) {
int inter;
MPI_Comm_test_inter(pares, &inter);
printf ("%s rank %d(%d) : %s an inter communicator\n", parent?"parent":"child ", parent?0:localrank, rank, inter?"IS":"is NOT");
}
if (parent) {
color = 0;
} else if (0 == rank%3) {
color = 0;
} else {
color = MPI_UNDEFINED;
}
MPI_Comm_split(intercom, color, rank, &m3);
if (!parent && MPI_COMM_NULL != m3) {
MPI_Comm_rank(m3, &localrank);
printf("Child with rank %d in MPI_COMM_WORLD and rank %d in m3\n", rank, localrank);
}
if (MPI_COMM_NULL != pares) {
int inter;
MPI_Comm_test_inter(pares, &inter);
printf ("%s rank %d(%d) : %s an inter communicator\n", parent?"parent":"child ", parent?0:localrank, rank, inter?"IS":"is NOT");
}
MPI_Finalize();
return 0;
}
Upvotes: 1