
#ifndef GLOBUS_DUROC_BOOTSTRAP_H
#define GLOBUS_DUROC_BOOTSTRAP_H


#include "nexus.h"

#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
 
EXTERN_C_BEGIN


extern int 
globus_duroc_bootstrap_activate (void);

extern int
globus_duroc_bootstrap_deactivate (void);

extern globus_module_descriptor_t globus_duroc_bootstrap_module;
#define GLOBUS_DUROC_BOOTSTRAP_MODULE (&globus_duroc_bootstrap_module)


extern int
globus_duroc_bootstrap_subjob_exchange (const char   * local_info,
				 int          * subjob_countp,
				 int          * local_indexp,
				 char       *** subjob_info_arrayp);

extern int
globus_duroc_bootstrap_linearize_startpoint (nexus_startpoint_t  * sp,
				      char               ** lsp_string);

extern int 
globus_duroc_bootstrap_extract_linearized_startpoint (nexus_startpoint_t * spp, 
					       const char         * sp_msg);

/* 
 * local_sp is the startpoint on each node that should be distributed
 * in the sp_vector.
 * on one node:
 *   (*job_sizep) is initialized with the number of nodes.
 *   (*sp_vectorp) is initialized with a nexus_startpoint_t array,
 *       where (*sp_vector)[i] is the startpoint to node i.
 * on all other nodes:
 *   (*job_sizep) is undefined.
 *   (*sp_vectorp) is NULL.
 */
extern int
globus_duroc_bootstrap_master_sp_vector (nexus_startpoint_t  * local_sp, 
				  int                 * job_sizep,
				  nexus_startpoint_t ** sp_vectorp);

/* 
 * local_sp is the startpoint on each node that should be distributed
 * in the sp_vector.
 * subjob_index positions this subjob relative to others in the
 * linearized address space.
 * on one node:
 *   (*job_sizep) is initialized with the number of nodes.
 *   (*sp_vectorp) is initialized with a nexus_startpoint_t array,
 *       where (*sp_vector)[i] is the startpoint to node i.
 * on all other nodes:
 *   (*job_sizep) is undefined.
 *   (*sp_vectorp) is NULL.
 */
extern int
globus_duroc_bootstrap_ordered_master_sp_vector (nexus_startpoint_t  * local_sp, 
					  int                   subjob_index,
					  int                 * job_sizep,
					  nexus_startpoint_t ** sp_vectorp);

extern
void
globus_duroc_bootstrap_all_to_all_distribute_bytearray(
    globus_byte_t *			inbuff,
    int					inbufflen,
    int *				nprocs,
    int *				my_grank,
    globus_byte_t ***			outbuffs,
    int **				outbufflens);

extern
void
globus_i_duroc_get_topology(
    int					rank_in_my_subjob, 
    int *				my_subjob_size, 
    int **				subjob_addresses,
    int *				nprocs, 
    int *				nsubjobs, 
    int *				my_grank);

extern
void
globus_i_duroc_distribute_byte_array(
    globus_byte_t *			inbuff,
    int 				inbufflen,
    int 				rank_in_my_subjob,
    int 				my_subjob_size,
    int *				subjob_addresses,
    int 				nprocs,
    int 				nsubjobs,
    int 				my_grank,
    globus_byte_t **			outbuffs,
    int *				outbufflens);

EXTERN_C_END

#endif /* GLOBUS_DUROC_BOOTSTRAP_H */

