psmile_bsend.c File Reference

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "mpi.h"
#include "PSMILe_f2c.h"
Include dependency graph for psmile_bsend.c:

Go to the source code of this file.

Defines

#define PRISM_Error_Alloc   13
#define MAX(a, b)   (a) > (b) ? (a) : (b)
#define ASSERT2(c, a, b)
#define n_to_free   64
#define dfree   64*2048
#define N_HASH   16

Functions/Subroutines

void psmile_bsend_init (INTEGER *ftypes, INTEGER *flengths, INTEGER *number_of_ftypes, INTEGER *ierror)
void psmile_bsend (void *buf, INTEGER *lenbuf, INTEGER *dtype, INTEGER *dest, INTEGER *tag, INTEGER *comm, INTEGER *ierror)
static void error_in_testany (int imin, int ind, int error)
static int free_buffers (long long len_bytes, int free_memory)
static int release_buffer (int i, long long len_bytes, int *imin, int free_memory)

Variables

static double dalloc = 0.0
static MPI_Request * requests = NULL
static void ** buffers = NULL
static long long * lengths = NULL
static int nalloc = 0
static int max_alloc = 0
static int use_hash = 0
static int max_type = -1
static int min_type = 0
static int * dbsend = NULL
static int * dbtype = NULL
static int * dblen = NULL

Define Documentation

#define ASSERT2 ( c,
a,
 ) 
Value:
if (!(c)) {\
   fprintf(stderr, "### Assertion violation: %s (%s = %d, %s = %d) in %s:%d\n", #c, #a, a, #b, b, __FILE__, __LINE__);\
   abort();\
}

Definition at line 19 of file psmile_bsend.c.

Referenced by psmile_bsend(), and release_buffer().

#define dfree   64*2048

Definition at line 39 of file psmile_bsend.c.

Referenced by psmile_bsend().

#define MAX ( a,
 )     (a) > (b) ? (a) : (b)

Definition at line 17 of file psmile_bsend.c.

Referenced by prismtrs_interp(), and psmile_bsend().

#define N_HASH   16

Definition at line 40 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().

#define n_to_free   64

Definition at line 36 of file psmile_bsend.c.

Referenced by psmile_bsend().

#define PRISM_Error_Alloc   13

Definition at line 15 of file psmile_bsend.c.

