Changeset 3608ca


Ignore:
Timestamp:
11/06/10 08:08:15 (3 years ago)
Author:
William Gropp <gropp@…>
Branches:
master
Children:
70c0c7
Parents:
1f4f64
Message:

[svn-r7416] Major improvement to RMA performance for long lists of operations, an immediate mode accumulate for single ints, store the MPID_Comm within the window, and added a basic performance instrumentation interface that was extensively used to improve the RMA performance (enabled with --enable-g=instr). With these fixes, MPICH2 can run the one-sided version of the Graph500 benchmark at a respectable if not great rate

Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • configure.in

    rcd9484 r3608ca  
    136136fi 
    137137AC_SUBST(MPICH2_RELEASE_DATE) 
    138  
    139138# Produce a numeric version assuming the following format: 
    140139# Version: [MAJ].[MIN].[REV][EXT][EXT_NUMBER] 
     
    331330                   MPICH2LIB_FFLAGS, and MPICH2LIB_FCFLAGS. 
    332331        debug    - Synonym for dbg 
     332        instr    - Enable instrumentation 
    333333        log      - Enable debug event logging 
    334334        mem      - Memory usage tracing 
     
    741741            MPI_DEFAULT_FCOPTS="-$option" 
    742742        else 
     743            IFS="$save_IFS" 
    743744            AC_MSG_WARN([Unknown value $option for --enable-fast]) 
     745            IFS="," 
    744746        fi 
    745747        ;; 
     
    752754        ;; 
    753755        *) 
     756        IFS="$save_IFS" 
    754757        AC_MSG_WARN([Unknown value $option for --enable-fast]) 
     758        IFS="," 
    755759        ;; 
    756760    esac 
     
    12611265        AC_DEFINE(MPICH_DEBUG_HANDLES,1,[Define to enable handle checking]) 
    12621266        ;; 
     1267        instr) 
     1268        perform_instr=yes 
     1269        ;; 
    12631270        meminit) 
    12641271        perform_meminit=yes 
     
    12851292        enable_append_g=yes 
    12861293        perform_meminit=yes 
     1294        perform_instr=yes 
    12871295        perform_dbgmutex=yes 
    12881296        perform_mutexnesting=yes 
     
    12901298        ;; 
    12911299        *) 
    1292         AC_MSG_WARN([Unknown value $enable_g for enable-g]) 
     1300        IFS=$save_IFS 
     1301        AC_MSG_WARN([Unknown value $option for enable-g]) 
     1302        IFS="," 
    12931303        ;; 
    12941304    esac 
     
    13121322fi 
    13131323if test "$perform_handlealloc" = yes ; then 
    1314    AC_DEFINE(MPICH_DEBUG_HANDLEALLOC,1,[Define to enable checking of handles still allocated at MPI_Finalize]) 
     1324    AC_DEFINE(MPICH_DEBUG_HANDLEALLOC,1,[Define to enable checking of handles still allocated at MPI_Finalize]) 
     1325fi 
     1326if test "$perform_instr" = yes ; then 
     1327    AC_DEFINE(USE_MPIU_INSTR,1,[Define this to enable internal instrumentation] ) 
    13151328fi 
    13161329 
  • src/include/mpiimpl.h

    r6f304b r3608ca  
    14981498    MPID_Group *start_group_ptr; /* group passed in MPI_Win_start */ 
    14991499    int start_assert;            /* assert passed to MPI_Win_start */ 
    1500     MPI_Comm    comm;         /* communicator of window (dup) */ 
     1500    MPID_Comm *comm_ptr;         /* Pointer to comm of window (dup) */ 
     1501    int         myrank;          /* Rank of this process in comm (used to  
     1502                                    detect operations on self) */ 
    15011503#ifdef USE_THREADED_WINDOW_CODE 
    15021504    /* These were causing compilation errors.  We need to figure out how to 
     
    19601962#include "mpierror.h" 
    19611963#include "mpierrs.h" 
     1964 
     1965/* Definitions for instrumentation (currently used within RMA code) */ 
     1966#include "mpiinstr.h" 
    19621967 
    19631968/* FIXME: This routine is only used within mpi/src/err/errutil.c and  
  • src/mpi/rma/accumulate.c

    r9df3f7 r3608ca  
    127127            } 
    128128 
    129             MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     129            comm_ptr = win_ptr->comm_ptr; 
    130130            MPIR_ERRTEST_SEND_RANK(comm_ptr, target_rank, mpi_errno); 
    131131 
  • src/mpi/rma/get.c

    r9df3f7 r3608ca  
    123123            } 
    124124 
    125             MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     125            comm_ptr = win_ptr->comm_ptr; 
    126126            MPIR_ERRTEST_SEND_RANK(comm_ptr, target_rank, mpi_errno); 
    127127             
  • src/mpi/rma/put.c

    r9df3f7 r3608ca  
    123123            } 
    124124 
    125             MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     125            comm_ptr = win_ptr->comm_ptr; 
    126126            MPIR_ERRTEST_SEND_RANK(comm_ptr, target_rank, mpi_errno); 
    127127             
  • src/mpi/rma/win_get_group.c

    r8b7a87 r3608ca  
    9999 
    100100    /* ... body of routine ...  */ 
    101     MPID_Comm_get_ptr( win_ptr->comm, win_comm_ptr ); 
     101    win_comm_ptr = win_ptr->comm_ptr; 
    102102 
    103103    mpi_errno = MPIR_Comm_group_impl(win_comm_ptr, &group_ptr); 
  • src/mpi/rma/win_lock.c

    r9df3f7 r3608ca  
    118118                                                  "**locktype", 0 ); 
    119119 
    120             MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
     120            comm_ptr = win_ptr->comm_ptr; 
    121121            MPIR_ERRTEST_SEND_RANK(comm_ptr, rank, mpi_errno); 
    122122 
  • src/mpi/rma/win_unlock.c

    r9df3f7 r3608ca  
    8888            if (mpi_errno) goto fn_fail; 
    8989 
    90             MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
     90            comm_ptr = win_ptr->comm_ptr; 
    9191            MPIR_ERRTEST_SEND_RANK(comm_ptr, rank, mpi_errno); 
    9292 
  • src/mpid/ch3/include/mpidimpl.h

    rb46eb9 r3608ca  
    10951095int MPIDI_CH3_RMAFnsInit( MPIDI_RMAFns * ); 
    10961096 
     1097/* FIXME: These are specific to the RMA code and should be in the RMA  
     1098   header file. */ 
    10971099#define MPIDI_RMA_PUT 23 
    10981100#define MPIDI_RMA_GET 24 
    10991101#define MPIDI_RMA_ACCUMULATE 25 
    11001102#define MPIDI_RMA_LOCK 26 
     1103 
     1104/* Special case RMA operations */ 
     1105#define MPIDI_RMA_ACC_CONTIG 27 
     1106 
    11011107#define MPIDI_RMA_DATATYPE_BASIC 50 
    11021108#define MPIDI_RMA_DATATYPE_DERIVED 51 
     
    17051711int MPIDI_CH3_PktHandler_Accumulate( MPIDI_VC_t *, MPIDI_CH3_Pkt_t *,  
    17061712                                     MPIDI_msg_sz_t *, MPID_Request ** ); 
     1713int MPIDI_CH3_PktHandler_Accumulate_Immed( MPIDI_VC_t *, MPIDI_CH3_Pkt_t *,  
     1714                                     MPIDI_msg_sz_t *, MPID_Request ** ); 
    17071715int MPIDI_CH3_PktHandler_Get( MPIDI_VC_t *, MPIDI_CH3_Pkt_t *,  
    17081716                              MPIDI_msg_sz_t *, MPID_Request ** ); 
  • src/mpid/ch3/include/mpidpkt.h

    r300b1e r3608ca  
    1111#define USE_EAGER_SHORT 
    1212#define MPIDI_EAGER_SHORT_INTS 4 
     13/* FIXME: This appears to assume that sizeof(int) == 4 (or at least >= 4) */ 
    1314#define MPIDI_EAGER_SHORT_SIZE 16 
     15 
     16/* This is the number of ints that can be carried within an RMA packet */ 
     17#define MPIDI_RMA_IMMED_INTS 1 
    1418 
    1519/* 
     
    4549    MPIDI_CH3_PKT_LOCK_ACCUM_UNLOCK, /* optimization for single accumulates */ 
    4650                                     /* RMA Packets end here */ 
     51    MPIDI_CH3_PKT_ACCUM_IMMED,     /* optimization for short accumulate */ 
     52    /* FIXME: Add PUT, GET_IMMED packet types */ 
    4753    MPIDI_CH3_PKT_FLOW_CNTL_UPDATE,  /* FIXME: Unused */ 
    4854    MPIDI_CH3_PKT_CLOSE, 
     
    193199} 
    194200MPIDI_CH3_Pkt_accum_t; 
     201 
     202typedef struct MPIDI_CH3_Pkt_accum_immed 
     203{ 
     204    MPIDI_CH3_Pkt_type_t type; 
     205    void *addr; 
     206    int count; 
     207    /* FIXME: Compress datatype/op into a single word (immedate mode) */ 
     208    MPI_Datatype datatype; 
     209    MPI_Op op; 
     210    /* FIXME: do we need these (use a regular accum packet if we do?) */ 
     211    MPI_Win target_win_handle; /* Used in the last RMA operation in each 
     212                               * epoch for decrementing rma op counter in 
     213                               * active target rma and for unlocking window  
     214                               * in passive target rma. Otherwise set to NULL*/ 
     215    MPI_Win source_win_handle; /* Used in the last RMA operation in an 
     216                               * epoch in the case of passive target rma 
     217                               * with shared locks. Otherwise set to NULL*/ 
     218    int data[MPIDI_RMA_IMMED_INTS]; 
     219} 
     220MPIDI_CH3_Pkt_accum_immed_t; 
    195221 
    196222typedef struct MPIDI_CH3_Pkt_lock 
     
    277303    MPIDI_CH3_Pkt_get_resp_t get_resp; 
    278304    MPIDI_CH3_Pkt_accum_t accum; 
     305    MPIDI_CH3_Pkt_accum_immed_t accum_immed; 
    279306    MPIDI_CH3_Pkt_lock_t lock; 
    280307    MPIDI_CH3_Pkt_lock_granted_t lock_granted; 
  • src/mpid/ch3/include/mpidpre.h

    rcb4ca9 r3608ca  
    171171    MPI_Win *all_win_handles;    /* array of handles to the window objects\ 
    172172                                          of all processes */            \ 
    173     struct MPIDI_RMA_ops *rma_ops_list; /* list of outstanding RMA requests */  \ 
     173    struct MPIDI_RMA_ops *rma_ops_list_head; /* list of outstanding \ 
     174                                                RMA requests */ \ 
     175    struct MPIDI_RMA_ops *rma_ops_list_tail; \ 
    174176    volatile int lock_granted;  /* flag to indicate whether lock has     \ 
    175177                                   been granted to this process (as source) for         \ 
  • src/mpid/ch3/include/mpidrma.h

    rac4f4c r3608ca  
    2929typedef struct MPIDI_RMA_ops { 
    3030    struct MPIDI_RMA_ops *next;  /* pointer to next element in list */ 
     31    /* FIXME: It would be better to setup the packet that will be sent, at  
     32       least in most cases (if, as a result of the sync/ops/sync sequence, 
     33       a different packet type is needed, it can be extracted from the  
     34       information otherwise stored). */ 
     35    /* FIXME: Use enum for RMA op type? */ 
    3136    int type;  /* MPIDI_RMA_PUT, MPID_REQUEST_GET, 
    3237                  MPIDI_RMA_ACCUMULATE, MPIDI_RMA_LOCK */ 
     
    4045    MPI_Op op;  /* for accumulate */ 
    4146    int lock_type;  /* for win_lock */ 
     47    /* Used to complete operations */ 
     48    struct MPID_Request *request; 
     49    MPIDI_RMA_dtype_info dtype_info; 
     50    void *dataloop; 
    4251} MPIDI_RMA_ops; 
    4352 
     
    6069    struct MPIDI_PT_single_op *pt_single_op;  /* to store info for lock-put-unlock optimization */ 
    6170} MPIDI_Win_lock_queue; 
    62  
    6371#endif 
  • src/mpid/ch3/src/ch3u_handle_recv_pkt.c

    rdb4c14 r3608ca  
    586586    pktArray[MPIDI_CH3_PKT_LOCK_GET_UNLOCK] =  
    587587        MPIDI_CH3_PktHandler_LockGetUnlock; 
     588    pktArray[MPIDI_CH3_PKT_ACCUM_IMMED] =  
     589        MPIDI_CH3_PktHandler_Accumulate_Immed; 
    588590    /* End of default RMA operations */ 
    589591 
  • src/mpid/ch3/src/ch3u_handle_recv_req.c

    rdb4c14 r3608ca  
    631631    { 
    632632        /* get the function by indexing into the op table */ 
    633         uop = MPIR_Op_table[(rreq->dev.op)%16 - 1]; 
     633        uop = MPIR_Op_table[((rreq->dev.op)&0xf) - 1]; 
    634634    } 
    635635    else 
     
    957957    { 
    958958        /* get the function by indexing into the op table */ 
    959         uop = MPIR_Op_table[(single_op->op)%16 - 1]; 
     959        uop = MPIR_Op_table[((single_op->op)&0xf) - 1]; 
    960960    } 
    961961    else 
  • src/mpid/ch3/src/ch3u_rma_ops.c

    rdb4c14 r3608ca  
    77#include "mpidi_ch3_impl.h" 
    88#include "mpidrma.h" 
     9 
     10static int enableShortACC=1; 
     11 
     12MPIU_THREADSAFE_INIT_DECL(initRMAoptions); 
     13#ifdef USE_MPIU_INSTR 
     14MPIU_INSTR_DURATION_DECL(wincreate_allgather); 
     15MPIU_INSTR_DURATION_DECL(winfree_rs); 
     16MPIU_INSTR_DURATION_DECL(winfree_complete); 
     17MPIU_INSTR_DURATION_DECL(rmaqueue_alloc); 
     18extern void MPIDI_CH3_RMA_InitInstr(void); 
     19#endif 
     20extern void MPIDI_CH3_RMA_SetAccImmed( int ); 
    921 
    1022#define MPIDI_PASSIVE_TARGET_DONE_TAG  348297 
     
    1931                     MPID_Comm *comm_ptr, MPID_Win **win_ptr ) 
    2032{ 
    21     int mpi_errno=MPI_SUCCESS, i, comm_size, rank; 
     33    int mpi_errno=MPI_SUCCESS, i, k, comm_size, rank; 
    2234    MPI_Aint *tmp_buf; 
    2335    MPID_Comm *win_comm_ptr; 
     
    3042    /* FIXME: There should be no unreferenced args */ 
    3143    MPIU_UNREFERENCED_ARG(info); 
     44 
     45    if(initRMAoptions) { 
     46        int rc; 
     47        MPIU_THREADSAFE_INIT_BLOCK_BEGIN(initRMAoptions); 
     48        /* Default is to enable the use of the immediate accumulate feature */ 
     49        if (!MPL_env2bool( "MPICH_RMA_ACC_IMMED", &rc )) 
     50            rc = 1; 
     51        MPIDI_CH3_RMA_SetAccImmed(rc); 
     52#ifdef USE_MPIU_INSTR 
     53    /* Define all instrumentation handle used in the CH3 RMA here*/ 
     54        MPIU_INSTR_DURATION_INIT(wincreate_allgather,0,"WIN_CREATE:Allgather"); 
     55        MPIU_INSTR_DURATION_INIT(winfree_rs,0,"WIN_FREE:ReduceScatterBlock"); 
     56        MPIU_INSTR_DURATION_INIT(winfree_complete,0,"WIN_FREE:Complete"); 
     57        MPIU_INSTR_DURATION_INIT(rmaqueue_alloc,0,"Allocate RMA Queue element"); 
     58        MPIDI_CH3_RMA_InitInstr(); 
     59 
     60#endif     
     61        MPIU_THREADSAFE_INIT_CLEAR(initRMAoptions); 
     62        MPIU_THREADSAFE_INIT_BLOCK_END(initRMAoptions); 
     63    } 
    3264 
    3365    comm_size = comm_ptr->local_size; 
     
    4779    (*win_ptr)->start_assert = 0;  
    4880    (*win_ptr)->attributes = NULL; 
    49     (*win_ptr)->rma_ops_list = NULL; 
     81    (*win_ptr)->rma_ops_list_head = NULL; 
     82    (*win_ptr)->rma_ops_list_tail = NULL; 
    5083    (*win_ptr)->lock_granted = 0; 
    5184    (*win_ptr)->current_lock_type = MPID_LOCK_NONE; 
     
    5790    mpi_errno = MPIR_Comm_dup_impl(comm_ptr, &win_comm_ptr); 
    5891    if (mpi_errno) MPIU_ERR_POP(mpi_errno); 
    59     (*win_ptr)->comm = win_comm_ptr->handle; 
    60      
     92    (*win_ptr)->comm_ptr   = win_comm_ptr; 
     93    (*win_ptr)->myrank = rank; 
     94 
     95    MPIU_INSTR_DURATION_START(wincreate_allgather); 
    6196    /* allocate memory for the base addresses, disp_units, and 
    6297       completion counters of all processes */  
     
    83118     
    84119    /* FIXME: This needs to be fixed for heterogeneous systems */ 
    85     tmp_buf[3*rank] = MPIU_PtrToAint(base); 
     120    tmp_buf[3*rank]   = MPIU_PtrToAint(base); 
    86121    tmp_buf[3*rank+1] = (MPI_Aint) disp_unit; 
    87122    tmp_buf[3*rank+2] = (MPI_Aint) (*win_ptr)->handle; 
     
    90125                                    tmp_buf, 3 * sizeof(MPI_Aint), MPI_BYTE, 
    91126                                    comm_ptr); 
     127    MPIU_INSTR_DURATION_END(wincreate_allgather); 
    92128    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
    93      
     129 
     130    k = 0; 
    94131    for (i=0; i<comm_size; i++) 
    95132    { 
    96         (*win_ptr)->base_addrs[i] = MPIU_AintToPtr(tmp_buf[3*i]); 
    97         (*win_ptr)->disp_units[i] = (int) tmp_buf[3*i+1]; 
    98         (*win_ptr)->all_win_handles[i] = (MPI_Win) tmp_buf[3*i+2]; 
     133        (*win_ptr)->base_addrs[i] = MPIU_AintToPtr(tmp_buf[k++]); 
     134        (*win_ptr)->disp_units[i] = (int) tmp_buf[k++]; 
     135        (*win_ptr)->all_win_handles[i] = (MPI_Win) tmp_buf[k++]; 
    99136    } 
    100137         
     
    127164    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_FREE); 
    128165         
    129     MPID_Comm_get_ptr( (*win_ptr)->comm, comm_ptr ); 
    130  
     166    comm_ptr = (*win_ptr)->comm_ptr; 
     167    MPIU_INSTR_DURATION_START(winfree_rs); 
    131168    mpi_errno = MPIR_Reduce_scatter_block_impl((*win_ptr)->pt_rma_puts_accs,  
    132169                                               &total_pt_rma_puts_accs, 1,  
    133170                                               MPI_INT, MPI_SUM, comm_ptr); 
    134171    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
     172    MPIU_INSTR_DURATION_END(winfree_rs); 
    135173 
    136174    if (total_pt_rma_puts_accs != (*win_ptr)->my_pt_rma_puts_accs) 
     
    139177             
    140178        /* poke the progress engine until the two are equal */ 
     179        MPIU_INSTR_DURATION_START(winfree_complete); 
    141180        MPID_Progress_start(&progress_state); 
    142181        while (total_pt_rma_puts_accs != (*win_ptr)->my_pt_rma_puts_accs) 
     
    152191        } 
    153192        MPID_Progress_end(&progress_state); 
     193        MPIU_INSTR_DURATION_END(winfree_complete); 
    154194    } 
    155195 
     
    188228    int mpi_errno = MPI_SUCCESS; 
    189229    int dt_contig, rank, predefined; 
    190     MPIDI_RMA_ops *curr_ptr, *prev_ptr, *new_ptr; 
     230    MPIDI_RMA_ops *new_ptr; 
    191231    MPID_Datatype *dtp; 
    192232    MPI_Aint dt_true_lb; 
    193233    MPIDI_msg_sz_t data_sz; 
    194     MPID_Comm *win_comm_ptr; 
    195234    MPIU_CHKPMEM_DECL(1); 
    196235    MPIDI_STATE_DECL(MPID_STATE_MPIDI_PUT); 
     
    206245    } 
    207246 
    208     /* FIXME: It makes sense to save the rank (and size) of the 
    209        communicator in the window structure to speed up these operations, 
    210        or to save a pointer to the communicator structure, rather than 
    211        just the handle  
    212     */ 
    213     MPID_Comm_get_ptr(win_ptr->comm, win_comm_ptr); 
    214     rank = MPIR_Comm_rank(win_comm_ptr); 
     247    rank = win_ptr->myrank; 
    215248     
    216249    /* If the put is a local operation, do it here */ 
     
    224257    { 
    225258        /* queue it up */ 
    226         curr_ptr = win_ptr->rma_ops_list; 
    227         prev_ptr = curr_ptr; 
    228         while (curr_ptr != NULL) 
    229         { 
    230             prev_ptr = curr_ptr; 
    231             curr_ptr = curr_ptr->next; 
    232         } 
    233  
    234         /* FIXME: Where does this memory get freed? */ 
     259        /* FIXME: For short operations, should we use a (per-thread) pool? */ 
     260        MPIU_INSTR_DURATION_START(rmaqueue_alloc); 
    235261        MPIU_CHKPMEM_MALLOC(new_ptr, MPIDI_RMA_ops *, sizeof(MPIDI_RMA_ops),  
    236262                            mpi_errno, "RMA operation entry"); 
    237         if (prev_ptr != NULL) 
    238             prev_ptr->next = new_ptr; 
    239         else  
    240             win_ptr->rma_ops_list = new_ptr; 
    241          
     263        MPIU_INSTR_DURATION_END(rmaqueue_alloc); 
     264        if (win_ptr->rma_ops_list_tail)  
     265            win_ptr->rma_ops_list_tail->next = new_ptr; 
     266        else 
     267            win_ptr->rma_ops_list_head = new_ptr; 
     268        win_ptr->rma_ops_list_tail = new_ptr; 
     269 
     270        /* FIXME: For contig and very short operations, use a streamlined op */ 
    242271        new_ptr->next = NULL;   
    243272        new_ptr->type = MPIDI_RMA_PUT; 
     
    291320    int dt_contig, rank, predefined; 
    292321    MPI_Aint dt_true_lb; 
    293     MPIDI_RMA_ops *curr_ptr, *prev_ptr, *new_ptr; 
     322    MPIDI_RMA_ops *new_ptr; 
    294323    MPID_Datatype *dtp; 
    295     MPID_Comm *win_comm_ptr; 
    296324    MPIU_CHKPMEM_DECL(1); 
    297325    MPIDI_STATE_DECL(MPID_STATE_MPIDI_GET); 
     
    307335    } 
    308336 
    309     /* FIXME: It makes sense to save the rank (and size) of the 
    310        communicator in the window structure to speed up these operations */ 
    311     MPID_Comm_get_ptr(win_ptr->comm, win_comm_ptr); 
    312     rank = MPIR_Comm_rank(win_comm_ptr); 
     337    rank = win_ptr->myrank; 
    313338     
    314339    /* If the get is a local operation, do it here */ 
     
    324349    { 
    325350        /* queue it up */ 
    326         curr_ptr = win_ptr->rma_ops_list; 
    327         prev_ptr = curr_ptr; 
    328         while (curr_ptr != NULL) 
    329         { 
    330             prev_ptr = curr_ptr; 
    331             curr_ptr = curr_ptr->next; 
    332         } 
    333          
     351        MPIU_INSTR_DURATION_START(rmaqueue_alloc); 
    334352        MPIU_CHKPMEM_MALLOC(new_ptr, MPIDI_RMA_ops *, sizeof(MPIDI_RMA_ops),  
    335353                            mpi_errno, "RMA operation entry"); 
    336         if (prev_ptr != NULL) 
    337         { 
    338             prev_ptr->next = new_ptr; 
    339         } 
     354        MPIU_INSTR_DURATION_END(rmaqueue_alloc); 
     355        if (win_ptr->rma_ops_list_tail)  
     356            win_ptr->rma_ops_list_tail->next = new_ptr; 
    340357        else 
    341         { 
    342             win_ptr->rma_ops_list = new_ptr; 
    343         } 
     358            win_ptr->rma_ops_list_head = new_ptr; 
     359        win_ptr->rma_ops_list_tail = new_ptr; 
    344360             
     361        /* FIXME: For contig and very short operations, use a streamlined op */ 
    345362        new_ptr->next = NULL;   
    346363        new_ptr->type = MPIDI_RMA_GET; 
     
    395412    int dt_contig, rank, origin_predefined, target_predefined; 
    396413    MPI_Aint dt_true_lb; 
    397     MPIDI_RMA_ops *curr_ptr, *prev_ptr, *new_ptr; 
     414    MPIDI_RMA_ops *new_ptr; 
    398415    MPID_Datatype *dtp; 
    399     MPID_Comm *win_comm_ptr; 
    400416    MPIU_CHKLMEM_DECL(2); 
    401417    MPIU_CHKPMEM_DECL(1); 
     
    411427        goto fn_exit; 
    412428    } 
    413      
    414     /* FIXME: It makes sense to save the rank (and size) of the 
    415        communicator in the window structure to speed up these operations, 
    416        or to save a pointer to the communicator structure, rather than 
    417        just the handle  
    418     */ 
    419     MPID_Comm_get_ptr(win_ptr->comm, win_comm_ptr); 
    420     rank = MPIR_Comm_rank(win_comm_ptr); 
     429 
     430    rank = win_ptr->myrank; 
    421431     
    422432    MPIDI_CH3I_DATATYPE_IS_PREDEFINED(origin_datatype, origin_predefined); 
    423433    MPIDI_CH3I_DATATYPE_IS_PREDEFINED(target_datatype, target_predefined); 
    424434 
     435    /* Do =! rank first (most likely branch?) */ 
    425436    if (target_rank == rank) 
    426437    { 
     
    441452         
    442453        /* get the function by indexing into the op table */ 
    443         uop = MPIR_Op_table[(op)%16 - 1]; 
     454        uop = MPIR_Op_table[((op)&0xf) - 1]; 
    444455         
    445456        if (origin_predefined && target_predefined) 
     
    525536    { 
    526537        /* queue it up */ 
    527         curr_ptr = win_ptr->rma_ops_list; 
    528         prev_ptr = curr_ptr; 
    529         while (curr_ptr != NULL) 
    530         { 
    531             prev_ptr = curr_ptr; 
    532             curr_ptr = curr_ptr->next; 
    533         } 
    534          
     538        MPIU_INSTR_DURATION_START(rmaqueue_alloc); 
    535539        MPIU_CHKPMEM_MALLOC(new_ptr, MPIDI_RMA_ops *, sizeof(MPIDI_RMA_ops),  
    536540                            mpi_errno, "RMA operation entry"); 
    537         if (prev_ptr != NULL) 
    538         { 
    539             prev_ptr->next = new_ptr; 
    540         } 
     541        MPIU_INSTR_DURATION_END(rmaqueue_alloc); 
     542        if (win_ptr->rma_ops_list_tail)  
     543            win_ptr->rma_ops_list_tail->next = new_ptr; 
    541544        else 
    542         { 
    543             win_ptr->rma_ops_list = new_ptr; 
    544         } 
    545          
     545            win_ptr->rma_ops_list_head = new_ptr; 
     546        win_ptr->rma_ops_list_tail = new_ptr; 
     547 
     548        /* If predefined and contiguous, use a simplified element */ 
     549        if (origin_predefined && target_predefined && enableShortACC) { 
     550            new_ptr->next = NULL; 
     551            new_ptr->type = MPIDI_RMA_ACC_CONTIG; 
     552            /* Only the information needed for the contig/predefined acc */ 
     553            new_ptr->origin_addr = origin_addr; 
     554            new_ptr->origin_count = origin_count; 
     555            new_ptr->origin_datatype = origin_datatype; 
     556            new_ptr->target_rank = target_rank; 
     557            new_ptr->target_disp = target_disp; 
     558            new_ptr->target_count = target_count; 
     559            new_ptr->target_datatype = target_datatype; 
     560            new_ptr->op = op; 
     561            goto fn_exit; 
     562        } 
     563 
    546564        new_ptr->next = NULL;   
    547565        new_ptr->type = MPIDI_RMA_ACCUMULATE; 
  • src/mpid/ch3/src/ch3u_rma_sync.c

    rdb4c14 r3608ca  
    77#include "mpidimpl.h" 
    88#include "mpidrma.h" 
     9 
     10static int EnableImmedAcc = 1; 
     11void MPIDI_CH3_RMA_SetAccImmed( int flag ) 
     12{ 
     13    EnableImmedAcc = flag; 
     14} 
     15 
     16#ifdef USE_MPIU_INSTR 
     17MPIU_INSTR_DURATION_DECL(winfence_clearlock); 
     18MPIU_INSTR_DURATION_DECL(winfence_rs); 
     19MPIU_INSTR_DURATION_DECL(winfence_issue); 
     20MPIU_INSTR_DURATION_DECL(winfence_complete); 
     21MPIU_INSTR_DURATION_DECL(winfence_wait); 
     22MPIU_INSTR_DURATION_DECL(winfence_block); 
     23MPIU_INSTR_DURATION_DECL(winpost_clearlock); 
     24MPIU_INSTR_DURATION_DECL(winpost_sendsync); 
     25MPIU_INSTR_DURATION_DECL(winstart_clearlock); 
     26MPIU_INSTR_DURATION_DECL(wincomplete_issue); 
     27MPIU_INSTR_DURATION_DECL(wincomplete_complete); 
     28MPIU_INSTR_DURATION_DECL(wincomplete_recvsync); 
     29MPIU_INSTR_DURATION_DECL(winwait_wait); 
     30MPIU_INSTR_DURATION_DECL(winlock_getlocallock); 
     31MPIU_INSTR_DURATION_DECL(winunlock_getlock); 
     32MPIU_INSTR_DURATION_DECL(winunlock_issue); 
     33MPIU_INSTR_DURATION_DECL(winunlock_complete); 
     34MPIU_INSTR_DURATION_DECL(lockqueue_alloc); 
     35MPIU_INSTR_DURATION_DECL(rmapkt_acc); 
     36MPIU_INSTR_DURATION_DECL(rmapkt_acc_predef); 
     37MPIU_INSTR_DURATION_DECL(rmapkt_acc_immed); 
     38MPIU_INSTR_DURATION_EXTERN_DECL(rmaqueue_alloc); 
     39void MPIDI_CH3_RMA_InitInstr(void); 
     40 
     41void MPIDI_CH3_RMA_InitInstr(void) 
     42{ 
     43    MPIU_INSTR_DURATION_INIT(lockqueue_alloc,0,"Allocate Lock Queue element"); 
     44    MPIU_INSTR_DURATION_INIT(winfence_clearlock,1,"WIN_FENCE:Clear prior lock"); 
     45    MPIU_INSTR_DURATION_INIT(winfence_rs,0,"WIN_FENCE:ReduceScatterBlock"); 
     46    MPIU_INSTR_DURATION_INIT(winfence_issue,2,"WIN_FENCE:Issue RMA ops"); 
     47    MPIU_INSTR_DURATION_INIT(winfence_complete,1,"WIN_FENCE:Complete RMA ops"); 
     48    MPIU_INSTR_DURATION_INIT(winfence_wait,1,"WIN_FENCE:Wait for ops from other processes"); 
     49    MPIU_INSTR_DURATION_INIT(winfence_block,0,"WIN_FENCE:Wait for any progress"); 
     50    MPIU_INSTR_DURATION_INIT(winpost_clearlock,1,"WIN_POST:Clear prior lock"); 
     51    MPIU_INSTR_DURATION_INIT(winpost_sendsync,1,"WIN_POST:Senc sync messages"); 
     52    MPIU_INSTR_DURATION_INIT(winstart_clearlock,1,"WIN_START:Clear prior lock"); 
     53    MPIU_INSTR_DURATION_INIT(wincomplete_recvsync,1,"WIN_COMPLETE:Recv sync messages"); 
     54    MPIU_INSTR_DURATION_INIT(wincomplete_issue,2,"WIN_COMPLETE:Issue RMA ops"); 
     55    MPIU_INSTR_DURATION_INIT(wincomplete_complete,1,"WIN_COMPLETE:Complete RMA ops"); 
     56    MPIU_INSTR_DURATION_INIT(winwait_wait,1,"WIN_WAIT:Wait for ops from other processes"); 
     57    MPIU_INSTR_DURATION_INIT(winlock_getlocallock,0,"WIN_LOCK:Get local lock"); 
     58    MPIU_INSTR_DURATION_INIT(winunlock_issue,2,"WIN_UNLOCK:Issue RMA ops"); 
     59    MPIU_INSTR_DURATION_INIT(winunlock_complete,1,"WIN_UNLOCK:Complete RMA ops"); 
     60    MPIU_INSTR_DURATION_INIT(winunlock_getlock,0,"WIN_UNLOCK:Acquire lock"); 
     61    MPIU_INSTR_DURATION_INIT(rmapkt_acc,0,"RMA:PKTHANDLER for Accumulate"); 
     62    MPIU_INSTR_DURATION_INIT(rmapkt_acc_predef,0,"RMA:PKTHANDLER for Accumulate: predef dtype"); 
     63    MPIU_INSTR_DURATION_INIT(rmapkt_acc_immed,0,"RMA:PKTHANDLER for Accum immed"); 
     64} 
     65#endif 
    966 
    1067/* 
     
    3289                                   MPIDI_RMA_dtype_info * dtype_info,  
    3390                                   void ** dataloop, MPID_Request ** request);  
     91static int MPIDI_CH3I_Send_contig_acc_msg(MPIDI_RMA_ops * rma_op,  
     92                                          MPID_Win * win_ptr,  
     93                                          MPI_Win source_win_handle,  
     94                                          MPI_Win target_win_handle,  
     95                                          MPID_Request ** request); 
    3496static int MPIDI_CH3I_Do_passive_target_rma(MPID_Win *win_ptr,  
    3597                                            int *wait_for_rma_done_pkt); 
     
    49111{ 
    50112    int mpi_errno = MPI_SUCCESS; 
    51     int comm_size, done; 
     113    int comm_size; 
    52114    int *rma_target_proc, *nops_to_proc, i, total_op_count, *curr_ops_cnt; 
    53     MPIDI_RMA_ops *curr_ptr, *next_ptr; 
     115    MPIDI_RMA_ops *curr_ptr; 
    54116    MPID_Comm *comm_ptr; 
    55     MPID_Request **requests=NULL; /* array of requests */ 
    56117    MPI_Win source_win_handle, target_win_handle; 
    57     MPIDI_RMA_dtype_info *dtype_infos=NULL; 
    58     void **dataloops=NULL;    /* to store dataloops for each datatype */ 
    59118    MPID_Progress_state progress_state; 
    60     MPIU_CHKLMEM_DECL(6); 
     119    MPIU_CHKLMEM_DECL(3); 
    61120    MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_FENCE); 
    62121 
     
    72131    if (win_ptr->current_lock_type != MPID_LOCK_NONE) 
    73132    { 
     133        MPIU_INSTR_DURATION_START(winfence_clearlock); 
    74134        MPID_Progress_start(&progress_state); 
    75135        while (win_ptr->current_lock_type != MPID_LOCK_NONE) 
     
    83143            } 
    84144            /* --END ERROR HANDLING-- */ 
    85  
     145            MPIU_INSTR_DURATION_INCR(winfence_clearlock,0,1); 
    86146        } 
    87147        MPID_Progress_end(&progress_state); 
     148        MPIU_INSTR_DURATION_END(winfence_clearlock); 
    88149    } 
    89150 
     
    109170    else 
    110171    { 
     172        MPIDI_RMA_ops **prevNextPtr, *tmpptr; 
     173        MPIU_INSTR_DURATION_START(winfence_rs); 
    111174        /* This is the second or later fence. Do all the preceding RMA ops. */ 
    112          
    113         MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
    114          
     175        comm_ptr = win_ptr->comm_ptr; 
    115176        /* First inform every process whether it is a target of RMA 
    116177           ops from this process */ 
     
    132193           ops from this process */ 
    133194        total_op_count = 0; 
    134         curr_ptr = win_ptr->rma_ops_list; 
     195        curr_ptr = win_ptr->rma_ops_list_head; 
    135196        while (curr_ptr != NULL) 
    136197        { 
     
    144205                            mpi_errno, "curr_ops_cnt"); 
    145206        for (i=0; i<comm_size; i++) curr_ops_cnt[i] = 0; 
    146          
    147         if (total_op_count != 0) 
    148         { 
    149             MPIU_CHKLMEM_MALLOC(requests, MPID_Request **,  
    150                                 total_op_count*sizeof(MPID_Request*), 
    151                                 mpi_errno, "requests"); 
    152             MPIU_CHKLMEM_MALLOC(dtype_infos, MPIDI_RMA_dtype_info *,  
    153                                 total_op_count*sizeof(MPIDI_RMA_dtype_info), 
    154                                 mpi_errno, "dtype_infos"); 
    155             MPIU_CHKLMEM_MALLOC(dataloops, void **,  
    156                                 total_op_count*sizeof(void*), 
    157                                 mpi_errno, "dataloops"); 
    158             for (i=0; i<total_op_count; i++) dataloops[i] = NULL; 
    159         } 
    160          
    161         /* do a reduce_scatter_block (with MPI_SUM) on rma_target_proc. As a result, 
     207        /* do a reduce_scatter_block (with MPI_SUM) on rma_target_proc.  
     208           As a result, 
    162209           each process knows how many other processes will be doing 
    163210           RMA ops on its window */   
     
    168215        mpi_errno = MPIR_Reduce_scatter_block_impl(MPI_IN_PLACE, rma_target_proc, 1, 
    169216                                                   MPI_INT, MPI_SUM, comm_ptr); 
     217        MPIU_INSTR_DURATION_END(winfence_rs); 
    170218        /* result is stored in rma_target_proc[0] */ 
    171219        if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
     
    176224        win_ptr->my_counter = win_ptr->my_counter - comm_size +  
    177225            rma_target_proc[0];   
    178              
     226 
     227        MPIU_INSTR_DURATION_START(winfence_issue); 
     228        MPIU_INSTR_DURATION_INCR(winfence_issue,0,total_op_count); 
     229        MPIU_INSTR_DURATION_MAX(winfence_issue,1,total_op_count); 
    179230        i = 0; 
    180         curr_ptr = win_ptr->rma_ops_list; 
     231        curr_ptr = win_ptr->rma_ops_list_head; 
     232        prevNextPtr = &win_ptr->rma_ops_list_head; 
    181233        while (curr_ptr != NULL) 
    182234        { 
     
    192244             
    193245            target_win_handle = win_ptr->all_win_handles[curr_ptr->target_rank]; 
    194              
     246 
     247            curr_ptr->dataloop = 0; 
    195248            switch (curr_ptr->type) 
    196249            { 
     
    199252                mpi_errno = MPIDI_CH3I_Send_rma_msg(curr_ptr, win_ptr, 
    200253                                        source_win_handle, target_win_handle,  
    201                                         &dtype_infos[i], 
    202                                         &dataloops[i], &requests[i]); 
     254                                        &curr_ptr->dtype_info, 
     255                                        &curr_ptr->dataloop, &curr_ptr->request); 
    203256                if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
     257                break; 
     258            case MPIDI_RMA_ACC_CONTIG: 
     259                mpi_errno = MPIDI_CH3I_Send_contig_acc_msg(curr_ptr, win_ptr, 
     260                                   source_win_handle, target_win_handle,  
     261                                   &curr_ptr->request ); 
    204262                break; 
    205263            case (MPIDI_RMA_GET): 
    206264                mpi_errno = MPIDI_CH3I_Recv_rma_msg(curr_ptr, win_ptr, 
    207265                                        source_win_handle, target_win_handle,  
    208                                         &dtype_infos[i],  
    209                                         &dataloops[i], &requests[i]); 
     266                                        &curr_ptr->dtype_info,  
     267                                        &curr_ptr->dataloop, &curr_ptr->request); 
    210268                if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
    211269                break; 
     
    215273            i++; 
    216274            curr_ops_cnt[curr_ptr->target_rank]++; 
    217             curr_ptr = curr_ptr->next; 
    218         } 
    219          
    220              
     275            /* If the request is null, we can remove it immediately */ 
     276            if (!curr_ptr->request) { 
     277                if (curr_ptr->dataloop != NULL) { 
     278                    MPIU_Free(curr_ptr->dataloop); /* allocated in send_rma_msg or  
     279                                                      recv_rma_msg */ 
     280                } 
     281                tmpptr       = curr_ptr->next; 
     282                *prevNextPtr = tmpptr; 
     283                MPIU_Free( curr_ptr ); 
     284                curr_ptr     = tmpptr; 
     285            } 
     286            else  { 
     287                curr_ptr    = curr_ptr->next; 
     288                prevNextPtr = &curr_ptr->next; 
     289                /* FIXME: We could at least occassionally try to wait 
     290                   on completion of the pending send requests rather than 
     291                   focus on filling the queues.  */ 
     292            } 
     293        } 
     294        MPIU_INSTR_DURATION_END(winfence_issue); 
     295 
     296        /* We replaced a loop over an array of requests with a list of the 
     297           incomplete requests.  The reason to do  
     298           that is for long lists - processing the entire list until 
     299           all are done introduces a potentially n^2 time.  In  
     300           testing with test/mpi/perf/manyrma.c , the number of iterations 
     301           within the "while (total_op_count) was O(total_op_count). 
     302            
     303           Another alternative is to create a more compressed list (storing 
     304           only the necessary information, reducing the number of cache lines 
     305           needed while looping through the requests. 
     306        */ 
    221307        if (total_op_count) 
    222308        {  
    223             done = 1; 
     309            int ntimes = 0; 
     310            MPIU_INSTR_DURATION_START(winfence_complete); 
    224311            MPID_Progress_start(&progress_state); 
    225             while (total_op_count) 
    226             { 
    227                 for (i=0; i<total_op_count; i++) 
    228                 { 
    229                     if (requests[i] != NULL) 
    230                     { 
    231                         if (!MPID_Request_is_complete(requests[i])) 
    232                         { 
    233                             done = 0; 
    234                             break; 
    235                         } 
    236                         else 
    237                         { 
    238                             mpi_errno = requests[i]->status.MPI_ERROR; 
     312            /* Process all operations until they are complete */ 
     313            while (win_ptr->rma_ops_list_head) { 
     314                int loopcount = 0; 
     315                prevNextPtr = &win_ptr->rma_ops_list_head; 
     316                ntimes++; 
     317                curr_ptr = win_ptr->rma_ops_list_head; 
     318                do { 
     319                    if (MPID_Request_is_complete(curr_ptr->request)) { 
     320                        /* Once we find a complete request, we complete 
     321                         as many as possible until we find an incomplete 
     322                         or null request */ 
     323                        do { 
     324                            mpi_errno = curr_ptr->request->status.MPI_ERROR; 
    239325                            /* --BEGIN ERROR HANDLING-- */ 
    240                             if (mpi_errno != MPI_SUCCESS) 
    241                             { 
     326                            if (mpi_errno != MPI_SUCCESS) { 
    242327                                MPID_Progress_end(&progress_state); 
    243328                                MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winRMAmessage"); 
    244329                            } 
    245330                            /* --END ERROR HANDLING-- */ 
    246                             /* if origin datatype was a derived 
    247                                datatype, it will get freed when the 
    248                                request gets freed. */  
    249                             MPID_Request_release(requests[i]); 
    250                             requests[i] = NULL; 
     331                            MPID_Request_release(curr_ptr->request); 
     332                            if (curr_ptr->dataloop != NULL) { 
     333                                MPIU_Free(curr_ptr->dataloop); /* allocated in send_rma_msg or  
     334                                                                  recv_rma_msg */ 
     335                            } 
     336                            /* We can remove and free this rma op element */ 
     337                            tmpptr       = curr_ptr->next; 
     338                            *prevNextPtr = tmpptr; 
     339                            MPIU_Free( curr_ptr ); 
     340                            curr_ptr     = tmpptr; 
    251341                        } 
     342                        while (curr_ptr && 
     343                               MPID_Request_is_complete(curr_ptr->request)); 
     344                        /* Once a request completes, we wait for another 
     345                           operation to arrive rather than check the 
     346                           rest of the requests.  */ 
     347                        break; 
    252348                    } 
     349                    else { 
     350                        /* In many cases, if the list of pending requests 
     351                           is long, there's no point in checking the entire 
     352                           list */ 
     353                        if (loopcount++ > 4) /* FIXME: threshold as parameter */ 
     354                            break;  /* wait for an event */ 
     355                        prevNextPtr = &curr_ptr->next; 
     356                        curr_ptr    = curr_ptr->next; 
     357                    } 
     358                } while (curr_ptr); 
     359          
     360                /* Wait for something to arrive*/ 
     361                /* In some tests, this hung unless the test ensured that  
     362                   there was an incomplete request. */ 
     363                curr_ptr = win_ptr->rma_ops_list_head; 
     364                if (curr_ptr && !MPID_Request_is_complete(curr_ptr->request) ) { 
     365                    MPIU_INSTR_DURATION_START(winfence_block); 
     366                    mpi_errno = MPID_Progress_wait(&progress_state); 
     367                    /* --BEGIN ERROR HANDLING-- */ 
     368                    if (mpi_errno != MPI_SUCCESS) { 
     369                        MPID_Progress_end(&progress_state); 
     370                        MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winnoprogress"); 
     371                    } 
     372                    /* --END ERROR HANDLING-- */ 
     373                    MPIU_INSTR_DURATION_END(winfence_block); 
    253374                } 
    254                      
    255                 if (done) 
    256                 { 
    257                     break; 
    258                 } 
    259                      
    260                 mpi_errno = MPID_Progress_wait(&progress_state); 
    261                 /* --BEGIN ERROR HANDLING-- */ 
    262                 if (mpi_errno != MPI_SUCCESS) { 
    263                     MPID_Progress_end(&progress_state); 
    264                     MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winnoprogress"); 
    265                 } 
    266                 /* --END ERROR HANDLING-- */ 
    267                  
    268                 done = 1; 
    269             }  
     375            } /* While list of rma operation is non-empty */ 
    270376            MPID_Progress_end(&progress_state); 
     377            MPIU_INSTR_DURATION_INCR(winfence_complete,0,ntimes); 
     378            MPIU_INSTR_DURATION_END(winfence_complete); 
    271379        } 
    272380             
    273         if (total_op_count != 0) 
    274         { 
    275             for (i=0; i<total_op_count; i++) 
    276             { 
    277                 if (dataloops[i] != NULL) 
    278                 { 
    279                     MPIU_Free(dataloops[i]); /* allocated in send_rma_msg or  
    280                                                 recv_rma_msg */ 
    281                 } 
    282             } 
    283         } 
    284          
    285         /* free MPIDI_RMA_ops_list */ 
    286         curr_ptr = win_ptr->rma_ops_list; 
    287         while (curr_ptr != NULL) 
    288         { 
    289             next_ptr = curr_ptr->next; 
    290             MPIU_Free(curr_ptr); 
    291             curr_ptr = next_ptr; 
    292         } 
    293         win_ptr->rma_ops_list = NULL; 
     381        win_ptr->rma_ops_list_head = NULL; 
     382        win_ptr->rma_ops_list_tail = NULL; 
    294383         
    295384        /* wait for all operations from other processes to finish */ 
    296385        if (win_ptr->my_counter) 
    297386        { 
     387            MPIU_INSTR_DURATION_START(winfence_wait); 
    298388            MPID_Progress_start(&progress_state); 
    299389            while (win_ptr->my_counter) 
     
    306396                } 
    307397                /* --END ERROR HANDLING-- */ 
     398                MPIU_INSTR_DURATION_INCR(winfence_wait,0,1); 
    308399            } 
    309400            MPID_Progress_end(&progress_state); 
     401            MPIU_INSTR_DURATION_END(winfence_wait); 
    310402        }  
    311403         
     
    471563    */ 
    472564 
    473     MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     565    comm_ptr = win_ptr->comm_ptr; 
    474566    MPIDI_Comm_get_vc_set_active(comm_ptr, rma_op->target_rank, &vc); 
    475567 
     
    642734} 
    643735 
     736/* 
     737 * Use this for contiguous accumulate operations 
     738 */ 
     739#undef FUNCNAME 
     740#define FUNCNAME MPIDI_CH3I_Send_contig_acc_msg 
     741#undef FCNAME 
     742#define FCNAME MPIDI_QUOTE(FUNCNAME) 
     743static int MPIDI_CH3I_Send_contig_acc_msg(MPIDI_RMA_ops *rma_op,  
     744                                          MPID_Win *win_ptr, 
     745                                          MPI_Win source_win_handle,  
     746                                          MPI_Win target_win_handle,  
     747                                          MPID_Request **request)  
     748{ 
     749    MPIDI_CH3_Pkt_t upkt; 
     750    MPIDI_CH3_Pkt_accum_t *accum_pkt = &upkt.accum; 
     751    MPID_IOV iov[MPID_IOV_LIMIT]; 
     752    int mpi_errno=MPI_SUCCESS; 
     753    int origin_type_size, iovcnt;  
     754    MPIDI_VC_t * vc; 
     755    MPID_Comm *comm_ptr; 
     756    int len; 
     757    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_SEND_CONTIG_ACC_MSG); 
     758    MPIDI_STATE_DECL(MPID_STATE_MEMCPY); 
     759 
     760    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEND_CONTIG_ACC_MSG); 
     761 
     762    *request = NULL; 
     763 
     764    MPID_Datatype_get_size_macro(rma_op->origin_datatype, origin_type_size); 
     765    /* FIXME: Make this size check efficient and match the packet type */ 
     766    len = rma_op->origin_count * origin_type_size; 
     767    if (EnableImmedAcc && len <= MPIDI_RMA_IMMED_INTS*sizeof(int)) { 
     768        MPIDI_CH3_Pkt_accum_immed_t * accumi_pkt = &upkt.accum_immed; 
     769        void *dest = accumi_pkt->data, *src = rma_op->origin_addr; 
     770         
     771        MPIDI_Pkt_init(accumi_pkt, MPIDI_CH3_PKT_ACCUM_IMMED); 
     772        accumi_pkt->addr = (char *) win_ptr->base_addrs[rma_op->target_rank] + 
     773            win_ptr->disp_units[rma_op->target_rank] * rma_op->target_disp; 
     774        accumi_pkt->count = rma_op->target_count; 
     775        accumi_pkt->datatype = rma_op->target_datatype; 
     776        accumi_pkt->op = rma_op->op; 
     777        accumi_pkt->target_win_handle = target_win_handle; 
     778        accumi_pkt->source_win_handle = source_win_handle; 
     779         
     780        switch (len) { 
     781        case 1: *(uint8_t *)dest  = *(uint8_t *)src;  break; 
     782        case 2: *(uint16_t *)dest = *(uint16_t *)src; break; 
     783        case 4: *(uint32_t *)dest = *(uint32_t *)src; break; 
     784        case 8: *(uint64_t *)dest = *(uint64_t *)src; break; 
     785        default: 
     786            MPIU_Memcpy( accumi_pkt->data, (void *)rma_op->origin_addr, len ); 
     787        } 
     788        comm_ptr = win_ptr->comm_ptr; 
     789        MPIDI_Comm_get_vc_set_active(comm_ptr, rma_op->target_rank, &vc); 
     790        MPIU_THREAD_CS_ENTER(CH3COMM,vc); 
     791        mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, accumi_pkt, sizeof(*accumi_pkt), request)); 
     792        MPIU_THREAD_CS_EXIT(CH3COMM,vc); 
     793        MPIU_ERR_CHKANDJUMP(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**ch3|rmamsg"); 
     794        goto fn_exit; 
     795    } 
     796 
     797    MPIDI_Pkt_init(accum_pkt, MPIDI_CH3_PKT_ACCUMULATE); 
     798    accum_pkt->addr = (char *) win_ptr->base_addrs[rma_op->target_rank] + 
     799        win_ptr->disp_units[rma_op->target_rank] * rma_op->target_disp; 
     800    accum_pkt->count = rma_op->target_count; 
     801    accum_pkt->datatype = rma_op->target_datatype; 
     802    accum_pkt->dataloop_size = 0; 
     803    accum_pkt->op = rma_op->op; 
     804    accum_pkt->target_win_handle = target_win_handle; 
     805    accum_pkt->source_win_handle = source_win_handle; 
     806     
     807    iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) accum_pkt; 
     808    iov[0].MPID_IOV_LEN = sizeof(*accum_pkt); 
     809 
     810    /*    printf("send pkt: type %d, addr %d, count %d, base %d\n", rma_pkt->type, 
     811          rma_pkt->addr, rma_pkt->count, win_ptr->base_addrs[rma_op->target_rank]); 
     812          fflush(stdout); 
     813    */ 
     814 
     815    comm_ptr = win_ptr->comm_ptr; 
     816    MPIDI_Comm_get_vc_set_active(comm_ptr, rma_op->target_rank, &vc); 
     817 
     818 
     819    /* basic datatype on target */ 
     820    /* basic datatype on origin */ 
     821    /* FIXME: This is still very heavyweight for a small message operation, 
     822       such as a single word update */ 
     823    /* One possibility is to use iStartMsg with a buffer that is just large  
     824       enough, though note that nemesis has an optimization for this */ 
     825    iov[1].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)rma_op->origin_addr; 
     826    iov[1].MPID_IOV_LEN = rma_op->origin_count * origin_type_size; 
     827    iovcnt = 2; 
     828    MPIU_THREAD_CS_ENTER(CH3COMM,vc); 
     829    mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsgv(vc, iov, iovcnt, request)); 
     830    MPIU_THREAD_CS_EXIT(CH3COMM,vc); 
     831    MPIU_ERR_CHKANDJUMP(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**ch3|rmamsg"); 
     832 
     833 fn_exit: 
     834    MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_SEND_CONTIG_ACC_MSG); 
     835    return mpi_errno; 
     836    /* --BEGIN ERROR HANDLING-- */ 
     837 fn_fail: 
     838    if (*request) 
     839    { 
     840        MPIU_Object_set_ref(*request, 0); 
     841        MPIDI_CH3_Request_destroy(*request); 
     842    } 
     843    *request = NULL; 
     844    goto fn_exit; 
     845    /* --END ERROR HANDLING-- */ 
     846} 
     847 
    644848 
    645849 
     
    709913*/ 
    710914             
    711     MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     915    comm_ptr = win_ptr->comm_ptr; 
    712916    MPIDI_Comm_get_vc_set_active(comm_ptr, rma_op->target_rank, &vc); 
    713917 
     
    791995 
    792996 
    793  
    794  
    795997#undef FUNCNAME 
    796998#define FUNCNAME MPIDI_Win_post 
     
    8251027        MPID_Progress_state progress_state; 
    8261028         
     1029        MPIU_INSTR_DURATION_START(winpost_clearlock); 
    8271030        /* poke the progress engine */ 
    8281031        MPID_Progress_start(&progress_state); 
     
    8361039            } 
    8371040            /* --END ERROR HANDLING-- */ 
     1041            MPIU_INSTR_DURATION_INCR(winpost_clearlock,0,1); 
    8381042        } 
    8391043        MPID_Progress_end(&progress_state); 
     1044        MPIU_INSTR_DURATION_END(winpost_clearlock); 
    8401045    } 
    8411046         
     
    8491054        MPI_Request *req; 
    8501055        MPI_Status *status; 
     1056 
     1057        MPIU_INSTR_DURATION_START(winpost_sendsync); 
    8511058  
    8521059        /* NOCHECK not specified. We need to notify the source 
     
    8541061         
    8551062        /* We need to translate the ranks of the processes in 
    856            post_group to ranks in win_ptr->comm, so that we 
     1063           post_group to ranks in win_ptr->comm_ptr, so that we 
    8571064           can do communication */ 
    8581065             
     
    8691076        } 
    8701077         
    871         MPID_Comm_get_ptr( win_ptr->comm, win_comm_ptr ); 
     1078        win_comm_ptr = win_ptr->comm_ptr; 
    8721079 
    8731080        mpi_errno = MPIR_Comm_group_impl(win_comm_ptr, &win_grp_ptr); 
     
    8781085                                        win_grp_ptr, ranks_in_win_grp); 
    8791086         
    880         rank = MPIR_Comm_rank(win_comm_ptr); 
     1087        rank = win_ptr->myrank; 
    8811088         
    8821089        MPIU_CHKLMEM_MALLOC(req, MPI_Request *, post_grp_size * sizeof(MPI_Request), mpi_errno, "req"); 
     
    8841091 
    8851092        /* Send a 0-byte message to the source processes */ 
     1093        MPIU_INSTR_DURATION_INCR(winpost_sendsync,0,post_grp_size); 
    8861094        for (i = 0; i < post_grp_size; i++) { 
    8871095            dst = ranks_in_win_grp[i]; 
    888              
     1096 
     1097            /* FIXME: Short messages like this shouldn't normally need a  
     1098               request - this should consider using the ch3 call to send 
     1099               a short message and return a request only if the message is 
     1100               not delivered. */ 
    8891101            if (dst != rank) { 
    8901102                MPID_Request *req_ptr; 
     
    9131125        mpi_errno = MPIR_Group_free_impl(win_grp_ptr); 
    9141126        if (mpi_errno) MPIU_ERR_POP(mpi_errno); 
     1127        MPIU_INSTR_DURATION_END(winpost_sendsync); 
    9151128    } 
    9161129 
     
    9551168        MPID_Progress_state progress_state; 
    9561169         
     1170        MPIU_INSTR_DURATION_START(winstart_clearlock); 
    9571171        /* poke the progress engine */ 
    9581172        MPID_Progress_start(&progress_state); 
     
    9661180            } 
    9671181            /* --END ERROR HANDLING-- */ 
     1182            MPIU_INSTR_DURATION_INCR(winstart_clearlock,0,1); 
    9681183        } 
    9691184        MPID_Progress_end(&progress_state); 
     1185        MPIU_INSTR_DURATION_END(winstart_clearlock); 
    9701186    } 
    9711187     
     
    9901206    int comm_size, *nops_to_proc, src, new_total_op_count; 
    9911207    int i, j, dst, done, total_op_count, *curr_ops_cnt; 
    992     MPIDI_RMA_ops *curr_ptr, *next_ptr; 
     1208    MPIDI_RMA_ops *curr_ptr, *tmpptr, **prevNextPtr; 
    9931209    MPID_Comm *comm_ptr; 
    994     MPID_Request **requests; /* array of requests */ 
    9951210    MPI_Win source_win_handle, target_win_handle; 
    996     MPIDI_RMA_dtype_info *dtype_infos=NULL; 
    997     void **dataloops=NULL;    /* to store dataloops for each datatype */ 
    9981211    MPID_Group *win_grp_ptr; 
    9991212    int start_grp_size, *ranks_in_start_grp, *ranks_in_win_grp, rank; 
     
    10031216    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_WIN_COMPLETE); 
    10041217 
    1005     MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
     1218    comm_ptr = win_ptr->comm_ptr; 
    10061219    comm_size = comm_ptr->local_size; 
    10071220         
    10081221    /* Translate the ranks of the processes in 
    1009        start_group to ranks in win_ptr->comm */ 
     1222       start_group to ranks in win_ptr->comm_ptr */ 
    10101223     
    10111224    start_grp_size = win_ptr->start_group_ptr->size; 
    1012          
     1225 
     1226    MPIU_INSTR_DURATION_START(wincomplete_recvsync); 
    10131227    MPIU_CHKLMEM_MALLOC(ranks_in_start_grp, int *, start_grp_size*sizeof(int),  
    10141228                        mpi_errno, "ranks_in_start_grp"); 
     
    10251239    if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
    10261240 
    1027     MPIR_Group_translate_ranks_impl(win_ptr->start_group_ptr, start_grp_size, ranks_in_start_grp, 
     1241    MPIR_Group_translate_ranks_impl(win_ptr->start_group_ptr, start_grp_size,  
     1242                                    ranks_in_start_grp, 
    10281243                                    win_grp_ptr, ranks_in_win_grp); 
    10291244         
    1030     rank = MPIR_Comm_rank(comm_ptr); 
     1245    rank = win_ptr->myrank; 
    10311246 
    10321247    /* If MPI_MODE_NOCHECK was not specified, we need to check if 
     
    10371252        MPI_Request *req; 
    10381253        MPI_Status *status; 
    1039          
     1254 
    10401255        MPIU_CHKLMEM_MALLOC(req, MPI_Request *, start_grp_size*sizeof(MPI_Request), mpi_errno, "req"); 
    10411256        MPIU_CHKLMEM_MALLOC(status, MPI_Status *, start_grp_size*sizeof(MPI_Status), mpi_errno, "status"); 
    10421257 
     1258        MPIU_INSTR_DURATION_INCR(wincomplete_recvsync,0,start_grp_size); 
    10431259        for (i = 0; i < start_grp_size; i++) { 
    10441260            src = ranks_in_win_grp[i]; 
    10451261            if (src != rank) { 
    10461262                MPID_Request *req_ptr; 
     1263                /* FIXME: This is a heavyweight way to process these sync  
     1264                   messages - this should be handled with a special packet 
     1265                   type and callback function. 
     1266                */ 
    10471267                mpi_errno = MPID_Irecv(NULL, 0, MPI_INT, src, SYNC_POST_TAG, 
    10481268                                       comm_ptr, MPID_CONTEXT_INTRA_PT2PT, &req_ptr); 
     
    10681288        /* --END ERROR HANDLING-- */ 
    10691289    } 
    1070          
     1290    MPIU_INSTR_DURATION_END(wincomplete_recvsync); 
     1291 
    10711292    /* keep track of no. of ops to each proc. Needed for knowing 
    10721293       whether or not to decrement the completion counter. The 
    10731294       completion counter is decremented only on the last 
    10741295       operation. */ 
    1075          
     1296 
     1297    MPIU_INSTR_DURATION_START(wincomplete_issue); 
     1298 
    10761299    MPIU_CHKLMEM_MALLOC(nops_to_proc, int *, comm_size*sizeof(int),  
    10771300                        mpi_errno, "nops_to_proc"); 
     
    10791302 
    10801303    total_op_count = 0; 
    1081     curr_ptr = win_ptr->rma_ops_list; 
     1304    curr_ptr = win_ptr->rma_ops_list_head; 
    10821305    while (curr_ptr != NULL) 
    10831306    { 
     
    10861309        curr_ptr = curr_ptr->next; 
    10871310    } 
    1088      
    1089     MPIU_CHKLMEM_MALLOC(requests, MPID_Request **,  
    1090                         (total_op_count+start_grp_size) * sizeof(MPID_Request*), 
    1091                         mpi_errno, "requests"); 
     1311 
     1312    MPIU_INSTR_DURATION_INCR(wincomplete_issue,0,total_op_count); 
     1313    MPIU_INSTR_DURATION_MAX(wincomplete_issue,1,total_op_count); 
     1314 
    10921315    /* We allocate a few extra requests because if there are no RMA 
    10931316       ops to a target process, we need to send a 0-byte message just 
     
    10971320                        mpi_errno, "curr_ops_cnt"); 
    10981321    for (i=0; i<comm_size; i++) curr_ops_cnt[i] = 0; 
    1099      
    1100     if (total_op_count != 0) 
    1101     { 
    1102         MPIU_CHKLMEM_MALLOC(dtype_infos, MPIDI_RMA_dtype_info *,  
    1103                             total_op_count*sizeof(MPIDI_RMA_dtype_info), 
    1104                             mpi_errno, "dtype_infos"); 
    1105         MPIU_CHKLMEM_MALLOC(dataloops, void **, total_op_count*sizeof(void*), 
    1106                             mpi_errno, "dataloops"); 
    1107         for (i=0; i<total_op_count; i++) dataloops[i] = NULL; 
    1108     } 
    11091322         
    11101323    i = 0; 
    1111     curr_ptr = win_ptr->rma_ops_list; 
     1324    prevNextPtr = &win_ptr->rma_ops_list_head; 
     1325    curr_ptr = win_ptr->rma_ops_list_head; 
    11121326    while (curr_ptr != NULL) 
    11131327    { 
     
    11231337         
    11241338        target_win_handle = win_ptr->all_win_handles[curr_ptr->target_rank]; 
    1125          
     1339 
     1340        curr_ptr->dataloop = 0; 
    11261341        switch (curr_ptr->type) 
    11271342        { 
     
    11301345            mpi_errno = MPIDI_CH3I_Send_rma_msg(curr_ptr, win_ptr, 
    11311346                                source_win_handle, target_win_handle,  
    1132                                 &dtype_infos[i], 
    1133                                 &dataloops[i], &requests[i]);  
     1347                                &curr_ptr->dtype_info, 
     1348                                &curr_ptr->dataloop, &curr_ptr->request);  
    11341349            if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
     1350            break; 
     1351        case MPIDI_RMA_ACC_CONTIG: 
     1352            mpi_errno = MPIDI_CH3I_Send_contig_acc_msg(curr_ptr, win_ptr, 
     1353                                       source_win_handle, target_win_handle,  
     1354                                       &curr_ptr->request ); 
    11351355            break; 
    11361356        case (MPIDI_RMA_GET): 
    11371357            mpi_errno = MPIDI_CH3I_Recv_rma_msg(curr_ptr, win_ptr, 
    11381358                                source_win_handle, target_win_handle,  
    1139                                 &dtype_infos[i],  
    1140                                 &dataloops[i], &requests[i]); 
     1359                                &curr_ptr->dtype_info,  
     1360                                &curr_ptr->dataloop, &curr_ptr->request); 
    11411361            if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
    11421362            break; 
     
    11461366        i++; 
    11471367        curr_ops_cnt[curr_ptr->target_rank]++; 
    1148         curr_ptr = curr_ptr->next; 
    1149     } 
     1368        /* If the request is null, we can remove it immediately */ 
     1369        if (!curr_ptr->request) { 
     1370            if (curr_ptr->dataloop != NULL) { 
     1371                MPIU_Free(curr_ptr->dataloop); /* allocated in send_rma_msg or  
     1372                                                  recv_rma_msg */ 
     1373            } 
     1374            tmpptr       = curr_ptr->next; 
     1375            *prevNextPtr = tmpptr; 
     1376            MPIU_Free( curr_ptr ); 
     1377            curr_ptr     = tmpptr; 
     1378        } 
     1379        else  { 
     1380            curr_ptr    = curr_ptr->next; 
     1381            prevNextPtr = &curr_ptr->next; 
     1382        } 
     1383    } 
     1384    MPIU_INSTR_DURATION_END(wincomplete_issue); 
    11501385         
    11511386    /* If the start_group included some processes that did not end up 
     
    11681403            MPIDI_CH3_Pkt_put_t *put_pkt = &upkt.put; 
    11691404            MPIDI_VC_t * vc; 
     1405            MPID_Request *request; 
    11701406             
    11711407            MPIDI_Pkt_init(put_pkt, MPIDI_CH3_PKT_PUT); 
     
    11811417            mpi_errno = MPIU_CALL(MPIDI_CH3,iStartMsg(vc, put_pkt, 
    11821418                                                      sizeof(*put_pkt), 
    1183                                                       &requests[j])); 
     1419                                                      &request)); 
    11841420            MPIU_THREAD_CS_EXIT(CH3COMM,vc); 
    11851421            if (mpi_errno != MPI_SUCCESS) { 
    11861422                MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**ch3|rmamsg" ); 
    11871423            } 
     1424            /* In the unlikely event that a request is returned (the message 
     1425               is not sent yet), add it to the list of pending operations */ 
     1426            if (request) { 
     1427                /* Its hard to use the automatic allocator here, as those  
     1428                   macros are optimized for a known maximum number of items. */ 
     1429                MPIDI_RMA_ops *new_ptr; 
     1430                new_ptr = (MPIDI_RMA_ops *)MPIU_Malloc(sizeof(MPIDI_RMA_ops) ); 
     1431                /* --BEGIN ERROR HANDLING-- */ 
     1432                if (!new_ptr) { 
     1433                    MPIU_CHKMEM_SETERR(mpi_errno,sizeof(MPIDI_RMA_ops), 
     1434                                        "RMA operation entry"); 
     1435                    goto fn_fail; 
     1436                } 
     1437                /* --END ERROR HANDLING-- */ 
     1438                if (win_ptr->rma_ops_list_tail)  
     1439                    win_ptr->rma_ops_list_tail->next = new_ptr; 
     1440                else 
     1441                    win_ptr->rma_ops_list_head = new_ptr; 
     1442                win_ptr->rma_ops_list_tail = new_ptr; 
     1443                new_ptr->next     = NULL; 
     1444                new_ptr->request  = request; 
     1445                new_ptr->dataloop = 0; 
     1446            } 
    11881447            j++; 
    11891448            new_total_op_count++; 
    11901449        } 
    11911450    } 
    1192          
     1451 
    11931452    if (new_total_op_count) 
    11941453    { 
     
    11961455         
    11971456        done = 1; 
     1457        MPIU_INSTR_DURATION_START(wincomplete_complete); 
    11981458        MPID_Progress_start(&progress_state); 
    1199         while (new_total_op_count) 
    1200         { 
    1201             for (i=0; i<new_total_op_count; i++) 
    1202             { 
    1203                 if (requests[i] != NULL) 
    1204                 { 
    1205                     if (!MPID_Request_is_complete(requests[i])) 
    1206                     { 
    1207                         done = 0; 
    1208                         break; 
    1209                     } 
    1210                     else 
    1211                     { 
    1212                         mpi_errno = requests[i]->status.MPI_ERROR; 
     1459        while (win_ptr->rma_ops_list_head) { 
     1460            prevNextPtr = &win_ptr->rma_ops_list_head; 
     1461            curr_ptr    = win_ptr->rma_ops_list_head; 
     1462            do { 
     1463                if (MPID_Request_is_complete(curr_ptr->request)) { 
     1464                    /* Once we find a complete request, we complete 
     1465                       as many as possible until we find an incomplete 
     1466                       or null request */ 
     1467                    do { 
     1468                        mpi_errno = curr_ptr->request->status.MPI_ERROR; 
    12131469                        /* --BEGIN ERROR HANDLING-- */ 
    1214                         if (mpi_errno != MPI_SUCCESS) 
    1215                         { 
     1470                        if (mpi_errno != MPI_SUCCESS) { 
    12161471                            MPID_Progress_end(&progress_state); 
    1217                             MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winRMArequest"); 
     1472                            MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winRMAmessage"); 
    12181473                        } 
    12191474                        /* --END ERROR HANDLING-- */ 
    1220                         MPID_Request_release(requests[i]); 
    1221                         requests[i] = NULL; 
     1475                        MPID_Request_release(curr_ptr->request); 
     1476                        if (curr_ptr->dataloop != NULL) { 
     1477                            MPIU_Free(curr_ptr->dataloop); /* allocated in send_rma_msg or  
     1478                                                              recv_rma_msg */ 
     1479                        } 
     1480                        /* We can remove and free this rma op element */ 
     1481                        tmpptr       = curr_ptr->next; 
     1482                        *prevNextPtr = tmpptr; 
     1483                        MPIU_Free( curr_ptr ); 
     1484                        curr_ptr     = tmpptr; 
    12221485                    } 
     1486                    while (curr_ptr && 
     1487                           MPID_Request_is_complete(curr_ptr->request)); 
     1488                    /* Once a request completes, we wait for another 
     1489                       operation to arrive rather than check the 
     1490                       rest of the requests.  */ 
     1491                    break; 
    12231492                } 
     1493                else { 
     1494                    prevNextPtr = &curr_ptr->next; 
     1495                    curr_ptr    = curr_ptr->next; 
     1496                    break; 
     1497                } 
     1498            } while (curr_ptr); 
     1499 
     1500            /* Wait for something to arrive*/ 
     1501            /* In some tests, this hung unless the test ensured that  
     1502               there was an incomplete request. */ 
     1503            curr_ptr = win_ptr->rma_ops_list_head; 
     1504            if (curr_ptr && !MPID_Request_is_complete(curr_ptr->request) ) { 
     1505                MPIU_INSTR_DURATION_START(winfence_block); 
     1506                mpi_errno = MPID_Progress_wait(&progress_state); 
     1507                /* --BEGIN ERROR HANDLING-- */ 
     1508                if (mpi_errno != MPI_SUCCESS) { 
     1509                    MPID_Progress_end(&progress_state); 
     1510                    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winnoprogress"); 
     1511                } 
     1512                /* --END ERROR HANDLING-- */ 
     1513                MPIU_INSTR_DURATION_END(winfence_block); 
    12241514            } 
    1225                  
    1226             if (done) 
    1227             { 
    1228                 break; 
    1229             } 
     1515        } /* While list of rma operation is non-empty */ 
    12301516             
    1231             mpi_errno = MPID_Progress_wait(&progress_state); 
    1232             done = 1; 
    1233         }  
     1517             
    12341518        MPID_Progress_end(&progress_state); 
    12351519    } 
    1236          
    1237     if (total_op_count != 0) 
    1238     { 
    1239         for (i=0; i<total_op_count; i++) 
    1240         { 
    1241             if (dataloops[i] != NULL) 
    1242             { 
    1243                 MPIU_Free(dataloops[i]); 
    1244             } 
    1245         } 
    1246     } 
    1247          
    1248     /* free MPIDI_RMA_ops_list */ 
    1249     curr_ptr = win_ptr->rma_ops_list; 
    1250     while (curr_ptr != NULL) 
    1251     { 
    1252         next_ptr = curr_ptr->next; 
    1253         MPIU_Free(curr_ptr); 
    1254         curr_ptr = next_ptr; 
    1255     } 
    1256     win_ptr->rma_ops_list = NULL; 
     1520 
     1521    MPIU_Assert( !win_ptr->rma_ops_list_head ); 
     1522    win_ptr->rma_ops_list_head = NULL; 
     1523    win_ptr->rma_ops_list_tail = NULL; 
    12571524     
    12581525    mpi_errno = MPIR_Group_free_impl(win_grp_ptr); 
     
    12921559        MPID_Progress_state progress_state; 
    12931560         
     1561        MPIU_INSTR_DURATION_START(winwait_wait); 
    12941562        MPID_Progress_start(&progress_state); 
    12951563        while (win_ptr->my_counter) 
     
    13041572            } 
    13051573            /* --END ERROR HANDLING-- */ 
     1574            MPIU_INSTR_DURATION_INCR(winwait_wait,0,1) 
    13061575        } 
    13071576        MPID_Progress_end(&progress_state); 
     1577        MPIU_INSTR_DURATION_END(winwait_wait); 
    13081578    }  
    13091579 
     
    13631633    if (dest == MPI_PROC_NULL) goto fn_exit; 
    13641634         
    1365     MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
    1366      
    1367     if (dest == comm_ptr->rank) { 
     1635    comm_ptr = win_ptr->comm_ptr; 
     1636     
     1637    if (dest == win_ptr->myrank) { 
    13681638        /* The target is this process itself. We must block until the lock 
    13691639         * is acquired. */ 
     
    13741644            MPID_Progress_state progress_state; 
    13751645             
     1646            MPIU_INSTR_DURATION_START(winlock_getlocallock); 
    13761647            MPID_Progress_start(&progress_state); 
    13771648            while (MPIDI_CH3I_Try_acquire_win_lock(win_ptr, lock_type) == 0)  
     
    13861657            } 
    13871658            MPID_Progress_end(&progress_state); 
     1659            MPIU_INSTR_DURATION_END(winlock_getlocallock); 
    13881660        } 
    13891661        /* local lock acquired. local puts, gets, accumulates will be done  
     
    13931665    else { 
    13941666        /* target is some other process. add the lock request to rma_ops_list */ 
    1395              
     1667        MPIU_INSTR_DURATION_START(rmaqueue_alloc); 
    13961668        MPIU_CHKPMEM_MALLOC(new_ptr, MPIDI_RMA_ops *, sizeof(MPIDI_RMA_ops),  
    13971669                            mpi_errno, "RMA operation entry"); 
     1670        MPIU_INSTR_DURATION_END(rmaqueue_alloc); 
    13981671             
    1399         win_ptr->rma_ops_list = new_ptr; 
     1672        win_ptr->rma_ops_list_head = new_ptr; 
     1673        win_ptr->rma_ops_list_tail = new_ptr; 
    14001674         
    14011675        new_ptr->next = NULL;   
     
    14351709    if (dest == MPI_PROC_NULL) goto fn_exit; 
    14361710         
    1437     MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
    1438          
    1439     if (dest == comm_ptr->rank) { 
     1711    comm_ptr = win_ptr->comm_ptr; 
     1712         
     1713    if (dest == win_ptr->myrank) { 
    14401714        /* local lock. release the lock on the window, grant the next one 
    14411715         * in the queue, and return. */ 
     
    14461720    } 
    14471721         
    1448     rma_op = win_ptr->rma_ops_list; 
     1722    rma_op = win_ptr->rma_ops_list_head; 
    14491723     
    14501724    /* win_lock was not called. return error */ 
     
    14621736        /* only win_lock called, no put/get/acc. Do nothing and return. */ 
    14631737        MPIU_Free(rma_op); 
    1464         win_ptr->rma_ops_list = NULL; 
     1738        win_ptr->rma_ops_list_head = NULL; 
     1739        win_ptr->rma_ops_list_tail = NULL; 
    14651740        goto fn_exit; 
    14661741    } 
     
    15031778         
    15041779        /* Send a lock packet over to the target. wait for the lock_granted 
    1505          * reply. then do all the RMA ops. */  
     1780         * reply. Then do all the RMA ops. */  
    15061781         
    15071782        MPIDI_Pkt_init(lock_pkt, MPIDI_CH3_PKT_LOCK); 
     
    15361811            MPID_Progress_state progress_state; 
    15371812             
     1813            MPIU_INSTR_DURATION_START(winunlock_getlock); 
    15381814            MPID_Progress_start(&progress_state); 
    15391815            while (win_ptr->lock_granted == 0) 
     
    15481824            } 
    15491825            MPID_Progress_end(&progress_state); 
     1826            MPIU_INSTR_DURATION_END(winunlock_getlock); 
    15501827        } 
    15511828         
     
    16041881{ 
    16051882    int mpi_errno = MPI_SUCCESS, done, i, nops; 
    1606     MPIDI_RMA_ops *curr_ptr, *next_ptr, **curr_ptr_ptr, *tmp_ptr; 
     1883    MPIDI_RMA_ops *curr_ptr; 
    16071884    MPID_Comm *comm_ptr; 
    1608     MPID_Request **requests=NULL; /* array of requests */ 
    1609     MPIDI_RMA_dtype_info *dtype_infos=NULL; 
    1610     void **dataloops=NULL;    /* to store dataloops for each datatype */ 
     1885    MPIDI_RMA_ops **prevNextPtr, *tmpptr; 
    16111886    MPI_Win source_win_handle, target_win_handle; 
    1612     MPIU_CHKLMEM_DECL(3); 
    16131887    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3I_DO_PASSIVE_TARGET_RMA); 
    16141888 
    16151889    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_DO_PASSIVE_TARGET_RMA); 
    16161890 
    1617     if (win_ptr->rma_ops_list->lock_type == MPI_LOCK_EXCLUSIVE) { 
     1891    if (win_ptr->rma_ops_list_head->lock_type == MPI_LOCK_EXCLUSIVE) { 
    16181892        /* exclusive lock. no need to wait for rma done pkt at the end */ 
    16191893        *wait_for_rma_done_pkt = 0; 
     
    16241898           pkt is not needed. If there is no get, rma done pkt is needed */ 
    16251899 
    1626         /* First check whether the last operation is a get. Skip the first op,  
    1627            which is a lock. */ 
    1628  
    1629         curr_ptr = win_ptr->rma_ops_list->next; 
    1630         while (curr_ptr->next != NULL)  
    1631             curr_ptr = curr_ptr->next; 
    1632      
    1633         if (curr_ptr->type == MPIDI_RMA_GET) { 
     1900        if (win_ptr->rma_ops_list_tail->type == MPIDI_RMA_GET) { 
    16341901            /* last operation is a get. no need to wait for rma done pkt */ 
    16351902            *wait_for_rma_done_pkt = 0; 
     
    16371904        else { 
    16381905            /* go through the list and move the first get operation  
    1639                (if there is one) to the end */ 
     1906               (if there is one) to the end.  Note that the first 
     1907               operation must be a lock, so we can skip it */ 
    16401908             
    1641             curr_ptr = win_ptr->rma_ops_list->next; 
    1642             curr_ptr_ptr = &(win_ptr->rma_ops_list->next); 
     1909            curr_ptr = win_ptr->rma_ops_list_head->next; 
     1910            prevNextPtr = &(win_ptr->rma_ops_list_head->next); 
    16431911             
    16441912            *wait_for_rma_done_pkt = 1; 
     
    16461914            while (curr_ptr != NULL) { 
    16471915                if (curr_ptr->type == MPIDI_RMA_GET) { 
     1916                    /* Found a GET, move it to the end */ 
    16481917                    *wait_for_rma_done_pkt = 0; 
    1649                     *curr_ptr_ptr = curr_ptr->next; 
    1650                     tmp_ptr = curr_ptr; 
    1651                     while (curr_ptr->next != NULL) 
    1652                         curr_ptr = curr_ptr->next; 
    1653                     curr_ptr->next = tmp_ptr; 
    1654                     tmp_ptr->next = NULL; 
     1918                    win_ptr->rma_ops_list_tail->next = curr_ptr; 
     1919                    *prevNextPtr = curr_ptr->next; 
     1920                    curr_ptr->next = NULL; 
     1921                    win_ptr->rma_ops_list_tail = curr_ptr; 
    16551922                    break; 
    16561923                } 
    16571924                else { 
    1658                     curr_ptr_ptr = &(curr_ptr->next); 
    1659                     curr_ptr = curr_ptr->next; 
     1925                    prevNextPtr = &(curr_ptr->next); 
     1926                    curr_ptr    = curr_ptr->next; 
    16601927                } 
    16611928            } 
     
    16631930    } 
    16641931 
    1665     MPID_Comm_get_ptr( win_ptr->comm, comm_ptr ); 
     1932    comm_ptr = win_ptr->comm_ptr; 
    16661933 
    16671934    /* Ignore the first op in the list because it is a win_lock and do 
    16681935       the rest */ 
    16691936 
    1670     curr_ptr = win_ptr->rma_ops_list->next; 
     1937    /*  
     1938       This list has a head (lock) (but no tail (unlock)) that is not  
     1939       processed, so we must skip over that head  
     1940    */ 
     1941 
     1942    curr_ptr = win_ptr->rma_ops_list_head->next; 
    16711943    nops = 0; 
    16721944    while (curr_ptr != NULL) { 
     
    16741946        curr_ptr = curr_ptr->next; 
    16751947    } 
    1676  
    1677     MPIU_CHKLMEM_MALLOC(requests, MPID_Request **, nops*sizeof(MPID_Request*), 
    1678                         mpi_errno, "requests"); 
    1679     MPIU_CHKLMEM_MALLOC(dtype_infos, MPIDI_RMA_dtype_info *,  
    1680                         nops*sizeof(MPIDI_RMA_dtype_info), 
    1681                         mpi_errno, "dtype_infos"); 
    1682     MPIU_CHKLMEM_MALLOC(dataloops, void **, nops*sizeof(void*), 
    1683                         mpi_errno, "dataloops"); 
    1684  
    1685     for (i=0; i<nops; i++) 
    1686     { 
    1687         dataloops[i] = NULL; 
    1688     } 
    1689      
     1948     
     1949    MPIU_INSTR_DURATION_START(winunlock_issue); 
    16901950    i = 0; 
    1691     curr_ptr = win_ptr->rma_ops_list->next; 
     1951 
     1952    /* Remove the lock entry */ 
     1953    curr_ptr = win_ptr->rma_ops_list_head; 
     1954    tmpptr       = curr_ptr->next; 
     1955    win_ptr->rma_ops_list_head = tmpptr; 
     1956    MPIU_Free( curr_ptr ); 
     1957 
     1958    prevNextPtr = &win_ptr->rma_ops_list_head; 
     1959    curr_ptr    = win_ptr->rma_ops_list_head; 
    16921960    target_win_handle = win_ptr->all_win_handles[curr_ptr->target_rank]; 
    16931961    while (curr_ptr != NULL) 
     
    16961964           source_win_handle only on the last operation. Otherwise,  
    16971965           we pass MPI_WIN_NULL. */ 
    1698         if (i == nops - 1) 
     1966        /* Could also be curr_ptr->next == NULL */ 
     1967        if (/*i == nops - 1*/!curr_ptr->next) 
    16991968            source_win_handle = win_ptr->handle; 
    17001969        else  
    17011970            source_win_handle = MPI_WIN_NULL; 
    17021971         
     1972        curr_ptr->dataloop = 0; 
    17031973        switch (curr_ptr->type) 
    17041974        { 
     
    17071977            win_ptr->pt_rma_puts_accs[curr_ptr->target_rank]++; 
    17081978            mpi_errno = MPIDI_CH3I_Send_rma_msg(curr_ptr, win_ptr, 
    1709                          source_win_handle, target_win_handle, &dtype_infos[i], 
    1710                                                 &dataloops[i], &requests[i]); 
     1979                                source_win_handle, target_win_handle,  
     1980                                &curr_ptr->dtype_info, 
     1981                                &curr_ptr->dataloop, &curr_ptr->request); 
    17111982            if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
    17121983            break; 
     1984        case MPIDI_RMA_ACC_CONTIG: 
     1985            win_ptr->pt_rma_puts_accs[curr_ptr->target_rank]++; 
     1986            mpi_errno = MPIDI_CH3I_Send_contig_acc_msg(curr_ptr, win_ptr, 
     1987                                       source_win_handle, target_win_handle,  
     1988                                       &curr_ptr->request ); 
     1989            break; 
    17131990        case (MPIDI_RMA_GET): 
    17141991            mpi_errno = MPIDI_CH3I_Recv_rma_msg(curr_ptr, win_ptr, 
    1715                          source_win_handle, target_win_handle, &dtype_infos[i], 
    1716                                                 &dataloops[i], &requests[i]); 
     1992                         source_win_handle, target_win_handle,  
     1993                                &curr_ptr->dtype_info, 
     1994                                &curr_ptr->dataloop, &curr_ptr->request); 
    17171995            if (mpi_errno) { MPIU_ERR_POP(mpi_errno); } 
    17181996            break; 
     
    17211999        } 
    17222000        i++; 
    1723         curr_ptr = curr_ptr->next; 
    1724     } 
     2001        /* If the request is null, we can remove it immediately */ 
     2002        if (!curr_ptr->request) { 
     2003            if (curr_ptr->dataloop != NULL) { 
     2004                MPIU_Free(curr_ptr->dataloop); /* allocated in send_rma_msg or  
     2005                                                  recv_rma_msg */ 
     2006            } 
     2007            tmpptr       = curr_ptr->next; 
     2008            *prevNextPtr = tmpptr; 
     2009            MPIU_Free( curr_ptr ); 
     2010            curr_ptr     = tmpptr; 
     2011        } 
     2012        else  { 
     2013            curr_ptr    = curr_ptr->next; 
     2014            prevNextPtr = &curr_ptr->next; 
     2015        } 
     2016    } 
     2017    MPIU_INSTR_DURATION_END(winunlock_issue); 
    17252018     
    17262019    if (nops) 
     
    17292022         
    17302023        done = 1; 
     2024        MPIU_INSTR_DURATION_START(winunlock_complete); 
    17312025        MPID_Progress_start(&progress_state); 
    1732         while (nops) 
    1733         { 
    1734             for (i=0; i<nops; i++) 
    1735             { 
    1736                 if (requests[i] != NULL) 
    1737                 { 
    1738                     if (!MPID_Request_is_complete(requests[i])) 
    1739                     { 
    1740                         done = 0; 
    1741                         break; 
    1742                     } 
    1743                     else 
    1744                     { 
    1745                         mpi_errno = requests[i]->status.MPI_ERROR; 
     2026        while (win_ptr->rma_ops_list_head) { 
     2027            prevNextPtr = &win_ptr->rma_ops_list_head; 
     2028            curr_ptr    = win_ptr->rma_ops_list_head; 
     2029            do { 
     2030                if (MPID_Request_is_complete(curr_ptr->request)) { 
     2031                    /* Once we find a complete request, we complete 
     2032                       as many as possible until we find an incomplete 
     2033                       or null request */ 
     2034                    do { 
     2035                        mpi_errno = curr_ptr->request->status.MPI_ERROR; 
    17462036                        /* --BEGIN ERROR HANDLING-- */ 
    1747                         if (mpi_errno != MPI_SUCCESS) 
    1748                         { 
     2037                        if (mpi_errno != MPI_SUCCESS) { 
    17492038                            MPID_Progress_end(&progress_state); 
    17502039                            MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winRMAmessage"); 
    17512040                        } 
    17522041                        /* --END ERROR HANDLING-- */ 
    1753                         /* if origin datatype was a derived 
    1754                            datatype, it will get freed when the 
    1755                            request gets freed. */  
    1756                         MPID_Request_release(requests[i]); 
    1757                         requests[i] = NULL; 
     2042                        MPID_Request_release(curr_ptr->request); 
     2043                        if (curr_ptr->dataloop != NULL) { 
     2044                            MPIU_Free(curr_ptr->dataloop); /* allocated in send_rma_msg or  
     2045                                                              recv_rma_msg */ 
     2046                        } 
     2047                        /* We can remove and free this rma op element */ 
     2048                        tmpptr       = curr_ptr->next; 
     2049                        *prevNextPtr = tmpptr; 
     2050                        MPIU_Free( curr_ptr ); 
     2051                        curr_ptr     = tmpptr; 
    17582052                    } 
     2053                    while (curr_ptr && 
     2054                           MPID_Request_is_complete(curr_ptr->request)); 
     2055                    /* Once a request completes, we wait for another 
     2056                       operation to arrive rather than check the 
     2057                       rest of the requests.  */ 
     2058                    break; 
    17592059                } 
     2060                else { 
     2061                    prevNextPtr = &curr_ptr->next; 
     2062                    curr_ptr    = curr_ptr->next; 
     2063                    break; 
     2064                } 
     2065            } while (curr_ptr); 
     2066             
     2067            /* Wait for something to arrive*/ 
     2068            /* In some tests, this hung unless the test ensured that  
     2069               there was an incomplete request. */ 
     2070            curr_ptr = win_ptr->rma_ops_list_head; 
     2071            if (curr_ptr && !MPID_Request_is_complete(curr_ptr->request) ) { 
     2072                MPIU_INSTR_DURATION_START(winfence_block); 
     2073                mpi_errno = MPID_Progress_wait(&progress_state); 
     2074                /* --BEGIN ERROR HANDLING-- */ 
     2075                if (mpi_errno != MPI_SUCCESS) { 
     2076                    MPID_Progress_end(&progress_state); 
     2077                    MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winnoprogress"); 
     2078                } 
     2079                /* --END ERROR HANDLING-- */ 
     2080                MPIU_INSTR_DURATION_END(winfence_block); 
    17602081            } 
    1761          
    1762             if (done)  
    1763             { 
    1764                 break; 
    1765             } 
    1766          
    1767             mpi_errno = MPID_Progress_wait(&progress_state); 
    1768             /* --BEGIN ERROR HANDLING-- */ 
    1769             if (mpi_errno != MPI_SUCCESS) { 
    1770                 MPID_Progress_end(&progress_state); 
    1771                 MPIU_ERR_SETANDJUMP(mpi_errno,MPI_ERR_OTHER,"**winnoprogress"); 
    1772             } 
    1773             /* --END ERROR HANDLING-- */ 
    1774             done = 1; 
    1775         } 
     2082        } /* While list of rma operation is non-empty */ 
     2083             
    17762084        MPID_Progress_end(&progress_state); 
    17772085    }  
    17782086     
    1779     for (i=0; i<nops; i++) 
    1780     { 
    1781         if (dataloops[i] != NULL) 
    1782         { 
    1783             MPIU_Free(dataloops[i]); 
    1784         } 
    1785     } 
    1786      
    1787     /* free MPIDI_RMA_ops_list */ 
    1788     curr_ptr = win_ptr->rma_ops_list; 
    1789     while (curr_ptr != NULL) 
    1790     { 
    1791         next_ptr = curr_ptr->next; 
    1792         MPIU_Free(curr_ptr); 
    1793         curr_ptr = next_ptr; 
    1794     } 
    1795     win_ptr->rma_ops_list = NULL; 
     2087 
     2088    MPIU_Assert( !win_ptr->rma_ops_list_head ); 
     2089 
     2090    win_ptr->rma_ops_list_head = NULL; 
     2091    win_ptr->rma_ops_list_tail = NULL; 
    17962092 
    17972093 fn_exit: 
    1798     MPIU_CHKLMEM_FREEALL(); 
    17992094    MPIDI_RMA_FUNC_EXIT(MPID_STATE_MPIDI_CH3I_DO_PASSIVE_TARGET_RMA); 
    18002095    return mpi_errno; 
     
    18302125    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEND_LOCK_PUT_OR_ACC); 
    18312126 
    1832     lock_type = win_ptr->rma_ops_list->lock_type; 
    1833  
    1834     rma_op = win_ptr->rma_ops_list->next; 
     2127    lock_type = win_ptr->rma_ops_list_head->lock_type; 
     2128 
     2129    rma_op = win_ptr->rma_ops_list_head->next; 
    18352130 
    18362131    win_ptr->pt_rma_puts_accs[rma_op->target_rank]++; 
     
    18722167        iov[0].MPID_IOV_LEN = sizeof(*lock_accum_unlock_pkt); 
    18732168    } 
    1874  
    1875     MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     2169    else if (rma_op->type == MPIDI_RMA_ACC_CONTIG) { 
     2170        MPIDI_Pkt_init(lock_accum_unlock_pkt, MPIDI_CH3_PKT_LOCK_ACCUM_UNLOCK); 
     2171        lock_accum_unlock_pkt->target_win_handle =  
     2172            win_ptr->all_win_handles[rma_op->target_rank]; 
     2173        lock_accum_unlock_pkt->source_win_handle = win_ptr->handle; 
     2174        lock_accum_unlock_pkt->lock_type = lock_type; 
     2175 
     2176        lock_accum_unlock_pkt->addr =  
     2177            (char *) win_ptr->base_addrs[rma_op->target_rank] + 
     2178            win_ptr->disp_units[rma_op->target_rank] * rma_op->target_disp; 
     2179         
     2180        lock_accum_unlock_pkt->count = rma_op->target_count; 
     2181        lock_accum_unlock_pkt->datatype = rma_op->target_datatype; 
     2182        lock_accum_unlock_pkt->op = rma_op->op; 
     2183 
     2184        iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST) lock_accum_unlock_pkt; 
     2185        iov[0].MPID_IOV_LEN = sizeof(*lock_accum_unlock_pkt); 
     2186    } 
     2187    else { 
     2188        printf( "expected short accumulate...\n" ); 
     2189        /* */ 
     2190    } 
     2191 
     2192    comm_ptr = win_ptr->comm_ptr; 
    18762193    MPIDI_Comm_get_vc_set_active(comm_ptr, rma_op->target_rank, &vc); 
    18772194 
     
    19752292 
    19762293    /* free MPIDI_RMA_ops_list */ 
    1977     MPIU_Free(win_ptr->rma_ops_list->next); 
    1978     MPIU_Free(win_ptr->rma_ops_list); 
    1979     win_ptr->rma_ops_list = NULL; 
     2294    MPIU_Free(win_ptr->rma_ops_list_head->next); 
     2295    MPIU_Free(win_ptr->rma_ops_list_head); 
     2296    win_ptr->rma_ops_list_head = NULL; 
     2297    win_ptr->rma_ops_list_tail = NULL; 
    19802298 
    19812299 fn_fail: 
     
    20052323    MPIDI_RMA_FUNC_ENTER(MPID_STATE_MPIDI_CH3I_SEND_LOCK_GET); 
    20062324 
    2007     lock_type = win_ptr->rma_ops_list->lock_type; 
    2008  
    2009     rma_op = win_ptr->rma_ops_list->next; 
     2325    lock_type = win_ptr->rma_ops_list_head->lock_type; 
     2326 
     2327    rma_op = win_ptr->rma_ops_list_head->next; 
    20102328 
    20112329    /* create a request, store the origin buf, cnt, datatype in it, 
     
    20492367    lock_get_unlock_pkt->request_handle = rreq->handle; 
    20502368 
    2051     MPID_Comm_get_ptr(win_ptr->comm, comm_ptr); 
     2369    comm_ptr = win_ptr->comm_ptr; 
    20522370    MPIDI_Comm_get_vc_set_active(comm_ptr, rma_op->target_rank, &vc); 
    20532371 
     
    20962414 
    20972415    /* free MPIDI_RMA_ops_list */ 
    2098     MPIU_Free(win_ptr->rma_ops_list->next); 
    2099     MPIU_Free(win_ptr->rma_ops_list); 
    2100     win_ptr->rma_ops_list = NULL; 
     2416    MPIU_Free(win_ptr->rma_ops_list_head->next); 
     2417    MPIU_Free(win_ptr->rma_ops_list_head); 
     2418    win_ptr->rma_ops_list_head = NULL; 
     2419    win_ptr->rma_ops_list_tail = NULL; 
     2420 
    21012421 
    21022422 fn_fail: 
     
    22402560            mpi_errno = MPIDI_CH3_ReqHandler_PutAccumRespComplete(vc, req, &complete); 
    22412561            if (mpi_errno) MPIU_ERR_POP(mpi_errno); 
    2242              
    22432562            if (complete) 
    22442563            { 
     
    24682787     
    24692788    MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"received accumulate pkt"); 
    2470      
     2789 
     2790    MPIU_INSTR_DURATION_START(rmapkt_acc); 
    24712791    data_len = *buflen - sizeof(MPIDI_CH3_Pkt_t); 
    24722792    data_buf = (char *)pkt + sizeof(MPIDI_CH3_Pkt_t); 
     
    24852805    if (predefined) 
    24862806    { 
     2807        MPIU_INSTR_DURATION_START(rmapkt_acc_predef); 
    24872808        MPIDI_Request_set_type(req, MPIDI_REQUEST_TYPE_ACCUM_RESP); 
    24882809        req->dev.datatype = accum_pkt->datatype; 
     
    25312852                { 
    25322853                    *rreqp = NULL; 
     2854                    MPIU_INSTR_DURATION_END(rmapkt_acc_predef); 
    25332855                    goto fn_exit; 
    25342856                } 
    25352857            } 
     2858            MPIU_INSTR_DURATION_END(rmapkt_acc_predef); 
    25362859        } 
    25372860    } 
     
    25912914 
    25922915 fn_exit: 
     2916    MPIU_INSTR_DURATION_END(rmapkt_acc); 
    25932917    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_PKTHANDLER_ACCUMULATE); 
     2918    return mpi_errno; 
     2919 fn_fail: 
     2920    goto fn_exit; 
     2921 
     2922} 
     2923 
     2924/* Special accumulate for short data items entirely within the packet */ 
     2925#undef FUNCNAME 
     2926#define FUNCNAME MPIDI_CH3_PktHandler_Accumulate_Immed 
     2927#undef FCNAME 
     2928#define FCNAME MPIDI_QUOTE(FUNCNAME) 
     2929int MPIDI_CH3_PktHandler_Accumulate_Immed( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt, 
     2930                                           MPIDI_msg_sz_t *buflen,  
     2931                                           MPID_Request **rreqp ) 
     2932{ 
     2933    MPIDI_CH3_Pkt_accum_immed_t * accum_pkt = &pkt->accum_immed; 
     2934    MPID_Win *win_ptr; 
     2935    MPI_Aint extent; 
     2936    int mpi_errno = MPI_SUCCESS; 
     2937    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_PKTHANDLER_ACCUMULATE_IMMED); 
     2938     
     2939    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_PKTHANDLER_ACCUMULATE_IMMED); 
     2940 
     2941    MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"received accumulate immedidate pkt"); 
     2942 
     2943    MPIU_INSTR_DURATION_START(rmapkt_acc_immed); 
     2944 
     2945    /* return the number of bytes processed in this function */ 
     2946    /* data_len == 0 (all within packet) */ 
     2947    *buflen = sizeof(MPIDI_CH3_Pkt_t); 
     2948    *rreqp  = NULL; 
     2949 
     2950    MPID_Datatype_get_extent_macro(accum_pkt->datatype, extent);  
     2951     
     2952    /* size == 0 should never happen */ 
     2953    if (accum_pkt->count == 0 || extent == 0) { 
     2954        ; 
     2955    } 
     2956    else { 
     2957        /* Data is already present */ 
     2958        if (accum_pkt->op == MPI_REPLACE) { 
     2959            /* no datatypes required */ 
     2960            int len = accum_pkt->count * extent; 
     2961            /* FIXME: use immediate copy because this is short */ 
     2962            MPIUI_Memcpy( accum_pkt->addr, accum_pkt->data, len ); 
     2963        } 
     2964        else { 
     2965            if (HANDLE_GET_KIND(accum_pkt->op) == HANDLE_KIND_BUILTIN) { 
     2966                MPI_User_function *uop; 
     2967                /* get the function by indexing into the op table */ 
     2968                uop = MPIR_Op_table[((accum_pkt->op)&0xf) - 1]; 
     2969                (*uop)(accum_pkt->data, accum_pkt->addr, 
     2970                       &(accum_pkt->count), &(accum_pkt->datatype)); 
     2971            } 
     2972            else { 
     2973                MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OP, "**opnotpredefined", 
     2974                                     "**opnotpredefined %d", accum_pkt->op ); 
     2975            } 
     2976        } 
     2977 
     2978        /* There are additional steps to take if this is a passive  
     2979           target RMA or the last operation from the source */ 
     2980         
     2981        /* Here is the code executed in PutAccumRespComplete after the 
     2982           accumulation operation */ 
     2983        MPID_Win_get_ptr(accum_pkt->target_win_handle, win_ptr); 
     2984         
     2985        /* if passive target RMA, increment counter */ 
     2986        if (win_ptr->current_lock_type != MPID_LOCK_NONE) 
     2987            win_ptr->my_pt_rma_puts_accs++; 
     2988         
     2989        if (accum_pkt->source_win_handle != MPI_WIN_NULL) { 
     2990            /* Last RMA operation from source. If active 
     2991               target RMA, decrement window counter. If 
     2992               passive target RMA, release lock on window and 
     2993               grant next lock in the lock queue if there is 
     2994               any. If it's a shared lock or a lock-put-unlock 
     2995               type of optimization, we also need to send an 
     2996               ack to the source. */  
     2997            if (win_ptr->current_lock_type == MPID_LOCK_NONE) { 
     2998                /* FIXME: MT: this has to be done atomically */ 
     2999                win_ptr->my_counter -= 1; 
     3000                MPIDI_CH3_Progress_signal_completion(); 
     3001            } 
     3002            else { 
     3003                if ((win_ptr->current_lock_type == MPI_LOCK_SHARED) || 
     3004                    (/*rreq->dev.single_op_opt*/ 0 == 1)) { 
     3005                    mpi_errno = MPIDI_CH3I_Send_pt_rma_done_pkt(vc,  
     3006                                        accum_pkt->source_win_handle); 
     3007                    if (mpi_errno) { 
     3008                            MPIU_ERR_POP(mpi_errno); 
     3009                    } 
     3010                } 
     3011                mpi_errno = MPIDI_CH3I_Release_lock(win_ptr); 
     3012            } 
     3013        } 
     3014 
     3015        goto fn_exit; 
     3016    } 
     3017 
     3018 fn_exit: 
     3019    MPIU_INSTR_DURATION_END(rmapkt_acc_immed); 
     3020    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_PKTHANDLER_ACCUMULATE_IMMED); 
    25943021    return mpi_errno; 
    25953022 fn_fail: 
     
    26323059        /* FIXME: MT: This may need to be done atomically. */ 
    26333060         
     3061        /* FIXME: Since we need to add to the tail of the list, 
     3062           we should maintain a tail pointer rather than traversing the  
     3063           list each time to find the tail. */ 
    26343064        curr_ptr = (MPIDI_Win_lock_queue *) win_ptr->lock_queue; 
    26353065        prev_ptr = curr_ptr; 
     
    26403070        } 
    26413071         
     3072        MPIU_INSTR_DURATION_START(lockqueue_alloc); 
    26423073        new_ptr = (MPIDI_Win_lock_queue *) MPIU_Malloc(sizeof(MPIDI_Win_lock_queue)); 
     3074        MPIU_INSTR_DURATION_END(lockqueue_alloc); 
    26433075        if (!new_ptr) { 
    26443076            MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**nomem","**nomem %s", 
     
    27143146        MPIDI_Win_lock_queue *curr_ptr, *prev_ptr, *new_ptr; 
    27153147         
     3148        MPIU_INSTR_DURATION_START(lockqueue_alloc); 
    27163149        new_ptr = (MPIDI_Win_lock_queue *) MPIU_Malloc(sizeof(MPIDI_Win_lock_queue)); 
     3150        MPIU_INSTR_DURATION_END(lockqueue_alloc); 
    27173151        if (!new_ptr) { 
    27183152            MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**nomem","**nomem %s", 
     
    28753309         
    28763310        /* FIXME: MT: This may need to be done atomically. */ 
    2877          
     3311 
    28783312        curr_ptr = (MPIDI_Win_lock_queue *) win_ptr->lock_queue; 
    28793313        prev_ptr = curr_ptr; 
     
    28843318        } 
    28853319         
     3320        MPIU_INSTR_DURATION_START(lockqueue_alloc); 
    28863321        new_ptr = (MPIDI_Win_lock_queue *) MPIU_Malloc(sizeof(MPIDI_Win_lock_queue)); 
     3322        MPIU_INSTR_DURATION_END(lockqueue_alloc); 
    28873323        if (!new_ptr) { 
    28883324            MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**nomem","**nomem %s", 
     
    29623398    /* queue the information */ 
    29633399     
     3400    MPIU_INSTR_DURATION_START(lockqueue_alloc); 
    29643401    new_ptr = (MPIDI_Win_lock_queue *) MPIU_Malloc(sizeof(MPIDI_Win_lock_queue)); 
     3402    MPIU_INSTR_DURATION_END(lockqueue_alloc); 
    29653403    if (!new_ptr) { 
    29663404        MPIU_ERR_SETANDJUMP1(mpi_errno,MPI_ERR_OTHER,"**nomem","**nomem %s", 
     
    32203658    return MPI_SUCCESS; 
    32213659} 
     3660int MPIDI_CH3_PktPrint_Accum_Immed( FILE *fp, MPIDI_CH3_Pkt_t *pkt ) 
     3661{ 
     3662    MPIU_DBG_PRINTF((" type ......... MPIDI_CH3_PKT_ACCUM_IMMED\n")); 
     3663    MPIU_DBG_PRINTF((" addr ......... %p\n", pkt->accum_immed.addr)); 
     3664    MPIU_DBG_PRINTF((" count ........ %d\n", pkt->accum_immed.count)); 
     3665    MPIU_DBG_PRINTF((" datatype ..... 0x%08X\n", pkt->accum_immed.datatype)); 
     3666    MPIU_DBG_PRINTF((" op ........... 0x%08X\n", pkt->accum_immed.op)); 
     3667    MPIU_DBG_PRINTF((" target ....... 0x%08X\n", pkt->accum_immed.target_win_handle)); 
     3668    MPIU_DBG_PRINTF((" source ....... 0x%08X\n", pkt->accum_immed.source_win_handle)); 
     3669    /*MPIU_DBG_PRINTF((" win_ptr ...... 0x%08X\n", pkt->accum.win_ptr));*/ 
     3670    fflush(stdout); 
     3671    return MPI_SUCCESS; 
     3672} 
    32223673int MPIDI_CH3_PktPrint_Lock( FILE *fp, MPIDI_CH3_Pkt_t *pkt ) 
    32233674{ 
  • src/util/instrm/Makefile.sm

    r6a1cbd r3608ca  
    1 lib${MPILIBNAME}_a_SOURCES = states.c 
     1lib${MPILIBNAME}_a_SOURCES = states.c instr.c 
    22INCLUDES = -I../../include -I${top_srcdir}/src/include 
Note: See TracChangeset for help on using the changeset viewer.