Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
authorMartin Quinson <martin.quinson@loria.fr>
Fri, 20 May 2016 13:42:08 +0000 (15:42 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Fri, 20 May 2016 13:42:08 +0000 (15:42 +0200)
25 files changed:
CMakeLists.txt
doc/doxygen/options.doc
include/smpi/mpi.h
include/smpi/smpi.h
include/smpi/smpi_extended_traces.h [new file with mode: 0644]
include/smpi/smpi_extended_traces_fortran.h [new file with mode: 0644]
src/instr/instr_paje_header.cpp
src/instr/instr_paje_trace.cpp
src/instr/instr_private.h
src/instr/instr_smpi.h [new file with mode: 0644]
src/instr/instr_trace.cpp
src/simgrid/sg_config.cpp
src/smpi/instr_smpi.cpp
src/smpi/private.h
src/smpi/private.hpp [new file with mode: 0644]
src/smpi/smpi_bench.cpp
src/smpi/smpi_global.cpp
src/smpi/smpicc.in
src/smpi/smpiff.in
tools/cmake/DefinePackages.cmake
tools/cmake/MakeLib.cmake
tools/cmake/Modules/FindPAPI.cmake [new file with mode: 0644]
tools/cmake/Option.cmake
tools/cmake/src/internal_config.h.in
tools/smpi/generate_smpi_defines.pl [new file with mode: 0755]

index b46a981..579a485 100644 (file)
@@ -217,6 +217,13 @@ endif()
 if(WIN32)
   set(Boost_USE_STATIC_LIBS 1)
 endif()
+set(HAVE_PAPI 0)
+if(enable_smpi_papi)
+  include(FindPAPI)
+  if (NOT HAVE_PAPI)
+    message(FATAL_ERROR "Cannot find PAPI. Please install it (apt-get install papi-tools libpapi-dev) or disable PAPI bindings.")
+  endif()
+endif()
 
 find_package(Boost 1.48)
 if(Boost_FOUND)
@@ -962,6 +969,7 @@ message("        Compile Smpi ................: ${HAVE_SMPI}")
 message("          Smpi fortran ..............: ${SMPI_FORTRAN}")
 message("          MPICH3 testsuite ..........: ${enable_smpi_MPICH3_testsuite}")
 message("          Privatization .............: ${HAVE_PRIVATIZATION}")
+message("          PAPI support...............: ${HAVE_PAPI}")
 message("        Compile Boost.Context support: ${HAVE_BOOST_CONTEXTS}")
 message("")
 message("        Maintainer mode .............: ${enable_maintainer_mode}")
index b64faef..f25de99 100644 (file)
@@ -762,6 +762,33 @@ computation.
     you should check the SMPI_SAMPLE macros, documented in the chapter
     \ref SMPI_adapting_speed.
 
+\subsection options_model_smpi_adj_file smpi/comp-adjustment-file: Slow-down or speed-up parts of your code.
+
+This option allows you to pass a file that contains two columns: The first column
+defines the section that will be subject to a speedup; the second column is the speedup.
+
+For instance:
+
+\verbatim
+"start:stop","ratio"
+"exchange_1.f:30:exchange_1.f:130",1.18244559422142
+\endverbatim
+
+The first line is the header - you must include it.
+The following line means that the code between two consecutive MPI calls on
+line 30 in exchange_1.f and line 130 in exchange_1.f should receive a speedup
+of 1.18244559422142. The value for the second column is therefore a speedup, if it is
+larger than 1 and a slow-down if it is smaller than 1. Nothing will be changed if it is
+equal to 1.
+
+Of course, you can set any arbitrary filenames you want (so the start and end don't have to be
+in the same file), but be aware that this mechanism only supports \i consecutive calls!
+
+\note
+    Please note that you must pass the \b -trace-call-location flag to smpicc
+    or smpiff, respectively! This flag activates some macro definitions in our
+    mpi.h / mpi.f files that help with obtaining the call location.
+
 \subsection options_model_smpi_bw_factor smpi/bw-factor: Bandwidth factors
 
 The possible throughput of network links is often dependent on the
@@ -1118,6 +1145,7 @@ silently overflow on other parts of the memory.
 - \c smpi/async-small-thresh: \ref options_model_network_asyncsend
 - \c smpi/bw-factor: \ref options_model_smpi_bw_factor
 - \c smpi/coll-selector: \ref options_model_smpi_collectives
+- \c smpi/comp-adjustment-file: \ref options_model_smpi_adj_file
 - \c smpi/cpu-threshold: \ref options_smpi_bench
 - \c smpi/display-timing: \ref options_smpi_timing
 - \c smpi/lat-factor: \ref options_model_smpi_lat_factor
index 2cb6aca..a5474a6 100644 (file)
@@ -25,4 +25,9 @@
 #define assert(x) MC_assert(x)
 #endif
 
+#if TRACE_CALL_LOCATION
+#include "src/instr/instr_smpi.h"
+#include "smpi_extended_traces.h"
+#endif
+
 #endif
index 11afb63..d392f25 100644 (file)
@@ -14,6 +14,7 @@
 #include <xbt/misc.h>
 #include <xbt/function_types.h>
 
+#include "src/instr/instr_smpi.h"
 
 #ifdef _WIN32
 #define MPI_CALL(type,name,args) \
@@ -811,6 +812,12 @@ XBT_PUBLIC(unsigned long long) smpi_rastro_timestamp (void);
 XBT_PUBLIC(void) smpi_sample_1(int global, const char *file, int line, int iters, double threshold);
 XBT_PUBLIC(int) smpi_sample_2(int global, const char *file, int line);
 XBT_PUBLIC(void) smpi_sample_3(int global, const char *file, int line);
+XBT_PUBLIC(void) smpi_trace_set_call_location(const char *file, int line);
+/** Fortran binding **/
+XBT_PUBLIC(void) smpi_trace_set_call_location_(const char *file, int* line);
+/** Fortran binding + -fsecond-underscore **/
+XBT_PUBLIC(void) smpi_trace_set_call_location__(const char *file, int* line);
+XBT_PUBLIC(smpi_trace_call_location_t*) smpi_process_get_call_location(void);
 
 #define SMPI_SAMPLE_LOCAL(iters,thres) for(smpi_sample_1(0, __FILE__, __LINE__, iters, thres); \
                                            smpi_sample_2(0, __FILE__, __LINE__);      \
@@ -909,5 +916,6 @@ if(!name) {                                         \
 
 #define SMPI_VARGET_STATIC(name) name[smpi_process_index()]
 
+
 SG_END_DECL()
 #endif
diff --git a/include/smpi/smpi_extended_traces.h b/include/smpi/smpi_extended_traces.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/include/smpi/smpi_extended_traces_fortran.h b/include/smpi/smpi_extended_traces_fortran.h
new file mode 100644 (file)
index 0000000..3b2904f
--- /dev/null
@@ -0,0 +1,246 @@
+! This file has been automatically generated by the script
+! in ./generate_smpi_defines.pl
+! DO NOT EDIT MANUALLY. ALL CHANGES WILL BE OVERWRITTEN!
+#define MPI_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_init
+#define MPI_FINALIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_finalize
+#define MPI_FINALIZED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_finalized
+#define MPI_INIT_THREAD smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_init_thread
+#define MPI_QUERY_THREAD smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_query_thread
+#define MPI_IS_THREAD_MAIN smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_is_thread_main
+#define MPI_ABORT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_abort
+#define MPI_WTIME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_wtime
+#define MPI_WTICK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_wtick
+#define MPI_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_address
+#define MPI_GET_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get_address
+#define MPI_TYPE_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_free
+#define MPI_TYPE_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_size
+#define MPI_TYPE_GET_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_get_extent
+#define MPI_TYPE_GET_TRUE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_get_true_extent
+#define MPI_TYPE_EXTENT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_extent
+#define MPI_TYPE_LB smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_lb
+#define MPI_TYPE_UB smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_ub
+#define MPI_TYPE_COMMIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_commit
+#define MPI_TYPE_HINDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_hindexed
+#define MPI_TYPE_CREATE_HINDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_hindexed
+#define MPI_TYPE_CREATE_HINDEXED_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_hindexed_block
+#define MPI_TYPE_HVECTOR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_hvector
+#define MPI_TYPE_CREATE_HVECTOR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_hvector
+#define MPI_TYPE_INDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_indexed
+#define MPI_TYPE_CREATE_INDEXED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_indexed
+#define MPI_TYPE_CREATE_INDEXED_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_indexed_block
+#define MPI_TYPE_STRUCT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_struct
+#define MPI_TYPE_CREATE_STRUCT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_struct
+#define MPI_TYPE_VECTOR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_vector
+#define MPI_TYPE_CONTIGUOUS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_contiguous
+#define MPI_TESTALL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_testall
+#define MPI_OP_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_op_create
+#define MPI_OP_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_op_free
+#define MPI_GROUP_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_free
+#define MPI_GROUP_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_size
+#define MPI_GROUP_RANK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_rank
+#define MPI_GROUP_TRANSLATE_RANKS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_translate_ranks
+#define MPI_GROUP_COMPARE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_compare
+#define MPI_GROUP_UNION smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_union
+#define MPI_GROUP_INTERSECTION smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_intersection
+#define MPI_GROUP_DIFFERENCE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_difference
+#define MPI_GROUP_INCL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_incl
+#define MPI_GROUP_EXCL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_excl
+#define MPI_GROUP_RANGE_INCL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_range_incl
+#define MPI_GROUP_RANGE_EXCL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_range_excl
+#define MPI_COMM_RANK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_rank
+#define MPI_COMM_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_size
+#define MPI_COMM_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_get_name
+#define MPI_GET_PROCESSOR_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get_processor_name
+#define MPI_GET_COUNT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get_count
+#define MPI_COMM_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_group
+#define MPI_COMM_COMPARE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_compare
+#define MPI_COMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_create
+#define MPI_COMM_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_free
+#define MPI_COMM_DISCONNECT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_disconnect
+#define MPI_COMM_SPLIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_split
+#define MPI_SEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_send_init
+#define MPI_RECV_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_recv_init
+#define MPI_START smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_start
+#define MPI_STARTALL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_startall
+#define MPI_REQUEST_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_request_free
+#define MPI_IRECV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_irecv
+#define MPI_ISEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_isend
+#define MPI_RECV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_recv
+#define MPI_SEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_send
+#define MPI_SENDRECV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_sendrecv
+#define MPI_SENDRECV_REPLACE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_sendrecv_replace
+#define MPI_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_test
+#define MPI_TESTANY smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_testany
+#define MPI_WAIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_wait
+#define MPI_WAITANY smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_waitany
+#define MPI_WAITALL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_waitall
+#define MPI_WAITSOME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_waitsome
+#define MPI_TESTSOME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_testsome
+#define MPI_BCAST smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_bcast
+#define MPI_BARRIER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_barrier
+#define MPI_GATHER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_gather
+#define MPI_GATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_gatherv
+#define MPI_ALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_allgather
+#define MPI_ALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_allgatherv
+#define MPI_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_scatter
+#define MPI_SCATTERV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_scatterv
+#define MPI_REDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_reduce
+#define MPI_ALLREDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_allreduce
+#define MPI_SCAN smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_scan
+#define MPI_REDUCE_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_reduce_scatter
+#define MPI_REDUCE_SCATTER_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_reduce_scatter_block
+#define MPI_ALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_alltoall
+#define MPI_ALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_alltoallv
+#define MPI_IPROBE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_iprobe
+#define MPI_PROBE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_probe
+#define MPI_GET_VERSION smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get_version
+#define MPI_GET_LIBRARY_VERSION smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get_library_version
+#define MPI_REDUCE_LOCAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_reduce_local
+#define MPI_WIN_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_free
+#define MPI_WIN_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_create
+#define MPI_WIN_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_set_name
+#define MPI_WIN_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_get_name
+#define MPI_WIN_GET_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_get_group
+#define MPI_WIN_FENCE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_fence
+#define MPI_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get
+#define MPI_PUT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_put
+#define MPI_ACCUMULATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_accumulate
+#define MPI_ALLOC_MEM smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_alloc_mem
+#define MPI_FREE_MEM smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_free_mem
+#define MPI_TYPE_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_f2c
+#define MPI_TYPE_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_c2f
+#define MPI_GROUP_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_f2c
+#define MPI_GROUP_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_group_c2f
+#define MPI_REQUEST_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_request_f2c
+#define MPI_REQUEST_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_request_c2f
+#define MPI_WIN_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_f2c
+#define MPI_WIN_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_c2f
+#define MPI_OP_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_op_f2c
+#define MPI_OP_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_op_c2f
+#define MPI_COMM_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_f2c
+#define MPI_COMM_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_c2f
+#define MPI_INFO_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_f2c
+#define MPI_INFO_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_c2f
+#define MPI_ERRHANDLER_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_errhandler_f2c
+#define MPI_ERRHANDLER_C2F smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_errhandler_c2f
+#define MPI_PACK_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_pack_size
+#define MPI_CART_COORDS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_coords
+#define MPI_CART_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_create
+#define MPI_CART_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_get
+#define MPI_CART_MAP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_map
+#define MPI_CART_RANK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_rank
+#define MPI_CART_SHIFT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_shift
+#define MPI_CART_SUB smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cart_sub
+#define MPI_CARTDIM_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cartdim_get
+#define MPI_GRAPH_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_graph_create
+#define MPI_GRAPH_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_graph_get
+#define MPI_GRAPH_MAP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_graph_map
+#define MPI_GRAPH_NEIGHBORS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_graph_neighbors
+#define MPI_GRAPH_NEIGHBORS_COUNT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_graph_neighbors_count
+#define MPI_GRAPHDIMS_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_graphdims_get
+#define MPI_TOPO_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_topo_test
+#define MPI_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_error_class
+#define MPI_ERRHANDLER_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_errhandler_create
+#define MPI_ERRHANDLER_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_errhandler_free
+#define MPI_ERRHANDLER_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_errhandler_get
+#define MPI_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_error_string
+#define MPI_ERRHANDLER_SET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_errhandler_set
+#define MPI_COMM_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_set_errhandler
+#define MPI_COMM_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_get_errhandler
+#define MPI_COMM_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_create_errhandler
+#define MPI_COMM_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_call_errhandler
+#define MPI_ADD_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_add_error_class
+#define MPI_ADD_ERROR_CODE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_add_error_code
+#define MPI_ADD_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_add_error_string
+#define MPI_CANCEL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_cancel
+#define MPI_BUFFER_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_buffer_attach
+#define MPI_BUFFER_DETACH smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_buffer_detach
+#define MPI_COMM_TEST_INTER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_test_inter
+#define MPI_COMM_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_get_attr
+#define MPI_COMM_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_set_attr
+#define MPI_COMM_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_delete_attr
+#define MPI_COMM_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_create_keyval
+#define MPI_COMM_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_free_keyval
+#define MPI_TYPE_GET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_get_attr
+#define MPI_TYPE_SET_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_set_attr
+#define MPI_TYPE_DELETE_ATTR smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_delete_attr
+#define MPI_TYPE_CREATE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_keyval
+#define MPI_TYPE_FREE_KEYVAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_free_keyval
+#define MPI_TYPE_DUP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_dup
+#define MPI_TYPE_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_set_name
+#define MPI_TYPE_GET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_get_name
+#define MPI_UNPACK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_unpack
+#define MPI_SSEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_ssend
+#define MPI_SSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_ssend_init
+#define MPI_INTERCOMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_intercomm_create
+#define MPI_INTERCOMM_MERGE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_intercomm_merge
+#define MPI_BSEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_bsend
+#define MPI_BSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_bsend_init
+#define MPI_IBSEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_ibsend
+#define MPI_COMM_REMOTE_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_remote_group
+#define MPI_COMM_REMOTE_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_remote_size
+#define MPI_ISSEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_issend
+#define MPI_ATTR_DELETE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_attr_delete
+#define MPI_ATTR_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_attr_get
+#define MPI_ATTR_PUT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_attr_put
+#define MPI_RSEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_rsend
+#define MPI_RSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_rsend_init
+#define MPI_IRSEND smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_irsend
+#define MPI_KEYVAL_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_keyval_create
+#define MPI_KEYVAL_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_keyval_free
+#define MPI_TEST_CANCELLED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_test_cancelled
+#define MPI_PACK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_pack
+#define MPI_GET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_get_elements
+#define MPI_DIMS_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_dims_create
+#define MPI_INITIALIZED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_initialized
+#define MPI_PCONTROL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_pcontrol
+#define MPI_INFO_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_create
+#define MPI_INFO_SET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_set
+#define MPI_INFO_GET smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_get
+#define MPI_INFO_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_free
+#define MPI_INFO_DELETE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_delete
+#define MPI_INFO_DUP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_dup
+#define MPI_INFO_GET_NKEYS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_get_nkeys
+#define MPI_INFO_GET_NTHKEY smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_get_nthkey
+#define MPI_INFO_GET_VALUELEN smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_info_get_valuelen
+#define MPI_WIN_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_set_errhandler
+#define MPI_TYPE_GET_ENVELOPE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_get_envelope
+#define MPI_TYPE_GET_CONTENTS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_get_contents
+#define MPI_TYPE_CREATE_DARRAY smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_darray
+#define MPI_PACK_EXTERNAL_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_pack_external_size
+#define MPI_PACK_EXTERNAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_pack_external
+#define MPI_UNPACK_EXTERNAL smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_unpack_external
+#define MPI_TYPE_CREATE_RESIZED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_resized
+#define MPI_TYPE_CREATE_SUBARRAY smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_create_subarray
+#define MPI_TYPE_MATCH_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_type_match_size
+#define MPI_ALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_alltoallw
+#define MPI_EXSCAN smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_exscan
+#define MPI_COMM_SET_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_set_name
+#define MPI_COMM_SET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_set_info
+#define MPI_COMM_GET_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_get_info
+#define MPI_COMM_DUP smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_dup
+#define MPI_COMM_DUP_WITH_INFO smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_dup_with_info
+#define MPI_COMM_SPLIT_TYPE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_split_type
+#define MPI_COMM_CONNECT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_connect
+#define MPI_REQUEST_GET_STATUS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_request_get_status
+#define MPI_GREQUEST_START smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_grequest_start
+#define MPI_GREQUEST_COMPLETE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_grequest_complete
+#define MPI_STATUS_SET_CANCELLED smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_status_set_cancelled
+#define MPI_STATUS_SET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_status_set_elements
+#define MPI_UNPUBLISH_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_unpublish_name
+#define MPI_PUBLISH_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_publish_name
+#define MPI_LOOKUP_NAME smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_lookup_name
+#define MPI_COMM_JOIN smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_join
+#define MPI_OPEN_PORT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_open_port
+#define MPI_CLOSE_PORT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_close_port
+#define MPI_COMM_ACCEPT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_accept
+#define MPI_COMM_SPAWN smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_spawn
+#define MPI_COMM_SPAWN_MULTIPLE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_spawn_multiple
+#define MPI_COMM_GET_PARENT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_comm_get_parent
+#define MPI_WIN_COMPLETE smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_complete
+#define MPI_WIN_LOCK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_lock
+#define MPI_WIN_POST smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_post
+#define MPI_WIN_START smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_start
+#define MPI_WIN_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_test
+#define MPI_WIN_UNLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_unlock
+#define MPI_WIN_WAIT smpi_trace_set_call_location(__FILE__,__LINE__); call mpi_win_wait
index 2d76e28..f135044 100644 (file)
@@ -5,6 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "src/instr/instr_private.h"
+#include "simgrid/sg_config.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_header, instr, "Paje tracing event system (header)");
 
@@ -163,6 +164,10 @@ static void TRACE_header_PajePushState (int basic, int size)
   fprintf(tracing_file, "%%       Container string\n");
   fprintf(tracing_file, "%%       Value string\n");
   if (size) fprintf(tracing_file, "%%       Size int\n");
+  if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
+    fprintf(tracing_file, "%%       Filename string\n");
+    fprintf(tracing_file, "%%       Linenumber int\n");
+  }
   fprintf(tracing_file, "%%EndEventDef\n");
 }
 