Referenced by get_neigh_method_data_dble(), get_neigh_method_data_real(), prism_enddef(), prism_error(), prism_init(), prism_put(), prismdrv_init(), prismdrv_init_appl(), prismdrv_set_scc_info(), prismtrs_enqueue_glob_sum_dble(), prismtrs_enqueue_glob_sum_int(), prismtrs_enqueue_in_field_dble(), prismtrs_enqueue_in_field_int(), prismtrs_enqueue_in_field_real(), prismtrs_get_epio_handle(), prismtrs_interp(), prismtrs_mind_dble(), prismtrs_mind_int(), prismtrs_mind_real(), prismtrs_set_neighbors3d(), prismtrs_set_src_epio_dble(), prismtrs_set_src_epio_real(), prismtrs_set_tgt_epio_dble(), prismtrs_set_tgt_epio_real(), psmile_add_nn_found_dble(), psmile_add_nn_found_real(), psmile_add_points_found(), psmile_bbcells_3d_dble(), psmile_bbcells_3d_real(), psmile_bbcells_virt_2d_dble(), psmile_bbcells_virt_2d_real(), psmile_bsend_init(), psmile_compact_locations(), psmile_compact_neighbors_3d(), psmile_create_timeaxis(), psmile_def_domains(), psmile_def_grid(), psmile_def_partition(), psmile_def_var(), psmile_enddef_action(), psmile_enddef_action_cell(), psmile_enddef_action_extra(), psmile_enddef_action_sel(), psmile_enddef_appl(), psmile_enddef_appl_miss(), psmile_enddef_comp(), psmile_enddef_comp_periodic(), psmile_field2grid(), psmile_find_intersect(), psmile_gauss_get_neighbours(), psmile_gauss_setup(), psmile_get_act_comps(), psmile_get_comp_handle(), psmile_get_cyclic_dir_3d_dble(), psmile_get_cyclic_dir_3d_real(), psmile_get_dble(), psmile_get_epio_handle(), psmile_get_exch_index(), psmile_get_field_dble(), psmile_get_field_handle(), psmile_get_field_int(), psmile_get_field_real(), psmile_get_grid_handle(), psmile_get_halo_indices(), psmile_get_int(), psmile_get_intersect(), psmile_get_irr_field_dble(), psmile_get_irr_field_int(), psmile_get_irr_field_real(), psmile_get_locations_3d(), psmile_get_mask_handle(), psmile_get_method_handle(), psmile_get_next_field(), psmile_get_real(), psmile_get_restart(), PSMILe_Get_userdef_handle(), psmile_global_search_cell_dble(), psmile_global_search_cell_real(), psmile_global_search_dble(), psmile_global_search_nnx_dble(), psmile_global_search_nnx_real(), psmile_global_search_real(), psmile_hash_extra(), psmile_info_coords_3d_reg_dble(), psmile_info_coords_3d_reg_real(), psmile_info_coords_irreg2_dble(), psmile_info_coords_irreg2_real(), psmile_info_trf_coords_3d_dble(), psmile_info_trf_coords_3d_real(), psmile_info_trs_loc_3d_reg_dble(), psmile_info_trs_loc_3d_reg_real(), psmile_info_trs_loc_gauss2_dble(), psmile_info_trs_loc_gauss2_real(), psmile_info_trs_loc_irreg2_dble(), psmile_info_trs_loc_irreg2_real(), psmile_info_trs_locs_3d_dble(), psmile_info_trs_locs_3d_real(), psmile_init_mpi1(), psmile_init_mpi2(), psmile_io_get::psmile_io_get_info_init(), psmile_locations_3d(), psmile_locations_alloc(), psmile_locations_direct(), psmile_locations_irreg2(), psmile_mg_coars_level_dble(), psmile_mg_coars_level_real(), psmile_mg_first_level_dble(), psmile_mg_first_level_real(), psmile_mg_found_loc_to_3d(), psmile_mg_method_gauss2_dble(), psmile_mg_method_gauss2_real(), psmile_mg_method_irreg2_dble(), psmile_mg_method_irreg2_real(), psmile_mg_setup(), psmile_mg_srch_nneigh_irr_dble(), psmile_mg_srch_nneigh_irr_real(), psmile_neigh_cells_3d_dble(), psmile_neigh_cells_3d_real(), psmile_neigh_cells_3d_reg_dble(), psmile_neigh_cells_3d_reg_real(), psmile_neigh_cells_irreg2_dble(), psmile_neigh_cells_irreg2_real(), psmile_neigh_extra_points(), psmile_neigh_extra_search_dble(), psmile_neigh_extra_search_init(), psmile_neigh_extra_search_real(), psmile_neigh_global_points(), psmile_neigh_near_3d_irr2_dble(), psmile_neigh_near_3d_irr2_real(), psmile_neigh_near_3d_irr3_dble(), psmile_neigh_near_3d_irr3_real(), psmile_neigh_near_irr2_3d_dble(), psmile_neigh_near_irr2_3d_real(), psmile_neigh_near_irreg2_dble(), psmile_neigh_near_irreg2_real(), psmile_neigh_nearest_3d_dble(), psmile_neigh_nearest_3d_real(), psmile_neigh_nearestx_3d_dble(), psmile_neigh_nearestx_3d_real(), psmile_neigh_nearx_3d_irr2_dble(), psmile_neigh_nearx_3d_irr2_real(), psmile_neigh_nearx_3d_irr3_dble(), psmile_neigh_nearx_3d_irr3_real(), psmile_neigh_nearx_3d_reg_dble(), psmile_neigh_nearx_3d_reg_real(), psmile_neigh_nearx_irr2_3d_dble(), psmile_neigh_nearx_irr2_3d_real(), psmile_neigh_nearx_irreg2_dble(), psmile_neigh_nearx_irreg2_real(), psmile_neigh_nearx_sub_irr_dble(), psmile_neigh_nearx_sub_irr_real(), psmile_neigh_nearx_sub_reg_dble(), psmile_neigh_nearx_sub_reg_real(), psmile_open_file_byid(), psmile_put_dble(), psmile_put_field_21d_dble(), psmile_put_field_21d_int(), psmile_put_field_21d_real(), psmile_put_field_3d_dble(), psmile_put_field_3d_int(), psmile_put_field_3d_real(), psmile_put_field_dble(), psmile_put_field_gauss2_dble(), psmile_put_field_gauss2_int(), psmile_put_field_gauss2_real(), psmile_put_field_int(), psmile_put_field_real(), psmile_put_int(), psmile_put_irr_field_dble(), psmile_put_irr_field_int(), psmile_put_irr_field_real(), psmile_put_real(), psmile_read_3d_int(), psmile_read_3d_real(), psmile_read_4d_int(), psmile_read_4d_real(), psmile_read_byid_dble(), psmile_read_byid_int(), psmile_read_byid_real(), psmile_reallocate::psmile_reallocate_cp(), psmile_reallocate::psmile_reallocate_dble(), psmile_reallocate::psmile_reallocate_int(), psmile_reallocate::psmile_reallocate_log(), psmile_reallocate::psmile_reallocate_real(), psmile_reallocate::psmile_reallocate_rfi(), psmile_reallocate::psmile_reallocate_ri(), psmile_reallocate::psmile_reallocate_sai(), psmile_reallocate::psmile_reallocate_sfi(), psmile_reallocate::psmile_reallocate_si(), psmile_reallocate::psmile_reallocate_ts(), psmile_reallocate::psmile_reallocate_ugd(), psmile_reallocate::psmile_reallocate_umd(), psmile_reallocate::psmile_reallocate_upd(), psmile_reallocate::psmile_reallocate_uvd(), psmile_recv_req_coords_dble(), psmile_recv_req_coords_real(), psmile_recv_req_corners_dble(), psmile_recv_req_corners_real(), psmile_recv_req_mask(), psmile_recv_req_subgrid(), psmile_reducedgrid_map(), psmile_return_extra_off_dble(), psmile_return_extra_off_real(), psmile_search_donor_2d_dble(), psmile_search_donor_2d_real(), psmile_search_donor_3d_dble(), psmile_search_donor_3d_real(), psmile_search_donor_3d_reg_dble(), psmile_search_donor_3d_reg_real(), psmile_search_donor_cells(), psmile_search_donor_extra_nn(), psmile_search_donor_gauss2_dble(), psmile_search_donor_gauss2_real(), psmile_search_donor_irreg2_dble(), psmile_search_donor_irreg2_real(), psmile_search_nn_3d_dble(), psmile_search_nn_3d_real(), psmile_search_nn_3d_reg_dble(), psmile_search_nn_3d_reg_real(), psmile_search_nn_irreg2_dble(), psmile_search_nn_irreg2_real(), psmile_select_nn_found(), psmile_send_req_corners_dble(), psmile_send_req_corners_real(), psmile_set_corners_3d_double(), psmile_set_corners_3d_real(), psmile_set_mask(), psmile_set_points_3d_double(), psmile_set_points_3d_real(), psmile_set_points_gridless(), psmile_spawn_child_appl(), psmile_srch_coords_reg_21d_dble(), psmile_srch_coords_reg_21d_real(), psmile_store_dest_locs_21d(), psmile_store_dest_locs_3d(), psmile_store_dest_locs_3d_msk(), psmile_store_dest_locs_3d_reg(), psmile_store_mask_locs_21d(), psmile_store_mask_locs_3d(), psmile_store_source_locs_1d(), psmile_store_source_locs_2d(), psmile_store_source_locs_3d(), psmile_store_source_locs_3d_msk(), psmile_store_source_locs_3d_reg(), psmile_store_source_virt_3d(), psmile_tricu_3d_extra_off(), psmile_tricu_gauss2_extra(), psmile_trili_3d_extra_off(), psmile_trili_gauss2_extra(), psmile_unfolded_check_dble(), psmile_unfolded_check_real(), psmile_write_3d_int(), psmile_write_3d_log(), psmile_write_3d_real(), psmile_write_4d_int(), psmile_write_4d_log(), psmile_write_4d_real(), psmile_write_byid_dble(), psmile_write_byid_int(), psmile_write_byid_real(), psmile_write_meta_byid(), and recv_halo().


