Initializes a LAPI context.
Availability Library (liblapi_r.a)
#include <lapi.h>
int LAPI_Init(hndl,lapi_info)
lapi_handle_t *hndl;
lapi_info_t *lapi_info;
include 'lapif.h'
LAPI_INIT(hndl,lapi_info,ierror)
INTEGER hndl
TYPE (LAPI_INFO_T) :: lapi_info
INTEGER ierror
Type of call: Local initialization
Use this subroutine to instantiate and initialize a new LAPI context. A handle to the newly-created LAPI context is returned in hndl. All subsequent LAPI calls can use hndl to specify the context of the LAPI operation. Except for LAPI_Address() and LAPI_Msg_string(), the user cannot make any LAPI calls before calling LAPI_Init().
The lapi_info structure (lapi_info_t) must be "zeroed out" before any fields are filled in. To do this in C, use this statement: bzero (lapi_info, size of (lapi_info_t)). In FORTRAN, you need to "zero out" each field manually in the LAPI_INFO_T type. Fields with a description of Future support should not be used because the names of those fields might change.
typedef struct {
lapi_dev_t protocol; /* Protocol device returned */
lapi_lib_t lib_vers; /* LAPI library version -- user-supplied */
uint epoch_num; /* No longer used */
int num_compl_hndlr_thr; /* Number of completion handler threads */
uint instance_no; /* Instance of LAPI to initialize [1-16] */
int info6; /* Future support */
LAPI_err_hndlr *err_hndlr; /* User-registered error handler */
com_thread_info_t *lapi_thread_attr; /* Support thread att and init function */
void *adapter_name; /* What adapter to initialize, i.e. css0, ml0 */
lapi_extend_t *add_info; /* Additional structure extension */
} lapi_info_t;
The fields are used as follows: MP_MSG_API=[ lapi | [ lapi,mpi | mpi,lapi ] | mpi_lapi ]
MP_EUILIB=[ ip | us ] (ip is the default)
MP_PROCS=number_of_tasks_in_job
LAPI_USE_SHM=[ yes | no | only ] (no is the default)
For systems running PE
Both US and UDP/IP are supported for shared handles as long as they are the same for both handles. Mixed transport protocols such as LAPI IP and shared user space (US) are not supported.
{
lapi_handle_t hndl;
lapi_info_t info;
bzero(&info, sizeof(lapi_info_t)); /* clear lapi_info */
LAPI_Init(&hndl, &info);
}
void my_err_hndlr(lapi_handle_t *hndl, int *error_code, lapi_err_t *err_type,
int *task_id, int *src )
{
/* examine passed parameters and delete desired information */
if ( user wants to terminate ) {
LAPI_Term(*hndl); /* will terminate LAPI */
exit(some_return_code);
}
/* any additional processing */
return; /* signals to LAPI that error is non-fatal; execution should continue */
}
{
lapi_handle_t hndl;
lapi_info_t info;
bzero(&info, sizeof(lapi_info_t)); /* clear lapi_info */
/* set error handler pointer */
info.err_hndlr = (LAPI_err_hndlr) my_err_hndlr;
LAPI_Init(&hndl, &info);
}
For standalone systems (not running PE)
int my_udp_hndlr(lapi_handle_t *hndl, lapi_udp_t *local_addr, lapi_udp_t *addr_list,
lapi_udpinfo_t *info)
{
/* LAPI will allocate and free addr_list pointer when using */
/* a user handler */
/* use the AIX(r) inet_addr call to convert an IP address */
/* from a dotted quad to a long */
task_0_ip_as_long = inet_addr(task_0_ip_as_string);
addr_list[0].ip_addr = task_0_ip_as_long;
addr_list[0].port_no = task_0_port_as_unsigned;
task_1_ip_as_long = inet_addr(task_1_ip_as_string);
addr_list[1].ip_addr = task_1_ip_as_long;
addr_list[1].port_no = task_1_port_as_unsigned;
.
.
.
task_num_tasks-1_ip_as_long = inet_addr(task_num_tasks-1_ip_as_string);
addr_list[num_tasks-1].ip_addr = task_num_tasks-1_ip_as_long;
addr_list[num_tasks-1].port_no = task_num_tasks-1_port_as_unsigned;
}
{
lapi_handle_t hndl;
lapi_info_t info;
lapi_extend_t extend_info;
bzero(&info, sizeof(lapi_info_t)); /* clear lapi_info */
bzero(&extend_info, sizeof(lapi_extend_t)); /* clear lapi_extend_info */
extend_info.udp_hndlr = (udp_init_hndlr *) my_udp_hndlr;
info.add_info = &extend_info;
LAPI_Init(&hndl, &info);
}
{
lapi_handle_t hndl;
lapi_info_t info;
lapi_extend_t extend_info;
lapi_udp_t *addr_list;
bzero(&info, sizeof(lapi_info_t)); /* clear lapi_info */
bzero(&extend_info, sizeof(lapi_extend_t)); /* clear lapi_extend_info */
/* when using a user list, the user is responsible for allocating */
/* and freeing the list pointer */
addr_list = malloc(num_tasks);
/* Note, since we need to know the number of tasks before LAPI is */
/* initialized, we can't use LAPI_Qenv. getenv("MP_PROCS") will */
/* do the trick. */
/* populate addr_list */
/* use the AIX(r) inet_addr call to convert an IP address */
/* from a dotted quad to a long */
task_0_ip_as_long = inet_addr(task_0_ip_as_string);
addr_list[0].ip_addr = task_0_ip_as_long;
addr_list[0].port_no = task_0_port_as_unsigned;
task_1_ip_as_long = inet_addr(task_1_ip_as_string);
addr_list[1].ip_addr = task_1_ip_as_long;
addr_list[1].port_no = task_1_port_as_unsigned;
.
.
.
task_num_tasks-1_ip_as_long = inet_addr(task_num_tasks-1_ip_as_string);
addr_list[num_tasks-1].ip_addr = task_num_tasks-1_ip_as_long;
addr_list[num_tasks-1].port_no = task_num_tasks-1_port_as_unsigned;
/* then assign to extend pointer */
extend_info.add_udp_addrs = addr_list;
info.add_info = &extend_info;
LAPI_Init(&hndl, &info);
.
.
.
/* user's responsibility only in the case of user list */
free(addr_list);
}
See the LAPI sample programs for complete examples of initialization in standalone mode.
export MP_MSG_API=lapi
export MP_EUILIB=us
export MP_PROCS= /* number of tasks in job */
export MP_PARTITION= /* unique job key */
export MP_CHILD= /* unique task ID */
export MP_LAPI_NETWORK=@1:164,sn0 /* LAPI network information */
run LAPI jobs as normal
See the README.LAPI.STANDALONE.US file
in the standalone/us directory of the LAPI
sample files for complete details.