Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
authorJonathan Rouzaud-Cornabas <jonathan.rouzaud-cornabas@ens-lyon.fr>
Thu, 13 Jun 2013 12:50:23 +0000 (14:50 +0200)
committerJonathan Rouzaud-Cornabas <jonathan.rouzaud-cornabas@ens-lyon.fr>
Thu, 13 Jun 2013 12:50:23 +0000 (14:50 +0200)
30 files changed:
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/jenkins/run.sh
buildtools/jenkins/runmingw.sh
examples/msg/mc/bugged1.tesh
examples/msg/mc/bugged2.tesh
src/include/smpi/smpi_interface.h
src/mc/mc_dpor.c
src/mc/mc_request.c
src/simgrid/sg_config.c
src/simix/smx_network.c
src/simix/smx_private.h
src/smpi/colls/barrier-ompi.c [new file with mode: 0644]
src/smpi/colls/colls.h
src/smpi/colls/reduce_scatter-ompi.c [new file with mode: 0644]
src/smpi/colls/scatter-ompi.c [new file with mode: 0644]
src/smpi/colls/smpi_openmpi_selector.c
src/smpi/private.h
src/smpi/smpi_base.c
src/smpi/smpi_coll.c
src/smpi/smpi_global.c
src/smpi/smpi_pmpi.c
teshsuite/smpi/CMakeLists.txt
teshsuite/smpi/barrier.c
teshsuite/smpi/barrier_coll.tesh [new file with mode: 0644]
teshsuite/smpi/mpich-test/coll/redscat.c
teshsuite/smpi/mpich-test/coll/runtests
teshsuite/smpi/reduce_scatter_coll.c [new file with mode: 0644]
teshsuite/smpi/reduce_scatter_coll.tesh [new file with mode: 0644]
teshsuite/smpi/scatter_coll.tesh [new file with mode: 0644]

