#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "mpi.h"
#include "PSMILe_f2c.h"
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 ASSERT2 | ( | c, | |||
a, | |||||
b | ) |
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().
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().
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 }
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 }
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 }
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 }
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 }
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().