Function Documentation

static void error_in_testany ( int  imin,
int  ind,
int  error 
) [static]

Definition at line 699 of file psmile_bsend.c.

References buffers, i, lengths, nalloc, requests, and mpp_mod_oa::stderr().

Referenced by free_buffers().

00700 {
00701    register int i;
00702    fprintf (stderr, "\nError in MPI_Testany () called form psmile_bsend: error %d\n",
00703                error);
00704    fprintf (stderr, "ind %d request %d nalloc %d ibeg %d:\n",
00705                  ind, requests[ind], nalloc, ibeg);
00706  
00707    for (i=0; i < nalloc; i++) {
00708       fprintf (stderr, "i = %d, start 0x%p len %lld, request %d\n",
00709                    i, buffers [i], lengths [i], requests[i]);
00710    }
00711  
00712    /* Set ``requests [i]'' to NULL to avoid indefinite loop */
00713  
00714    requests [ind] = MPI_REQUEST_NULL;
00715 }

Here is the call graph for this function:

Here is the caller graph for this function:

int free_buffers ( long long  len_bytes,
int  free_memory 
) [static]

Definition at line 535 of file psmile_bsend.c.

References ASSERT, mpp_io_mod_oa::error, error_in_testany(), i, lengths, nalloc, release_buffer(), and requests.

