首页 > 解决方案 > mpi_intercomm_create 的问题

问题描述

我需要创建一个父进程,它将创建 10 个子进程mpi_comm_spawn。然后我必须创建两个交互器。

父子之间的一个处理两个的倍数。

父亲和孩子之间的其他过程是三的倍数。

因此,有诸如 5,7 之类的进程,它们不属于任何互通者。

MPI_comm_split颜色参数返回的 NULL 通信器可能存在问题MPI_UNDEFINED。我试图在子代码的其他两个部分中删除它:

MPI_Comm_split(MPI_COMM_WORLD, MPI_UNDEFINED, rank, &paresImpares);
MPI_Intercomm_create(paresImpares, 0, iguales, 0, 2, &pares);

但我必须调用 mpi_comm_split 因为它是一个集体功能。

另一种尝试是仅删除 else 子部分中的 MPI_Intercomm_create ,我得到了这个结果:

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$ 

有任何想法吗 ?

代码

#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;
}

标签: cmpiopenmpi

解决方案


您可以直接拆分内部通信器,如下面的代码所示

#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;
}

推荐阅读