index 9a9e631..d106f33 100644 (file)
@@ -8,6 +8,7 @@
 #include "xbt/virtu.h" /* sg_cmdline */
 #include <sstream>
 #include <iomanip> /** std::setprecision **/
+#include "simgrid/sg_config.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_trace, instr_trace, "tracing event system");
 
@@ -222,6 +223,12 @@ void print_pajeSetState(paje_event_t event) {
 
   print_default_pajeState_row<setState_t>(event);
   stream << " " << static_cast<setState_t>(event->data)->value->id;
+
+  if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
+    stream << " \"" << static_cast<setState_t>(event->data)->filename
+           << "\" " << static_cast<setState_t>(event->data)->linenumber;
+  }
+
   print_row();
 }
 
@@ -239,6 +246,12 @@ void print_pajePushState(paje_event_t event) {
       stream << 0;
     }
   }
+
+  if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
+    stream << " \"" << static_cast<pushState_t>(event->data)->filename
+           << "\" " << static_cast<pushState_t>(event->data)->linenumber;
+  }
+
   print_row();
 
   if (static_cast<pushState_t>(event->data)->extra != NULL) {
index bd861c1..c9f3272 100644 (file)
@@ -175,6 +175,8 @@ typedef struct s_setState {
   container_t container;
   type_t type;
   val_t value;
+  const char* filename;
+  int linenumber;
 }s_setState_t;
 
 typedef struct s_pushState *pushState_t;
@@ -183,6 +185,8 @@ typedef struct s_pushState {
   type_t type;
   val_t value;
   int size;
+  const char* filename;
+  int linenumber;
   void* extra;
 }s_pushState_t;
 
diff --git a/src/instr/instr_smpi.h b/src/instr/instr_smpi.h
new file mode 100644 (file)
index 0000000..d80aed2
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef INSTR_SMPI_H_
+#define INSTR_SMPI_H_ 
+#ifdef __cplusplus
+#include <string>
+extern "C" {
+#endif
+
+typedef struct smpi_trace_call_location {
+  const char* filename;
+  int linenumber;
+
+  const char* previous_filename;
+  int previous_linenumber;
+
+#ifdef __cplusplus
+  std::string get_composed_key() {
+    return std::string(previous_filename) + ':' + std::to_string(previous_linenumber) + ':' + filename + ':' + std::to_string(linenumber);
+  }
+#endif
+
+} smpi_trace_call_location_t;
+
+smpi_trace_call_location_t* smpi_trace_get_call_location();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
index c98e2a9..149f937 100644 (file)
@@ -5,6 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "src/instr/instr_private.h"
+#include "src/instr/instr_smpi.h"
 #include "xbt/virtu.h" /* sg_cmdline */
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_trace, instr, "tracing event system");
@@ -341,6 +342,11 @@ void new_pajeSetState (double timestamp, container_t container, type_t type, val
   ((setState_t)(event->data))->container = container;
   ((setState_t)(event->data))->value = value;
 
+  smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
+  ((setState_t)(event->data))->filename   = loc->filename;
+  ((setState_t)(event->data))->linenumber = loc->linenumber;
+
   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
 
   insert_into_buffer (event);
@@ -360,6 +366,10 @@ void new_pajePushStateWithExtra (double timestamp, container_t container, type_t
   ((pushState_t)(event->data))->value = value;
   ((pushState_t)(event->data))->extra = extra;
 
+  smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
+  ((pushState_t)(event->data))->filename   = loc->filename;
+  ((pushState_t)(event->data))->linenumber = loc->linenumber;
+
   XBT_DEBUG("%s: event_type=%d, timestamp=%f", __FUNCTION__, (int)event->event_type, event->timestamp);
 
   insert_into_buffer (event);
index 8459539..d7b07e8 100644 (file)
@@ -573,6 +573,8 @@ void sg_config_init(int *argc, char **argv)
     xbt_cfg_register_alias("smpi/async-small-thresh","smpi/async_small_thresh");
     xbt_cfg_register_alias("smpi/async-small-thresh","smpi/async_small_thres");
 
+    xbt_cfg_register_boolean("smpi/trace-call-location", "no", NULL, "Should filename and linenumber of MPI calls be traced?");
+
     xbt_cfg_register_int("smpi/send-is-detached-thresh", 65536, NULL,
         "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend");
     xbt_cfg_register_alias("smpi/send-is-detached-thresh","smpi/send_is_detached_thresh");
@@ -581,6 +583,10 @@ void sg_config_init(int *argc, char **argv)
     xbt_cfg_register_boolean("smpi/privatize-global-variables", "no", NULL, "Whether we should privatize global variable at runtime.");
     xbt_cfg_register_alias("smpi/privatize-global-variables", "smpi/privatize_global_variables");
 
+#if HAVE_PAPI
+    xbt_cfg_register_string("smpi/papi-events", nullptr, NULL, "This switch enables tracking the specified counters with PAPI");
+#endif
+    xbt_cfg_register_string("smpi/comp-adjustment-file", nullptr, NULL, "A file containing speedups or slowdowns for some parts of the code.");
     xbt_cfg_register_string("smpi/os", "1:0:0:0:0", NULL,  "Small messages timings (MPI_Send minimum time for small messages)");
     xbt_cfg_register_string("smpi/ois", "1:0:0:0:0", NULL, "Small messages timings (MPI_Isend minimum time for small messages)");
     xbt_cfg_register_string("smpi/or", "1:0:0:0:0", NULL,  "Small messages timings (MPI_Recv minimum time for small messages)");
index 1141a22..2618f2d 100644 (file)
@@ -5,6 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "private.h"
+#include "private.hpp"
 #include <ctype.h>
 #include <wchar.h>
 #include <stdarg.h>
@@ -82,7 +83,7 @@ static const char *instr_find_color (const char *state)
   return ret;
 }
 
-static char *smpi_container(int rank, char *container, int n)
+XBT_PRIVATE char *smpi_container(int rank, char *container, int n)
 {
   snprintf(container, n, "rank-%d", rank);
   return container;
index 746abc8..2c1965d 100644 (file)
@@ -699,6 +699,7 @@ XBT_PRIVATE void TRACE_smpi_send(int rank, int src, int dst, int size);
 XBT_PRIVATE void TRACE_smpi_recv(int rank, int src, int dst);
 XBT_PRIVATE void TRACE_smpi_init(int rank);
 XBT_PRIVATE void TRACE_smpi_finalize(int rank);
+XBT_PRIVATE char *smpi_container(int rank, char *container, int n);
 
 XBT_PRIVATE const char* encode_datatype(MPI_Datatype datatype, int* known);
 
diff --git a/src/smpi/private.hpp b/src/smpi/private.hpp
new file mode 100644 (file)
index 0000000..f6a71ab
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef SMPI_PRIVATE_HPP
+#define SMPI_PRIVATE_HPP
+
+#ifdef HAVE_PAPI
+typedef 
+    std::vector<std::pair</* counter name */std::string, /* counter value */long long>> papi_counter_t;
+XBT_PRIVATE papi_counter_t& smpi_process_counter_data(void);
+XBT_PRIVATE int smpi_process_event_set(void);
+#endif
+
+extern std::map<std::string, double> location2speedup;
+#endif
index 0f1578e..a997df0 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "src/internal_config.h"
 #include "private.h"
+#include "private.hpp"
 #include "xbt/dict.h"
 #include "xbt/sysdep.h"
 #include "xbt/ex.h"
@@ -251,6 +252,7 @@ void smpi_bench_end(void)
   if (MC_is_active() || MC_record_replay_is_active())
     return;
 
+  double speedup = 1;
   xbt_os_timer_t timer = smpi_process_timer();
   xbt_os_threadtimer_stop(timer);
 //  smpi_switch_data_segment(smpi_process_count());
@@ -260,9 +262,22 @@ void smpi_bench_end(void)
     xbt_backtrace_display_current();
     xbt_die("Aborting.");
   }
+
+  if (xbt_cfg_get_string("smpi/comp-adjustment-file")[0] != '\0') { // Maybe we need to artificially speed up or slow
+                                                         // down our computation based on our statistical analysis.
+
+    smpi_trace_call_location_t* loc                  = smpi_process_get_call_location();
+    std::string key                                  = loc->get_composed_key();
+    std::map<std::string, double>::const_iterator it = location2speedup.find(key);
+    if (it != location2speedup.end()) {
+      speedup = it->second;
+    }
+  }
+  
   // Simulate the benchmarked computation unless disabled via command-line argument
-  if (xbt_cfg_get_boolean("smpi/simulate-computation")) 
-    smpi_execute(xbt_os_timer_elapsed(timer));
+  if (xbt_cfg_get_boolean("smpi/simulate-computation")) {
+    smpi_execute(xbt_os_timer_elapsed(timer)/speedup);
+  }
 
   smpi_total_benched_time += xbt_os_timer_elapsed(timer);
 }
@@ -722,3 +737,33 @@ void smpi_destroy_global_memory_segments(){
   xbt_free(smpi_privatisation_regions);
 #endif
 }
+
+extern "C" {
+
+  smpi_trace_call_location_t* smpi_trace_get_call_location() {
+    return smpi_process_get_call_location();
+  }
+
+  void smpi_trace_set_call_location(const char* file, const int line) {
+    smpi_trace_call_location_t* loc = smpi_process_get_call_location();
+
+    loc->previous_filename   = loc->filename;
+    loc->previous_linenumber = loc->linenumber;
+    loc->filename            = file;
+    loc->linenumber          = line;
+  }
+
+  /**
+   * Required for Fortran bindings
+   */
+  void smpi_trace_set_call_location_(const char* file, int* line) {
+    smpi_trace_set_call_location(file, *line);
+  }
+
+  /** 
+   * Required for Fortran if -fsecond-underscore is activated
+   */
+  void smpi_trace_set_call_location__(const char* file, int* line) {
+    smpi_trace_set_call_location(file, *line);
+  }
+}
index 3608667..2dd5af6 100644 (file)
@@ -5,6 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "private.h"
+#include "private.hpp"
 #include "smpi_mpi_dt_private.h"
 #include "mc/mc.h"
 #include "src/mc/mc_record.h"
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <fstream>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, "Logging specific to SMPI (kernel)");
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp> /* trim_right / trim_left */
+
+std::map<std::string, double> location2speedup;
 
 typedef struct s_smpi_process_data {
   double simulated;
@@ -43,6 +49,7 @@ typedef struct s_smpi_process_data {
   int replaying;                /* is the process replaying a trace */
   xbt_bar_t finalization_barrier;
   int return_value;
+  smpi_trace_call_location_t* trace_call_loc;
 } s_smpi_process_data_t;
 
 static smpi_process_data_t *process_data = NULL;
@@ -227,6 +234,18 @@ int smpi_process_count(void)
   return process_count;
 }
 