Referenced by psmile_bsend().

00536 {
00537    int imin = -1;
00538    int ibeg = 0;
00539    int error, flag;
00540    MPI_Status lstatus;
00541  
00542    /* --------------------------------------------------------------
00543       Look within the requests which are already fulfilled
00544       -------------------------------------------------------------- */
00545 
00546    while (ibeg < nalloc) {
00547       register int i;
00548 
00549 #pragma vdir vector
00550       for (i=ibeg; i < nalloc; i++) {
00551          if (requests [i] == MPI_REQUEST_NULL) break;
00552       }
00553 
00554       if (i >= nalloc) break;
00555 
00556 
00557       ibeg = release_buffer (i, len_bytes, &imin, free_memory);
00558       if (imin >= 0 && lengths[imin] == len_bytes) {
00559      return imin;
00560       }
00561 
00562    } /* end while */
00563 
00564    /* All buffers are controlled
00565       If a valid buffer IMIN was found, send message */
00566  
00567    if (imin != -1) return imin;
00568  
00569    /* ------------------------------------------------
00570       Look in requests which are not already fulfilled
00571       ------------------------------------------------ */
00572  
00573    ibeg = 0;
00574 
00575    while (ibeg < nalloc) {
00576       int ind;
00577       error = MPI_Testany (nalloc-ibeg, requests+ibeg, &ind, &flag,
00578                            &lstatus);
00579       if (error != MPI_SUCCESS) {
00580          error_in_testany (ibeg, ind, error);
00581          return imin;
00582       }
00583 
00584       /* no request fullfilled ? */
00585  
00586 
00587       if (! flag || ind == MPI_UNDEFINED) return imin;
00588 
00589       /* Request ibeg+ind was finished */
00590  
00591       ind = ibeg + ind;
00592 
00593       /* Control MPI function */
00594 
00595       ASSERT (requests[ind] == MPI_REQUEST_NULL)
00596  
00597       ibeg = release_buffer (ind, len_bytes, &imin, free_memory);
00598       /* if (lengths[imin] == len_bytes && ! free_memory) return imin; */
00599       if (imin >= 0 && lengths[imin] == len_bytes) return imin;
00600    }
00601 
00602    return imin;
00603 }

Here is the call graph for this function:

Here is the caller graph for this function:

void psmile_bsend ( void *  buf,
INTEGER *  lenbuf,
INTEGER *  dtype,
INTEGER *  dest,
INTEGER *  tag,
INTEGER *  comm,
INTEGER *  ierror 
)

Definition at line 114 of file psmile_bsend.c.

References ASSERT, ASSERT2, buffers, dalloc, dblen, dbsend, dbtype, dfree, free_buffers(), i, j, lengths, MALLOC, MAX, max_alloc, max_type, min_type, N_HASH, n_to_free, nalloc, requests, mpp_mod_oa::stderr(), mpp_mod_oa::stdout(), and use_hash.

Referenced by get_neigh_method_data_dble(), get_neigh_method_data_real(), psmile_enddef_action(), psmile_enddef_action_cell(), psmile_find_intersect(), psmile_gauss_get_neighbours(), psmile_get_next_field(), psmile_global_search_cell_dble(), psmile_global_search_cell_real(), psmile_global_search_dble(), psmile_global_search_nnx_dble(), psmile_global_search_nnx_real(), psmile_global_search_real(), psmile_put_field_21d_dble(), psmile_put_field_21d_int(), psmile_put_field_21d_real(), psmile_put_field_3d_dble(), psmile_put_field_3d_int(), psmile_put_field_3d_real(), psmile_put_field_dble(), psmile_put_field_gauss2_dble(), psmile_put_field_gauss2_int(), psmile_put_field_gauss2_real(), psmile_put_field_int(), psmile_put_field_real(), psmile_put_irr_field_dble(), psmile_put_irr_field_int(), psmile_put_irr_field_real(), psmile_return_extra_off_dble(), psmile_return_extra_off_real(), psmile_search_donor_3d_reg_dble(), psmile_search_donor_3d_reg_real(), psmile_search_donor_gauss2_dble(), psmile_search_donor_gauss2_real(), psmile_search_donor_irreg2_dble(), psmile_search_donor_irreg2_real(), psmile_trs_put_dble(), psmile_trs_put_int(), psmile_trs_put_real(), and send_halo().

