Skip to content

Commit

Permalink
libpmi-client: add pmi client library
Browse files Browse the repository at this point in the history
Flux will use this library to bootstrap from a PM, including itself.
We will also use this library to test our PMI implementation.

Initially there are two embeded implementations:

"dlopen" - this implementation dlopens libpmi.so.  Functions that
are undefined will fail gracefully wtih a PMI_FAIL return code.

"simple" - this implements the simple v1 PMI wire protocol used
by mpich and hydra.  It is sufficient to allow hydra to launch Flux,
but otherwise is very rigid about what it expects on the wire,
and is missing a few functions that could be implemented.

The pmi client object can be initialized to explicitly use one of
these implementations with parameters such as a fully qualified path
to a library to dlopen, or pmi_create_guess() can be called to
pick one based on the environment.
  • Loading branch information
garlick committed Oct 2, 2015
1 parent fe2444a commit 8d5ee42
Show file tree
Hide file tree
Showing 8 changed files with 1,340 additions and 1 deletion.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ AC_CONFIG_FILES( \
src/common/liblsd/Makefile \
src/common/libutil/Makefile \
src/common/libev/Makefile \
src/common/libpmi-client/Makefile \
src/common/libflux/Makefile \
src/common/libcompat/Makefile \
src/lib/Makefile \
Expand Down
3 changes: 2 additions & 1 deletion src/common/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS = libtap libev liblsd libutil libflux libcompat
SUBDIRS = libtap libev libpmi-client liblsd libutil libflux libcompat

AM_CFLAGS = @GCCWARN@ $(CODE_COVERAGE_CFLAGS)
AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS)
Expand All @@ -12,6 +12,7 @@ libflux_internal_la_LIBADD = \
$(builddir)/liblsd/liblsd.la \
$(builddir)/libutil/libutil.la \
$(builddir)/libev/libev.la \
$(builddir)/libpmi-client/libpmi-client.la \
$(builddir)/libcompat/libcompat.la \
$(LIBMUNGE) $(JSON_LIBS) $(ZMQ_LIBS) $(LIBPTHREAD) $(LIBUTIL) \
$(LIBDL) -lrt
Expand Down
20 changes: 20 additions & 0 deletions src/common/libpmi-client/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
AM_CFLAGS = \
@GCCWARN@ \
$(CODE_COVERAGE_CFLAGS)

AM_LDFLAGS = \
$(CODE_COVERAGE_LDFLAGS)

AM_CPPFLAGS = \
$(JSON_CFLAGS) $(ZMQ_CFLAGS) \
-Wno-strict-aliasing \
-I$(top_srcdir) -I$(top_srcdir)/src/include

noinst_LTLIBRARIES = libpmi-client.la

libpmi_client_la_SOURCES = \
pmi-client.h \
pmi-impl.h \
pmi.c \
pmi-dlopen.c \
pmi-simple.c
132 changes: 132 additions & 0 deletions src/common/libpmi-client/pmi-client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#ifndef _FLUX_CORE_PMI_CLIENT_H
#define _FLUX_CORE_PMI_CLIENT_H

#ifndef PMI_SUCCESS
#define PMI_SUCCESS 0
#endif
#ifndef PMI_FAIL
#define PMI_FAIL -1
#endif
#ifndef PMI_ERR_INIT
#define PMI_ERR_INIT 1
#endif
#ifndef PMI_ERR_NOMEM
#define PMI_ERR_NOMEM 2
#endif
#ifndef PMI_ERR_INVALID_ARG
#define PMI_ERR_INVALID_ARG 3
#endif
#ifndef PMI_ERR_INVALID_KEY
#define PMI_ERR_INVALID_KEY 4
#endif
#ifndef PMI_ERR_INVALID_KEY_LENGTH
#define PMI_ERR_INVALID_KEY_LENGTH 5
#endif
#ifndef PMI_ERR_INVALID_VAL
#define PMI_ERR_INVALID_VAL 6
#endif
#ifndef PMI_ERR_INVALID_VAL_LENGTH
#define PMI_ERR_INVALID_VAL_LENGTH 7
#endif
#ifndef PMI_ERR_INVALID_LENGTH
#define PMI_ERR_INVALID_LENGTH 8
#endif
#ifndef PMI_ERR_INVALID_NUM_ARGS
#define PMI_ERR_INVALID_NUM_ARGS 9
#endif
#ifndef PMI_ERR_INVALID_ARGS
#define PMI_ERR_INVALID_ARGS 10
#endif
#ifndef PMI_ERR_INVALID_NUM_PARSED
#define PMI_ERR_INVALID_NUM_PARSED 11
#endif
#ifndef PMI_ERR_INVALID_KEYVALP
#define PMI_ERR_INVALID_KEYVALP 12
#endif
#ifndef PMI_ERR_INVALID_SIZE
#define PMI_ERR_INVALID_SIZE 13
#endif