+/**
+ * \brief Returns a structure that stores the location (filename + linenumber)
+ *        of the last calls to MPI_* functions.
+ *
+ * \see smpi_trace_set_call_location
+ */
+smpi_trace_call_location_t* smpi_process_get_call_location(void)
+{
+  smpi_process_data_t process_data = smpi_process_data();
+  return process_data->trace_call_loc;
+}
+
 int smpi_process_index(void)
 {
   smpi_process_data_t data = smpi_process_data();
@@ -406,6 +425,28 @@ void smpi_global_init(void)
     global_timer = xbt_os_timer_new();
     xbt_os_walltimer_start(global_timer);
   }
+
+  if (xbt_cfg_get_string("smpi/comp-adjustment-file")[0] != '\0') { 
+    std::string filename {xbt_cfg_get_string("smpi/comp-adjustment-file")};
+    std::ifstream fstream(filename);
+    if (!fstream.is_open()) {
+      xbt_die("Could not open file %s. Does it exist?", filename.c_str());
+    }
+
+    std::string line;
+    typedef boost::tokenizer< boost::escaped_list_separator<char>> Tokenizer;
+    std::getline(fstream, line); // Skip the header line
+    while (std::getline(fstream, line)) {
+      Tokenizer tok(line);
+      Tokenizer::iterator it  = tok.begin();
+      Tokenizer::iterator end = std::next(tok.begin());
+
+      std::string location = *it;
+      boost::trim(location);
+      location2speedup.insert(std::pair<std::string, double>(location, std::stod(*end)));
+    }
+  }
+
   if (process_count == 0){
     process_count = SIMIX_process_count();
     smpirun=1;
@@ -430,6 +471,7 @@ void smpi_global_init(void)
     process_data[i]->sampling             = 0;
     process_data[i]->finalization_barrier = NULL;
     process_data[i]->return_value         = 0;
+    process_data[i]->trace_call_loc       = xbt_new(smpi_trace_call_location_t, 1);
   }
   //if the process was launched through smpirun script we generate a global mpi_comm_world
   //if not, we let MPI_COMM_NULL, and the comm world will be private to each mpi instance
