LAPI_Amsend 子例程
用途
将用户消息传输到远程任务,从用户指定的头处理程序获取远程任务上的目标地址。
库
可用性库 (liblapi_r.a)
C 语法
#include <lapi.h>
typedef void (compl_hndlr_t) (hndl, user_info);
lapi_handle_t *hndl; /* pointer to LAPI context passed in from LAPI_Amsend */
void *user_info; /* buffer (user_info) pointer passed in */
/* from header handler (void *(hdr_hndlr_t)) */
typedef void *(hdr_hndlr_t)(hndl, uhdr, uhdr_len, msg_len, comp_h, user_info);
lapi_handle_t *hndl; /* pointer to LAPI context passed in from LAPI_Amsend */
void *uhdr; /* uhdr passed in from LAPI_Amsend */
uint *uhdr_len; /* uhdr_len passed in from LAPI_Amsend */
ulong *msg_len; /* udata_len passed in fom LAPI_Amsend */
compl_hndlr_t **comp_h; /* function address of completion handler */
/* (void (compl_hndlr_t)) that needs to be filled */
/* out by this header handler function. */
void **user_info; /* pointer to the parameter to be passed */
/* in to the completion handler */
int LAPI_Amsend(hndl, tgt, hdr_hdl, uhdr, uhdr_len, udata, udata_len,
tgt_cntr, org_cntr, cmpl_cntr)
lapi_handle_t hndl;
uint tgt;
void *hdr_hdl;
void *uhdr;
uint uhdr_len;
void *udata;
ulong udata_len;
lapi_cntr_t *tgt_cntr;
lapi_cntr_t *org_cntr;
lapi_cntr_t *cmpl_cntr;
FORTRAN 语法
include 'lapif.h'
INTEGER SUBROUTINE COMPL_H (hndl, user_info)
INTEGER hndl
INTEGER user_info
INTEGER FUNCTION HDR_HDL (hndl, uhdr, uhdr_len, msg_len, comp_h, user_info)
INTEGER hndl
INTEGER uhdr
INTEGER uhdr_len
INTEGER (KIND=LAPI_LONG_TYPE) :: msg_len
EXTERNAL INTEGER FUNCTION comp_h
TYPE (LAPI_ADDR_T) :: user_info
LAPI_AMSEND(hndl, tgt, hdr_hdl, uhdr, uhdr_len, udata, udata_len,
tgt_cntr, org_cntr, cmpl_cntr, ierror)
INTEGER hndl
INTEGER tgt
EXTERNAL INTEGER FUNCTION hdr_hdl
INTEGER uhdr
INTEGER uhdr_len
TYPE (LAPI_ADDR_T) :: udata
INTEGER (KIND=LAPI_LONG_TYPE) :: udata_len
INTEGER (KIND=LAPI_ADDR_TYPE) :: tgt_cntr
TYPE (LAPI_CNTR_T) :: org_cntr
TYPE (LAPI_CNTR_T) :: cmpl_cntr
INTEGER ierror描述
Type of call: 点到点通信 (非阻塞)
使用此子例程将数据传输到目标任务,在该任务中,最好在消息传递开始之前或在传递完成之后对目标任务运行处理程序。 LAPI_Amsend 允许用户提供头处理程序和可选完成处理程序。 头处理程序用于指定用于写入数据的目标缓冲区地址,从而在调用子例程时不需要知道源任务上的地址。
用户数据 (uhdr 和 udata) 将发送到目标任务。 在源任务上不再需要这些缓冲区时,源计数器将递增,这指示可用于修改的源缓冲区的可用性。 将 LAPI_Xfer 调用与 LAPI_AM_XFER 类型配合使用将提供相同类型的传输,并且可以选择使用发送完成处理程序而不是源计数器来指定缓冲区可用性。
当第一个数据包到达目标时,将调用用户的头处理程序。 请注意,头处理程序必须由用户提供,因为它返回缓冲区的基本地址, LAPI 将在该缓冲区中写入从源任务 (udata) 发送的数据。 请参阅 RSCT for AIX 5L: LAPI Programming Guide ,以获取针对单包消息向 LAPI 提供缓冲区地址这一要求的优化异常。
头处理程序还向 LAPI 提供有关消息传递的其他信息,例如完成处理程序。 LAPI_Amsend 和类似调用 (例如 LAPI_Amsendv 和相应的 LAPI_Xfer 传输) 也允许用户指定其自己的消息头信息,这些信息可供头处理程序使用。 用户还可以从头处理程序中指定完成处理程序参数。 LAPI 将在执行时将信息传递到完成处理程序。
请注意,头处理程序由运行 LAPI 分派器的线程以内联方式运行。 因此,头处理程序必须是非分块的,因为在返回之前不会对消息进行其他处理。 还建议执行头处理程序简单快捷。 另一方面,完成处理程序通常由单独的线程排队等待执行。 可以请求以内联方式运行完成处理程序。 请参阅 RSCT for AIX 5L: LAPI Programming Guide ,以获取有关内联完成处理程序的更多信息。
如果未指定完成处理程序 (即,在 FORTRAN 中设置为 LAPI_ADDR_NULL 或其指针在 C 中设置为 NULL) ,那么最终包的到达将导致 LAPI 增大远程任务上的目标计数器并将内部消息发送回源任务。 此消息导致完成计数器 (如果在 C 中不为 NULL ,在 FORTRAN 中不为 LAPI_ADDR_NULL ) 在源任务上递增。
如果指定了完成处理程序,那么上述步骤将在完成处理程序返回后执行。 要保证完成处理程序已在目标上执行,必须在完成计数器上等待。 请参阅 RSCT for AIX 5L: LAPI Programming Guide ,以获取 LAPI_Amsend 调用中事件的时序图。
用户详细信息
void *hdr_hndlr(lapi_handle_t *hndl, void *uhdr, uint *uhdr_len, ulong *msg_len,
compl_hndlr_t **cmpl_hndlr, void **user_info);LAPI 将头处理程序返回的值解释为用于写入传递到 LAPI_Amsend 调用的用户数据 (udata) 的地址。 uhdr 和 uhdr_len 参数由 LAPI 传递到头处理程序,并包含用户传递到 LAPI_Amsend 调用的相应参数的信息。使用 LAPI_Addr_set
通常通过在初始化 LAPI 的几个步骤中发出集合体 LAPI_Address_init 调用来交换远程地址。 LAPI 还提供了 LAPI_Addr_set 机制,用户可以通过此机制在表中注册一个或多个头处理程序地址,从而使索引值与每个地址相关联。 然后,可以将此索引传递到 LAPI_Amsend ,而不是传递到实际地址。 在目标端, LAPI 将使用索引来获取头处理程序地址。 请注意,如果所有任务对其头处理程序使用相同的索引,那么可以避免初始集合体通信。 每个任务只需使用众所周知的索引来注册其自己的头处理程序地址。 然后,在任何 LAPI_Amsend 调用上,可以将保留索引传递到头处理程序地址参数。
头处理程序的角色
用户 (可选) 通过 cmpl_hndlr 参数返回完成处理程序函数的地址,并通过 user_info 参数返回完成处理程序参数。 通过 user_info 参数传递的地址可以引用包含用户定义的数据类型的内存,然后根据需要从完成处理程序内强制转换为相应类型。
typedef void (compl_hndlr_t)(lapi_handle_t *hndl, void *completion_param);通过用户头处理程序的 user_info 成员通过引用返回的自变量将传递到用户完成处理程序的 completion_param 自变量。 请参阅 C 示例 ,以获取在头处理程序中设置完成处理程序和参数的示例。如上所述,头处理程序返回的值必须是用于写入从源任务发送的用户数据的地址。 此规则有一个例外。 对于单包消息, LAPI 在接收 FIFO 中传递包的地址,允许在头处理程序中使用整个消息。 在这种情况下,头处理程序应该返回 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中) ,以便 LAPI 不会将消息复制到目标缓冲区。 请参阅 RSCT for AIX 5L: LAPI Programming Guide 以获取更多信息 (包括使用此方法快速检索单包消息的样本头处理程序)。
通过 lapi_return_info_t 传递其他信息
LAPI 允许通过通过 msg_len 参数传递指向 lapi_return_info_t 的指针,将其他信息传递到头处理程序并从头处理程序返回。 从调用 LAPI_Amsend调用的头处理程序返回时, lapi_return_info_t 的 ret_flags 成员可以包含下列其中一个值: LAPI_NORMAL (缺省值) , LAPI_SEND_REPLY (以内联方式运行完成处理程序) 或 LAPI_LOCAL_STATE (未发送应答)。 不应将 lapi_return_info_t 的 dgsp_handle 成员与 LAPI_Amsend结合使用。
有关 lapi_return_info_t 类型的完整描述,请参阅 RSCT for AIX 5L: LAPI Programming Guide
内联执行完成处理程序
在正常操作下, LAPI 使用单独的线程来执行用户完成处理程序。 在最终包到达后,完成处理程序指针将放入此线程要处理的队列中。 出于性能原因,用户可能会请求以内联方式运行给定的完成处理程序,而不是将其放在其他完成处理程序之后的此队列上。 此机制使用户在确定性能关键型消息的完成处理程序执行优先级方面具有更大程度的控制。
LAPI 对 "正常" 运行的完成处理程序 (即,由完成处理程序线程) 没有任何限制。 内联完成处理程序应该短且不应阻塞,因为在主线程执行处理程序时无法取得任何进度。 用户必须谨慎使用内联完成处理程序,以便 LAPI 的内部队列在等待处理程序完成时不会填满。 不能使用内联完成处理程序执行 I/O 操作。
参数
- INPUT
- hndl
- 指定 LAPI 句柄。
- tgt
- 指定目标任务的任务标识。 The value of this parameter must be in the range 0 <= 哥特 < NUM_TASKS.
- hdr_hdl
- 指定指向要在目标上调用的远程头处理程序函数的指针。 此参数的值可以采用已使用 LAPI_Addr_set注册的地址句柄。 此参数的值不能为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中)。
- uhdr
- 指定指向用户头数据的指针。 此数据将传递到目标上的用户头处理程序。 如果 uhdr_len 是 0,那么此参数的值可以是 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中)。
- uhdr_len
- 指定用户头的长度。 The value of this parameter must be a multiple of the processor's 词 size in the range 0 <= Uhdr_len <= MAX_UHDR_SZ.
- udata
- 指定指向用户数据的指针。 如果 udata_len 是 0,那么此参数的值可以是 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中)。
- udata_len
- 指定用户数据的长度 (以字节计)。 The value of this parameter must be in the range 0 <= Udata_len <= the value of LAPI constant LAPI_MAX_MSG_SZ.
- 输入/输出
- tgt_cntr
- 指定目标计数器地址。 目标计数器在完成处理程序 (如果指定) 完成后或数据传输完成后递增。 如果此参数的值为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中) ,那么不会更新目标计数器。
- org_cntr
- 指定源计数器地址 (C) 或源计数器 (FORTRAN)。 从源地址 (C) 或源 (FORTRAN) 复制数据后,源计数器将递增。 如果此参数的值为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中) ,那么不会更新源计数器。
- cmpl_cntr
- 指定表示完成处理程序完成的源处的计数器。 完成处理程序完成后,将对其进行更新。 如果未指定完成处理程序,那么在完成消息传递时计数器将递增。 如果此参数的值为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中) ,那么不会更新完成计数器。
- 输出
- ierror
- 指定 FORTRAN 返回码。 这始终是最后一个参数。
返回值
- 成功 (LAPI_SUCCESS)
- 指示函数调用已成功完成。
- LAPI_ERR_DATA_LEN
- 指示 udata_len 的值大于 LAPI 常量 LAPI_MAX_MSG_SZ的值。
- LAPI_ERR_HDR_HNDLR_NULL
- 指示传入的 hdr_hdl 的值为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中)。
- LAPI_ERR_HNDL_INVALID
- 指示传入的 hndl 无效 (未初始化或处于终止状态)。
- LAPI_ERR_ORG_ADDR_NULL
- 指示传入的 udata 参数的值为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中) ,但 udata_len 的值大于 0。
- LAPI_ERR_TGT
- 指示传入的 tgt 超出作业中定义的任务范围。
- 已清除的 LAPI_ERR_TGT_PURGED
- 指示由于调用了 LAPI_Purge_totask() 而提前返回了子例程。
- LAPI_ERR_UHDR_LEN
- 指示传入的 uhdr_len 值大于 MAX_UHDR_SZ 或不是处理器双字大小的倍数。
- LAPI_ERR_UHDR_NULL
- 指示传入的 uhdr 为 NULL (在 C 中) 或 LAPI_ADDR_NULL (在 FORTRAN 中) ,但 uhdr_len 不是 0。
C 示例
/* header handler routine to execute on target task */
void *hdr_hndlr(lapi_handle_t *hndl, void *uhdr, uint *uhdr_len,
ulong *msg_len, compl_hndlr_t **cmpl_hndlr,
void **user_info)
{
/* set completion handler pointer and other information */
/* return base address for LAPI to begin its data copy */
}
{
lapi_handle_t hndl; /* the LAPI handle */
int task_id; /* the LAPI task ID */
int num_tasks; /* the total number of tasks */
void *hdr_hndlr_list[NUM_TASKS]; /* the table of remote header handlers */
int buddy; /* the communication partner */
lapi_cntr_t cmpl_cntr; /* the completion counter */
int data_buffer[DATA_LEN]; /* the data to transfer */
.
.
.
/* retrieve header handler addresses */
LAPI_Address_init(hndl, (void *)&hdr_hndlr, hdr_hndlr_list);
/*
** up to this point, all instructions have executed on all
** tasks. we now begin differentiating tasks.
*/
if ( sender ) { /* origin task */
/* initialize data buffer, cmpl_cntr, etc. */
.
.
.
/* synchronize before starting data transfer */
LAPI_Gfence(hndl);
LAPI_Amsend(hndl, buddy, (void *)hdr_hndlr_list[buddy], NULL,
0,&(data_buffer[0]),DATA_LEN*(sizeof(int)),
NULL, NULL, cmpl_cntr);
/* Wait on completion counter before continuing. Completion */
/* counter will update when message completes at target. */
} else { /* receiver */
.
.
.
/* to match the origin's synchronization before data transfer */
LAPI_Gfence(hndl);
}
.
.
.
}有关完整的程序列表,请参阅 RSCT for AIX 5L: LAPI Programming Guide 。 可以在 LAPI 样本文件中找到说明 LAPI_Amsend 调用的样本代码。 有关 LAPI 随附的样本程序的更多信息,请参阅 RSCT for AIX 5L: LAPI Programming Guide 。
位置
- /usr/lib/liblapi_r.a