LAPI_Init Subroutine
Purpose
Initializes a LAPI context.
Library
Availability Library (liblapi_r.a)
C Syntax
#include <lapi.h>
int LAPI_Init(hndl,lapi_info)
lapi_handle_t *hndl;
lapi_info_t *lapi_info;
FORTRAN Syntax
include 'lapif.h'
LAPI_INIT(hndl,lapi_info,ierror)
INTEGER hndl
TYPE (LAPI_INFO_T) :: lapi_info
INTEGER ierror
Description
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: - protocol
- LAPI sets this field to the protocol that has been initialized.
- lib_vers
- Is used to indicate a library version to LAPI for compatibility
purposes. Valid values for this field are:
- L1_LIB
- Provides basic functionality (this is the default).
- L2_LIB
- Provides the ability to use counters as structures.
- LAST_LIB
- Provides the most current level of functionality. For new users of LAPI, lib_vers should be set to LAST_LIB.
- epoch_num
- This field is no longer used.
- num_compl_hndlr_thr
- Indicates to LAPI the number of completion handler threads to initialize.
- instance_no
- Specifies the instance of LAPI to initialize (1 to 16).
- info6
- This field is for future use.
- err_hndlr
- Use this field to optionally pass a callback pointer to an error-handler routine.
- lapi_thread_attr
- Supports thread attributes and initialization function.
- adapter_name
- Is used in persistent subsystem (PSS) mode to pass an adapter name.
- add_info
- Is used for additional information in standalone UDP mode.
Parameters
- INPUT/OUTPUT
- lapi_info
- Specifies a structure that provides the parallel job information with which this LAPI context is associated. The value of this parameter cannot be NULL (in C) or LAPI_ADDR_NULL (in FORTRAN).
- OUTPUT
- hndl
- Specifies a pointer to the LAPI handle to initialize.
- ierror
- Specifies a FORTRAN return code. This is always the last parameter.
Return Values
- LAPI_SUCCESS
- Indicates that the function call completed successfully.
- LAPI_ERR_ALL_HNDL_IN_USE
- All available LAPI instances are in use.
- LAPI_ERR_BOTH_NETSTR_SET
- Both the MP_LAPI_NETWORK and MP_LAPI_INET statements are set (only one should be set).
- LAPI_ERR_CSS_LOAD_FAILED
- LAPI is unable to load the communication utility library.
- LAPI_ERR_HNDL_INVALID
- The lapi_handle_t * passed to LAPI for initialization is NULL (in C) or LAPI_ADDR_NULL (in FORTRAN).
- LAPI_ERR_INFO_NONZERO_INFO
- The future support fields in the lapi_info_t structure that was passed to LAPI are not set to zero (and should be).
- LAPI_ERR_INFO_NULL
- The lapi_info_t pointer passed to LAPI is NULL (in C) or LAPI_ADDR_NULL (in FORTRAN).
- LAPI_ERR_MEMORY_EXHAUSTED
- LAPI is unable to obtain memory from the system.
- LAPI_ERR_MSG_API
- Indicates that the MP_MSG_API environment variable is not set correctly.
- LAPI_ERR_NO_NETSTR_SET
- No network statement is set. Note that if running with POE, this will be returned if MP_MSG_API is not set correctly.
- LAPI_ERR_NO_UDP_HNDLR
- You passed a value of NULL (in C) or LAPI_ADDR_NULL (in FORTRAN) for both the UDP handler and the UDP list. One of these (the UDP handler or the UDP list) must be initialized for standalone UDP initialization. This error is returned in standalone UDP mode only.
- LAPI_ERR_PSS_NON_ROOT
- You tried to initialize the persistent subsystem (PSS) protocol as a nonroot user.
- LAPI_ERR_SHM_KE_NOT_LOADED
- LAPI's shared memory kernel extension is not loaded.
- LAPI_ERR_SHM_SETUP
- LAPI is unable to set up shared memory. This error will be returned if LAPI_USE_SHM=only and tasks are assigned to more than one node.
- LAPI_ERR_UDP_PKT_SZ
- The UDP packet size you indicated is not valid.
- LAPI_ERR_UNKNOWN
- An internal error has occurred.
- LAPI_ERR_USER_UDP_HNDLR_FAIL
- The UDP handler you passed has returned a non-zero error code. This error is returned in standalone UDP mode only.
C Examples
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)
- Set environment variables (as described in RSCT for AIX 5L: LAPI Programming Guide) before the user application is invoked. The remaining steps are done in the user application.
- Clear lapi_info_t, then set any fields.
- Call LAPI_Init.
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.Location
- /usr/lib/liblapi_r.a