LAPI_Amsendv Sous-routine
Objectif
Transfère un vecteur utilisateur vers une tâche distante, obtenant l'adresse cible sur la tâche distante à partir d'un gestionnaire d'en-tête spécifié par l'utilisateur.
Bibliothèque
Bibliothèque de disponibilité (liblapi_r.a)
Syntaxe C
#include <lapi.h>
typedef void (compl_hndlr_t) (hndl, user_info);
lapi_handle_t *hndl; /* the LAPI handle passed in from LAPI_Amsendv */
void *user_info; /* the buffer (user_info) pointer passed in */
/* from vhdr_hndlr (void *(vhdr_hndlr_t)) */
typedef lapi_vec_t *(vhdr_hndlr_t) (hndl, uhdr, uhdr_len, len_vec, comp_h, uinfo);
lapi_handle_t *hndl; /* pointer to the LAPI handle passed in from LAPI_Amsendv */
void *uhdr; /* uhdr passed in from LAPI_Amsendv */
uint *uhdr_len; /* uhdr_len passed in from LAPI_Amsendv */
ulong *len_vec[ ]; /* vector of lengths passed in LAPI_Amsendv */
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_Amsendv(hndl, tgt, hdr_hdl, uhdr, uhdr_len, org_vec,
tgt_cntr, org_cntr, cmpl_cntr);
lapi_handle_t hndl;
uint tgt;
void *hdr_hdl;
void *uhdr;
uint uhdr_len;
lapi_vec_t *org_vec;
lapi_cntr_t *tgt_cntr;
lapi_cntr_t *org_cntr;
lapi_cntr_t *cmpl_cntr; Syntaxe FORTRAN
include 'lapif.h'
INTEGER SUBROUTINE COMPL_H (hndl, user_info)
INTEGER hndl
INTEGER user_info(*)
INTEGER FUNCTION VHDR_HDL (hndl, uhdr, uhdr_len, len_vec, comp_h, user_info)
INTEGER hndl
INTEGER uhdr
INTEGER uhdr_len
INTEGER (KIND=LAPI_LONG_TYPE) :: len_vec
EXTERNAL INTEGER FUNCTION comp_h
TYPE (LAPI_ADDR_T) :: user_info
LAPI_AMSENDV(hndl, tgt, hdr_hdl, uhdr, uhdr_len, org_vec,
tgt_cntr, org_cntr, cmpl_cntr, ierror)
INTEGER hndl
INTEGER tgt
EXTERNAL INTEGER FUNCTION hdr_hdl
INTEGER uhdr
INTEGER uhdr_len
TYPE (LAPI_VEC_T) :: org_vec
INTEGER (KIND=LAPI_ADDR_TYPE) :: tgt_cntr
TYPE (LAPI_CNTR_T) :: org_cntr
TYPE (LAPI_CNTR_T) :: cmpl_cntr
INTEGER ierror
Descriptif
Communication point à point Type of call: (non bloquante)
LAPI_Amsendv est la version vectorielle de l'appel LAPI_Amsend . Vous pouvez l'utiliser pour spécifier des descriptions multidimensionnelles et non contiguës des données à transférer. Alors que les appels LAPI réguliers permettent la spécification d'une seule adresse de mémoire tampon de données et de longueur, les versions vectorielles permettent la spécification d'un vecteur d'adresses et de combinaisons de longueur. Des informations supplémentaires sont autorisées dans la description des données sur la tâche d'origine et la tâche cible.
Utilisez cette sous-routine pour transférer un vecteur de données vers une tâche cible, lorsque vous souhaitez qu'un gestionnaire s'exécute sur la tâche cible avant le début de la distribution des messages ou la fin de la distribution des messages.
Pour utiliser LAPI_Amsendv, vous devez fournir un gestionnaire d'en-tête qui renvoie l'adresse de la description du vecteur cible que LAPI utilise pour écrire les données qui sont décrites par le vecteur d'origine. Le gestionnaire d'en-tête est utilisé pour spécifier l'adresse de la description de vecteur pour l'écriture des données, ce qui élimine la nécessité de connaître la description de la tâche d'origine lorsque le sous-programme est appelé. Le gestionnaire d'en-tête est appelé à l'arrivée du premier paquet de données à la cible.
Vous pouvez également fournir un gestionnaire d'exécution. Le gestionnaire d'en-tête fournit des informations supplémentaires à LAPI sur la distribution des messages, telles que le gestionnaire d'exécution. Vous pouvez également spécifier un paramètre de gestionnaire d'exécution à partir du gestionnaire d'en-tête. LAPI transmet les informations au gestionnaire d'exécution lors de l'exécution.
A l'exception de l'adresse renvoyée par le gestionnaire d'exécution, l'utilisation des compteurs, des gestionnaires d'en-tête et des gestionnaires d'exécution dans LAPI_Amsendv est identique à celle de LAPI_Amsend. Dans les deux cas, le gestionnaire d'en-tête utilisateur renvoie les informations utilisées par LAPI pour écrire sur la cible. Pour plus d'informations, voir LAPI_Amsend . Cette section présente des informations spécifiques à la version vectorielle de l'appel (LAPI_Amsendv).
typedef struct {
lapi_vectype_t vec_type;
uint num_vecs;
void **info;
ulong *len;
} lapi_vec_t;type_vecteur est une énumération qui décrit le type de transfert de vecteur, qui peut être: LAPI_GEN_GENERIC, LAPI_GEN_IOVECTORou LAPI_GEN_STRIDED_XFER.- Num_vecs
- Indique le nombre de vecteurs de données à transférer. Chaque vecteur de données est défini par une adresse de base et une longueur de données.
- info
- Est le tableau d'adresses.
- longueur
- Est le tableau des longueurs de données.
vec_type = LAPI_GEN_IOVECTOR
num_vecs = 3
info = {addr_0, addr_1, addr_2}
len = {len_0, len_1, len_2}Du côté de l'origine, cet exemple indique à LAPI de lire len_0 octets à partir de addr_0, len_1 octets de addr_1et len_2 octets de addr_2. En tant que vecteur cible, cet exemple indique à LAPI d'écrire len_0 octets à addr_0, len_1 octets à addr_1et len_2 octets à addr_2.Rappelez-vous que les transferts de vecteurs nécessitent une origine et un vecteur cible. Pour les appels LAPI_Amsendv , le vecteur d'origine est transmis à l'appel API sur la tâche d'origine. L'adresse du vecteur cible est renvoyée par le gestionnaire d'en-tête.
Pour les transferts de type LAPI_GEN_GENERIC, la description du vecteur cible doit également être de type LAPI_GEN_GENERIC. Le contenu des tableaux Informations et Len est illimité dans le cas générique ; le nombre de vecteurs et la longueur des vecteurs sur l'origine et la cible n'ont pas besoin d'être identiques. Dans ce cas, LAPI transfère un nombre donné d'octets dans des mémoires tampon non contiguës spécifiées par le vecteur d'origine vers un ensemble de tampons non contigus spécifié par le vecteur cible.
Origin_vector: {
num_vecs = 3;
info = {orgaddr_0, orgaddr_1, orgaddr_2};
len = {5, 10, 5}
}
Target_vector: {
num_vecs = 4;
info = {tgtaddr_0, tgtaddr_1, tgtaddr_2, tgtaddr_3};
len = {12, 2, 4, 2}
}LAPI copie les données comme suit:- 5 octets de orgaddr_0 à tgtaddr_0 (laisse 7 octets d'espace à un décalage de 5 octets à partir de tgtaddr_0)
- 7 octets de orgaddr_1 à l'espace restant dans tgtaddr_0 (laisse 3 octets de données à transférer depuis orgaddr_1)
- 2 octets de orgaddr_1 à tgtaddr_1 (laisse un octet à un transfert à partir de orgaddr_1)
- 1 octet de orgaddr_1 suivi de 3 octets de orgaddr_2 vers tgt_addr_2 (laisse 3 octets à transférer à partir de orgaddr_2)
- 2 octets de orgaddr_2 à tgtaddr_3
Origin_vector: {
num_vecs = 1;
info = {orgaddr_0};
len = {20}
}
Target_vector: {
num_vecs = 2;
info = {tgtaddr_0, tgtaddr_1};
len = {5, 10}
}LAPI copie 5 octets de orgaddr_0 vers tgtaddr_0 et les 10 octets suivants de orgaddr_0 vers tgtaddr_1. Les 5 octets restants de orgaddr_0 ne seront pas copiés.- avoir également le type LAPI_GEN_IOVECTOR
- Avoir le même Num_vecs que le vecteur d'origine
- Initialisez le tableau d'informations avec les adresses Num_vecs dans l'espace adresse cible. Pour les vecteurs LAPI origin_vecteur et target_vecteurs décrits de la même manière que l'exemple ci-dessus, les données sont copiées comme suit:
- transférer origin_vector.len[ 0 ] octets de l'adresse origin_vector.info[ 0 ] vers l'adresse target_vector.info[ 0 ]
- transfert de origin_vector.len[ 1 ] octets de l'adresse origin_vector.info[ 1 ] à l'adresse target_vector.info[ 1 ]
- transfert de origin_vector.len[n] octets de l'adresse à origin_vector.info[n] vers l'adresse à target_vector.info[n], pour n = 2 vers n = [num_vecs-3 ]
- transfer origin_vector.len[num_vecs-2 ] octets de l'adresse origin_vector.info[num_vecs-2 ] à l'adresse target_vector.info[num_vecs-2 ]
- copy origin_vector.len[nombre_vecs-1 ] octets à partir de l'adresse origin_vector.info[nombre_vecs-1 ] vers l'adresse target_vector.info[nombre_vecs-1 ]
Transferts vectoriels rayés
Origin_vector {
num_vecs = 3;
info = {orgaddr, 5, 8}
}En fonction de cette description, LAPI transfère 5 octets d'orgaddr, 5 octets de orgaddr+8 et 5 octets à partir de orgaddr+16.Coordonnées de la téléconférence
Comme indiqué ci-dessus, le comportement des compteurs et des gestionnaires dans LAPI_Amsendv est presque identique à celui de LAPI_Amsend. Un court résumé de ce comportement est fourni ici. Pour plus d'informations, voir la description de LAPI_Amsend .
Il s'agit d'un appel non bloquant. La tâche appelante ne peut pas modifier les données Uhc (en-tête d'origine) et Org_vec jusqu'à ce que l'achèvement à l'origine soit signalé par l'incrémentation de Org_cntr . La tâche appelante ne peut pas supposer que la structure Org_vec peut être modifiée avant l'incrémentation du compteur d'origine. La structure (de type lapi_vec_t) renvoyée par le gestionnaire d'en-tête ne peut pas être modifiée avant que le compteur cible ait été incrémenté. De plus, si un gestionnaire d'achèvement est spécifié, il peut s'exécuter de manière asynchrone et ne peut être supposé être terminé qu'après les incréments de compteur cible (sur la cible) ou les incréments du compteur d'achèvement (à l'origine).
La longueur de l'en-tête spécifié par l'utilisateur (Uhdr_len) est limitée par la valeur maximale spécifiée par l'implémentation MAX_UHDR_SZ. Uhdr_len doit être un multiple de la taille du mot double du processeur. Pour obtenir la meilleure bande passante, Uhdr_len doit être le plus petit possible.
- Si un vecteur strié est transféré, la taille de chaque bloc ne doit pas être supérieure à la taille de segment en octets.
LAPI ne vérifie pas les régions qui se chevauchent entre les vecteurs, soit à l'origine, soit à la cible. Si les régions qui se chevauchent existent sur le côté cible, le contenu de la mémoire tampon cible n'est pas défini après l'opération.
Paramètres
- Hndl
- Indique le descripteur LAPI.
- Tgt
- Indique l'ID tâche de la tâche cible. La valeur de ce paramètre doit être comprise dans la plage 0 < = tgt < NUM_TASKS.
- Hdr_hdl
- Pointe vers la fonction de gestionnaire d'en-tête distant à appeler sur la cible. La valeur de ce paramètre peut prendre un descripteur d'adresse précédemment enregistré à l'aide du mécanisme LAPI_Addr_set/LAPI_Addr_get . La valeur de ce paramètre ne peut pas être NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN).
- Uhc
- Indique le pointeur vers l'en-tête local (liste de paramètres) transmis à la fonction de gestionnaire. Si uhdr_len est 0, la valeur de ce paramètre peut être NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN).
- Uhdr_len
- Indique la longueur de l'en-tête de l'utilisateur. La valeur de ce paramètre doit être un multiple de la taille de mot double du processeur dans la plage 0 < = uhdr_len < = MAX_UHDR_SZ.
- Org_vec
- Pointe vers le vecteur d'origine.
- Entrée-sortie
- Tgt_cntr
- Indique l'adresse du compteur cible. Le compteur cible est incrémenté lorsque le gestionnaire d'achèvement (si spécifié) est terminé ou après l'achèvement du transfert de données. Si la valeur de ce paramètre est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN), le compteur cible n'est pas mis à jour.
- Org_cntr
- Indique l'adresse du compteur d'origine (en C) ou le compteur d'origine (dans FORTRAN). Le compteur d'origine est incrémenté lorsque les données sont copiées hors de l'adresse d'origine (en C) ou de l'origine (dans FORTRAN). Si la valeur de ce paramètre est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN), le compteur d'origine n'est pas mis à jour.
- Cmpl_cntr
- Indique le compteur à l'origine qui signifie l'achèvement du gestionnaire d'achèvement. Il est mis à jour une fois le gestionnaire d'achèvement terminé. Si aucun gestionnaire d'achèvement n'est spécifié, le compteur est incrémenté à la fin de la distribution des messages. Si la valeur de ce paramètre est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN), le compteur d'achèvement n'est pas mis à jour.
- Sortie
- Ierror
- Indique un code retour FORTRAN. C'est toujours le dernier paramètre.
C Exemples
- Pour envoyer un LAPI_GEN_IOVECTOR à l'aide de messages actifs:
L'exemple ci-dessus peut également illustrer le type LAPI_GEN_GENERIC , avec les modifications suivantes:/* header handler routine to execute on target task */ lapi_vec_t *hdr_hndlr(lapi_handle_t *handle, void *uhdr, uint *uhdr_len, ulong *len_vec[ ], compl_hndlr_t **completion_handler, void **user_info) { /* set completion handler pointer and other info */ /* set up the vector to return to LAPI */ /* for a LAPI_GEN_IOVECTOR: num_vecs, vec_type, and len must all have */ /* the same values as the origin vector. The info array should */ /* contain the buffer addresses for LAPI to write the data */ vec->num_vecs = NUM_VECS; vec->vec_type = LAPI_GEN_IOVECTOR; vec->len = (unsigned long *)malloc(NUM_VECS*sizeof(unsigned long)); vec->info = (void **) malloc(NUM_VECS*sizeof(void *)); for( i=0; i < NUM_VECS; i++ ) { vec->info[i] = (void *) &data_buffer[i]; vec->len[i] = (unsigned long)(sizeof(int)); } return vec; } { . . . void *hdr_hndlr_list[NUM_TASKS]; /* table of remote header handlers */ lapi_vec_t *vec; /* data for data transfer */ vec->num_vecs = NUM_VECS; vec->vec_type = LAPI_GEN_IOVECTOR; vec->len = (unsigned long *) malloc(NUM_VECS*sizeof(unsigned long)); vec->info = (void **) malloc(NUM_VECS*sizeof(void *)); /* each vec->info[i] gets a base address */ /* each vec->len[i] gets the number of bytes to transfer from vec->info[i] */ LAPI_Amsendv(hndl, tgt, (void *) hdr_hdl_list[buddy], NULL, 0, vec, tgt_cntr, org_cntr, cmpl_cntr); /* data will be copied as follows: */ /* len[0] bytes of data starting from address info[0] */ /* len[1] bytes of data starting from address info[1] */ . . . /* len[NUM_VECS-1] bytes of data starting from address info[NUM_VECS-1] */ }- Les deux vecteurs auraient besoin de LAPI_GEN_GENERIC comme vec_type.
- Il n'existe aucune restriction quant à la symétrie du nombre de vecteurs et de longueurs entre l'origine et les côtés cibles.
- Pour envoyer un LAPI_STRIDED_VECTOR à l'aide de messages actifs:
/* header handler routine to execute on target task */ lapi_vec_t *hdr_hndlr(lapi_handle_t *handle, void *uhdr, uint *uhdr_len, ulong *len_vec[ ], compl_hndlr_t **completion_handler, void **user_info) { int block_size; /* block size */ int data_size; /* stride */ . . . vec->num_vecs = NUM_VECS; /* NUM_VECS = number of vectors to transfer */ /* must match that of the origin vector */ vec->vec_type = LAPI_GEN_STRIDED_XFER; /* same as origin vector */ /* see comments in origin vector setup for a description of how data */ /* will be copied based on these settings. */ vec->info[0] = buffer_address; /* starting address for data copy */ vec->info[1] = block_size; /* bytes of data to copy */ vec->info[2] = stride; /* distance from copy block to copy block */ . . . return vec; } { . . . lapi_vec_t *vec; /* data for data transfer */ vec->num_vecs = NUM_VECS; /* NUM_VECS = number of vectors to transfer */ /* must match that of the target vector */ vec->vec_type = LAPI_GEN_STRIDED_XFER; /* same as target vector */ vec->info[0] = buffer_address; /* starting address for data copy */ vec->info[1] = block_size; /* bytes of data to copy */ vec->info[2] = stride; /* distance from copy block to copy block */ /* data will be copied as follows: */ /* block_size bytes will be copied from buffer_address */ /* block_size bytes will be copied from buffer_address+stride */ /* block_size bytes will be copied from buffer_address+(2*stride) */ /* block_size bytes will be copied from buffer_address+(3*stride) */ . . . /* block_size bytes will be copied from buffer_address+((NUM_VECS-1)*stride) */ . . . /* if uhdr isn't used, uhdr should be NULL and uhdr_len should be 0 */ /* tgt_cntr, org_cntr and cmpl_cntr can all be NULL */ LAPI_Amsendv(hndl, tgt, (void *) hdr_hdl_list[buddy], uhdr, uhdr_len, vec, tgt_cntr, org_cntr, cmpl_cntr); . . . }
Pour des exemples complets, voir les exemples de programmes fournis avec LAPI.
Valeurs renvoyées
- LAPI_SUCCESS
- Indique que l'appel de fonction a abouti.
- LAPI_ERR_HDR_HNDLR_NULL
- Indique que le hdr_hdl transmis est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN).
- LAPI_ERR_HNDL_INVALID
- Indique que le Hndl transmis n'est pas valide (non initialisé ou à l'état arrêté).
- LAPI_ERR_ORG_EXTENT
- Indique que l'extension de org_vec(stride * num_vecs) est supérieure à la valeur de la constante LAPI LAPI_MAX_MSG_SZ.
- LAPI_ERR_ORG_STRIDE
- Indique que la segmentation Org_vec est inférieure à bloc.
- ADRESSE_ERR_ORG_ADRESSE_VECTEUR_ORDINATEUR
- Indique que org_vec->info [ i ] est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN), mais que sa longueur (org_vec->len [ i ]) n'est pas 0.
- LAPI_ERR_ORG_VEC_LEN
- Indique que la somme de org_vec->len est supérieure à la valeur de la constante LAPI LAPI_MAX_MSG_SZ.
- LAPI_ERR_ORG_VEC_NULL
- Indique que org_vec est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN).
- LAPI_ERR_ORG_VEC_TYPE
- Indique que Org_vec->Type_vecteur n'est pas valide.
- LAPI_ERR_STRIDE_ORG_VEC_ADDR_NULL
- Indique que l'adresse de vecteur segmentée org_vec->info[ 0 ] est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN).
- ERR_ERR_TGT
- Indique que le Tgt transmis ne correspond pas à la plage de tâches définie dans le travail.
- LAPI_ERR_TGT_PURGÉ
- Indique que la sous-routine a été renvoyée tôt car LAPI_Purge_totask() a été appelé.
- LAPI_ERR_UHDR_LEN
- Indique que la valeur Uhdr_len transmise est supérieure à MAX_UHDR_SZ ou qu'elle n'est pas un multiple de la taille du mot de passe du processeur.
- LAPI_ERR_UHDR_NULL
- Indique que le uhdr transmis est NULL (en C) ou LAPI_ADDR_NULL (en FORTRAN), mais que uhdr_len n'est pas 0.
Emplacement
- /usr/lib/liblapi_r.a