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