index 41ece46..d664bbf 100755 (executable)
@@ -51,6 +51,9 @@ while [ $# -gt 0 ]; do
             printf '%b\n' "$SIMGRID_GITHASH"
             exit 0
             ;;
+        '-trace-call-location')
+            list_add_not_empty CMDLINE "-DTRACE_CALL_LOCATION"
+            ;;
         '-compiler-version' | '--compiler-version')
             ${CC} --version
             ;;
index 90e0140..6dceb77 100644 (file)
@@ -30,10 +30,15 @@ trap 'cleanup' EXIT
 filter_and_compile() {
     list_add TMPFILES "${TMPFILE}"
     #replace "program main_name by subroutine user\_main (and the end clause as well)"
-    sed 's/[[:space:]]\{6\}[[:space:]]*\(end \)\{0,1\}program[[:space:]]*\([a-zA-Z0-9\-\_]*\)/      \1subroutine user_main /gI;s/[[:space:]]*use[[:space:]]*mpi/\include \"mpif\.h\" /gI' "${ARG}" > "${TMPFILE}"
+    if [ $TRACE_CALL_LOCATION -gt 0 ]; then
+      echo "#include \"/tmp/local/include/smpi/smpi_extended_traces_fortran.h\"" > ${TMPFILE}
+    echo "#line 1 \"${ARG}\"" >> ${TMPFILE}
+    fi
+    sed 's/[[:space:]]\{6\}[[:space:]]*\(end \)\{0,1\}program[[:space:]]*\([a-zA-Z0-9\-\_]*\)/      \1subroutine user_main /gI;s/[[:space:]]*use[[:space:]]*mpi/\include \"mpif\.h\" /gI' "${ARG}" >> "${TMPFILE}"
     SRCFILE="${TMPFILE}"
     list_add CMDLINE "${SRCFILE}"
 }