index 3ec061d..d46d860 100644 (file)
@@ -415,6 +415,18 @@ if(NOT enable_memcheck)
         ADD_TEST(smpi-reduce-coll-${REDUCE_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/reduce:${REDUCE_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/reduce_coll.tesh)
     ENDFOREACH()
 
+    FOREACH (REDUCE_SCATTER_COLL default  ompi ompi_basic_recursivehalving ompi_ring)
+        ADD_TEST(smpi-reduce_scatter-coll-${REDUCE_SCATTER_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/reduce_scatter:${REDUCE_SCATTER_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/reduce_scatter_coll.tesh)
+    ENDFOREACH()
+
+    FOREACH (SCATTER_COLL default  ompi ompi_basic_linear ompi_binomial)
+        ADD_TEST(smpi-scatter-coll-${SCATTER_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/scatter:${SCATTER_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/scatter_coll.tesh)
+    ENDFOREACH()
+
+    FOREACH (BARRIER_COLL default  ompi ompi_basic_linear ompi_tree ompi_bruck ompi_recursivedoubling ompi_doublering)
+        ADD_TEST(smpi-barrier-coll-${BARRIER_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/barrier:${BARRIER_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/barrier_coll.tesh)
+    ENDFOREACH()
+
   endif()
 
   # END TESH TESTS
@@ -463,12 +475,9 @@ if(NOT enable_memcheck)
 
   # examples/msg/mc
   if(HAVE_MC)
-    ADD_TEST(mc-bugged1-thread                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:thread --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1.tesh)
-    ADD_TEST(mc-centralized-thread              ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:thread --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc centralized.tesh)
     if(CONTEXT_UCONTEXT)
       ADD_TEST(mc-bugged1-ucontext              ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1.tesh)
       ADD_TEST(mc-bugged2-ucontext              ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged2.tesh)
-      ADD_TEST(mc-centralized-ucontext          ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc centralized.tesh)
       if(PROCESSOR_x86_64) # liveness model-checking works only on 64bits (for now ...)
         ADD_TEST(mc-bugged1-liveness-ucontext   ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness.tesh)
       endif()
@@ -476,25 +485,6 @@ if(NOT enable_memcheck)
     if(HAVE_RAWCTX)
       ADD_TEST(mc-bugged1-raw                   ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:raw --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1.tesh)
       ADD_TEST(mc-bugged2-raw                   ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:raw --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged2.tesh)
-      ADD_TEST(mc-centralized-raw               ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:raw --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc centralized.tesh)
-    endif()
-  endif()
-
-  ###
-  ### Declare that we know that some tests are broken
-  ###
-
-  # Those tests are broken : set to "fail" for release v3.6
-  if(release)
-    if(HAVE_MC)
-      set_tests_properties(mc-bugged1-thread PROPERTIES WILL_FAIL true)
-      set_tests_properties(mc-centralized-thread PROPERTIES WILL_FAIL true)
-      if(CONTEXT_UCONTEXT)
-        set_tests_properties(mc-centralized-ucontext PROPERTIES WILL_FAIL true)
-      endif()
-      if(HAVE_RAWCTX)
-        set_tests_properties(mc-centralized-raw PROPERTIES WILL_FAIL true)
-      endif()
     endif()
   endif()
 
index 0131674..6d5586f 100644 (file)
@@ -196,6 +196,9 @@ set(SMPI_SRC
   src/smpi/colls/reduce-scatter-gather.c
   src/smpi/colls/reduce-ompi.c
   src/smpi/colls/gather-ompi.c
+  src/smpi/colls/reduce_scatter-ompi.c
+  src/smpi/colls/scatter-ompi.c
+  src/smpi/colls/barrier-ompi.c
   )
 
 if(SMPI_F2C)
index 5558ac8..fe5a509 100644 (file)
@@ -22,7 +22,7 @@ fi
 
 if [ "$build_mode" = "ModelChecker" ]
 then
-cmake -Denable_coverage=ON -Denable_java=ON -Denable_model-checking=ON -Denable_lua=ON -Denable_compile_optimizations=ON -Denable_compile_warnings=ON .
+cmake -Denable_coverage=ON -Denable_java=ON -Denable_model-checking=ON -Denable_lua=ON -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON .
 fi
 
 if [ "$build_mode" = "DynamicAnalysis" ]
@@ -47,7 +47,7 @@ fi
 
 if [ "$build_mode" = "ModelChecker" ]
 then
-cmake -Denable_coverage=ON -Denable_java=ON -Denable_model-checking=ON -Denable_lua=ON -Denable_compile_optimizations=ON -Denable_compile_warnings=ON .
+cmake -Denable_coverage=ON -Denable_java=ON -Denable_model-checking=ON -Denable_lua=ON -Denable_compile_optimizations=OFF -Denable_compile_warnings=ON .
 fi
 
 if [ "$build_mode" = "DynamicAnalysis" ]
index b813165..dc901e8 100644 (file)
@@ -16,7 +16,7 @@ fi
 
 if [ "$build_mode" = "ModelChecker" ]
 then
-cmake -G "MSYS Makefiles" -Denable_model-checking=ON ..
+cmake -G "MSYS Makefiles" -Denable_model-checking=ON -Denable_compile_optimizations=OFF ..
 fi
 
 make
index fb48186..78c1f5e 100644 (file)
@@ -1,6 +1,7 @@
 #! ./tesh
 
 ! expect signal SIGABRT
+! timeout 20
 $ ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
 > [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
 > [  0.000000] (0:@) Check a safety property
@@ -9,6 +10,13 @@ $ ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%
 > [  0.000000] (1:server@HostA) OK
 > [  0.000000] (4:client@HostD) Sent!
 > [  0.000000] (2:client@HostB) Sent!
+> [  0.000000] (3:client@HostC) Sent!
+> [  0.000000] (2:client@HostB) Sent!
+> [  0.000000] (3:client@HostC) Sent!
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (4:client@HostD) Sent!
+> [  0.000000] (2:client@HostB) Sent!
+> [  0.000000] (3:client@HostC) Sent!
 > [  0.000000] (2:client@HostB) Sent!
 > [  0.000000] (1:server@HostA) **************************
 > [  0.000000] (1:server@HostA) *** PROPERTY NOT VALID ***
@@ -24,6 +32,6 @@ $ ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%
 > [  0.000000] (1:server@HostA) [(1)HostA (server)] iRecv (dst=(1)HostA (server), buff=(verbose only), size=(verbose only))
 > [  0.000000] (1:server@HostA) [(3)HostC (client)] iSend (src=(3)HostC (client), buff=(verbose only), size=(verbose only))
 > [  0.000000] (1:server@HostA) [(1)HostA (server)] Wait (comm=(verbose only) [(3)HostC (client)-> (1)HostA (server)])
-> [  0.000000] (1:server@HostA) Expanded states = 17
-> [  0.000000] (1:server@HostA) Visited states = 32
-> [  0.000000] (1:server@HostA) Executed transitions = 30
+> [  0.000000] (1:server@HostA) Expanded states = 22
+> [  0.000000] (1:server@HostA) Visited states = 56
+> [  0.000000] (1:server@HostA) Executed transitions = 52
index fcd9ca5..bbfd7ac 100644 (file)
@@ -1,6 +1,7 @@
 #! ./tesh
 
 ! expect signal SIGABRT
+! timeout 20
 $ ${bindir:=.}/bugged2 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
 > [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
 > [  0.000000] (0:@) Check a safety property
@@ -15,50 +16,884 @@ $ ${bindir:=.}/bugged2 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%
 > [  0.000000] (1:server@HostA) OK
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) OK
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) OK
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) OK
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (1:server@HostA) OK
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (1:server@HostA) OK
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) OK
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
 > [  0.000000] (3:client@HostC) Send 2!
 > [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
 > [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 1
 > [  0.000000] (1:server@HostA) OK
-> [  0.000000] (0:@) Expanded states = 68
-> [  0.000000] (0:@) Visited states = 132
-> [  0.000000] (0:@) Executed transitions = 124
\ No newline at end of file
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 1
+> [  0.000000] (2:client@HostB) Send 1!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (3:client@HostC) Send 2!
+> [  0.000000] (1:server@HostA) Received 2
+> [  0.000000] (1:server@HostA) **************************
+> [  0.000000] (1:server@HostA) *** PROPERTY NOT VALID ***
+> [  0.000000] (1:server@HostA) **************************
+> [  0.000000] (1:server@HostA) Counter-example execution trace:
+> [  0.000000] (1:server@HostA) [(1)HostA (server)] iRecv (dst=(1)HostA (server), buff=(verbose only), size=(verbose only))
+> [  0.000000] (1:server@HostA) [(3)HostC (client)] iSend (src=(3)HostC (client), buff=(verbose only), size=(verbose only))
+> [  0.000000] (1:server@HostA) [(1)HostA (server)] Wait (comm=(verbose only) [(3)HostC (client)-> (1)HostA (server)])
+> [  0.000000] (1:server@HostA) [(3)HostC (client)] Wait (comm=(verbose only) [(3)HostC (client)-> (1)HostA (server)])
+> [  0.000000] (1:server@HostA) [(1)HostA (server)] iRecv (dst=(1)HostA (server), buff=(verbose only), size=(verbose only))
+> [  0.000000] (1:server@HostA) [(3)HostC (client)] iSend (src=(3)HostC (client), buff=(verbose only), size=(verbose only))
+> [  0.000000] (1:server@HostA) [(1)HostA (server)] Wait (comm=(verbose only) [(3)HostC (client)-> (1)HostA (server)])
+> [  0.000000] (1:server@HostA) Expanded states = 461
+> [  0.000000] (1:server@HostA) Visited states = 2271
+> [  0.000000] (1:server@HostA) Executed transitions = 2117
index 77736f9..04fc1da 100644 (file)
@@ -91,6 +91,30 @@ XBT_PUBLIC_DATA(int (*mpi_coll_reduce_fun)
                 (void *buf, void *rbuf, int count, MPI_Datatype datatype,
                  MPI_Op op, int root, MPI_Comm comm));
 
+/** \ingroup MPI reduce_scatter
+ *  \brief The list of all available allgather collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_reduce_scatter_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_reduce_scatter_fun)
+                (void *sbuf, void *rbuf, int *rcounts,
+                 MPI_Datatype dtype, MPI_Op op,MPI_Comm comm));
+
+/** \ingroup MPI scatter
+ *  \brief The list of all available allgather collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_scatter_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_scatter_fun)
+                (void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                void *recvbuf, int recvcount, MPI_Datatype recvtype,
+                int root, MPI_Comm comm));
+
+/** \ingroup MPI barrier
+ *  \brief The list of all available allgather collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_barrier_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_barrier_fun)
+                (MPI_Comm comm));
+
 
 XBT_PUBLIC(void) coll_help(const char *category,
                            s_mpi_coll_description_t * table);
index ebb65ea..08990a5 100644 (file)
@@ -395,8 +395,9 @@ void MC_dpor(void)
         MC_SET_RAW_MEM;
         xbt_fifo_shift(mc_stack_safety);
         MC_state_delete(state);
+        XBT_DEBUG("Delete state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1);
         MC_UNSET_RAW_MEM;
-
+        
         max_depth_reached = 0;
       }
       
@@ -427,11 +428,11 @@ void MC_dpor(void)
                 XBT_DEBUG("Dependent Transitions:");
                 prev_req = MC_state_get_executed_request(prev_state, &value);
                 req_str = MC_request_to_string(prev_req, value);
-                XBT_DEBUG("%s (state=%p)", req_str, prev_state);
+                XBT_DEBUG("%s (state=%d)", req_str, prev_state->num);
                 xbt_free(req_str);
                 prev_req = MC_state_get_executed_request(state, &value);
                 req_str = MC_request_to_string(prev_req, value);
-                XBT_DEBUG("%s (state=%p)", req_str, state);
+                XBT_DEBUG("%s (state=%d)", req_str, state->num);
                 xbt_free(req_str);              
               }
 
@@ -447,13 +448,17 @@ void MC_dpor(void)
               XBT_DEBUG("Simcall %d and %d with same issuer", req->call, MC_state_get_internal_request(prev_state)->call);
               break;
 
+            }else{
+
+              XBT_DEBUG("Simcall %d, process %lu (state %d) and simcall %d, process %lu (state %d) are independant", req->call, req->issuer->pid, state->num, MC_state_get_internal_request(prev_state)->call, MC_state_get_internal_request(prev_state)->issuer->pid, prev_state->num);
+
             }
           }
         }
              
         if (MC_state_interleave_size(state) && xbt_fifo_size(mc_stack_safety) < _sg_mc_max_depth) {
           /* We found a back-tracking point, let's loop */
-          XBT_DEBUG("Back-tracking to depth %d", xbt_fifo_size(mc_stack_safety) + 1);
+          XBT_DEBUG("Back-tracking to state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1);
           if(_sg_mc_checkpoint){
             if(state->system_state != NULL){
               MC_restore_snapshot(state->system_state);
@@ -481,10 +486,10 @@ void MC_dpor(void)
             MC_UNSET_RAW_MEM;
             MC_replay(mc_stack_safety, -1);
           }
-          XBT_DEBUG("Back-tracking to depth %d", xbt_fifo_size(mc_stack_safety));
+          XBT_DEBUG("Back-tracking to state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety));
           break;
         } else {
-          XBT_DEBUG("Delete state at depth %d",xbt_fifo_size(mc_stack_safety) + 1); 
+          XBT_DEBUG("Delete state %d at depth %d", state->num, xbt_fifo_size(mc_stack_safety) + 1); 
           MC_state_delete(state);
         }
       }
index 3e03859..9ce5f61 100644 (file)
@@ -24,39 +24,43 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
   if(r1->call == SIMCALL_COMM_IRECV && r2->call == SIMCALL_COMM_ISEND)
     return FALSE;
 
-  if(   (r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
-        &&  r2->call == SIMCALL_COMM_WAIT){
-
-    if(simcall_comm_wait__get__comm(r2)->comm.rdv == NULL)
-      return FALSE;
+  if((r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
+     &&  r2->call == SIMCALL_COMM_WAIT){
 
     smx_rdv_t rdv = r1->call == SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r1) : simcall_comm_irecv__get__rdv(r1);
 
-    if((simcall_comm_wait__get__comm(r2)->comm.rdv != rdv) && (simcall_comm_wait__get__timeout(r2) <= 0))
+    if(rdv != simcall_comm_wait__get__comm(r2)->comm.rdv_cpy && simcall_comm_wait__get__timeout(r2) <= 0)
+      return FALSE;
+
+    if((r1->issuer != simcall_comm_wait__get__comm(r2)->comm.src_proc) && (r1->issuer != simcall_comm_wait__get__comm(r2)->comm.dst_proc))
       return FALSE;
 
-    if((simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND) && (r1->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__timeout(r2) <= 0))
+    if((r1->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND) 
+       && (simcall_comm_wait__get__comm(r2)->comm.src_buff != simcall_comm_isend__get__src_buff(r1)))
       return FALSE;
 
-    if((simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE) && (r1->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__timeout(r2) <= 0))
+    if((r1->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE) 
+       && (simcall_comm_wait__get__comm(r2)->comm.dst_buff != simcall_comm_irecv__get__dst_buff(r1)))
       return FALSE;
   }
 
-  if(   (r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
+  if((r2->call == SIMCALL_COMM_ISEND || r2->call == SIMCALL_COMM_IRECV)
         &&  r1->call == SIMCALL_COMM_WAIT){
 
-    if(simcall_comm_wait__get__comm(r1)->comm.rdv != NULL)
-      return FALSE;
-
     smx_rdv_t rdv = r2->call == SIMCALL_COMM_ISEND ? simcall_comm_isend__get__rdv(r2) : simcall_comm_irecv__get__rdv(r2);
 
-    if((simcall_comm_wait__get__comm(r1)->comm.rdv != rdv) && (simcall_comm_wait__get__timeout(r1) <= 0))
+    if(rdv != simcall_comm_wait__get__comm(r1)->comm.rdv_cpy && simcall_comm_wait__get__timeout(r1) <= 0)
       return FALSE;
 
-    if((simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_SEND) && (r2->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__timeout(r1) <= 0))
+    if((r2->issuer != simcall_comm_wait__get__comm(r1)->comm.src_proc) && (r2->issuer != simcall_comm_wait__get__comm(r1)->comm.dst_proc))
+        return FALSE;  
+
+    if((r2->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_SEND) 
+       && (simcall_comm_wait__get__comm(r1)->comm.src_buff != simcall_comm_isend__get__src_buff(r2)))
       return FALSE;
 
-    if((simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE) && (r2->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__timeout(r1) <= 0))
+    if((r2->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE) 
+       && (simcall_comm_wait__get__comm(r1)->comm.dst_buff != simcall_comm_irecv__get__dst_buff(r2)))
       return FALSE;
   }
 
index 797a0ae..3022b61 100644 (file)
@@ -276,6 +276,15 @@ static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
 {
   _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);  
 }
+static void _sg_cfg_cb__coll_reduce_scatter(const char *name, int pos){
+  _sg_cfg_cb__coll("reduce_scatter", mpi_coll_reduce_scatter_description, name, pos);
+}
+static void _sg_cfg_cb__coll_scatter(const char *name, int pos){
+  _sg_cfg_cb__coll("scatter", mpi_coll_scatter_description, name, pos);
+}
+static void _sg_cfg_cb__coll_barrier(const char *name, int pos){
+  _sg_cfg_cb__coll("barrier", mpi_coll_barrier_description, name, pos);
+}
 #endif
 
 /* callback of the inclusion path */
@@ -772,6 +781,21 @@ void sg_config_init(int *argc, char **argv)
                     xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allgather,
                     NULL);
 
+    xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
+                    "Which collective to use for barrier",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_barrier,
+                    NULL);
+
+    xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
+                    "Which collective to use for reduce_scatter",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_reduce_scatter,
+                    NULL);
+
+    xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
+                    "Which collective to use for scatter",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_scatter,
+                    NULL);
+
     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
                     "Which collective to use for allgatherv",
                     xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allgatherv,
index 3cdc13b..3be4eb5 100644 (file)
@@ -199,6 +199,9 @@ smx_action_t SIMIX_fifo_get_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
       xbt_fifo_remove_item(fifo, item);
       xbt_fifo_free_item(item);
       action->comm.refcount++;
+#ifdef HAVE_MC
+      action->comm.rdv_cpy = action->comm.rdv;
+#endif
       action->comm.rdv = NULL;
       return action;
     }
index c966f22..1130ff9 100644 (file)
@@ -132,6 +132,12 @@ typedef struct s_smx_action {
     struct {
       e_smx_comm_type_t type;         /* Type of the communication (SIMIX_COMM_SEND or SIMIX_COMM_RECEIVE) */
       smx_rdv_t rdv;                  /* Rendez-vous where the comm is queued */
+
+#ifdef HAVE_MC
+      smx_rdv_t rdv_cpy;              /* Copy of the rendez-vous where the comm is queued, MC needs it for DPOR 
+                                         (comm.rdv set to NULL when the communication is removed from the mailbox 
+                                         (used as garbage collector)) */
+#endif
       int refcount;                   /* Number of processes involved in the cond */
       int detached;                   /* If detached or not */
 
diff --git a/src/smpi/colls/barrier-ompi.c b/src/smpi/colls/barrier-ompi.c
new file mode 100644 (file)
index 0000000..ad5b748
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
+ *                         University Research and Technology
+ *                         Corporation.  All rights reserved.
+ * Copyright (c) 2004-2006 The University of Tennessee and The University
+ *                         of Tennessee Research Foundation.  All rights
+ *                         reserved.
+ * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
+ *                         University of Stuttgart.  All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ *                         All rights reserved.
+ * Copyright (c) 2008      Sun Microsystems, Inc.  All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#include "colls_private.h"
+#include "coll_tuned_topo.h"
+
+
+#define MCA_COLL_BASE_TAG_BARRIER 100
+/*
+ * Barrier is ment to be a synchronous operation, as some BTLs can mark 
+ * a request done before its passed to the NIC and progress might not be made 
+ * elsewhere we cannot allow a process to exit the barrier until its last 
+ * [round of] sends are completed.
+ *
+ * It is last round of sends rather than 'last' individual send as each pair of 
+ * peers can use different channels/devices/btls and the receiver of one of 
+ * these sends might be forced to wait as the sender
+ * leaves the collective and does not make progress until the next mpi call 
+ *
+ */
+
+/*
+ * Simple double ring version of barrier
+ *
+ * synchronous gurantee made by last ring of sends are synchronous
+ *
+ */
+int smpi_coll_tuned_barrier_ompi_doublering(MPI_Comm comm
+                                            )
+{
+    int rank, size;
+    int left, right;
+
+
+    rank = smpi_comm_rank(comm);
+    size = smpi_comm_size(comm);
+
+    XBT_DEBUG("ompi_coll_tuned_barrier_ompi_doublering rank %d", rank);
+  
+    left = ((rank-1)%size);
+    right = ((rank+1)%size);
+
+    if (rank > 0) { /* receive message from the left */
+        smpi_mpi_recv((void*)NULL, 0, MPI_BYTE, left, 
+                                MCA_COLL_BASE_TAG_BARRIER, comm, 
+                                MPI_STATUS_IGNORE);
+    }
+
+    /* Send message to the right */
+    smpi_mpi_send((void*)NULL, 0, MPI_BYTE, right, 
+                            MCA_COLL_BASE_TAG_BARRIER, 
+                             comm);
+
+    /* root needs to receive from the last node */
+    if (rank == 0) {
+        smpi_mpi_recv((void*)NULL, 0, MPI_BYTE, left, 
+                                MCA_COLL_BASE_TAG_BARRIER, comm, 
+                                MPI_STATUS_IGNORE);
+    }
+
+    /* Allow nodes to exit */
+    if (rank > 0) { /* post Receive from left */
+        smpi_mpi_recv((void*)NULL, 0, MPI_BYTE, left, 
+                                MCA_COLL_BASE_TAG_BARRIER, comm, 
+                                MPI_STATUS_IGNORE);
+    }
+
+    /* send message to the right one */
+    smpi_mpi_send((void*)NULL, 0, MPI_BYTE, right, 
+                            MCA_COLL_BASE_TAG_BARRIER, 
+                             comm);
+    /* rank 0 post receive from the last node */
+    if (rank == 0) {
+        smpi_mpi_recv((void*)NULL, 0, MPI_BYTE, left, 
+                                MCA_COLL_BASE_TAG_BARRIER, comm, 
+                                MPI_STATUS_IGNORE);
+    }
+
+    return MPI_SUCCESS;
+
+}
+
+
+/*
+ * To make synchronous, uses sync sends and sync sendrecvs
+ */
+
+int smpi_coll_tuned_barrier_ompi_recursivedoubling(MPI_Comm comm
+                                                   )
+{
+    int rank, size, adjsize;
+    int mask, remote;
+
+    rank = smpi_comm_rank(comm);
+    size = smpi_comm_size(comm);
+    XBT_DEBUG(
+                 "ompi_coll_tuned_barrier_ompi_recursivedoubling rank %d", 
+                 rank);
+
+    /* do nearest power of 2 less than size calc */
+    for( adjsize = 1; adjsize <= size; adjsize <<= 1 );
+    adjsize >>= 1;
+
+    /* if size is not exact power of two, perform an extra step */
+    if (adjsize != size) {
+        if (rank >= adjsize) {
+            /* send message to lower ranked node */
+            remote = rank - adjsize;
+            smpi_mpi_sendrecv(NULL, 0, MPI_BYTE, remote,
+                                                  MCA_COLL_BASE_TAG_BARRIER,
+                                                  NULL, 0, MPI_BYTE, remote,
+                                                  MCA_COLL_BASE_TAG_BARRIER,
+                                                  comm, MPI_STATUS_IGNORE);
+
+        } else if (rank < (size - adjsize)) {
+
+            /* receive message from high level rank */
+            smpi_mpi_recv((void*)NULL, 0, MPI_BYTE, rank+adjsize,
+                                    MCA_COLL_BASE_TAG_BARRIER, comm, 
+                                    MPI_STATUS_IGNORE);
+
+        }
+    }
+
+    /* exchange messages */
+    if ( rank < adjsize ) {
+        mask = 0x1;
+        while ( mask < adjsize ) {
+            remote = rank ^ mask;
+            mask <<= 1;
+            if (remote >= adjsize) continue;
+
+            /* post receive from the remote node */
+            smpi_mpi_sendrecv(NULL, 0, MPI_BYTE, remote,
+                                                  MCA_COLL_BASE_TAG_BARRIER,
+                                                  NULL, 0, MPI_BYTE, remote,
+                                                  MCA_COLL_BASE_TAG_BARRIER,
+                                                  comm, MPI_STATUS_IGNORE);
+        }
+    }
+
+    /* non-power of 2 case */
+    if (adjsize != size) {
+        if (rank < (size - adjsize)) {
+            /* send enter message to higher ranked node */
+            remote = rank + adjsize;
+            smpi_mpi_send((void*)NULL, 0, MPI_BYTE, remote, 
+                                    MCA_COLL_BASE_TAG_BARRIER, 
+                                     comm);
+
+        }
+    }
+
+    return MPI_SUCCESS;
+
+}
+
+
+/*
+ * To make synchronous, uses sync sends and sync sendrecvs
+ */
+
+int smpi_coll_tuned_barrier_ompi_bruck(MPI_Comm comm
+                                       )
+{
+    int rank, size;
+    int distance, to, from;
+
+    rank = smpi_comm_rank(comm);
+    size = smpi_comm_size(comm);
+    XBT_DEBUG(
+                 "ompi_coll_tuned_barrier_ompi_bruck rank %d", rank);
+
+    /* exchange data with rank-2^k and rank+2^k */
+    for (distance = 1; distance < size; distance <<= 1) { 
+        from = (rank + size - distance) % size;
+        to   = (rank + distance) % size;
+
+        /* send message to lower ranked node */
+        smpi_mpi_sendrecv(NULL, 0, MPI_BYTE, to, 
+                                              MCA_COLL_BASE_TAG_BARRIER,
+                                              NULL, 0, MPI_BYTE, from, 
+                                              MCA_COLL_BASE_TAG_BARRIER,
+                                              comm, MPI_STATUS_IGNORE);
+    }
+
+    return MPI_SUCCESS;
+
+}
+
+
+/*
+ * To make synchronous, uses sync sends and sync sendrecvs
+ */
+/* special case for two processes */
+int smpi_coll_tuned_barrier_ompi_two_procs(MPI_Comm comm
+                                           )
+{
+    int remote;
+
+    remote = smpi_comm_rank(comm);
+    XBT_DEBUG(
+                 "ompi_coll_tuned_barrier_ompi_two_procs rank %d", remote);
+    remote = (remote + 1) & 0x1;
+
+    smpi_mpi_sendrecv(NULL, 0, MPI_BYTE, remote, 
+                                          MCA_COLL_BASE_TAG_BARRIER, 
+                                          NULL, 0, MPI_BYTE, remote, 
+                                          MCA_COLL_BASE_TAG_BARRIER,
+                                          comm, MPI_STATUS_IGNORE);
+    return (MPI_SUCCESS);
+}
+
+
+/*
+ * Linear functions are copied from the BASIC coll module
+ * they do not segment the message and are simple implementations
+ * but for some small number of nodes and/or small data sizes they
+ * are just as fast as tuned/tree based segmenting operations
+ * and as such may be selected by the decision functions
+ * These are copied into this module due to the way we select modules
+ * in V1. i.e. in V2 we will handle this differently and so will not
+ * have to duplicate code.
+ * GEF Oct05 after asking Jeff.
+ */
+
+/* copied function (with appropriate renaming) starts here */
+
+int smpi_coll_tuned_barrier_ompi_basic_linear(MPI_Comm comm)
+{
+    int i;
+    int size = smpi_comm_size(comm);
+    int rank = smpi_comm_rank(comm);
+
+    /* All non-root send & receive zero-length message. */
+
+    if (rank > 0) {
+        smpi_mpi_send (NULL, 0, MPI_BYTE, 0, 
+                                 MCA_COLL_BASE_TAG_BARRIER,
+                                  comm);
+
+        smpi_mpi_recv (NULL, 0, MPI_BYTE, 0, 
+                                 MCA_COLL_BASE_TAG_BARRIER,
+                                 comm, MPI_STATUS_IGNORE);
+    }
+
+    /* The root collects and broadcasts the messages. */
+
+    else {
+        MPI_Request* requests;
+
+        requests = (MPI_Request*)malloc( size * sizeof(MPI_Request) );
+        for (i = 1; i < size; ++i) {
+            requests[i] = smpi_mpi_irecv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE,
+                                     MCA_COLL_BASE_TAG_BARRIER, comm
+                                     );
+        }
+        smpi_mpi_waitall( size-1, requests+1, MPI_STATUSES_IGNORE );
+
+        for (i = 1; i < size; ++i) {
+            requests[i] = smpi_mpi_isend(NULL, 0, MPI_BYTE, i,
+                                     MCA_COLL_BASE_TAG_BARRIER, 
+                                      comm
+                                     );
+        }
+        smpi_mpi_waitall( size-1, requests+1, MPI_STATUSES_IGNORE );
+        free( requests );
+    }
+
+    /* All done */
+
+    return MPI_SUCCESS;
+
+}
+/* copied function (with appropriate renaming) ends here */
+
+/*
+ * Another recursive doubling type algorithm, but in this case
+ * we go up the tree and back down the tree.  
+ */
+int smpi_coll_tuned_barrier_ompi_tree(MPI_Comm comm)
+{
+    int rank, size, depth;
+    int jump, partner;
+
+    rank = smpi_comm_rank(comm);
+    size = smpi_comm_size(comm);
+    XBT_DEBUG(
+                 "ompi_coll_tuned_barrier_ompi_tree %d", 
+                 rank);
+
+    /* Find the nearest power of 2 of the communicator size. */
+    for(depth = 1; depth < size; depth <<= 1 );
+
+    for (jump=1; jump<depth; jump<<=1) {
+        partner = rank ^ jump;
+        if (!(partner & (jump-1)) && partner < size) {
+            if (partner > rank) {
+                smpi_mpi_recv (NULL, 0, MPI_BYTE, partner, 
+                                         MCA_COLL_BASE_TAG_BARRIER, comm,
+                                         MPI_STATUS_IGNORE);
+            } else if (partner < rank) {
+                smpi_mpi_send (NULL, 0, MPI_BYTE, partner,
+                                         MCA_COLL_BASE_TAG_BARRIER, 
+                                          comm);
+            }
+        }
+    }
+    
+    depth>>=1;
+    for (jump = depth; jump>0; jump>>=1) {
+        partner = rank ^ jump;
+        if (!(partner & (jump-1)) && partner < size) {
+            if (partner > rank) {
+                smpi_mpi_send (NULL, 0, MPI_BYTE, partner,
+                                         MCA_COLL_BASE_TAG_BARRIER,
+                                          comm);
+            } else if (partner < rank) {
+                smpi_mpi_recv (NULL, 0, MPI_BYTE, partner, 
+                                         MCA_COLL_BASE_TAG_BARRIER, comm,
+                                         MPI_STATUS_IGNORE);
+            }
+        }
+    }
+
+    return MPI_SUCCESS;
+}
index 4495b4d..09e47ce 100644 (file)
@@ -213,4 +213,52 @@ COLL_APPLY(action, COLL_REDUCE_SIG, ompi_binomial)
 
 COLL_REDUCES(COLL_PROTO, COLL_NOsep)
 
+/*************
+ * REDUCE_SCATTER *
+ *************/
+#define COLL_REDUCE_SCATTER_SIG reduce_scatter, int, \
+                         (void *sbuf, void *rbuf, int *rcounts,\
+                    MPI_Datatype dtype,MPI_Op  op,MPI_Comm  comm)
+
+#define COLL_REDUCE_SCATTERS(action, COLL_sep) \
+COLL_APPLY(action, COLL_REDUCE_SCATTER_SIG, ompi) COLL_sep \
+COLL_APPLY(action, COLL_REDUCE_SCATTER_SIG, ompi_basic_recursivehalving) COLL_sep \
+COLL_APPLY(action, COLL_REDUCE_SCATTER_SIG, ompi_ring) 
+
+COLL_REDUCE_SCATTERS(COLL_PROTO, COLL_NOsep)
+
+
+/*************
+ * SCATTER *
+ *************/
+#define COLL_SCATTER_SIG scatter, int, \
+                (void *sendbuf, int sendcount, MPI_Datatype sendtype,\
+                void *recvbuf, int recvcount, MPI_Datatype recvtype,\
+                int root, MPI_Comm comm)
+
+#define COLL_SCATTERS(action, COLL_sep) \
+COLL_APPLY(action, COLL_SCATTER_SIG, ompi) COLL_sep \
+COLL_APPLY(action, COLL_SCATTER_SIG, ompi_basic_linear) COLL_sep \
+COLL_APPLY(action, COLL_SCATTER_SIG, ompi_binomial) 
+
+COLL_SCATTERS(COLL_PROTO, COLL_NOsep)
+
+/*************
+ * SCATTER *
+ *************/
+#define COLL_BARRIER_SIG barrier, int, \
+                (MPI_Comm comm)
+
+#define COLL_BARRIERS(action, COLL_sep) \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi) COLL_sep \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi_basic_linear) COLL_sep \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi_two_procs)  COLL_sep \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi_tree)  COLL_sep \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi_bruck)  COLL_sep \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi_recursivedoubling) COLL_sep \
+COLL_APPLY(action, COLL_BARRIER_SIG, ompi_doublering)  
+
+COLL_BARRIERS(COLL_PROTO, COLL_NOsep)
+
+
 #endif
diff --git a/src/smpi/colls/reduce_scatter-ompi.c b/src/smpi/colls/reduce_scatter-ompi.c
new file mode 100644 (file)
index 0000000..e10be98
--- /dev/null
@@ -0,0 +1,515 @@
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
+ *                         University Research and Technology
+ *                         Corporation.  All rights reserved.
+ * Copyright (c) 2004-2012 The University of Tennessee and The University
+ *                         of Tennessee Research Foundation.  All rights
+ *                         reserved.
+ * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
+ *                         University of Stuttgart.  All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ *                         All rights reserved.
+ * Copyright (c) 2008      Sun Microsystems, Inc.  All rights reserved.
+ * Copyright (c) 2009      University of Houston. All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+#include "colls_private.h"
+#include "coll_tuned_topo.h"
+
+#define MCA_COLL_BASE_TAG_REDUCE_SCATTER 222
+/*
+ * Recursive-halving function is (*mostly*) copied from the BASIC coll module.
+ * I have removed the part which handles "large" message sizes 
+ * (non-overlapping version of reduce_Scatter).
+ */
+
+/* copied function (with appropriate renaming) starts here */
+
+/*
+ *  reduce_scatter_ompi_basic_recursivehalving
+ *
+ *  Function:   - reduce scatter implementation using recursive-halving 
+ *                algorithm
+ *  Accepts:    - same as MPI_Reduce_scatter()
+ *  Returns:    - MPI_SUCCESS or error code
+ *  Limitation: - Works only for commutative operations.
+ */
+int
+smpi_coll_tuned_reduce_scatter_ompi_basic_recursivehalving(void *sbuf, 
+                                                            void *rbuf, 
+                                                            int *rcounts,
+                                                            MPI_Datatype dtype,
+                                                            MPI_Op op,
+                                                            MPI_Comm comm
+                                                            )
+{
+    int i, rank, size, count, err = MPI_SUCCESS;
+    int tmp_size=1, remain = 0, tmp_rank, *disps = NULL;
+    ptrdiff_t true_lb, true_extent, lb, extent, buf_size;
+    char *recv_buf = NULL, *recv_buf_free = NULL;
+    char *result_buf = NULL, *result_buf_free = NULL;
+   
+    /* Initialize */
+    rank = smpi_comm_rank(comm);
+    size = smpi_comm_size(comm);
+   
+    XBT_DEBUG("coll:tuned:reduce_scatter_ompi_basic_recursivehalving, rank %d", rank);
+
+    /* Find displacements and the like */
+    disps = (int*) xbt_malloc(sizeof(int) * size);
+    if (NULL == disps) return MPI_ERR_OTHER;
+
+    disps[0] = 0;
+    for (i = 0; i < (size - 1); ++i) {
+        disps[i + 1] = disps[i] + rcounts[i];
+    }
+    count = disps[size - 1] + rcounts[size - 1];
+
+    /* short cut the trivial case */
+    if (0 == count) {
+        xbt_free(disps);
+        return MPI_SUCCESS;
+    }
+
+    /* get datatype information */
+    smpi_datatype_extent(dtype, &lb, &extent);
+    smpi_datatype_extent(dtype, &true_lb, &true_extent);
+    buf_size = true_extent + (ptrdiff_t)(count - 1) * extent;
+
+    /* Handle MPI_IN_PLACE */
+    if (MPI_IN_PLACE == sbuf) {
+        sbuf = rbuf;
+    }
+
+    /* Allocate temporary receive buffer. */
+    recv_buf_free = (char*) xbt_malloc(buf_size);
+    recv_buf = recv_buf_free - lb;
+    if (NULL == recv_buf_free) {
+        err = MPI_ERR_OTHER;
+        goto cleanup;
+    }
+   
+    /* allocate temporary buffer for results */
+    result_buf_free = (char*) xbt_malloc(buf_size);
+    result_buf = result_buf_free - lb;
+   
+    /* copy local buffer into the temporary results */
+    err =smpi_datatype_copy(sbuf, count, dtype, result_buf, count, dtype);
+    if (MPI_SUCCESS != err) goto cleanup;
+   
+    /* figure out power of two mapping: grow until larger than
+       comm size, then go back one, to get the largest power of
+       two less than comm size */
+    while (tmp_size <= size) tmp_size <<= 1;
+    tmp_size >>= 1;
+    remain = size - tmp_size;
+   
+    /* If comm size is not a power of two, have the first "remain"
+       procs with an even rank send to rank + 1, leaving a power of
+       two procs to do the rest of the algorithm */
+    if (rank < 2 * remain) {
+        if ((rank & 1) == 0) {
+            smpi_mpi_send(result_buf, count, dtype, rank + 1, 
+                                    MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                    comm);
+            /* we don't participate from here on out */
+            tmp_rank = -1;
+        } else {
+            smpi_mpi_recv(recv_buf, count, dtype, rank - 1,
+                                    MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                    comm, MPI_STATUS_IGNORE);
+         
+            /* integrate their results into our temp results */
+            smpi_op_apply(op, recv_buf, result_buf, &count, &dtype);
+         
+            /* adjust rank to be the bottom "remain" ranks */
+            tmp_rank = rank / 2;
+        }
+    } else {
+        /* just need to adjust rank to show that the bottom "even
+           remain" ranks dropped out */
+        tmp_rank = rank - remain;
+    }
+   
+    /* For ranks not kicked out by the above code, perform the
+       recursive halving */
+    if (tmp_rank >= 0) {
+        int *tmp_disps = NULL, *tmp_rcounts = NULL;
+        int mask, send_index, recv_index, last_index;
+      
+        /* recalculate disps and rcounts to account for the
+           special "remainder" processes that are no longer doing
+           anything */
+        tmp_rcounts = (int*) xbt_malloc(tmp_size * sizeof(int));
+        if (NULL == tmp_rcounts) {
+            err = MPI_ERR_OTHER;
+            goto cleanup;
+        }
+        tmp_disps = (int*) xbt_malloc(tmp_size * sizeof(int));
+        if (NULL == tmp_disps) {
+            xbt_free(tmp_rcounts);
+            err = MPI_ERR_OTHER;
+            goto cleanup;
+        }
+
+        for (i = 0 ; i < tmp_size ; ++i) {
+            if (i < remain) {
+                /* need to include old neighbor as well */
+                tmp_rcounts[i] = rcounts[i * 2 + 1] + rcounts[i * 2];
+            } else {
+                tmp_rcounts[i] = rcounts[i + remain];
+            }
+        }
+
+        tmp_disps[0] = 0;
+        for (i = 0; i < tmp_size - 1; ++i) {
+            tmp_disps[i + 1] = tmp_disps[i] + tmp_rcounts[i];
+        }
+
+        /* do the recursive halving communication.  Don't use the
+           dimension information on the communicator because I
+           think the information is invalidated by our "shrinking"
+           of the communicator */
+        mask = tmp_size >> 1;
+        send_index = recv_index = 0;
+        last_index = tmp_size;
+        while (mask > 0) {
+            int tmp_peer, peer, send_count, recv_count;
+            MPI_Request request;
+
+            tmp_peer = tmp_rank ^ mask;
+            peer = (tmp_peer < remain) ? tmp_peer * 2 + 1 : tmp_peer + remain;
+
+            /* figure out if we're sending, receiving, or both */
+            send_count = recv_count = 0;
+            if (tmp_rank < tmp_peer) {
+                send_index = recv_index + mask;
+                for (i = send_index ; i < last_index ; ++i) {
+                    send_count += tmp_rcounts[i];
+                }
+                for (i = recv_index ; i < send_index ; ++i) {
+                    recv_count += tmp_rcounts[i];
+                }
+            } else {
+                recv_index = send_index + mask;
+                for (i = send_index ; i < recv_index ; ++i) {
+                    send_count += tmp_rcounts[i];
+                }
+                for (i = recv_index ; i < last_index ; ++i) {
+                    recv_count += tmp_rcounts[i];
+                }
+            }
+
+            /* actual data transfer.  Send from result_buf,
+               receive into recv_buf */
+            if (send_count > 0 && recv_count != 0) {
+                request=smpi_mpi_irecv(recv_buf + (ptrdiff_t)tmp_disps[recv_index] * extent,
+                                         recv_count, dtype, peer,
+                                         MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                         comm);
+                if (MPI_SUCCESS != err) {
+                    xbt_free(tmp_rcounts);
+                    xbt_free(tmp_disps);
+                    goto cleanup;
+                }                                             
+            }
+            if (recv_count > 0 && send_count != 0) {
+                smpi_mpi_send(result_buf + (ptrdiff_t)tmp_disps[send_index] * extent,
+                                        send_count, dtype, peer, 
+                                        MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                        comm);
+                if (MPI_SUCCESS != err) {
+                    xbt_free(tmp_rcounts);
+                    xbt_free(tmp_disps);
+                    goto cleanup;
+                }                                             
+            }
+            if (send_count > 0 && recv_count != 0) {
+                smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+            }
+
+            /* if we received something on this step, push it into
+               the results buffer */
+            if (recv_count > 0) {
+                smpi_op_apply(op, 
+                               recv_buf + (ptrdiff_t)tmp_disps[recv_index] * extent, 
+                               result_buf + (ptrdiff_t)tmp_disps[recv_index] * extent,
+                               &recv_count, &dtype);
+            }
+
+            /* update for next iteration */
+            send_index = recv_index;
+            last_index = recv_index + mask;
+            mask >>= 1;
+        }
+
+        /* copy local results from results buffer into real receive buffer */
+        if (0 != rcounts[rank]) {
+            err = smpi_datatype_copy(result_buf + disps[rank] * extent,
+                                       rcounts[rank], dtype, 
+                                       rbuf, rcounts[rank], dtype);
+            if (MPI_SUCCESS != err) {
+                xbt_free(tmp_rcounts);
+                xbt_free(tmp_disps);
+                goto cleanup;
+            }                                             
+        }
+
+        xbt_free(tmp_rcounts);
+        xbt_free(tmp_disps);
+    }
+
+    /* Now fix up the non-power of two case, by having the odd
+       procs send the even procs the proper results */
+    if (rank < (2 * remain)) {
+        if ((rank & 1) == 0) {
+            if (rcounts[rank]) {
+                smpi_mpi_recv(rbuf, rcounts[rank], dtype, rank + 1,
+                                        MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                        comm, MPI_STATUS_IGNORE);
+            }
+        } else {
+            if (rcounts[rank - 1]) {
+                smpi_mpi_send(result_buf + disps[rank - 1] * extent,
+                                        rcounts[rank - 1], dtype, rank - 1,
+                                        MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                        comm);
+            }
+        }            
+    }
+
+ cleanup:
+    if (NULL != disps) xbt_free(disps);
+    if (NULL != recv_buf_free) xbt_free(recv_buf_free);
+    if (NULL != result_buf_free) xbt_free(result_buf_free);
+
+    return err;
+}
+
+/* copied function (with appropriate renaming) ends here */
+
+
+/*
+ *   smpi_coll_tuned_reduce_scatter_ompi_ring
+ *
+ *   Function:       Ring algorithm for reduce_scatter operation
+ *   Accepts:        Same as MPI_Reduce_scatter()
+ *   Returns:        MPI_SUCCESS or error code
+ *
+ *   Description:    Implements ring algorithm for reduce_scatter: 
+ *                   the block sizes defined in rcounts are exchanged and 
+ 8                    updated until they reach proper destination.
+ *                   Algorithm requires 2 * max(rcounts) extra buffering
+ *
+ *   Limitations:    The algorithm DOES NOT preserve order of operations so it 
+ *                   can be used only for commutative operations.
+ *         Example on 5 nodes:
+ *         Initial state
+ *   #      0              1             2              3             4
+ *        [00]           [10]   ->     [20]           [30]           [40]
+ *        [01]           [11]          [21]  ->       [31]           [41]
+ *        [02]           [12]          [22]           [32]  ->       [42]
+ *    ->  [03]           [13]          [23]           [33]           [43] --> ..
+ *        [04]  ->       [14]          [24]           [34]           [44]
+ *
+ *        COMPUTATION PHASE
+ *         Step 0: rank r sends block (r-1) to rank (r+1) and 
+ *                 receives block (r+1) from rank (r-1) [with wraparound].
+ *   #      0              1             2              3             4
+ *        [00]           [10]        [10+20]   ->     [30]           [40]
+ *        [01]           [11]          [21]          [21+31]  ->     [41]
+ *    ->  [02]           [12]          [22]           [32]         [32+42] -->..
+ *      [43+03] ->       [13]          [23]           [33]           [43]
+ *        [04]         [04+14]  ->     [24]           [34]           [44]
+ *         
+ *         Step 1:
+ *   #      0              1             2              3             4
+ *        [00]           [10]        [10+20]       [10+20+30] ->     [40]
+ *    ->  [01]           [11]          [21]          [21+31]      [21+31+41] ->
+ *     [32+42+02] ->     [12]          [22]           [32]         [32+42] 
+ *        [03]        [43+03+13] ->    [23]           [33]           [43]
+ *        [04]         [04+14]      [04+14+24]  ->    [34]           [44]
+ *
+ *         Step 2:
+ *   #      0              1             2              3             4
+ *     -> [00]           [10]        [10+20]       [10+20+30]   [10+20+30+40] ->
+ *   [21+31+41+01]->     [11]          [21]          [21+31]      [21+31+41]
+ *     [32+42+02]   [32+42+02+12]->    [22]           [32]         [32+42] 
+ *        [03]        [43+03+13]   [43+03+13+23]->    [33]           [43]
+ *        [04]         [04+14]      [04+14+24]    [04+14+24+34] ->   [44]
+ *
+ *         Step 3:
+ *   #      0             1              2              3             4
+ * [10+20+30+40+00]     [10]         [10+20]       [10+20+30]   [10+20+30+40]
+ *  [21+31+41+01] [21+31+41+01+11]     [21]          [21+31]      [21+31+41]
+ *    [32+42+02]   [32+42+02+12] [32+42+02+12+22]     [32]         [32+42] 
+ *       [03]        [43+03+13]    [43+03+13+23] [43+03+13+23+33]    [43]
+ *       [04]         [04+14]       [04+14+24]    [04+14+24+34] [04+14+24+34+44]
+ *    DONE :)
+ *
+ */
+int 
+smpi_coll_tuned_reduce_scatter_ompi_ring(void *sbuf, void *rbuf, int *rcounts,
+                                          MPI_Datatype dtype,
+                                          MPI_Op op,
+                                          MPI_Comm comm
+                                          )
+{
+    int ret, line, rank, size, i, k, recv_from, send_to, total_count, max_block_count;
+    int inbi, *displs = NULL;
+    char *tmpsend = NULL, *tmprecv = NULL, *accumbuf = NULL, *accumbuf_free = NULL;
+    char *inbuf_free[2] = {NULL, NULL}, *inbuf[2] = {NULL, NULL};
+    ptrdiff_t true_lb, true_extent, lb, extent, max_real_segsize;
+    MPI_Request reqs[2] = {NULL, NULL};
+
+    size = smpi_comm_size(comm);
+    rank = smpi_comm_rank(comm);
+
+    XBT_DEBUG(  "coll:tuned:reduce_scatter_ompi_ring rank %d, size %d", 
+                 rank, size);
+
+    /* Determine the maximum number of elements per node, 
+       corresponding block size, and displacements array.
+    */
+    displs = (int*) xbt_malloc(size * sizeof(int));
+    if (NULL == displs) { ret = -1; line = __LINE__; goto error_hndl; }
+    displs[0] = 0;
+    total_count = rcounts[0];
+    max_block_count = rcounts[0];
+    for (i = 1; i < size; i++) { 
+        displs[i] = total_count;
+        total_count += rcounts[i];
+        if (max_block_count < rcounts[i]) max_block_count = rcounts[i];
+    }
+      
+    /* Special case for size == 1 */
+    if (1 == size) {
+        if (MPI_IN_PLACE != sbuf) {
+            ret = smpi_datatype_copy((char*)sbuf, total_count, dtype, (char*)rbuf, total_count, dtype);
+            if (ret < 0) { line = __LINE__; goto error_hndl; }
+        }
+        xbt_free(displs);
+        return MPI_SUCCESS;
+    }
+
+    /* Allocate and initialize temporary buffers, we need:
+       - a temporary buffer to perform reduction (size total_count) since
+       rbuf can be of rcounts[rank] size.
+       - up to two temporary buffers used for communication/computation overlap.
+    */
+    smpi_datatype_extent(dtype, &lb, &extent);
+    smpi_datatype_extent(dtype, &true_lb, &true_extent);
+
+    max_real_segsize = true_extent + (ptrdiff_t)(max_block_count - 1) * extent;
+
+    accumbuf_free = (char*)xbt_malloc(true_extent + (ptrdiff_t)(total_count - 1) * extent);
+    if (NULL == accumbuf_free) { ret = -1; line = __LINE__; goto error_hndl; }
+    accumbuf = accumbuf_free - lb;
+
+    inbuf_free[0] = (char*)xbt_malloc(max_real_segsize);
+    if (NULL == inbuf_free[0]) { ret = -1; line = __LINE__; goto error_hndl; }
+    inbuf[0] = inbuf_free[0] - lb;
+    if (size > 2) {
+        inbuf_free[1] = (char*)xbt_malloc(max_real_segsize);
+        if (NULL == inbuf_free[1]) { ret = -1; line = __LINE__; goto error_hndl; }
+        inbuf[1] = inbuf_free[1] - lb;
+    }
+
+    /* Handle MPI_IN_PLACE for size > 1 */
+    if (MPI_IN_PLACE == sbuf) {
+        sbuf = rbuf;
+    }
+
+    ret = smpi_datatype_copy((char*)sbuf, total_count, dtype, accumbuf, total_count, dtype);
+    if (ret < 0) { line = __LINE__; goto error_hndl; }
+
+    /* Computation loop */
+
+    /* 
+       For each of the remote nodes:
+       - post irecv for block (r-2) from (r-1) with wrap around
+       - send block (r-1) to (r+1)
+       - in loop for every step k = 2 .. n
+       - post irecv for block (r - 1 + n - k) % n
+       - wait on block (r + n - k) % n to arrive
+       - compute on block (r + n - k ) % n
+       - send block (r + n - k) % n
+       - wait on block (r)
+       - compute on block (r)
+       - copy block (r) to rbuf
+       Note that we must be careful when computing the begining of buffers and
+       for send operations and computation we must compute the exact block size.
+    */
+    send_to = (rank + 1) % size;
+    recv_from = (rank + size - 1) % size;
+
+    inbi = 0;
+    /* Initialize first receive from the neighbor on the left */
+    reqs[inbi]=smpi_mpi_irecv(inbuf[inbi], max_block_count, dtype, recv_from,
+                             MCA_COLL_BASE_TAG_REDUCE_SCATTER, comm
+                             );
+    tmpsend = accumbuf + (ptrdiff_t)displs[recv_from] * extent;
+    smpi_mpi_send(tmpsend, rcounts[recv_from], dtype, send_to,
+                            MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                             comm);
+
+    for (k = 2; k < size; k++) {
+        const int prevblock = (rank + size - k) % size;
+      
+        inbi = inbi ^ 0x1;
+
+        /* Post irecv for the current block */
+        reqs[inbi]=smpi_mpi_irecv(inbuf[inbi], max_block_count, dtype, recv_from,
+                                 MCA_COLL_BASE_TAG_REDUCE_SCATTER, comm 
+                                 );
+      
+        /* Wait on previous block to arrive */
+        smpi_mpi_wait(&reqs[inbi ^ 0x1], MPI_STATUS_IGNORE);
+      
+        /* Apply operation on previous block: result goes to rbuf
+           rbuf[prevblock] = inbuf[inbi ^ 0x1] (op) rbuf[prevblock]
+        */
+        tmprecv = accumbuf + (ptrdiff_t)displs[prevblock] * extent;
+        smpi_op_apply(op, inbuf[inbi ^ 0x1], tmprecv, &(rcounts[prevblock]), &dtype);
+      
+        /* send previous block to send_to */
+        smpi_mpi_send(tmprecv, rcounts[prevblock], dtype, send_to,
+                                MCA_COLL_BASE_TAG_REDUCE_SCATTER,
+                                 comm);
+    }
+
+    /* Wait on the last block to arrive */
+    smpi_mpi_wait(&reqs[inbi], MPI_STATUS_IGNORE);
+
+    /* Apply operation on the last block (my block)
+       rbuf[rank] = inbuf[inbi] (op) rbuf[rank] */
+    tmprecv = accumbuf + (ptrdiff_t)displs[rank] * extent;
+    smpi_op_apply(op, inbuf[inbi], tmprecv, &(rcounts[rank]), &dtype);
+   
+    /* Copy result from tmprecv to rbuf */
+    ret = smpi_datatype_copy(tmprecv, rcounts[rank], dtype, (char*)rbuf, rcounts[rank], dtype);
+    if (ret < 0) { line = __LINE__; goto error_hndl; }
+
+    if (NULL != displs) xbt_free(displs);
+    if (NULL != accumbuf_free) xbt_free(accumbuf_free);
+    if (NULL != inbuf_free[0]) xbt_free(inbuf_free[0]);
+    if (NULL != inbuf_free[1]) xbt_free(inbuf_free[1]);
+
+    return MPI_SUCCESS;
+
+ error_hndl:
+    XBT_DEBUG( "%s:%4d\tRank %d Error occurred %d\n",
+                 __FILE__, line, rank, ret);
+    if (NULL != displs) xbt_free(displs);
+    if (NULL != accumbuf_free) xbt_free(accumbuf_free);
+    if (NULL != inbuf_free[0]) xbt_free(inbuf_free[0]);
+    if (NULL != inbuf_free[1]) xbt_free(inbuf_free[1]);
+    return ret;
+}
+
diff --git a/src/smpi/colls/scatter-ompi.c b/src/smpi/colls/scatter-ompi.c
new file mode 100644 (file)
index 0000000..205d602
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
+ *                         University Research and Technology
+ *                         Corporation.  All rights reserved.
+ * Copyright (c) 2004-2006 The University of Tennessee and The University
+ *                         of Tennessee Research Foundation.  All rights
+ *                         reserved.
+ * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
+ *                         University of Stuttgart.  All rights reserved.
+ * Copyright (c) 2004-2005 The Regents of the University of California.
+ *                         All rights reserved.
+ * $COPYRIGHT$
+ *
+ * Additional copyrights may follow
+ *
+ * $HEADER$
+ */
+
+
+#include "colls_private.h"
+#include "coll_tuned_topo.h"
+
+#define MCA_COLL_BASE_TAG_SCATTER 111
+
+int
+smpi_coll_tuned_scatter_ompi_binomial(void *sbuf, int scount,
+                                      MPI_Datatype sdtype,
+                                      void *rbuf, int rcount,
+                                      MPI_Datatype rdtype,
+                                      int root,
+                                      MPI_Comm comm
+                                      )
+{
+    int line = -1;
+    int i;
+    int rank;
+    int vrank;
+    int size;
+    int total_send = 0;
+    char *ptmp     = NULL;
+    char *tempbuf  = NULL;
+    int err;
+    ompi_coll_tree_t* bmtree;
+    MPI_Status status;
+    MPI_Aint sextent, slb, strue_lb, strue_extent; 
+    MPI_Aint rextent, rlb, rtrue_lb, rtrue_extent;
+
+    size = smpi_comm_size(comm);
+    rank = smpi_comm_rank(comm);
+
+    XBT_DEBUG(
+                 "smpi_coll_tuned_scatter_ompi_binomial rank %d", rank);
+
+    /* create the binomial tree */
+    
+//    COLL_TUNED_UPDATE_IN_ORDER_BMTREE( comm, tuned_module, root );
+    bmtree =  ompi_coll_tuned_topo_build_in_order_bmtree( comm, root);//ompi_ data->cached_in_order_bmtree;
+
+    smpi_datatype_extent(sdtype, &slb, &sextent);
+    smpi_datatype_extent(sdtype, &strue_lb, &strue_extent);
+    smpi_datatype_extent(rdtype, &rlb, &rextent);
+    smpi_datatype_extent(rdtype, &rtrue_lb, &rtrue_extent);
+
+    vrank = (rank - root + size) % size;
+
+    if (rank == root) {
+       if (0 == root) {
+           /* root on 0, just use the send buffer */
+           ptmp = (char *) sbuf;
+           if (rbuf != MPI_IN_PLACE) {
+               /* local copy to rbuf */
+               err = smpi_datatype_copy(sbuf, scount, sdtype,
+                                     rbuf, rcount, rdtype);
+               if (MPI_SUCCESS != err) { line = __LINE__; goto err_hndl; }
+           }
+       } else {
+           /* root is not on 0, allocate temp buffer for send */
+           tempbuf = (char *) malloc(strue_extent + (scount*size - 1) * sextent);
+           if (NULL == tempbuf) {
+               err = MPI_ERR_OTHER; line = __LINE__; goto err_hndl;
+           }
+
+           ptmp = tempbuf - slb;
+
+           /* and rotate data so they will eventually in the right place */
+           err = smpi_datatype_copy((char *) sbuf + sextent*root*scount, scount*(size-root), sdtype,
+            ptmp, scount*(size-root), sdtype);
+           if (MPI_SUCCESS != err) { line = __LINE__; goto err_hndl; }
+
+
+           err = smpi_datatype_copy((char*)sbuf, scount*root, sdtype,
+                                                ptmp + sextent*scount*(size - root), scount*root, sdtype);
+           if (MPI_SUCCESS != err) { line = __LINE__; goto err_hndl; }
+
+           if (rbuf != MPI_IN_PLACE) {
+               /* local copy to rbuf */
+               err = smpi_datatype_copy(ptmp, scount, sdtype,
+                                     rbuf, rcount, rdtype);
+               if (MPI_SUCCESS != err) { line = __LINE__; goto err_hndl; }
+           }
+       }
+       total_send = scount;
+    } else if (!(vrank % 2)) {
+       /* non-root, non-leaf nodes, allocte temp buffer for recv
+        * the most we need is rcount*size/2 */
+       tempbuf = (char *) malloc(rtrue_extent + (rcount*size - 1) * rextent);
+       if (NULL == tempbuf) {
+           err= MPI_ERR_OTHER; line = __LINE__; goto err_hndl;
+       }
+
+       ptmp = tempbuf - rlb;
+
+       sdtype = rdtype;
+       scount = rcount;
+       sextent = rextent;
+       total_send = scount;
+    } else {
+       /* leaf nodes, just use rbuf */
+       ptmp = (char *) rbuf;
+    }
+
+    if (!(vrank % 2)) {
+       if (rank != root) {
+           /* recv from parent on non-root */
+           smpi_mpi_recv(ptmp, rcount*size, rdtype, bmtree->tree_prev,
+                                   MCA_COLL_BASE_TAG_SCATTER, comm, &status);
+           /* local copy to rbuf */
+           err = smpi_datatype_copy(ptmp, scount, sdtype,
+                                 rbuf, rcount, rdtype);
+       }
+       /* send to children on all non-leaf */
+       for (i = 0; i < bmtree->tree_nextsize; i++) {
+           int mycount = 0, vkid;
+           /* figure out how much data I have to send to this child */
+           vkid = (bmtree->tree_next[i] - root + size) % size;
+           mycount = vkid - vrank;
+           if (mycount > (size - vkid))
+               mycount = size - vkid;
+           mycount *= scount;
+
+           smpi_mpi_send(ptmp + total_send*sextent, mycount, sdtype,
+                                   bmtree->tree_next[i],
+                                   MCA_COLL_BASE_TAG_SCATTER,
+                                    comm);
+
+           total_send += mycount;
+       }
+
+       if (NULL != tempbuf) 
+           free(tempbuf);
+    } else {
+       /* recv from parent on leaf nodes */
+       smpi_mpi_recv(ptmp, rcount, rdtype, bmtree->tree_prev,
+                               MCA_COLL_BASE_TAG_SCATTER, comm, &status);
+    }
+
+    return MPI_SUCCESS;
+
+ err_hndl:
+    if (NULL != tempbuf)
+       free(tempbuf);
+
+    XBT_DEBUG(  "%s:%4d\tError occurred %d, rank %2d",
+                __FILE__, line, err, rank);
+    return err;
+}
+
+/*
+ * Linear functions are copied from the BASIC coll module
+ * they do not segment the message and are simple implementations
+ * but for some small number of nodes and/or small data sizes they 
+ * are just as fast as tuned/tree based segmenting operations 
+ * and as such may be selected by the decision functions
+ * These are copied into this module due to the way we select modules
+ * in V1. i.e. in V2 we will handle this differently and so will not
+ * have to duplicate code.
+ * JPG following the examples from other coll_tuned implementations. Dec06.
+ */
+
+/* copied function (with appropriate renaming) starts here */
+/*
+ *     scatter_intra
+ *
+ *     Function:       - basic scatter operation
+ *     Accepts:        - same arguments as MPI_Scatter()
+ *     Returns:        - MPI_SUCCESS or error code
+ */
+int
+smpi_coll_tuned_scatter_ompi_basic_linear(void *sbuf, int scount,
+                                          MPI_Datatype sdtype,
+                                          void *rbuf, int rcount,
+                                          MPI_Datatype rdtype,
+                                          int root,
+                                          MPI_Comm comm
+                                          )
+{
+    int i, rank, size, err;
+    char *ptmp;
+    ptrdiff_t lb, incr;
+
+    /* Initialize */
+
+    rank = smpi_comm_rank(comm);
+    size = smpi_comm_size(comm);
+
+    /* If not root, receive data. */
+
+    if (rank != root) {
+        smpi_mpi_recv(rbuf, rcount, rdtype, root,
+                                MCA_COLL_BASE_TAG_SCATTER,
+                                comm, MPI_STATUS_IGNORE);
+        return MPI_SUCCESS;
+    }
+
+    /* I am the root, loop sending data. */
+
+    err = smpi_datatype_extent(sdtype, &lb, &incr);
+    if (MPI_SUCCESS != err) {
+        return MPI_ERR_OTHER;
+    }
+
+    incr *= scount;
+    for (i = 0, ptmp = (char *) sbuf; i < size; ++i, ptmp += incr) {
+
+        /* simple optimization */
+
+        if (i == rank) {
+            if (MPI_IN_PLACE != rbuf) {
+                err =
+                    smpi_datatype_copy(ptmp, scount, sdtype, rbuf, rcount,
+                                    rdtype);
+            }
+        } else {
+            smpi_mpi_send(ptmp, scount, sdtype, i,
+                                    MCA_COLL_BASE_TAG_SCATTER,
+                                     comm);
+        }
+        if (MPI_SUCCESS != err) {
+            return err;
+        }
+    }
+
+    /* All done */
+
+    return MPI_SUCCESS;
+}
index 72c3699..819242f 100644 (file)
@@ -99,27 +99,27 @@ int smpi_coll_tuned_alltoallv_ompi(void *sbuf, int *scounts, int *sdisps,
                                                         comm);
 }
 
-/*
-void smpi_coll_tuned_barrier_ompi(MPI_Comm  comm)
+
+int smpi_coll_tuned_barrier_ompi(MPI_Comm  comm)
 {    int communicator_size = smpi_comm_size(comm);
 
     if( 2 == communicator_size )
-        return smpi_coll_tuned_barrier_intra_two_procs(comm, module);
-     * Basic optimisation. If we have a power of 2 number of nodes
-     * the use the recursive doubling algorithm, otherwise
-     * bruck is the one we want.
+        return smpi_coll_tuned_barrier_ompi_two_procs(comm);
+/*     * Basic optimisation. If we have a power of 2 number of nodes*/
+/*     * the use the recursive doubling algorithm, otherwise*/
+/*     * bruck is the one we want.*/
     {
-        bool has_one = false;
+        int has_one = 0;
         for( ; communicator_size > 0; communicator_size >>= 1 ) {
             if( communicator_size & 0x1 ) {
                 if( has_one )
-                    return smpi_coll_tuned_barrier_intra_bruck(comm, module);
-                has_one = true;
+                    return smpi_coll_tuned_barrier_ompi_bruck(comm);
+                has_one = 1;
             }
         }
     }
-    return smpi_coll_tuned_barrier_intra_recursivedoubling(comm, module);
-}*/
+    return smpi_coll_tuned_barrier_ompi_recursivedoubling(comm);
+}
 
 int smpi_coll_tuned_bcast_ompi(void *buff, int count,
                                           MPI_Datatype datatype, int root,
@@ -324,11 +324,11 @@ int smpi_coll_tuned_reduce_ompi( void *sendbuf, void *recvbuf,
 #endif  /* 0 */
 }
 
-/*int smpi_coll_tuned_reduce_scatter_ompi( void *sbuf, void *rbuf,
+int smpi_coll_tuned_reduce_scatter_ompi( void *sbuf, void *rbuf,
                                                     int *rcounts,
                                                     MPI_Datatype dtype,
                                                     MPI_Op  op,
-                                                    MPI_Comm  comm,
+                                                    MPI_Comm  comm
                                                     )
 {
     int comm_size, i, pow2;
@@ -337,25 +337,26 @@ int smpi_coll_tuned_reduce_ompi( void *sendbuf, void *recvbuf,
     const double b = 8.0;
     const size_t small_message_size = 12 * 1024;
     const size_t large_message_size = 256 * 1024;
-    bool zerocounts = false;
-
-    OPAL_OUTPUT((smpi_coll_tuned_stream, "smpi_coll_tuned_reduce_scatter_ompi"));
+    int zerocounts = 0;
 
+    XBT_DEBUG("smpi_coll_tuned_reduce_scatter_ompi");
+    
     comm_size = smpi_comm_size(comm);
     // We need data size for decision function 
-    ompi_datatype_type_size(dtype, &dsize);
+    dsize=smpi_datatype_size(dtype);
     total_message_size = 0;
     for (i = 0; i < comm_size; i++) { 
         total_message_size += rcounts[i];
         if (0 == rcounts[i]) {
-            zerocounts = true;
+            zerocounts = 1;
         }
     }
 
-    if( !ompi_op_is_commute(op) || (zerocounts)) {
-        return smpi_coll_tuned_reduce_scatter_intra_nonoverlapping (sbuf, rbuf, rcounts, 
+    if( !smpi_op_is_commute(op) || (zerocounts)) {
+        smpi_mpi_reduce_scatter (sbuf, rbuf, rcounts, 
                                                                     dtype, op, 
-                                                                    comm, module); 
+                                                                    comm); 
+        return MPI_SUCCESS;
     }
    
     total_message_size *= dsize;
@@ -367,20 +368,17 @@ int smpi_coll_tuned_reduce_ompi( void *sendbuf, void *recvbuf,
         ((total_message_size <= large_message_size) && (pow2 == comm_size)) ||
         (comm_size >= a * total_message_size + b)) {
         return 
-            smpi_coll_tuned_reduce_scatter_intra_basic_recursivehalving(sbuf, rbuf, rcounts,
+            smpi_coll_tuned_reduce_scatter_ompi_basic_recursivehalving(sbuf, rbuf, rcounts,
                                                                         dtype, op,
-                                                                        comm, module);
+                                                                        comm);
     } 
-    return smpi_coll_tuned_reduce_scatter_intra_ring(sbuf, rbuf, rcounts,
+    return smpi_coll_tuned_reduce_scatter_ompi_ring(sbuf, rbuf, rcounts,
                                                      dtype, op,
-                                                     comm, module);
+                                                     comm);
 
-  
-    return smpi_coll_tuned_reduce_scatter(sbuf, rbuf, rcounts,
-                                                     dtype, op,
-                                                     comm;
 
-}*/
+
+}
 
 int smpi_coll_tuned_allgather_ompi(void *sbuf, int scount, 
                                               MPI_Datatype sdtype,
@@ -570,12 +568,12 @@ int smpi_coll_tuned_gather_ompi(void *sbuf, int scount,
                                                       rbuf, rcount, rdtype, 
                                                       root, comm);
 }
-/*
+
 int smpi_coll_tuned_scatter_ompi(void *sbuf, int scount, 
                                             MPI_Datatype sdtype,
                                             void* rbuf, int rcount, 
                                             MPI_Datatype rdtype, 
-                                            int root, MPI_Comm  comm,
+                                            int root, MPI_Comm  comm
                                             )
 {
     const size_t small_block_size = 300;
@@ -583,28 +581,27 @@ int smpi_coll_tuned_scatter_ompi(void *sbuf, int scount,
     int communicator_size, rank;
     size_t dsize, block_size;
 
-    OPAL_OUTPUT((smpi_coll_tuned_stream, 
-                 "smpi_coll_tuned_scatter_ompi"));
+    XBT_DEBUG("smpi_coll_tuned_scatter_ompi");
 
     communicator_size = smpi_comm_size(comm);
-    rank = ompi_comm_rank(comm);
+    rank = smpi_comm_rank(comm);
     // Determine block size 
     if (root == rank) {
-        ompi_datatype_type_size(sdtype, &dsize);
+        dsize=smpi_datatype_size(sdtype);
         block_size = dsize * scount;
     } else {
-        ompi_datatype_type_size(rdtype, &dsize);
+        dsize=smpi_datatype_size(rdtype);
         block_size = dsize * rcount;
     } 
 
     if ((communicator_size > small_comm_size) &&
         (block_size < small_block_size)) {
-        return smpi_coll_tuned_scatter_intra_binomial (sbuf, scount, sdtype, 
+        return smpi_coll_tuned_scatter_ompi_binomial (sbuf, scount, sdtype, 
                                                        rbuf, rcount, rdtype, 
-                                                       root, comm, module);
+                                                       root, comm);
     }
-    return smpi_coll_tuned_scatter_intra_basic_linear (sbuf, scount, sdtype, 
+    return smpi_coll_tuned_scatter_ompi_basic_linear (sbuf, scount, sdtype, 
                                                        rbuf, rcount, rdtype, 
-                                                       root, comm, module);
-}*/
+                                                       root, comm);
+}
 
index cf46856..156337f 100644 (file)
@@ -211,6 +211,8 @@ void smpi_mpi_barrier(MPI_Comm comm);
 void smpi_mpi_gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                      void *recvbuf, int recvcount, MPI_Datatype recvtype,
                      int root, MPI_Comm comm);
+void smpi_mpi_reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
+                       MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
 void smpi_mpi_gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                       void *recvbuf, int *recvcounts, int *displs,
                       MPI_Datatype recvtype, int root, MPI_Comm comm);
index baf4891..067cd82 100644 (file)
@@ -941,6 +941,27 @@ void smpi_mpi_gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   }
 }
 
