1
1

add format parameter and layout format to OMPI_Affinity_str

This commit was SVN r24182.
Этот коммит содержится в:
Terry Dontje 2010-12-16 15:11:17 +00:00
родитель b113b1a382
Коммит 6da16ab0d7
7 изменённых файлов: 318 добавлений и 18 удалений

18
README
Просмотреть файл

@ -561,6 +561,24 @@ Network Support
See http://runtime.bordeaux.inria.fr/knem/ for details on Knem.
Open MPI Extensions
-------------------
- Extensions framework added. See the "Open MPI API Extensions"
section below for more information on compiling and using
extensions.
- The following extensions are included in this version of Open MPI:
- affinity: Provides the OMPI_Affinity_str() routine on retrieving
a string that contains what resources a process is bound to. See
its man page for more details.
- cr: Provides routines to access to checkpoint restart routines.
See ompi/mpiext/cr/mpiext_cr_c.h for a listing of availble
functions.
- example: A non-functional extension; its only purpose is to
provide an example for how to create other extensions.
===========================================================================
Building Open MPI

Просмотреть файл

@ -1,4 +1,4 @@
.\" Copyright 2007-2008 Sun Microsystems, Inc.
.\" Copyright 2007-2010 Oracle and/or its affiliates. All rights reserved.
.\" Copyright (c) 1996 Thinking Machines Corporation
.\" Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
.TH OMPI_Affinity_str 3 "#OMPI_DATE#" "#PACKAGE_VERSION#" "#PACKAGE_NAME#"
@ -12,7 +12,8 @@
#include <mpi.h>
#include <mpi-ext.h>
int OMPI_Affinity_str(char \fIompi_bound\fP[OMPI_AFFINITY_STRING_MAX],
int OMPI_Affinity_str(ompi_affinity_fmt_type_t \fIfmt_type\fP,
char \fIompi_bound\fP[OMPI_AFFINITY_STRING_MAX],
char \fIcurrent_binding\fP[OMPI_AFFINITY_STRING_MAX],
char \fIexists\fP[OMPI_AFFINITY_STRING_MAX])
.fi
@ -21,6 +22,22 @@ There is no Fortran binding for this function.
.
.SH C++ Syntax
There is no C++ binding for this function.
.
.SH INPUT PARAMETERS
.ft R
.TP 1i
fmt_type
An enum indicating how to format the returned ompi_bound and
current_binding strings. OMPI_AFFINITY_RSRC_STRING_FMT returns the
string as human-readable resource names, such as "socket 0, core 0".
OMPI_AFFINITY_LAYOUT_FMT returns ASCII art representing where this MPI
process is bound relative to the machine resource layout. For example
"[. B][. .]" shows the process that called the routine is bound to
socket 0, core 1 in a system with 2 sockets, each containing 2 cores.
See below for more output examples.
.
.SH OUTPUT PARAMETERS
.ft R
@ -80,7 +97,100 @@ that this process can see (which is
.I usually
all processors in the system).
.SH SEE ALSO
.SH Examples
.ft R
\fBExample 1:\fP Print out processes binding using resource string format.
.sp
.nf
int rank;
char ompi_bound[OMPI_AFFINITY_STRING_MAX];
char current_binding[OMPI_AFFINITY_STRING_MAX];
char exists[OMPI_AFFINITY_STRING_MAX];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
OMPI_Affinity_str(OMPI_AFFINITY_RSRC_STRING_FMT,
ompi_bound, current_binding, exists);
printf("rank %d: \\n"
" ompi_bound: %s\\n"
" current_binding: %s\\n"
" exists: %s\\n",
rank, ompi_bound, current_binding, exists);
...
.fi
.PP
Output of mpirun -np 2 -bind-to-core a.out:
.nf
rank 0:
ompi_bound: socket 0[core 0]
current_binding: socket 0[core 0]
exists: socket 0 has 4 cores
rank 1:
ompi_bound: socket 0[core 1]
current_binding: socket 0[core 1]
exists: socket 0 has 4 cores
.fi
.PP
Output of mpirun -np 2 -bind-to-socket a.out:
.nf
rank 0:
ompi_bound: socket 0[core 0-3]
current_binding: Not bound (or bound to all available processors)
exists: socket 0 has 4 cores
rank 1:
ompi_bound: socket 0[core 0-3]
current_binding: Not bound (or bound to all available processors)
exists: socket 0 has 4 cores
.fi
.sp
.br
\fBExample 2:\fP Print out processes binding using layout string format.
.sp
.nf
int rank;
char ompi_bound[OMPI_AFFINITY_STRING_MAX];
char current_binding[OMPI_AFFINITY_STRING_MAX];
char exists[OMPI_AFFINITY_STRING_MAX];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
OMPI_Affinity_str(OMPI_AFFINITY_LAYOUT_FMT,
ompi_bound, current_binding, exists);
printf("rank %d: \\n"
" ompi_bound: %s\\n"
" current_binding: %s\\n"
" exists: %s\\n",
rank, ompi_bound, current_binding, exists);
...
.fi
.PP
Output of mpirun -np 2 -bind-to-core a.out:
.nf
rank 0:
ompi_bound: [B . . .]
current_binding: [B . . .]
exists: [. . . .]
rank 1:
ompi_bound: [. B . .]
current_binding: [. B . .]
exists: [. . . .]
.fi
.PP
Output of mpirun -np 2 -bind-to-socket a.out:
.nf
rank 0:
ompi_bound: [B B B B]
current_binding: [B B B B]
exists: [. . . .]
rank 1:
ompi_bound: [B B B B]
current_binding: [B B B B]
exists: [. . . .]
.fi
.SH See Also
.ft R
.nf
mpirun(1)

Просмотреть файл

@ -1,10 +1,16 @@
Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
Jeff Squyres
19 April 2010
Terry Dontje
18 November 2010
This extension provides a single new function, OMPI_Affinity_str(),
that provides 3 prettyprint strings as output:
that takes a format value and then provides 3 prettyprint strings as output:
fmt_type: is an enum that tells OMPI_Affinity_str() whether to use a resource description
string or layout string format for ompi_bound and currently_bound output strings.
ompi_bound: describes what sockets/cores Open MPI bound this process
to (or indicates that Open MPI did not bind this process).

Просмотреть файл

@ -3,6 +3,7 @@
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -32,12 +33,15 @@
static const char FUNC_NAME[] = "OMPI_Affinity";
static int fill_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX]);
static int fill_current_binding(char str[OMPI_AFFINITY_STRING_MAX]);
static int fill_exists(char str[OMPI_AFFINITY_STRING_MAX]);
static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX]);
static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX]);
static int get_rsrc_exists(char str[OMPI_AFFINITY_STRING_MAX]);
static int get_layout_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX]);
static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX]);
static int get_layout_exists(char str[OMPI_AFFINITY_STRING_MAX]);
int OMPI_Affinity_str(char ompi_bound[OMPI_AFFINITY_STRING_MAX],
int OMPI_Affinity_str(ompi_affinity_fmt_t fmt_type,
char ompi_bound[OMPI_AFFINITY_STRING_MAX],
char current_binding[OMPI_AFFINITY_STRING_MAX],
char exists[OMPI_AFFINITY_STRING_MAX])
{
@ -46,16 +50,29 @@ int OMPI_Affinity_str(char ompi_bound[OMPI_AFFINITY_STRING_MAX],
memset(ompi_bound, 0, sizeof(ompi_bound));
memset(current_binding, 0, sizeof(current_binding));
if (OPAL_SUCCESS != (ret = fill_ompi_bound(ompi_bound)) ||
OPAL_SUCCESS != (ret = fill_current_binding(current_binding)) ||
OPAL_SUCCESS != (ret = fill_exists(exists))) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
switch(fmt_type) {
case OMPI_AFFINITY_RSRC_STRING_FMT:
if (OPAL_SUCCESS != (ret = get_rsrc_ompi_bound(ompi_bound)) ||
OPAL_SUCCESS != (ret = get_rsrc_current_binding(current_binding)) ||
OPAL_SUCCESS != (ret = get_rsrc_exists(exists))) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
}
break;
case OMPI_AFFINITY_LAYOUT_FMT:
if (OPAL_SUCCESS != (ret = get_layout_ompi_bound(ompi_bound)) ||
OPAL_SUCCESS != (ret = get_layout_current_binding(current_binding)) ||
OPAL_SUCCESS != (ret = get_layout_exists(exists))) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, ret, FUNC_NAME);
}
break;
default:
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
}
return MPI_SUCCESS;
}
static int fill_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
static int get_rsrc_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
{
int ret;
opal_paffinity_base_cpu_set_t cset;
@ -78,7 +95,7 @@ static int fill_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
return opal_paffinity_base_cset2str(str, OMPI_AFFINITY_STRING_MAX, &cset);
}
static int fill_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
static int get_rsrc_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
{
int ret, flag;
opal_paffinity_base_cpu_set_t cset;
@ -102,7 +119,7 @@ static int fill_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
/* Prettyprint a list of all available processors */
static int fill_exists(char str[OMPI_AFFINITY_STRING_MAX])
static int get_rsrc_exists(char str[OMPI_AFFINITY_STRING_MAX])
{
int ret, i, num_sockets, num_cores;
char tmp[BUFSIZ];
@ -137,3 +154,83 @@ static int fill_exists(char str[OMPI_AFFINITY_STRING_MAX])
return OPAL_SUCCESS;
}
static int get_layout_ompi_bound(char str[OMPI_AFFINITY_STRING_MAX])
{
int ret;
opal_paffinity_base_cpu_set_t cset;
/* If OMPI did not bind, indicate that */
if (!opal_paffinity_base_bound) {
const char tmp[] = "Open MPI did not bind this process";
strncpy(str, tmp, OMPI_AFFINITY_STRING_MAX - 1);
return OPAL_SUCCESS;
}
/* Find out what OMPI bound us to and prettyprint it */
ret =
opal_paffinity_base_parse_binding(opal_paffinity_base_applied_binding,
&cset);
if (OPAL_SUCCESS != ret) {
return ret;
}
return opal_paffinity_base_cset2mapstr(str, OMPI_AFFINITY_STRING_MAX, &cset);
}
static int get_layout_current_binding(char str[OMPI_AFFINITY_STRING_MAX])
{
int ret = OPAL_SUCCESS, flag;
opal_paffinity_base_cpu_set_t cset;
/* Get our binding */
ret = opal_paffinity_base_get(&cset);
if (OPAL_SUCCESS != ret) {
return ret;
}
/* Are we bound anywhere? */
OPAL_PAFFINITY_PROCESS_IS_BOUND(cset, &flag);
if (!flag) {
const char tmp[] = "Not bound (or bound to all available processors)";
strncat(str, tmp, OMPI_AFFINITY_STRING_MAX - 1);
return OPAL_SUCCESS;
}
return opal_paffinity_base_cset2mapstr(str, OMPI_AFFINITY_STRING_MAX, &cset);
}
/* Prettyprint a list of all available processors in layout format*/
static int get_layout_exists(char str[OMPI_AFFINITY_STRING_MAX])
{
int ret, i, j, num_sockets, num_cores;
int len = OMPI_AFFINITY_STRING_MAX;
str[0] = '\0';
/* Loop over the number of sockets in this machine */
ret = opal_paffinity_base_get_socket_info(&num_sockets);
if (OPAL_SUCCESS != ret) {
return ret;
}
for (i = 0; i < num_sockets; ++i) {
strncat(str, "[", len - strlen(str));
/* Loop over the number of cores in this socket */
ret = opal_paffinity_base_get_core_info(i, &num_cores);
if (OPAL_SUCCESS != ret) {
return ret;
}
for (j = 0; j < num_cores; j++) {
if (0 < j) {
/* add space after first core is printed */
strncat(str, " ", len - strlen(str));
}
/* mark core exists */
strncat(str, ".", len - strlen(str));
}
strncat(str, "]", len - strlen(str));
}
return OPAL_SUCCESS;
}

Просмотреть файл

@ -2,6 +2,7 @@
* Copyright (c) 2004-2009 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -12,7 +13,12 @@
#define OMPI_AFFINITY_STRING_MAX 1024
OMPI_DECLSPEC int OMPI_Affinity_str(char ompi_bound[OMPI_AFFINITY_STRING_MAX],
typedef enum ompi_affinity_fmt {
OMPI_AFFINITY_RSRC_STRING_FMT,
OMPI_AFFINITY_LAYOUT_FMT
} ompi_affinity_fmt_t;
OMPI_DECLSPEC int OMPI_Affinity_str(ompi_affinity_fmt_t fmt_type,
char ompi_bound[OMPI_AFFINITY_STRING_MAX],
char current_binding[OMPI_AFFINITY_STRING_MAX],
char exists[OMPI_AFFINITY_STRING_MAX]);

Просмотреть файл

@ -10,6 +10,7 @@
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007-2010 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
@ -276,6 +277,12 @@ OPAL_DECLSPEC int opal_paffinity_base_slot_list_set(long rank, char *slot_str,
OPAL_DECLSPEC int opal_paffinity_base_cset2str(char *str, int len,
opal_paffinity_base_cpu_set_t *cset);
/**
* Make a prettyprint string for a cset with a map format.
*/
OPAL_DECLSPEC int opal_paffinity_base_cset2mapstr(char *str, int len,
opal_paffinity_base_cpu_set_t *cset);
/**
* Debugging output stream
*/

Просмотреть файл

@ -11,6 +11,7 @@
* All rights reserved.
* Copyright (c) 2007-2010 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2008 Voltaire. All rights reserved
* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
*
* $COPYRIGHT$
*
@ -607,4 +608,59 @@ int opal_paffinity_base_cset2str(char *str, int len,
return OPAL_SUCCESS;
}
/**
* Make a prettyprint string for a cset in a map format.
* Example: [B_/__]
* Key: [] - signifies socket
* / - signifies core
* _ - signifies thread a process not bound to
* B - signifies thread a process is bound to
*/
int opal_paffinity_base_cset2mapstr(char *str, int len,
opal_paffinity_base_cpu_set_t *cset)
{
int ret, i, j, k, m, num_sockets, num_cores, flag, count,
range_first=0, range_last;
char tmp[BUFSIZ];
const int stmp = sizeof(tmp) - 1;
str[0] = tmp[stmp] = '\0';
/* Loop over the number of sockets in this machine */
ret = opal_paffinity_base_get_socket_info(&num_sockets);
if (OPAL_SUCCESS != ret) {
return ret;
}
for (i = 0; i < num_sockets; ++i) {
strncat(str, "[", len - strlen(str));
/* Loop over the number of cores in this socket */
ret = opal_paffinity_base_get_core_info(i, &num_cores);
if (OPAL_SUCCESS != ret) {
return ret;
}
for (j = 0; j < num_cores; j++) {
if (0 < j) {
/* add space after first core is printed */
strncat(str, " ", len - strlen(str));
}
ret = opal_paffinity_base_get_map_to_processor_id(i, j, &k);
if (OPAL_SUCCESS != ret) {
return ret;
}
flag = OPAL_PAFFINITY_CPU_ISSET(k, *cset);
if (flag) {
/* mark core as bound to process */
strncat(str, "B", len - strlen(str));
} else {
/* mark core as no process bound to it */
strncat(str, ".", len - strlen(str));
}
}
strncat(str, "]", len - strlen(str));
}
return OPAL_SUCCESS;
}