Blame test/mpi/spawn/pgroup_connect_test.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2003 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/** PGROUP Creation (Connect/Accept Method)
Packit Service c5cf8c
  * James Dinan <dinan@mcs.anl.gov>
Packit Service c5cf8c
  * May, 2011
Packit Service c5cf8c
  *
Packit Service c5cf8c
  * In this test, processes create an intracommunicator and creation is
Packit Service c5cf8c
  * collective only on the members of the new communicator, not on the parent
Packit Service c5cf8c
  * communicator.  This is accomplished by building up and merging
Packit Service c5cf8c
  * intercommunicators using Connect/Accept to merge with a master/controller
Packit Service c5cf8c
  * process.
Packit Service c5cf8c
  */
Packit Service c5cf8c
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <assert.h>
Packit Service c5cf8c
Packit Service c5cf8c
#include <mpi.h>
Packit Service c5cf8c
#include "mpitest.h"
Packit Service c5cf8c
Packit Service c5cf8c
const int verbose = 0;
Packit Service c5cf8c
Packit Service c5cf8c
void PGroup_create(int count, int members[], MPI_Comm * group);
Packit Service c5cf8c
void PGroup_create(int count, int members[], MPI_Comm * group)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, me, nproc, is_member;
Packit Service c5cf8c
    char *port;
Packit Service c5cf8c
    MPI_Comm pgroup;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &me);
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
Packit Service c5cf8c
Packit Service c5cf8c
    if (count == 0) {
Packit Service c5cf8c
        *group = MPI_COMM_NULL;
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    } else if (count == 1 && members[0] == me) {
Packit Service c5cf8c
        *group = MPI_COMM_SELF;
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0, is_member = 0; i < count; i++) {
Packit Service c5cf8c
        if (members[i] == me) {
Packit Service c5cf8c
            is_member = 1;
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    if (!is_member) {
Packit Service c5cf8c
        *group = MPI_COMM_NULL;
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    port = malloc(MPI_MAX_PORT_NAME);
Packit Service c5cf8c
Packit Service c5cf8c
    /* NOTE: Assume members list is identical and sorted on all processes */
Packit Service c5cf8c
Packit Service c5cf8c
    /* I am the leader */
Packit Service c5cf8c
    if (me == members[0]) {
Packit Service c5cf8c
        MPI_Comm pgroup_new;
Packit Service c5cf8c
Packit Service c5cf8c
        pgroup = MPI_COMM_SELF;
Packit Service c5cf8c
Packit Service c5cf8c
        MPI_Open_port(MPI_INFO_NULL, port);
Packit Service c5cf8c
Packit Service c5cf8c
        for (i = 1; i < count; i++) {
Packit Service c5cf8c
            MPI_Comm pgroup_old = pgroup;
Packit Service c5cf8c
Packit Service c5cf8c
            MPI_Send(port, MPI_MAX_PORT_NAME, MPI_CHAR, members[i], 0, MPI_COMM_WORLD);
Packit Service c5cf8c
            MPI_Comm_accept(port, MPI_INFO_NULL, 0, pgroup, &pgroup_new);
Packit Service c5cf8c
            MPI_Intercomm_merge(pgroup_new, 0 /* LOW */ , &pgroup);
Packit Service c5cf8c
Packit Service c5cf8c
            MPI_Comm_free(&pgroup_new);
Packit Service c5cf8c
            if (pgroup_old != MPI_COMM_SELF)
Packit Service c5cf8c
                MPI_Comm_free(&pgroup_old);
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        MPI_Close_port(port);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* I am not the leader */
Packit Service c5cf8c
    else {
Packit Service c5cf8c
        int merged = 0;
Packit Service c5cf8c
        MPI_Comm pgroup_new;
Packit Service c5cf8c
Packit Service c5cf8c
        for (i = 0; i < count; i++) {
Packit Service c5cf8c
            if (members[i] == me) {
Packit Service c5cf8c
                MPI_Recv(port, MPI_MAX_PORT_NAME, MPI_CHAR, members[0], 0, MPI_COMM_WORLD,
Packit Service c5cf8c
                         MPI_STATUS_IGNORE);
Packit Service c5cf8c
                MPI_Comm_connect(port, MPI_INFO_NULL, 0, MPI_COMM_SELF, &pgroup_new);
Packit Service c5cf8c
                MPI_Intercomm_merge(pgroup_new, 1 /* HIGH */ , &pgroup);
Packit Service c5cf8c
                MPI_Comm_free(&pgroup_new);
Packit Service c5cf8c
                merged = 1;
Packit Service c5cf8c
            } else if (merged) {
Packit Service c5cf8c
                MPI_Comm pgroup_old = pgroup;
Packit Service c5cf8c
Packit Service c5cf8c
                MPI_Comm_connect(port, MPI_INFO_NULL, 0, pgroup, &pgroup_new);
Packit Service c5cf8c
                MPI_Intercomm_merge(pgroup_new, 0 /* HIGH */ , &pgroup);
Packit Service c5cf8c
Packit Service c5cf8c
                MPI_Comm_free(&pgroup_new);
Packit Service c5cf8c
                MPI_Comm_free(&pgroup_old);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            /* else => !merged */
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    free(port);
Packit Service c5cf8c
    *group = pgroup;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char **argv)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int me, nproc, i;
Packit Service c5cf8c
    int gsize, *glist;
Packit Service c5cf8c
    MPI_Comm group;
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Init(&argc, &argv);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &me);
Packit Service c5cf8c
    MPI_Comm_size(MPI_COMM_WORLD, &nproc);
Packit Service c5cf8c
Packit Service c5cf8c
    gsize = nproc / 2 + (nproc % 2);
Packit Service c5cf8c
    glist = malloc(gsize * sizeof(int));
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < nproc; i += 2)
Packit Service c5cf8c
        glist[i / 2] = i;
Packit Service c5cf8c
Packit Service c5cf8c
    if (me % 2 == 0) {
Packit Service c5cf8c
        int gme, gnproc;
Packit Service c5cf8c
Packit Service c5cf8c
        PGroup_create(gsize, glist, &group);
Packit Service c5cf8c
        MPI_Barrier(group);
Packit Service c5cf8c
Packit Service c5cf8c
        MPI_Comm_rank(group, &gme);
Packit Service c5cf8c
        MPI_Comm_size(group, &gnproc);
Packit Service c5cf8c
        if (verbose)
Packit Service c5cf8c
            printf("[%d] Group rank = %d, size = %d\n", me, gme, gnproc);
Packit Service c5cf8c
Packit Service c5cf8c
        if (group != MPI_COMM_SELF)
Packit Service c5cf8c
            MPI_Comm_free(&group);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    free(glist);
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Finalize(0);
Packit Service c5cf8c
Packit Service c5cf8c
    return MTestReturnValue(0);
Packit Service c5cf8c
}