Index: ompi/mpi/c/alltoallv.c =================================================================== --- ompi/mpi/c/alltoallv.c (revision 21956) +++ ompi/mpi/c/alltoallv.c (working copy) @@ -106,11 +106,13 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_alltoallv); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_alltoallv(sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm, comm->c_coll.coll_alltoallv_module); + ompi_comm_call_down(comm,ompi_mqs_comm_alltoallv); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/bcast.c =================================================================== --- ompi/mpi/c/bcast.c (revision 21956) +++ ompi/mpi/c/bcast.c (working copy) @@ -105,9 +105,11 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_bcast); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_bcast(buffer, count, datatype, root, comm, comm->c_coll.coll_bcast_module); + ompi_comm_call_down(comm,ompi_mqs_comm_bcast); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/allgather.c =================================================================== --- ompi/mpi/c/allgather.c (revision 21956) +++ ompi/mpi/c/allgather.c (working copy) @@ -99,11 +99,13 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_allgather); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, comm->c_coll.coll_allgather_module); + ompi_comm_call_down(comm,ompi_mqs_comm_allgather); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/scatter.c =================================================================== --- ompi/mpi/c/scatter.c (revision 21956) +++ ompi/mpi/c/scatter.c (working copy) @@ -156,10 +156,12 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_scatter); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, comm->c_coll.coll_scatter_module); + ompi_comm_call_down(comm,ompi_mqs_comm_scatterv); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/gather.c =================================================================== --- ompi/mpi/c/gather.c (revision 21956) +++ ompi/mpi/c/gather.c (working copy) @@ -173,10 +173,12 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_gather); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, comm->c_coll.coll_gather_module); + ompi_comm_call_down(comm,ompi_mqs_comm_gather); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/allgatherv.c =================================================================== --- ompi/mpi/c/allgatherv.c (revision 21956) +++ ompi/mpi/c/allgatherv.c (working copy) @@ -119,12 +119,14 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_allgatherv); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm, comm->c_coll.coll_allgatherv_module); + ompi_comm_call_down(comm,ompi_mqs_comm_allgatherv); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/reduce_scatter.c =================================================================== --- ompi/mpi/c/reduce_scatter.c (revision 21956) +++ ompi/mpi/c/reduce_scatter.c (working copy) @@ -123,6 +123,7 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_reduce_scatter); /* Invoke the coll component to perform the back-end operation */ OBJ_RETAIN(op); @@ -130,5 +131,6 @@ datatype, op, comm, comm->c_coll.coll_reduce_scatter_module); OBJ_RELEASE(op); + ompi_comm_call_down(comm,ompi_mqs_comm_reduce_scatter); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/scan.c =================================================================== --- ompi/mpi/c/scan.c (revision 21956) +++ ompi/mpi/c/scan.c (working copy) @@ -95,6 +95,7 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_scan); /* Call the coll component to actually perform the allgather */ OBJ_RETAIN(op); @@ -102,5 +103,6 @@ datatype, op, comm, comm->c_coll.coll_scan_module); OBJ_RELEASE(op); + ompi_comm_call_down(comm,ompi_mqs_comm_scan); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/scatterv.c =================================================================== --- ompi/mpi/c/scatterv.c (revision 21956) +++ ompi/mpi/c/scatterv.c (working copy) @@ -185,10 +185,12 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_scatterv); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, comm->c_coll.coll_scatterv_module); + ompi_comm_call_down(comm,ompi_mqs_comm_scatterv); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/allreduce.c =================================================================== --- ompi/mpi/c/allreduce.c (revision 21956) +++ ompi/mpi/c/allreduce.c (working copy) @@ -99,6 +99,7 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_allreduce); /* Invoke the coll component to perform the back-end operation */ OBJ_RETAIN(op); @@ -106,6 +107,7 @@ datatype, op, comm, comm->c_coll.coll_allreduce_module); OBJ_RELEASE(op); + ompi_comm_call_down(comm,ompi_mqs_comm_allreduce); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/alltoall.c =================================================================== --- ompi/mpi/c/alltoall.c (revision 21956) +++ ompi/mpi/c/alltoall.c (working copy) @@ -82,11 +82,13 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_alltoall); /* Invoke the coll component to perform the back-end operation */ err = comm->c_coll.coll_alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, comm->c_coll.coll_alltoall_module); + ompi_comm_call_down(comm,ompi_mqs_comm_alltoall); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/reduce.c =================================================================== --- ompi/mpi/c/reduce.c (revision 21956) +++ ompi/mpi/c/reduce.c (working copy) @@ -126,6 +126,7 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_reduce); /* Invoke the coll component to perform the back-end operation */ OBJ_RETAIN(op); @@ -133,5 +134,6 @@ datatype, op, root, comm, comm->c_coll.coll_reduce_module); OBJ_RELEASE(op); + ompi_comm_call_down(comm,ompi_mqs_comm_reduce); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/mpi/c/barrier.c =================================================================== --- ompi/mpi/c/barrier.c (revision 21956) +++ ompi/mpi/c/barrier.c (working copy) @@ -54,6 +54,8 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_barrier); + /* Intracommunicators: Only invoke the back-end coll module barrier function if there's more than one process in the communicator */ @@ -70,6 +72,7 @@ err = comm->c_coll.coll_barrier(comm, comm->c_coll.coll_barrier_module); } + ompi_comm_call_down(comm,ompi_mqs_comm_barrier); /* All done */ OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); Index: ompi/mpi/c/gatherv.c =================================================================== --- ompi/mpi/c/gatherv.c (revision 21956) +++ ompi/mpi/c/gatherv.c (working copy) @@ -187,11 +187,13 @@ OPAL_CR_ENTER_LIBRARY(); + ompi_comm_call_up(comm,ompi_mqs_comm_gatherv); /* Invoke the coll component to perform the back-end operation */ - + err = comm->c_coll.coll_gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm, comm->c_coll.coll_gatherv_module); + ompi_comm_call_down(comm,ompi_mqs_comm_gatherv); OMPI_ERRHANDLER_RETURN(err, comm, err, FUNC_NAME); } Index: ompi/communicator/communicator.h =================================================================== --- ompi/communicator/communicator.h (revision 21956) +++ ompi/communicator/communicator.h (working copy) @@ -137,6 +137,14 @@ int c_f_to_c_index; + /* There values match the enum in mpi_interface.h, we increase "up" every time a collective + * function is called and increase "down" every time the library returns, comm_call_active + * is used to ensure we only change the counters for the top-level function if one collective + * is implemented in terms of another */ + int c_call_counters_up[15]; + int c_call_counters_down[15]; + int c_comm_call_active; + #ifdef OMPI_WANT_PERUSE /* * Place holder for the PERUSE events. @@ -233,8 +241,40 @@ OMPI_DECLSPEC extern ompi_predefined_communicator_t ompi_mpi_comm_self; OMPI_DECLSPEC extern ompi_predefined_communicator_t ompi_mpi_comm_null; +/* 14 of them */ +typedef enum + { + ompi_mqs_comm_barrier, + ompi_mqs_comm_bcast, + ompi_mqs_comm_allgather, + ompi_mqs_comm_allgatherv, + ompi_mqs_comm_allreduce, + ompi_mqs_comm_alltoall, + ompi_mqs_comm_alltoallv, + ompi_mqs_comm_reduce_scatter, + ompi_mqs_comm_reduce, + ompi_mqs_comm_gather, + ompi_mqs_comm_gatherv, + ompi_mqs_comm_scan, + ompi_mqs_comm_scatter, + ompi_mqs_comm_scatterv + } ompi_mqs_comm_class; +static inline void ompi_comm_call_up (ompi_communicator_t* comm, ompi_mqs_comm_class op) +{ + if ( ! comm->c_comm_call_active++ ) { + comm->c_call_counters_up[op]++; + } +} +static inline void ompi_comm_call_down (ompi_communicator_t* comm, ompi_mqs_comm_class op) +{ + if ( ! --comm->c_comm_call_active ) { + comm->c_call_counters_down[op]++; + } +} + + /** * Is this a valid communicator? This is a complicated question. * :-) @@ -330,6 +370,7 @@ } + /** * Initialise MPI_COMM_WORLD and MPI_COMM_SELF */ Index: ompi/communicator/comm.c =================================================================== --- ompi/communicator/comm.c (revision 21956) +++ ompi/communicator/comm.c (working copy) @@ -98,7 +98,7 @@ { ompi_communicator_t *newcomm=NULL; - int ret; + int ret, i; /* ompi_comm_allocate */ newcomm = OBJ_NEW(ompi_communicator_t); @@ -106,7 +106,14 @@ newcomm->c_cube_dim = opal_cube_dim(local_size); newcomm->c_id_available = MPI_UNDEFINED; newcomm->c_id_start_index = MPI_UNDEFINED; + + newcomm->c_comm_call_active = 0; + for ( i = 0 ; i < 14 ; i++ ) { + newcomm->c_call_counters_up[i] = 0; + newcomm->c_call_counters_down[i] = 0; + } + if (NULL == local_group) { /* determine how the list of local_rank can be stored most efficiently */ Index: ompi/debuggers/ompi_msgq_dll.c =================================================================== --- ompi/debuggers/ompi_msgq_dll.c (revision 21956) +++ ompi/debuggers/ompi_msgq_dll.c (working copy) @@ -367,11 +367,12 @@ int mqs_image_has_queues (mqs_image *image, char **message) { mpi_image_info * i_info = (mpi_image_info *)mqs_get_image_info (image); - + int res; + i_info->extra = NULL; /* Default failure message ! */ - *message = "The symbols and types in the Open MPI library used by TotalView\n" + *message = "The symbols and types in the Open MPI library\n" "to extract the message queues are not as expected in\n" "the image '%s'\n" "No message queue display is possible.\n" @@ -393,7 +394,10 @@ } /* Fill in the type information */ - return ompi_fill_in_type_info(image, message); + res = ompi_fill_in_type_info(image); + if ( res == mqs_ok ) + *message = NULL; + return res; } /* mqs_image_has_queues */ /*********************************************************************** @@ -1319,6 +1323,35 @@ mqs_free (info); } /* mqs_destroy_image_info */ + +int mqs_get_comm_coll_state (mqs_process *proc, int op, int *in, int *curr) +{ + mpi_process_info *p_info = (mpi_process_info *)mqs_get_process_info (proc); + mpi_process_info_extra *extra = (mpi_process_info_extra*) p_info->extra; + mqs_image * image = mqs_get_image (proc); + mpi_image_info *i_info = (mpi_image_info *)mqs_get_image_info (image); + + mqs_taddr_t comm_ptr = extra->current_communicator->comm_ptr; + int out; + + + if ( op >= 14 ) + return mqs_no_information; + + *in = ompi_fetch_int( proc, + comm_ptr + i_info->ompi_communicator_t.offset.c_call_counters_up + ( op * sizeof(int)), + p_info ); + + out = ompi_fetch_int( proc, + comm_ptr + i_info->ompi_communicator_t.offset.c_call_counters_down + ( op * sizeof(int)), + p_info ); + + *curr = ( *in == out ? 0 : 1); + + return mqs_ok; +} + + /***********************************************************************/ /* Convert an error code into a printable string */ char * mqs_dll_error_string (int errcode) Index: ompi/debuggers/ompi_common_dll.c =================================================================== --- ompi/debuggers/ompi_common_dll.c (revision 21956) +++ ompi/debuggers/ompi_common_dll.c (working copy) @@ -76,7 +76,7 @@ * basic type for the requests as they hold all the information we * need to export to the debugger. */ -int ompi_fill_in_type_info(mqs_image *image, char **message) +int ompi_fill_in_type_info(mqs_image *image) { char* missing_in_action; mpi_image_info * i_info = (mpi_image_info *)mqs_get_image_info (image); @@ -330,7 +330,12 @@ qh_type, ompi_communicator_t, c_topo_comm); ompi_field_offset(i_info->ompi_communicator_t.offset.c_keyhash, qh_type, ompi_communicator_t, c_keyhash); + ompi_field_offset(i_info->ompi_communicator_t.offset.c_call_counters_up, + qh_type, ompi_communicator_t, c_call_counters_up); + ompi_field_offset(i_info->ompi_communicator_t.offset.c_call_counters_down, + qh_type, ompi_communicator_t, c_call_counters_down); } +#if 0 { mqs_type* qh_type = mqs_find_type( image, "mca_topo_base_comm_1_0_0_t", mqs_lang_c ); if( !qh_type ) { @@ -348,6 +353,7 @@ ompi_field_offset(i_info->ompi_mca_topo_base_comm_1_0_0_t.offset.mtc_reorder, qh_type, mca_topo_base_comm_1_0_0_t, mtc_reorder); } +#endif { mqs_type* qh_type = mqs_find_type( image, "ompi_group_t", mqs_lang_c ); if( !qh_type ) { @@ -400,7 +406,6 @@ } /* All the types are here. Let's succesfully return. */ - *message = NULL; return mqs_ok; type_missing: @@ -409,7 +414,6 @@ * unable to extract the information we need from the pointers. We * did our best but here we're at our limit. Give up! */ - *message = missing_in_action; printf( "The following type is missing %s\n", missing_in_action ); return err_missing_type; } Index: ompi/debuggers/msgq_interface.h =================================================================== --- ompi/debuggers/msgq_interface.h (revision 21956) +++ ompi/debuggers/msgq_interface.h (working copy) @@ -691,6 +691,8 @@ extern int mqs_set_process_identity (mqs_process *, int); #endif +OMPI_DECLSPEC extern int mqs_get_comm_coll_state (mqs_process *, int, int *, int *); + END_C_DECLS #endif /* defined (_MPI_INTERFACE_INCLUDED) */ Index: ompi/debuggers/ompi_common_dll_defs.h =================================================================== --- ompi/debuggers/ompi_common_dll_defs.h (revision 21956) +++ ompi/debuggers/ompi_common_dll_defs.h (working copy) @@ -199,6 +199,8 @@ int c_f_to_c_index; int c_topo_comm; int c_keyhash; + int c_call_counters_up; + int c_call_counters_down; } offset; } ompi_communicator_t; /* base topology information in a communicator */ @@ -282,7 +284,7 @@ extern const mqs_basic_callbacks *mqs_basic_entrypoints; /* OMPI-specific functions */ -int ompi_fill_in_type_info(mqs_image *image, char **message); +int ompi_fill_in_type_info(mqs_image *image); /* Fetch a pointer from the process */ mqs_taddr_t ompi_fetch_pointer(mqs_process *proc, mqs_taddr_t addr,