+TRACE_CALL_LOCATION=0
 NEEDS_OUTPUT=1
 
 list_set CMDLINE "${F77}"
@@ -68,6 +73,12 @@ while [ $# -gt 0 ]; do
         '-compiler-version' | '--compiler-version')
             ${F77} --version
             ;;
+        '-trace-call-location')
+            TRACE_CALL_LOCATION=1
+            # This should be list_add FFLAGS but it's not possible
+            # anymore: FFLAGS was already moved into CMDLINE above.
+            list_add_not_empty CMDLINE "-ffixed-line-length-none" "-cpp"
+            ;;
         -o)
             NEEDS_OUTPUT=0
             list_add CMDLINE "-o"   
index 45a3c2d..d111567 100644 (file)
@@ -43,6 +43,7 @@ set(EXTRA_DIST
   src/smpi/colls/colls_private.h
   src/smpi/colls/smpi_mvapich2_selector_stampede.h
   src/smpi/private.h
+  src/smpi/private.hpp
   src/smpi/smpi_mpi_dt_private.h
   src/surf/cpu_cas01.hpp
   src/surf/cpu_interface.hpp
@@ -506,6 +507,7 @@ set(TRACING_SRC
   src/instr/instr_paje_types.cpp
   src/instr/instr_paje_values.cpp
   src/instr/instr_private.h
+  src/instr/instr_smpi.h
   src/instr/instr_resource_utilization.cpp
   src/instr/instr_trace.cpp
   )
index efb9595..ed62a97 100644 (file)
@@ -56,6 +56,10 @@ if(HAVE_LUA)
   SET(SIMGRID_DEP "${SIMGRID_DEP} ${LUA_LIBRARY} -ldl")
 endif()
 
+if(HAVE_PAPI)
+  SET(SIMGRID_DEP "${SIMGRID_DEP} -lpapi")
+endif()
+
 if(HAVE_GRAPHVIZ)
   if(HAVE_CGRAPH_LIB)
     SET(SIMGRID_DEP "${SIMGRID_DEP} -lcgraph")
diff --git a/tools/cmake/Modules/FindPAPI.cmake b/tools/cmake/Modules/FindPAPI.cmake
new file mode 100644 (file)
index 0000000..afb95bb
--- /dev/null
@@ -0,0 +1,77 @@
+# Try to find PAPI headers and LIBRARY.
+#
+# Usage of this module as follows:
+#
+#     find_package(PAPI)
+#
+# Variables used by this module, they can change the default behaviour and need
+# to be set before calling find_package:
+#
+#  PAPI_PREFIX         Set this variable to the root installation of
+#                      libpapi if the module has problems finding the
+#                      proper installation path.
+#
+# Variables defined by this module:
+#
+#  PAPI_FOUND              System has PAPI LIBRARY and headers
+#  PAPI_LIBRARY          The PAPI library
+#  PAPI_INCLUDE_DIRS       The location of PAPI headers
+
+set(HAVE_PAPI 0)
+set(PAPI_HINT ${papi_path} CACHE PATH "Path to search for PAPI headers and library")
+
+find_path(PAPI_PREFIX
+    NAMES include/papi.h
+       PATHS
+       ${PAPI_HINT}
+)
+
+message(STATUS "Looking for libpapi")
+find_library(PAPI_LIBRARY
+    NAMES libpapi papi
+    PATH_SUFFIXES lib64 lib 
+    # HINTS gets searched before PATHS
+    HINTS 
+    ${PAPI_PREFIX}/lib 
+)
+if(PAPI_LIBRARY)
+  message(STATUS "Looking for libpapi - found at ${PAPI_LIBRARY}")
+else()
+  message(STATUS "Looking for libpapi - not found")
+endif()
+
+message(STATUS "Looking for papi.h")
+find_path(PAPI_INCLUDE_DIRS
+    NAMES papi.h
+    # HINTS gets searched before PATHS
+    HINTS ${PAPI_PREFIX}/include 
+)
+if(PAPI_INCLUDE_DIRS)
+  message(STATUS "Looking for papi.h - found at ${PAPI_INCLUDE_DIRS}")
+else()
+  message(STATUS "Looking for papi.h - not found")
+endif()
+
+
+if (PAPI_LIBRARY)
+  if(PAPI_INCLUDE_DIRS)
+    set(HAVE_PAPI 1)
+    mark_as_advanced(HAVE_PAPI)
+  endif()
+endif()
+if(NOT HAVE_PAPI)
+  message(FATAL_ERROR, "Could not find PAPI LIBRARY and/or papi.h. Make sure they are correctly installed!")
+endif()
+
+#include(FindPackageHandleStandardArgs)
+#find_package_handle_standard_args(PAPI DEFAULT_MSG
+#    PAPI_LIBRARY
+#    PAPI_INCLUDE_DIRS
+#)
+
+mark_as_advanced(
+    PAPI_PREFIX_DIRS
+    PAPI_LIBRARY
+    PAPI_INCLUDE_DIRS
+)
+
index dc14fd0..511f861 100644 (file)
@@ -38,6 +38,9 @@ if(WIN32)
   option(enable_smpi_MPICH3_testsuite "Whether the test suite form MPICH 3 should be built" off)
 else()
   option(enable_smpi "Whether SMPI in included in library." on)
+  # PAPI does not support windows (they did in 3.7, but not anymore in 5.x)
+  # See http://icl.cs.utk.edu/papi/custom/index.html?lid=62&slid=96
+  option(enable_smpi_papi    "Whether SMPI supports PAPI bindings." off)
   option(enable_smpi_MPICH3_testsuite "Whether the test suite form MPICH 3 should be built" off)
 endif()
 option(enable_smpi_ISP_testsuite "Whether the test suite from ISP should be built." off)
index 0b8d91b..1ad92b1 100644 (file)
@@ -56,6 +56,9 @@
 #define SMPI_FORTRAN       @SMPI_FORTRAN@
 #define HAVE_PRIVATIZATION @HAVE_PRIVATIZATION@ /* We have mmap and objdump to handle privatization */
 
+/* Make PAPI available? */
+#define HAVE_PAPI @HAVE_PAPI@
+
 /* Other function checks */
 #define HAVE_BACKTRACE @HAVE_BACKTRACE@ /* Function backtrace */
 #define HAVE_MMAP      @HAVE_MMAP@ /* Function mmap */
diff --git a/tools/smpi/generate_smpi_defines.pl b/tools/smpi/generate_smpi_defines.pl
new file mode 100755 (executable)
index 0000000..b741fca
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+# Copyright 2016 Vincent Danjean <vincent.danjean@inria.fr>
+# 
+# Call this script like this:
+# C/C++  : ./generate_smpi_defines.pl ../../include/smpi/smpi.h
+# FORTRAN: ./generate_smpi_defines.pl -f ../../include/smpi/smpi.h
+#
+# It will generate macros that are useful for adding file and line numbers to
+# traces without obtaining a backtrace (as this would be very slow and make
+# the simulation/trace unreliable when compared to a "real" trace as obtained
+# with MPI+TAU).
+use strict;
+use warnings;
+use Getopt::Std; 
+
+my %options=();
+getopts("fc", \%options);
+
+# $incall denotes whether we are currently parsing a macro or not...
+my $incall=0;
+
+my $commentChar="//";
+if (defined $options{f}) {
+  $commentChar="!"
+}
+
+print "$commentChar This file has been automatically generated by the script\n";
+print "$commentChar in " . __FILE__ ."\n";
+print "$commentChar DO NOT EDIT MANUALLY. ALL CHANGES WILL BE OVERWRITTEN!\n";
+
+# Formatting of the output
+sub output_macro {
+  my $line = shift;
+  my @parts = split (/\s*,\s*/, $line);
+  my $id = $parts[1];
+
+  # This is a GCC extension. The last statement is the value of the expression
+  # in parentheses.
+  if (defined $options{f}) {
+    print "#define ". uc($id) ." smpi_trace_set_call_location(__FILE__,__LINE__); call ". lc $id ."\n";
+  }
+  else {
+    print "#define $id(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); $id(__VA_ARGS__); })\n";
+  }
+}
+
+my $wholemacro;
+my $line;
+while (defined($line = <>)) {
+  chomp($line);
+  if ($line =~ /^MPI_CALL/) {
+    if ($incall) {
+        output_macro($wholemacro);
+    }
+    $incall=1;
+    $wholemacro = $line;
+  } elsif ($incall && $line =~ /^\s+\S/) { 
+    # Did we already start parsing an MPI_CALL macro? If so, just concatenate
+    $wholemacro .= ' '.$line;
+  } elsif ($incall) {
+    output_macro($wholemacro);
+    $incall=0;
+  }
+}