1
1

* Add "serialization" of ompi_rte_schedule_t structs for sending over sockets

or rsh/ssh stdin/stdout, even includes a test case
* add base function for use when PCMs can't provide uniqueness strings, so
  that we all have the same value

This commit was SVN r2082.
Этот коммит содержится в:
Brian Barrett 2004-08-12 06:55:04 +00:00
родитель 620ccad317
Коммит 192ff6867f
13 изменённых файлов: 616 добавлений и 7 удалений

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

@ -936,6 +936,8 @@ AC_CONFIG_FILES([
test/mca/ns/Makefile
test/mca/llm/Makefile
test/mca/llm/base/Makefile
test/mca/pcm/Makefile
test/mca/pcm/base/Makefile
test/threads/Makefile
test/util/Makefile
test/rte/Makefile

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

@ -20,8 +20,10 @@ headers = \
libmca_pcm_base_la_SOURCES = \
$(headers) \
pcm_base_close.c \
pcm_base_comm.c \
pcm_base_open.c \
pcm_base_select.c
pcm_base_select.c \
pcm_base_util.c
# Conditionally install the header files

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

@ -23,6 +23,18 @@ extern "C" {
int mca_pcm_base_select(bool *allow_multi_user_threads,
bool *have_hidden_threads);
int mca_pcm_base_close(void);
char* mca_pcm_base_no_unique_name(void);
int mca_pcm_base_send_schedule(FILE *fd,
ompi_rte_node_schedule_t *sched,
ompi_list_t *nodelist);
int mca_pcm_base_recv_schedule(FILE *fd,
ompi_rte_node_schedule_t *sched,
ompi_list_t *nodelist);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif

377
src/mca/pcm/base/pcm_base_comm.c Обычный файл
Просмотреть файл

@ -0,0 +1,377 @@
/*
* $HEADER$
*/
#include "ompi_config.h"
#include "class/ompi_list.h"
#include "mca/pcm/base/base.h"
#define START_KEY "@MCA_PCM@\n"
#define END_KEY "@MCA_PCM_END@\n"
#define NODE_KEY "@MCA_PCM_NODE@\n"
#define PROTOCOL_VERSION 1
int
mca_pcm_base_send_schedule(FILE *fp,
ompi_rte_node_schedule_t *sched,
ompi_list_t *nodelist)
{
int i, envc;
ompi_list_item_t *node_item, *info_item;
ompi_rte_node_allocation_t *node;
ompi_rte_valuepair_t *valpair;
fprintf(fp, START_KEY);
fprintf(fp, "%d\n", PROTOCOL_VERSION);
/* ARGC */
fprintf(fp, "%d\n", sched->argc);
for (i = 0 ; i < sched->argc ; ++i) {
fprintf(fp, "%d %s\n", (int) strlen((sched->argv)[i]),
(sched->argv)[i]);
}
/* ENV - since we don't have a envc, must create ourselves...*/
for (envc = 0 ; (sched->env)[envc] != NULL ; ++envc) ;
fprintf(fp, "%d\n", envc);
for (i = 0 ; i < envc ; ++i) {
fprintf(fp, "%d %s\n", (int) strlen((sched->env)[i]),
(sched->env)[i]);
}
/* CWD */
fprintf(fp, "%d %s\n", (int) strlen(sched->cwd),
(strlen(sched->cwd) > 0) ? sched->cwd : "");
fflush(fp);
/* NODE LIST */
fprintf(fp, "%d\n", (int) ompi_list_get_size(nodelist));
for (node_item = ompi_list_get_first(nodelist) ;
node_item != ompi_list_get_end(nodelist) ;
node_item = ompi_list_get_next(node_item)) {
node = (ompi_rte_node_allocation_t*) node_item;
fprintf(fp, NODE_KEY);
fprintf(fp, "%d %s\n", (int) strlen(node->hostname),
node->hostname);
fprintf(fp, "%d\n", node->count);
/* INFO */
fprintf(fp, "%d\n", (int) ompi_list_get_size(&(node->info)));
for (info_item = ompi_list_get_first(&(node->info)) ;
info_item != ompi_list_get_end(&(node->info)) ;
info_item = ompi_list_get_next(info_item)) {
valpair = (ompi_rte_valuepair_t*) info_item;
fprintf(fp, "%d %d %s %s\n",
(int) strlen(valpair->key), (int) strlen(valpair->value),
valpair->key, valpair->value);
}
}
/*
* so we've basically ignored the fact we might error out up until
* this point, which probably won't hurt anything. But do a quick
* check that the other side hasn't dropped our connection yet.
*
* Do this before the last print so we don't get swapped out and
* accidently catch an eof or something
*/
if (feof(fp) || ferror(fp)) return OMPI_ERROR;
fprintf(fp, END_KEY);
/*
* don't check eof, because it is possible we got swapped out for
* a bit and caught the other side going bye-bye
*/
if (ferror(fp)) return OMPI_ERROR;
return OMPI_SUCCESS;
}
static int
get_key(FILE *fp, const char *key)
{
size_t pos = 0;
size_t len;
int val;
len = strlen(key);
while (pos < len) {
val = fgetc(fp);
if (val == EOF) {
if (feof(fp)) {
/* BWB: probably want to back off at some point */
clearerr(fp);
} else {
return OMPI_ERROR;
}
} else {
if (val == key[pos]) {
pos++;
} else if (pos != 0) {
/* this wasn't the key - start looking again */
pos = 0;
}
}
}
return OMPI_SUCCESS;
}
static int
get_check_version(FILE *fp)
{
int ret;
int ver;
ret = fscanf(fp, "%d\n", &ver);
if (ret != 1) return OMPI_ERROR;
if (ver != PROTOCOL_VERSION) return OMPI_ERROR;
return OMPI_SUCCESS;
}
static int
get_string(FILE *fp, char **strp)
{
int len;
int ret;
char *str;
size_t str_read;;
ret = fscanf(fp, "%d ", &len);
if (ret != 1) return OMPI_ERROR;
str = (char*) malloc(sizeof(char) * (len + 2));
if (NULL == str) return OMPI_ERROR;
str_read = fread(str, len, 1, fp);
if (str_read != 1) {
free(str);
return OMPI_ERROR;
}
/* just in case */
str[len] = '\0';
ret = fgetc(fp);
if (ret != '\n') {
free(str);
return OMPI_ERROR;
}
*strp = str;
return OMPI_SUCCESS;
}
static int
get_argv_array(FILE *fp, int *argcp, char ***argvp)
{
int ret;
int len;
int i, j;
char **argv;
ret = fscanf(fp, "%d\n", &len);
if (ret != 1) return OMPI_ERROR;
argv = (char**) malloc(sizeof(char*) * (len + 1));
if (NULL == argv) return OMPI_ERROR;
/* NULL terminiate the array */
argv[len] = NULL;
for (i = 0 ; i < len ; ++i) {
ret = get_string(fp, &(argv[i]));
if (OMPI_SUCCESS != ret) {
for (j = 0 ; j < len ; ++i) {
free(argv[j]);
}
free(argv);
return OMPI_ERROR;
}
}
*argcp = len;
*argvp = argv;
return OMPI_SUCCESS;
}
static int
get_keyval(FILE *fp, char **keyp, char **valp)
{
int ret;
char *key, *val;
int keylen, vallen;
size_t str_read;;
ret = fscanf(fp, "%d %d ", &keylen, &vallen);
if (ret != 2) return OMPI_ERROR;
key = (char*) malloc(sizeof(char) * (keylen + 2));
if (NULL == key) return OMPI_ERROR;
val = (char*) malloc(sizeof(char) * (vallen + 2));
if (NULL == val) {
free(key);
return OMPI_ERROR;
}
/* get the key */
str_read = fread(key, keylen, 1, fp);
if (str_read != 1) {
free(key);
free(val);
return OMPI_ERROR;
}
/* get the space */
ret = fgetc(fp);
if (ret != ' ') {
free(key);
free(val);
return OMPI_ERROR;
}
/* get the value */
str_read = fread(val, vallen, 1, fp);
if (str_read != 1) {
free(key);
free(val);
return OMPI_ERROR;
}
/* get the end of line newline */
ret = fgetc(fp);
if (ret != '\n') {
free(key);
free(val);
return OMPI_ERROR;
}
return OMPI_SUCCESS;
}
static int
get_nodeinfo(FILE *fp, ompi_list_t info)
{
ompi_rte_valuepair_t *newinfo;
int ret;
int info_len;
int i;
ret = fscanf(fp, "%d\n", &info_len);
if (ret != 1) return OMPI_ERROR;
for (i = 0 ; i < info_len ; ++i) {
ret = get_keyval(fp, &(newinfo->key), &(newinfo->value));
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(newinfo);
return ret;
}
ompi_list_append(&info, (ompi_list_item_t*) newinfo);
}
return OMPI_SUCCESS;
}
static int
get_nodelist(FILE *fp, ompi_list_t *nodelist)
{
int nodelist_len;
int ret;
ompi_rte_node_allocation_t *newnode;
int i;
char *tmpstr;
ret = fscanf(fp, "%d\n", &nodelist_len);
if (ret != 1) return OMPI_ERROR;
for (i = 0 ; i < nodelist_len ; ++i) {
/* make sure we have a key */
ret = get_key(fp, NODE_KEY);
if (OMPI_SUCCESS != ret) return ret;
/* create the node */
newnode = OBJ_NEW(ompi_rte_node_allocation_t);
/* fill in fields */
ret = get_string(fp, &tmpstr);
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(newnode);
return OMPI_ERROR;
}
strncpy(newnode->hostname, tmpstr, sizeof(newnode->hostname));
free(tmpstr);
ret = fscanf(fp, "%d\n", &(newnode->count));
if (ret != 1) {
OBJ_RELEASE(newnode);
return OMPI_ERROR;
}
ret = get_nodeinfo(fp, newnode->info);
if (OMPI_SUCCESS != ret) {
OBJ_RELEASE(newnode);
return OMPI_ERROR;
}
ompi_list_append(nodelist, (ompi_list_item_t*) newnode);
}
return OMPI_SUCCESS;
}
int
mca_pcm_base_recv_schedule(FILE *fp,
ompi_rte_node_schedule_t *sched,
ompi_list_t *nodelist)
{
int ret, val;
/* try to get our starting key */
ret = get_key(fp, START_KEY);
if (OMPI_SUCCESS != ret) return ret;
/* check our version */
get_check_version(fp);
if (OMPI_SUCCESS != ret) return ret;
/* get argc */
get_argv_array(fp, &(sched->argc), &(sched->argv));
if (OMPI_SUCCESS != ret) return ret;
/* get env */
get_argv_array(fp, &val, &(sched->env));
if (OMPI_SUCCESS != ret) return ret;
/* get cwd */
get_string(fp, &(sched->cwd));
if (OMPI_SUCCESS != ret) return ret;
/* get node list */
get_nodelist(fp, nodelist);
if (OMPI_SUCCESS != ret) return ret;
/* make sure we have our end */
ret = get_key(fp, END_KEY);
if (OMPI_SUCCESS != ret) return ret;
return OMPI_SUCCESS;
}

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

@ -7,12 +7,11 @@
#include "ompi_config.h"
#include "mca/pcm/pcm.h"
#include "mca/pcm/rsh/src/pcm_rsh.h"
#include <string.h>
char *
mca_pcm_rsh_get_unique_name(void)
mca_pcm_base_no_unique_name(void)
{
return strdup("none");
return strdup("0");
}

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

@ -17,7 +17,6 @@ libmca_pcm_rsh_la_SOURCES = \
pcm_rsh_deallocate_resources.c \
pcm_rsh_get_peers.c \
pcm_rsh_get_self.c \
pcm_rsh_get_unique_name.c \
pcm_rsh_kill_job.c \
pcm_rsh_kill_proc.c \
pcm_rsh_register_monitor.c \

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

@ -13,6 +13,7 @@
#include "mca/mca.h"
#include "mca/base/mca_base_param.h"
#include "mca/pcm/pcm.h"
#include "mca/pcm/base/base.h"
#include "mca/pcm/rsh/src/pcm_rsh.h"
#include <stdio.h>
@ -43,7 +44,7 @@ mca_pcm_base_component_1_0_0_t mca_pcm_rsh_component = {
struct mca_pcm_base_module_1_0_0_t mca_pcm_rsh_1_0_0 = {
mca_pcm_rsh_get_unique_name,
mca_pcm_base_no_unique_name,
mca_pcm_rsh_allocate_resources,
mca_pcm_rsh_register_monitor,
mca_pcm_rsh_can_spawn,

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

@ -5,6 +5,6 @@
include $(top_srcdir)/config/Makefile.options
SUBDIRS = oob llm
SUBDIRS = oob llm pcm
DIST_SUBDIRS = $(SUBDIRS) ns

8
test/mca/pcm/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,8 @@
# -*- makefile -*-
#
# $HEADER$
#
include $(top_srcdir)/config/Makefile.options
SUBDIRS = base

21
test/mca/pcm/base/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,21 @@
# -*- makefile -*-
#
# $HEADER$
#
include $(top_srcdir)/config/Makefile.options
AM_CPPFLAGS = -I$(top_srcdir)/test/support -DOMPI_ENABLE_DEBUG_OVERRIDE=1
EXTRA_DIST = \
test1_out_std \
test2_out_std
noinst_PROGRAMS = \
sched_comm
sched_comm_SOURCES = \
sched_comm.c
sched_comm_LDADD = \
$(top_builddir)/src/libmpi.la \
$(top_builddir)/test/support/libsupport.la
sched_comm_DEPENDENCIES = $(sched_comm_LDADD)

98
test/mca/pcm/base/sched_comm.c Обычный файл
Просмотреть файл

@ -0,0 +1,98 @@
/*
* $HEADER$
*/
#include "ompi_config.h"
#include "support.h"
#include <stdio.h>
#include "runtime/runtime_types.h"
#include "mca/pcm/base/base.h"
extern char **environ;
static char *cmd1_str="diff ./test1_out ./test1_out_std";
static char *cmd2_str="diff ./test2_out ./test2_out_std";
int
main(int argc, char *argv[])
{
ompi_rte_node_schedule_t *schedout, *schedin;
FILE *test1_out=NULL; /* output file for first test */
FILE *test2_out=NULL; /* output file for second test */
FILE *test2_in = NULL;
int result; /* result of system call */
test_init("sched_comm_t");
/* Open output files for the tests */
test1_out = fopen("./test1_out", "w+" );
if( test1_out == NULL ) {
printf("can't open test 1 output file\n");
exit(-1);
}
test2_out = fopen("./test2_out", "w+" );
if( test2_out == NULL ) {
printf("can't open test 2 output file\n");
exit(-1);
}
schedout = malloc(sizeof(ompi_rte_node_schedule_t));
OBJ_CONSTRUCT(&(schedout->nodelist), ompi_list_t);
schedout->argv = argv;
schedout->argc = argc;
schedout->env = environ;
schedout->cwd = "/foo/bar/baz";
result = mca_pcm_base_send_schedule(test1_out, schedout,
&(schedout->nodelist));
if (result != OMPI_SUCCESS) {
test_failure("send_schedule failed");
exit(1);
}
fclose( test1_out );
/* See if the file matches the test standard */
result = system( cmd1_str );
if( result == 0 ) {
test_success();
}
else {
test_failure( "sched_comm test1 failed" );
}
/* test 2 */
schedin = malloc(sizeof(ompi_rte_node_schedule_t));
OBJ_CONSTRUCT(&(schedin->nodelist), ompi_list_t);
test2_in = fopen("./test1_out", "r");
result = mca_pcm_base_recv_schedule(test2_in, schedin,
&(schedin->nodelist));
if (result != OMPI_SUCCESS) {
test_failure("recv_schedule failed");
exit(1);
}
mca_pcm_base_send_schedule(test2_out, schedin, &(schedin->nodelist));
if (result != OMPI_SUCCESS) {
test_failure("send_schedule (2) failed");
exit(1);
}
fclose( test2_out );
/* See if the file matches the test standard */
result = system( cmd2_str );
if( result == 0 ) {
test_success();
}
else {
test_failure( "sched_comm test2 failed" );
}
test_finalize();
return 0;
}

45
test/mca/pcm/base/test1_out_std Обычный файл
Просмотреть файл

@ -0,0 +1,45 @@
@MCA_PCM@
1
1
12 ./sched_comm
37
24 SECURITYSESSIONID=20f500
20 HOME=/Users/bbarrett
15 SHELL=/bin/tcsh
13 USER=bbarrett
192 PATH=/Users/bbarrett/research/Software/powerpc-apple-darwin7/bin:/Users/bbarrett/Software/powerpc-apple-darwin7/bin:/sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin
33 __CF_USER_TEXT_ENCODING=0x1F5:0:0
27 TERM_PROGRAM=Apple_Terminal
24 TERM_PROGRAM_VERSION=100
16 TERM=xterm-color
16 LOGNAME=bbarrett
17 HOSTTYPE=powermac
12 VENDOR=apple
13 OSTYPE=darwin
16 MACHTYPE=powerpc
7 SHLVL=1
57 PWD=/Users/bbarrett/research/ompi/trunk/test/mca/pcm/base
14 GROUP=bbarrett
17 HOST=fluffy.local
27 OMPI_MCA_verbose=level:1000
25 BWB_HAVE_RUN_TCSHRC_PRE=1
164 MANPATH=::/Users/bbarrett/research/Software/powerpc-apple-darwin7/man:/Users/bbarrett/Software/powerpc-apple-darwin7/man:/sw/share/man:/usr/share/man:/usr/X11R6/man
48 INFOPATH=/sw/share/info:/sw/info:/usr/share/info
43 PERL5LIB=/sw/lib/perl5:/sw/lib/perl5/darwin
33 XAPPLRESDIR=/sw/etc/app-defaults/
10 DISPLAY=:0
30 BWB_ARCH=powerpc-apple-darwin7
26 ARCH=powerpc-apple-darwin7
21 BWB_HAVE_RUN_TCSHRC=1
50 MSP=/Users/bbarrett/Software/powerpc-apple-darwin7
126 LD_LIBRARY_PATH=/Users/bbarrett/research/Software/powerpc-apple-darwin7/lib:/Users/bbarrett/Software/powerpc-apple-darwin7/lib
60 DDIR=/Users/bbarrett/research/Software/powerpc-apple-darwin7
11 CVS_RSH=ssh
12 CVSEDITOR=vi
13 SVN_EDITOR=vi
12 EDITOR=emacs
10 LAMRSH=ssh
443 LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=41;37;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.bz2=01;31:*.jpg=01;35:*.JPG=01;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*.cc=01;35:*.c=01;35:*.h=01;35:*.C=01;35:*.hh=01;35:*.o=35:
12 /foo/bar/baz
0
@MCA_PCM_END@

45
test/mca/pcm/base/test2_out_std Обычный файл
Просмотреть файл

@ -0,0 +1,45 @@
@MCA_PCM@
1
1
12 ./sched_comm
37
24 SECURITYSESSIONID=20f500
20 HOME=/Users/bbarrett
15 SHELL=/bin/tcsh
13 USER=bbarrett
192 PATH=/Users/bbarrett/research/Software/powerpc-apple-darwin7/bin:/Users/bbarrett/Software/powerpc-apple-darwin7/bin:/sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin
33 __CF_USER_TEXT_ENCODING=0x1F5:0:0
27 TERM_PROGRAM=Apple_Terminal
24 TERM_PROGRAM_VERSION=100
16 TERM=xterm-color
16 LOGNAME=bbarrett
17 HOSTTYPE=powermac
12 VENDOR=apple
13 OSTYPE=darwin
16 MACHTYPE=powerpc
7 SHLVL=1
57 PWD=/Users/bbarrett/research/ompi/trunk/test/mca/pcm/base
14 GROUP=bbarrett
17 HOST=fluffy.local
27 OMPI_MCA_verbose=level:1000
25 BWB_HAVE_RUN_TCSHRC_PRE=1
164 MANPATH=::/Users/bbarrett/research/Software/powerpc-apple-darwin7/man:/Users/bbarrett/Software/powerpc-apple-darwin7/man:/sw/share/man:/usr/share/man:/usr/X11R6/man
48 INFOPATH=/sw/share/info:/sw/info:/usr/share/info
43 PERL5LIB=/sw/lib/perl5:/sw/lib/perl5/darwin
33 XAPPLRESDIR=/sw/etc/app-defaults/
10 DISPLAY=:0
30 BWB_ARCH=powerpc-apple-darwin7
26 ARCH=powerpc-apple-darwin7
21 BWB_HAVE_RUN_TCSHRC=1
50 MSP=/Users/bbarrett/Software/powerpc-apple-darwin7
126 LD_LIBRARY_PATH=/Users/bbarrett/research/Software/powerpc-apple-darwin7/lib:/Users/bbarrett/Software/powerpc-apple-darwin7/lib
60 DDIR=/Users/bbarrett/research/Software/powerpc-apple-darwin7
11 CVS_RSH=ssh
12 CVSEDITOR=vi
13 SVN_EDITOR=vi
12 EDITOR=emacs
10 LAMRSH=ssh
443 LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=41;37;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.bz2=01;31:*.jpg=01;35:*.JPG=01;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*.cc=01;35:*.c=01;35:*.h=01;35:*.C=01;35:*.hh=01;35:*.o=35:
12 /foo/bar/baz
0
@MCA_PCM_END@