+
+void smpi_mpi_reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
+                       MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+    int i, size, count;
+    int *displs;
+    int rank = smpi_process_index();
+    /* arbitrarily choose root as rank 0 */
+    size = smpi_comm_size(comm);
+    count = 0;
+    displs = xbt_new(int, size);
+    for (i = 0; i < size; i++) {
+      displs[i] = count;
+      count += recvcounts[i];
+    }
+    mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, 0, comm);
+    smpi_mpi_scatterv(recvbuf, recvcounts, displs, datatype, recvbuf,
+                      recvcounts[rank], datatype, 0, comm);
+    xbt_free(displs);
+}
+
 void smpi_mpi_gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                       void *recvbuf, int *recvcounts, int *displs,
                       MPI_Datatype recvtype, int root, MPI_Comm comm)
index f242c77..172ddb1 100644 (file)
@@ -47,6 +47,29 @@ COLL_ALLREDUCES(COLL_DESCRIPTION, COLL_COMMA),
   {NULL, NULL, NULL}      /* this array must be NULL terminated */
 };
 
+s_mpi_coll_description_t mpi_coll_reduce_scatter_description[] = {
+  {"default",
+   "reduce_scatter default collective",
+   smpi_mpi_reduce_scatter},
+COLL_REDUCE_SCATTERS(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_mpi_coll_description_t mpi_coll_scatter_description[] = {
+  {"default",
+   "scatter default collective",
+   smpi_mpi_scatter},
+COLL_SCATTERS(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_mpi_coll_description_t mpi_coll_barrier_description[] = {
+  {"default",
+   "barrier default collective",
+   smpi_mpi_barrier},
+COLL_BARRIERS(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
 s_mpi_coll_description_t mpi_coll_alltoall_description[] = {
   {"default",
    "Ompi alltoall default collective",
@@ -143,7 +166,9 @@ int (*mpi_coll_alltoall_fun)(void *, int, MPI_Datatype, void*, int, MPI_Datatype
 int (*mpi_coll_alltoallv_fun)(void *, int*, int*, MPI_Datatype, void*, int*, int*, MPI_Datatype, MPI_Comm);
 int (*mpi_coll_bcast_fun)(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm com);
 int (*mpi_coll_reduce_fun)(void *buf, void *rbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
-
+int (*mpi_coll_reduce_scatter_fun)(void *sbuf, void *rbuf, int *rcounts,MPI_Datatype dtype,MPI_Op  op,MPI_Comm  comm);
+int (*mpi_coll_scatter_fun)(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm);
+int (*mpi_coll_barrier_fun)(MPI_Comm comm);
 struct s_proc_tree {
   int PROCTREE_A;
   int numChildren;
index 189bac1..c62c103 100644 (file)
@@ -408,6 +408,24 @@ int smpi_main(int (*realmain) (int argc, char *argv[]),int argc, char *argv[])
                                  MPI_Op op, int root, MPI_Comm comm))
                        mpi_coll_reduce_description[reduce_id].coll;
 
+  int reduce_scatter_id = find_coll_description(mpi_coll_reduce_scatter_description,
+                                           sg_cfg_get_string("smpi/reduce_scatter"));
+  mpi_coll_reduce_scatter_fun = (int (*)(void *sbuf, void *rbuf, int *rcounts,\
+                    MPI_Datatype dtype,MPI_Op  op,MPI_Comm  comm))
+                          mpi_coll_reduce_scatter_description[reduce_scatter_id].coll;
+
+  int scatter_id = find_coll_description(mpi_coll_scatter_description,
+                                           sg_cfg_get_string("smpi/scatter"));
+  mpi_coll_scatter_fun = (int (*)(void *sendbuf, int sendcount, MPI_Datatype sendtype,\
+                void *recvbuf, int recvcount, MPI_Datatype recvtype,\
+                int root, MPI_Comm comm))
+                          mpi_coll_scatter_description[scatter_id].coll;
+
+  int barrier_id = find_coll_description(mpi_coll_barrier_description,
+                                           sg_cfg_get_string("smpi/barrier"));
+  mpi_coll_barrier_fun = (int (*)(MPI_Comm comm))
+                          mpi_coll_barrier_description[barrier_id].coll;
+
   smpi_global_init();
 
   /* Clean IO before the run */
index 783395b..64c66cb 100644 (file)
@@ -1579,7 +1579,7 @@ int PMPI_Barrier(MPI_Comm comm)
   if (comm == MPI_COMM_NULL) {
     retval = MPI_ERR_COMM;
   } else {
-    smpi_mpi_barrier(comm);
+    mpi_coll_barrier_fun(comm);
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
@@ -1735,7 +1735,7 @@ int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
              || recvtype == MPI_DATATYPE_NULL) {
     retval = MPI_ERR_TYPE;
   } else {
-    smpi_mpi_scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount,
+    mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
                      recvtype, root, comm);
     retval = MPI_SUCCESS;
   }
@@ -1869,12 +1869,10 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
 {
-  int retval, i, size, count;
-  int *displs;
-  int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
-
+  int retval;
   smpi_bench_end();
 #ifdef HAVE_TRACING
+  int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
   TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
@@ -1887,19 +1885,9 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
   } else if (recvcounts == NULL) {
     retval = MPI_ERR_ARG;
   } else {
-    /* arbitrarily choose root as rank 0 */
-    /* TODO: faster direct implementation ? */
-    size = smpi_comm_size(comm);
-    count = 0;
-    displs = xbt_new(int, size);
-    for (i = 0; i < size; i++) {
-      count += recvcounts[i];
-      displs[i] = 0;
-    }
-    mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, 0, comm);
-    smpi_mpi_scatterv(recvbuf, recvcounts, displs, datatype, recvbuf,
-                      recvcounts[rank], datatype, 0, comm);
-    xbt_free(displs);
+
+    mpi_coll_reduce_scatter_fun(sendbuf, recvbuf, recvcounts,
+                       datatype,  op, comm);
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
index 78de3f4..3def58b 100644 (file)
@@ -20,7 +20,8 @@ if(enable_smpi)
   add_executable(allreduce allreduce.c)
   add_executable(allreduce_coll allreduce_coll.c)  
   add_executable(bcast bcast.c)
-  add_executable(bcast_coll bcast_coll.c)  
+  add_executable(bcast_coll bcast_coll.c) 
+  add_executable(barrier_coll barrier.c )
   add_executable(compute compute.c)
   add_executable(compute2 compute2.c)
   add_executable(compute3 compute3.c)
@@ -28,6 +29,7 @@ if(enable_smpi)
   add_executable(scatter scatter.c)
   add_executable(reduce reduce.c)
   add_executable(reduce_coll reduce_coll.c)
+  add_executable(reduce_scatter_coll reduce_scatter_coll.c)
   add_executable(split split.c)
   add_executable(smpi_sendrecv sendrecv.c)
   add_executable(ttest01 ttest01.c)
@@ -54,6 +56,7 @@ if(enable_smpi)
   target_link_libraries(scatter simgrid)
   target_link_libraries(reduce simgrid)
   target_link_libraries(reduce_coll simgrid)      
+  target_link_libraries(reduce_scatter_coll simgrid)      
   target_link_libraries(split simgrid)
   target_link_libraries(smpi_sendrecv simgrid)
   target_link_libraries(ttest01 simgrid)
@@ -80,6 +83,8 @@ set(tesh_files
   ${CMAKE_CURRENT_SOURCE_DIR}/allreduce_coll.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/alltoall_coll.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/alltoallv_coll.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/scatter_coll.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/barrier_coll.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/bcast.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/bcast_coll.tesh  
   ${CMAKE_CURRENT_SOURCE_DIR}/compute.tesh
@@ -88,6 +93,7 @@ set(tesh_files
   ${CMAKE_CURRENT_SOURCE_DIR}/pt2pt.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/reduce.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/reduce_coll.tesh  
+  ${CMAKE_CURRENT_SOURCE_DIR}/reduce_scatter_coll.tesh  
   ${CMAKE_CURRENT_SOURCE_DIR}/struct.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/vector.tesh  
   PARENT_SCOPE
@@ -106,6 +112,7 @@ set(examples_src
   ${CMAKE_CURRENT_SOURCE_DIR}/alltoallv_coll.c  
   ${CMAKE_CURRENT_SOURCE_DIR}/bcast_coll.c
   ${CMAKE_CURRENT_SOURCE_DIR}/reduce_coll.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/reduce_scatter_coll.c
   ${CMAKE_CURRENT_SOURCE_DIR}/alltoallv_coll.c
   ${CMAKE_CURRENT_SOURCE_DIR}/get_processor_name.c
   ${CMAKE_CURRENT_SOURCE_DIR}/pingpong.c
index 568015e..7fb9a0c 100644 (file)
 int main(int argc, char **argv)
 {
   int size, rank;
-  int root = 0;
-  int value;
-  double start_timer;
+  //double start_timer;
 
   MPI_Init(&argc, &argv);
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
-  start_timer = MPI_Wtime();
+  //start_timer = MPI_Wtime();
 
   MPI_Barrier(MPI_COMM_WORLD);
 
   MPI_Barrier(MPI_COMM_WORLD);
   if (0 == rank) {
     printf("... Barrier ....\n");
-    printf("Elapsed=%lf s\n", MPI_Wtime() - start_timer);
+    //printf("Elapsed=%lf s\n", MPI_Wtime() - start_timer);
   }
 
   MPI_Finalize();
diff --git a/teshsuite/smpi/barrier_coll.tesh b/teshsuite/smpi/barrier_coll.tesh
new file mode 100644 (file)
index 0000000..a65b0de
--- /dev/null
@@ -0,0 +1,26 @@
+# Smpi  scatter collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test scatter
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./barrier_coll
+> ... Barrier ....
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [rank 0] -> Tremblay
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [rank 1] -> Jupiter
+> [rank 2] -> Fafard
+> [rank 3] -> Ginette
+> [rank 4] -> Bourassa
+> [rank 5] -> Tremblay
+> [rank 6] -> Jupiter
+> [rank 7] -> Fafard
+> [rank 8] -> Ginette
+> [rank 9] -> Bourassa
+
index 3cb057d..9cb824a 100644 (file)
@@ -31,10 +31,8 @@ int main( int argc, char **argv )
     recvcounts = (int *)malloc( size * sizeof(int) );
         recvbuf = (int *)malloc( size * sizeof(int) );
     for (i=0; i<size; i++) 
-       recvcounts[i] = 1;
-printf("rank : %d\n", rank);
+    recvcounts[i] = 1;
     MPI_Reduce_scatter( sendbuf, recvbuf, recvcounts, MPI_INT, MPI_SUM, comm );
-printf("rankt : %d\n", rank);
     sumval = size * rank + ((size - 1) * size)/2;
 /* recvbuf should be size * (rank + i) */
     if (recvbuf[0] != sumval) {
index 9cb6cf8..33a2703 100755 (executable)
@@ -155,7 +155,7 @@ RunTest allred2 4 "*** Allred2 ***"
 RunTest scattern 4 "*** Scattern ***"
 
 #fails, more debug needed to understand
-#RunTest redscat 4 "*** Reduce_scatter ***"
+RunTest redscat 4 "*** Reduce_scatter ***"
 
 RunTest alltoallv_mpich 4 "*** Alltoallv ***"
 echo "runtests: fortran ($have_fortran)"
diff --git a/teshsuite/smpi/reduce_scatter_coll.c b/teshsuite/smpi/reduce_scatter_coll.c
new file mode 100644 (file)
index 0000000..cba19bc
--- /dev/null
@@ -0,0 +1,50 @@
+/* 
+ * Test of reduce scatter.
+ *
+ * Each processor contributes its rank + the index to the reduction, 
+ * then receives the ith sum
+ *
+ * Can be called with any number of processors.
+ */
+
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int main( int argc, char **argv )
+{
+    int      err = 0, toterr;
+    int      *sendbuf, *recvbuf, *recvcounts;
+    int      size, rank, i, sumval;
+    MPI_Comm comm;
+
+
+    MPI_Init( &argc, &argv );
+    comm = MPI_COMM_WORLD;
+
+    MPI_Comm_size( comm, &size );
+    MPI_Comm_rank( comm, &rank );
+    sendbuf = (int *) malloc( size * sizeof(int) );
+    for (i=0; i<size; i++) 
+       sendbuf[i] = rank + i;
+    recvcounts = (int *)malloc( size * sizeof(int) );
+        recvbuf = (int *)malloc( size * sizeof(int) );
+    for (i=0; i<size; i++) 
+    recvcounts[i] = 1;
+    MPI_Reduce_scatter( sendbuf, recvbuf, recvcounts, MPI_INT, MPI_SUM, comm );
+    sumval = size * rank + ((size - 1) * size)/2;
+/* recvbuf should be size * (rank + i) */
+    if (recvbuf[0] != sumval) {
+       err++;
+       fprintf( stdout, "Did not get expected value for reduce scatter\n" );
+       fprintf( stdout, "[%d] Got %d expected %d\n", rank, recvbuf[0], sumval );
+    }
+
+    MPI_Allreduce( &err, &toterr, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
+    if (rank == 0 && toterr == 0) {
+       printf( " No Errors\n" );
+    }
+    MPI_Finalize( );
+
+    return toterr;
+}
diff --git a/teshsuite/smpi/reduce_scatter_coll.tesh b/teshsuite/smpi/reduce_scatter_coll.tesh
new file mode 100644 (file)
index 0000000..8c4a278
--- /dev/null
@@ -0,0 +1,25 @@
+# Smpi reduce scatter collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test reduce_scatter
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./reduce_scatter_coll 
+> No Errors
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [rank 0] -> Tremblay
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [rank 1] -> Jupiter
+> [rank 2] -> Fafard
+> [rank 3] -> Ginette
+> [rank 4] -> Bourassa
+> [rank 5] -> Tremblay
+> [rank 6] -> Jupiter
+> [rank 7] -> Fafard
+> [rank 8] -> Ginette
+> [rank 9] -> Bourassa
diff --git a/teshsuite/smpi/scatter_coll.tesh b/teshsuite/smpi/scatter_coll.tesh
new file mode 100644 (file)
index 0000000..f5d2c79
--- /dev/null
@@ -0,0 +1,58 @@
+# Smpi  scatter collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test scatter
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./scatter 
+>      [0] ok.
+>      [0] ok.
+>      [10] ok.
+>      [10] ok.
+>      [11] ok.
+>      [11] ok.
+>      [12] ok.
+>      [12] ok.
+>      [13] ok.
+>      [13] ok.
+>      [14] ok.
+>      [14] ok.
+>      [15] ok.
+>      [15] ok.
+>      [1] ok.
+>      [1] ok.
+>      [2] ok.
+>      [2] ok.
+>      [3] ok.
+>      [3] ok.
+>      [4] ok.
+>      [4] ok.
+>      [5] ok.
+>      [5] ok.
+>      [6] ok.
+>      [6] ok.
+>      [7] ok.
+>      [7] ok.
+>      [8] ok.
+>      [8] ok.
+>      [9] ok.
+>      [9] ok.
+> ** IBM Test Result: ... 
+> ** Small Test Result: ... 
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [rank 0] -> Tremblay
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [rank 1] -> Jupiter
+> [rank 2] -> Fafard
+> [rank 3] -> Ginette
+> [rank 4] -> Bourassa
+> [rank 5] -> Tremblay
+> [rank 6] -> Jupiter
+> [rank 7] -> Fafard
+> [rank 8] -> Ginette
+> [rank 9] -> Bourassa