LAPI_Amsend Subroutine
Propósito
Transfere uma mensagem de usuário para uma tarefa remota, obtendo o endereço de destino na tarefa remota a partir de um manipulador de cabeçalho especificado pelo usuário.
Biblioteca
Biblioteca de Disponibilidade (liblapi_r.a)
Sintaxe 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;
Sintaxe 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 ierrorDescrição
Type of call: comunicação ponto-a-ponto (sem bloqueio)
Use este subroutine para transferir dados para uma tarefa de destino, em que é desejável executar um manipulador na tarefa de destino antes que a entrega de mensagens comece ou após a entrega ser concluída. LAPI_Amsend permite que o usuário forneça um manipulador de cabeçalho e manipulador de conclusão opcional. O manipulador de cabeçalho é usado para especificar o endereço de buffer de destino para a escrita dos dados, eliminando a necessidade de saber o endereço na tarefa de origem quando a subroutine é chamada.
Os dados do usuário (uhdr e udata) são enviados para a tarefa de destino. Uma vez que esses buffers não são mais necessários na tarefa de origem, o contador de origem é incrementado, o que indica a disponibilidade de buffers de origem para modificação. O uso da chamada LAPI_Xfer com o tipo LAPI_AM_XFER fornece o mesmo tipo de transferência, com a opção de usar um manipulador de conclusão de envio em vez do contador de origem para especificar disponibilidade de buffer.
Após a chegada do primeiro pacote de dados no alvo, o manipulador de cabeçalho do usuário é invocado. Note que um manipulador de cabeçalho deve ser fornecido pelo usuário porque ele retorna o endereço base do buffer no qual LAPI irá gravar os dados enviados a partir da tarefa de origem (udata). Veja RSCT para AIX 5L: Guia de Programação LAPI para uma exceção de otimização a esta exigência de que um endereço de buffer seja fornecido a LAPI para mensagens de pacotes únicos.
O manipulador de cabeçalho também fornece informações adicionais ao LAPI sobre a entrega de mensagens, como o manipulador de conclusão. LAPI_Amsend e chamadas semelhantes (como LAPI_Amsendv e correspondentes LAPI_Xfer transferências) também permitem que o usuário especifique as suas próprias informações de cabeçalho de mensagem, que está disponível para o manipulador de cabeçalho. O usuário pode também especificar um parâmetro de manipulador de conclusão de dentro do manipulador de cabeçalho. LAPI irá passar as informações para o manipulador de conclusão em execução.
Note que o manipulador de cabeçalho é executado inline pela thread executando o despachante LAPI. Por esta razão, o manipulador de cabeçalho deve ser não bloqueando porque nenhum outro progresso em mensagens será feito até que ele retorne. Sugere-se também que a execução do manipulador de cabeçalho seja simples e rápida. O manipulador de conclusão, por outro lado, é normalmente enfileirado para execução por um fio separado. É possível solicitar que o manipulador de conclusão seja executado inline. Veja RSCT para AIX 5L: Guia de Programação LAPI para obter mais informações sobre manipuladores de acabamento inline.
Se um manipulador de conclusão de conclusão não foi especificado (ou seja, configurado como LAPI_ADDR_NULL no FORTRAN ou seu conjunto de ponteiro para NULL em C), a chegada do pacote final faz com que o LAPI incremente o contador de destino na tarefa remota e envie uma mensagem interna de volta para a tarefa de origem. A mensagem causa o contador de conclusão (se ele não for NULL em C ou LAPI_ADDR_NULL no FORTRAN) para incrementar na tarefa de origem.
Se um manipulador de conclusão foi especificado, as etapas acima ocorram após o retorno do manipulador de conclusão. Para garantir que o manipulador de conclusão tenha executado no alvo, deve-se aguardar no balcão de conclusão. Veja RSCT para AIX 5L: Guia de Programação LAPI para um diagrama de sequência de tempo de eventos em uma chamada LAPI_Amsend .
Detalhes do usuário
void *hdr_hndlr(lapi_handle_t *hndl, void *uhdr, uint *uhdr_len, ulong *msg_len,
compl_hndlr_t **cmpl_hndlr, void **user_info);O valor retornado pelo manipulador de cabeçalho é interpretado por LAPI como um endereço para a escrita dos dados do usuário (udata) que foi passada para a chamada LAPI_Amsend . Os parâmetros uhdr e uhdr_len são transmitidos por LAPI para o manipulador de cabeçalho e contêm as informações passadas pelo usuário para os parâmetros correspondentes da chamada LAPI_Amsend .Uso de LAPI_Addr_set
Os endereços remotos são comumente trocados por meio da emissão de um chamado coletivo LAPI_Address_init dentro de alguns passos de inicializar LAPI. A LAPI também fornece o mecanismo LAPI_Addr_set , pelo qual os usuários podem registrar um ou mais endereços de manipulador de cabeçalho em uma tabela, associando um valor de índice a cada endereço. Esse índice pode então ser passado para LAPI_Amsend em vez de um endereço real. No lado alvo, LAPI usará o índice para obter o endereço do manipulador de cabeçalho. Observe que, se todas as tarefas utilizarem o mesmo índice para seu manipulador de cabeçalho, a comunicação coletiva inicial poderá ser evitada. Cada tarefa simplesmente registra seu próprio endereço de manipulador de cabeçalho usando o índice conhecido. Em seguida, em quaisquer chamadas LAPI_Amsend , o índice reservado pode ser passado para o parâmetro de endereço do manipulador de cabeçalho.
Função do manipulador de cabeçalho
O usuário, opcionalmente, retorna o endereço de uma função de manipulador de conclusão por meio do parâmetro cmpl_hndlr e um parâmetro manipulador de conclusão através do parâmetro user_info . O endereço passado através do parâmetro user_info pode referir-se à memória contendo um datatype definido pelo usuário e, em seguida, escalar para o tipo apropriado a partir de dentro do manipulador de conclusão se desejar.
typedef void (compl_hndlr_t)(lapi_handle_t *hndl, void *completion_param);O argumento retornado por referência através do membro user_info do manipulador de cabeçalho do usuário será passado para o argumento completion_param do manipulador de conclusão do usuário. Veja os Exemplos de C para um exemplo de configuração do manipulador de conclusão e parâmetro no manipulador de cabeçalho.Como mencionado acima, o valor retornado pelo manipulador de cabeçalho deve ser um endereço para a escrita dos dados do usuário enviados a partir da tarefa de origem. Há uma exceção para essa regra. No caso de uma mensagem de pacote único, LAPI passa o endereço do pacote no FIFO do recebimento, permitindo que toda a mensagem seja consumida dentro do manipulador de cabeçalho. Neste caso, o manipulador de cabeçalho deve retornar NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN) para que o LAPI não copie a mensagem para um buffer de destino. Veja RSCT para AIX 5L: Guia de Programação LAPI para obter mais informações (incluindo um manipulador de cabeçalho de amostra que usa este método para recuperação rápida de uma mensagem de um pacote único).
Passando informações adicionais através de lapi_return_info_t
O LAPI permite que informações adicionais sejam passadas e retornadas do manipulador de cabeçalho passando um ponteiro para lapi_return_info_t através do argumento msg_len . No retorno de um manipulador de cabeçalho que é invocado por uma chamada para LAPI_Amsend, o membro ret_flags de lapi_return_info_t pode conter um desses valores: LAPI_NORMAL (o padrão), LAPI_SEND_REPLY (para executar o manipulador de conclusão inline), ou LAPI_LOCAL_STATE (nenhuma resposta é enviada). O membro dgsp_handle de lapi_return_info_t não deve ser usado em conjunto com LAPI_Amsend.
Para uma descrição completa do tipo lapi_return_info_t , consulte RSCT para AIX 5L: Guia de Programação LAPI
execução inline de manipuladores de conclusão
Em operação normal, LAPI usa uma thread separada para executar manipuladores de conclusão de usuário. Após o pacote final chegar, os ponteiros do manipulador de conclusão são colocados em uma fila para serem tratados por este encadeamento. Por motivos de desempenho, o usuário pode solicitar que um determinado manipulador de conclusão seja executado inline em vez de ser colocado nesta fila atrás de outros manipuladores de acabamento. Este mecanismo dá aos usuários um maior grau de controle na priorização da execução do manipulador de conclusão para mensagens de desempenho crítico.
LAPI coloca sem restrições os manipuladores de conclusão que são executados "normalmente" (ou seja, pelo encadeamento do manipulador de conclusão). Os manipuladores de acabamento inline devem ser curtos e não devem bloquear, pois nenhum progresso pode ser feito enquanto a thread principal estiver executando o manipulador. O usuário deve usar o cuidado com os manipuladores de conclusão de inline para que as filas internas da LAPI não se preencham enquanto aguarda o manipulador ser concluído. As operações de E/S não devem ser executadas com um manipulador de conclusão inline.
Parâmetros
- INPUT
- hndl
- Especifica a alça LAPI.
- tgt
- Especifica o ID da tarefa da tarefa de destino. O valor deste parâmetro deve estar na faixa 0 < = tgt < NUM_TASKS.
- hdr_hdl
- Especifica o ponteiro para a função de manipulador de cabeçalho remoto a ser invocado no destino. O valor deste parâmetro pode tirar uma alça de endereço que já foi registrado usando LAPI_Addr_set. O valor deste parâmetro não pode ser NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN).
- uhdr
- Especifica o ponteiro para os dados do cabeçalho do usuário. Esses dados serão passados para o manipulador de cabeçalho do usuário no destino. Se uhdr_len for 0, O valor deste parâmetro pode ser NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN).
- uhdr_len
- Especifica o comprimento do cabeçalho do usuário. O valor deste parâmetro deve ser um múltiplo do tamanho word do processador no intervalo 0 < = uhdr_len < = MAX_UHDR_SZ.
- udata
- Especifica o ponteiro para os dados do usuário. Se udata_len for 0, O valor deste parâmetro pode ser NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN).
- udata_len
- Especifica o comprimento dos dados do usuário em bytes. O valor deste parâmetro deve estar na faixa 0 < = udata_len < = o valor da constante LAPI LAPI_MAX_MSG_SZ.
- entrada/saída
- tgt_cntr
- Especifica o endereço do contador de destino. O contador de destino é incrementado após o manipulador de conclusão (se especificado) concluir ou após a conclusão da transferência de dados. Se o valor deste parâmetro for NULL (em C) ou LAPI_ADDR_NULL (no FORTRAN), o contador de destino não será atualizado.
- org_cntr
- Especifica o endereço do contador de origem (em C) ou o contador de origem (em FORTRAN). O contador de origem é incrementado após os dados serem copiados para fora do endereço de origem (em C) ou da origem (em FORTRAN). Se o valor deste parâmetro for NULL (em C) ou LAPI_ADDR_NULL (no FORTRAN), o contador de origem não será atualizado.
- cmpl_cntr
- Especifica o contador na origem que significa conclusão do manipulador de conclusão. Ele é atualizado uma vez que o manipulador de conclusão é concluído. Se nenhum manipulador de conclusão for especificado, o contador será incrementado na conclusão da entrega de mensagens. Se o valor deste parâmetro for NULL (em C) ou LAPI_ADDR_NULL (no FORTRAN), o contador de conclusão não será atualizado.
- SAÍDA
- ierror
- Especifica um código de retorno FORTRAN. Este é sempre o último parâmetro.
Valores De Retorno
- LAPI_SUCESSO
- Indica que a chamada de função foi concluída com sucesso.
- LAPI_ERR_DATA_LEN
- Indica que o valor de udata_len é maior do que o valor da constante LAPI LAPI_MAX_MSG_SZ.
- LAPI_ERR_HDR_HNDLR_NULL
- Indica que o valor do hdr_hdl passado em é NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN).
- LAPI_ERR_HNDL_INVÁLIDA
- Indica que o hndl passado em não é válido (não inicializado ou em estado finalizado).
- LAPI_ERR_ORG_ADDR_NULL
- Indica que o valor do parâmetro udata passado em é NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN), mas o valor de udata_len é maior que 0.
- LAPI_ERR_TGT
- Indica que o tgt passado em está fora do intervalo de tarefas definidas no job.
- LAPI_ERR_TGT_PURGED
- Indica que a subroutine retornou mais cedo porque LAPI_Purge_totask() foi chamada.
- LAPI_ERR_UHDR_LEN
- Indica que o valor uhdr_len passado em é maior do que MAX_UHDR_SZ ou não é um múltiplo do tamanho do doubleword do processador.
- LAPI_ERR_UHDR_NULL
- Indica que o uhdr passado em é NULL (em C) ou LAPI_ADDR_NULL (em FORTRAN), mas uhdr_len não é 0.
Exemplos de 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);
}
.
.
.
}Para uma listagem completa do programa, consulte RSCT para AIX 5L: Guia de Programação LAPI. Código de amostra ilustrando a chamada LAPI_Amsend pode ser encontrado nos arquivos de amostra LAPI. Veja RSCT para AIX 5L: Guia de Programação LAPI para obter mais informações sobre os programas de amostra embarcados com LAPI.
Local
- /usr/lib/liblapi_r.a