typedef void (*pmi_free_f)(void *impl);

typedef struct pmi_struct pmi_t;

/* Create/destroy pmi_t class.
*/
void pmi_destroy (pmi_t *pmi);

pmi_t *pmi_create_dlopen (const char *filename);
pmi_t *pmi_create_simple (int fd, int rank, int size);
pmi_t *pmi_create_guess (void);

const char *pmi_strerror (int errnum);


/* Functions below match the canonical PMIv1 ABI, except for
* the pmi_t first argument and the lower case function names.
*/

typedef struct {
const char *key;
char *val;
} pmi_keyval_t;

int pmi_init (pmi_t *pmi, int *spawned);
int pmi_initialized (pmi_t *pmi, int *initialized);
int pmi_finalize (pmi_t *pmi);
int pmi_get_size (pmi_t *pmi, int *size);
int pmi_get_rank (pmi_t *pmi, int *rank);
int pmi_get_universe_size (pmi_t *pmi, int *size);
int pmi_get_appnum (pmi_t *pmi, int *appnum);
int pmi_publish_name (pmi_t *pmi, const char *service_name, const char *port);
int pmi_unpublish_name (pmi_t *pmi, const char *service_name);
int pmi_lookup_name (pmi_t *pmi, const char *service_name, char *port);
int pmi_barrier (pmi_t *pmi);
int pmi_abort (pmi_t *pmi, int exit_code, const char *error_msg);
int pmi_kvs_get_my_name (pmi_t *pmi, char *kvsname, int length);
int pmi_kvs_get_name_length_max (pmi_t *pmi, int *length);
int pmi_kvs_get_key_length_max (pmi_t *pmi, int *length);
int pmi_kvs_get_value_length_max (pmi_t *pmi, int *length);
int pmi_kvs_put (pmi_t *pmi,
const char *kvsname, const char *key, const char *value);
int pmi_kvs_commit (pmi_t *pmi, const char *kvsname);
int pmi_kvs_get (pmi_t *pmi,
const char *kvsname, const char *key, char *value, int len);
int pmi_spawn_multiple (pmi_t *pmi,
int count,
const char *cmds[],
const char **argvs[],
const int maxprocs[],
const int info_keyval_sizesp[],
const pmi_keyval_t *info_keyval_vectors[],
int preput_keyval_size,
const pmi_keyval_t preput_keyval_vector[],
int errors[]);

/* These functions were eventually deprecated in MPICH.
* Be careful using these - if unimplemented PMI_FAIL is returned.
*/

int pmi_get_id (pmi_t *pmi, char *id_str, int length);
int pmi_get_kvs_domain_id (pmi_t *pmi, char *id_str, int length);
int pmi_get_id_length_max (pmi_t *pmi, int *length);
int pmi_get_clique_size (pmi_t *pmi, int *size);
int pmi_get_clique_ranks (pmi_t *pmi, int *ranks, int length);
int pmi_kvs_create (pmi_t *pmi, char *kvsname, int length);
int pmi_kvs_destroy (pmi_t *pmi, const char *kvsname);
int pmi_kvs_iter_first (pmi_t *pmi, const char *kvsname,
char *key, int key_len, char *val, int val_len);
int pmi_kvs_iter_next (pmi_t *pmi, const char *kvsname,
char *key, int key_len, char *val, int val_len);
int pmi_parse_option (pmi_t *pmi, int num_args, char *args[],
int *num_parsed, pmi_keyval_t **keyvalp, int *size);
int pmi_args_to_keyval (pmi_t *pmi, int *argcp, char *((*argvp)[]),
pmi_keyval_t **keyvalp, int *size);
int pmi_free_keyvals (pmi_t *pmi, pmi_keyval_t keyvalp[], int size);
int pmi_get_options (pmi_t *pmi, char *str, int length);

#endif /* ! _FLUX_CORE_PMI_CLIENT_H */

/*
* vi:tabstop=4 shiftwidth=4 expandtab
*/
Loading

0 comments on commit 8d5ee42

Please sign in to comment.