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 사용자가 헤더 핸들러와 선택적 완성 핸들러를 제공할 수 있도록 합니다. 헤더 핸들러는 데이터를 쓰기 위한 대상 버퍼 주소를 지정하는 데 사용되므로 서브루틴이 호출될 때 원본 작업의 주소를 알 필요가 없습니다.

사용자 데이터(uhdrudata)가 대상 작업으로 전송됩니다. 오리진 작업에서 이러한 버퍼가 더 이상 필요하지 않게 되면 오리진 카운터가 증가하여 수정할 수 있는 오리진 버퍼의 가용성을 나타냅니다. ' LAPI_Xfer 호출을 ' LAPI_AM_XFER ' 유형과 함께 사용하면 동일한 유형의 전송을 제공하며, 원본 카운터 대신 전송 완료 핸들러를 사용하여 버퍼 가용성을 지정하는 옵션이 제공됩니다.

대상에 첫 번째 데이터 패킷이 도착하면 사용자의 헤더 핸들러가 호출됩니다. 헤더 핸들러는 LAPI가 원본 작업(udata)에서 보낸 데이터를 기록할 버퍼의 기본 주소를 반환하므로 사용자가 제공해야 합니다. 단일 패킷 메시지에 대한 버퍼 주소를 LAPI에 제공해야 하는 이 요구 사항에 대한 최적화 예외에 대해서는 AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요.

헤더 핸들러는 완료 핸들러와 같은 메시지 전달에 대한 추가 정보도 LAPI에 제공합니다. LAPI_Amsend ' 및 이와 유사한 호출(' LAPI_Amsendv ' 및 해당 ' LAPI_Xfer 전송 등)을 통해 사용자는 헤더 핸들러가 사용할 수 있는 메시지 헤더 정보를 직접 지정할 수도 있습니다. 사용자는 헤더 핸들러 내에서 완성 핸들러 매개변수를 지정할 수도 있습니다. LAPI는 실행 시 완료 핸들러에 정보를 전달합니다.

헤더 핸들러는 LAPI 디스패처를 실행하는 스레드에서 인라인으로 실행된다는 점에 유의하세요. 따라서 헤더 핸들러가 반환될 때까지 메시지에 대한 다른 진행이 이루어지지 않으므로 헤더 핸들러는 비차단이어야 합니다. 또한 헤더 핸들러를 간단하고 빠르게 실행하는 것이 좋습니다. 반면에 완료 처리기는 일반적으로 별도의 스레드에서 실행을 위해 대기열에 대기합니다. 완료 처리기를 인라인으로 실행하도록 요청할 수 있습니다. 인라인 완료 핸들러에 대한 자세한 내용은 AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요.

완료 처리기가 지정되지 않은 경우(즉, FORTRAN에서 ' LAPI_ADDR_NULL '로 설정되거나 C에서 해당 포인터가 NULL로 설정된 경우), 최종 패킷이 도착하면 LAPI는 원격 작업의 대상 카운터를 증가시키고 내부 메시지를 원본 작업으로 다시 보냅니다. 이 메시지는 원본 작업에서 완료 카운터(C에서는 NULL 또는 FORTRAN에서는 ' LAPI_ADDR_NULL '이 아닌 경우)가 증가하도록 합니다.

완료 처리기를 지정한 경우 완료 처리기가 반환된 후 위의 단계가 수행됩니다. 완료 핸들러가 대상에서 실행되었는지 확인하려면 완료 카운터를 기다려야 합니다. ' LAPI_Amsend 호출에서 이벤트의 시간 순서 다이어그램은 AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요.

사용자 세부사항

위에서 언급했듯이 사용자는 첫 번째 데이터 패킷이 도착하면 대상에서 실행할 헤더 핸들러의 주소를 제공해야 합니다. 헤더 핸들러의 서명은 다음과 같습니다:
void *hdr_hndlr(lapi_handle_t *hndl, void *uhdr, uint *uhdr_len, ulong *msg_len, 
               compl_hndlr_t **cmpl_hndlr, void **user_info);
헤더 핸들러가 반환한 값은 ' LAPI_Amsend ' 호출에 전달된 사용자 데이터(udata)를 쓰기 위한 주소로 LAPI에서 해석됩니다. Uhdruhdr_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에 패킷 주소를 전달하여 헤더 핸들러 내에서 전체 메시지를 소비할 수 있도록 합니다. 이 경우 헤더 핸들러는 LAPI가 메시지를 대상 버퍼에 복사하지 않도록 NULL(C에서는) 또는 ' LAPI_ADDR_NULL '(FORTRAN에서는)을 반환해야 합니다. 자세한 내용은 (단일 패킷 메시지의 빠른 검색을 위해 이 방법을 사용하는 헤더 처리기 샘플을 포함한) AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요.

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 ' 유형에 대한 자세한 설명은 AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요

완료 핸들러의 인라인 실행

정상 작동 시 LAPI는 사용자 완료 핸들러를 실행하기 위해 별도의 스레드를 사용합니다. 최종 패킷이 도착하면 완료 핸들러 포인터가 이 스레드에서 처리할 대기열에 배치됩니다. 성능상의 이유로 사용자는 특정 완료 처리기를 다른 완료 처리기 뒤에 이 대기열에 배치하는 대신 인라인으로 실행하도록 요청할 수 있습니다. 이 메커니즘을 통해 사용자는 성능에 중요한 메시지에 대한 완료 핸들러 실행 우선순위를 보다 세밀하게 제어할 수 있습니다.

LAPI는 "정상적으로"(즉, 완료 핸들러 스레드에 의해) 실행되는 완료 핸들러에는 아무런 제한을 두지 않습니다. 인라인 완료 핸들러는 짧아야 하며 메인 스레드가 핸들러를 실행하는 동안에는 진행이 불가능하므로 차단해서는 안 됩니다. 사용자는 인라인 완료 처리기를 사용할 때 주의하여 처리기가 완료되기를 기다리는 동안 LAPI의 내부 대기열이 가득 차지 않도록 해야 합니다. 인라인 완료 핸들러로 I/O 작업을 수행해서는 안 됩니다.

매개변수

입력
hndl
LAPI 핸들을 지정합니다.
tgt
대상 작업의 작업 ID를 지정합니다. 이 매개변수의 값은 0 <= tgt < 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
사용자 헤더의 길이를 지정합니다. 이 매개변수의 값은 ' 0 <= uhdr_len <= MAX_UHDR_SZ 범위에서 프로세서 워드 크기의 배수여야 합니다.
udata
사용자 데이터에 대한 포인터를 지정합니다. Udata_len이 ' 0인 경우 이 매개변수의 값은 NULL(C에서는) 또는 ' LAPI_ADDR_NULL '(FORTRAN에서는)일 수 있습니다.
udata_len
사용자 데이터의 길이를 바이트 단위로 지정합니다. 이 파라미터의 값은 0 <= udata_len <= LAPI 상수 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의 경우)이면 완료 카운터가 업데이트되지 않습니다.
OUTPUT
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);
    }

    .
    .
    .
}

전체 프로그램 목록은 AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요. ' LAPI_Amsend ' 호출을 설명하는 샘플 코드는 LAPI 샘플 파일에서 확인할 수 있습니다. LAPI와 함께 제공되는 샘플 프로그램에 대한 자세한 내용은 AIX 5L용 RSCT: LAPI 프로그래밍 가이드를 참조하세요.

위치

/usr/lib/liblapi_r.a