00123                    :
00124  
00125       void, Intent (In)               :: buf (*)
00126  
00127       Message buffer to be sent
00128  
00129       Integer, Intent (In)            :: lenbuf
00130  
00131       Length of the buffer (of type "dtype") to be sent.
00132  
00133       Integer, Intent (In)            :: dtype
00134  
00135       Fortran Datatype of buffer
00136  
00137       Integer, Intent (In)            :: dest
00138  
00139       Destination of message.
00140  
00141       Integer, Intent (In)            :: tag
00142  
00143       Message tag to be used
00144  
00145       Integer, Intent (In)            :: comm
00146  
00147       Communicator
00148  
00149   !RETURN VALUES:
00150   
00151       Integer, Intent (Out)           :: ierror
00152  
00153       Returns the error code of psmile_bsend:
00154               ierror = 0 : No error
00155               ierror > 0 : Severe error
00156  
00157   !DESCRIPTION:
00158  
00159    Subroutine "psmile_bsend" performs a buffered send.
00160    It allocates a message buffer of the length "lenbuf",
00161       copies buf(1:lenbuf) into this message buffer and
00162       sends  this message to the destination process using
00163       non-blocking sends.
00164 
00165       !!! In MPI-2 koennte man mit general requests arbeiten !!!
00166 
00167   !FILES USED:
00168 
00169          <stdio.h>
00170          <stddef.h>
00171          <stdlib.h>
00172          <string.h>
00173 
00174          "mpi.h"
00175          "PSMILe_f2c.h"
00176 
00177   !REVISION HISTORY:
00178 
00179     Date      Programmer   Description
00180   ----------  ----------   -----------
00181   06.07.03    H. Ritzdorf  created
00182  
00183 //EOP
00184 
00185  ----------------------------------------------------------------------
00186   $Id: psmile_bsend.c 2325 2010-04-21 15:00:07Z valcke $
00187   $Author: valcke $
00188  ---------------------------------------------------------------------- */
00189 
00190 {
00191    long long len_bytes; /* Message length in Bytes */
00192    MPI_Datatype dtypec = MPI_Type_f2c(*dtype);
00193    MPI_Comm commc  = MPI_Comm_f2c(*comm);
00194    
00195    /* Internal control */
00196 
00197    ASSERT (*dtype >= min_type && *dtype <= max_type)
00198 
00199    if (use_hash) {
00200       register int i, j = (*dtype) % N_HASH;
00201 #pragma vdir vector
00202       for (i = dbsend[j]; i < dbsend[j+1]; j++)
00203          if (dbtype[i] == (*dtype)) break;
00204 
00205       ASSERT (i < dbsend[j+1]);
00206       len_bytes = *lenbuf * dblen[i];
00207    }
00208    else {
00209       ASSERT (dbsend [*dtype-min_type] > 0)
00210       len_bytes = *lenbuf * dbsend [*dtype-min_type];
00211    }
00212 
00213 #ifdef VERBOSE_COMM
00214 #define VERBOSE_COMM
00215    fprintf (stdout, "-> %d; tag %d comm %d lenbuf %d %lld\n", 
00216                 *dest, *tag, *comm, *lenbuf, len_bytes);
00217    fflush (stdout);
00218 #else /* VERBOSE_COMM */
00219  
00220 #ifdef DEBUG
00221    if (*lenbuf < 1) {
00222       int rank;
00223       MPI_Comm_rank (commc, &rank);
00224       fprintf (stderr, "(%d)-> psmile_bsend: dest = %d, tag = %d, comm %d, lenbuf %d\n",
00225            rank, *dest, *tag, *comm, *lenbuf);
00226    }
00227 #endif /* DEBUG */
00228 #endif /* VERBOSE_COMM */
00229 
00230 /* =======================================================================
00231    Special case : Can the message be sent by mpi_send ?
00232    ======================================================================= */
00233  
00234 #ifdef PSMILE_SEND_LENBUF
00235  
00236    if (len_bytes <= PSMILE_SEND_LENBUF) {
00237       *ierror = MPI_Send (buf, (int) *lenbuf, dtypec,
00238                            (int) *dest,   (int) *tag,   commc);
00239 
00240       return;
00241    }
00242  
00243 #else  /* PSMILE_SEND_LENBUF */
00244 /* =======================================================================
00245    Special case : Empty message
00246    ======================================================================= */
00247 
00248    if (*lenbuf <= 0) {
00249       MPI_Request lrequest;
00250 
00251       *ierror = MPI_Isend (buf, (int) *lenbuf, dtypec,
00252                        (int) *dest, (int) *tag, commc, &lrequest);
00253       if (*ierror != MPI_SUCCESS) return;
00254  
00255       *ierror = MPI_Request_free (&lrequest);
00256       return;
00257    }
00258 #endif /* PSMILE_SEND_LENBUF */
00259 
00260 /* =======================================================================
00261    Send message using non blocking send
00262 
00263    ======================================================================= */
00264  
00265    /* Look for a free message buffer.
00266       (i) Control message buffers allocated
00267  
00268       buffers (i) = reference address
00269       lengths (i) = size of buffer allocated
00270    */
00271  
00272    {
00273       int imin = -1;
00274       int free_memory = nalloc > n_to_free || dalloc > dfree;
00275 
00276       if (free_memory) {
00277      imin = free_buffers (len_bytes, free_memory);
00278          ASSERT2 (imin < nalloc, imin, nalloc);
00279       }
00280 
00281    /* ==============================================================
00282       Send message
00283  
00284       imin = -1 : Allocate message buffer
00285                   Otherwise, use old message buffer
00286       ============================================================== */
00287  
00288       if (imin == -1) {
00289      if (nalloc == max_alloc) {
00290         register int i;
00291         max_alloc += 32;
00292         if (nalloc == 0) {
00293            requests = (MPI_Request *) MALLOC (max_alloc * sizeof(MPI_Request));
00294            buffers  = (void **)     MALLOC (max_alloc * sizeof(void *));
00295            lengths  = (long long *) MALLOC (max_alloc * sizeof(long long));
00296         }
00297         else {
00298            requests = (MPI_Request *) realloc (requests, max_alloc * sizeof(MPI_Request));
00299            buffers  = (void **)       realloc (buffers, max_alloc * sizeof(void *));
00300            lengths  = (long long *)   realloc (lengths, max_alloc * sizeof(long long));
00301         }
00302 
00303         if (! requests || ! buffers || ! lengths) {
00304            fprintf (stderr, "pmsile_bsend: Cannot allocate %d bytes in order to allocate requests\n",
00305                max_alloc*(sizeof(MPI_Request)+sizeof(void *)+sizeof(long long)));
00306                *ierror = MAX (1307, MPI_ERR_LASTCODE+10);
00307            return;
00308         }
00309 
00310             /* Initialize newly allocated parts of control vectors */
00311 #pragma vdir vector
00312         for (i=nalloc; i < max_alloc; i++) {
00313            requests[i] = MPI_REQUEST_NULL;
00314            buffers[i] = (void *) NULL;
00315            lengths[i] = 0;
00316         }
00317      }
00318 
00319          /* Allocate a new buffer */
00320  
00321 allocate_buffer:
00322      buffers [nalloc] = (void *) MALLOC (len_bytes);
00323      if (buffers [nalloc] == NULL) {
00324             if (! free_memory) {
00325            /* Try to free buffers */
00326                free_memory = 1;
00327            imin = free_buffers (len_bytes, free_memory);
00328                if (imin == -1) goto allocate_buffer;
00329                ASSERT2 (imin < nalloc, imin, nalloc);
00330         }
00331         else {
00332            fprintf (stderr, "pmsile_bsend: Cannot allocate %lld bytes in order to send buffer\n",
00333                len_bytes);
00334                *ierror = MAX (1307, MPI_ERR_LASTCODE+10);
00335            return;
00336         }
00337      }
00338      else {
00339             /* Store data of buffer newly allocated */
00340 
00341             imin = nalloc;
00342             nalloc ++;
00343             dalloc += len_bytes;
00344             lengths [ imin] = len_bytes;
00345      }
00346       }
00347 
00348       /* Internal Control */
00349 
00350       ASSERT2 (imin < nalloc, imin, nalloc);
00351       ASSERT (imin >= 0);
00352       ASSERT (lengths[imin] >= len_bytes);
00353       ASSERT (requests[imin] == MPI_REQUEST_NULL);
00354  
00355       /* Copy and send message */
00356 
00357       memcpy (buffers[imin], buf, (size_t) len_bytes);
00358  
00359       *ierror = MPI_Isend (buffers[imin], *lenbuf, dtypec,
00360                            *dest, *tag, commc, &requests[imin]);
00361 
00362       return;
00363    }
00364 }

Here is the call graph for this function:

Here is the caller graph for this function:

void psmile_bsend_init ( INTEGER *  ftypes,
INTEGER *  flengths,
INTEGER *  number_of_ftypes,
INTEGER *  ierror 
)

Definition at line 395 of file psmile_bsend.c.

References dblen, dbsend, dbtype, FREE, i, j, MALLOC, max_type, min_type, N_HASH, PRISM_Error_Alloc, mpp_mod_oa::stderr(), and use_hash.

Referenced by psmile_init_datatypes().

00402 {
00403    register int i, j, k, ndbsnd;
00404    register int n_ftypes = *number_of_ftypes;
00405    int *num = NULL;
00406 
00407    max_type = min_type = ftypes[0];
00408 #pragma vdir vector
00409    for (i=1; i < n_ftypes; i++) 
00410       max_type = ftypes[i] > max_type ? ftypes [i] : max_type;
00411 
00412 #pragma vdir vector
00413    for (i=1; i < n_ftypes; i++) 
00414       min_type = ftypes[i] < min_type ? ftypes [i] : min_type;
00415 
00416    use_hash = max_type - min_type > 64;
00417    if (! use_hash) {
00418       /* Small datatype range */
00419       ndbsnd = max_type - min_type + 1;
00420       dbsend = (int *) MALLOC (ndbsnd*sizeof(int));
00421       if (! dbsend) {
00422          fprintf (stderr, "Error in psmile_bsend_init: Cannot allocate %d bytes\n",
00423                       ndbsnd*sizeof(int));
00424          *ierror = PRISM_Error_Alloc;
00425          return;
00426       }
00427 
00428 #pragma vdir vector
00429       for (i = 0; i < ndbsnd; i++) dbsend [i] = 0;
00430 
00431 #pragma vdir vector
00432       for (i = 0; i < n_ftypes; i++)
00433          dbsend [ftypes[i]-min_type] = flengths[i];
00434    }
00435    else {
00436       /* Large datatype range; generate simple hash table */
00437       ndbsnd = N_HASH + 1;
00438 
00439       dbsend = (int *) MALLOC ((ndbsnd+2*n_ftypes)*sizeof(int));
00440       if (! dbsend) {
00441          fprintf (stderr, "Error in psmile_bsend_init: Cannot allocate %d bytes\n",
00442                       (ndbsnd+2*n_ftypes)*sizeof(int));
00443          *ierror = PRISM_Error_Alloc;
00444          return;
00445       }
00446 
00447       num = (int *) MALLOC (ndbsnd*sizeof(int));
00448       if (! num) {
00449          fprintf (stderr, "Error in psmile_bsend_init: Cannot allocate %d bytes\n",
00450                       ndbsnd*sizeof(int));
00451          *ierror = PRISM_Error_Alloc;
00452          return;
00453       }
00454 
00455       dbtype = dbsend + ndbsnd;
00456       dblen  = dbtype + n_ftypes;
00457 
00458 #pragma vdir vector
00459       for (j = 0; j < ndbsnd; j++) 
00460          dbsend [j] = 0;
00461 
00462 #pragma vdir vector
00463       for (i = 0; i < n_ftypes; i++) {
00464          j = ftypes[i] % N_HASH;
00465          dbsend[j+1] ++;
00466       }
00467 
00468       /* dbsend[j] = start index of ftypes, where ftypes[i]%N_HASH == j
00469                      end index is dbsend[j+1]-1 */
00470 
00471 #pragma vdir vector
00472       for (j = 1; j < ndbsnd; j++) {
00473          dbsend[j] += dbsend[j-1];
00474       }
00475 
00476 #pragma vdir vector
00477       for (j = 0; j < ndbsnd; j++) {
00478          num[j] = 0;
00479       }
00480 
00481 #pragma vdir vector
00482       for (i = 0; i < n_ftypes; i++) {
00483          j = ftypes[i] % N_HASH;
00484      k = dbsend[j] + num[j]; /* Index in dbtype and dblen */
00485          num[j] ++;
00486 
00487          dbtype[k] = ftypes[i];
00488          dblen [k] = flengths[i];
00489       }
00490 
00491 #ifdef DEBUGXX
00492       fprintf (stderr, "ftypes:");
00493       for (i = 0; i < n_ftypes; i++) fprintf (stderr, "%d ", ftypes[i]);
00494       fprintf (stderr, "\n");
00495 
00496       fprintf (stderr, "flengths:");
00497       for (i = 0; i < n_ftypes; i++) fprintf (stderr, "%d ", flengths[i]);
00498       fprintf (stderr, "\n");
00499 
00500       fprintf (stderr, "dbsend:");
00501       for (i = 0; i < ndbsnd; i++) fprintf (stderr, "%d ", dbsend[i]);
00502       fprintf (stderr, "\n");
00503 
00504       fprintf (stderr, "dbtype:");
00505       for (i = 0; i < n_ftypes; i++) fprintf (stderr, "%d ", dbtype[i]);
00506       fprintf (stderr, "\n");
00507 
00508       fprintf (stderr, "dblen:");
00509       for (i = 0; i < n_ftypes; i++) fprintf (stderr, "%d ", dblen[i]);
00510       fprintf (stderr, "\n");
00511 #endif /* DEBUGXX */
00512 
00513       /* Free temporary space */
00514 
00515       FREE (num);
00516    }
00517 
00518    *ierror = 0;
00519    return;
00520 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int release_buffer ( int  i,
long long  len_bytes,
int *  imin,
int  free_memory 
) [static]

Definition at line 622 of file psmile_bsend.c.

References ASSERT, ASSERT2, buffers, dalloc, FREE, lengths, nalloc, and requests.

Referenced by free_buffers().

00624 {
00625    ASSERT (0 <= i && i < nalloc)
00626    ASSERT (i != *imin)
00627 
00628    if (lengths [i] < len_bytes ||
00629        (*imin >= 0 && lengths[i] >= lengths[*imin])) {
00630  
00631       /* Buffer is too small or too large */
00632  
00633       if (free_memory) {
00634          FREE (buffers[i]);
00635  
00636          dalloc -= lengths [i];
00637          nalloc --;
00638 
00639          buffers [i] = buffers [nalloc];
00640          lengths [i] = lengths [nalloc];
00641  
00642          requests [i] = requests [nalloc];
00643 
00644 #ifdef PRISM_ASSERTION
00645      /* for the Assertions */
00646          requests [nalloc] = MPI_REQUEST_NULL;
00647 #endif
00648       }
00649       else i++;
00650    }
00651    else if (free_memory && *imin >= 0) {
00652       /* ... Buffer "I" is smaller than buffer "*IMIN".
00653              Release buffer "*IMIN" */
00654  
00655       ASSERT2 (*imin < nalloc, *imin, nalloc)
00656       ASSERT (*imin >= 0)
00657       ASSERT (lengths[*imin] >= len_bytes)
00658       ASSERT (requests [*imin] == MPI_REQUEST_NULL)
00659       ASSERT (requests [i]    == MPI_REQUEST_NULL)
00660  
00661       FREE (buffers[*imin]);
00662 
00663       dalloc -= lengths [*imin];
00664       nalloc --;
00665 
00666       /* Replace entry *imin */
00667 
00668       buffers [*imin] = buffers [i];
00669       lengths [*imin] = lengths [i];
00670 
00671       /* Move last entry */
00672  
00673       buffers [i] = buffers [nalloc];
00674       lengths [i] = lengths [nalloc];
00675  
00676       requests [i] = requests [nalloc];
00677 
00678 #ifdef PRISM_ASSERTION
00679       /* for the Assertions */
00680       requests [nalloc] = MPI_REQUEST_NULL;
00681 #endif
00682    }
00683    else {
00684       *imin = i;
00685       i++;
00686    }
00687 
00688    ASSERT2 (*imin < nalloc, *imin, nalloc)
00689 
00690    return i;
00691 }

Here is the caller graph for this function:


Variable Documentation

void** buffers = NULL [static]

Definition at line 72 of file psmile_bsend.c.

Referenced by error_in_testany(), psmile_bsend(), and release_buffer().

double dalloc = 0.0 [static]

Definition at line 69 of file psmile_bsend.c.

Referenced by psmile_bsend(), and release_buffer().

int* dblen = NULL [static]

Definition at line 80 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().

int* dbsend = NULL [static]

Definition at line 78 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().

int* dbtype = NULL [static]

Definition at line 79 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().

long long* lengths = NULL [static]

Definition at line 73 of file psmile_bsend.c.

Referenced by error_in_testany(), free_buffers(), psmile_bsend(), and release_buffer().

int max_alloc = 0 [static]

Definition at line 74 of file psmile_bsend.c.

Referenced by psmile_bsend().

int max_type = -1 [static]

Definition at line 77 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().

int min_type = 0 [static]

Definition at line 77 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().

int nalloc = 0 [static]

Definition at line 74 of file psmile_bsend.c.

Referenced by error_in_testany(), free_buffers(), psmile_bsend(), and release_buffer().

MPI_Request* requests = NULL [static]

Definition at line 71 of file psmile_bsend.c.

Referenced by error_in_testany(), free_buffers(), psmile_bsend(), and release_buffer().

int use_hash = 0 [static]

Definition at line 76 of file psmile_bsend.c.

Referenced by psmile_bsend(), and psmile_bsend_init().


Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1