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>
Mon, 15 Apr 2013 16:10:51 +0000 (18:10 +0200)
committerJonathan Rouzaud-Cornabas <jonathan.rouzaud-cornabas@ens-lyon.fr>
Mon, 15 Apr 2013 16:10:51 +0000 (18:10 +0200)
180 files changed:
.gitignore
ChangeLog
README.coding
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/Distrib.cmake
buildtools/Cmake/MakeLib.cmake
buildtools/Cmake/MakeLibWin.cmake
buildtools/Cmake/Option.cmake
doc/Doxyfile.in
doc/doxygen/bindings.doc
doc/doxygen/inside_extending.doc
doc/doxygen/module-msg.doc
doc/doxygen/module-smpi.doc [new file with mode: 0644]
doc/doxygen/modules.doc
examples/msg/mc/CMakeLists.txt
examples/msg/mc/bugged1.tesh
examples/msg/mc/bugged1_liveness.tesh
examples/msg/mc/chord/chord_liveness.h [deleted file]
examples/msg/mc/chord/chord_neverjoin.tesh [deleted file]
examples/msg/mc/chord_liveness/chord_liveness.c [moved from examples/msg/mc/chord/chord_liveness.c with 90% similarity]
examples/msg/mc/chord_liveness/chord_neverdeliver.tesh [new file with mode: 0644]
examples/msg/mc/chord_liveness/chord_neverjoin.tesh [new file with mode: 0644]
examples/msg/mc/chord_liveness/chord_neverjoin_timeout_visited.tesh [new file with mode: 0644]
examples/msg/mc/chord_liveness/deploy_chord_liveness.xml [moved from examples/msg/mc/chord/deploy_chord_liveness.xml with 100% similarity]
examples/msg/mc/chord_liveness/promela_chord_neverdeliver [new file with mode: 0644]
examples/msg/mc/chord_liveness/promela_chord_neverjoin [moved from examples/msg/mc/chord/promela_chord_liveness with 100% similarity]
examples/msg/mc/deploy_electric_fence.xml [moved from examples/msg/mc/deploy_random_test.xml with 71% similarity]
examples/msg/mc/electric_fence.c [new file with mode: 0644]
examples/msg/mc/random_test.c [deleted file]
examples/smpi/CMakeLists.txt
examples/smpi/MM/CMakeLists.txt
include/msg/msg.h
include/simgrid/platf.h
include/smpi/mpif.h
include/smpi/smpi.h
include/surf/simgrid_dtd.h
src/include/smpi/smpi_interface.h
src/include/surf/surfxml_parse_values.h
src/instr/instr_config.c
src/instr/instr_private.h
src/mc/mc_compare.c
src/mc/mc_dpor.c
src/mc/mc_global.c
src/mc/mc_liveness.c
src/mc/mc_request.c
src/mc/memory_map.c
src/msg/msg_mailbox.h
src/simgrid/sg_config.c
src/smpi/colls/COPYRIGHTS
src/smpi/colls/allgather-2dmesh.c [new file with mode: 0644]
src/smpi/colls/allgather-3dmesh.c [new file with mode: 0644]
src/smpi/colls/allgather-GB.c [new file with mode: 0644]
src/smpi/colls/allgather-NTSLR-NB.c [new file with mode: 0644]
src/smpi/colls/allgather-NTSLR.c [new file with mode: 0644]
src/smpi/colls/allgather-SMP-NTS.c [new file with mode: 0644]
src/smpi/colls/allgather-bruck.c [new file with mode: 0644]
src/smpi/colls/allgather-loosely-lr.c [new file with mode: 0644]
src/smpi/colls/allgather-lr.c [new file with mode: 0644]
src/smpi/colls/allgather-pair.c [new file with mode: 0644]
src/smpi/colls/allgather-rdb.c [new file with mode: 0644]
src/smpi/colls/allgather-rhv.c [new file with mode: 0644]
src/smpi/colls/allgather-ring.c [new file with mode: 0644]
src/smpi/colls/allgather-smp-simple.c [new file with mode: 0644]
src/smpi/colls/allgather-spreading-simple.c [new file with mode: 0644]
src/smpi/colls/allgatherv-GB.c [new file with mode: 0644]
src/smpi/colls/allgatherv-pair.c [new file with mode: 0644]
src/smpi/colls/allgatherv-ring.c [new file with mode: 0644]
src/smpi/colls/allreduce-NTS.c [new file with mode: 0644]
src/smpi/colls/allreduce-lr.c [new file with mode: 0644]
src/smpi/colls/allreduce-rab-rdb.c [new file with mode: 0644]
src/smpi/colls/allreduce-rab-reduce-scatter.c [new file with mode: 0644]
src/smpi/colls/allreduce-rab-rsag.c [new file with mode: 0644]
src/smpi/colls/allreduce-rab1.c [new file with mode: 0644]
src/smpi/colls/allreduce-rab2.c [new file with mode: 0644]
src/smpi/colls/allreduce-rdb.c [new file with mode: 0644]
src/smpi/colls/allreduce-redbcast.c [new file with mode: 0644]
src/smpi/colls/allreduce-smp-binomial-pipeline.c [new file with mode: 0644]
src/smpi/colls/allreduce-smp-binomial.c [new file with mode: 0644]
src/smpi/colls/allreduce-smp-rdb.c [new file with mode: 0644]
src/smpi/colls/allreduce-smp-rsag-lr.c [new file with mode: 0644]
src/smpi/colls/allreduce-smp-rsag-rab.c [new file with mode: 0644]
src/smpi/colls/allreduce-smp-rsag.c [new file with mode: 0644]
src/smpi/colls/alltoall-2dmesh.c
src/smpi/colls/alltoall-3dmesh.c
src/smpi/colls/alltoall-bruck.c
src/smpi/colls/alltoall-native.c [deleted file]
src/smpi/colls/alltoall-pair-light-barrier.c
src/smpi/colls/alltoall-pair-mpi-barrier.c
src/smpi/colls/alltoall-pair-one-barrier.c
src/smpi/colls/alltoall-pair.c
src/smpi/colls/alltoall-rdb.c
src/smpi/colls/alltoall-ring-light-barrier.c
src/smpi/colls/alltoall-ring-mpi-barrier.c
src/smpi/colls/alltoall-ring-one-barrier.c
src/smpi/colls/alltoall-ring.c
src/smpi/colls/alltoall-simple.c
src/smpi/colls/alltoallv-bruck.c [new file with mode: 0644]
src/smpi/colls/alltoallv-pair-light-barrier.c [new file with mode: 0644]
src/smpi/colls/alltoallv-pair-mpi-barrier.c [new file with mode: 0644]
src/smpi/colls/alltoallv-pair-one-barrier.c [new file with mode: 0644]
src/smpi/colls/alltoallv-pair.c [new file with mode: 0644]
src/smpi/colls/alltoallv-ring-light-barrier.c [new file with mode: 0644]
src/smpi/colls/alltoallv-ring-mpi-barrier.c [new file with mode: 0644]
src/smpi/colls/alltoallv-ring-one-barrier.c [new file with mode: 0644]
src/smpi/colls/alltoallv-ring.c [new file with mode: 0644]
src/smpi/colls/bcast-NTSB.c [new file with mode: 0644]
src/smpi/colls/bcast-NTSL-Isend.c [new file with mode: 0644]
src/smpi/colls/bcast-NTSL.c [new file with mode: 0644]
src/smpi/colls/bcast-SMP-binary.c [new file with mode: 0644]
src/smpi/colls/bcast-SMP-binomial.c [new file with mode: 0644]
src/smpi/colls/bcast-SMP-linear.c [new file with mode: 0644]
src/smpi/colls/bcast-arrival-nb.c [new file with mode: 0644]
src/smpi/colls/bcast-arrival-pattern-aware-wait.c [new file with mode: 0644]
src/smpi/colls/bcast-arrival-pattern-aware.c [new file with mode: 0644]
src/smpi/colls/bcast-arrival-scatter.c [new file with mode: 0644]
src/smpi/colls/bcast-binomial-tree.c [new file with mode: 0644]
src/smpi/colls/bcast-flattree-pipeline.c [new file with mode: 0644]
src/smpi/colls/bcast-flattree.c [new file with mode: 0644]
src/smpi/colls/bcast-scatter-LR-allgather.c [new file with mode: 0644]
src/smpi/colls/bcast-scatter-rdb-allgather.c [new file with mode: 0644]
src/smpi/colls/colls.h
src/smpi/colls/colls_global.c [new file with mode: 0644]
src/smpi/colls/colls_private.h [new file with mode: 0644]
src/smpi/colls/reduce-NTSL.c [new file with mode: 0644]
src/smpi/colls/reduce-arrival-pattern-aware.c [new file with mode: 0644]
src/smpi/colls/reduce-binomial.c [new file with mode: 0644]
src/smpi/colls/reduce-flat-tree.c [new file with mode: 0644]
src/smpi/colls/reduce-scatter-gather.c [new file with mode: 0644]
src/smpi/private.h
src/smpi/smpi_base.c
src/smpi/smpi_coll.c
src/smpi/smpi_f77.c
src/smpi/smpi_global.c
src/smpi/smpi_mpi.c
src/smpi/smpi_mpi_dt.c
src/smpi/smpi_mpi_dt_private.h
src/smpi/smpi_pmpi.c
src/smpi/smpi_replay.c
src/smpi/smpicc.in
src/smpi/smpif2c.in
src/smpi/smpif90.in
src/smpi/smpirun.in
src/surf/simgrid.dtd
src/surf/simgrid_dtd.c
src/surf/surf_routing.c
src/surf/surf_routing_cluster.c
src/surf/surf_routing_private.h
src/surf/surfxml_parse.c
src/xbt/log.c
src/xbt/mmalloc/mfree.c
src/xbt/mmalloc/mm_diff.c
src/xbt/mmalloc/mmprivate.h
src/xbt/xbt_os_time.c
teshsuite/smpi/CMakeLists.txt
teshsuite/smpi/allgather_coll.c [new file with mode: 0644]
teshsuite/smpi/allgather_coll.tesh [new file with mode: 0644]
teshsuite/smpi/allgatherv_coll.c [new file with mode: 0644]
teshsuite/smpi/allgatherv_coll.tesh [new file with mode: 0644]
teshsuite/smpi/allreduce_coll.c [new file with mode: 0644]
teshsuite/smpi/allreduce_coll.tesh [new file with mode: 0644]
teshsuite/smpi/alltoall_basic.c
teshsuite/smpi/alltoall_coll.c [new file with mode: 0644]
teshsuite/smpi/alltoall_coll.tesh [new file with mode: 0644]
teshsuite/smpi/alltoallv_coll.c [moved from teshsuite/smpi/alltoallv.c with 52% similarity]
teshsuite/smpi/alltoallv_coll.tesh [new file with mode: 0644]
teshsuite/smpi/bcast_coll.c [new file with mode: 0644]
teshsuite/smpi/bcast_coll.tesh [new file with mode: 0644]
teshsuite/smpi/mpich-test/coll/CMakeLists.txt
teshsuite/smpi/mpich-test/context/CMakeLists.txt
teshsuite/smpi/mpich-test/env/CMakeLists.txt
teshsuite/smpi/mpich-test/env/gtime.c
teshsuite/smpi/mpich-test/profile/CMakeLists.txt
teshsuite/smpi/mpich-test/pt2pt/CMakeLists.txt
teshsuite/smpi/reduce_coll.c [new file with mode: 0644]
teshsuite/smpi/reduce_coll.tesh [new file with mode: 0644]
teshsuite/xbt/mmalloc_32.tesh
teshsuite/xbt/mmalloc_64.tesh
tools/check_dist_archive.exclude
tools/tesh/run_context.c

index 47a2888..adb5d0e 100644 (file)
@@ -144,12 +144,6 @@ examples/msg/tracing/volume
 examples/msg/io/file
 examples/msg/io/file_unlink
 examples/msg/mc/bugged3
-examples/msg/mc/random_test
-examples/msg/mc/bugged1_for_liveness
-examples/msg/mc/bugged1_while_liveness
-examples/msg/mc/centralized_liveness_deadlock
-examples/msg/mc/test/test_heap_comparison
-examples/msg/mc/chord_liveness
 examples/msg/mc/test/snapshot_comparison1
 examples/msg/mc/test/snapshot_comparison2
 examples/msg/mc/test/snapshot_comparison3
index 5176313..2f30967 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,12 +12,14 @@ SimGrid (3.10) NOT RELEASED; urgency=low
    cached in the Java world
 
  SMPI:
+ * SMPI is not built as a separate library anymore, it's now included in
+   libsimgrid.
  * Improvements of the SMPI replay tool:
    - Most of the collective communications are now rooted in the same process as
      in the original application.
-   - Traces now rely on the same MPI datatype as the application (MPI_BYTE was 
+   - Traces now rely on the same MPI datatype as the application (MPI_BYTE was
      used until now). Multiple datatypes can now be used in a trace.
-   - The replay tool now supports traces produce either by TAU or a modified 
+   - The replay tool now supports traces produce either by TAU or a modified
      version of MPE.
    - Bug Fix: the compute part of the reduce action is now taken into account.
 
index e48b67f..4183390 100644 (file)
@@ -32,6 +32,16 @@ The tree is not split on projects, but on file finality:
  examples/ -> Supposed to be copy/pastable by the user, so keep it clear and
                 avoid any kind of trick. In particular, do only include the
                 public headers here.
+
+ teshsuite/ -> The more test the better. Put in there any strange test
+              doing things that the users are not supposed to do,
+              just to see if our framework is robust to incorrect and
+              unusual behaviors. All tests written in this section
+              should leverage our tesh(1) utility.
+ testsuite/ -> Old test suite, that should be converted to tesh and
+               moved to teshsuite at some point.
+
 **
 ** Indentation standard
 **
@@ -174,6 +184,9 @@ investigating the portability of the thing to windows.
       cmake -Denable_compile_optimizations=ON \
             -Denable_compile_warnings=ON
 
+* Your commit message should follow the git habits, explained eg here:
+  http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+
 * If you want to debug memory allocation problems, here are a few hints:
   - disable compiler optimizations, to have better backtraces;
   - disable the mallocators, or it will be hard to match malloc's with
@@ -191,3 +204,4 @@ investigating the portability of the thing to windows.
   deactivate the whole logging mechanism, switching to printfs
   instead. SimGrid becomes incredibly verbose when doing so, but it
   you let you fixing the dynars.
+  
\ No newline at end of file
index 1b3dda1..55ef3ea 100644 (file)
@@ -369,6 +369,40 @@ if(NOT enable_memcheck)
       ADD_TEST(smpi-tracing-ptp                 ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/tracing/smpi_traced.tesh)
       ADD_TEST(smpi-replay                      ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/smpi --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/replay/smpi_replay.tesh)
     endif()
+
+    FOREACH (ALLGATHER_COLL default  2dmesh 3dmesh bruck GB loosely_lr lr
+                           NTSLR NTSLR_NB pair rdb  rhv ring SMP_NTS
+                           smp_simple spreading_simple)
+        ADD_TEST(smpi-allgather-coll-${ALLGATHER_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/allgather:${ALLGATHER_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/allgather_coll.tesh)
+    ENDFOREACH()
+    FOREACH (ALLGATHERV_COLL default GB pair ring)
+        ADD_TEST(smpi-allgatherv-coll-${ALLGATHERV_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/allgatherv:${ALLGATHERV_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/allgatherv_coll.tesh)
+    ENDFOREACH()
+    FOREACH (ALLREDUCE_COLL default lr NTS rab1 rab2 rab_rdb
+                           rab_rsag rdb smp_binomial smp_binomial_pipeline
+                           smp_rdb smp_rsag smp_rsag_lr smp_rsag_rab redbcast)
+        ADD_TEST(smpi-allreduce-coll-${ALLREDUCE_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/allreduce:${ALLREDUCE_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/allreduce_coll.tesh)
+    ENDFOREACH()
+    FOREACH (ALLTOALL_COLL 2dmesh 3dmesh pair pair_one_barrier pair_light_barrier
+                          pair_mpi_barrier rdb ring ring_light_barrier
+                          ring_mpi_barrier ring_one_barrier
+                          simple bruck basic_linear)
+        ADD_TEST(smpi-alltoall-coll-${ALLTOALL_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/alltoall:${ALLTOALL_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/alltoall_coll.tesh)
+    ENDFOREACH()
+    FOREACH (ALLTOALLV_COLL default pair pair_light_barrier pair_mpi_barrier
+                           pair_one_barrier  ring ring_light_barrier
+                           ring_mpi_barrier ring_one_barrier bruck)
+        ADD_TEST(smpi-alltoallv-coll-${ALLTOALLV_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/alltoallv:${ALLTOALLV_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/alltoallv_coll.tesh)
+    ENDFOREACH()
+    FOREACH (BCAST_COLL default arrival_nb arrival_pattern_aware arrival_pattern_aware_wait arrival_scatter
+                       binomial_tree flattree flattree_pipeline NTSB NTSL NTSL_Isend scatter_LR_allgather
+                       scatter_rdb_allgather SMP_binary SMP_binomial SMP_linear)
+               ADD_TEST(smpi-bcast-coll-${BCAST_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/bcast:${BCAST_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/bcast_coll.tesh)
+    ENDFOREACH()
+    FOREACH (REDUCE_COLL default arrival_pattern_aware binomial flat_tree NTSL scatter_gather)
+        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()
+
   endif()
 
   # END TESH TESTS
@@ -415,13 +449,15 @@ if(NOT enable_memcheck)
       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-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)
-        ADD_TEST(mc-chord-neverjoin-ucontext      ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/chord --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/chord chord_neverjoin.tesh)
-        ADD_TEST(mc-test-snapshot-comparison1     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison1.tesh)
-        ADD_TEST(mc-test-snapshot-comparison2     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison2.tesh)
-        ADD_TEST(mc-test-snapshot-comparison3     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison3.tesh)
-        ADD_TEST(mc-test-snapshot-comparison4     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison4.tesh)
-        ADD_TEST(mc-test-snapshot-comparison5     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison5.tesh)
+        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)
+        ADD_TEST(mc-chord-neverjoin-ucontext                   ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/chord_liveness --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/chord_liveness chord_neverjoin.tesh)
+        ADD_TEST(mc-chord-neverdeliver-ucontext                ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/chord_liveness --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/chord_liveness chord_neverdeliver.tesh)
+        ADD_TEST(mc-chord-neverjoin-timeout-visited-ucontext   ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/chord_liveness --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/chord_liveness chord_neverjoin_timeout_visited.tesh)
+        ADD_TEST(mc-test-snapshot-comparison1                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison1.tesh)
+        ADD_TEST(mc-test-snapshot-comparison2                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison2.tesh)
+        ADD_TEST(mc-test-snapshot-comparison3                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison3.tesh)
+        ADD_TEST(mc-test-snapshot-comparison4                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison4.tesh)
+        ADD_TEST(mc-test-snapshot-comparison5                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc/test --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/test snapshot_comparison5.tesh)
       endif()
     endif()
     if(HAVE_RAWCTX)
index 0cf83fa..3e9cb61 100644 (file)
@@ -35,7 +35,9 @@ set(EXTRA_DIST
   src/simix/smx_smurf_private.h
   src/simix/smx_synchro_private.h
   src/smpi/README
+  src/smpi/colls/COPYRIGHTS
   src/smpi/colls/colls.h
+  src/smpi/colls/colls_private.h
   src/smpi/private.h
   src/smpi/smpi_mpi_dt_private.h
   src/surf/cpu_ti_private.h
@@ -108,9 +110,43 @@ set(SMPI_SRC
   src/smpi/smpi_mpi_dt.c
   src/smpi/smpi_pmpi.c
   src/smpi/smpi_replay.c
+  src/smpi/colls/colls_global.c
+  src/smpi/colls/allgather-2dmesh.c
+  src/smpi/colls/allgather-3dmesh.c
+  src/smpi/colls/allgather-bruck.c
+  src/smpi/colls/allgather-GB.c
+  src/smpi/colls/allgather-loosely-lr.c
+  src/smpi/colls/allgather-lr.c
+  src/smpi/colls/allgather-NTSLR.c
+  src/smpi/colls/allgather-NTSLR-NB.c
+  src/smpi/colls/allgather-pair.c
+  src/smpi/colls/allgather-rdb.c
+  src/smpi/colls/allgather-rhv.c
+  src/smpi/colls/allgather-ring.c
+  src/smpi/colls/allgather-SMP-NTS.c
+  src/smpi/colls/allgather-smp-simple.c
+  src/smpi/colls/allgather-spreading-simple.c
+  src/smpi/colls/allgatherv-GB.c  
+  src/smpi/colls/allgatherv-pair.c
+  src/smpi/colls/allgatherv-ring.c
+  src/smpi/colls/allreduce-lr.c
+  src/smpi/colls/allreduce-NTS.c
+  src/smpi/colls/allreduce-rab1.c
+  src/smpi/colls/allreduce-rab2.c
+  src/smpi/colls/allreduce-rab-rdb.c
+  #src/smpi/colls/allreduce-rab-reduce-scatter.c
+  src/smpi/colls/allreduce-rab-rsag.c
+  src/smpi/colls/allreduce-rdb.c
+  src/smpi/colls/allreduce-redbcast.c
+  src/smpi/colls/allreduce-smp-binomial.c
+  src/smpi/colls/allreduce-smp-binomial-pipeline.c
+  src/smpi/colls/allreduce-smp-rdb.c
+  src/smpi/colls/allreduce-smp-rsag.c
+  src/smpi/colls/allreduce-smp-rsag-lr.c
+  src/smpi/colls/allreduce-smp-rsag-rab.c
   src/smpi/colls/alltoall-2dmesh.c
   src/smpi/colls/alltoall-3dmesh.c
-  #  src/smpi/colls/alltoall-bruck.c
+  #src/smpi/colls/alltoall-bruck.c
   src/smpi/colls/alltoall-pair.c
   src/smpi/colls/alltoall-pair-light-barrier.c
   src/smpi/colls/alltoall-pair-mpi-barrier.c
@@ -121,6 +157,35 @@ set(SMPI_SRC
   src/smpi/colls/alltoall-ring-mpi-barrier.c
   src/smpi/colls/alltoall-ring-one-barrier.c
   src/smpi/colls/alltoall-simple.c
+  src/smpi/colls/alltoallv-pair.c   
+  src/smpi/colls/alltoallv-pair-light-barrier.c
+  src/smpi/colls/alltoallv-pair-mpi-barrier.c
+  src/smpi/colls/alltoallv-pair-one-barrier.c 
+  src/smpi/colls/alltoallv-ring.c
+  src/smpi/colls/alltoallv-ring-light-barrier.c
+  src/smpi/colls/alltoallv-ring-mpi-barrier.c
+  src/smpi/colls/alltoallv-ring-one-barrier.c
+  src/smpi/colls/alltoallv-bruck.c
+  src/smpi/colls/bcast-arrival-nb.c
+  src/smpi/colls/bcast-arrival-pattern-aware.c
+  src/smpi/colls/bcast-arrival-pattern-aware-wait.c
+  src/smpi/colls/bcast-arrival-scatter.c
+  src/smpi/colls/bcast-binomial-tree.c
+  src/smpi/colls/bcast-flattree.c
+  src/smpi/colls/bcast-flattree-pipeline.c
+  src/smpi/colls/bcast-NTSB.c
+  src/smpi/colls/bcast-NTSL.c
+  src/smpi/colls/bcast-NTSL-Isend.c
+  src/smpi/colls/bcast-scatter-LR-allgather.c
+  src/smpi/colls/bcast-scatter-rdb-allgather.c
+  src/smpi/colls/bcast-SMP-binary.c
+  src/smpi/colls/bcast-SMP-binomial.c
+  src/smpi/colls/bcast-SMP-linear.c
+  src/smpi/colls/reduce-arrival-pattern-aware.c
+  src/smpi/colls/reduce-binomial.c
+  src/smpi/colls/reduce-flat-tree.c
+  src/smpi/colls/reduce-NTSL.c
+  src/smpi/colls/reduce-scatter-gather.c
   )
 
 if(SMPI_F2C)
@@ -553,7 +618,6 @@ set(simgrid_sources
   ${SURF_SRC}
   ${TRACING_SRC}
   ${XBT_SRC}
-  ${SMPI_SRC}
   )
 
 if(${HAVE_JEDULE})
@@ -568,6 +632,13 @@ else()
     )
 endif()
 
+if(enable_smpi)
+  set(simgrid_sources
+    ${simgrid_sources}
+    ${SMPI_SRC}
+    )
+endif()
+
 if(${HAVE_TRACING})
   set(simgrid_sources
     ${simgrid_sources}
@@ -657,6 +728,7 @@ set(DOC_SOURCES
   doc/doxygen/module-sd.doc
   doc/doxygen/module-simix.doc
   doc/doxygen/module-surf.doc
+  doc/doxygen/module-smpi.doc
   doc/doxygen/module-trace.doc
   doc/doxygen/module-xbt.doc
   doc/doxygen/modules.doc
index 4e314ba..6a9c66c 100644 (file)
@@ -61,18 +61,9 @@ add_custom_target(simgrid_update_xml ALL
 install(TARGETS simgrid 
   DESTINATION $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/)
 
-if(enable_smpi)
-  install(TARGETS smpi
-    DESTINATION $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/)
-endif()
-
 if(enable_lib_static AND NOT WIN32)
   install(TARGETS simgrid_static
     DESTINATION $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/)
-  if(enable_smpi)
-    install(TARGETS smpi_static
-      DESTINATION $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/)
-  endif()
 endif()
 
 if(enable_java)
@@ -127,7 +118,6 @@ add_custom_target(uninstall
   COMMAND ${CMAKE_COMMAND} -E  remove_directory ${CMAKE_INSTALL_PREFIX}/doc/simgrid
   COMMAND ${CMAKE_COMMAND} -E  echo "uninstall doc ok"
   COMMAND ${CMAKE_COMMAND} -E  remove -f ${CMAKE_INSTALL_PREFIX}/lib/libsimgrid*
-  COMMAND ${CMAKE_COMMAND} -E  remove -f ${CMAKE_INSTALL_PREFIX}/lib/libsmpi*
   COMMAND ${CMAKE_COMMAND} -E   remove -f ${CMAKE_INSTALL_PREFIX}/lib/lua/5.1/simgrid*
   COMMAND ${CMAKE_COMMAND} -E  echo "uninstall lib ok"
   COMMAND ${CMAKE_COMMAND} -E  remove -f ${CMAKE_INSTALL_PREFIX}/bin/smpicc
index e31007b..0c8e76f 100644 (file)
@@ -15,14 +15,6 @@ if(enable_lib_static)
   add_library(simgrid_static STATIC ${simgrid_sources})
 endif()
 
-if(enable_smpi)
-  add_library(smpi SHARED ${SMPI_SRC})
-  set_target_properties(smpi PROPERTIES VERSION ${libsmpi_version})
-  if(enable_lib_static)
-    add_library(smpi_static STATIC ${SMPI_SRC})
-  endif()
-endif()
-
 if(enable_java)
   include(${CMAKE_HOME_DIRECTORY}/buildtools/Cmake/MakeJava.cmake)
 endif()
@@ -37,9 +29,9 @@ if (enable_supernovae)
   endif()
 
   if(enable_smpi)
-    add_dependencies(smpi ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_smpi.c)
+    add_dependencies(simgrid ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_smpi.c)
     if(enable_lib_static)
-      add_dependencies(smpi_static ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_smpi.c)
+      add_dependencies(simgrid_static ${CMAKE_CURRENT_BINARY_DIR}/src/supernovae_smpi.c)
     endif()
   endif()
 endif()
@@ -126,28 +118,20 @@ if(HAVE_POSIX_GETTIME)
   SET(SIMGRID_DEP "${SIMGRID_DEP} -lrt")
 endif()
 
-target_link_libraries(simgrid  ${SIMGRID_DEP})
-
 # Compute the dependencies of SMPI
 ##################################
-set(SMPI_DEP "")
-if(APPLE)
-  set(SMPI_DEP "-Wl,-U -Wl,_smpi_simulated_main")
-endif()
-if(enable_smpi)
-  target_link_libraries(smpi   simgrid ${SMPI_DEP})
+if(enable_smpi AND APPLE)
+  set(SIMGRID_DEP "${SIMGRID_DEP} -Wl,-U -Wl,_smpi_simulated_main")
 endif()
 
+target_link_libraries(simgrid  ${SIMGRID_DEP})
+
 # Pass dependencies to static libs
 ##################################
 if(enable_lib_static)
   target_link_libraries(simgrid_static         ${SIMGRID_DEP})
   add_dependencies(simgrid_static maintainer_files)
   set_target_properties(simgrid_static PROPERTIES OUTPUT_NAME simgrid)
-  if(enable_smpi)
-    target_link_libraries(smpi_static  simgrid ${SMPI_DEP})
-    set_target_properties(smpi_static PROPERTIES OUTPUT_NAME smpi)
-  endif()
 endif()
 
 # Dependencies from maintainer mode
index 168e85a..081c6e0 100644 (file)
@@ -41,14 +41,3 @@ if(PEXPORTS_PATH)
   add_custom_command(TARGET simgrid POST_BUILD
     COMMAND ${PEXPORTS_PATH}/pexports.exe ${CMAKE_BINARY_DIR}/lib/libsimgrid.dll > ${CMAKE_BINARY_DIR}/lib/libsimgrid.def)
 endif()
-
-if(enable_smpi)
-  set(SMPI_DEP "${LIBRARY_OUTPUT_PATH}/libsimgrid.dll")
-  add_library(smpi SHARED ${SMPI_SRC})
-  set_target_properties(smpi PROPERTIES COMPILE_FLAGS "-D_XBT_DLL_EXPORT -DDLL_EXPORT" LINK_FLAGS "-shared" VERSION ${libsmpi_version} PREFIX "lib" SUFFIX ".dll" IMPORT_PREFIX "lib" IMPORT_SUFFIX ".dll")
-  target_link_libraries(smpi ${SMPI_DEP})
-  if(PEXPORTS_PATH)
-    add_custom_command(TARGET smpi POST_BUILD
-     COMMAND ${PEXPORTS_PATH}/pexports.exe ${CMAKE_BINARY_DIR}/lib/libsmpi.dll > ${CMAKE_BINARY_DIR}/lib/libsmpi.def)
-  endif()
-endif()
index af31674..2df5821 100644 (file)
@@ -41,9 +41,9 @@ option(enable_supernovae "Whether Supernovae mode (helping compiler optimization
 option(enable_msg_deprecated "This option enable the use of msg deprecated functions" off)
 
 if(WIN32)
-  option(enable_smpi "Whether the smpi library is compiled." off)
+  option(enable_smpi "Whether SMPI in included in library." off)
 else()
-  option(enable_smpi "Whether the smpi library is compiled." on)
+  option(enable_smpi "Whether SMPI in included in library." on)
 endif()
 
 mark_as_advanced(HAVE_SSH)
index b399a5c..4b9d212 100644 (file)
@@ -685,6 +685,7 @@ INPUT                  = doxygen/index.doc \
                            doxygen/module-sd.doc \
                            doxygen/module-surf.doc \
                            doxygen/module-simix.doc \
+                           doxygen/module-smpi.doc \
                            doxygen/module-trace.doc \
                            index-API.doc \
                          @top_srcdir@/doc/doxygen/logcategories.doc \
index 0a8cbbd..accc6b9 100644 (file)
@@ -1,9 +1,9 @@
 /*! \page bindings Bindings
 
-\section bindings_binding_Ruby Ruby Binding
+\section MSG_Ruby Ruby Binding
 Check online for our specific [Simgrid-Ruby documentation](http://simgrid.gforge.inria.fr/documentation.html).
 
-\section bindings_binding_Java Java Binding
+\section MSG_Java Java Binding
 Simgrid-java is a java API that let you use [Simgrid](http://simgrid.gforge.inria.fr/)
 MSG API in your favorite language (java). Without it, you would be forced to
 use C or one of the other bindings provided.
index 554ab17..f7c796b 100644 (file)
@@ -2,9 +2,9 @@
 \page inside_extending Extending SimGrid 
 
 We start to put TAGS in simgrid source code for having tutorials to see where is the important parts ans steps to create:
-\li a new MSG functions or a new API.
-\li a new model in surf.
-\li new tags in xml files
+\li \ref simgrid_dev_guide_api
+\li \ref simgrid_dev_guide_model
+\li \ref simgrid_dev_guide_tag
 
 \section simgrid_dev_guide_api How to add a new MSG function?
 Search for expression \"TUTORIAL: New API\".
index a96494e..2241a15 100644 (file)
@@ -1,18 +1,26 @@
 /** \addtogroup MSG_API
 
-      MSG was the first distributed programming environment provided within
-      SimGrid. While almost realistic, it remains quite simple (simplistic?).
-      This describes the native to MSG.
-
-      \section jMSG_who Who should use this (and who shouldn't)
-
-      You should use MSG if you want to study some heuristics for a
-      given problem you don't really want to implement. If you want to
-      use the C programming language, your are in the right
-      section. To use the Java or Ruby programming interfaces, please refer to
-      the documentation provided in the relevant packages.
-
-  \section MSG_funct Offered functionnalities
+MSG was the first distributed programming environment provided within SimGrid,
+and is still the most commonly used nowadays. If you are unsure of the interface
+you should use, they you probably want to use MSG. It constitutes a convenient
+simplification of the reality of distributed systems. It can be used to build
+rather realistic simulations, but remains simple to use: most unpleasant
+technical elements can be abstracted away rather easily.  If you want to use the
+C programming language, your are in the right section. If you prefer not to use
+this venerable but demanding language, please refer to the @ref MSG_Java, the
+@ref MSG_LUA, or the @ref MSG_Ruby (that are distributed separately).
+
+If you think that MSG may not be the interface you need, please consider the
+other user interfaces provided by SimGrid: If you want to use DAGs, have a look
+at the \ref SD_API programming environment. If you want to study an existing MPI
+program, have a look at the \ref SMPI_API one. If none of those programming
+environments fits your needs, you may consider implementing your own directly on
+top of \ref SIMIX_API, or even on top of \ref SURF_API (but you want to contact
+us before digging into these badly documented internal modules).
+
+
+
+\section MSG_funct Offered functionalities
    - \ref msg_simulation
    - \ref m_process_management
    - \ref m_host_management
@@ -86,7 +94,7 @@ details).
 
 /** @defgroup msg_VMs VMs
  *  @ingroup MSG_API
- *  @brief This section describes the interface created to mimick IaaS clouds.
+ *  @brief This section describes the interface created to mimic IaaS clouds.
  *
  *  With it, you can create virtual machines to put your processes
  *  into, and interact directly with the VMs to manage groups of
@@ -146,14 +154,13 @@ This is the lua bindings of the \ref MSG_API interface.
 
 \section lMSG_who Who should use this (and who shouldn't)
 
-If you want to use MSG to study your algorithm, but you don't want to
-use the C language (using \ref MSG_API), then you should use some
-bindings such as this one. The advantage of the lua bindings is that
-they are distributed directly with the main archive (in contrary to
-Java and Ruby bindings, for example, that are distributed separately).
-Another advantage of lua is that there is almost no performance loss
-with regard to the C version (at least there shouln't be any -- it is
-still to be precisely assessed).
+If you want to use MSG to study your algorithm, but you don't want to use the C
+language (using \ref MSG_API), then you should use some bindings such as this
+one. Just like the \ref MSG_Java, the advantage of the lua bindings is that they
+are distributed directly with the main archive (in contrary to Ruby bindings,
+that are distributed separately).  Another advantage of lua is that there is
+almost no performance loss with regard to the C version (at least there
+shouldn't be any -- it is still to be precisely assessed).
 
 \section MSG_Lua_funct  Lua offered functionnalities in MSG
 
diff --git a/doc/doxygen/module-smpi.doc b/doc/doxygen/module-smpi.doc
new file mode 100644 (file)
index 0000000..a5c5099
--- /dev/null
@@ -0,0 +1,161 @@
+/** @addtogroup SMPI_API
+
+This programming environment enables the study of MPI application by
+emulating them on top of the SimGrid simulator. This is particularly
+interesting to study existing MPI applications within the comfort of
+the simulator. The motivation for this work is detailed in the
+reference article (available at http://hal.inria.fr/inria-00527150).
+
+Our goal is to enable the study of *unmodified* MPI applications,
+although we are not quite there yet (see @ref SMPI_what). In
+addition, you can modify your code to speed up your studies or
+otherwise increase their scalability (see @ref SMPI_adapting).
+
+\section SMPI_who Who should use SMPI (and who shouldn't)
+
+SMPI is now considered as stable and you can use it in production. You
+may probably want to read the scientific publications that detail the
+models used and their limits, but this should not be absolutely
+necessary. If you already fluently write and use MPI applications,
+SMPI should sound very familiar to you. Use smpicc instead of mpicc,
+and smpirun instead of mpirun (see below for more details).
+
+Of course, if you don't know what MPI is, the documentation of SMPI
+will seem a bit terse to you. You should pick up a good MPI tutorial
+on the Internet (or a course in your favorite university) and come
+back to SMPI once you know a bit more about MPI. Alternatively, you
+may want to turn to the other SimGrid interfaces such as the 
+\ref MSG_API environment, or the \ref SD_API one.
+
+\section SMPI_what What can run within SMPI?
+
+You can run unmodified MPI applications (both C and Fortran) within
+SMPI, provided that (1) you only use MPI calls that we implemented in
+MPI and (2) you don't use any globals in your application.
+
+\subsection SMPI_what_coverage MPI coverage of SMPI
+
+Our coverage of the interface is very decent, but still incomplete;
+Given the size of the MPI standard, it may well be that we never
+implement absolutely all existing primitives. One sided communications
+and I/O primitives are not targeted for now. Our current state is
+still very decent: we pass most of the MPICH coverage tests.
+
+The full list of not yet implemented functions is documented in the
+file <tt>include/smpi/smpi.h</tt> of the archive, between two lines
+containing the <tt>FIXME</tt> marker. If you really need a missing
+feature, please get in touch with us: we can guide you though the
+SimGrid code to help you implementing it, and we'd glad to integrate
+it in the main project afterward if you contribute them back.
+
+\subsection SMPI_what_globals Issues with the globals
+
+Concerning the globals, the problem comes from the fact that usually,
+MPI processes run as real UNIX processes while they are all folded
+into threads of a unique system process in SMPI. Global variables are
+usually private to each MPI process while they become shared between
+the processes in SMPI. This point is rather problematic, and currently
+forces to modify your application to privatize the global variables.
+
+We tried several techniques to work this around. We used to have a
+script that privatized automatically the globals through static
+analysis of the source code, but it was not robust enough to be used
+in production. This issue, as well as several potential solutions, is
+discussed in this article: "Automatic Handling of Global Variables for
+Multi-threaded MPI Programs",
+available at http://charm.cs.illinois.edu/newPapers/11-23/paper.pdf
+(note that this article does not deal with SMPI but with a concurrent
+solution called AMPI that suffers of the same issue). 
+
+Currently, we have no solution to offer you, because all proposed solutions will
+modify the performance of your application (in the computational
+sections). Sacrificing realism for usability is not very satisfying, so we did
+not implement them yet. You will thus have to modify your application if it uses
+global variables. We are working on another solution, leveraging distributed
+simulation to keep each MPI process within a separate system process, but this
+is far from being ready at the moment.
+
+\section SMPI_compiling Compiling your code
+
+This is very simply done with the <tt>smpicc</tt> script. If you
+already compiled any MPI code before, you already know how to use it.
+If not, you should try to get your MPI code running on top of MPI
+before giving SMPI a spin. Actually, that's very simple even if it's
+the first time you use MPI code: just use smpicc as a compiler (in
+replacement of gcc or your usual compiler), and you're set.
+
+\section SMPI_executing Executing your code on top of the simulator
+
+This is done though the <tt>smpirun</tt> script as follows.
+<tt>my_hostfile.txt</tt> is a classical MPI hostfile (that is, this
+file lists the machines on which the processes must be dispatched, one
+per line)  <tt>my_platform.xml</tt> is a classical SimGrid platform
+file. Of course, the hosts of the hostfile must exist in the provided
+platform. <tt>./program</tt> is the MPI program that you want to
+simulate (must be compiled by <tt>smpicc</tt>) while <tt>-arg</tt> is
+a command-line parameter passed to this program.
+
+\verbatim
+smpirun -hostfile my_hostfile.txt -platform my_platform.xml ./program -arg
+\endverbatim
+
+smpirun accepts other parameters, such as <tt>-np</tt> if you don't
+want to use all the hosts defined in the hostfile, <tt>-map</tt> to
+display on which host each rank gets mapped of <tt>-trace</tt> to
+activate the tracing during the simulation. You can get the full list
+by running
+\verbatim
+smpirun -help
+\endverbatim
+
+\section SMPI_adapting Adapting your MPI code to the use of SMPI
+
+As detailed in the reference article (available at
+http://hal.inria.fr/inria-00527150), you may want to adapt your code
+to improve the simulation performance. But these tricks may seriously
+hinder the result quality (or even prevent the app to run) if used
+wrongly. We assume that if you want to simulate an HPC application,
+you know what you are doing. Don't prove us wrong!
+
+\section SMPI_adapting_size Reducing your memory footprint
+
+If you get short on memory (the whole app is executed on a single node when
+simulated), you should have a look at the SMPI_SHARED_MALLOC and
+SMPI_SHARED_FREE macros. It allows to share memory areas between processes: The
+purpose of these macro is that the same line malloc on each process will point
+to the exact same memory area. So if you have a malloc of 2M and you have 16
+processes, this macro will change your memory consumption from 2M*16 to 2M
+only. Only one block for all processes.
+
+If your program is ok with a block containing garbage value because all
+processes write and read to the same place without any kind of coordination,
+then this macro can dramatically shrink your memory consumption. For example,
+that will be very beneficial to a matrix multiplication code, as all blocks will
+be stored on the same area. Of course, the resulting computations will useless,
+but you can still study the application behavior this way. 
+
+Naturally, this won't work if your code is data-dependent. For example, a Jacobi
+iterative computation depends on the result computed by the code to detect
+convergence conditions, so turning them into garbage by sharing the same memory
+area between processes does not seem very wise. You cannot use the
+SMPI_SHARED_MALLOC macro in this case, sorry.
+
+This feature is demoed by the example file
+<tt>examples/smpi/NAS/DT-folding/dt.c</tt>
+
+\section SMPI_adapting_speed Toward faster simulations
+
+If your application is too slow, try using SMPI_SAMPLE_LOCAL,
+SMPI_SAMPLE_GLOBAL and friends to indicate which computation loops can
+be sampled. Some of the loop iterations will be executed to measure
+their duration, and this duration will be used for the subsequent
+iterations. These samples are done per processor with
+SMPI_SAMPLE_LOCAL, and shared between all processors with
+SMPI_SAMPLE_GLOBAL. Of course, none of this will work if the execution
+time of your loop iteration are not stable.
+
+This feature is demoed by the example file 
+<tt>examples/smpi/NAS/EP-sampling/ep.c</tt>
+
+
+*/
\ No newline at end of file
index d21c24c..7b5f076 100644 (file)
@@ -2,19 +2,6 @@
 @defgroup MSG_API      MSG
 @brief Simple programming environment
 
-MSG was the first distributed programming environment provided within
-SimGrid. While almost realistic, it remains quite simple
-(simplistic?).
-
-@section MSG_who Who should use this (and who shouldn't)
-
-You should use this module if you want to study some heuristics for a
-given problem you don't really want to implement. If you want to use
-DAGs, have a look at the \ref SD_API programming environment. If you
-want to study an existing MPI program, have a look at the \ref
-SMPI_API one. If none of those programming environments fits your
-needs, you may consider implementing your own directly on top of 
-\ref SURF_API (but you probably want to contact us before). 
 */
 
 /** 
@@ -52,101 +39,6 @@ parameter in the command line (see \ref tracing for details).
 
 /** \defgroup SMPI_API      SMPI
     \brief Programming environment for the simulation of MPI applications
-
-This programming environment permits to study existing MPI application
-by emulating them on top of the SimGrid simulator. In other words, it
-will constitute an emulation solution for parallel codes. You don't
-even have to modify your code for that, although that may help, as
-detailed below.
-
-\section SMPI_who Who should use SMPI (and who shouldn't)
-
-You should use this programming environment of the SimGrid suite if
-you want to study existing MPI applications.  If you want to study
-some heuristics for a given problem (and if your goal is to produce
-theorems and publications, not code), have a look at the \ref MSG_API
-environment, or the \ref SD_API one if you need to use DAGs. If none
-of those programming environments fits your needs, you may consider
-implementing your own directly on top of \ref SURF_API (but you
-probably want to contact us before).
-
-\section SMPI_what What can run within SMPI?
-
-You can run unmodified MPI applications (both C and Fortran) within
-SMPI, provided you only use MPI calls that we implemented in MPI. Our
-coverage of the interface is not bad, but will probably never be
-complete. One sided communications and I/O primitives are not targeted
-for now. The full list of not yet implemented functions is available
-in file <tt>include/smpi/smpi.h</tt> of the archive, between two lines
-containing the <tt>FIXME</tt> marker. If you really need a missing
-feature, please get in touch with us: we can guide you though the
-SimGrid code to help you implementing it, and we'd glad to integrate
-it in the main project afterward if you contribute them back.
-
-\section SMPI_adapting Adapting your MPI code to the use of SMPI
-
-As detailed in the reference article (available at
-http://hal.inria.fr/inria-00527150), you may want to adapt your code
-to improve the simulation performance. But these tricks may seriously
-hinder the result qualtity (or even prevent the app to run) if used
-wrongly. We assume that if you want to simulate an HPC application,
-you know what you are doing. Don't prove us wrong!
-
-If you get short on memory (the whole app is executed on a single node
-when simulated), you should have a look at the SMPI_SHARED_MALLOC and
-SMPI_SHARED_FREE macros. It allows to share memory areas between
-processes. For example, matrix multiplication code may want to store
-the blocks on the same area. Of course, the resulting computations
-will useless, but you can still study the application behavior this
-way. Of course, if your code is data-dependent, this won't work.
-
-If your application is too slow, try using SMPI_SAMPLE_LOCAL,
-SMPI_SAMPLE_GLOBAL and friends to indicate which computation loops can
-be sampled. Some of the loop iterations will be executed to measure
-their duration, and this duration will be used for the subsequent
-iterations. These samples are done per processor with
-SMPI_SAMPLE_LOCAL, and shared between all processors with
-SMPI_SAMPLE_GLOBAL. Of course, none of this will work if the execution
-time of your loop iteration are not stable.
-
-Yes, that's right, these macros are not documented yet, but we'll fix
-it as soon as time permits. Sorry about that -- patch welcomed!
-Meanwhile, grep for them on the examples for more information.
-
-\section SMPI_compiling Compiling your code
-
-This is very simply done with the <tt>smpicc</tt> script. If you
-already compiled any MPI code before, you already know how to use it.
-If not, you should try to get your MPI code running on top of MPI
-before giving SMPI a spin. Actually, that's very simple even if it's
-the first time you use MPI code: just use smpicc as a compiler (in
-replacement of gcc or your usual compiler), and you're set.
-
-\section SMPI_executing Executing your code on top of the simulator
-
-This is done though the <tt>smpirun</tt> script as follows.
-<tt>my_hostfile.txt</tt> is a classical MPI hostfile (that is, this
-file lists the machines on which the processes must be dispatched, one
-per line)  <tt>my_platform.xml</tt> is a classical SimGrid platform
-file. Of course, the hosts of the hostfile must exist in the provided
-platform. <tt>./program</tt> is the MPI program that you want to
-simulate (must be compiled by <tt>smpicc</tt>) while <tt>-arg</tt> is
-a command-line parameter passed to this program.
-
-\verbatim
-smpirun -hostfile my_hostfile.txt -platform my_platform.xml ./program -arg
-\endverbatim
-
-smpirun accepts other parameters, such as <tt>-np</tt> if you don't
-want to use all the hosts defined in the hostfile, <tt>-map</tt> to
-display on which host each rank gets mapped of <tt>-trace</tt> to
-activate the tracing during the simulation. You can get the full list
-by running
-\verbatim
-smpirun -help
-\endverbatim
-
-
 */
 
 
index d9765bc..d556a5e 100644 (file)
@@ -4,15 +4,16 @@ if(HAVE_MC)
   set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
 
   file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/")
-  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/chord/")
+  file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/chord_liveness/")
 
   add_executable(centralized centralized_mutex.c)
   add_executable(bugged1     bugged1.c)
   add_executable(bugged2      bugged2.c)
   add_executable(bugged3          bugged3.c)
+  add_executable(electric_fence           electric_fence.c)
   add_executable(bugged1_liveness bugged1_liveness.c)
   add_executable(bugged2_liveness bugged2_liveness.c)
-  add_executable(chord/chord_liveness chord/chord_liveness.c)
+  add_executable(chord_liveness/chord_liveness chord_liveness/chord_liveness.c)
   add_executable(test/snapshot_comparison1 test/snapshot_comparison1.c)
   add_executable(test/snapshot_comparison2 test/snapshot_comparison2.c)
   add_executable(test/snapshot_comparison3 test/snapshot_comparison3.c)
@@ -23,9 +24,10 @@ if(HAVE_MC)
   target_link_libraries(bugged1     simgrid )
   target_link_libraries(bugged2     simgrid )
   target_link_libraries(bugged3     simgrid )
+  target_link_libraries(electric_fence     simgrid )
   target_link_libraries(bugged1_liveness     simgrid )
   target_link_libraries(bugged2_liveness     simgrid )
-  target_link_libraries(chord/chord_liveness     simgrid )
+  target_link_libraries(chord_liveness/chord_liveness     simgrid )
   target_link_libraries(test/snapshot_comparison1     simgrid )
   target_link_libraries(test/snapshot_comparison2     simgrid )
   target_link_libraries(test/snapshot_comparison3     simgrid )
@@ -39,7 +41,9 @@ set(tesh_files
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged1.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged1_liveness.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/centralized.tesh
-  ${CMAKE_CURRENT_SOURCE_DIR}/chord/chord_neverjoin.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/chord_neverjoin.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/chord_neverdeliver.tesh 
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/chord_neverjoin_timeout_visited.tesh 
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison1.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison2.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison3.tesh
@@ -54,10 +58,10 @@ set(xml_files
   ${CMAKE_CURRENT_SOURCE_DIR}/deploy_bugged2_liveness.xml
   ${CMAKE_CURRENT_SOURCE_DIR}/deploy_bugged2.xml
   ${CMAKE_CURRENT_SOURCE_DIR}/deploy_bugged3.xml
+  ${CMAKE_CURRENT_SOURCE_DIR}/deploy_electric_fence.xml
   ${CMAKE_CURRENT_SOURCE_DIR}/deploy_mutex.xml
-  ${CMAKE_CURRENT_SOURCE_DIR}/deploy_random_test.xml
   ${CMAKE_CURRENT_SOURCE_DIR}/platform.xml
-  ${CMAKE_CURRENT_SOURCE_DIR}/chord/deploy_chord_liveness.xml
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/deploy_chord_liveness.xml
   ${CMAKE_CURRENT_SOURCE_DIR}/test/deploy_snapshot_comparison.xml
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison_platform.xml
   PARENT_SCOPE
@@ -69,11 +73,11 @@ set(examples_src
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged2.c
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged2_liveness.c
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged3.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/electric_fence.c
   ${CMAKE_CURRENT_SOURCE_DIR}/centralized_mutex.c
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged1_liveness.h
   ${CMAKE_CURRENT_SOURCE_DIR}/bugged2_liveness.h
-  ${CMAKE_CURRENT_SOURCE_DIR}/chord/chord_liveness.c
-  ${CMAKE_CURRENT_SOURCE_DIR}/chord/chord_liveness.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/chord_liveness.c
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison1.c
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison2.c
   ${CMAKE_CURRENT_SOURCE_DIR}/test/snapshot_comparison3.c
@@ -86,7 +90,8 @@ set(bin_files
   ${CMAKE_CURRENT_SOURCE_DIR}/parse_dwarf
   ${CMAKE_CURRENT_SOURCE_DIR}/promela_bugged1_liveness
   ${CMAKE_CURRENT_SOURCE_DIR}/promela_bugged2_liveness
-  ${CMAKE_CURRENT_SOURCE_DIR}/chord/promela_chord_liveness
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/promela_chord_neverjoin
+  ${CMAKE_CURRENT_SOURCE_DIR}/chord_liveness/promela_chord_neverdeliver
   ${CMAKE_CURRENT_SOURCE_DIR}/test/promela
   PARENT_SCOPE
   )
index 6a11193..dbdc4eb 100644 (file)
@@ -9,21 +9,6 @@ $ ${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] (1:server@HostA) OK
-> [  0.000000] (3:client@HostC) Sent!
-> [  0.000000] (4:client@HostD) 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] (1:server@HostA) OK
-> [  0.000000] (3:client@HostC) Sent!
-> [  0.000000] (4:client@HostD) 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] (1:server@HostA) **************************
 > [  0.000000] (1:server@HostA) *** PROPERTY NOT VALID ***
@@ -39,6 +24,6 @@ $ ${bindir:=.}/bugged1 --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%
 > [  0.000000] (1:server@HostA) [(1)server] iRecv (dst=server, buff=(verbose only), size=(verbose only))
 > [  0.000000] (1:server@HostA) [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
 > [  0.000000] (1:server@HostA) [(1)server] Wait (comm=(verbose only) [(3)client -> (1)server])
-> [  0.000000] (1:server@HostA) Expanded states = 36
-> [  0.000000] (1:server@HostA) Visited states = 75
-> [  0.000000] (1:server@HostA) Executed transitions = 70
+> [  0.000000] (1:server@HostA) Expanded states = 17
+> [  0.000000] (1:server@HostA) Visited states = 32
+> [  0.000000] (1:server@HostA) Executed transitions = 30
index b0f05b3..6954ef6 100644 (file)
@@ -2,43 +2,44 @@
 
 ! expect signal SIGABRT
 ! timeout 200
-$ ${bindir:=.}/bugged1_liveness --cfg=model-check:1 --cfg=contexts/factory:ucontext
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [mc_global/INFO] Check the liveness property promela_bugged1_liveness
-> [Fafard:client:(2) 0.000000] [bugged1_liveness/INFO] Ask the request
-> [Boivin:client:(3) 0.000000] [bugged1_liveness/INFO] Ask the request
-> [Fafard:client:(2) 0.000000] [bugged1_liveness/INFO] Propositions changed : r=1, cs=0
-> [Tremblay:coordinator:(1) 0.000000] [bugged1_liveness/INFO] CS idle. Grant immediatly
-> [Boivin:client:(3) 0.000000] [bugged1_liveness/INFO] 2 got the answer. Sleep a bit and release it
-> [Tremblay:coordinator:(1) 0.000000] [bugged1_liveness/INFO] CS release. resource now idle
-> [Boivin:client:(3) 0.000000] [bugged1_liveness/INFO] Ask the request
-> [Tremblay:coordinator:(1) 0.000000] [bugged1_liveness/INFO] CS idle. Grant immediatly
-> [0.000000] [mc_liveness/INFO] Next pair (depth = 22, 1 interleave) already reached !
-> [0.000000] [mc_liveness/INFO] *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [0.000000] [mc_liveness/INFO] |             ACCEPTANCE CYCLE            |
-> [0.000000] [mc_liveness/INFO] *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [0.000000] [mc_liveness/INFO] Counter-example that violates formula :
-> [0.000000] [mc_global/INFO] [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(2)client] iSend (src=client, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)coordinator] Wait (comm=(verbose only) [(2)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(2)client] Wait (comm=(verbose only) [(2)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(2)client] iRecv (dst=client, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)coordinator] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(1)coordinator] iSend (src=coordinator, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(3)client] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(3)client] iRecv (dst=client, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)coordinator] Wait (comm=(verbose only) [(1)coordinator -> (3)client])
-> [0.000000] [mc_global/INFO] [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(3)client] Wait (comm=(verbose only) [(1)coordinator -> (3)client])
-> [0.000000] [mc_global/INFO] [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)coordinator] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(3)client] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)coordinator] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
-> [0.000000] [mc_global/INFO] [(1)coordinator] iSend (src=coordinator, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] Expanded pairs = 23
-> [0.000000] [mc_global/INFO] Visited pairs = 21
-> [0.000000] [mc_global/INFO] Executed transitions = 21
+$ ${bindir:=.}/bugged1_liveness --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext
+> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+> [  0.000000] (0:@) Check the liveness property promela_bugged1_liveness
+> [  0.000000] (2:client@Fafard) Ask the request
+> [  0.000000] (3:client@Boivin) Ask the request
+> [  0.000000] (2:client@Fafard) Propositions changed : r=1, cs=0
+> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly
+> [  0.000000] (3:client@Boivin) 2 got the answer. Sleep a bit and release it
+> [  0.000000] (1:coordinator@Tremblay) CS release. resource now idle
+> [  0.000000] (3:client@Boivin) Ask the request
+> [  0.000000] (1:coordinator@Tremblay) CS idle. Grant immediatly
+> [  0.000000] (0:@) Next pair (depth = 22, 1 interleave) already reached (equal to state 11) !
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) |             ACCEPTANCE CYCLE            |
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) Counter-example that violates formula :
+> [  0.000000] (0:@) [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)client] iSend (src=client, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)coordinator] Wait (comm=(verbose only) [(2)client -> (1)coordinator])
+> [  0.000000] (0:@) [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)client] Wait (comm=(verbose only) [(2)client -> (1)coordinator])
+> [  0.000000] (0:@) [(2)client] iRecv (dst=client, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)coordinator] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
+> [  0.000000] (0:@) [(1)coordinator] iSend (src=coordinator, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)client] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
+> [  0.000000] (0:@) [(3)client] iRecv (dst=client, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)coordinator] Wait (comm=(verbose only) [(1)coordinator -> (3)client])
+> [  0.000000] (0:@) [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)client] Wait (comm=(verbose only) [(1)coordinator -> (3)client])
+> [  0.000000] (0:@) [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)coordinator] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
+> [  0.000000] (0:@) [(1)coordinator] iRecv (dst=coordinator, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)client] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
+> [  0.000000] (0:@) [(3)client] iSend (src=client, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)coordinator] Wait (comm=(verbose only) [(3)client -> (1)coordinator])
+> [  0.000000] (0:@) [(1)coordinator] iSend (src=coordinator, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) Expanded pairs = 23
+> [  0.000000] (0:@) Visited pairs = 21
+> [  0.000000] (0:@) Executed transitions = 21
+
diff --git a/examples/msg/mc/chord/chord_liveness.h b/examples/msg/mc/chord/chord_liveness.h
deleted file mode 100644 (file)
index e522b77..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _CHORD_LIVENESS_H
-#define _CHORD_LIVENESS_H
-
-int predJoin(void);
-
-#endif
diff --git a/examples/msg/mc/chord/chord_neverjoin.tesh b/examples/msg/mc/chord/chord_neverjoin.tesh
deleted file mode 100644 (file)
index b458c9c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#! ./tesh
-
-! expect signal SIGABRT
-! timeout 200
-$ ${bindir:=.}/chord_liveness --cfg=model-check:1 --cfg=contexts/factory:ucontext
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'model-check' to '1'
-> [0.000000] [mc_global/INFO] Check the liveness property promela_chord_liveness
-> [Jean_Yves:node:(1) 0.000000] [chord_liveness/INFO] Joining the ring with id 14, knowing node 1
-> [Boivin:node:(2) 0.000000] [chord_liveness/INFO] Joining the ring with id 8, knowing node 1
-> [Jacquelin:node:(3) 0.000000] [chord_liveness/INFO] A transfer has occured
-> [Jacquelin:node:(3) 0.000000] [chord_liveness/INFO] The task was successfully received by node 1
-> [Jean_Yves:node:(1) 0.000000] [chord_liveness/INFO] Node 14 joined the ring
-> [0.000000] [mc_liveness/INFO] Next pair (depth = 11, 2 interleave) already reached !
-> [0.000000] [mc_liveness/INFO] *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [0.000000] [mc_liveness/INFO] |             ACCEPTANCE CYCLE            |
-> [0.000000] [mc_liveness/INFO] *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
-> [0.000000] [mc_liveness/INFO] Counter-example that violates formula :
-> [0.000000] [mc_global/INFO] [(1)node] iSend (src=node, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(2)node] iSend (src=node, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(3)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)node] Wait (comm=(verbose only) [(1)node -> (3)node])
-> [0.000000] [mc_global/INFO] [(1)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(3)node] Test TRUE (comm=(verbose only) [(1)node -> (3)node])
-> [0.000000] [mc_global/INFO] [(3)node] iSend (src=node, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)node] Wait (comm=(verbose only) [(3)node -> (1)node])
-> [0.000000] [mc_global/INFO] [(1)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
-> [0.000000] [mc_global/INFO] [(1)node] Test FALSE (comm=(verbose only))
-> [0.000000] [mc_global/INFO] Expanded pairs = 14
-> [0.000000] [mc_global/INFO] Visited pairs = 10
-> [0.000000] [mc_global/INFO] Executed transitions = 10
similarity index 90%
rename from examples/msg/mc/chord/chord_liveness.c
rename to examples/msg/mc/chord_liveness/chord_liveness.c
index 4856395..f7d1a0d 100644 (file)
@@ -10,7 +10,6 @@
 #include "xbt/log.h"
 #include "xbt/asserts.h"
 #include "simgrid/modelchecker.h"
-#include "chord_liveness.h"
 #include "mc/mc.h"
 
 /** @addtogroup MSG_examples
@@ -121,8 +120,9 @@ static void check_predecessor(node_t node);
 static void random_lookup(node_t);
 static void quit_notify(node_t node);
 
-/* Global variable corresponding to atomic proposition */
+/* Global variables corresponding to atomic propositions */
 int node_join = 0;
+int node_deliver = 0;
 
 /**
  * \brief Global initialization of the Chord simulation.
@@ -209,9 +209,11 @@ static void get_mailbox(int node_id, char* mailbox)
 static void task_free(void* task)
 {
   // TODO add a parameter data_free_function to MSG_task_create?
-  xbt_free(MSG_task_get_data(task));
-  MSG_task_destroy(task);
-  task = NULL;
+  if(task != NULL){
+    xbt_free(MSG_task_get_data(task));
+    MSG_task_destroy(task);
+    task = NULL;
+  }
 }
 
 /**
@@ -329,7 +331,6 @@ int node(int argc, char *argv[])
     if(join_success){
       XBT_INFO("Node %d joined the ring", node.id);
       node_join = 1; 
-      //MC_compare();
     }
   }
 
@@ -347,34 +348,71 @@ int node(int argc, char *argv[])
 
       if (!MSG_comm_test(node.comm_receive)) {
 
-        // no task was received: make some periodic calls
-        if (MSG_get_clock() >= next_stabilize_date) {
-          stabilize(&node);
-          next_stabilize_date = MSG_get_clock() + periodic_stabilize_delay;
-        }
-        else if (MSG_get_clock() >= next_fix_fingers_date) {
-          fix_fingers(&node);
-          next_fix_fingers_date = MSG_get_clock() + periodic_fix_fingers_delay;
-        }
-        else if (MSG_get_clock() >= next_check_predecessor_date) {
-          check_predecessor(&node);
-          next_check_predecessor_date = MSG_get_clock() + periodic_check_predecessor_delay;
-        }
-        else if (MSG_get_clock() >= next_lookup_date) {
-          random_lookup(&node);
-          next_lookup_date = MSG_get_clock() + periodic_lookup_delay;
-        }
-        else {
-          // nothing to do: sleep for a while
-          MSG_process_sleep(5);
-        }
+        #ifdef HAVE_MC
+          if(MC_is_active()){
+            if(MC_random()){
+              stabilize(&node);
+            }else if(MC_random()){
+              fix_fingers(&node);
+            }else if(MC_random()){
+              check_predecessor(&node);
+            }else if(MC_random()){
+              random_lookup(&node);
+            }else{
+              MSG_process_sleep(5);
+            }
+          }else{
+            if (MSG_get_clock() >= next_stabilize_date) {
+              stabilize(&node);
+              next_stabilize_date = MSG_get_clock() + periodic_stabilize_delay;
+            }
+            else if (MSG_get_clock() >= next_fix_fingers_date) {
+              fix_fingers(&node);
+              next_fix_fingers_date = MSG_get_clock() + periodic_fix_fingers_delay;
+            }
+            else if (MSG_get_clock() >= next_check_predecessor_date) {
+              check_predecessor(&node);
+              next_check_predecessor_date = MSG_get_clock() + periodic_check_predecessor_delay;
+            }
+            else if (MSG_get_clock() >= next_lookup_date) {
+              random_lookup(&node);
+              next_lookup_date = MSG_get_clock() + periodic_lookup_delay;
+            }
+            else {
+              // nothing to do: sleep for a while
+              MSG_process_sleep(5);
+            }
+          }
+        #else
+          if (MSG_get_clock() >= next_stabilize_date) {
+            stabilize(&node);
+            next_stabilize_date = MSG_get_clock() + periodic_stabilize_delay;
+          }
+          else if (MSG_get_clock() >= next_fix_fingers_date) {
+            fix_fingers(&node);
+            next_fix_fingers_date = MSG_get_clock() + periodic_fix_fingers_delay;
+          }
+          else if (MSG_get_clock() >= next_check_predecessor_date) {
+            check_predecessor(&node);
+            next_check_predecessor_date = MSG_get_clock() + periodic_check_predecessor_delay;
+          }
+          else if (MSG_get_clock() >= next_lookup_date) {
+            random_lookup(&node);
+            next_lookup_date = MSG_get_clock() + periodic_lookup_delay;
+          }
+          else {
+            // nothing to do: sleep for a while
+            MSG_process_sleep(5);
+          }
+        #endif
+
       }else{
 
         if (node.comm_receive) {
 
-          XBT_INFO("A transfer has occured");
+          node_deliver = 0;
 
-          //MC_compare();
+          XBT_INFO("A transfer has occured");
 
           // a transfer has occured
 
@@ -426,6 +464,7 @@ static void handle_task(node_t node, msg_task_t task) {
   switch (type) {
 
     case TASK_FIND_SUCCESSOR:
+      node_deliver = 1;
       XBT_DEBUG("Receiving a 'Find Successor' request from %s for id %d",
           task_data->issuer_host_name, task_data->request_id);
       // is my successor the successor?
@@ -895,10 +934,14 @@ static void random_lookup(node_t node)
   find_successor(node, id);
 }
 
-int predJoin(void){
+static int predJoin(void){
   return node_join;
 }
 
+static int predDeliver(void){
+  return node_deliver;
+}
+
 
 /**
  * \brief Main function.
@@ -906,13 +949,13 @@ int predJoin(void){
 int main(int argc, char *argv[])
 {
   MSG_init(&argc, argv);
-  /*if (argc < 3) {
+  if (argc < 3) {
     printf("Usage: %s [-nb_bits=n] [-timeout=t] platform_file deployment_file\n", argv[0]);
-    printf("example: %s ../msg_platform.xml chord.xml\n", argv[0]);
+    printf("example: %s ../../msg_platform.xml deploy_chord_liveness.xml\n", argv[0]);
     exit(1);
-    }*/
+  }
 
-  char **options = &argv[0];
+  char **options = &argv[1];
   while (!strncmp(options[0], "-", 1)) {
 
     int length = strlen("-nb_bits=");
@@ -934,21 +977,20 @@ int main(int argc, char *argv[])
     options++;
   }
 
-  //const char* platform_file = options[0];
-  //const char* application_file = options[1];
+  const char* platform_file = options[0];
+  const char* application_file = options[1];
 
   chord_initialize();
 
-  MSG_config("model-check/property","promela_chord_liveness");
   MC_automaton_new_propositional_symbol("join", &predJoin);
+  MC_automaton_new_propositional_symbol("deliver", &predDeliver);
 
-  MSG_create_environment("../../msg_platform.xml");
-
+  MSG_create_environment(platform_file);
+  
   MSG_function_register("node", node);
-  MSG_launch_application("deploy_chord_liveness.xml");
+  MSG_launch_application(application_file);
 
   msg_error_t res = MSG_main();
-  //XBT_CRITICAL("Messages created: %ld", smx_total_comms);
   XBT_INFO("Simulated time: %g", MSG_get_clock());
 
   chord_exit();
diff --git a/examples/msg/mc/chord_liveness/chord_neverdeliver.tesh b/examples/msg/mc/chord_liveness/chord_neverdeliver.tesh
new file mode 100644 (file)
index 0000000..fed20cb
--- /dev/null
@@ -0,0 +1,35 @@
+#! ./tesh
+
+! expect signal SIGABRT
+! timeout 200
+$ ${bindir:=.}/chord_liveness ../../msg_platform.xml deploy_chord_liveness.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/property:promela_chord_neverdeliver
+> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+> [  0.000000] (0:@) Configuration change: Set 'model-check/property' to 'promela_chord_neverdeliver'
+> [  0.000000] (0:@) Check the liveness property promela_chord_neverdeliver
+> [  0.000000] (1:node@Jean_Yves) Joining the ring with id 14, knowing node 1
+> [  0.000000] (2:node@Boivin) Joining the ring with id 8, knowing node 1
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Node 14 joined the ring
+> [  0.000000] (0:@) Next pair (depth = 15, 2 interleave) already reached (equal to state 13) !
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) |             ACCEPTANCE CYCLE            |
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) Counter-example that violates formula :
+> [  0.000000] (0:@) [(1)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] Wait (comm=(verbose only) [(1)node -> (3)node])
+> [  0.000000] (0:@) [(1)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)node] Test TRUE (comm=(verbose only) [(1)node -> (3)node])
+> [  0.000000] (0:@) [(3)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] Wait (comm=(verbose only) [(3)node -> (1)node])
+> [  0.000000] (0:@) [(1)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] Test FALSE (comm=(verbose only))
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) Expanded pairs = 24
+> [  0.000000] (0:@) Visited pairs = 14
+> [  0.000000] (0:@) Executed transitions = 14
diff --git a/examples/msg/mc/chord_liveness/chord_neverjoin.tesh b/examples/msg/mc/chord_liveness/chord_neverjoin.tesh
new file mode 100644 (file)
index 0000000..56d3a28
--- /dev/null
@@ -0,0 +1,37 @@
+#! ./tesh
+
+! expect signal SIGABRT
+! timeout 200
+$ ${bindir:=.}/chord_liveness ../../msg_platform.xml deploy_chord_liveness.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/property:promela_chord_neverjoin
+> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+> [  0.000000] (0:@) Configuration change: Set 'model-check/property' to 'promela_chord_neverjoin'
+> [  0.000000] (0:@) Check the liveness property promela_chord_neverjoin
+> [  0.000000] (1:node@Jean_Yves) Joining the ring with id 14, knowing node 1
+> [  0.000000] (2:node@Boivin) Joining the ring with id 8, knowing node 1
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Node 14 joined the ring
+> [  0.000000] (0:@) Next pair (depth = 15, 2 interleave) already reached (equal to state 11) !
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) |             ACCEPTANCE CYCLE            |
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) Counter-example that violates formula :
+> [  0.000000] (0:@) [(1)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] Wait (comm=(verbose only) [(1)node -> (3)node])
+> [  0.000000] (0:@) [(1)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)node] Test TRUE (comm=(verbose only) [(1)node -> (3)node])
+> [  0.000000] (0:@) [(3)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] Wait (comm=(verbose only) [(3)node -> (1)node])
+> [  0.000000] (0:@) [(1)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] Test FALSE (comm=(verbose only))
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(1)node] MC_RANDOM (0)
+> [  0.000000] (0:@) Expanded pairs = 22
+> [  0.000000] (0:@) Visited pairs = 14
+> [  0.000000] (0:@) Executed transitions = 14
+
+
diff --git a/examples/msg/mc/chord_liveness/chord_neverjoin_timeout_visited.tesh b/examples/msg/mc/chord_liveness/chord_neverjoin_timeout_visited.tesh
new file mode 100644 (file)
index 0000000..ed80aeb
--- /dev/null
@@ -0,0 +1,105 @@
+#! ./tesh
+
+! expect signal SIGABRT
+! timeout 200
+$ ${bindir:=.}/chord_liveness ../../msg_platform.xml deploy_chord_liveness.xml --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/property:promela_chord_neverjoin --cfg=model-check/timeout:1 --cfg=model-check/visited:100
+> [  0.000000] (0:@) Configuration change: Set 'model-check' to '1'
+> [  0.000000] (0:@) Configuration change: Set 'model-check/property' to 'promela_chord_neverjoin'
+> [  0.000000] (0:@) Configuration change: Set 'model-check/timeout' to '1'
+> [  0.000000] (0:@) Configuration change: Set 'model-check/visited' to '100'
+> [  0.000000] (0:@) Check the liveness property promela_chord_neverjoin
+> [  0.000000] (1:node@Jean_Yves) Joining the ring with id 14, knowing node 1
+> [  0.000000] (2:node@Boivin) Joining the ring with id 8, knowing node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (2:node@Boivin) Cannot join the ring.
+> [  0.000000] (1:node@Jean_Yves) Cannot join the ring.
+> [  0.000000] (3:node@Jacquelin) A transfer has occured
+> [  0.000000] (3:node@Jacquelin) The task was successfully received by node 1
+> [  0.000000] (2:node@Boivin) Node 8 joined the ring
+> [  0.000000] (0:@) Next pair (depth = 16, 2 interleave) already reached (equal to state 71) !
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) |             ACCEPTANCE CYCLE            |
+> [  0.000000] (0:@) *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
+> [  0.000000] (0:@) Counter-example that violates formula :
+> [  0.000000] (0:@) [(1)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(1)node] WaitTimeout (comm=(verbose only))
+> [  0.000000] (0:@) [(2)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)node] Wait (comm=(verbose only) [(2)node -> (3)node])
+> [  0.000000] (0:@) [(2)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(3)node] Test TRUE (comm=(verbose only) [(2)node -> (3)node])
+> [  0.000000] (0:@) [(3)node] iSend (src=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)node] Wait (comm=(verbose only) [(3)node -> (2)node])
+> [  0.000000] (0:@) [(2)node] iRecv (dst=node, buff=(verbose only), size=(verbose only))
+> [  0.000000] (0:@) [(2)node] Test FALSE (comm=(verbose only))
+> [  0.000000] (0:@) [(2)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(2)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(2)node] MC_RANDOM (0)
+> [  0.000000] (0:@) [(2)node] MC_RANDOM (0)
+> [  0.000000] (0:@) Expanded pairs = 82
+> [  0.000000] (0:@) Visited pairs = 337
+> [  0.000000] (0:@) Executed transitions = 360
\ No newline at end of file
diff --git a/examples/msg/mc/chord_liveness/promela_chord_neverdeliver b/examples/msg/mc/chord_liveness/promela_chord_neverdeliver
new file mode 100644 (file)
index 0000000..d102137
--- /dev/null
@@ -0,0 +1,12 @@
+never { /* !(!(GFdeliver)) */
+T0_init :    /* init */
+       if
+       :: (deliver) -> goto accept_S1
+       :: (1) -> goto T0_init
+       fi;
+accept_S1 :    /* 1 */
+       if
+       :: (deliver) -> goto accept_S1
+       :: (1) -> goto T0_init
+       fi;
+}
\ No newline at end of file
similarity index 71%
rename from examples/msg/mc/deploy_random_test.xml
rename to examples/msg/mc/deploy_electric_fence.xml
index 31415a5..3fd4d5a 100644 (file)
@@ -4,14 +4,10 @@
   <process host="HostA" function="server">
     <argument value="0"/>
   </process>
-  <process host="HostB" function="server">
-    <argument value="0"/>
-  </process>
-
-<!--  <process host="HostB" function="client">
+  <process host="HostB" function="client">
     <argument value="1"/>
   </process>  
   <process host="HostC" function="client">
     <argument value="2"/>
-  </process> -->
+  </process>
 </platform>
diff --git a/examples/msg/mc/electric_fence.c b/examples/msg/mc/electric_fence.c
new file mode 100644 (file)
index 0000000..cfe23b7
--- /dev/null
@@ -0,0 +1,68 @@
+/* Copyright (c) 2013. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+
+/******************** Non-deterministic message ordering  *********************/
+/* This example implements one process which receives messages from two other */
+/* processes. There is no bug on it, it is just provided to test the soundness*/ 
+/* of the state space reduction with DPOR, if the maximum depth (defined with */
+/* --cfg=model-check/max_depth:) is reached.                                  */
+/******************************************************************************/
+
+#include <msg/msg.h>
+#include <simgrid/modelchecker.h>
+
+#define N 2
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(electric_fence, "Example to check the soundness of DPOR");
+
+int server(int argc, char *argv[]);
+int client(int argc, char *argv[]);
+
+int server(int argc, char *argv[])
+{
+  msg_task_t task1 = NULL, task2 = NULL;
+  msg_comm_t comm_received1 = NULL, comm_received2 = NULL;
+
+  comm_received1 = MSG_task_irecv(&task1, "mymailbox");
+  comm_received2 = MSG_task_irecv(&task2, "mymailbox");
+
+  MSG_comm_wait(comm_received1, -1);
+  MSG_comm_wait(comm_received2, -1);
+
+  XBT_INFO("OK");
+  return 0;
+}
+
+int client(int argc, char *argv[])
+{
+
+  msg_task_t task = MSG_task_create(argv[1], 0, 10000, NULL);
+
+  MSG_task_send(task, "mymailbox");
+  
+  XBT_INFO("Sent!");
+  return 0;
+}
+
+int main(int argc, char *argv[])
+{
+
+  MSG_init(&argc, argv);
+
+  MSG_create_environment("platform.xml");
+
+  MSG_function_register("server", server);
+
+  MSG_function_register("client", client);
+
+  MSG_launch_application("deploy_electric_fence.xml");
+
+  MSG_main();
+
+  return 0;
+
+}
diff --git a/examples/msg/mc/random_test.c b/examples/msg/mc/random_test.c
deleted file mode 100644 (file)
index 8814bdf..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <msg/msg.h>
-#include <simgrid/modelchecker.h>
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(random_test, "Random Test");
-
-int server(int argc, char *argv[]);
-
-int server(int argc, char *argv[])
-{
-  int val;
-  val = MC_random(3, 6);
-  XBT_INFO("val=%d", val);
-  XBT_INFO("OK");
-  return 0;
-}
-
-int main(int argc, char *argv[])
-{
-  MSG_init(&argc, argv);
-
-  MSG_create_environment("platform.xml");
-
-  MSG_function_register("server", server);
-
-//  MSG_function_register("client", client);
-
-  MSG_launch_application("deploy_random_test.xml");
-
-  MSG_main();
-
-  return 0;
-}
index eda1d82..58d9040 100644 (file)
@@ -20,13 +20,13 @@ if(enable_smpi)
   add_executable(mc_bugged2 mc_bugged2.c)
   add_executable(smpi_replay replay/replay.c)
 
-  target_link_libraries(bcbench simgrid smpi )
-  target_link_libraries(mvmul simgrid smpi )
-  target_link_libraries(smpi_traced simgrid smpi )
-  target_link_libraries(smpi_traced_simple simgrid smpi )
-  target_link_libraries(mc_bugged1 simgrid smpi )
-  target_link_libraries(mc_bugged2 simgrid smpi )
-  target_link_libraries(smpi_replay simgrid smpi )
+  target_link_libraries(bcbench simgrid)
+  target_link_libraries(mvmul simgrid)
+  target_link_libraries(smpi_traced simgrid)
+  target_link_libraries(smpi_traced_simple simgrid)
+  target_link_libraries(mc_bugged1 simgrid)
+  target_link_libraries(mc_bugged2 simgrid)
+  target_link_libraries(smpi_replay simgrid)
 
 endif()
 
index 2965048..366f39c 100644 (file)
@@ -8,7 +8,7 @@ if(enable_smpi)
   if(NOT WIN32)
     add_executable(MM_mpi MM_mpi.c 2.5D_MM.c Summa.c Matrix_init.c)
     ### Add definitions for compile
-    target_link_libraries(MM_mpi simgrid pthread smpi)
+    target_link_libraries(MM_mpi simgrid pthread)
   endif()
 endif()
 
index 986a463..0826da7 100644 (file)
@@ -300,7 +300,7 @@ XBT_PUBLIC(msg_error_t)
     MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task,
                              double timeout);
 
-void MSG_mailbox_set_async(const char *alias);
+XBT_PUBLIC(void) MSG_mailbox_set_async(const char *alias);
 
 
 /************************** Action handling **********************************/
index 49ad142..652b8bc 100644 (file)
@@ -187,6 +187,9 @@ typedef struct s_sg_platf_cluster_cbarg {
   double lat;
   double bb_bw;
   double bb_lat;
+  double loopback_bw;
+  double loopback_lat;
+  double limiter_link;
   const char* router_id;
   e_surf_link_sharing_policy_t sharing_policy;
   e_surf_link_sharing_policy_t bb_sharing_policy;
index 7c900d8..632e77d 100644 (file)
       parameter(MPI_BAND=9)
       parameter(MPI_BOR=10)
       parameter(MPI_BXOR=11)
+      
+      INTEGER MPI_ADDRESS_KIND, MPI_OFFSET_KIND
+      PARAMETER (MPI_ADDRESS_KIND=8)
+      PARAMETER (MPI_OFFSET_KIND=8)
+      
+      INTEGER MPI_MODE_NOPRECEDE
+      PARAMETER (MPI_MODE_NOPRECEDE=8192)
 
       external MPI_INIT, MPI_FINALIZE, MPI_ABORT
       external MPI_COMM_RANK, MPI_COMM_SIZE, MPI_COMM_DUP, MPI_COMM_SPLIT
index aa601ec..b3cfb99 100644 (file)
@@ -401,6 +401,8 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Probe,
 //FIXME: these are not yet implemented
 
 typedef void MPI_Handler_function(MPI_Comm*, int*, ...);
+typedef int MPI_Win;
+typedef int MPI_Info;
 typedef void* MPI_Errhandler;
 typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval, void* extra_state, void* attribute_val_in,
                               void* attribute_val_out, int* flag);
@@ -464,6 +466,14 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Get_elements, (MPI_Status* status, MPI_Datatype da
 MPI_CALL(XBT_PUBLIC(int), MPI_Dims_create, (int nnodes, int ndims, int* dims));
 MPI_CALL(XBT_PUBLIC(int), MPI_Initialized, (int* flag));
 MPI_CALL(XBT_PUBLIC(int), MPI_Pcontrol, (const int level ));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_fence,( int assert,  MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_free,( MPI_Win* win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_create,( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_create,( MPI_Info *info));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_set,( MPI_Info *info, char *key, char *value));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_free,( MPI_Info *info));
+MPI_CALL(XBT_PUBLIC(int), MPI_Get,( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
+    MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win));
 
 //FIXME: End of all the not yet implemented stuff
 
@@ -508,10 +518,10 @@ XBT_PUBLIC(void*) smpi_shared_set_call(const char* func, const char* input, void
                                          : smpi_shared_set_call(#func, input, func(__VA_ARGS__)))
 
 /* Fortran specific stuff */
-XBT_PUBLIC(int) __attribute__((weak)) smpi_simulated_main__(int argc, char** argv);
+XBT_PUBLIC(int) __attribute__((weak)) smpi_simulated_main_(int argc, char** argv);
 XBT_PUBLIC(int) __attribute__((weak)) MAIN__(void);
 XBT_PUBLIC(int) smpi_main(int (*realmain) (int argc, char *argv[]),int argc, char *argv[]);
-XBT_PUBLIC(void) __attribute__((weak)) user_main__(void);
+XBT_PUBLIC(void) __attribute__((weak)) user_main_(void);
 
 XBT_PUBLIC(int) smpi_process_index(void);
 
index 00bea13..f619d05 100644 (file)
@@ -179,6 +179,8 @@ typedef int AT_surfxml_cluster_bb___bw;
 typedef int AT_surfxml_argument_value;
 #define AU_surfxml_argument_value NULL
 typedef enum { AU_surfxml_link_state, A_surfxml_link_state_ON,A_surfxml_link_state_OFF } AT_surfxml_link_state;
+typedef int AT_surfxml_cluster_loopback___bw;
+#define AU_surfxml_cluster_loopback___bw NULL
 typedef int AT_surfxml_ASroute_gw___src;
 #define AU_surfxml_ASroute_gw___src NULL
 typedef enum { AU_surfxml_AS_routing, A_surfxml_AS_routing_Full,A_surfxml_AS_routing_Floyd,A_surfxml_AS_routing_Dijkstra,A_surfxml_AS_routing_DijkstraCache,A_surfxml_AS_routing_None,A_surfxml_AS_routing_RuleBased,A_surfxml_AS_routing_Vivaldi,A_surfxml_AS_routing_Cluster } AT_surfxml_AS_routing;
@@ -263,6 +265,8 @@ typedef int AT_surfxml_peer_id;
 #define AU_surfxml_peer_id NULL
 typedef int AT_surfxml_cluster_router___id;
 #define AU_surfxml_cluster_router___id NULL
+typedef int AT_surfxml_cluster_loopback___lat;
+#define AU_surfxml_cluster_loopback___lat NULL
 typedef int AT_surfxml_cabinet_radical;
 #define AU_surfxml_cabinet_radical NULL
 typedef enum { AU_surfxml_cluster_sharing___policy, A_surfxml_cluster_sharing___policy_SHARED,A_surfxml_cluster_sharing___policy_FULLDUPLEX,A_surfxml_cluster_sharing___policy_FATPIPE } AT_surfxml_cluster_sharing___policy;
@@ -304,6 +308,8 @@ typedef int AT_surfxml_random_std___deviation;
 #define AU_surfxml_random_std___deviation NULL
 typedef int AT_surfxml_cluster_core;
 #define AU_surfxml_cluster_core NULL
+typedef int AT_surfxml_cluster_limiter___link;
+#define AU_surfxml_cluster_limiter___link NULL
 typedef int AT_surfxml_host_state___file;
 #define AU_surfxml_host_state___file NULL
 typedef int AT_surfxml_route_dst;
@@ -437,6 +443,9 @@ XBT_PUBLIC_DATA(short int) surfxml_argument_value_isset;
 XBT_PUBLIC_DATA(AT_surfxml_link_state) AX_surfxml_link_state;
 #define A_surfxml_link_state AX_surfxml_link_state
 XBT_PUBLIC_DATA(short int) surfxml_link_state_isset;
+XBT_PUBLIC_DATA(AT_surfxml_cluster_loopback___bw) AX_surfxml_cluster_loopback___bw;
+#define A_surfxml_cluster_loopback___bw (surfxml_bufferstack + AX_surfxml_cluster_loopback___bw)
+XBT_PUBLIC_DATA(short int) surfxml_cluster_loopback___bw_isset;
 XBT_PUBLIC_DATA(AT_surfxml_ASroute_gw___src) AX_surfxml_ASroute_gw___src;
 #define A_surfxml_ASroute_gw___src (surfxml_bufferstack + AX_surfxml_ASroute_gw___src)
 XBT_PUBLIC_DATA(short int) surfxml_ASroute_gw___src_isset;
@@ -569,6 +578,9 @@ XBT_PUBLIC_DATA(short int) surfxml_peer_id_isset;
 XBT_PUBLIC_DATA(AT_surfxml_cluster_router___id) AX_surfxml_cluster_router___id;
 #define A_surfxml_cluster_router___id (surfxml_bufferstack + AX_surfxml_cluster_router___id)
 XBT_PUBLIC_DATA(short int) surfxml_cluster_router___id_isset;
+XBT_PUBLIC_DATA(AT_surfxml_cluster_loopback___lat) AX_surfxml_cluster_loopback___lat;
+#define A_surfxml_cluster_loopback___lat (surfxml_bufferstack + AX_surfxml_cluster_loopback___lat)
+XBT_PUBLIC_DATA(short int) surfxml_cluster_loopback___lat_isset;
 XBT_PUBLIC_DATA(AT_surfxml_cabinet_radical) AX_surfxml_cabinet_radical;
 #define A_surfxml_cabinet_radical (surfxml_bufferstack + AX_surfxml_cabinet_radical)
 XBT_PUBLIC_DATA(short int) surfxml_cabinet_radical_isset;
@@ -632,6 +644,9 @@ XBT_PUBLIC_DATA(short int) surfxml_random_std___deviation_isset;
 XBT_PUBLIC_DATA(AT_surfxml_cluster_core) AX_surfxml_cluster_core;
 #define A_surfxml_cluster_core (surfxml_bufferstack + AX_surfxml_cluster_core)
 XBT_PUBLIC_DATA(short int) surfxml_cluster_core_isset;
+XBT_PUBLIC_DATA(AT_surfxml_cluster_limiter___link) AX_surfxml_cluster_limiter___link;
+#define A_surfxml_cluster_limiter___link (surfxml_bufferstack + AX_surfxml_cluster_limiter___link)
+XBT_PUBLIC_DATA(short int) surfxml_cluster_limiter___link_isset;
 XBT_PUBLIC_DATA(AT_surfxml_host_state___file) AX_surfxml_host_state___file;
 #define A_surfxml_host_state___file (surfxml_bufferstack + AX_surfxml_host_state___file)
 XBT_PUBLIC_DATA(short int) surfxml_host_state___file_isset;
index ed7f5c4..d172618 100644 (file)
@@ -19,23 +19,74 @@ void TRACE_smpi_finalize(int rank);
 typedef struct mpi_coll_description {
   const char *name;
   const char *description;
-  voidcoll;
+  void *coll;
 } s_mpi_coll_description_t, *mpi_coll_description_t;
 
-/** \ingroup MPI alltoallcollectives
- *  \brief The list of all available alltoall collectives
+/** \ingroup MPI allgather
+ *  \brief The list of all available allgather collectives
  */
-XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_alltoall_description[];
-int (*mpi_coll_alltoall_fun)(void *, int, MPI_Datatype, void*, int, MPI_Datatype, MPI_Comm);
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_allgather_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_allgather_fun)
+                (void *, int, MPI_Datatype, void *, int, MPI_Datatype,
+                 MPI_Comm));
 
 /** \ingroup MPI allgather
  *  \brief The list of all available allgather collectives
  */
-XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_allgather_description[];
-int (*mpi_coll_allgather_fun)(void *, int, MPI_Datatype, void*, int, MPI_Datatype, MPI_Comm);
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_allgatherv_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_allgatherv_fun)
+                (void *, int, MPI_Datatype, void *, int*, int*, MPI_Datatype,
+                 MPI_Comm));
+
 
-XBT_PUBLIC(void) coll_help(const char *category, s_mpi_coll_description_t * table);
+/** \ingroup MPI allreduce
+ *  \brief The list of all available allgather collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_allreduce_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_allreduce_fun)
+                (void *sbuf, void *rbuf, int rcount, MPI_Datatype dtype,
+                 MPI_Op op, MPI_Comm comm));
+
+
+/** \ingroup MPI alltoall
+ *  \brief The list of all available alltoall collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_alltoall_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_alltoall_fun)
+                (void *, int, MPI_Datatype, void *, int, MPI_Datatype,
+                 MPI_Comm));
+
+/** \ingroup MPI alltoallv
+ *  \brief The list of all available alltoallv collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_alltoallv_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_alltoallv_fun)
+                (void *, int*, int*, MPI_Datatype, void *, int*, int*, MPI_Datatype,
+                 MPI_Comm));
+
+
+/** \ingroup MPI bcast
+ *  \brief The list of all available bcast collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_bcast_description[];
+XBT_PUBLIC_DATA(int (*mpi_coll_bcast_fun)
+                (void *buf, int count, MPI_Datatype datatype, int root,
+                 MPI_Comm com));
+
+
+/** \ingroup MPI reduce
+ *  \brief The list of all available reduce collectives
+ */
+XBT_PUBLIC_DATA(s_mpi_coll_description_t) mpi_coll_reduce_description[];
+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));
+
+
+XBT_PUBLIC(void) coll_help(const char *category,
+                           s_mpi_coll_description_t * table);
 XBT_PUBLIC(int) find_coll_description(s_mpi_coll_description_t * table,
-                           const char *name);
+                                      const char *name);
+
 
 #endif                          /* _SMPI_INTERFAC_H */
index 0092095..ab31a17 100644 (file)
@@ -12,6 +12,8 @@ typedef struct s_surf_parsing_link_up_down *surf_parsing_link_up_down_t;
 typedef struct s_surf_parsing_link_up_down {
   void* link_up;
   void* link_down;
+  void* limiter_link;
+  void* loopback_link;
 } s_surf_parsing_link_up_down_t;
 
 #endif /* SURFXML_PARSE_VALUES_H_ */
index f41aad7..7d61fef 100644 (file)
@@ -19,6 +19,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration");
 #define OPT_TRACING_SMPI          "tracing/smpi"
 #define OPT_TRACING_SMPI_GROUP    "tracing/smpi/group"
 #define OPT_TRACING_SMPI_COMPUTING "tracing/smpi/computing"
+#define OPT_TRACING_SMPI_INTERNALS "tracing/smpi/internals"
 #define OPT_TRACING_CATEGORIZED   "tracing/categorized"
 #define OPT_TRACING_UNCATEGORIZED "tracing/uncategorized"
 #define OPT_TRACING_MSG_PROCESS   "tracing/msg/process"
@@ -41,6 +42,7 @@ static int trace_platform_topology;
 static int trace_smpi_enabled;
 static int trace_smpi_grouped;
 static int trace_smpi_computing;
+static int trace_view_internals;
 static int trace_categorized;
 static int trace_uncategorized;
 static int trace_msg_process_enabled;
@@ -65,6 +67,7 @@ static void TRACE_getopts(void)
   trace_smpi_enabled = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI);
   trace_smpi_grouped = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI_GROUP);
   trace_smpi_computing = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI_COMPUTING);
+  trace_view_internals = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_SMPI_INTERNALS);
   trace_categorized = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_CATEGORIZED);
   trace_uncategorized = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_UNCATEGORIZED);
   trace_msg_process_enabled = xbt_cfg_get_int(_sg_cfg_set, OPT_TRACING_MSG_PROCESS);
@@ -225,6 +228,10 @@ int TRACE_smpi_is_computing(void)
   return trace_smpi_computing;
 }
 
+int TRACE_smpi_view_internals(void)
+{
+  return trace_view_internals;
+}
 
 int TRACE_categorized (void)
 {
@@ -352,6 +359,13 @@ void TRACE_global_init(int *argc, char **argv)
                    xbt_cfgelm_int, &default_tracing_smpi_computing, 0, 1,
                    NULL, NULL);
 
+  /* smpi internals */
+  int default_tracing_smpi_internals = 0;
+  xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_SMPI_INTERNALS,
+                   "View internal messages sent by Collective communications in SMPI",
+                   xbt_cfgelm_int, &default_tracing_smpi_internals, 0, 1,
+                   NULL, NULL);
+
   /* tracing categorized resource utilization traces */
   int default_tracing_categorized = 0;
   xbt_cfg_register(&_sg_cfg_set, OPT_TRACING_CATEGORIZED,
@@ -506,6 +520,9 @@ void TRACE_help (int detailed)
       "  This option aims at tracing computations in the application, outside SMPI\n"
       "  to allow further study of simulated or real computation time",
       detailed);
+  print_line (OPT_TRACING_SMPI_INTERNALS, "Generates tracing events corresponding",
+      "  to point-to-point messages sent by collective communications",
+      detailed);
   print_line (OPT_TRACING_MSG_PROCESS, "Trace processes behavior (MSG)",
       "  This option only has effect if this simulator is MSG-based. It traces the\n"
       "  behavior of all categorized MSG processes, grouping them by hosts. This option\n"
index 07f7dce..24f2af3 100644 (file)
@@ -161,6 +161,7 @@ void instr_resume_tracing (void);
 XBT_PUBLIC(int) TRACE_smpi_is_enabled(void);
 XBT_PUBLIC(int) TRACE_smpi_is_grouped(void);
 XBT_PUBLIC(int) TRACE_smpi_is_computing(void);
+XBT_PUBLIC(int) TRACE_smpi_view_internals(void);
 
 /* from resource_utilization.c */
 void TRACE_surf_host_set_utilization(const char *resource,
index 7388684..da1efaa 100644 (file)
@@ -72,33 +72,17 @@ static int compare_global_variables(int region_type, void *d1, void *d2){ /* reg
     }
     i = 0;
     while(i < current_var->size){
-      if(memcmp((char*)d1 + offset + i, (char*)d2 + offset + i, 1) != 0){
+      if(memcmp((char *)d1 + offset + i, (char *)d2 + offset + i, 1) != 0){ 
         pointer_align = (i / sizeof(void*)) * sizeof(void*); 
         addr_pointed1 = *((void **)((char *)d1 + offset + pointer_align));
         addr_pointed2 = *((void **)((char *)d2 + offset + pointer_align));
         if((addr_pointed1 > plt_start && addr_pointed1 < plt_end) || (addr_pointed2 > plt_start && addr_pointed2 < plt_end)){
-          break;
-        }else{
-          if((addr_pointed1 > std_heap) && ((char *)addr_pointed1 < (char *)std_heap + STD_HEAP_SIZE) 
-             && (addr_pointed2 > std_heap) && ((char *)addr_pointed2 < (char *)std_heap + STD_HEAP_SIZE)){
-            res_compare = compare_area(addr_pointed1, addr_pointed2, NULL);
-            if(res_compare == 1){
-              #ifdef MC_VERBOSE
-              if(region_type == 2)
-                XBT_VERB("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
-              else
-                XBT_VERB("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
-              #endif
-              #ifdef MC_DEBUG
-                if(region_type == 2)
-                  XBT_DEBUG("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
-                else
-                  XBT_DEBUG("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
-              #endif
-                XBT_INFO("Different global variable (%p, %p) : %s at addresses %p - %p (size = %zu)", current_var->address, addr_pointed1, current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
-              return 1;
-            }
-          }else{
+          i = pointer_align + sizeof(void*);
+          continue;
+        }else if((addr_pointed1 > std_heap) && ((char *)addr_pointed1 < (char *)std_heap + STD_HEAP_SIZE) 
+                && (addr_pointed2 > std_heap) && ((char *)addr_pointed2 < (char *)std_heap + STD_HEAP_SIZE)){
+          res_compare = compare_area(addr_pointed1, addr_pointed2, NULL);
+          if(res_compare == 1){
             #ifdef MC_VERBOSE
               if(region_type == 2)
                 XBT_VERB("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
@@ -111,12 +95,26 @@ static int compare_global_variables(int region_type, void *d1, void *d2){ /* reg
               else
                 XBT_DEBUG("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
             #endif
-              XBT_INFO("Different global variable (%p, %p) : %s at addresses %p - %p (size = %zu)", current_var->address, addr_pointed1, current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
             return 1;
           }
-              
-        }
-      } 
+          i = pointer_align + sizeof(void*);
+          continue;
+        }else{
+          #ifdef MC_VERBOSE
+            if(region_type == 2)
+              XBT_VERB("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+            else
+              XBT_VERB("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+          #endif
+          #ifdef MC_DEBUG
+            if(region_type == 2)
+              XBT_DEBUG("Different global variable in binary : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+            else
+              XBT_DEBUG("Different global variable in libsimgrid : %s at addresses %p - %p (size = %zu)", current_var->name, (char *)d1+offset, (char *)d2+offset, current_var->size);
+          #endif
+          return 1;
+        }              
+      }
       i++;
     }
   }
@@ -409,49 +407,48 @@ int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){
     xbt_os_timer_start(timer);
   #endif
 
-    /* Stacks comparison */
-    unsigned int  cursor = 0;
-    int diff_local = 0;
-    is_diff = 0;
+  /* Stacks comparison */
+  unsigned int  cursor = 0;
+  int diff_local = 0;
+  is_diff = 0;
     
-    while(cursor < xbt_dynar_length(s1->stacks)){
-      diff_local = compare_local_variables(((mc_snapshot_stack_t)xbt_dynar_get_as(s1->stacks, cursor, mc_snapshot_stack_t))->local_variables->data, ((mc_snapshot_stack_t)xbt_dynar_get_as(s2->stacks, cursor, mc_snapshot_stack_t))->local_variables->data);
-      if(diff_local > 0){
-        #ifdef MC_DEBUG
-          if(is_diff == 0){
-            xbt_os_timer_stop(timer);
-            mc_comp_times->stacks_comparison_time = xbt_os_timer_elapsed(timer); 
-          }
-          XBT_DEBUG("Different local variables between stacks %d", cursor + 1);
-          errors++;
-          is_diff = 1;
-        #else
+  while(cursor < xbt_dynar_length(s1->stacks)){
+    diff_local = compare_local_variables(((mc_snapshot_stack_t)xbt_dynar_get_as(s1->stacks, cursor, mc_snapshot_stack_t))->local_variables->data, ((mc_snapshot_stack_t)xbt_dynar_get_as(s2->stacks, cursor, mc_snapshot_stack_t))->local_variables->data);
+    if(diff_local > 0){
+      #ifdef MC_DEBUG
+        if(is_diff == 0){
+          xbt_os_timer_stop(timer);
+          mc_comp_times->stacks_comparison_time = xbt_os_timer_elapsed(timer); 
+        }
+        XBT_DEBUG("Different local variables between stacks %d", cursor + 1);
+        errors++;
+        is_diff = 1;
+      #else
         
-          #ifdef MC_VERBOSE
-            XBT_VERB("Different local variables between stacks %d", cursor + 1);
-          #endif
-          
-            reset_heap_information();
-            xbt_os_timer_free(timer);
-            xbt_os_timer_stop(global_timer);
-            mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
-            xbt_os_timer_free(global_timer);
-            
-            if(!raw_mem)
-              MC_UNSET_RAW_MEM;
-            
-            return 1;
+        #ifdef MC_VERBOSE
+          XBT_VERB("Different local variables between stacks %d", cursor + 1);
         #endif
-      }
-      cursor++;
+          
+        reset_heap_information();
+        xbt_os_timer_free(timer);
+        xbt_os_timer_stop(global_timer);
+        mc_snapshot_comparison_time = xbt_os_timer_elapsed(global_timer);
+        xbt_os_timer_free(global_timer);
+        
+        if(!raw_mem)
+          MC_UNSET_RAW_MEM;
+        
+        return 1;
+      #endif
     }
+    cursor++;
+  }
     
-    #ifdef MC_DEBUG
-      xbt_os_timer_start(timer);
-    #endif
+  #ifdef MC_DEBUG
+    xbt_os_timer_start(timer);
+  #endif
 
   /* Compare heap */
   if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[0]->data, (xbt_mheap_t)s2->regions[0]->data)){
 
     #ifdef MC_DEBUG
@@ -572,7 +569,7 @@ static int compare_local_variables(char *s1, char *s2){
             continue;
           }else {
             #ifdef MC_VERBOSE
-              XBT_VERB("Different local variable : %s at addresses %p - %p", var_name, addr1, addr2);
+              XBT_VERB("Different local variable : %s at addresses %p - %p in frame %s", var_name, addr1, addr2, frame_name1);
             #endif
             #ifdef MC_DEBUG
               XBT_DEBUG("Different local variable : %s at addresses %p - %p", var_name, addr1, addr2);
@@ -595,7 +592,7 @@ static int compare_local_variables(char *s1, char *s2){
             continue;
           }else {
             #ifdef MC_VERBOSE
-              XBT_VERB("Different local variable : %s (%s - %s)", var_name, xbt_dynar_get_as(s_tokens1, 1, char *), xbt_dynar_get_as(s_tokens2, 1, char *));
+              XBT_VERB("Different local variable : %s (%s - %s) in frame %s", var_name, xbt_dynar_get_as(s_tokens1, 1, char *), xbt_dynar_get_as(s_tokens2, 1, char *), frame_name1);
             #endif
             #ifdef MC_DEBUG
               XBT_DEBUG("Different local variable : %s (%s - %s)", var_name, xbt_dynar_get_as(s_tokens1, 1, char *), xbt_dynar_get_as(s_tokens2, 1, char *));
index a97440a..7c5b998 100644 (file)
@@ -247,14 +247,14 @@ void MC_dpor(void)
 {
 
   char *req_str;
-  int value, value2;
-  smx_simcall_t req = NULL, prev_req = NULL, req2 = NULL;
-  s_smx_simcall_t req3;
+  int value;
+  smx_simcall_t req = NULL, prev_req = NULL;
   mc_state_t state = NULL, prev_state = NULL, next_state = NULL, restore_state=NULL;
   smx_process_t process = NULL;
   xbt_fifo_item_t item = NULL;
   int pos;
   int visited_state;
+  int enabled = 0, max_depth_reached = 0;
 
   while (xbt_fifo_size(mc_stack_safety) > 0) {
 
@@ -282,7 +282,8 @@ void MC_dpor(void)
         xbt_free(req_str);
       }
         
-      req_str = MC_request_get_dot_output(req, value);
+      if(dot_output != NULL)
+        req_str = MC_request_get_dot_output(req, value);
 
       MC_state_set_executed_request(state, req, value);
       mc_stats->executed_transitions++;
@@ -293,8 +294,6 @@ void MC_dpor(void)
       xbt_free(key);
       MC_UNSET_RAW_MEM;
 
-      MC_state_set_executed_request(state, req, value);
-
       /* Answer the request */
       SIMIX_simcall_pre(req, value); /* After this call req is no longer usefull */
 
@@ -347,24 +346,64 @@ void MC_dpor(void)
 
       MC_UNSET_RAW_MEM;
 
-      xbt_free(req_str);
+      if(dot_output != NULL)
+        xbt_free(req_str);
 
       /* Let's loop again */
 
       /* The interleave set is empty or the maximum depth is reached, let's back-track */
     } else {
 
-      if(xbt_fifo_size(mc_stack_safety) == _sg_mc_max_depth)  
+      if(xbt_fifo_size(mc_stack_safety) > _sg_mc_max_depth){  
+
         XBT_WARN("/!\\ Max depth reached ! /!\\ ");
-      else
+
+        /* Interleave enabled processes in the state in which they have been enabled for the first time */
+        xbt_swag_foreach(process, simix_global->process_list){
+          if(MC_process_is_enabled(process)){
+            char *key = bprintf("%lu", process->pid);
+            enabled = (int)strtoul(xbt_dict_get_or_null(first_enabled_state, key), 0, 10);
+            xbt_free(key);
+            mc_state_t state_test = NULL;
+            xbt_fifo_item_t item = NULL;
+            int cursor = xbt_fifo_size(mc_stack_safety);
+            xbt_fifo_foreach(mc_stack_safety, item, state_test, mc_state_t){
+              if(cursor-- == enabled){ 
+                if(!MC_state_process_is_done(state_test, process)){ 
+                  MC_state_interleave_process(state_test, process);
+                  break;
+                }
+              }
+            } 
+          }
+        }
+
+        if(MC_state_interleave_size(state) > 0){
+          max_depth_reached = 1;
+        }else{
+          /* Trash the current state, no longer needed */
+          MC_SET_RAW_MEM;
+          xbt_fifo_shift(mc_stack_safety);
+          MC_state_delete(state);
+          MC_UNSET_RAW_MEM;
+
+          max_depth_reached = 0;
+        }
+        
+
+      }else{
+
         XBT_DEBUG("There are no more processes to interleave.");
 
-      /* Trash the current state, no longer needed */
-      MC_SET_RAW_MEM;
-      xbt_fifo_shift(mc_stack_safety);
-      MC_state_delete(state);
-      MC_UNSET_RAW_MEM;
+        /* Trash the current state, no longer needed */
+        MC_SET_RAW_MEM;
+        xbt_fifo_shift(mc_stack_safety);
+        MC_state_delete(state);
+        MC_UNSET_RAW_MEM;
 
+        max_depth_reached = 0;
+      }
+      
       /* Check for deadlocks */
       if(MC_deadlock_check()){
         MC_show_deadlock(NULL);
@@ -381,33 +420,11 @@ void MC_dpor(void)
       
       while ((state = xbt_fifo_shift(mc_stack_safety)) != NULL) {
         if(mc_reduce_kind != e_mc_reduce_none){
-          req = MC_state_get_internal_request(state);
-          /* If max_depth reached, check only for the last state if the request that has generated
-             it, depends on any other processes still enabled when max_depth reached */
-          if(xbt_fifo_size(mc_stack_safety) == _sg_mc_max_depth - 1){
-            req3 = *req;
-            xbt_swag_foreach(process, simix_global->process_list){
-              if(MC_process_is_enabled(process) && !MC_state_process_is_done(state, process)){
-                MC_state_interleave_process(state, process);
-                req2 = MC_state_get_request(state, &value2);
-                MC_state_set_executed_request(state, req2, value2);
-                req2 = MC_state_get_internal_request(state);
-                if(MC_request_depend(&req3, req2)){
-                  if(XBT_LOG_ISENABLED(mc_dpor, xbt_log_priority_debug)){
-                    XBT_DEBUG("Dependent Transitions:");
-                    req_str = MC_request_to_string(&req3, value);
-                    XBT_DEBUG("%s (state=%p)", req_str, state);
-                    xbt_free(req_str);
-                    req_str = MC_request_to_string(req2, value);
-                    XBT_DEBUG("%s (state=%p)", req_str, state);
-                    xbt_free(req_str);              
-                  } 
-                  MC_state_interleave_process(state, process);
-                  break;
-                }
-              }
-            }
+          if((xbt_fifo_size(mc_stack_safety) == _sg_mc_max_depth) && max_depth_reached){
+            req = MC_state_get_request(state, &value);
+            MC_state_set_executed_request(state, req, value);
           }
+          req = MC_state_get_internal_request(state);
           xbt_fifo_foreach(mc_stack_safety, item, prev_state, mc_state_t) {
             if(MC_request_depend(req, MC_state_get_internal_request(prev_state))){
               if(XBT_LOG_ISENABLED(mc_dpor, xbt_log_priority_debug)){
@@ -438,8 +455,9 @@ void MC_dpor(void)
           }
         }
              
-        if (MC_state_interleave_size(state)) {
+        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);
           if(_sg_mc_checkpoint){
             if(state->system_state != NULL){
               MC_restore_snapshot(state->system_state);
index 562eb37..430da06 100644 (file)
@@ -138,9 +138,6 @@ void MC_do_the_modelcheck_for_real() {
   mc_comp_times = xbt_new0(s_mc_comparison_times_t, 1);
   MC_UNSET_RAW_MEM;
   
-  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0'))
-    MC_init_dot_output();
-
   if (!_sg_mc_property_file || _sg_mc_property_file[0]=='\0') {
     if (mc_reduce_kind==e_mc_reduce_unset)
       mc_reduce_kind=e_mc_reduce_dpor;
@@ -213,6 +210,9 @@ void MC_init(){
   MC_ignore_stack("next_context", "smx_ctx_sysv_suspend_serial");
   MC_ignore_stack("i", "smx_ctx_sysv_suspend_serial");
 
+  /* Ignore local variable about time used for tracing */
+  MC_ignore_stack("start_time", "*"); 
+
   MC_ignore_data_bss(&mc_comp_times, sizeof(mc_comp_times));
   MC_ignore_data_bss(&mc_snapshot_comparison_time, sizeof(mc_snapshot_comparison_time)); 
   MC_ignore_data_bss(&mc_time, sizeof(mc_time));
@@ -269,6 +269,9 @@ void MC_modelcheck_safety(void)
   /* Create exploration stack */
   mc_stack_safety = xbt_fifo_new();
 
+  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0'))
+    MC_init_dot_output();
+
   MC_UNSET_RAW_MEM;
 
   if(_sg_mc_visited > 0){
@@ -320,6 +323,9 @@ void MC_modelcheck_liveness(){
   /* Create the initial state */
   initial_state_liveness = xbt_new0(s_mc_global_t, 1);
 
+  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0'))
+    MC_init_dot_output();
+  
   MC_UNSET_RAW_MEM;
 
   MC_ddfs_init();
@@ -336,13 +342,6 @@ void MC_modelcheck_liveness(){
 
 void MC_exit(void)
 {
-  MC_SET_RAW_MEM;
-  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0')){
-    fprintf(dot_output, "}\n");
-    fclose(dot_output);
-  }
-  MC_UNSET_RAW_MEM;
-
   xbt_free(mc_time);
   MC_memory_exit();
   xbt_abort();
@@ -738,6 +737,12 @@ void MC_print_statistics(mc_stats_t stats)
     XBT_INFO("Visited pairs = %lu", stats->visited_pairs);
   }
   XBT_INFO("Executed transitions = %lu", stats->executed_transitions);
+  MC_SET_RAW_MEM;
+  if((_sg_mc_dot_output_file != NULL) && (_sg_mc_dot_output_file[0]!='\0')){
+    fprintf(dot_output, "}\n");
+    fclose(dot_output);
+  }
+  MC_UNSET_RAW_MEM;
 }
 
 void MC_assert(int prop)
@@ -844,10 +849,10 @@ void MC_ignore_heap(void *address, size_t size){
   
   if(((xbt_mheap_t)std_heap)->heapinfo[region->block].type == 0){
     region->fragment = -1;
-    ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_block.ignore = 1;
+    ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_block.ignore++;
   }else{
     region->fragment = ((uintptr_t) (ADDR2UINT (address) % (BLOCKSIZE))) >> ((xbt_mheap_t)std_heap)->heapinfo[region->block].type;
-    ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_frag.ignore[region->fragment] = 1;
+    ((xbt_mheap_t)std_heap)->heapinfo[region->block].busy_frag.ignore[region->fragment]++;
   }
   
   if(mc_heap_comparison_ignore == NULL){
index 362e331..424929e 100644 (file)
@@ -605,6 +605,7 @@ void MC_ddfs(int search_cycle){
   xbt_automaton_transition_t transition_succ;
   unsigned int cursor = 0;
   int res;
+  int reached_num;
 
   mc_pair_t next_pair = NULL;
   mc_pair_t pair_succ;
@@ -694,9 +695,9 @@ void MC_ddfs(int search_cycle){
 
             if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){ 
           
-              if(is_reached_acceptance_pair(pair_succ->num, pair_succ->automaton_state) != -1){
+              if((reached_num = is_reached_acceptance_pair(pair_succ->num, pair_succ->automaton_state)) != -1){
         
-                XBT_INFO("Next pair (depth = %d, %u interleave) already reached !", xbt_fifo_size(mc_stack_liveness) + 1, MC_state_interleave_size(pair_succ->graph_state));
+                XBT_INFO("Next pair (depth = %d, %u interleave) already reached (equal to state %d) !", xbt_fifo_size(mc_stack_liveness) + 1, MC_state_interleave_size(pair_succ->graph_state), reached_num);
 
                 XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
                 XBT_INFO("|             ACCEPTANCE CYCLE            |");
@@ -845,9 +846,9 @@ void MC_ddfs(int search_cycle){
 
           if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){ 
 
-            if(is_reached_acceptance_pair(pair_succ->num, pair_succ->automaton_state) != -1){
+            if((reached_num = is_reached_acceptance_pair(pair_succ->num, pair_succ->automaton_state)) != -1){
            
-              XBT_INFO("Next pair (depth = %d) already reached !", xbt_fifo_size(mc_stack_liveness) + 1);
+              XBT_INFO("Next pair (depth = %d) already reached (equal to state %d)!", xbt_fifo_size(mc_stack_liveness) + 1, reached_num);
         
               XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
               XBT_INFO("|             ACCEPTANCE CYCLE            |");
index c25a0bc..95b4b9e 100644 (file)
@@ -24,7 +24,7 @@ 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)
+  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)
@@ -32,13 +32,13 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
 
     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)
+    if((simcall_comm_wait__get__comm(r2)->comm.rdv != rdv) && (simcall_comm_wait__get__timeout(r2) <= 0))
       return FALSE;
 
-    if(simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND && r1->call == SIMCALL_COMM_ISEND)
+    if((simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_SEND) && (r1->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__timeout(r2) <= 0))
       return FALSE;
 
-    if(simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE && r1->call == SIMCALL_COMM_IRECV)
+    if((simcall_comm_wait__get__comm(r2)->comm.type == SIMIX_COMM_RECEIVE) && (r1->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__timeout(r2) <= 0))
       return FALSE;
   }
 
@@ -50,15 +50,15 @@ int MC_request_depend(smx_simcall_t r1, smx_simcall_t r2) {
 
     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)
+    if((simcall_comm_wait__get__comm(r1)->comm.rdv != rdv) && (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)
+    if((simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_SEND) && (r2->call == SIMCALL_COMM_ISEND) && (simcall_comm_wait__get__timeout(r1) <= 0))
       return FALSE;
 
-    if(simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE && r2->call == SIMCALL_COMM_IRECV)
+    if((simcall_comm_wait__get__comm(r1)->comm.type == SIMIX_COMM_RECEIVE) && (r2->call == SIMCALL_COMM_IRECV) && (simcall_comm_wait__get__timeout(r1) <= 0))
       return FALSE;
-      }*/
+  }
 
   /* FIXME: the following rule assumes that the result of the
    * isend/irecv call is not stored in a buffer used in the
@@ -195,7 +195,7 @@ char *MC_request_to_string(smx_simcall_t req, int value)
     if(value == -1){
       type = xbt_strdup("WaitTimeout");
       p = pointer_to_string(act);
-      args = bprintf("comm=%p", p);
+      args = bprintf("comm=%s", p);
     }else{
       type = xbt_strdup("Wait");
       p = pointer_to_string(act);
index b431523..b0e84a6 100644 (file)
@@ -32,6 +32,8 @@ memory_map_t get_memory_map(void)
   xbt_assert(fp,
               "Cannot open /proc/self/maps to investigate the memory map of the process. Please report this bug.");
 
+  setbuf(fp, NULL);
+
   ret = xbt_new0(s_memory_map_t, 1);
 
   /* Read one line at the time, parse it and add it to the memory map to be returned */
index 9f3f379..f587002 100644 (file)
@@ -77,7 +77,7 @@ XBT_PUBLIC(int) MSG_mailbox_is_empty(msg_mailbox_t mailbox);
  * \param alias    The alias of the mailbox to modify.
  *
  */
-void MSG_mailbox_set_async(const char *alias);
+XBT_PUBLIC(void) MSG_mailbox_set_async(const char *alias);
 
 /*! \brief MSG_mailbox_get_head - get the task at the head of a mailbox.
  *
index 28fcdf7..63f1a02 100644 (file)
@@ -226,8 +226,9 @@ static void _sg_cfg_cb__weight_S(const char *name, int pos)
   sg_weight_S_parameter = xbt_cfg_get_double(_sg_cfg_set, name);
 }
 
+#ifdef HAVE_SMPI
 /* callback of the mpi collectives */
-static void _sg_cfg_cb__coll(char *category,
+static void _sg_cfg_cb__coll(const char *category,
                             s_mpi_coll_description_t * table,
                             const char *name, int pos)
 {
@@ -246,14 +247,33 @@ static void _sg_cfg_cb__coll(char *category,
   /* New Module missing */
   find_coll_description(table, val);
 }
+static void _sg_cfg_cb__coll_allgather(const char *name, int pos){
+  _sg_cfg_cb__coll("allgather", mpi_coll_allgather_description, name, pos);
+}
+static void _sg_cfg_cb__coll_allgatherv(const char *name, int pos){
+  _sg_cfg_cb__coll("allgatherv", mpi_coll_allgatherv_description, name, pos);
+}
+static void _sg_cfg_cb__coll_allreduce(const char *name, int pos)
+{
+  _sg_cfg_cb__coll("allreduce", mpi_coll_allreduce_description, name, pos);
+}
 static void _sg_cfg_cb__coll_alltoall(const char *name, int pos)
 {
   _sg_cfg_cb__coll("alltoall", mpi_coll_alltoall_description, name, pos);  
 }
-static void _sg_cfg_cb__coll_allgather(const char *name, int pos){
-  _sg_cfg_cb__coll("allgather", mpi_coll_allgather_description, name, pos);
+static void _sg_cfg_cb__coll_alltoallv(const char *name, int pos)
+{
+  _sg_cfg_cb__coll("alltoallv", mpi_coll_alltoallv_description, name, pos);  
 }
-
+static void _sg_cfg_cb__coll_bcast(const char *name, int pos)
+{
+  _sg_cfg_cb__coll("bcast", mpi_coll_bcast_description, name, pos);  
+}
+static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
+{
+  _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);  
+}
+#endif
 
 /* callback of the inclusion path */
 static void _sg_cfg_cb__surf_path(const char *name, int pos)
@@ -674,7 +694,7 @@ void sg_config_init(int *argc, char **argv)
     xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
 #endif
 
-//SMPI
+#ifdef HAVE_SMPI
     double default_reference_speed = 20000.0;
     xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
                      "Power of the host running the simulation (in flop/s). Used to bench the operations.",
@@ -740,19 +760,49 @@ void sg_config_init(int *argc, char **argv)
                      NULL);
     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
 
-    default_value = xbt_strdup("ompi");    
+    default_value = xbt_strdup("default");
+    xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
+                    "Which collective to use for allgather",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_allgather,
+                    NULL);
+
+    default_value = xbt_strdup("default");
+    xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
+                    "Which collective to use for allgatherv",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_allgatherv,
+                    NULL);
+
+    default_value = xbt_strdup("default");
+    xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
+                    "Which collective to use for allreduce",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_allreduce,
+                    NULL);
+
+    default_value = xbt_strdup("ompi");
     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
                     "Which collective to use for alltoall",
                     xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_alltoall,
                     NULL);
 
-    default_value = xbt_strdup("default");    
-    xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
-                    "Which collective to use for allgather",
-                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_allgather,
+    default_value = xbt_strdup("default");
+    xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
+                    "Which collective to use for alltoallv",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_alltoallv,
                     NULL);
-    //END SMPI
 
+    default_value = xbt_strdup("default");
+    xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
+                    "Which collective to use for bcast",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_bcast,
+                    NULL);
+
+
+    default_value = xbt_strdup("default");
+    xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
+                    "Which collective to use for reduce",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_reduce,
+                    NULL);
+#endif // HAVE_SMPI
 
     if (!surf_path) {
       /* retrieves the current directory of the        current process */
index 97b85eb..6fe2029 100644 (file)
@@ -1,39 +1,30 @@
-Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
-All rights reserved.
+Copyright(c) 2006, Ahmad Faraj & Xin Yuan, All rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-  * Redistributions of source code must retain the above copyright notice,
+*Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright notice,
+    * Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation
-    and/or other materials provided with the distribution.
-
-  * Neither the name of the Florida State University nor the names of its
+    and / or other materials provided with the distribution.
+    * Neither the name of the Florida State University nor the names of its
     contributors may be used to endorse or promote products derived from this
-    software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-  ***************************************************************************
-  *     Any results obtained from executing this software require the       *
-  *     acknowledgment and citation of the software and its owners.         *
-  *     The full citation is given below:                                   *
-  *                                                                         *
-  *     A. Faraj, X. Yuan, and D. Lowenthal. "STAR-MPI: Self Tuned Adaptive *
-  *     Routines for MPI Collective Operations." The 20th ACM International *
-  *     Conference on Supercomputing (ICS), Queensland, Australia           *
-  *     June 28-July 1, 2006.                                               *
-  ***************************************************************************
-
+    software without specific prior written permission.THIS SOFTWARE IS PROVIDED
+    BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+    WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE ARE DISCLAIMED.
+    IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
+                             PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+                             LOSS OF USE, DATA, OR PROFITS;
+                             OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON
+    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    ***************************************************************************
+    *Any results obtained from executing this software require the *
+    *acknowledgment and citation of the software and its owners. *
+    *The full citation is given below:****A.Faraj, X.Yuan, and D.Lowenthal."STAR-MPI: Self Tuned Adaptive *
+  *     Routines for MPI Collective Operations." The 20 th ACM International * *Conference on Supercomputing(ICS), Queensland, Australia * *June 28 - July 1, 2006. * ***************************************************************************
diff --git a/src/smpi/colls/allgather-2dmesh.c b/src/smpi/colls/allgather-2dmesh.c
new file mode 100644 (file)
index 0000000..b5f5042
--- /dev/null
@@ -0,0 +1,186 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+
+ * Function: is_2dmesh
+
+ * Return: int
+
+ * Inputs:
+     num: the number of processors in a communicator
+     i: x dimension
+     j: y dimension
+
+ * Descp: takes a number and tries to find a factoring of x, y mesh out of it
+
+ * Auther: Ahmad Faraj
+ ****************************************************************************/
+#ifndef TWOD
+#define TWOD
+static int is_2dmesh(int num, int *i, int *j)
+{
+  int x, max = num / 2;
+  x = sqrt(num);
+
+  while (x <= max) {
+    if ((num % x) == 0) {
+      *i = x;
+      *j = num / x;
+
+      if (*i > *j) {
+        x = *i;
+        *i = *j;
+        *j = x;
+      }
+
+      return 1;
+    }
+    x++;
+  }
+  return 0;
+}
+#endif
+/*****************************************************************************
+ * Function: allgather_2dmesh_shoot
+ * return: int
+ * send_buff: send input buffer
+ * send_count: number of elements to send
+ * send_type: data type of elements being sent
+ * recv_buff: receive output buffer
+ * recv_count: number of elements to received
+ * recv_type: data type of elements being received
+ * comm: communication
+ * Descrp: Function realizes the allgather operation using the 2dmesh
+ * algorithm. Allgather ommunication occurs first in the x dimension then in
+ * the y dimension.  The communication in each dimension follows 
+ * "simple"
+ * Auther: Ahmad Faraj
+****************************************************************************/
+int
+smpi_coll_tuned_allgather_2dmesh(void *send_buff, int send_count, MPI_Datatype
+                                 send_type, void *recv_buff, int recv_count,
+                                 MPI_Datatype recv_type, MPI_Comm comm)
+{
+  MPI_Request *req, *req_ptr;
+  MPI_Aint extent;
+
+  int i, src, dst, rank, num_procs;
+  int X, Y, send_offset, recv_offset;
+  int my_row_base, my_col_base, src_row_base, block_size, num_reqs;
+  int tag = 1;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+
+  extent = smpi_datatype_get_extent(send_type);
+
+  block_size = extent * send_count;
+
+  is_2dmesh(num_procs, &X, &Y);
+  my_row_base = (rank / Y) * Y;
+  my_col_base = rank % Y;
+
+  num_reqs = X;
+  if (Y > X)
+    num_reqs = Y;
+
+  req = (MPI_Request *) xbt_malloc(num_reqs * sizeof(MPI_Request));
+
+  req_ptr = req;
+
+  // do local allgather/local copy 
+  recv_offset = rank * block_size;
+  smpi_datatype_copy(send_buff, send_count, send_type, (char *)recv_buff + recv_offset,
+                 recv_count, recv_type);
+
+  // do row-wise comm
+  for (i = 0; i < Y; i++) {
+    src = i + my_row_base;
+    if (src == rank)
+      continue;
+    recv_offset = src * block_size;
+    *(req_ptr++) = smpi_mpi_irecv((char *)recv_buff + recv_offset, recv_count, recv_type, src, tag,
+               comm);
+  }
+
+
+  for (i = 0; i < Y; i++) {
+    dst = i + my_row_base;
+    if (dst == rank)
+      continue;
+    smpi_mpi_send(send_buff, send_count, send_type, dst, tag, comm);
+  }
+
+  smpi_mpi_waitall(Y - 1, req, MPI_STATUSES_IGNORE);
+
+  req_ptr = req;
+
+  // do colwise comm
+  for (i = 0; i < X; i++) {
+    src = (i * Y + my_col_base);
+    if (src == rank)
+      continue;
+    src_row_base = (src / Y) * Y;
+    recv_offset = src_row_base * block_size;
+    *(req_ptr++) = smpi_mpi_irecv((char *)recv_buff + recv_offset, recv_count * Y, recv_type, src, tag,
+               comm);
+  }
+
+  for (i = 0; i < X; i++) {
+    dst = (i * Y + my_col_base);
+    if (dst == rank)
+      continue;
+    send_offset = my_row_base * block_size;
+    smpi_mpi_send((char *)recv_buff + send_offset, send_count * Y, send_type, dst, tag,
+              comm);
+  }
+
+  smpi_mpi_waitall(X - 1, req, MPI_STATUSES_IGNORE);
+
+  free(req);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-3dmesh.c b/src/smpi/colls/allgather-3dmesh.c
new file mode 100644 (file)
index 0000000..dfd2ace
--- /dev/null
@@ -0,0 +1,200 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+ * Function: is_2dmesh
+ * return: int
+ * num: the number of processors in a communicator
+ * i: x dimension
+ * j: y dimension
+ * k: z dimension
+ * descp: takes a number and tries to find a factoring of x*y*z mesh out of it
+ ****************************************************************************/
+#ifndef THREED
+#define THREED
+static int is_3dmesh(int num, int *i, int *j, int *k)
+{
+  int x, max = num / 3;
+  x = cbrt(num);
+  *i = *j = *k = 0;
+  while (x <= max) {
+    if ((num % (x * x)) == 0) {
+      *i = *j = x;
+      *k = num / (x * x);
+      return 1;
+    }
+    x++;
+  }
+  return 0;
+}
+#endif
+/*****************************************************************************
+ * Function: allgather_3dmesh_shoot
+ * return: int
+ * send_buff: send input buffer
+ * send_count: number of elements to send
+ * send_type: data type of elements being sent
+ * recv_buff: receive output buffer
+ * recv_count: number of elements to received
+ * recv_type: data type of elements being received
+ * comm: communication
+ * Descrp: Function realizes the allgather operation using the 2dmesh
+ * algorithm. Allgather ommunication occurs first in the x dimension, y
+ * dimension, and then in the z dimension. Communication in each dimension
+ * follows "simple"
+ * Auther: Ahmad Faraj
+****************************************************************************/
+int smpi_coll_tuned_allgather_3dmesh(void *send_buff, int send_count,
+                                     MPI_Datatype send_type, void *recv_buff,
+                                     int recv_count, MPI_Datatype recv_type,
+                                     MPI_Comm comm)
+{
+  MPI_Request *req, *req_ptr;
+  MPI_Aint extent;
+
+  int i, src, dst, rank, num_procs, block_size, my_z_base;
+  int my_z, X, Y, Z, send_offset, recv_offset;
+  int two_dsize, my_row_base, my_col_base, src_row_base, src_z_base, num_reqs;
+  int tag = 1;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
+
+  is_3dmesh(num_procs, &X, &Y, &Z);
+
+  num_reqs = X;
+
+  if (Y > X)
+    num_reqs = Y;
+  if (Z > Y)
+    num_reqs = Z;
+
+  two_dsize = X * Y;
+  my_z = rank / two_dsize;
+
+  my_row_base = (rank / X) * X;
+  my_col_base = (rank % Y) + (my_z * two_dsize);
+  my_z_base = my_z * two_dsize;
+
+  block_size = extent * send_count;
+
+  req = (MPI_Request *) xbt_malloc(num_reqs * sizeof(MPI_Request));
+
+  req_ptr = req;
+
+  // do local allgather/local copy 
+  recv_offset = rank * block_size;
+  smpi_datatype_copy(send_buff, send_count, send_type, (char *)recv_buff + recv_offset,
+                 recv_count, recv_type);
+
+  // do rowwise comm 
+  for (i = 0; i < Y; i++) {
+    src = i + my_row_base;
+    if (src == rank)
+      continue;
+    recv_offset = src * block_size;
+    *(req_ptr++) = smpi_mpi_irecv((char *)recv_buff + recv_offset, send_count, recv_type, src, tag,
+               comm);
+  }
+
+  for (i = 0; i < Y; i++) {
+    dst = i + my_row_base;
+    if (dst == rank)
+      continue;
+    smpi_mpi_send(send_buff, send_count, send_type, dst, tag, comm);
+  }
+
+  smpi_mpi_waitall(Y - 1, req, MPI_STATUSES_IGNORE);
+  req_ptr = req;
+
+  // do colwise comm, it does not matter here if i*X or i *Y since X == Y
+
+  for (i = 0; i < X; i++) {
+    src = (i * Y + my_col_base);
+    if (src == rank)
+      continue;
+
+    src_row_base = (src / X) * X;
+    recv_offset = src_row_base * block_size;
+    *(req_ptr++) = smpi_mpi_irecv((char *)recv_buff + recv_offset, recv_count * Y, recv_type, src, tag,
+               comm);
+  }
+
+  send_offset = my_row_base * block_size;
+
+  for (i = 0; i < X; i++) {
+    dst = (i * Y + my_col_base);
+    if (dst == rank)
+      continue;
+    smpi_mpi_send((char *)recv_buff + send_offset, send_count * Y, send_type, dst, tag,
+              comm);
+  }
+
+  smpi_mpi_waitall(X - 1, req, MPI_STATUSES_IGNORE);
+  req_ptr = req;
+
+  for (i = 1; i < Z; i++) {
+    src = (rank + i * two_dsize) % num_procs;
+    src_z_base = (src / two_dsize) * two_dsize;
+
+    recv_offset = (src_z_base * block_size);
+
+    *(req_ptr++) = smpi_mpi_irecv((char *)recv_buff + recv_offset, recv_count * two_dsize, recv_type,
+               src, tag, comm);
+  }
+
+  for (i = 1; i < Z; i++) {
+    dst = (rank + i * two_dsize) % num_procs;
+    send_offset = my_z_base * block_size;
+    smpi_mpi_send((char *)recv_buff + send_offset, send_count * two_dsize, send_type,
+              dst, tag, comm);
+  }
+  smpi_mpi_waitall(Z - 1, req, MPI_STATUSES_IGNORE);
+
+  free(req);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-GB.c b/src/smpi/colls/allgather-GB.c
new file mode 100644 (file)
index 0000000..f9a1e07
--- /dev/null
@@ -0,0 +1,16 @@
+#include "colls_private.h"
+
+// Allgather - gather/bcast algorithm
+int smpi_coll_tuned_allgather_GB(void *send_buff, int send_count,
+                                 MPI_Datatype send_type, void *recv_buff,
+                                 int recv_count, MPI_Datatype recv_type,
+                                 MPI_Comm comm)
+{
+  int num_procs;
+  num_procs = smpi_comm_size(comm);
+  smpi_mpi_gather(send_buff, send_count, send_type, recv_buff, recv_count, recv_type,
+             0, comm);
+  mpi_coll_bcast_fun(recv_buff, (recv_count * num_procs), recv_type, 0, comm);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-NTSLR-NB.c b/src/smpi/colls/allgather-NTSLR-NB.c
new file mode 100644 (file)
index 0000000..d0c6ef0
--- /dev/null
@@ -0,0 +1,63 @@
+#include "colls_private.h"
+
+// Allgather-Non-Topoloty-Scecific-Logical-Ring algorithm
+int
+smpi_coll_tuned_allgather_NTSLR_NB(void *sbuf, int scount, MPI_Datatype stype,
+                                   void *rbuf, int rcount, MPI_Datatype rtype,
+                                   MPI_Comm comm)
+{
+  MPI_Aint rextent, sextent;
+  MPI_Status status, status2;
+  int i, to, from, rank, size;
+  int send_offset, recv_offset;
+  int tag = 500;
+
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+  rextent = smpi_datatype_get_extent(rtype);
+  sextent = smpi_datatype_get_extent(stype);
+  MPI_Request *rrequest_array;
+  MPI_Request *srequest_array;
+  rrequest_array = (MPI_Request *) xbt_malloc(size * sizeof(MPI_Request));
+  srequest_array = (MPI_Request *) xbt_malloc(size * sizeof(MPI_Request));
+
+  // irregular case use default MPI fucntions
+  if (scount * sextent != rcount * rextent) {
+    XBT_WARN("MPI_allgather_NTSLR_NB use default MPI_allgather.");  
+    smpi_mpi_allgather(sbuf, scount, stype, rbuf, rcount, rtype, comm);
+    return MPI_SUCCESS;    
+  }
+
+  // topo non-specific
+  to = (rank + 1) % size;
+  from = (rank + size - 1) % size;
+
+  //copy a single segment from sbuf to rbuf
+  send_offset = rank * scount * sextent;
+
+  smpi_mpi_sendrecv(sbuf, scount, stype, rank, tag,
+               (char *)rbuf + send_offset, rcount, rtype, rank, tag, comm, &status);
+
+
+  //start sending logical ring message
+  int increment = scount * sextent;
+
+  //post all irecv first
+  for (i = 0; i < size - 1; i++) {
+    recv_offset = ((rank - i - 1 + size) % size) * increment;
+    rrequest_array[i] = smpi_mpi_irecv((char *)rbuf + recv_offset, rcount, rtype, from, tag + i, comm);
+  }
+
+
+  for (i = 0; i < size - 1; i++) {
+    send_offset = ((rank - i + size) % size) * increment;
+    srequest_array[i] = smpi_mpi_isend((char *)rbuf + send_offset, scount, stype, to, tag + i, comm);
+    smpi_mpi_wait(&rrequest_array[i], &status);
+    smpi_mpi_wait(&srequest_array[i], &status2);
+  }
+
+  free(rrequest_array);
+  free(srequest_array);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-NTSLR.c b/src/smpi/colls/allgather-NTSLR.c
new file mode 100644 (file)
index 0000000..bcaabfd
--- /dev/null
@@ -0,0 +1,50 @@
+#include "colls_private.h"
+
+// Allgather-Non-Topoloty-Scecific-Logical-Ring algorithm
+int
+smpi_coll_tuned_allgather_NTSLR(void *sbuf, int scount, MPI_Datatype stype,
+                                void *rbuf, int rcount, MPI_Datatype rtype,
+                                MPI_Comm comm)
+{
+  MPI_Aint rextent, sextent;
+  MPI_Status status;
+  int i, to, from, rank, size;
+  int send_offset, recv_offset;
+  int tag = 500;
+
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+  rextent = smpi_datatype_get_extent(rtype);
+  sextent = smpi_datatype_get_extent(stype);
+
+  // irregular case use default MPI fucntions
+  if (scount * sextent != rcount * rextent) {
+    XBT_WARN("MPI_allgather_NTSLR use default MPI_allgather.");  
+    smpi_mpi_allgather(sbuf, scount, stype, rbuf, rcount, rtype, comm);
+    return MPI_SUCCESS;    
+  }
+
+  // topo non-specific
+  to = (rank + 1) % size;
+  from = (rank + size - 1) % size;
+
+  //copy a single segment from sbuf to rbuf
+  send_offset = rank * scount * sextent;
+
+  smpi_mpi_sendrecv(sbuf, scount, stype, rank, tag,
+               (char *)rbuf + send_offset, rcount, rtype, rank, tag,
+               comm, &status);
+
+
+  //start sending logical ring message
+  int increment = scount * sextent;
+  for (i = 0; i < size - 1; i++) {
+    send_offset = ((rank - i + size) % size) * increment;
+    recv_offset = ((rank - i - 1 + size) % size) * increment;
+    smpi_mpi_sendrecv((char *) rbuf + send_offset, scount, stype, to, tag + i,
+                 (char *) rbuf + recv_offset, rcount, rtype, from, tag + i,
+                 comm, &status);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-SMP-NTS.c b/src/smpi/colls/allgather-SMP-NTS.c
new file mode 100644 (file)
index 0000000..a6b515a
--- /dev/null
@@ -0,0 +1,140 @@
+#include "colls_private.h"
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+int smpi_coll_tuned_allgather_SMP_NTS(void *sbuf, int scount,
+                                      MPI_Datatype stype, void *rbuf,
+                                      int rcount, MPI_Datatype rtype,
+                                      MPI_Comm comm)
+{
+  int src, dst, comm_size, rank;
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint rextent, sextent;
+  rextent = smpi_datatype_get_extent(rtype);
+  sextent = smpi_datatype_get_extent(stype);
+  int tag = 50;
+  MPI_Request request;
+  MPI_Request rrequest_array[128];
+
+  MPI_Status status;
+  int i, send_offset, recv_offset;
+  int intra_rank, inter_rank;
+  intra_rank = rank % NUM_CORE;
+  inter_rank = rank / NUM_CORE;
+  int inter_comm_size = (comm_size + NUM_CORE - 1) / NUM_CORE;
+  int num_core_in_current_smp = NUM_CORE;
+
+  /* for too small number of processes, use default implementation */
+  if (comm_size <= NUM_CORE) {
+    XBT_WARN("MPI_allgather_SMP_NTS use default MPI_allgather.");        
+    smpi_mpi_allgather(sbuf, scount, stype, rbuf, rcount, rtype, comm);
+    return MPI_SUCCESS;    
+  }
+
+  // the last SMP node may have fewer number of running processes than all others
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * NUM_CORE);
+  }
+  //copy corresponding message from sbuf to rbuf
+  recv_offset = rank * rextent * rcount;
+  smpi_mpi_sendrecv(sbuf, scount, stype, rank, tag,
+               ((char *) rbuf + recv_offset), rcount, rtype, rank, tag, comm,
+               &status);
+
+  //gather to root of each SMP
+
+  for (i = 1; i < num_core_in_current_smp; i++) {
+
+    dst =
+        (inter_rank * NUM_CORE) + (intra_rank + i) % (num_core_in_current_smp);
+    src =
+        (inter_rank * NUM_CORE) + (intra_rank - i +
+                                   num_core_in_current_smp) %
+        (num_core_in_current_smp);
+    recv_offset = src * rextent * rcount;
+
+    smpi_mpi_sendrecv(sbuf, scount, stype, dst, tag,
+                 ((char *) rbuf + recv_offset), rcount, rtype, src, tag, comm,
+                 &status);
+
+  }
+
+  // INTER-SMP-ALLGATHER 
+  // Every root of each SMP node post INTER-Sendrecv, then do INTRA-Bcast for each receiving message
+  // Use logical ring algorithm
+
+  // root of each SMP
+  if (intra_rank == 0) {
+    src = ((inter_rank - 1 + inter_comm_size) % inter_comm_size) * NUM_CORE;
+    dst = ((inter_rank + 1) % inter_comm_size) * NUM_CORE;
+
+    // post all inter Irecv
+    for (i = 0; i < inter_comm_size - 1; i++) {
+      recv_offset =
+          ((inter_rank - i - 1 +
+            inter_comm_size) % inter_comm_size) * NUM_CORE * sextent * scount;
+      rrequest_array[i] = smpi_mpi_irecv((char *)rbuf+recv_offset, rcount * NUM_CORE, rtype, src, tag+i, comm);
+    }
+
+    // send first message
+    send_offset =
+        ((inter_rank +
+          inter_comm_size) % inter_comm_size) * NUM_CORE * sextent * scount;
+    smpi_mpi_isend((char *) rbuf + send_offset, scount * NUM_CORE, stype,
+                   dst, tag, comm);
+
+    // loop : recv-inter , send-inter, send-intra (linear-bcast)
+    for (i = 0; i < inter_comm_size - 2; i++) {
+      recv_offset =
+          ((inter_rank - i - 1 +
+            inter_comm_size) % inter_comm_size) * NUM_CORE * sextent * scount;
+      smpi_mpi_wait(&rrequest_array[i], &status);
+      smpi_mpi_isend((char *) rbuf + recv_offset, scount * NUM_CORE, stype,
+                     dst, tag + i + 1, comm);
+      if (num_core_in_current_smp > 1) {
+        request = smpi_mpi_isend((char *) rbuf + recv_offset, scount * NUM_CORE, stype,
+                  (rank + 1), tag + i + 1, comm);
+      }
+    }
+
+    // recv last message and send_intra
+    recv_offset =
+        ((inter_rank - i - 1 +
+          inter_comm_size) % inter_comm_size) * NUM_CORE * sextent * scount;
+    //recv_offset = ((inter_rank + 1) % inter_comm_size) * NUM_CORE * sextent * scount;
+    //i=inter_comm_size-2;
+    smpi_mpi_wait(&rrequest_array[i], &status);
+    if (num_core_in_current_smp > 1) {
+      request = smpi_mpi_isend((char *) rbuf + recv_offset, scount * NUM_CORE, stype,
+                (rank + 1), tag + i + 1, comm);
+    }
+  }
+  // last rank of each SMP
+  else if (intra_rank == (num_core_in_current_smp - 1)) {
+    for (i = 0; i < inter_comm_size - 1; i++) {
+      recv_offset =
+          ((inter_rank - i - 1 +
+            inter_comm_size) % inter_comm_size) * NUM_CORE * sextent * scount;
+      request = smpi_mpi_irecv((char *) rbuf + recv_offset, (rcount * NUM_CORE), rtype,
+                rank - 1, tag + i + 1, comm);
+      smpi_mpi_wait(&request, &status);
+    }
+  }
+  // intermediate rank of each SMP
+  else {
+    for (i = 0; i < inter_comm_size - 1; i++) {
+      recv_offset =
+          ((inter_rank - i - 1 +
+            inter_comm_size) % inter_comm_size) * NUM_CORE * sextent * scount;
+      request = smpi_mpi_irecv((char *) rbuf + recv_offset, (rcount * NUM_CORE), rtype,
+                rank - 1, tag + i + 1, comm);
+      smpi_mpi_wait(&request, &status);
+      request = smpi_mpi_isend((char *) rbuf + recv_offset, (scount * NUM_CORE), stype,
+                (rank + 1), tag + i + 1, comm);
+    }
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-bruck.c b/src/smpi/colls/allgather-bruck.c
new file mode 100644 (file)
index 0000000..681690a
--- /dev/null
@@ -0,0 +1,129 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+
+/*****************************************************************************
+ * Function: allgather_bruck
+ * return: int
+ * inputs:
+ *   send_buff: send input buffer
+ *   send_count: number of elements to send
+ *   send_type: data type of elements being sent
+ *   recv_buff: receive output buffer
+ *   recv_count: number of elements to received
+ *   recv_type: data type of elements being received
+ *   comm: communication
+ * Descrp: Function realizes the allgather operation using the bruck
+ *         algorithm.
+ * Auther: MPICH
+ * Comment: Original bruck algorithm from MPICH is slightly modified by
+ *          Ahmad Faraj.  
+ ****************************************************************************/
+int smpi_coll_tuned_allgather_bruck(void *send_buff, int send_count,
+                                    MPI_Datatype send_type, void *recv_buff,
+                                    int recv_count, MPI_Datatype recv_type,
+                                    MPI_Comm comm)
+{
+  // MPI variables
+  MPI_Status status;
+  MPI_Aint recv_extent;
+
+  // local int variables
+  int src, dst, rank, num_procs, count, remainder;
+  int tag = 1;
+  int pof2 = 1;
+
+  // local string variables
+  char *tmp_buff;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  // get size of the communicator, followed by rank 
+  num_procs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  // get size of single element's type for recv buffer
+  recv_extent = smpi_datatype_get_extent(recv_type);
+
+  count = recv_count;
+
+  tmp_buff = (char *) xbt_malloc(num_procs * recv_count * recv_extent);
+
+  // perform a local copy
+  smpi_datatype_copy(send_ptr, send_count, send_type,
+                    tmp_buff, recv_count, recv_type);
+  while (pof2 <= (num_procs / 2)) {
+    src = (rank + pof2) % num_procs;
+    dst = (rank - pof2 + num_procs) % num_procs;
+
+    smpi_mpi_sendrecv(tmp_buff, count, recv_type, dst, tag,
+                  tmp_buff + count * recv_extent, count, recv_type,
+                  src, tag, comm, &status);
+    count *= 2;
+    pof2 *= 2;
+  }
+
+  remainder = num_procs - pof2;
+  if (remainder) {
+    src = (rank + pof2) % num_procs;
+    dst = (rank - pof2 + num_procs) % num_procs;
+
+    smpi_mpi_sendrecv(tmp_buff, remainder * recv_count, recv_type, dst, tag,
+                  tmp_buff + count * recv_extent, remainder * recv_count,
+                  recv_type, src, tag, comm, &status);
+  }
+
+  smpi_mpi_sendrecv(tmp_buff, (num_procs - rank) * recv_count, recv_type, rank,
+                tag, recv_ptr + rank * recv_count * recv_extent,
+                (num_procs - rank) * recv_count, recv_type, rank, tag, comm,
+                &status);
+
+  if (rank)
+    smpi_mpi_sendrecv(tmp_buff + (num_procs - rank) * recv_count * recv_extent,
+                  rank * recv_count, recv_type, rank, tag, recv_ptr,
+                  rank * recv_count, recv_type, rank, tag, comm, &status);
+  free(tmp_buff);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-loosely-lr.c b/src/smpi/colls/allgather-loosely-lr.c
new file mode 100644 (file)
index 0000000..6455db1
--- /dev/null
@@ -0,0 +1,119 @@
+#include "colls_private.h"
+
+#ifndef NUM_CORE
+#define NUM_CORE 4
+#endif
+
+int smpi_coll_tuned_allgather_loosely_lr(void *sbuf, int scount,
+                                         MPI_Datatype stype, void *rbuf,
+                                         int rcount, MPI_Datatype rtype,
+                                         MPI_Comm comm)
+{
+  int comm_size, rank;
+  int tag = 50;
+  int i, j, send_offset, recv_offset;
+  int intra_rank, inter_rank, inter_comm_size, intra_comm_size;
+  int inter_dst, inter_src;
+
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint rextent, sextent;
+  rextent = smpi_datatype_get_extent(rtype);
+  sextent = smpi_datatype_get_extent(stype);
+  MPI_Request inter_rrequest;
+  MPI_Request rrequest_array[128];
+  MPI_Request srequest_array[128];
+  MPI_Request inter_srequest_array[128];
+
+
+  int rrequest_count = 0;
+  int srequest_count = 0;
+  int inter_srequest_count = 0;
+
+  MPI_Status status;
+
+  intra_rank = rank % NUM_CORE;
+  inter_rank = rank / NUM_CORE;
+  inter_comm_size = (comm_size + NUM_CORE - 1) / NUM_CORE;
+  intra_comm_size = NUM_CORE;
+
+  int src_seg, dst_seg;
+
+  //copy corresponding message from sbuf to rbuf
+  recv_offset = rank * rextent * rcount;
+  smpi_mpi_sendrecv(sbuf, scount, stype, rank, tag,
+               (char *)rbuf + recv_offset, rcount, rtype, rank, tag, comm, &status);
+
+  int dst, src;
+  int inter_send_offset, inter_recv_offset;
+
+  rrequest_count = 0;
+  srequest_count = 0;
+  inter_srequest_count = 0;
+
+  for (i = 0; i < inter_comm_size; i++) {
+
+    // inter_communication
+
+    inter_dst = (rank + intra_comm_size) % comm_size;
+    inter_src = (rank - intra_comm_size + comm_size) % comm_size;
+
+    src_seg =
+        ((inter_rank - 1 - i +
+          inter_comm_size) % inter_comm_size) * intra_comm_size + intra_rank;
+    dst_seg =
+        ((inter_rank - i +
+          inter_comm_size) % inter_comm_size) * intra_comm_size + intra_rank;
+
+    inter_send_offset = dst_seg * sextent * scount;
+    inter_recv_offset = src_seg * rextent * rcount;
+
+    for (j = 0; j < intra_comm_size; j++) {
+
+      // inter communication
+      if (intra_rank == j) {
+        if (i != inter_comm_size - 1) {
+
+          inter_rrequest = smpi_mpi_irecv((char *)rbuf + inter_recv_offset, rcount, rtype,
+                                         inter_src, tag, comm);
+          inter_srequest_array[inter_srequest_count++] = smpi_mpi_isend((char *)rbuf + inter_send_offset, scount, stype,
+                                                                       inter_dst, tag, comm);
+        }
+      }
+      //intra_communication
+      src = inter_rank * intra_comm_size + j;
+      dst = inter_rank * intra_comm_size + j;
+
+      src_seg =
+          ((inter_rank - i +
+            inter_comm_size) % inter_comm_size) * intra_comm_size + j;
+      dst_seg =
+          ((inter_rank - i +
+            inter_comm_size) % inter_comm_size) * intra_comm_size + intra_rank;
+
+      send_offset = dst_seg * sextent * scount;
+      recv_offset = src_seg * rextent * rcount;
+
+
+      if (j != intra_rank) {
+
+        rrequest_array[rrequest_count++] = smpi_mpi_irecv((char *)rbuf + recv_offset, rcount, rtype, src, tag, comm);
+        srequest_array[srequest_count++] = smpi_mpi_isend((char *)rbuf + send_offset, scount, stype, dst, tag, comm);
+
+      }
+    }                           // intra loop
+
+
+    // wait for inter communication to finish for these rounds (# of round equals NUM_CORE)
+    if (i != inter_comm_size - 1) {
+      smpi_mpi_wait(&inter_rrequest, &status);
+    }
+
+  }                             //inter loop
+
+  smpi_mpi_waitall(rrequest_count, rrequest_array, MPI_STATUSES_IGNORE);
+  smpi_mpi_waitall(srequest_count, srequest_array, MPI_STATUSES_IGNORE);
+  smpi_mpi_waitall(inter_srequest_count, inter_srequest_array, MPI_STATUSES_IGNORE);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-lr.c b/src/smpi/colls/allgather-lr.c
new file mode 100644 (file)
index 0000000..7656069
--- /dev/null
@@ -0,0 +1,48 @@
+#include "colls_private.h"
+
+// Allgather-Non-Topoloty-Scecific-Logical-Ring algorithm
+int
+smpi_coll_tuned_allgather_lr(void *sbuf, int scount, MPI_Datatype stype,
+                             void *rbuf, int rcount, MPI_Datatype rtype,
+                             MPI_Comm comm)
+{
+  MPI_Aint rextent, sextent;
+  MPI_Status status;
+  int i, to, from, rank, size;
+  int send_offset, recv_offset;
+  int tag = 500;
+
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+  rextent = smpi_datatype_get_extent(rtype);
+  sextent = smpi_datatype_get_extent(stype);
+
+  // irregular case use default MPI fucntions
+  if (scount * sextent != rcount * rextent) {
+    XBT_WARN("MPI_allgather_lr use default MPI_allgather.");     
+    smpi_mpi_allgather(sbuf, scount, stype, rbuf, rcount, rtype, comm);
+    return MPI_SUCCESS;
+  }
+
+  // topo non-specific
+  to = (rank + 1) % size;
+  from = (rank + size - 1) % size;
+
+  //copy a single segment from sbuf to rbuf
+  send_offset = rank * scount * sextent;
+  smpi_mpi_sendrecv(sbuf, scount, stype, rank, tag,
+               (char *) rbuf + send_offset, rcount, rtype, rank, tag,
+               comm, &status);
+
+  //start sending logical ring message
+  int increment = scount * sextent;
+  for (i = 0; i < size - 1; i++) {
+    send_offset = ((rank - i + size) % size) * increment;
+    recv_offset = ((rank - i - 1 + size) % size) * increment;
+    smpi_mpi_sendrecv((char *) rbuf + send_offset, scount, stype, to, tag + i,
+                 (char *) rbuf + recv_offset, rcount, rtype, from, tag + i,
+                 comm, &status);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-pair.c b/src/smpi/colls/allgather-pair.c
new file mode 100644 (file)
index 0000000..0dc4aec
--- /dev/null
@@ -0,0 +1,93 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+ * Function: allgather_pair
+ * return: int
+ *  inputs:
+ *   send_buff: send input buffer
+ *   send_count: number of elements to send
+ *   send_type: data type of elements being sent
+ *   recv_buff: receive output buffer
+ *   recv_count: number of elements to received
+ *   recv_type: data type of elements being received
+ *   comm: communication
+ * Descrp: Function works when P is power of two. In each phase of P - 1
+ *         phases, nodes in pair communicate their data.
+ * Auther: Ahmad Faraj
+ ****************************************************************************/
+int
+smpi_coll_tuned_allgather_pair(void *send_buff, int send_count,
+                               MPI_Datatype send_type, void *recv_buff,
+                               int recv_count, MPI_Datatype recv_type,
+                               MPI_Comm comm)
+{
+
+  MPI_Aint extent;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+  MPI_Status status;
+
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
+
+  // local send/recv
+  smpi_mpi_sendrecv(send_ptr, send_count, send_type, rank, tag,
+               recv_ptr + rank * recv_count * extent,
+               recv_count, recv_type, rank, tag, comm, &status);
+
+  for (i = 1; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_sendrecv(send_ptr, send_count, send_type, dst, tag,
+                 recv_ptr + src * recv_count * extent, recv_count, recv_type,
+                 src, tag, comm, &status);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-rdb.c b/src/smpi/colls/allgather-rdb.c
new file mode 100644 (file)
index 0000000..520819a
--- /dev/null
@@ -0,0 +1,123 @@
+#include "colls_private.h"
+
+int
+smpi_coll_tuned_allgather_rdb(void *sbuf, int send_count,
+                              MPI_Datatype send_type, void *rbuf,
+                              int recv_count, MPI_Datatype recv_type,
+                              MPI_Comm comm)
+{
+  // MPI variables
+  MPI_Status status;
+  MPI_Aint send_chunk, recv_chunk;
+
+  // local int variables
+  int i, j, k, dst, rank, num_procs, send_offset, recv_offset, tree_root;
+  int dst_tree_root, rank_tree_root, last_recv_count = 0, num_procs_completed;
+  int offset, tmp_mask;
+  int tag = 1;
+  int mask = 1;
+  int success = 0;
+  int curr_count = recv_count;
+
+  // local string variables
+  char *send_ptr = (char *) sbuf;
+  char *recv_ptr = (char *) rbuf;
+
+  // get size of the communicator, followed by rank 
+  num_procs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  // get size of single element's type for send buffer and recv buffer
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  // multiply size of each element by number of elements to send or recv
+  send_chunk *= send_count;
+  recv_chunk *= recv_count;
+
+  // perform a local copy
+  smpi_mpi_sendrecv(send_ptr, send_count, send_type, rank, tag,
+               recv_ptr + rank * recv_chunk, recv_count, recv_type, rank, tag,
+               comm, &status);
+
+  i = 0;
+  while (mask < num_procs) {
+    dst = rank ^ mask;
+    dst_tree_root = dst >> i;
+    dst_tree_root <<= i;
+    rank_tree_root = rank >> i;
+    rank_tree_root <<= i;
+    send_offset = rank_tree_root * send_chunk;
+    recv_offset = dst_tree_root * recv_chunk;
+
+    if (dst < num_procs) {
+      smpi_mpi_sendrecv(recv_ptr + send_offset, curr_count, send_type, dst,
+                   tag, recv_ptr + recv_offset, mask * recv_count,
+                   recv_type, dst, tag, comm, &status);
+      last_recv_count = smpi_mpi_get_count(&status, recv_type);
+      curr_count += last_recv_count;
+    }
+
+    if (dst_tree_root + mask > num_procs) {
+      num_procs_completed = num_procs - rank_tree_root - mask;
+      /* num_procs_completed is the number of processes in this
+         subtree that have all the data. Send data to others
+         in a tree fashion. First find root of current tree
+         that is being divided into two. k is the number of
+         least-significant bits in this process's rank that
+         must be zeroed out to find the rank of the root */
+
+      j = mask;
+      k = 0;
+      while (j) {
+        j >>= 1;
+        k++;
+      }
+      k--;
+
+      offset = recv_chunk * (rank_tree_root + mask);
+      tmp_mask = mask >> 1;
+
+      while (tmp_mask) {
+        dst = rank ^ tmp_mask;
+
+        tree_root = rank >> k;
+        tree_root <<= k;
+
+        /* send only if this proc has data and destination
+           doesn't have data. at any step, multiple processes
+           can send if they have the data */
+        if ((dst > rank)
+            && (rank < tree_root + num_procs_completed)
+            && (dst >= tree_root + num_procs_completed)) {
+          smpi_mpi_send(recv_ptr + offset, last_recv_count, recv_type, dst,
+                   tag, comm);
+
+          /* last_recv_cnt was set in the previous
+             receive. that's the amount of data to be
+             sent now. */
+        }
+        /* recv only if this proc. doesn't have data and sender
+           has data */
+        else if ((dst < rank)
+                 && (dst < tree_root + num_procs_completed)
+                 && (rank >= tree_root + num_procs_completed)) {
+          smpi_mpi_recv(recv_ptr + offset,
+                   recv_count * num_procs_completed,
+                   recv_type, dst, tag, comm, &status);
+          // num_procs_completed is also equal to the no. of processes
+          // whose data we don't have
+          last_recv_count = smpi_mpi_get_count(&status, recv_type);
+          curr_count += last_recv_count;
+        }
+        tmp_mask >>= 1;
+        k--;
+      }
+    }
+
+    mask <<= 1;
+    i++;
+  }
+
+  return success;
+}
diff --git a/src/smpi/colls/allgather-rhv.c b/src/smpi/colls/allgather-rhv.c
new file mode 100644 (file)
index 0000000..c3db821
--- /dev/null
@@ -0,0 +1,96 @@
+#include "colls_private.h"
+
+// now only work with power of two processes
+
+int
+smpi_coll_tuned_allgather_rhv(void *sbuf, int send_count,
+                              MPI_Datatype send_type, void *rbuf,
+                              int recv_count, MPI_Datatype recv_type,
+                              MPI_Comm comm)
+{
+  MPI_Status status;
+  MPI_Aint s_extent, r_extent;
+
+  // local int variables
+  int i, dst, send_base_offset, recv_base_offset, send_chunk, recv_chunk,
+      send_offset, recv_offset;
+  int rank, num_procs;
+  int tag = 50;
+  int mask;
+  int curr_count;
+
+  // get size of the communicator, followed by rank 
+  num_procs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  // get size of single element's type for send buffer and recv buffer
+  s_extent = smpi_datatype_get_extent(send_type);
+  r_extent = smpi_datatype_get_extent(recv_type);
+
+  // multiply size of each element by number of elements to send or recv
+  send_chunk = s_extent * send_count;
+  recv_chunk = r_extent * recv_count;
+
+  if (send_chunk != recv_chunk) {
+    XBT_WARN("MPI_allgather_rhv use default MPI_allgather.");  
+    smpi_mpi_allgather(sbuf, send_count, send_type, rbuf, recv_count,
+                              recv_type, comm);
+    return MPI_SUCCESS;        
+  }
+
+  // compute starting offset location to perform local copy
+  int size = num_procs / 2;
+  int base_offset = 0;
+  mask = 1;
+  while (mask < num_procs) {
+    if (rank & mask) {
+      base_offset += size;
+    }
+    mask <<= 1;
+    size /= 2;
+  }
+
+  //  printf("node %d base_offset %d\n",rank,base_offset);
+
+  //perform a remote copy
+
+  dst = base_offset;
+  smpi_mpi_sendrecv(sbuf, send_count, send_type, dst, tag,
+               (char *)rbuf + base_offset * recv_chunk, recv_count, recv_type, dst, tag,
+               comm, &status);
+
+
+  mask >>= 1;
+  i = 1;
+  int phase = 0;
+  curr_count = recv_count;
+  while (mask >= 1) {
+    // destination pair for both send and recv
+    dst = rank ^ mask;
+
+    // compute offsets
+    send_base_offset = base_offset;
+    if (rank & mask) {
+      recv_base_offset = base_offset - i;
+      base_offset -= i;
+    } else {
+      recv_base_offset = base_offset + i;
+    }
+    send_offset = send_base_offset * recv_chunk;
+    recv_offset = recv_base_offset * recv_chunk;
+
+    //  printf("node %d send to %d in phase %d s_offset = %d r_offset = %d count = %d\n",rank,dst,phase, send_base_offset, recv_base_offset, curr_count);
+
+    smpi_mpi_sendrecv((char *)rbuf + send_offset, curr_count, recv_type, dst, tag,
+                (char *)rbuf + recv_offset, curr_count, recv_type, dst, tag,
+                 comm, &status);
+
+
+    curr_count *= 2;
+    i *= 2;
+    mask >>= 1;
+    phase++;
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-ring.c b/src/smpi/colls/allgather-ring.c
new file mode 100644 (file)
index 0000000..6108ae5
--- /dev/null
@@ -0,0 +1,93 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+ * Function: allgather_ring
+ * return: int
+ * inputs:
+ *   send_buff: send input buffer
+ *   send_count: number of elements to send
+ *   send_type: data type of elements being sent
+ *   recv_buff: receive output buffer
+ *   recv_count: number of elements to received
+ *   recv_type: data type of elements being received
+ *   comm: communication
+ * Descrp: Function works in P - 1 steps. In step i, node j - i -> j -> j+ i.
+ * Auther: Ahmad Faraj
+ ****************************************************************************/
+int
+smpi_coll_tuned_allgather_ring(void *send_buff, int send_count,
+                               MPI_Datatype send_type, void *recv_buff,
+                               int recv_count, MPI_Datatype recv_type,
+                               MPI_Comm comm)
+{
+
+  MPI_Aint extent;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+  MPI_Status status;
+
+  char *sendptr = (char *) send_buff;
+  char *recvptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
+
+  // local send/recv
+  smpi_mpi_sendrecv(sendptr, send_count, send_type, rank, tag,
+               recvptr + rank * recv_count * extent,
+               recv_count, recv_type, rank, tag, comm, &status);
+
+  for (i = 1; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+    smpi_mpi_sendrecv(sendptr, send_count, send_type, dst, tag,
+                 recvptr + src * recv_count * extent, recv_count, recv_type,
+                 src, tag, comm, &status);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-smp-simple.c b/src/smpi/colls/allgather-smp-simple.c
new file mode 100644 (file)
index 0000000..21cab26
--- /dev/null
@@ -0,0 +1,109 @@
+#include "colls_private.h"
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+int smpi_coll_tuned_allgather_smp_simple(void *send_buf, int scount,
+                                         MPI_Datatype stype, void *recv_buf,
+                                         int rcount, MPI_Datatype rtype,
+                                         MPI_Comm comm)
+{
+  int src, dst, comm_size, rank;
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint rextent, sextent;
+  rextent = smpi_datatype_get_extent(rtype);
+  sextent = smpi_datatype_get_extent(stype);
+  int tag = 50;
+  MPI_Status status;
+  int i, send_offset, recv_offset;
+  int intra_rank, inter_rank;
+  int num_core = NUM_CORE;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+  int num_core_in_current_smp = num_core;
+
+  // the last SMP node may have fewer number of running processes than all others
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * num_core);
+  }
+  //INTRA-SMP-ALLGATHER
+  recv_offset = rank * rextent * rcount;
+  smpi_mpi_sendrecv(send_buf, scount, stype, rank, tag,
+               ((char *) recv_buf + recv_offset), rcount, rtype, rank, tag,
+               comm, &status);
+  for (i = 1; i < num_core_in_current_smp; i++) {
+
+    dst =
+        (inter_rank * num_core) + (intra_rank + i) % (num_core_in_current_smp);
+    src =
+        (inter_rank * num_core) + (intra_rank - i +
+                                   num_core_in_current_smp) %
+        (num_core_in_current_smp);
+    recv_offset = src * rextent * rcount;
+
+    smpi_mpi_sendrecv(send_buf, scount, stype, dst, tag,
+                 ((char *) recv_buf + recv_offset), rcount, rtype, src, tag,
+                 comm, &status);
+
+  }
+
+  // INTER-SMP-ALLGATHER 
+  // Every root of each SMP node post INTER-Sendrecv, then do INTRA-Bcast for each receiving message
+
+
+
+  if (intra_rank == 0) {
+    MPI_Request *reqs, *req_ptr;
+    int num_req = (inter_comm_size - 1) * 2;
+    reqs = (MPI_Request *) xbt_malloc(num_req * sizeof(MPI_Request));
+    req_ptr = reqs;
+    MPI_Status *stat;
+    stat = (MPI_Status *) xbt_malloc(num_req * sizeof(MPI_Status));
+
+    for (i = 1; i < inter_comm_size; i++) {
+
+      //dst = ((inter_rank+i)%inter_comm_size) * num_core;
+      src = ((inter_rank - i + inter_comm_size) % inter_comm_size) * num_core;
+      //send_offset = (rank * sextent * scount);
+      recv_offset = (src * sextent * scount);
+      //      smpi_mpi_sendrecv((recv_buf+send_offset), (scount * num_core), stype, dst, tag, 
+      //             (recv_buf+recv_offset), (rcount * num_core), rtype, src, tag, comm, &status);
+      //MPIC_Isend((recv_buf+send_offset), (scount * num_core), stype, dst, tag, comm, req_ptr++);
+      *(req_ptr++) = smpi_mpi_irecv(((char *) recv_buf + recv_offset), (rcount * num_core), rtype,
+                src, tag, comm);
+    }
+    for (i = 1; i < inter_comm_size; i++) {
+
+      dst = ((inter_rank + i) % inter_comm_size) * num_core;
+      //src = ((inter_rank-i+inter_comm_size)%inter_comm_size) * num_core;
+      send_offset = (rank * sextent * scount);
+      //recv_offset = (src * sextent * scount);
+      //      smpi_mpi_sendrecv((recv_buf+send_offset), (scount * num_core), stype, dst, tag, 
+      //             (recv_buf+recv_offset), (rcount * num_core), rtype, src, tag, comm, &status);
+      *(req_ptr++) = smpi_mpi_isend(((char *) recv_buf + send_offset), (scount * num_core), stype,
+                dst, tag, comm);
+      //MPIC_Irecv((recv_buf+recv_offset), (rcount * num_core), rtype, src, tag, comm, req_ptr++);
+    }
+    smpi_mpi_waitall(num_req, reqs, stat);
+    free(reqs);
+    free(stat);
+
+  }
+  //INTRA-BCAST (use flat tree)
+
+  if (intra_rank == 0) {
+    for (i = 1; i < num_core_in_current_smp; i++) {
+      //printf("rank = %d, num = %d send to %d\n",rank, num_core_in_current_smp, (rank + i));
+      smpi_mpi_send(recv_buf, (scount * comm_size), stype, (rank + i), tag, comm);
+    }
+  } else {
+    //printf("rank = %d recv from %d\n",rank, (inter_rank * num_core));
+    smpi_mpi_recv(recv_buf, (rcount * comm_size), rtype, (inter_rank * num_core),
+             tag, comm, &status);
+  }
+
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgather-spreading-simple.c b/src/smpi/colls/allgather-spreading-simple.c
new file mode 100644 (file)
index 0000000..822ab53
--- /dev/null
@@ -0,0 +1,113 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+ * Function: allgather_spreading_simple
+ * return: int
+ *  inputs:
+ *   send_buff: send input buffer
+ *   send_count: number of elements to send
+ *   send_type: data type of elements being sent
+ *   recv_buff: receive output buffer
+ *   recv_count: number of elements to received
+ *   recv_type: data type of elements being received
+ *   comm: communication
+ * Descrp: Let i -> j denote the communication from node i to node j. The
+ *         order of communications for node i is i -> i + 1, i -> i + 2, ...,
+ *         i -> (i + p -1) % P.
+ *
+ * Auther: Ahmad Faraj
+ ****************************************************************************/
+int
+smpi_coll_tuned_allgather_spreading_simple(void *send_buff, int send_count,
+                                           MPI_Datatype send_type,
+                                           void *recv_buff, int recv_count,
+                                           MPI_Datatype recv_type,
+                                           MPI_Comm comm)
+{
+  MPI_Request *reqs, *req_ptr;
+  MPI_Aint extent;
+  int i, src, dst, rank, num_procs, num_reqs;
+  int tag = 1;
+  MPI_Status status;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
+
+  num_reqs = (2 * num_procs) - 2;
+  reqs = (MPI_Request *) xbt_malloc(num_reqs * sizeof(MPI_Request));
+  if (!reqs) {
+    printf("allgather-spreading-simple.c:40: cannot allocate memory\n");
+    MPI_Finalize();
+    exit(0);
+  }
+
+  req_ptr = reqs;
+  smpi_mpi_sendrecv(send_buff, send_count, send_type, rank, tag,
+               (char *) recv_buff + rank * recv_count * extent, recv_count,
+               recv_type, rank, tag, comm, &status);
+
+  for (i = 0; i < num_procs; i++) {
+    src = (rank + i) % num_procs;
+    if (src == rank)
+      continue;
+    *(req_ptr++) = smpi_mpi_irecv(recv_ptr + src * recv_count * extent, recv_count, recv_type,
+              src, tag, comm);
+  }
+
+  for (i = 0; i < num_procs; i++) {
+    dst = (rank + i) % num_procs;
+    if (dst == rank)
+      continue;
+    *(req_ptr++) = smpi_mpi_isend(send_buff, send_count, send_type, dst, tag, comm);
+  }
+
+  smpi_mpi_waitall(num_reqs, reqs, MPI_STATUSES_IGNORE);
+  free(reqs);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgatherv-GB.c b/src/smpi/colls/allgatherv-GB.c
new file mode 100644 (file)
index 0000000..5c643fa
--- /dev/null
@@ -0,0 +1,20 @@
+#include "colls_private.h"
+
+// Allgather - gather/bcast algorithm
+int smpi_coll_tuned_allgatherv_GB(void *send_buff, int send_count,
+                                 MPI_Datatype send_type, void *recv_buff,
+                                 int *recv_counts, int *recv_disps, MPI_Datatype recv_type,
+                                 MPI_Comm comm)
+{
+  smpi_mpi_gatherv(send_buff, send_count, send_type, recv_buff, recv_counts,
+                  recv_disps, recv_type, 0, comm);
+  int num_procs, i, current, max = 0;
+  num_procs = smpi_comm_size(comm);
+  for (i = 0; i < num_procs; i++) {
+    current = recv_disps[i] + recv_counts[i];
+    if (current > max) max = current;
+  }
+  mpi_coll_bcast_fun(recv_buff, current, recv_type, 0, comm);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgatherv-pair.c b/src/smpi/colls/allgatherv-pair.c
new file mode 100644 (file)
index 0000000..d60e77a
--- /dev/null
@@ -0,0 +1,92 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+ * Function: allgather_pair
+ * return: int
+ *  inputs:
+ *   send_buff: send input buffer
+ *   send_count: number of elements to send
+ *   send_type: data type of elements being sent
+ *   recv_buff: receive output buffer
+ *   recv_count: number of elements to received
+ *   recv_type: data type of elements being received
+ *   comm: communication
+ * Descrp: Function works when P is power of two. In each phase of P - 1
+ *         phases, nodes in pair communicate their data.
+ * Auther: Ahmad Faraj
+ ****************************************************************************/
+int
+smpi_coll_tuned_allgatherv_pair(void *send_buff, int send_count,
+                               MPI_Datatype send_type, void *recv_buff,
+                               int *recv_counts, int *recv_disps, MPI_Datatype recv_type,
+                               MPI_Comm comm)
+{
+
+  MPI_Aint extent;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+  MPI_Status status;
+
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
+
+  // local send/recv
+  smpi_mpi_sendrecv(send_ptr, send_count, send_type, rank, tag,
+               recv_ptr + recv_disps[rank] * extent,
+               recv_counts[rank], recv_type, rank, tag, comm, &status);
+  for (i = 1; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_sendrecv(send_ptr, send_count, send_type, dst, tag,
+                 recv_ptr + recv_disps[src] * extent, recv_counts[src], recv_type,
+                 src, tag, comm, &status);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allgatherv-ring.c b/src/smpi/colls/allgatherv-ring.c
new file mode 100644 (file)
index 0000000..4c1e14f
--- /dev/null
@@ -0,0 +1,94 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+ * Function: allgather_ring
+ * return: int
+ * inputs:
+ *   send_buff: send input buffer
+ *   send_count: number of elements to send
+ *   send_type: data type of elements being sent
+ *   recv_buff: receive output buffer
+ *   recv_count: number of elements to received
+ *   recv_type: data type of elements being received
+ *   comm: communication
+ * Descrp: Function works in P - 1 steps. In step i, node j - i -> j -> j+ i.
+ * Auther: Ahmad Faraj
+ ****************************************************************************/
+int
+smpi_coll_tuned_allgatherv_ring(void *send_buff, int send_count,
+                               MPI_Datatype send_type, void *recv_buff,
+                               int *recv_counts, int *recv_disps, MPI_Datatype recv_type,
+                               MPI_Comm comm)
+{
+
+  MPI_Aint extent;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+  MPI_Status status;
+
+  char *sendptr = (char *) send_buff;
+  char *recvptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
+
+  // local send/recv
+  smpi_mpi_sendrecv(sendptr, send_count, send_type, rank, tag,
+               recvptr + recv_disps[rank] * extent,
+               recv_counts[rank], recv_type, rank, tag, comm, &status);
+
+  for (i = 1; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+    
+    smpi_mpi_sendrecv(sendptr, send_count, send_type, dst, tag,
+                 recvptr + recv_disps[src] * extent, recv_counts[src], recv_type,
+                 src, tag, comm, &status);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-NTS.c b/src/smpi/colls/allreduce-NTS.c
new file mode 100644 (file)
index 0000000..a8cf48d
--- /dev/null
@@ -0,0 +1,95 @@
+#include "colls_private.h"
+/* IMPLEMENTED BY PITCH PATARASUK 
+   Non-topoloty-specific all-reduce operation designed bandwidth optimally */
+
+/* ** NOTE **
+   Use -DMPICH2_REDUCTION if this code does not compile.
+   MPICH1 code also work on MPICH2 on our cluster and the performance are similar.
+   This code assume commutative and associative reduce operator (MPI_SUM, MPI_MAX, etc).
+*/
+
+//#include <star-reduction.c>
+
+int
+smpi_coll_tuned_allreduce_NTS(void *sbuf, void *rbuf, int rcount,
+                              MPI_Datatype dtype, MPI_Op op, MPI_Comm comm)
+{
+  int tag = 5000;
+  MPI_Status status;
+  int rank, i, size, count;
+  int send_offset, recv_offset;
+  int remainder, remainder_flag, remainder_offset;
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* make it compatible with all data type */
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+
+  /* when communication size is smaller than number of process (not support) */
+  if (rcount < size) {
+    return mpi_coll_allreduce_fun(sbuf, rbuf, rcount, dtype, op, comm);
+  }
+
+  /* when communication size is not divisible by number of process: 
+     call the native implementation for the remain chunk at the end of the operation */
+  if (rcount % size != 0) {
+    remainder = rcount % size;
+    remainder_flag = 1;
+    remainder_offset = (rcount / size) * size * extent;
+  } else {
+    remainder = remainder_flag = remainder_offset = 0;
+  }
+
+  /* size of each point-to-point communication is equal to the size of the whole message
+     divided by number of processes
+   */
+  count = rcount / size;
+
+  /* our ALL-REDUCE implementation
+     1. copy (partial of)send_buf to recv_buf
+     2. use logical ring reduce-scatter
+     3. use logical ring all-gather 
+   */
+
+  // copy partial data
+  send_offset = ((rank - 1 + size) % size) * count * extent;
+  recv_offset = ((rank - 1 + size) % size) * count * extent;
+  smpi_mpi_sendrecv((char *) sbuf + send_offset, count, dtype, rank, tag - 1,
+               (char *) rbuf + recv_offset, count, dtype, rank, tag - 1, comm,
+               &status);
+
+  // reduce-scatter
+  for (i = 0; i < (size - 1); i++) {
+    send_offset = ((rank - 1 - i + size) % size) * count * extent;
+    recv_offset = ((rank - 2 - i + size) % size) * count * extent;
+    smpi_mpi_sendrecv((char *) rbuf + send_offset, count, dtype, ((rank + 1) % size),
+                 tag + i, (char *) rbuf + recv_offset, count, dtype,
+                 ((rank + size - 1) % size), tag + i, comm, &status);
+
+    // compute result to rbuf+recv_offset
+    smpi_op_apply(op, (char *)sbuf + recv_offset, (char *)rbuf + recv_offset, &count, &dtype);
+  }
+
+  // all-gather
+  for (i = 0; i < (size - 1); i++) {
+    send_offset = ((rank - i + size) % size) * count * extent;
+    recv_offset = ((rank - 1 - i + size) % size) * count * extent;
+    smpi_mpi_sendrecv((char *) rbuf + send_offset, count, dtype, ((rank + 1) % size),
+                 tag + i, (char *) rbuf + recv_offset, count, dtype,
+                 ((rank + size - 1) % size), tag + i, comm, &status);
+  }
+
+  /* when communication size is not divisible by number of process: 
+     call the native implementation for the remain chunk at the end of the operation */
+  if (remainder_flag) {
+    XBT_WARN("MPI_allreduce_NTS use default MPI_allreduce.");
+    smpi_mpi_allreduce((char *) sbuf + remainder_offset,
+                         (char *) rbuf + remainder_offset, remainder, dtype, op,
+                         comm);
+    return MPI_SUCCESS;    
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-lr.c b/src/smpi/colls/allreduce-lr.c
new file mode 100644 (file)
index 0000000..81cb392
--- /dev/null
@@ -0,0 +1,100 @@
+#include "colls_private.h"
+
+/* IMPLEMENTED BY PITCH PATARASUK 
+   Non-topoloty-specific all-reduce operation designed bandwidth optimally 
+   Bug fixing by Xin Yuan, 04/04/2008
+*/
+
+/* ** NOTE **
+   Use -DMPICH2_REDUCTION if this code does not compile.
+   MPICH1 code also work on MPICH2 on our cluster and the performance are similar.
+   This code assume commutative and associative reduce operator (MPI_SUM, MPI_MAX, etc).
+*/
+
+//#include <star-reduction.c>
+
+int
+smpi_coll_tuned_allreduce_lr(void *sbuf, void *rbuf, int rcount,
+                             MPI_Datatype dtype, MPI_Op op, MPI_Comm comm)
+{
+  int tag = 5000;
+  MPI_Status status;
+  int rank, i, size, count;
+  int send_offset, recv_offset;
+  int remainder, remainder_flag, remainder_offset;
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* make it compatible with all data type */
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+
+  /* when communication size is smaller than number of process (not support) */
+  if (rcount < size) {
+    XBT_WARN("MPI_allreduce_lr use default MPI_allreduce.");     
+    smpi_mpi_allreduce(sbuf, rbuf, rcount, dtype, op, comm);
+    return MPI_SUCCESS; 
+  }
+
+  /* when communication size is not divisible by number of process: 
+     call the native implementation for the remain chunk at the end of the operation */
+  if (rcount % size != 0) {
+    remainder = rcount % size;
+    remainder_flag = 1;
+    remainder_offset = (rcount / size) * size * extent;
+  } else {
+    remainder = remainder_flag = remainder_offset = 0;
+  }
+
+  /* size of each point-to-point communication is equal to the size of the whole message
+     divided by number of processes
+   */
+  count = rcount / size;
+
+  /* our ALL-REDUCE implementation
+     1. copy (partial of)send_buf to recv_buf
+     2. use logical ring reduce-scatter
+     3. use logical ring all-gather 
+   */
+
+  // copy partial data
+  send_offset = ((rank - 1 + size) % size) * count * extent;
+  recv_offset = ((rank - 1 + size) % size) * count * extent;
+  smpi_mpi_sendrecv((char *) sbuf + send_offset, count, dtype, rank, tag - 1,
+               (char *) rbuf + recv_offset, count, dtype, rank, tag - 1, comm,
+               &status);
+
+  // reduce-scatter
+  for (i = 0; i < (size - 1); i++) {
+    send_offset = ((rank - 1 - i + 2 * size) % size) * count * extent;
+    recv_offset = ((rank - 2 - i + 2 * size) % size) * count * extent;
+    //    recv_offset = ((rank-i+2*size)%size)*count*extent;
+    smpi_mpi_sendrecv((char *) rbuf + send_offset, count, dtype, ((rank + 1) % size),
+                 tag + i, (char *) rbuf + recv_offset, count, dtype,
+                 ((rank + size - 1) % size), tag + i, comm, &status);
+
+    // compute result to rbuf+recv_offset
+    smpi_op_apply(op, (char *) sbuf + recv_offset, (char *) rbuf + recv_offset,
+                   &count, &dtype);
+  }
+
+  // all-gather
+  for (i = 0; i < (size - 1); i++) {
+    send_offset = ((rank - i + 2 * size) % size) * count * extent;
+    recv_offset = ((rank - 1 - i + 2 * size) % size) * count * extent;
+    smpi_mpi_sendrecv((char *) rbuf + send_offset, count, dtype, ((rank + 1) % size),
+                 tag + i, (char *) rbuf + recv_offset, count, dtype,
+                 ((rank + size - 1) % size), tag + i, comm, &status);
+  }
+
+  /* when communication size is not divisible by number of process: 
+     call the native implementation for the remain chunk at the end of the operation */
+  if (remainder_flag) {
+    return mpi_coll_allreduce_fun((char *) sbuf + remainder_offset,
+                         (char *) rbuf + remainder_offset, remainder, dtype, op,
+                         comm);
+  }
+
+  return 0;
+}
diff --git a/src/smpi/colls/allreduce-rab-rdb.c b/src/smpi/colls/allreduce-rab-rdb.c
new file mode 100644 (file)
index 0000000..9d5ee9c
--- /dev/null
@@ -0,0 +1,189 @@
+#include "colls_private.h"
+
+int smpi_coll_tuned_allreduce_rab_rdb(void *sbuff, void *rbuff, int count,
+                                      MPI_Datatype dtype, MPI_Op op,
+                                      MPI_Comm comm)
+{
+  int nprocs, rank, tag = 543;
+  int mask, dst, pof2, newrank, rem, newdst, i,
+      send_idx, recv_idx, last_idx, send_cnt, recv_cnt, *cnts, *disps;
+  MPI_Aint extent;
+  MPI_Status status;
+  void *tmp_buf = NULL;
+
+  nprocs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  smpi_datatype_copy(sbuff, count, dtype, rbuff, count, dtype);
+
+  // find nearest power-of-two less than or equal to comm_size
+  pof2 = 1;
+  while (pof2 <= nprocs)
+    pof2 <<= 1;
+  pof2 >>= 1;
+
+  rem = nprocs - pof2;
+
+  // In the non-power-of-two case, all even-numbered
+  // processes of rank < 2*rem send their data to
+  // (rank+1). These even-numbered processes no longer
+  // participate in the algorithm until the very end. The
+  // remaining processes form a nice power-of-two. 
+
+  if (rank < 2 * rem) {
+    // even       
+    if (rank % 2 == 0) {
+
+      smpi_mpi_send(rbuff, count, dtype, rank + 1, tag, comm);
+
+      // temporarily set the rank to -1 so that this
+      // process does not pariticipate in recursive
+      // doubling
+      newrank = -1;
+    } else                      // odd
+    {
+      smpi_mpi_recv(tmp_buf, count, dtype, rank - 1, tag, comm, &status);
+      // do the reduction on received data. since the
+      // ordering is right, it doesn't matter whether
+      // the operation is commutative or not.
+       smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+
+      // change the rank 
+      newrank = rank / 2;
+    }
+  }
+
+  else                          // rank >= 2 * rem 
+    newrank = rank - rem;
+
+  // If op is user-defined or count is less than pof2, use
+  // recursive doubling algorithm. Otherwise do a reduce-scatter
+  // followed by allgather. (If op is user-defined,
+  // derived datatypes are allowed and the user could pass basic
+  // datatypes on one process and derived on another as long as
+  // the type maps are the same. Breaking up derived
+  // datatypes to do the reduce-scatter is tricky, therefore
+  // using recursive doubling in that case.) 
+
+  if (newrank != -1) {
+    // do a reduce-scatter followed by allgather. for the
+    // reduce-scatter, calculate the count that each process receives
+    // and the displacement within the buffer 
+
+    cnts = (int *) xbt_malloc(pof2 * sizeof(int));
+    disps = (int *) xbt_malloc(pof2 * sizeof(int));
+
+    for (i = 0; i < (pof2 - 1); i++)
+      cnts[i] = count / pof2;
+    cnts[pof2 - 1] = count - (count / pof2) * (pof2 - 1);
+
+    disps[0] = 0;
+    for (i = 1; i < pof2; i++)
+      disps[i] = disps[i - 1] + cnts[i - 1];
+
+    mask = 0x1;
+    send_idx = recv_idx = 0;
+    last_idx = pof2;
+    while (mask < pof2) {
+      newdst = newrank ^ mask;
+      // find real rank of dest 
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      send_cnt = recv_cnt = 0;
+      if (newrank < newdst) {
+        send_idx = recv_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < last_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < send_idx; i++)
+          recv_cnt += cnts[i];
+      } else {
+        recv_idx = send_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < recv_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < last_idx; i++)
+          recv_cnt += cnts[i];
+      }
+
+      // Send data from recvbuf. Recv into tmp_buf 
+      smpi_mpi_sendrecv((char *) rbuff + disps[send_idx] * extent, send_cnt,
+                   dtype, dst, tag,
+                   (char *) tmp_buf + disps[recv_idx] * extent, recv_cnt,
+                   dtype, dst, tag, comm, &status);
+
+      // tmp_buf contains data received in this step.
+      // recvbuf contains data accumulated so far 
+
+      // This algorithm is used only for predefined ops
+      // and predefined ops are always commutative.
+      smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+                        (char *) rbuff + disps[recv_idx] * extent, &recv_cnt, &dtype);
+
+      // update send_idx for next iteration 
+      send_idx = recv_idx;
+      mask <<= 1;
+
+      // update last_idx, but not in last iteration because the value
+      // is needed in the allgather step below. 
+      if (mask < pof2)
+        last_idx = recv_idx + pof2 / mask;
+    }
+
+    // now do the allgather 
+
+    mask >>= 1;
+    while (mask > 0) {
+      newdst = newrank ^ mask;
+      // find real rank of dest
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      send_cnt = recv_cnt = 0;
+      if (newrank < newdst) {
+        // update last_idx except on first iteration 
+        if (mask != pof2 / 2)
+          last_idx = last_idx + pof2 / (mask * 2);
+
+        recv_idx = send_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < recv_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < last_idx; i++)
+          recv_cnt += cnts[i];
+      } else {
+        recv_idx = send_idx - pof2 / (mask * 2);
+        for (i = send_idx; i < last_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < send_idx; i++)
+          recv_cnt += cnts[i];
+      }
+
+      smpi_mpi_sendrecv((char *) rbuff + disps[send_idx] * extent, send_cnt,
+                   dtype, dst, tag,
+                   (char *) rbuff + disps[recv_idx] * extent, recv_cnt,
+                   dtype, dst, tag, comm, &status);
+
+      if (newrank > newdst)
+        send_idx = recv_idx;
+
+      mask >>= 1;
+    }
+
+    free(cnts);
+    free(disps);
+
+  }
+  // In the non-power-of-two case, all odd-numbered processes of
+  // rank < 2 * rem send the result to (rank-1), the ranks who didn't
+  // participate above.
+
+  if (rank < 2 * rem) {
+    if (rank % 2)               // odd 
+      smpi_mpi_send(rbuff, count, dtype, rank - 1, tag, comm);
+    else                        // even 
+      smpi_mpi_recv(rbuff, count, dtype, rank + 1, tag, comm, &status);
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-rab-reduce-scatter.c b/src/smpi/colls/allreduce-rab-reduce-scatter.c
new file mode 100644 (file)
index 0000000..5650ef2
--- /dev/null
@@ -0,0 +1,521 @@
+#include "colls_private.h"
+#ifndef REDUCE_STUFF
+#define REDUCE_STUFF
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+extern MPI_User_function *MPIR_Op_table[];
+
+
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*  $Id: mpich-stuff.h,v 1.1 2005/08/22 19:50:21 faraj Exp $
+ *
+ *  (C) 2001 by Argonne National Laboratory.
+ *      See COPYRIGHT in top-level directory.
+ */
+#ifndef _MPICH_STUFF_H
+#define _MPICH_STUFF_H
+
+/*TOpaqOverview.tex
+  MPI Opaque Objects:
+
+  MPI Opaque objects such as 'MPI_Comm' or 'MPI_Datatype' are specified by 
+  integers (in the MPICH2 implementation); the MPI standard calls these
+  handles.  
+  Out of range values are invalid; the value 0 is reserved.
+  For most (with the possible exception of 
+  'MPI_Request' for performance reasons) MPI Opaque objects, the integer
+  encodes both the kind of object (allowing runtime tests to detect a datatype
+  passed where a communicator is expected) and important properties of the 
+  object.  Even the 'MPI_xxx_NULL' values should be encoded so that 
+  different null handles can be distinguished.  The details of the encoding
+  of the handles is covered in more detail in the MPICH2 Design Document.
+  For the most part, the ADI uses pointers to the underlying structures
+  rather than the handles themselves.  However, each structure contains an 
+  'handle' field that is the corresponding integer handle for the MPI object.
+
+  MPID objects (objects used within the implementation of MPI) are not opaque.
+
+  T*/
+
+/* Known MPI object types.  These are used for both the error handlers 
+   and for the handles.  This is a 4 bit value.  0 is reserved for so 
+   that all-zero handles can be flagged as an error. */
+/*E
+  MPID_Object_kind - Object kind (communicator, window, or file)
+
+  Notes:
+  This enum is used by keyvals and errhandlers to indicate the type of
+  object for which MPI opaque types the data is valid.  These are defined
+  as bits to allow future expansion to the case where an object is value for
+  multiple types (for example, we may want a universal error handler for 
+  errors return).  This is also used to indicate the type of MPI object a 
+  MPI handle represents.  It is an enum because only this applies only the
+  the MPI objects.
+
+  Module:
+  Attribute-DS
+  E*/
+typedef enum MPID_Object_kind {
+  MPID_COMM = 0x1,
+  MPID_GROUP = 0x2,
+  MPID_DATATYPE = 0x3,
+  MPID_FILE = 0x4,
+  MPID_ERRHANDLER = 0x5,
+  MPID_OP = 0x6,
+  MPID_INFO = 0x7,
+  MPID_WIN = 0x8,
+  MPID_KEYVAL = 0x9,
+  MPID_ATTR = 0xa,
+  MPID_REQUEST = 0xb
+} MPID_Object_kind;
+/* The above objects should correspond to MPI objects only. */
+#define HANDLE_MPI_KIND_SHIFT 26
+#define HANDLE_GET_MPI_KIND(a) ( ((a)&0x3c000000) >> HANDLE_MPI_KIND_SHIFT )
+
+/* Handle types.  These are really 2 bits */
+#define HANDLE_KIND_INVALID  0x0
+#define HANDLE_KIND_BUILTIN  0x1
+#define HANDLE_KIND_DIRECT   0x2
+#define HANDLE_KIND_INDIRECT 0x3
+/* Mask assumes that ints are at least 4 bytes */
+#define HANDLE_KIND_MASK 0xc0000000
+#define HANDLE_KIND_SHIFT 30
+#define HANDLE_GET_KIND(a) (((a)&HANDLE_KIND_MASK)>>HANDLE_KIND_SHIFT)
+#define HANDLE_SET_KIND(a,kind) ((a)|((kind)<<HANDLE_KIND_SHIFT))
+
+/* For indirect, the remainder of the handle has a block and index */
+#define HANDLE_INDIRECT_SHIFT 16
+#define HANDLE_BLOCK(a) (((a)& 0x03FF0000) >> HANDLE_INDIRECT_SHIFT)
+#define HANDLE_BLOCK_INDEX(a) ((a) & 0x0000FFFF)
+
+/* Handle block is between 1 and 1024 *elements* */
+#define HANDLE_BLOCK_SIZE 256
+/* Index size is bewtween 1 and 65536 *elements* */
+#define HANDLE_BLOCK_INDEX_SIZE 1024
+
+/* For direct, the remainder of the handle is the index into a predefined 
+   block */
+#define HANDLE_MASK 0x03FFFFFF
+#define HANDLE_INDEX(a) ((a)& HANDLE_MASK)
+
+/* ALL objects have the handle as the first value. */
+/* Inactive (unused and stored on the appropriate avail list) objects 
+   have MPIU_Handle_common as the head */
+typedef struct MPIU_Handle_common {
+  int handle;
+  volatile int ref_count;       /* This field is used to indicate that the
+                                   object is not in use (see, e.g., 
+                                   MPID_Comm_valid_ptr) */
+  void *next;                   /* Free handles use this field to point to the next
+                                   free object */
+} MPIU_Handle_common;
+
+/* All *active* (in use) objects have the handle as the first value; objects
+   with referene counts have the reference count as the second value.
+   See MPIU_Object_add_ref and MPIU_Object_release_ref. */
+typedef struct MPIU_Handle_head {
+  int handle;
+  volatile int ref_count;
+} MPIU_Handle_head;
+
+/* This type contains all of the data, except for the direct array,
+   used by the object allocators. */
+typedef struct MPIU_Object_alloc_t {
+  MPIU_Handle_common *avail;    /* Next available object */
+  int initialized;              /* */
+  void *(*indirect)[];          /* Pointer to indirect object blocks */
+  int indirect_size;            /* Number of allocated indirect blocks */
+  MPID_Object_kind kind;        /* Kind of object this is for */
+  int size;                     /* Size of an individual object */
+  void *direct;                 /* Pointer to direct block, used 
+                                   for allocation */
+  int direct_size;              /* Size of direct block */
+} MPIU_Object_alloc_t;
+extern void *MPIU_Handle_obj_alloc(MPIU_Object_alloc_t *);
+extern void MPIU_Handle_obj_alloc_start(MPIU_Object_alloc_t *);
+extern void MPIU_Handle_obj_alloc_complete(MPIU_Object_alloc_t *, int init);
+extern void MPIU_Handle_obj_free(MPIU_Object_alloc_t *, void *);
+void *MPIU_Handle_get_ptr_indirect(int, MPIU_Object_alloc_t *);
+extern void *MPIU_Handle_direct_init(void *direct, int direct_size,
+                                     int obj_size, int handle_type);
+#endif
+#define MPID_Getb_ptr(kind,a,bmsk,ptr)                                  \
+{                                                                       \
+   switch (HANDLE_GET_KIND(a)) {                                        \
+      case HANDLE_KIND_BUILTIN:                                         \
+          ptr=MPID_##kind##_builtin+((a)&(bmsk));                       \
+          break;                                                        \
+      case HANDLE_KIND_DIRECT:                                          \
+          ptr=MPID_##kind##_direct+HANDLE_INDEX(a);                     \
+          break;                                                        \
+      case HANDLE_KIND_INDIRECT:                                        \
+          ptr=((MPID_##kind*)                                           \
+               MPIU_Handle_get_ptr_indirect(a,&MPID_##kind##_mem));     \
+          break;                                                        \
+      case HANDLE_KIND_INVALID:                                         \
+      default:                                                         \
+          ptr=0;                                                       \
+          break;                                                       \
+    }                                                                   \
+}
+
+
+
+#define MPID_Op_get_ptr(a,ptr)         MPID_Getb_ptr(Op,a,0x000000ff,ptr)
+typedef enum MPID_Lang_t { MPID_LANG_C
+#ifdef HAVE_FORTRAN_BINDING
+      , MPID_LANG_FORTRAN, MPID_LANG_FORTRAN90
+#endif
+#ifdef HAVE_CXX_BINDING
+      , MPID_LANG_CXX
+#endif
+} MPID_Lang_t;
+/* Reduction and accumulate operations */
+/*E
+  MPID_Op_kind - Enumerates types of MPI_Op types
+
+  Notes:
+  These are needed for implementing 'MPI_Accumulate', since only predefined
+  operations are allowed for that operation.  
+
+  A gap in the enum values was made allow additional predefined operations
+  to be inserted.  This might include future additions to MPI or experimental
+  extensions (such as a Read-Modify-Write operation).
+
+  Module:
+  Collective-DS
+  E*/
+typedef enum MPID_Op_kind { MPID_OP_MAX = 1, MPID_OP_MIN = 2,
+  MPID_OP_SUM = 3, MPID_OP_PROD = 4,
+  MPID_OP_LAND = 5, MPID_OP_BAND = 6, MPID_OP_LOR = 7, MPID_OP_BOR = 8,
+  MPID_OP_LXOR = 9, MPID_OP_BXOR = 10, MPID_OP_MAXLOC = 11,
+  MPID_OP_MINLOC = 12, MPID_OP_REPLACE = 13,
+  MPID_OP_USER_NONCOMMUTE = 32, MPID_OP_USER = 33
+} MPID_Op_kind;
+
+/*S
+  MPID_User_function - Definition of a user function for MPI_Op types.
+
+  Notes:
+  This includes a 'const' to make clear which is the 'in' argument and 
+  which the 'inout' argument, and to indicate that the 'count' and 'datatype'
+  arguments are unchanged (they are addresses in an attempt to allow 
+  interoperation with Fortran).  It includes 'restrict' to emphasize that 
+  no overlapping operations are allowed.
+
+  We need to include a Fortran version, since those arguments will
+  have type 'MPI_Fint *' instead.  We also need to add a test to the
+  test suite for this case; in fact, we need tests for each of the handle
+  types to ensure that the transfered handle works correctly.
+
+  This is part of the collective module because user-defined operations
+  are valid only for the collective computation routines and not for 
+  RMA accumulate.
+
+  Yes, the 'restrict' is in the correct location.  C compilers that 
+  support 'restrict' should be able to generate code that is as good as a
+  Fortran compiler would for these functions.
+
+  We should note on the manual pages for user-defined operations that
+  'restrict' should be used when available, and that a cast may be 
+  required when passing such a function to 'MPI_Op_create'.
+
+  Question:
+  Should each of these function types have an associated typedef?
+
+  Should there be a C++ function here?
+
+  Module:
+  Collective-DS
+  S*/
+typedef union MPID_User_function {
+  void (*c_function) (const void *, void *, const int *, const MPI_Datatype *);
+  void (*f77_function) (const void *, void *,
+                        const MPI_Fint *, const MPI_Fint *);
+} MPID_User_function;
+/* FIXME: Should there be "restrict" in the definitions above, e.g., 
+   (*c_function)( const void restrict * , void restrict *, ... )? */
+
+/*S
+  MPID_Op - MPI_Op structure
+
+  Notes:
+  All of the predefined functions are commutative.  Only user functions may 
+  be noncummutative, so there are two separate op types for commutative and
+  non-commutative user-defined operations.
+
+  Operations do not require reference counts because there are no nonblocking
+  operations that accept user-defined operations.  Thus, there is no way that
+  a valid program can free an 'MPI_Op' while it is in use.
+
+  Module:
+  Collective-DS
+  S*/
+typedef struct MPID_Op {
+  int handle;                   /* value of MPI_Op for this structure */
+  volatile int ref_count;
+  MPID_Op_kind kind;
+  MPID_Lang_t language;
+  MPID_User_function function;
+} MPID_Op;
+#define MPID_OP_N_BUILTIN 14
+extern MPID_Op MPID_Op_builtin[MPID_OP_N_BUILTIN];
+extern MPID_Op MPID_Op_direct[];
+extern MPIU_Object_alloc_t MPID_Op_mem;
+
+/*****************************************************************************
+
+* Function: get_op_func
+
+* return: Pointer to MPI_User_function
+
+* inputs:
+   op: operator (max, min, etc)
+
+   * Descrp: Function returns the function associated with current operator
+   * op.
+
+   * Auther: AHMAD FARAJ
+
+****************************************************************************/
+MPI_User_function *get_op_func(MPI_Op op)
+{
+
+  if (HANDLE_GET_KIND(op) == HANDLE_KIND_BUILTIN)
+    return MPIR_Op_table[op % 16 - 1];
+  return NULL;
+}
+
+#endif
+
+
+int smpi_coll_tuned_allreduce_rab_reduce_scatter(void *sbuff, void *rbuff,
+                                                 int count, MPI_Datatype dtype,
+                                                 MPI_Op op, MPI_Comm comm)
+{
+  int nprocs, rank, type_size, tag = 543;
+  int mask, dst, pof2, newrank, rem, newdst, i,
+      send_idx, recv_idx, last_idx, send_cnt, recv_cnt, *cnts, *disps;
+  MPI_Aint lb, extent;
+  MPI_Status status;
+  void *tmp_buf = NULL;
+  MPI_User_function *func = get_op_func(op);
+  nprocs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  MPIR_Localcopy(sbuff, count, dtype, rbuff, count, dtype);
+
+  type_size = smpi_datatype_size(dtype);
+
+  // find nearest power-of-two less than or equal to comm_size
+  pof2 = 1;
+  while (pof2 <= nprocs)
+    pof2 <<= 1;
+  pof2 >>= 1;
+
+  rem = nprocs - pof2;
+
+  // In the non-power-of-two case, all even-numbered
+  // processes of rank < 2*rem send their data to
+  // (rank+1). These even-numbered processes no longer
+  // participate in the algorithm until the very end. The
+  // remaining processes form a nice power-of-two. 
+
+  if (rank < 2 * rem) {
+    // even       
+    if (rank % 2 == 0) {
+
+      MPIC_Send(rbuff, count, dtype, rank + 1, tag, comm);
+
+      // temporarily set the rank to -1 so that this
+      // process does not pariticipate in recursive
+      // doubling
+      newrank = -1;
+    } else                      // odd
+    {
+      MPIC_Recv(tmp_buf, count, dtype, rank - 1, tag, comm, &status);
+      // do the reduction on received data. since the
+      // ordering is right, it doesn't matter whether
+      // the operation is commutative or not.
+      (*func) (tmp_buf, rbuff, &count, &dtype);
+
+      // change the rank 
+      newrank = rank / 2;
+    }
+  }
+
+  else                          // rank >= 2 * rem 
+    newrank = rank - rem;
+
+  // If op is user-defined or count is less than pof2, use
+  // recursive doubling algorithm. Otherwise do a reduce-scatter
+  // followed by allgather. (If op is user-defined,
+  // derived datatypes are allowed and the user could pass basic
+  // datatypes on one process and derived on another as long as
+  // the type maps are the same. Breaking up derived
+  // datatypes to do the reduce-scatter is tricky, therefore
+  // using recursive doubling in that case.) 
+
+  if (newrank != -1) {
+    // do a reduce-scatter followed by allgather. for the
+    // reduce-scatter, calculate the count that each process receives
+    // and the displacement within the buffer 
+
+    cnts = (int *) xbt_malloc(pof2 * sizeof(int));
+    disps = (int *) xbt_malloc(pof2 * sizeof(int));
+
+    for (i = 0; i < (pof2 - 1); i++)
+      cnts[i] = count / pof2;
+    cnts[pof2 - 1] = count - (count / pof2) * (pof2 - 1);
+
+    disps[0] = 0;
+    for (i = 1; i < pof2; i++)
+      disps[i] = disps[i - 1] + cnts[i - 1];
+
+    mask = 0x1;
+    send_idx = recv_idx = 0;
+    last_idx = pof2;
+    while (mask < pof2) {
+      newdst = newrank ^ mask;
+      // find real rank of dest 
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      send_cnt = recv_cnt = 0;
+      if (newrank < newdst) {
+        send_idx = recv_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < last_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < send_idx; i++)
+          recv_cnt += cnts[i];
+      } else {
+        recv_idx = send_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < recv_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < last_idx; i++)
+          recv_cnt += cnts[i];
+      }
+
+      // Send data from recvbuf. Recv into tmp_buf 
+      MPIC_Sendrecv((char *) rbuff + disps[send_idx] * extent, send_cnt,
+                    dtype, dst, tag,
+                    (char *) tmp_buf + disps[recv_idx] * extent, recv_cnt,
+                    dtype, dst, tag, comm, &status);
+
+      // tmp_buf contains data received in this step.
+      // recvbuf contains data accumulated so far 
+
+      // This algorithm is used only for predefined ops
+      // and predefined ops are always commutative.
+      (*func) ((char *) tmp_buf + disps[recv_idx] * extent,
+               (char *) rbuff + disps[recv_idx] * extent, &recv_cnt, &dtype);
+
+      // update send_idx for next iteration 
+      send_idx = recv_idx;
+      mask <<= 1;
+
+      // update last_idx, but not in last iteration because the value
+      // is needed in the allgather step below. 
+      if (mask < pof2)
+        last_idx = recv_idx + pof2 / mask;
+    }
+
+    // now do the allgather 
+
+    mask >>= 1;
+    while (mask > 0) {
+      newdst = newrank ^ mask;
+      // find real rank of dest
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      send_cnt = recv_cnt = 0;
+      if (newrank < newdst) {
+        // update last_idx except on first iteration 
+        if (mask != pof2 / 2)
+          last_idx = last_idx + pof2 / (mask * 2);
+
+        recv_idx = send_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < recv_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < last_idx; i++)
+          recv_cnt += cnts[i];
+      } else {
+        recv_idx = send_idx - pof2 / (mask * 2);
+        for (i = send_idx; i < last_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < send_idx; i++)
+          recv_cnt += cnts[i];
+      }
+
+      MPIC_Sendrecv((char *) rbuff + disps[send_idx] * extent, send_cnt,
+                    dtype, dst, tag,
+                    (char *) rbuff + disps[recv_idx] * extent, recv_cnt,
+                    dtype, dst, tag, comm, &status);
+
+      if (newrank > newdst)
+        send_idx = recv_idx;
+
+      mask >>= 1;
+    }
+
+    free(cnts);
+    free(disps);
+
+  }
+  // In the non-power-of-two case, all odd-numbered processes of
+  // rank < 2 * rem send the result to (rank-1), the ranks who didn't
+  // participate above.
+
+  if (rank < 2 * rem) {
+    if (rank % 2)               // odd 
+      MPIC_Send(rbuff, count, dtype, rank - 1, tag, comm);
+    else                        // even 
+      MPIC_Recv(rbuff, count, dtype, rank + 1, tag, comm, &status);
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-rab-rsag.c b/src/smpi/colls/allreduce-rab-rsag.c
new file mode 100644 (file)
index 0000000..34e23d6
--- /dev/null
@@ -0,0 +1,191 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+int smpi_coll_tuned_allreduce_rab_rsag(void *sbuff, void *rbuff, int count,
+                                       MPI_Datatype dtype, MPI_Op op,
+                                       MPI_Comm comm)
+{
+  int nprocs, rank, tag = 543;
+  int mask, dst, pof2, newrank, rem, newdst, i,
+      send_idx, recv_idx, last_idx, send_cnt, recv_cnt, *cnts, *disps;
+  MPI_Aint extent;
+  MPI_Status status;
+  void *tmp_buf = NULL;
+  nprocs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  smpi_mpi_sendrecv(sbuff, count, dtype, rank, tag, rbuff, count, dtype, rank, tag,
+               comm, &status);
+
+  // find nearest power-of-two less than or equal to comm_size
+  pof2 = 1;
+  while (pof2 <= nprocs)
+    pof2 <<= 1;
+  pof2 >>= 1;
+
+  rem = nprocs - pof2;
+
+  // In the non-power-of-two case, all even-numbered
+  // processes of rank < 2*rem send their data to
+  // (rank+1). These even-numbered processes no longer
+  // participate in the algorithm until the very end. The
+  // remaining processes form a nice power-of-two. 
+
+  if (rank < 2 * rem) {
+    // even       
+    if (rank % 2 == 0) {
+
+      smpi_mpi_send(rbuff, count, dtype, rank + 1, tag, comm);
+
+      // temporarily set the rank to -1 so that this
+      // process does not pariticipate in recursive
+      // doubling
+      newrank = -1;
+    } else                      // odd
+    {
+      smpi_mpi_recv(tmp_buf, count, dtype, rank - 1, tag, comm, &status);
+      // do the reduction on received data. since the
+      // ordering is right, it doesn't matter whether
+      // the operation is commutative or not.
+      smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+
+      // change the rank 
+      newrank = rank / 2;
+    }
+  }
+
+  else                          // rank >= 2 * rem 
+    newrank = rank - rem;
+
+  // If op is user-defined or count is less than pof2, use
+  // recursive doubling algorithm. Otherwise do a reduce-scatter
+  // followed by allgather. (If op is user-defined,
+  // derived datatypes are allowed and the user could pass basic
+  // datatypes on one process and derived on another as long as
+  // the type maps are the same. Breaking up derived
+  // datatypes to do the reduce-scatter is tricky, therefore
+  // using recursive doubling in that case.) 
+
+  if (newrank != -1) {
+    // do a reduce-scatter followed by allgather. for the
+    // reduce-scatter, calculate the count that each process receives
+    // and the displacement within the buffer 
+
+    cnts = (int *) xbt_malloc(pof2 * sizeof(int));
+    disps = (int *) xbt_malloc(pof2 * sizeof(int));
+
+    for (i = 0; i < (pof2 - 1); i++)
+      cnts[i] = count / pof2;
+    cnts[pof2 - 1] = count - (count / pof2) * (pof2 - 1);
+
+    disps[0] = 0;
+    for (i = 1; i < pof2; i++)
+      disps[i] = disps[i - 1] + cnts[i - 1];
+
+    mask = 0x1;
+    send_idx = recv_idx = 0;
+    last_idx = pof2;
+    while (mask < pof2) {
+      newdst = newrank ^ mask;
+      // find real rank of dest 
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      send_cnt = recv_cnt = 0;
+      if (newrank < newdst) {
+        send_idx = recv_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < last_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < send_idx; i++)
+          recv_cnt += cnts[i];
+      } else {
+        recv_idx = send_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < recv_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < last_idx; i++)
+          recv_cnt += cnts[i];
+      }
+
+      // Send data from recvbuf. Recv into tmp_buf 
+      smpi_mpi_sendrecv((char *) rbuff + disps[send_idx] * extent, send_cnt,
+                   dtype, dst, tag,
+                   (char *) tmp_buf + disps[recv_idx] * extent, recv_cnt,
+                   dtype, dst, tag, comm, &status);
+
+      // tmp_buf contains data received in this step.
+      // recvbuf contains data accumulated so far 
+
+      // This algorithm is used only for predefined ops
+      // and predefined ops are always commutative.
+      smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+                     (char *) rbuff + disps[recv_idx] * extent,
+                     &recv_cnt, &dtype);
+
+      // update send_idx for next iteration 
+      send_idx = recv_idx;
+      mask <<= 1;
+
+      // update last_idx, but not in last iteration because the value
+      // is needed in the allgather step below. 
+      if (mask < pof2)
+        last_idx = recv_idx + pof2 / mask;
+    }
+
+    // now do the allgather 
+
+    mask >>= 1;
+    while (mask > 0) {
+      newdst = newrank ^ mask;
+      // find real rank of dest
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      send_cnt = recv_cnt = 0;
+      if (newrank < newdst) {
+        // update last_idx except on first iteration 
+        if (mask != pof2 / 2)
+          last_idx = last_idx + pof2 / (mask * 2);
+
+        recv_idx = send_idx + pof2 / (mask * 2);
+        for (i = send_idx; i < recv_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < last_idx; i++)
+          recv_cnt += cnts[i];
+      } else {
+        recv_idx = send_idx - pof2 / (mask * 2);
+        for (i = send_idx; i < last_idx; i++)
+          send_cnt += cnts[i];
+        for (i = recv_idx; i < send_idx; i++)
+          recv_cnt += cnts[i];
+      }
+
+      smpi_mpi_sendrecv((char *) rbuff + disps[send_idx] * extent, send_cnt,
+                   dtype, dst, tag,
+                   (char *) rbuff + disps[recv_idx] * extent, recv_cnt,
+                   dtype, dst, tag, comm, &status);
+
+      if (newrank > newdst)
+        send_idx = recv_idx;
+
+      mask >>= 1;
+    }
+
+    free(cnts);
+    free(disps);
+
+  }
+  // In the non-power-of-two case, all odd-numbered processes of
+  // rank < 2 * rem send the result to (rank-1), the ranks who didn't
+  // participate above.
+
+  if (rank < 2 * rem) {
+    if (rank % 2)               // odd 
+      smpi_mpi_send(rbuff, count, dtype, rank - 1, tag, comm);
+    else                        // even 
+      smpi_mpi_recv(rbuff, count, dtype, rank + 1, tag, comm, &status);
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-rab1.c b/src/smpi/colls/allreduce-rab1.c
new file mode 100644 (file)
index 0000000..ae72f74
--- /dev/null
@@ -0,0 +1,101 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+// NP pow of 2 for now
+int smpi_coll_tuned_allreduce_rab1(void *sbuff, void *rbuff,
+                                   int count, MPI_Datatype dtype,
+                                   MPI_Op op, MPI_Comm comm)
+{
+  MPI_Status status;
+  MPI_Aint extent;
+  int tag = 4321, rank, nprocs, send_size, newcnt, share;
+  int pof2 = 1, mask, send_idx, recv_idx, dst, send_cnt, recv_cnt;
+
+  void *recv, *tmp_buf;
+
+  rank = smpi_comm_rank(comm);
+  nprocs = smpi_comm_size(comm);
+
+  extent = smpi_datatype_get_extent(dtype);
+
+  pof2 = 1;
+  while (pof2 <= nprocs)
+    pof2 <<= 1;
+  pof2 >>= 1;
+
+  mask = 1;
+  send_idx = recv_idx = 0;
+
+  // uneven count
+  if ((count % nprocs)) {
+    send_size = (count + nprocs) / nprocs;
+    newcnt = send_size * nprocs;
+
+    recv = (void *) xbt_malloc(extent * newcnt);
+    tmp_buf = (void *) xbt_malloc(extent * newcnt);
+    memcpy(recv, sbuff, extent * count);
+
+
+    mask = pof2 / 2;
+    share = newcnt / pof2;
+    while (mask > 0) {
+      dst = rank ^ mask;
+      send_cnt = recv_cnt = newcnt / (pof2 / mask);
+
+      if (rank < dst)
+        send_idx = recv_idx + (mask * share);
+      else
+        recv_idx = send_idx + (mask * share);
+
+      smpi_mpi_sendrecv((char *) recv + send_idx * extent, send_cnt, dtype, dst, tag,
+                   tmp_buf, recv_cnt, dtype, dst, tag, comm, &status);
+
+      smpi_op_apply(op, tmp_buf, (char *) recv + recv_idx * extent, &recv_cnt,
+                     &dtype);
+
+      // update send_idx for next iteration 
+      send_idx = recv_idx;
+      mask >>= 1;
+    }
+
+    memcpy(tmp_buf, (char *) recv + recv_idx * extent, recv_cnt * extent);
+    mpi_coll_allgather_fun(tmp_buf, recv_cnt, dtype, recv, recv_cnt, dtype, comm);
+
+    memcpy(rbuff, recv, count * extent);
+    free(recv);
+    free(tmp_buf);
+
+  }
+
+  else {
+    tmp_buf = (void *) xbt_malloc(extent * count);
+    memcpy(rbuff, sbuff, count * extent);
+    mask = pof2 / 2;
+    share = count / pof2;
+    while (mask > 0) {
+      dst = rank ^ mask;
+      send_cnt = recv_cnt = count / (pof2 / mask);
+
+      if (rank < dst)
+        send_idx = recv_idx + (mask * share);
+      else
+        recv_idx = send_idx + (mask * share);
+
+      smpi_mpi_sendrecv((char *) rbuff + send_idx * extent, send_cnt, dtype, dst,
+                   tag, tmp_buf, recv_cnt, dtype, dst, tag, comm, &status);
+
+      smpi_op_apply(op, tmp_buf, (char *) rbuff + recv_idx * extent, &recv_cnt,
+                     &dtype);
+
+      // update send_idx for next iteration 
+      send_idx = recv_idx;
+      mask >>= 1;
+    }
+
+    memcpy(tmp_buf, (char *) rbuff + recv_idx * extent, recv_cnt * extent);
+    mpi_coll_allgather_fun(tmp_buf, recv_cnt, dtype, rbuff, recv_cnt, dtype, comm);
+    free(tmp_buf);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-rab2.c b/src/smpi/colls/allreduce-rab2.c
new file mode 100644 (file)
index 0000000..982933c
--- /dev/null
@@ -0,0 +1,78 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+// this requires that count >= NP
+int smpi_coll_tuned_allreduce_rab2(void *sbuff, void *rbuff,
+                                   int count, MPI_Datatype dtype,
+                                   MPI_Op op, MPI_Comm comm)
+{
+  MPI_Aint s_extent;
+  int i, rank, nprocs;
+  int nbytes, send_size, s_offset, r_offset;
+  void *recv, *send, *tmp;
+  /*
+     #ifdef MPICH2_REDUCTION
+     MPI_User_function * uop = MPIR_Op_table[op % 16 - 1];
+     #else
+     MPI_User_function *uop;
+     struct MPIR_OP *op_ptr;
+     op_ptr = MPIR_ToPointer(op);
+     uop  = op_ptr->op;
+     #endif
+   */
+  rank = smpi_comm_rank(comm);
+  nprocs = smpi_comm_size(comm);
+
+
+  s_extent = smpi_datatype_get_extent(dtype);
+
+  // uneven count
+  if (count % nprocs) {
+    if (count < nprocs)
+      send_size = nprocs;
+    else
+      send_size = (count + nprocs) / nprocs;
+    nbytes = send_size * s_extent;
+
+    send = (void *) xbt_malloc(s_extent * send_size * nprocs);
+    recv = (void *) xbt_malloc(s_extent * send_size * nprocs);
+    tmp = (void *) xbt_malloc(nbytes);
+
+    memcpy(send, sbuff, s_extent * count);
+
+    mpi_coll_alltoall_fun(send, send_size, dtype, recv, send_size, dtype, comm);
+
+    memcpy(tmp, recv, nbytes);
+
+    for (i = 1, s_offset = nbytes; i < nprocs; i++, s_offset = i * nbytes)
+      smpi_op_apply(op, (char *) recv + s_offset, tmp, &send_size, &dtype);
+
+    mpi_coll_allgather_fun(tmp, send_size, dtype, recv, send_size, dtype, comm);
+    memcpy(rbuff, recv, count * s_extent);
+
+    free(recv);
+    free(tmp);
+    free(send);
+  } else {
+    send = sbuff;
+    send_size = count / nprocs;
+    nbytes = send_size * s_extent;
+    r_offset = rank * nbytes;
+
+    recv = (void *) xbt_malloc(s_extent * send_size * nprocs);
+
+    mpi_coll_alltoall_fun(send, send_size, dtype, recv, send_size, dtype, comm);
+
+    memcpy((char *) rbuff + r_offset, recv, nbytes);
+
+    for (i = 1, s_offset = nbytes; i < nprocs; i++, s_offset = i * nbytes)
+      smpi_op_apply(op, (char *) recv + s_offset, (char *) rbuff + r_offset,
+                     &send_size, &dtype);
+
+    mpi_coll_allgather_fun((char *) rbuff + r_offset, send_size, dtype, rbuff, send_size,
+                  dtype, comm);
+    free(recv);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-rdb.c b/src/smpi/colls/allreduce-rdb.c
new file mode 100644 (file)
index 0000000..44717ad
--- /dev/null
@@ -0,0 +1,124 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+int smpi_coll_tuned_allreduce_rdb(void *sbuff, void *rbuff, int count,
+                                  MPI_Datatype dtype, MPI_Op op, MPI_Comm comm)
+{
+  int nprocs, rank, tag = 543;
+  int mask, dst, pof2, newrank, rem, newdst;
+  MPI_Aint extent, lb;
+  MPI_Status status;
+  void *tmp_buf = NULL;
+  /*
+     #ifdef MPICH2_REDUCTION
+     MPI_User_function * uop = MPIR_Op_table[op % 16 - 1];
+     #else
+     MPI_User_function *uop;
+     struct MPIR_OP *op_ptr;
+     op_ptr = MPIR_ToPointer(op);
+     uop  = op_ptr->op;
+     #endif
+   */
+  nprocs=smpi_comm_size(comm);
+  rank=smpi_comm_rank(comm);
+
+  smpi_datatype_extent(dtype, &lb, &extent);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  smpi_mpi_sendrecv(sbuff, count, dtype, rank, 500,
+               rbuff, count, dtype, rank, 500, comm, &status);
+
+  // find nearest power-of-two less than or equal to comm_size
+  pof2 = 1;
+  while (pof2 <= nprocs)
+    pof2 <<= 1;
+  pof2 >>= 1;
+
+  rem = nprocs - pof2;
+
+  // In the non-power-of-two case, all even-numbered
+  // processes of rank < 2*rem send their data to
+  // (rank+1). These even-numbered processes no longer
+  // participate in the algorithm until the very end. The
+  // remaining processes form a nice power-of-two. 
+
+  if (rank < 2 * rem) {
+    // even       
+    if (rank % 2 == 0) {
+
+      smpi_mpi_send(rbuff, count, dtype, rank + 1, tag, comm);
+
+      // temporarily set the rank to -1 so that this
+      // process does not pariticipate in recursive
+      // doubling
+      newrank = -1;
+    } else                      // odd
+    {
+      smpi_mpi_recv(tmp_buf, count, dtype, rank - 1, tag, comm, &status);
+      // do the reduction on received data. since the
+      // ordering is right, it doesn't matter whether
+      // the operation is commutative or not.
+      smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+
+      // change the rank 
+      newrank = rank / 2;
+    }
+  }
+
+  else                          // rank >= 2 * rem 
+    newrank = rank - rem;
+
+  // If op is user-defined or count is less than pof2, use
+  // recursive doubling algorithm. Otherwise do a reduce-scatter
+  // followed by allgather. (If op is user-defined,
+  // derived datatypes are allowed and the user could pass basic
+  // datatypes on one process and derived on another as long as
+  // the type maps are the same. Breaking up derived
+  // datatypes to do the reduce-scatter is tricky, therefore
+  // using recursive doubling in that case.) 
+
+  if (newrank != -1) {
+    mask = 0x1;
+    while (mask < pof2) {
+      newdst = newrank ^ mask;
+      // find real rank of dest 
+      dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+
+      // Send the most current data, which is in recvbuf. Recv
+      // into tmp_buf 
+      smpi_mpi_sendrecv(rbuff, count, dtype, dst, tag, tmp_buf, count, dtype,
+                   dst, tag, comm, &status);
+
+      // tmp_buf contains data received in this step.
+      // recvbuf contains data accumulated so far 
+
+      // op is commutative OR the order is already right
+      // we assume it is commuttive op
+      //      if (op -> op_commute  || (dst < rank))
+      if ((dst < rank)) {
+        smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+      } else                    // op is noncommutative and the order is not right
+      {
+        smpi_op_apply(op, rbuff, tmp_buf, &count, &dtype);
+
+        // copy result back into recvbuf
+        smpi_mpi_sendrecv(tmp_buf, count, dtype, rank, tag, rbuff, count,
+                     dtype, rank, tag, comm, &status);
+      }
+      mask <<= 1;
+    }
+  }
+  // In the non-power-of-two case, all odd-numbered processes of
+  // rank < 2 * rem send the result to (rank-1), the ranks who didn't
+  // participate above.
+
+  if (rank < 2 * rem) {
+    if (rank % 2)               // odd 
+      smpi_mpi_send(rbuff, count, dtype, rank - 1, tag, comm);
+    else                        // even 
+      smpi_mpi_recv(rbuff, count, dtype, rank + 1, tag, comm, &status);
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-redbcast.c b/src/smpi/colls/allreduce-redbcast.c
new file mode 100644 (file)
index 0000000..69c552d
--- /dev/null
@@ -0,0 +1,10 @@
+#include "colls_private.h"
+
+int smpi_coll_tuned_allreduce_redbcast(void *buf, void *buf2, int count,
+                                       MPI_Datatype datatype, MPI_Op op,
+                                       MPI_Comm comm)
+{
+  smpi_mpi_reduce(buf, buf2, count, datatype, op, 0, comm);
+  smpi_mpi_bcast(buf2, count, datatype, 0, comm);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-smp-binomial-pipeline.c b/src/smpi/colls/allreduce-smp-binomial-pipeline.c
new file mode 100644 (file)
index 0000000..93d72bb
--- /dev/null
@@ -0,0 +1,194 @@
+#include "colls_private.h"
+/* IMPLEMENTED BY PITCH PATARASUK 
+   Non-topoloty-specific (however, number of cores/node need to be changed) 
+   all-reduce operation designed for smp clusters
+   It uses 2-layer communication: binomial for both intra-communication 
+   inter-communication
+   The communication are done in a pipeline fashion */
+
+/* change number of core per smp-node
+   we assume that number of core per process will be the same for all implementations */
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+/* this is a default segment size for pipelining, 
+   but it is typically passed as a command line argument */
+int allreduce_smp_binomial_pipeline_segment_size = 4096;
+
+/* ** NOTE **
+   This code is modified from allreduce-smp-binomial.c by wrapping the code with pipeline effect as follow
+   for (loop over pipelength) {
+     smp-binomial main code;
+   }
+*/
+
+/* ** NOTE **
+   Use -DMPICH2 if this code does not compile.
+   MPICH1 code also work on MPICH2 on our cluster and the performance are similar.
+   This code assume commutative and associative reduce operator (MPI_SUM, MPI_MAX, etc).
+*/
+
+/*
+This fucntion performs all-reduce operation as follow. ** in a pipeline fashion **
+1) binomial_tree reduce inside each SMP node
+2) binomial_tree reduce intra-communication between root of each SMP node
+3) binomial_tree bcast intra-communication between root of each SMP node
+4) binomial_tree bcast inside each SMP node
+*/
+int smpi_coll_tuned_allreduce_smp_binomial_pipeline(void *send_buf,
+                                                    void *recv_buf, int count,
+                                                    MPI_Datatype dtype,
+                                                    MPI_Op op, MPI_Comm comm)
+{
+  int comm_size, rank;
+  void *tmp_buf;
+  int tag = 50;
+  int mask, src, dst;
+  MPI_Status status;
+  int num_core = NUM_CORE;
+
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  int intra_rank, inter_rank;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+
+  int phase;
+  int send_offset;
+  int recv_offset;
+  int pcount = allreduce_smp_binomial_pipeline_segment_size;
+  if (pcount > count) {
+    pcount = count;
+  }
+
+  /* size of processes participate in intra communications =>
+     should be equal to number of machines */
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+
+  /* copy input buffer to output buffer */
+  smpi_mpi_sendrecv(send_buf, count, dtype, rank, tag,
+               recv_buf, count, dtype, rank, tag, comm, &status);
+
+  /* compute pipe length */
+  int pipelength;
+  pipelength = count / pcount;
+
+  /* pipelining over pipelength (+3 is because we have 4 stages:
+     reduce-intra, reduce-inter, bcast-inter, bcast-intra */
+  for (phase = 0; phase < pipelength + 3; phase++) {
+
+    /* start binomial reduce intra communication inside each SMP node */
+    if (phase < pipelength) {
+      mask = 1;
+      while (mask < num_core) {
+        if ((mask & intra_rank) == 0) {
+          src = (inter_rank * num_core) + (intra_rank | mask);
+          if (src < comm_size) {
+            recv_offset = phase * pcount * extent;
+            smpi_mpi_recv(tmp_buf, pcount, dtype, src, tag, comm, &status);
+            smpi_op_apply(op, tmp_buf, (char *)recv_buf + recv_offset, &pcount, &dtype);
+          }
+        } else {
+          send_offset = phase * pcount * extent;
+          dst = (inter_rank * num_core) + (intra_rank & (~mask));
+          smpi_mpi_send((char *)recv_buf + send_offset, pcount, dtype, dst, tag, comm);
+          break;
+        }
+        mask <<= 1;
+      }
+    }
+
+    /* start binomial reduce inter-communication between each SMP nodes: 
+       each node only have one process that can communicate to other nodes */
+    if ((phase > 0) && (phase < (pipelength + 1))) {
+      if (intra_rank == 0) {
+
+        mask = 1;
+        while (mask < inter_comm_size) {
+          if ((mask & inter_rank) == 0) {
+            src = (inter_rank | mask) * num_core;
+            if (src < comm_size) {
+              recv_offset = (phase - 1) * pcount * extent;
+              smpi_mpi_recv(tmp_buf, pcount, dtype, src, tag, comm, &status);
+              smpi_op_apply(op, tmp_buf, (char *)recv_buf + recv_offset, &pcount, &dtype);
+            }
+          } else {
+            dst = (inter_rank & (~mask)) * num_core;
+            send_offset = (phase - 1) * pcount * extent;
+            smpi_mpi_send((char *)recv_buf + send_offset, pcount, dtype, dst, tag, comm);
+            break;
+          }
+          mask <<= 1;
+        }
+      }
+    }
+
+    /* start binomial broadcast inter-communication between each SMP nodes: 
+       each node only have one process that can communicate to other nodes */
+    if ((phase > 1) && (phase < (pipelength + 2))) {
+      if (intra_rank == 0) {
+        mask = 1;
+        while (mask < inter_comm_size) {
+          if (inter_rank & mask) {
+            src = (inter_rank - mask) * num_core;
+            recv_offset = (phase - 2) * pcount * extent;
+            smpi_mpi_recv((char *)recv_buf + recv_offset, pcount, dtype, src, tag, comm,
+                     &status);
+            break;
+          }
+          mask <<= 1;
+        }
+        mask >>= 1;
+
+        while (mask > 0) {
+          if (inter_rank < inter_comm_size) {
+            dst = (inter_rank + mask) * num_core;
+            if (dst < comm_size) {
+              //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+              send_offset = (phase - 2) * pcount * extent;
+              smpi_mpi_send((char *)recv_buf + send_offset, pcount, dtype, dst, tag, comm);
+            }
+          }
+          mask >>= 1;
+        }
+      }
+    }
+
+    /* start binomial broadcast intra-communication inside each SMP nodes */
+    if (phase > 2) {
+      int num_core_in_current_smp = num_core;
+      if (inter_rank == (inter_comm_size - 1)) {
+        num_core_in_current_smp = comm_size - (inter_rank * num_core);
+      }
+      mask = 1;
+      while (mask < num_core_in_current_smp) {
+        if (intra_rank & mask) {
+          src = (inter_rank * num_core) + (intra_rank - mask);
+          recv_offset = (phase - 3) * pcount * extent;
+          smpi_mpi_recv((char *)recv_buf + recv_offset, pcount, dtype, src, tag, comm,
+                   &status);
+          break;
+        }
+        mask <<= 1;
+      }
+      mask >>= 1;
+
+      while (mask > 0) {
+        dst = (inter_rank * num_core) + (intra_rank + mask);
+        if (dst < comm_size) {
+          send_offset = (phase - 3) * pcount * extent;
+          smpi_mpi_send((char *)recv_buf + send_offset, pcount, dtype, dst, tag, comm);
+        }
+        mask >>= 1;
+      }
+    }
+  }                             // for phase
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-smp-binomial.c b/src/smpi/colls/allreduce-smp-binomial.c
new file mode 100644 (file)
index 0000000..ed9b68c
--- /dev/null
@@ -0,0 +1,147 @@
+#include "colls_private.h"
+/* IMPLEMENTED BY PITCH PATARASUK 
+   Non-topoloty-specific (however, number of cores/node need to be changed) 
+   all-reduce operation designed for smp clusters
+   It uses 2-layer communication: binomial for both intra-communication 
+   inter-communication*/
+
+/* change number of core per smp-node
+   we assume that number of core per process will be the same for all implementations */
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+/* ** NOTE **
+   Use -DMPICH2 if this code does not compile.
+   MPICH1 code also work on MPICH2 on our cluster and the performance are similar.
+   This code assume commutative and associative reduce operator (MPI_SUM, MPI_MAX, etc).
+*/
+
+//#include <star-reduction.c>
+
+/*
+This fucntion performs all-reduce operation as follow.
+1) binomial_tree reduce inside each SMP node
+2) binomial_tree reduce intra-communication between root of each SMP node
+3) binomial_tree bcast intra-communication between root of each SMP node
+4) binomial_tree bcast inside each SMP node
+*/
+int smpi_coll_tuned_allreduce_smp_binomial(void *send_buf, void *recv_buf,
+                                           int count, MPI_Datatype dtype,
+                                           MPI_Op op, MPI_Comm comm)
+{
+  int comm_size, rank;
+  void *tmp_buf;
+  int tag = 50;
+  int mask, src, dst;
+  int num_core = NUM_CORE;
+  MPI_Status status;
+
+  comm_size=smpi_comm_size(comm);
+  rank=smpi_comm_rank(comm);
+  MPI_Aint extent, lb;
+  smpi_datatype_extent(dtype, &lb, &extent);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  /* compute intra and inter ranking */
+  int intra_rank, inter_rank;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+
+  /* size of processes participate in intra communications =>
+     should be equal to number of machines */
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+
+  /* copy input buffer to output buffer */
+  smpi_mpi_sendrecv(send_buf, count, dtype, rank, tag,
+               recv_buf, count, dtype, rank, tag, comm, &status);
+
+  /* start binomial reduce intra communication inside each SMP node */
+  mask = 1;
+  while (mask < num_core) {
+    if ((mask & intra_rank) == 0) {
+      src = (inter_rank * num_core) + (intra_rank | mask);
+      if (src < comm_size) {
+        smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+      }
+    } else {
+      dst = (inter_rank * num_core) + (intra_rank & (~mask));
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  /* start binomial reduce inter-communication between each SMP nodes: 
+     each node only have one process that can communicate to other nodes */
+  if (intra_rank == 0) {
+    mask = 1;
+    while (mask < inter_comm_size) {
+      if ((mask & inter_rank) == 0) {
+        src = (inter_rank | mask) * num_core;
+        if (src < comm_size) {
+          smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+          smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        }
+      } else {
+        dst = (inter_rank & (~mask)) * num_core;
+        smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+        break;
+      }
+      mask <<= 1;
+    }
+  }
+
+  /* start binomial broadcast inter-communication between each SMP nodes: 
+     each node only have one process that can communicate to other nodes */
+  if (intra_rank == 0) {
+    mask = 1;
+    while (mask < inter_comm_size) {
+      if (inter_rank & mask) {
+        src = (inter_rank - mask) * num_core;
+        smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+        break;
+      }
+      mask <<= 1;
+    }
+    mask >>= 1;
+
+    while (mask > 0) {
+      if (inter_rank < inter_comm_size) {
+        dst = (inter_rank + mask) * num_core;
+        if (dst < comm_size) {
+          smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+        }
+      }
+      mask >>= 1;
+    }
+  }
+
+  /* start binomial broadcast intra-communication inside each SMP nodes */
+  int num_core_in_current_smp = num_core;
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * num_core);
+  }
+  mask = 1;
+  while (mask < num_core_in_current_smp) {
+    if (intra_rank & mask) {
+      src = (inter_rank * num_core) + (intra_rank - mask);
+      smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+      break;
+    }
+    mask <<= 1;
+  }
+  mask >>= 1;
+
+  while (mask > 0) {
+    dst = (inter_rank * num_core) + (intra_rank + mask);
+    if (dst < comm_size) {
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+    }
+    mask >>= 1;
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-smp-rdb.c b/src/smpi/colls/allreduce-smp-rdb.c
new file mode 100644 (file)
index 0000000..d208584
--- /dev/null
@@ -0,0 +1,180 @@
+#include "colls_private.h"
+/* IMPLEMENTED BY PITCH PATARASUK 
+   Non-topoloty-specific (however, number of cores/node need to be changed) 
+   all-reduce operation designed for smp clusters
+   It uses 2-layer communication: binomial for intra-communication 
+   and rdb for inter-communication*/
+
+/* change number of core per smp-node
+   we assume that number of core per process will be the same for all implementations */
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+/* ** NOTE **
+   Use -DMPICH2 if this code does not compile.
+   MPICH1 code also work on MPICH2 on our cluster and the performance are similar.
+   This code assume commutative and associative reduce operator (MPI_SUM, MPI_MAX, etc).
+*/
+
+//#include <star-reduction.c>
+
+/*
+This fucntion performs all-reduce operation as follow.
+1) binomial_tree reduce inside each SMP node
+2) Recursive doubling intra-communication between root of each SMP node
+3) binomial_tree bcast inside each SMP node
+*/
+int smpi_coll_tuned_allreduce_smp_rdb(void *send_buf, void *recv_buf, int count,
+                                      MPI_Datatype dtype, MPI_Op op,
+                                      MPI_Comm comm)
+{
+  int comm_size, rank;
+  void *tmp_buf;
+  int tag = 50;
+  int mask, src, dst;
+  MPI_Status status;
+  int num_core = NUM_CORE;
+  /*
+     #ifdef MPICH2_REDUCTION
+     MPI_User_function * uop = MPIR_Op_table[op % 16 - 1];
+     #else
+     MPI_User_function *uop;
+     struct MPIR_OP *op_ptr;
+     op_ptr = MPIR_ToPointer(op);
+     uop  = op_ptr->op;
+     #endif
+   */
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  /* compute intra and inter ranking */
+  int intra_rank, inter_rank;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+
+  /* size of processes participate in intra communications =>
+     should be equal to number of machines */
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+
+  /* copy input buffer to output buffer */
+  smpi_mpi_sendrecv(send_buf, count, dtype, rank, tag,
+               recv_buf, count, dtype, rank, tag, comm, &status);
+
+  /* start binomial reduce intra communication inside each SMP node */
+  mask = 1;
+  while (mask < num_core) {
+    if ((mask & intra_rank) == 0) {
+      src = (inter_rank * num_core) + (intra_rank | mask);
+      if (src < comm_size) {
+        smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+      }
+    } else {
+      dst = (inter_rank * num_core) + (intra_rank & (~mask));
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+      break;
+    }
+    mask <<= 1;
+  }                             /* end binomial reduce intra-communication */
+
+
+  /* start rdb (recursive doubling) all-reduce inter-communication 
+     between each SMP nodes : each node only have one process that can communicate
+     to other nodes */
+  if (intra_rank == 0) {
+
+    /* find nearest power-of-two less than or equal to inter_comm_size */
+    int pof2, rem, newrank, newdst;
+    pof2 = 1;
+    while (pof2 <= inter_comm_size)
+      pof2 <<= 1;
+    pof2 >>= 1;
+    rem = inter_comm_size - pof2;
+
+    /* In the non-power-of-two case, all even-numbered
+       processes of rank < 2*rem send their data to
+       (rank+1). These even-numbered processes no longer
+       participate in the algorithm until the very end.
+     */
+    if (inter_rank < 2 * rem) {
+      if (inter_rank % 2 == 0) {
+        dst = rank + num_core;
+        smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+        newrank = -1;
+      } else {
+        src = rank - num_core;
+        smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        newrank = inter_rank / 2;
+      }
+    } else {
+      newrank = inter_rank - rem;
+    }
+
+    /* example inter-communication RDB rank change algorithm 
+       0,4,8,12..36 <= true rank (assume 4 core per SMP)
+       0123 4567 89 <= inter_rank
+       1 3 4567 89 (1,3 got data from 0,2 : 0,2 will be idle until the end)
+       0 1 4567 89 
+       0 1 2345 67 => newrank
+     */
+
+    if (newrank != -1) {
+      mask = 1;
+      while (mask < pof2) {
+        newdst = newrank ^ mask;
+        /* find real rank of dest */
+        dst = (newdst < rem) ? newdst * 2 + 1 : newdst + rem;
+        dst *= num_core;
+
+        /* exchange data in rdb manner */
+        smpi_mpi_sendrecv(recv_buf, count, dtype, dst, tag, tmp_buf, count, dtype,
+                     dst, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        mask <<= 1;
+      }
+    }
+
+    /* non pof2 case 
+       left-over processes (all even ranks: < 2 * rem) get the result    
+     */
+    if (inter_rank < 2 * rem) {
+      if (inter_rank % 2) {
+        smpi_mpi_send(recv_buf, count, dtype, rank - num_core, tag, comm);
+      } else {
+        smpi_mpi_recv(recv_buf, count, dtype, rank + num_core, tag, comm, &status);
+      }
+    }
+  }
+
+  /* start binomial broadcast intra-communication inside each SMP nodes */
+  int num_core_in_current_smp = num_core;
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * num_core);
+  }
+  mask = 1;
+  while (mask < num_core_in_current_smp) {
+    if (intra_rank & mask) {
+      src = (inter_rank * num_core) + (intra_rank - mask);
+      smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+      break;
+    }
+    mask <<= 1;
+  }
+  mask >>= 1;
+
+  while (mask > 0) {
+    dst = (inter_rank * num_core) + (intra_rank + mask);
+    if (dst < comm_size) {
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+    }
+    mask >>= 1;
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-smp-rsag-lr.c b/src/smpi/colls/allreduce-smp-rsag-lr.c
new file mode 100644 (file)
index 0000000..fd49327
--- /dev/null
@@ -0,0 +1,254 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+/* change number of core per smp-node
+   we assume that number of core per process will be the same for all implementations */
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+/*
+This fucntion performs all-reduce operation as follow.
+1) binomial_tree reduce inside each SMP node
+2) reduce-scatter -inter between root of each SMP node
+3) allgather - inter between root of each SMP node
+4) binomial_tree bcast inside each SMP node
+*/
+int smpi_coll_tuned_allreduce_smp_rsag_lr(void *send_buf, void *recv_buf,
+                                          int count, MPI_Datatype dtype,
+                                          MPI_Op op, MPI_Comm comm)
+{
+  int comm_size, rank;
+  void *tmp_buf;
+  int tag = 50;
+  int mask, src, dst;
+  MPI_Status status;
+  int num_core = NUM_CORE;
+  /*
+     #ifdef MPICH2_REDUCTION
+     MPI_User_function * uop = MPIR_Op_table[op % 16 - 1];
+     #else
+     MPI_User_function *uop;
+     struct MPIR_OP *op_ptr;
+     op_ptr = MPIR_ToPointer(op);
+     uop  = op_ptr->op;
+     #endif
+   */
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  int intra_rank, inter_rank;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+
+  //printf("node %d intra_rank = %d, inter_rank = %d\n", rank, intra_rank, inter_rank);
+
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+
+  if (!rank) {
+    //printf("intra com size = %d\n",num_core);
+    //printf("inter com size = %d\n",inter_comm_size);
+  }
+
+
+  smpi_mpi_sendrecv(send_buf, count, dtype, rank, tag,
+               recv_buf, count, dtype, rank, tag, comm, &status);
+
+
+  // SMP_binomial_reduce
+  mask = 1;
+  while (mask < num_core) {
+    if ((mask & intra_rank) == 0) {
+      src = (inter_rank * num_core) + (intra_rank | mask);
+      //      if (src < ((inter_rank + 1) * num_core)) {
+      if (src < comm_size) {
+        smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+      }
+    } else {
+
+      dst = (inter_rank * num_core) + (intra_rank & (~mask));
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+      break;
+    }
+    mask <<= 1;
+  }
+
+
+
+  // INTER: reduce-scatter
+  if (intra_rank == 0) {
+    int send_offset, recv_offset;
+    int send_count, recv_count;
+    int curr_size = count / inter_comm_size;
+    int curr_remainder = count % inter_comm_size;
+
+    int to = ((inter_rank + 1) % inter_comm_size) * num_core;
+    int from =
+        ((inter_rank + inter_comm_size - 1) % inter_comm_size) * num_core;
+    int i;
+
+    //printf("node %d to %d from %d\n",rank,to,from);
+
+    /* last segment may have a larger size since it also include the remainder */
+    int last_segment_ptr =
+        (inter_comm_size - 1) * (count / inter_comm_size) * extent;
+
+    for (i = 0; i < (inter_comm_size - 1); i++) {
+
+      send_offset =
+          ((inter_rank - 1 - i +
+            inter_comm_size) % inter_comm_size) * curr_size * extent;
+      recv_offset =
+          ((inter_rank - 2 - i +
+            inter_comm_size) % inter_comm_size) * curr_size * extent;
+
+      /* adjust size */
+      if (send_offset != last_segment_ptr)
+        send_count = curr_size;
+      else
+        send_count = curr_size + curr_remainder;
+
+      if (recv_offset != last_segment_ptr)
+        recv_count = curr_size;
+      else
+        recv_count = curr_size + curr_remainder;
+
+      smpi_mpi_sendrecv((char *) recv_buf + send_offset, send_count, dtype, to,
+                   tag + i, tmp_buf, recv_count, dtype, from, tag + i, comm,
+                   &status);
+
+      // result is in rbuf
+      smpi_op_apply(op, tmp_buf, (char *) recv_buf + recv_offset, &recv_count,
+                     &dtype);
+    }
+
+    // INTER: allgather
+    for (i = 0; i < (inter_comm_size - 1); i++) {
+
+      send_offset =
+          ((inter_rank - i +
+            inter_comm_size) % inter_comm_size) * curr_size * extent;
+      recv_offset =
+          ((inter_rank - 1 - i +
+            inter_comm_size) % inter_comm_size) * curr_size * extent;
+
+      /* adjust size */
+      if (send_offset != last_segment_ptr)
+        send_count = curr_size;
+      else
+        send_count = curr_size + curr_remainder;
+
+      if (recv_offset != last_segment_ptr)
+        recv_count = curr_size;
+      else
+        recv_count = curr_size + curr_remainder;
+
+      smpi_mpi_sendrecv((char *) recv_buf + send_offset, send_count, dtype, to,
+                   tag + i, (char *) recv_buf + recv_offset, recv_count, dtype,
+                   from, tag + i, comm, &status);
+
+    }
+  }
+
+
+
+  /*
+     // INTER_binomial_reduce
+
+     // only root node for each SMP
+     if (intra_rank == 0) {
+
+     mask = 1;
+     while (mask < inter_comm_size) {
+     if ((mask & inter_rank) == 0) {
+     src = (inter_rank | mask) * num_core;
+     if (src < comm_size) {
+     smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+     (* uop) (tmp_buf, recv_buf, &count, &dtype);
+     //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+     }
+     }
+     else {
+     dst = (inter_rank & (~mask)) * num_core;
+     smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+     //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+     break;
+     }
+     mask <<=1;
+     }
+     }
+   */
+
+  /*
+     // INTER_binomial_bcast
+
+
+     if (intra_rank == 0) {
+     mask = 1;
+     while (mask < inter_comm_size) {
+     if (inter_rank & mask) {
+     src = (inter_rank - mask) * num_core;
+     //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+     smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+     break;
+     }
+     mask <<= 1;
+     }
+
+     mask >>= 1;
+     //printf("My rank = %d my mask = %d\n", rank,mask);
+
+     while (mask > 0) {
+     if (inter_rank < inter_comm_size) {
+     dst = (inter_rank + mask) * num_core;
+     if (dst < comm_size) {
+     //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+     smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+     }
+     }
+     mask >>= 1;
+     }
+     }
+   */
+
+
+  // INTRA_binomial_bcast
+
+  int num_core_in_current_smp = num_core;
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * num_core);
+  }
+  //  printf("Node %d num_core = %d\n",rank, num_core_in_current_smp);
+  mask = 1;
+  while (mask < num_core_in_current_smp) {
+    if (intra_rank & mask) {
+      src = (inter_rank * num_core) + (intra_rank - mask);
+      //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+      smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  mask >>= 1;
+  //printf("My rank = %d my mask = %d\n", rank,mask);
+
+  while (mask > 0) {
+    dst = (inter_rank * num_core) + (intra_rank + mask);
+    if (dst < comm_size) {
+      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+    }
+    mask >>= 1;
+  }
+
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-smp-rsag-rab.c b/src/smpi/colls/allreduce-smp-rsag-rab.c
new file mode 100644 (file)
index 0000000..c98b78d
--- /dev/null
@@ -0,0 +1,205 @@
+#include "colls_private.h"
+/* 
+ * implemented by Pitch Patarasuk, 07/01/2007
+ */
+//#include <star-reduction.c>
+
+/* change number of core per smp-node
+   we assume that number of core per process will be the same for all implementations */
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+/*
+This fucntion performs all-reduce operation as follow.
+1) binomial_tree reduce inside each SMP node
+2) reduce-scatter -inter between root of each SMP node
+3) allgather - inter between root of each SMP node
+4) binomial_tree bcast inside each SMP node
+*/
+int smpi_coll_tuned_allreduce_smp_rsag_rab(void *sbuf, void *rbuf, int count,
+                                           MPI_Datatype dtype, MPI_Op op,
+                                           MPI_Comm comm)
+{
+  int comm_size, rank;
+  void *tmp_buf;
+  int tag = 50;
+  int mask, src, dst;
+  MPI_Status status;
+  int num_core = NUM_CORE;
+
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  int intra_rank, inter_rank;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+
+  //printf("node %d intra_rank = %d, inter_rank = %d\n", rank, intra_rank, inter_rank);
+
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+
+  smpi_mpi_sendrecv(sbuf, count, dtype, rank, tag,
+               rbuf, count, dtype, rank, tag, comm, &status);
+
+  // SMP_binomial_reduce
+  mask = 1;
+  while (mask < num_core) {
+    if ((mask & intra_rank) == 0) {
+      src = (inter_rank * num_core) + (intra_rank | mask);
+      //      if (src < ((inter_rank + 1) * num_core)) {
+      if (src < comm_size) {
+        smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, rbuf, &count, &dtype);
+        //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+      }
+    } else {
+
+      dst = (inter_rank * num_core) + (intra_rank & (~mask));
+      smpi_mpi_send(rbuf, count, dtype, dst, tag, comm);
+      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+      break;
+    }
+    mask <<= 1;
+  }
+
+
+  // INTER: reduce-scatter
+  if (intra_rank == 0) {
+
+    int dst, base_offset, send_base_offset, recv_base_offset, recv_chunk;
+    int curr_count, i, recv_offset, send_offset;
+
+    // reduce-scatter
+
+    recv_chunk = extent * count / (comm_size / num_core);
+
+    mask = 1;
+    i = 0;
+    curr_count = count / 2;
+    int phase = 0;
+    base_offset = 0;
+    send_base_offset = 0;
+    recv_base_offset = 0;
+
+    while (mask < (comm_size / num_core)) {
+      dst = inter_rank ^ mask;
+
+      // compute offsets
+      send_base_offset = base_offset;
+
+      // right-handside
+      if (inter_rank & mask) {
+        recv_base_offset = base_offset + curr_count;
+        send_base_offset = base_offset;
+        base_offset = recv_base_offset;
+      }
+      // left-handside
+      else {
+        recv_base_offset = base_offset;
+        send_base_offset = base_offset + curr_count;
+      }
+      send_offset = send_base_offset * extent;
+      recv_offset = recv_base_offset * extent;
+
+      //      if (rank==7)
+      //      printf("node %d send to %d in phase %d s_offset = %d r_offset = %d count = %d\n",rank,dst,phase, send_offset, recv_offset, curr_count);
+
+      smpi_mpi_sendrecv((char *)rbuf + send_offset, curr_count, dtype, (dst * num_core), tag,
+                   tmp_buf, curr_count, dtype, (dst * num_core), tag,
+                   comm, &status);
+
+      smpi_op_apply(op, tmp_buf, (char *)rbuf + recv_offset, &curr_count, &dtype);
+
+      mask *= 2;
+      curr_count /= 2;
+      phase++;
+    }
+
+
+    // INTER: allgather
+
+    int size = (comm_size / num_core) / 2;
+    base_offset = 0;
+    mask = 1;
+    while (mask < (comm_size / num_core)) {
+      if (inter_rank & mask) {
+        base_offset += size;
+      }
+      mask <<= 1;
+      size /= 2;
+    }
+
+    curr_count *= 2;
+    mask >>= 1;
+    i = 1;
+    phase = 0;
+    while (mask >= 1) {
+      // destination pair for both send and recv
+      dst = inter_rank ^ mask;
+
+      // compute offsets
+      send_base_offset = base_offset;
+      if (inter_rank & mask) {
+        recv_base_offset = base_offset - i;
+        base_offset -= i;
+      } else {
+        recv_base_offset = base_offset + i;
+      }
+      send_offset = send_base_offset * recv_chunk;
+      recv_offset = recv_base_offset * recv_chunk;
+
+      //      if (rank==7)
+      //printf("node %d send to %d in phase %d s_offset = %d r_offset = %d count = %d\n",rank,dst,phase, send_offset, recv_offset, curr_count);
+
+      smpi_mpi_sendrecv((char *)rbuf + send_offset, curr_count, dtype, (dst * num_core), tag,
+                   (char *)rbuf + recv_offset, curr_count, dtype, (dst * num_core), tag,
+                   comm, &status);
+
+
+      curr_count *= 2;
+      i *= 2;
+      mask >>= 1;
+      phase++;
+    }
+
+
+  }                             // INTER
+
+  // intra SMP binomial bcast
+
+  int num_core_in_current_smp = num_core;
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * num_core);
+  }
+  //  printf("Node %d num_core = %d\n",rank, num_core_in_current_smp);
+  mask = 1;
+  while (mask < num_core_in_current_smp) {
+    if (intra_rank & mask) {
+      src = (inter_rank * num_core) + (intra_rank - mask);
+      //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+      smpi_mpi_recv(rbuf, count, dtype, src, tag, comm, &status);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  mask >>= 1;
+  //printf("My rank = %d my mask = %d\n", rank,mask);
+
+  while (mask > 0) {
+    dst = (inter_rank * num_core) + (intra_rank + mask);
+    if (dst < comm_size) {
+      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+      smpi_mpi_send(rbuf, count, dtype, dst, tag, comm);
+    }
+    mask >>= 1;
+  }
+
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/allreduce-smp-rsag.c b/src/smpi/colls/allreduce-smp-rsag.c
new file mode 100644 (file)
index 0000000..24ccaa0
--- /dev/null
@@ -0,0 +1,224 @@
+#include "colls_private.h"
+
+/* change number of core per smp-node
+   we assume that number of core per process will be the same for all implementations */
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+/*
+This fucntion performs all-reduce operation as follow.
+1) binomial_tree reduce inside each SMP node
+2) reduce-scatter -inter between root of each SMP node
+3) allgather - inter between root of each SMP node
+4) binomial_tree bcast inside each SMP node
+*/
+int smpi_coll_tuned_allreduce_smp_rsag(void *send_buf, void *recv_buf,
+                                       int count, MPI_Datatype dtype, MPI_Op op,
+                                       MPI_Comm comm)
+{
+  int comm_size, rank;
+  void *tmp_buf;
+  int tag = 50;
+  int mask, src, dst;
+  MPI_Status status;
+  int num_core = NUM_CORE;
+  /*
+     #ifdef MPICH2_REDUCTION
+     MPI_User_function * uop = MPIR_Op_table[op % 16 - 1];
+     #else
+     MPI_User_function *uop;
+     struct MPIR_OP *op_ptr;
+     op_ptr = MPIR_ToPointer(op);
+     uop  = op_ptr->op;
+     #endif
+   */
+  comm_size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(dtype);
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  int intra_rank, inter_rank;
+  intra_rank = rank % num_core;
+  inter_rank = rank / num_core;
+
+  //printf("node %d intra_rank = %d, inter_rank = %d\n", rank, intra_rank, inter_rank);
+
+  int inter_comm_size = (comm_size + num_core - 1) / num_core;
+
+  if (!rank) {
+    //printf("intra com size = %d\n",num_core);
+    //printf("inter com size = %d\n",inter_comm_size);
+  }
+
+
+  smpi_mpi_sendrecv(send_buf, count, dtype, rank, tag,
+               recv_buf, count, dtype, rank, tag, comm, &status);
+
+
+  // SMP_binomial_reduce
+  mask = 1;
+  while (mask < num_core) {
+    if ((mask & intra_rank) == 0) {
+      src = (inter_rank * num_core) + (intra_rank | mask);
+      //      if (src < ((inter_rank + 1) * num_core)) {
+      if (src < comm_size) {
+        smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+      }
+    } else {
+
+      dst = (inter_rank * num_core) + (intra_rank & (~mask));
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+      break;
+    }
+    mask <<= 1;
+  }
+
+
+
+  // INTER: reduce-scatter
+  if (intra_rank == 0) {
+    int send_offset, recv_offset;
+    int seg_count = count / inter_comm_size;
+    int to = ((inter_rank + 1) % inter_comm_size) * num_core;
+    int from =
+        ((inter_rank + inter_comm_size - 1) % inter_comm_size) * num_core;
+    int i;
+
+    //printf("node %d to %d from %d\n",rank,to,from);
+
+    for (i = 0; i < (inter_comm_size - 1); i++) {
+
+      send_offset =
+          ((inter_rank - 1 - i +
+            inter_comm_size) % inter_comm_size) * seg_count * extent;
+      recv_offset =
+          ((inter_rank - 2 - i +
+            inter_comm_size) % inter_comm_size) * seg_count * extent;
+
+      smpi_mpi_sendrecv((char *) recv_buf + send_offset, seg_count, dtype, to,
+                   tag + i, tmp_buf, seg_count, dtype, from, tag + i, comm,
+                   &status);
+
+      // result is in rbuf
+      smpi_op_apply(op, tmp_buf, (char *) recv_buf + recv_offset, &seg_count,
+                     &dtype);
+    }
+
+    // INTER: allgather
+    for (i = 0; i < (inter_comm_size - 1); i++) {
+
+      send_offset =
+          ((inter_rank - i +
+            inter_comm_size) % inter_comm_size) * seg_count * extent;
+      recv_offset =
+          ((inter_rank - 1 - i +
+            inter_comm_size) % inter_comm_size) * seg_count * extent;
+
+      smpi_mpi_sendrecv((char *) recv_buf + send_offset, seg_count, dtype, to,
+                   tag + i, (char *) recv_buf + recv_offset, seg_count, dtype,
+                   from, tag + i, comm, &status);
+
+    }
+  }
+
+
+
+  /*
+     // INTER_binomial_reduce
+
+     // only root node for each SMP
+     if (intra_rank == 0) {
+
+     mask = 1;
+     while (mask < inter_comm_size) {
+     if ((mask & inter_rank) == 0) {
+     src = (inter_rank | mask) * num_core;
+     if (src < comm_size) {
+     smpi_mpi_recv(tmp_buf, count, dtype, src, tag, comm, &status);
+     (* uop) (tmp_buf, recv_buf, &count, &dtype);
+     //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+     }
+     }
+     else {
+     dst = (inter_rank & (~mask)) * num_core;
+     smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+     //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+     break;
+     }
+     mask <<=1;
+     }
+     }
+   */
+
+  /*
+     // INTER_binomial_bcast
+
+
+     if (intra_rank == 0) {
+     mask = 1;
+     while (mask < inter_comm_size) {
+     if (inter_rank & mask) {
+     src = (inter_rank - mask) * num_core;
+     //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+     smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+     break;
+     }
+     mask <<= 1;
+     }
+
+     mask >>= 1;
+     //printf("My rank = %d my mask = %d\n", rank,mask);
+
+     while (mask > 0) {
+     if (inter_rank < inter_comm_size) {
+     dst = (inter_rank + mask) * num_core;
+     if (dst < comm_size) {
+     //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+     smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+     }
+     }
+     mask >>= 1;
+     }
+     }
+   */
+
+
+  // INTRA_binomial_bcast
+
+  int num_core_in_current_smp = num_core;
+  if (inter_rank == (inter_comm_size - 1)) {
+    num_core_in_current_smp = comm_size - (inter_rank * num_core);
+  }
+  //  printf("Node %d num_core = %d\n",rank, num_core_in_current_smp);
+  mask = 1;
+  while (mask < num_core_in_current_smp) {
+    if (intra_rank & mask) {
+      src = (inter_rank * num_core) + (intra_rank - mask);
+      //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
+      smpi_mpi_recv(recv_buf, count, dtype, src, tag, comm, &status);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  mask >>= 1;
+  //printf("My rank = %d my mask = %d\n", rank,mask);
+
+  while (mask > 0) {
+    dst = (inter_rank * num_core) + (intra_rank + mask);
+    if (dst < comm_size) {
+      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
+      smpi_mpi_send(recv_buf, count, dtype, dst, tag, comm);
+    }
+    mask >>= 1;
+  }
+
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
index 1e1e408..61ea21e 100644 (file)
@@ -1,7 +1,5 @@
-#include "colls.h"
+#include "colls_private.h"
 #include <math.h>
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_colls, smpi,
-                                "Logging specific to SMPI collectives");
 
 /*****************************************************************************
 
@@ -26,179 +24,147 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_colls, smpi,
  * Auther: Ahmad Faraj
 
 ****************************************************************************/
-int alltoall_check_is_2dmesh(int num, int * i, int * j)
+static int alltoall_check_is_2dmesh(int num, int *i, int *j)
 {
   int x, max = num / 2;
-  x = sqrt(num);  
-
-  while (x <= max)
-    {
-      if ((num % x) == 0)
-       {
-         * i = x;
-         * j = num / x;
-       
-         if (* i > * j)
-           {
-             x = * i;
-             * i = * j;
-             * j = x;
-           }
-       
-         return 1;
-       }
-      x++;
+  x = sqrt(num);
+
+  while (x <= max) {
+    if ((num % x) == 0) {
+      *i = x;
+      *j = num / x;
+
+      if (*i > *j) {
+        x = *i;
+        *i = *j;
+        *j = x;
+      }
+
+      return 1;
     }
+    x++;
+  }
   return 0;
 }
 
-int
-smpi_coll_tuned_alltoall_2dmesh(void * send_buff, int send_count, MPI_Datatype send_type,
-                     void * recv_buff, int recv_count, MPI_Datatype recv_type,
-                     MPI_Comm comm)
+int smpi_coll_tuned_alltoall_2dmesh(void *send_buff, int send_count,
+                                    MPI_Datatype send_type,
+                                    void *recv_buff, int recv_count,
+                                    MPI_Datatype recv_type, MPI_Comm comm)
 {
-  MPI_Status * statuses, s;
-  MPI_Request * reqs, * req_ptr;;
+  MPI_Status *statuses, s;
+  MPI_Request *reqs, *req_ptr;;
   MPI_Aint extent;
 
-  char * tmp_buff1, * tmp_buff2;
+  char *tmp_buff1, *tmp_buff2;
   int i, j, src, dst, rank, num_procs, count, num_reqs;
-  int rows, cols, my_row, my_col, X, Y, send_offset, recv_offset;
-  int two_dsize, my_row_base, my_col_base, src_row_base, block_size;
-  int tag = 1, failure = 0, success = 1;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &extent);
+  int X, Y, send_offset, recv_offset;
+  int my_row_base, my_col_base, src_row_base, block_size;
+  int tag = 1;
 
-  if (!alltoall_check_is_2dmesh(num_procs, &X, &Y))
-    return failure;
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
 
-  two_dsize = X * Y;
+  if (!alltoall_check_is_2dmesh(num_procs, &X, &Y))
+    return MPI_ERR_OTHER;
 
   my_row_base = (rank / Y) * Y;
   my_col_base = rank % Y;
 
   block_size = extent * send_count;
-  
-  tmp_buff1 =(char *) malloc(block_size * num_procs * Y);
-  if (!tmp_buff1)
-    {
-      XBT_DEBUG("alltoall-2dmesh_shoot.c:88: cannot allocate memory");
-      MPI_Finalize();
-      exit(failure);
-    }  
-
-  tmp_buff2 =(char *) malloc(block_size *  Y);  
-  if (!tmp_buff2)
-    {
-      XBT_WARN("alltoall-2dmesh_shoot.c:88: cannot allocate memory");
-      MPI_Finalize();
-      exit(failure);
-    }
-  
 
+  tmp_buff1 = (char *) xbt_malloc(block_size * num_procs * Y);
+  tmp_buff2 = (char *) xbt_malloc(block_size * Y);
 
   num_reqs = X;
-  if (Y > X) num_reqs = Y;
-
-  statuses = (MPI_Status *) malloc(num_reqs * sizeof(MPI_Status));  
-  reqs = (MPI_Request *) malloc(num_reqs * sizeof(MPI_Request));  
-  if (!reqs)
-    {
-      XBT_WARN("alltoall-2dmesh_shoot.c:88: cannot allocate memory");
-      MPI_Finalize();
-      exit(failure);
-    }
-  
+  if (Y > X)
+    num_reqs = Y;
+
+  statuses = (MPI_Status *) xbt_malloc(num_reqs * sizeof(MPI_Status));
+  reqs = (MPI_Request *) xbt_malloc(num_reqs * sizeof(MPI_Request));
+
   req_ptr = reqs;
 
   send_offset = recv_offset = (rank % Y) * block_size * num_procs;
 
   count = send_count * num_procs;
-  
-  for (i = 0; i < Y; i++)
-    {
-      src = i + my_row_base;
-      if (src == rank)
-       continue;
-
-      recv_offset = (src % Y) * block_size * num_procs;
-       MPI_Irecv(tmp_buff1 + recv_offset, count, recv_type, src, tag, comm,
-                req_ptr++);
-    }
-  
-  for (i = 0; i < Y; i++)
-    {
-      dst = i + my_row_base;
-      if (dst == rank)
-       continue;
-       MPI_Send(send_buff, count, send_type, dst, tag, comm);
-    }
-  
-  MPI_Waitall(Y - 1, reqs, statuses);
+
+  for (i = 0; i < Y; i++) {
+    src = i + my_row_base;
+    if (src == rank)
+      continue;
+
+    recv_offset = (src % Y) * block_size * num_procs;
+    *(req_ptr++) = smpi_mpi_irecv(tmp_buff1 + recv_offset, count, recv_type, src, tag, comm);
+  }
+
+  for (i = 0; i < Y; i++) {
+    dst = i + my_row_base;
+    if (dst == rank)
+      continue;
+    smpi_mpi_send(send_buff, count, send_type, dst, tag, comm);
+  }
+
+  smpi_mpi_waitall(Y - 1, reqs, statuses);
   req_ptr = reqs;
-  
-  for (i = 0; i < Y; i++)
-    {
-      send_offset = (rank * block_size) + (i * block_size * num_procs);
-      recv_offset = (my_row_base * block_size) + (i * block_size);
-     
-      if (i + my_row_base == rank) 
-       MPI_Sendrecv (send_buff + recv_offset, send_count, send_type,
-                     rank, tag, recv_buff + recv_offset, recv_count,
-                     recv_type, rank, tag, comm, &s);
-
-     else 
-         MPI_Sendrecv (tmp_buff1 + send_offset, send_count, send_type,
-                      rank, tag, 
-                      recv_buff + recv_offset, recv_count, recv_type,
-                      rank, tag, comm, &s);
-    }
 
-  
-  for (i = 0; i < X; i++)
-  {
-     src = (i * Y + my_col_base);
-     if (src == rank)
-       continue;
-     src_row_base = (src / Y) * Y;
+  for (i = 0; i < Y; i++) {
+    send_offset = (rank * block_size) + (i * block_size * num_procs);
+    recv_offset = (my_row_base * block_size) + (i * block_size);
+
+    if (i + my_row_base == rank)
+      smpi_mpi_sendrecv((char *) send_buff + recv_offset, send_count, send_type,
+                   rank, tag,
+                   (char *) recv_buff + recv_offset, recv_count, recv_type,
+                   rank, tag, comm, &s);
+
+    else
+      smpi_mpi_sendrecv(tmp_buff1 + send_offset, send_count, send_type,
+                   rank, tag,
+                   (char *) recv_buff + recv_offset, recv_count, recv_type,
+                   rank, tag, comm, &s);
+  }
+
+
+  for (i = 0; i < X; i++) {
+    src = (i * Y + my_col_base);
+    if (src == rank)
+      continue;
+    src_row_base = (src / Y) * Y;
 
-      MPI_Irecv(recv_buff + src_row_base * block_size, recv_count * Y,
-               recv_type, src, tag, comm, req_ptr++);
+    *(req_ptr++) = smpi_mpi_irecv((char *) recv_buff + src_row_base * block_size, recv_count * Y,
+              recv_type, src, tag, comm);
   }
-  
-  for (i = 0; i < X; i++)
-    {
-      dst = (i * Y + my_col_base);
-      if (dst == rank)
-       continue;
-
-      recv_offset = 0;
-      for (j = 0; j < Y; j++)
-       {
-         send_offset = (dst + j * num_procs) * block_size;
-
-         if (j + my_row_base == rank) 
-            MPI_Sendrecv (send_buff + dst * block_size, send_count, send_type,
-                          rank, tag, 
-                          tmp_buff2 + recv_offset, recv_count, recv_type,
-                          rank, tag, comm, &s);
-         else
-            MPI_Sendrecv (tmp_buff1 + send_offset, send_count, send_type,
-                          rank, tag, 
-                          tmp_buff2 + recv_offset, recv_count, recv_type,
-                          rank, tag, comm, &s);
-         
-         recv_offset += block_size;
-       }
-
-       MPI_Send(tmp_buff2, send_count * Y, send_type, dst, tag, comm);
+
+  for (i = 0; i < X; i++) {
+    dst = (i * Y + my_col_base);
+    if (dst == rank)
+      continue;
+
+    recv_offset = 0;
+    for (j = 0; j < Y; j++) {
+      send_offset = (dst + j * num_procs) * block_size;
+
+      if (j + my_row_base == rank)
+        smpi_mpi_sendrecv((char *) send_buff + dst * block_size, send_count,
+                     send_type, rank, tag, tmp_buff2 + recv_offset, recv_count,
+                     recv_type, rank, tag, comm, &s);
+      else
+        smpi_mpi_sendrecv(tmp_buff1 + send_offset, send_count, send_type,
+                     rank, tag,
+                     tmp_buff2 + recv_offset, recv_count, recv_type,
+                     rank, tag, comm, &s);
+
+      recv_offset += block_size;
     }
-  MPI_Waitall(X - 1, reqs, statuses);
+
+    smpi_mpi_send(tmp_buff2, send_count * Y, send_type, dst, tag, comm);
+  }
+  smpi_mpi_waitall(X - 1, reqs, statuses);
   free(reqs);
   free(statuses);
   free(tmp_buff1);
-  free(tmp_buff2);  
-  return success;
+  free(tmp_buff2);
+  return MPI_SUCCESS;
 }
index afd47ce..ca10de7 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 #include <math.h>
 
 /*****************************************************************************
  * Auther: Ahmad Faraj
 ****************************************************************************/
 
-int alltoall_check_is_3dmesh(int num, int * i, int * j, int * k)
+static int alltoall_check_is_3dmesh(int num, int *i, int *j, int *k)
 {
   int x, max = num / 3;
-  x = cbrt(num);  
-  * i = * j = * k = 0;
-  while (x <= max)
-    {
-      if ((num % (x * x)) == 0)
-       {
-         * i = * j = x;
-         * k = num / (x * x);
-         return 1;
-       }
-      x++;
+  x = cbrt(num);
+  *i = *j = *k = 0;
+  while (x <= max) {
+    if ((num % (x * x)) == 0) {
+      *i = *j = x;
+      *k = num / (x * x);
+      return 1;
     }
+    x++;
+  }
   return 0;
 }
 
-int smpi_coll_tuned_alltoall_3dmesh(void * send_buff, int send_count, MPI_Datatype send_type,
-                     void * recv_buff, int recv_count, MPI_Datatype recv_type,
-                     MPI_Comm comm)
+int smpi_coll_tuned_alltoall_3dmesh(void *send_buff, int send_count,
+                                    MPI_Datatype send_type,
+                                    void *recv_buff, int recv_count,
+                                    MPI_Datatype recv_type, MPI_Comm comm)
 {
-  MPI_Request * reqs, * req_ptr;
+  MPI_Request *reqs, *req_ptr;
   MPI_Aint extent;
-  MPI_Status status, * statuses;
+  MPI_Status status, *statuses;
   int i, j, src, dst, rank, num_procs, num_reqs, X, Y, Z, block_size, count;
   int my_z, two_dsize, my_row_base, my_col_base, my_z_base, src_row_base;
-  int src_z_base, send_offset, recv_offset, tag = 1, failure = 0, success = 1;
+  int src_z_base, send_offset, recv_offset, tag = 1;
 
-  char * tmp_buff1, * tmp_buff2;
+  char *tmp_buff1, *tmp_buff2;
 
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &extent);
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(send_type);
 
   if (!alltoall_check_is_3dmesh(num_procs, &X, &Y, &Z))
-     return failure;
+    return MPI_ERR_OTHER;
 
   num_reqs = X;
-  if (Y > X) num_reqs = Y;
-  if (Z > Y) num_reqs = Z;
+  if (Y > X)
+    num_reqs = Y;
+  if (Z > Y)
+    num_reqs = Z;
 
   two_dsize = X * Y;
-  my_z = rank / two_dsize;  
+  my_z = rank / two_dsize;
 
   my_row_base = (rank / X) * X;
   my_col_base = (rank % Y) + (my_z * two_dsize);
@@ -75,129 +76,105 @@ int smpi_coll_tuned_alltoall_3dmesh(void * send_buff, int send_count, MPI_Dataty
 
   block_size = extent * send_count;
 
-  tmp_buff1 =(char *) malloc(block_size * num_procs * two_dsize);
-  if (!tmp_buff1)
-    {
-      printf("alltoall-3Dmesh:97: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
-  
-  tmp_buff2 =(char *) malloc(block_size *  two_dsize);
-  if (!tmp_buff2)
-    {
-      printf("alltoall-3Dmesh:105: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
-  
-  statuses = (MPI_Status *) malloc(num_reqs * sizeof(MPI_Status));  
-  reqs = (MPI_Request *) malloc(num_reqs * sizeof(MPI_Request));  
-  if (!reqs)
-    {
-      printf("alltoall-3Dmesh:113: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
-  
+  tmp_buff1 = (char *) xbt_malloc(block_size * num_procs * two_dsize);
+  tmp_buff2 = (char *) xbt_malloc(block_size * two_dsize);
+
+  statuses = (MPI_Status *) xbt_malloc(num_reqs * sizeof(MPI_Status));
+  reqs = (MPI_Request *) xbt_malloc(num_reqs * sizeof(MPI_Request));
+
   req_ptr = reqs;
-  
+
   send_offset = recv_offset = (rank % two_dsize) * block_size * num_procs;
 
-  MPI_Sendrecv(send_buff, send_count * num_procs, send_type, rank, tag, 
-              tmp_buff1 + recv_offset, num_procs * recv_count,
-              recv_type, rank, tag, comm, &status);
+  smpi_mpi_sendrecv(send_buff, send_count * num_procs, send_type, rank, tag,
+               tmp_buff1 + recv_offset, num_procs * recv_count,
+               recv_type, rank, tag, comm, &status);
 
   count = send_count * num_procs;
 
-  for (i = 0; i < Y; i++)
-    {
-      src = i + my_row_base;
-      if (src == rank) continue;
-      recv_offset = (src % two_dsize) * block_size * num_procs;
-      MPI_Irecv(tmp_buff1 + recv_offset, count, recv_type, src, tag, comm,
-               req_ptr++);
-    }
+  for (i = 0; i < Y; i++) {
+    src = i + my_row_base;
+    if (src == rank)
+      continue;
+    recv_offset = (src % two_dsize) * block_size * num_procs;
+    *(req_ptr++) = smpi_mpi_irecv(tmp_buff1 + recv_offset, count, recv_type, src, tag, comm);
+  }
 
-  for (i = 0; i < Y; i++)
-    {
-      dst = i + my_row_base;
-      if (dst == rank) continue;
-      MPI_Send(send_buff, count, send_type, dst, tag, comm);
-    }  
+  for (i = 0; i < Y; i++) {
+    dst = i + my_row_base;
+    if (dst == rank)
+      continue;
+    smpi_mpi_send(send_buff, count, send_type, dst, tag, comm);
+  }
 
-  MPI_Waitall(Y - 1, reqs, statuses);
+  smpi_mpi_waitall(Y - 1, reqs, statuses);
   req_ptr = reqs;
-  
-
-  for (i = 0; i < X; i++)
-    {
-      src = (i * Y + my_col_base);
-      if (src == rank) continue;
-     
-      src_row_base = (src / X) * X;
-
-      recv_offset = (src_row_base % two_dsize) * block_size * num_procs;
-      MPI_Irecv(tmp_buff1 + recv_offset, recv_count * num_procs * Y,
-                recv_type, src, tag, comm, req_ptr++);
-    }
 
-  send_offset = (my_row_base % two_dsize) * block_size * num_procs;  
-  for (i = 0; i < X; i++)
-    {
-      dst = (i * Y + my_col_base);
-      if (dst == rank) continue;
-      MPI_Send(tmp_buff1 + send_offset, send_count * num_procs * Y, send_type,
-               dst, tag, comm);
-    }
-  
-  MPI_Waitall(X - 1, reqs, statuses);
+
+  for (i = 0; i < X; i++) {
+    src = (i * Y + my_col_base);
+    if (src == rank)
+      continue;
+
+    src_row_base = (src / X) * X;
+
+    recv_offset = (src_row_base % two_dsize) * block_size * num_procs;
+    *(req_ptr++) = smpi_mpi_irecv(tmp_buff1 + recv_offset, recv_count * num_procs * Y,
+              recv_type, src, tag, comm);
+  }
+
+  send_offset = (my_row_base % two_dsize) * block_size * num_procs;
+  for (i = 0; i < X; i++) {
+    dst = (i * Y + my_col_base);
+    if (dst == rank)
+      continue;
+    smpi_mpi_send(tmp_buff1 + send_offset, send_count * num_procs * Y, send_type,
+             dst, tag, comm);
+  }
+
+  smpi_mpi_waitall(X - 1, reqs, statuses);
   req_ptr = reqs;
 
-  for (i = 0; i < two_dsize; i++)
-    {
-      send_offset = (rank * block_size) + (i * block_size * num_procs);
-      recv_offset = (my_z_base * block_size) + (i * block_size);
-      MPI_Sendrecv(tmp_buff1 + send_offset, send_count, send_type, rank, tag,
-                  recv_buff + recv_offset, recv_count, recv_type, rank, tag,
-                  comm, &status);
-    }  
+  for (i = 0; i < two_dsize; i++) {
+    send_offset = (rank * block_size) + (i * block_size * num_procs);
+    recv_offset = (my_z_base * block_size) + (i * block_size);
+    smpi_mpi_sendrecv(tmp_buff1 + send_offset, send_count, send_type, rank, tag,
+                 (char *) recv_buff + recv_offset, recv_count, recv_type,
+                 rank, tag, comm, &status);
+  }
 
-  for (i = 1; i < Z; i++)
-    {
-      src = (rank + i * two_dsize) % num_procs;
-      src_z_base = (src / two_dsize) * two_dsize;
+  for (i = 1; i < Z; i++) {
+    src = (rank + i * two_dsize) % num_procs;
+    src_z_base = (src / two_dsize) * two_dsize;
 
-      recv_offset = (src_z_base * block_size);
+    recv_offset = (src_z_base * block_size);
 
-      MPI_Irecv(recv_buff + recv_offset, recv_count * two_dsize, recv_type,
-                src, tag, comm, req_ptr++);
+    *(req_ptr++) = smpi_mpi_irecv((char *) recv_buff + recv_offset, recv_count * two_dsize,
+              recv_type, src, tag, comm);
   }
 
-  for (i = 1; i < Z; i++)
-    {
-      dst = (rank + i * two_dsize) % num_procs;
-     
-      recv_offset = 0;
-      for (j = 0; j < two_dsize; j++)
-       {
-         send_offset = (dst + j * num_procs) * block_size;
-         MPI_Sendrecv(tmp_buff1 + send_offset, send_count, send_type,
-                      rank, tag, tmp_buff2 + recv_offset, recv_count,
-                      recv_type, rank, tag, comm, &status);
-         
-         recv_offset += block_size;
-       }
-
-      MPI_Send(tmp_buff2, send_count * two_dsize, send_type, dst, tag, comm);
-      
+  for (i = 1; i < Z; i++) {
+    dst = (rank + i * two_dsize) % num_procs;
+
+    recv_offset = 0;
+    for (j = 0; j < two_dsize; j++) {
+      send_offset = (dst + j * num_procs) * block_size;
+      smpi_mpi_sendrecv(tmp_buff1 + send_offset, send_count, send_type,
+                   rank, tag, tmp_buff2 + recv_offset, recv_count,
+                   recv_type, rank, tag, comm, &status);
+
+      recv_offset += block_size;
     }
-  
-  MPI_Waitall(Z - 1, reqs, statuses);
+
+    smpi_mpi_send(tmp_buff2, send_count * two_dsize, send_type, dst, tag, comm);
+
+  }
+
+  smpi_mpi_waitall(Z - 1, reqs, statuses);
 
   free(reqs);
   free(statuses);
   free(tmp_buff1);
   free(tmp_buff2);
-  return success;
+  return MPI_SUCCESS;
 }
index 5745f2f..d38b3e5 100644 (file)
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_bruck(void * send_buff, int send_count, MPI_Datatype send_type,
-              void * recv_buff, int recv_count, MPI_Datatype recv_type,
-              MPI_Comm comm)
+smpi_coll_tuned_alltoall_bruck(void *send_buff, int send_count,
+                               MPI_Datatype send_type, void *recv_buff,
+                               int recv_count, MPI_Datatype recv_type,
+                               MPI_Comm comm)
 {
   MPI_Status status;
   MPI_Aint extent;
   MPI_Datatype new_type;
-  int * blocks_length, * disps;
+
+  int *blocks_length, *disps;
   int i, src, dst, rank, num_procs, count, remainder, block, position;
-  int pack_size, tag = 1, pof2 = 1, success = 1, failure = 0;
-  
-
-  char * tmp_buff;  
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Comm_rank(comm, &rank);
-
-  MPI_Type_extent(recv_type, &extent);
-
-  tmp_buff = (char *) malloc (num_procs * recv_count * extent); 
-  if (!tmp_buff)
-    {
-      printf("alltoall-bruck:53: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
-
-  disps = (int *) malloc(sizeof(int) * num_procs);
-  if (!disps)
-    {
-      printf("alltoall-bruck:61: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
-  
-  blocks_length = (int *) malloc(sizeof(int) * num_procs);  
-  if (!blocks_length)
-    {
-      printf("alltoall-bruck:69: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
-
-  
-  MPI_Sendrecv(send_ptr + rank * send_count * extent,
-               (num_procs - rank) * send_count, send_type, rank, tag,
-               recv_ptr, (num_procs - rank) * recv_count, recv_type, rank,
-               tag, comm, &status);
-
-  MPI_Sendrecv(send_ptr, rank * send_count, send_type, rank, tag,
-               recv_ptr + (num_procs - rank) * recv_count * extent,
-               rank * recv_count, recv_type, rank, tag, comm, &status);  
-
-
-
-  MPI_Pack_size(send_count * num_procs, send_type, comm, &pack_size); 
-
-  while (pof2 < num_procs)
-    {
-      dst = (rank + pof2) % num_procs;
-      src = (rank - pof2 + num_procs) % num_procs;
-
-              
-      count = 0;
-      for (block = 1; block < num_procs; block++)
-       if (block & pof2) 
-         {
-           blocks_length[count] = send_count;
-           disps[count] = block * send_count;
-           count++;
-         }
-          
-      MPI_Type_indexed(count, blocks_length, disps, recv_type, &new_type);
-      MPI_Type_commit(&new_type);
-      
-      position = 0;
-      MPI_Pack(recv_buff, 1, new_type, tmp_buff, pack_size, &position, comm);
-      
-      MPI_Sendrecv(tmp_buff, position, MPI_PACKED, dst, tag, recv_buff, 1,
-                   new_type, src, tag, comm, &status);
-      MPI_Type_free(&new_type);
-      
-      pof2 *= 2;
-    }
+  int pack_size, tag = 1, pof2 = 1;
+
+
+  char *tmp_buff;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  num_procs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  extent = smpi_datatype_get_extent(recv_type);
+
+  tmp_buff = (char *) xbt_malloc(num_procs * recv_count * extent);
+  disps = (int *) xbt_malloc(sizeof(int) * num_procs);
+  blocks_length = (int *) xbt_malloc(sizeof(int) * num_procs);
+
+  smpi_mpi_sendrecv(send_ptr + rank * send_count * extent,
+               (num_procs - rank) * send_count, send_type, rank, tag,
+               recv_ptr, (num_procs - rank) * recv_count, recv_type, rank,
+               tag, comm, &status);
+
+  smpi_mpi_sendrecv(send_ptr, rank * send_count, send_type, rank, tag,
+               recv_ptr + (num_procs - rank) * recv_count * extent,
+               rank * recv_count, recv_type, rank, tag, comm, &status);
+
+
+
+  MPI_Pack_size(send_count * num_procs, send_type, comm, &pack_size);
+
+  while (pof2 < num_procs) {
+    dst = (rank + pof2) % num_procs;
+    src = (rank - pof2 + num_procs) % num_procs;
+
+
+    count = 0;
+    for (block = 1; block < num_procs; block++)
+      if (block & pof2) {
+        blocks_length[count] = send_count;
+        disps[count] = block * send_count;
+        count++;
+      }
+
+    MPI_Type_indexed(count, blocks_length, disps, recv_type, &new_type);
+    smpi_datatype_commit(&new_type);
+
+    position = 0;
+    MPI_Pack(recv_buff, 1, new_type, tmp_buff, pack_size, &position, comm);
+
+    smpi_mpi_sendrecv(tmp_buff, position, MPI_PACKED, dst, tag, recv_buff, 1,
+                 new_type, src, tag, comm, &status);
+    smpi_datatype_free(&new_type);
+
+    pof2 *= 2;
+  }
 
   free(disps);
   free(blocks_length);
-  
-  MPI_Sendrecv(recv_ptr + (rank + 1) * recv_count * extent,
-              (num_procs - rank - 1) * recv_count, send_type,
-               rank, tag, tmp_buff, (num_procs - rank - 1) * recv_count,
-               recv_type, rank, tag, comm, &status);
-  
-  MPI_Sendrecv(recv_ptr, (rank + 1) * recv_count, send_type, rank, tag,
-               tmp_buff + (num_procs - rank - 1) * recv_count * extent,
-               (rank + 1) * recv_count, recv_type, rank, tag, comm, &status);
-
-      
-  for (i = 0; i < num_procs; i++) 
-    MPI_Sendrecv(tmp_buff + i * recv_count * extent, recv_count, send_type,
-                 rank, tag,
-                 recv_ptr + (num_procs - i - 1) * recv_count * extent,
-                 recv_count, recv_type, rank, tag, comm, &status);
+
+  smpi_mpi_sendrecv(recv_ptr + (rank + 1) * recv_count * extent,
+               (num_procs - rank - 1) * recv_count, send_type,
+               rank, tag, tmp_buff, (num_procs - rank - 1) * recv_count,
+               recv_type, rank, tag, comm, &status);
+
+  smpi_mpi_sendrecv(recv_ptr, (rank + 1) * recv_count, send_type, rank, tag,
+               tmp_buff + (num_procs - rank - 1) * recv_count * extent,
+               (rank + 1) * recv_count, recv_type, rank, tag, comm, &status);
+
+
+  for (i = 0; i < num_procs; i++)
+    smpi_mpi_sendrecv(tmp_buff + i * recv_count * extent, recv_count, send_type,
+                 rank, tag,
+                 recv_ptr + (num_procs - i - 1) * recv_count * extent,
+                 recv_count, recv_type, rank, tag, comm, &status);
 
   free(tmp_buff);
-  return success;
+  return MPI_SUCCESS;
 }
diff --git a/src/smpi/colls/alltoall-native.c b/src/smpi/colls/alltoall-native.c
deleted file mode 100644 (file)
index 8f6137b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-int
-alltoall_native(void * send_buff, int send_count,
-               MPI_Datatype send_type, void * recv_buff,
-               int recv_count, MPI_Datatype recv_type,
-               MPI_Comm comm)
-{
-  return MPI_Alltoall(send_buff, send_count, send_type, recv_buff, recv_count,
-                     recv_type, comm);
-}
index e6ab92a..96cf68d 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_pair_light_barrier
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_pair_light_barrier(void * send_buff, int send_count,
-                           MPI_Datatype send_type, void * recv_buff,
-                           int recv_count, MPI_Datatype recv_type,
-                           MPI_Comm comm)
+smpi_coll_tuned_alltoall_pair_light_barrier(void *send_buff, int send_count,
+                                            MPI_Datatype send_type,
+                                            void *recv_buff, int recv_count,
+                                            MPI_Datatype recv_type,
+                                            MPI_Comm comm)
 {
   MPI_Aint send_chunk, recv_chunk;
   MPI_Status s;
   int i, src, dst, rank, num_procs, next_partner;
-  int tag = 1, success = 1; /*, failure = 0;*/
+  int tag = 1;     /*, failure = 0; */
 
   char send_sync = 'a', recv_sync = 'b';
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
   recv_chunk *= recv_count;
 
-  MPI_Sendrecv(send_ptr + rank * send_chunk, send_count, send_type, rank, tag,
-              recv_ptr + rank * recv_chunk, recv_count, recv_type, rank, tag,
-              comm, &s);
+  smpi_mpi_sendrecv(send_ptr + rank * send_chunk, send_count, send_type, rank, tag,
+               recv_ptr + rank * recv_chunk, recv_count, recv_type, rank, tag,
+               comm, &s);
+
+  for (i = 1; i < num_procs; i++) {
+    src = dst = rank ^ i;
 
-  for (i = 1; i < num_procs; i++)
-    {
-      src = dst = rank ^ i;
-      
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type,
-                  dst, tag, recv_ptr + src * recv_chunk, recv_count,
-                  recv_type, src, tag, comm, &s);
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type,
+                 dst, tag, recv_ptr + src * recv_chunk, recv_count,
+                 recv_type, src, tag, comm, &s);
 
-      if ((i + 1) < num_procs)
-       {
-         next_partner = rank ^ (i + 1);
-         MPI_Sendrecv(&send_sync, 1, MPI_CHAR, next_partner, tag,
-                      &recv_sync, 1, MPI_CHAR, next_partner, tag,
-                      comm, &s);       
-       }
+    if ((i + 1) < num_procs) {
+      next_partner = rank ^ (i + 1);
+      smpi_mpi_sendrecv(&send_sync, 1, MPI_CHAR, next_partner, tag,
+                   &recv_sync, 1, MPI_CHAR, next_partner, tag, comm, &s);
     }
-  return success;
+  }
+  return MPI_SUCCESS;
 }
index fcad564..f12c3f9 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_pair_mpi_barrier
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_pair_mpi_barrier(void * send_buff, int send_count,
-                         MPI_Datatype send_type, void * recv_buff,
-                         int recv_count, MPI_Datatype recv_type,
-                         MPI_Comm comm)
+smpi_coll_tuned_alltoall_pair_mpi_barrier(void *send_buff, int send_count,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int recv_count,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
 {
   MPI_Status s;
   MPI_Aint send_chunk, recv_chunk;
   int i, src, dst, rank, num_procs;
-  int tag = 101, success = 1; /*, failure = 0, pof2 = 1;*/
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  int tag = 101;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
-
-  for (i = 0; i < num_procs; i++)
-    {
-      src = dst = rank ^ i;     
-      MPI_Barrier(comm);      
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
-                  tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
-                  src, tag, comm, &s);
-    }
-  return success;
+  recv_chunk *= recv_count;
+
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_barrier(comm);
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
+                 tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
+                 src, tag, comm, &s);
+  }
+  return MPI_SUCCESS;
 }
index 478b881..19e693d 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_pair
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_pair_one_barrier(void * send_buff, int send_count, MPI_Datatype send_type,
-                         void * recv_buff, int recv_count, MPI_Datatype recv_type,
-                         MPI_Comm comm)
+smpi_coll_tuned_alltoall_pair_one_barrier(void *send_buff, int send_count,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int recv_count,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
 {
 
   MPI_Aint send_chunk, recv_chunk;
   MPI_Status s;
   int i, src, dst, rank, num_procs;
-  int tag = 1, success = 1; /*, failure = 0, pof2 = 1; */
+  int tag = 1;
 
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
-
-  MPI_Barrier(comm);
-  for (i = 0; i < num_procs; i++)
-    {
-      src = dst = rank ^ i;     
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
-                  tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
-                  src, tag, comm, &s);
-    }
-
-  return success;
+  recv_chunk *= recv_count;
+
+  smpi_mpi_barrier(comm);
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
+                 tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
+                 src, tag, comm, &s);
+  }
+
+  return MPI_SUCCESS;
 }
index 83658e0..24ef5f7 100644 (file)
@@ -1,4 +1,5 @@
-#include "smpi/mpi.h"
+#include "colls_private.h"
+
 /*****************************************************************************
 
  * Function: alltoall_pair
 
  ****************************************************************************/
 /*
-int
-alltoall_pair(void * send_buff, int send_count, MPI_Datatype send_type,
-             void * recv_buff, int recv_count, MPI_Datatype recv_type,
-             MPI_Comm comm)
+int alltoall_pair(void *send_buff, int send_count, MPI_Datatype send_type,
+                  void *recv_buff, int recv_count, MPI_Datatype recv_type,
+                  MPI_Comm comm)
 {
 
   MPI_Aint send_chunk, recv_chunk;
@@ -34,62 +34,58 @@ alltoall_pair(void * send_buff, int send_count, MPI_Datatype send_type,
   int i, src, dst, rank, num_procs;
   int tag = 1, success = 1, failure = 0, pof2 = 1;
 
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
-  MPI_Win_create(recv_buff, num_procs*recv_chunk*send_count,recv_chunk,0,
-                comm, &win);
+  MPI_Win_create(recv_buff, num_procs * recv_chunk * send_count, recv_chunk, 0,
+                 comm, &win);
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
+  recv_chunk *= recv_count;
 
   MPI_Win_fence(assert, win);
-  for (i = 0; i < num_procs; i++)
-    {
-      src = dst = rank ^ i;
-      MPI_Put(send_ptr + dst * send_chunk, send_count, send_type, dst,
-             rank*send_chunk, send_count, send_type, win);
-    }
-  MPI_Win_fence (assert, win);
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    MPI_Put(send_ptr + dst * send_chunk, send_count, send_type, dst,
+            rank * send_chunk, send_count, send_type, win);
+  }
+  MPI_Win_fence(assert, win);
   MPI_Win_free(&win);
   return 0;
 }
 */
 
-int
-smpi_coll_tuned_alltoall_pair(void * send_buff, int send_count, MPI_Datatype send_type,
-             void * recv_buff, int recv_count, MPI_Datatype recv_type,
-             MPI_Comm comm)
+int smpi_coll_tuned_alltoall_pair(void *send_buff, int send_count,
+                                  MPI_Datatype send_type,
+                                  void *recv_buff, int recv_count,
+                                  MPI_Datatype recv_type, MPI_Comm comm)
 {
 
   MPI_Aint send_chunk, recv_chunk;
   MPI_Status s;
   int i, src, dst, rank, num_procs;
-  int tag = 1, success = 1;
+  int tag = 1;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
 
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
+  recv_chunk *= recv_count;
 
-  for (i = 0; i < num_procs; i++)
-    {
-      src = dst = rank ^ i;     
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
-                  tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
-                  src, tag, comm, &s);
-    }
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst, tag,
+                recv_ptr + src * recv_chunk, recv_count, recv_type, src, tag,
+                comm, &s);
+  }
 
-  return success;
+  return MPI_SUCCESS;
 }
-
index b5bd8a5..45b529f 100644 (file)
@@ -1,4 +1,5 @@
-#include "colls.h"
+#include "colls_private.h"
+
 /*****************************************************************************
 
  * Function: alltoall_rdb
  * Auther: MPICH / slightly modified by Ahmad Faraj.  
 
  ****************************************************************************/
-int
-smpi_coll_tuned_alltoall_rdb(void * send_buff, int send_count, MPI_Datatype send_type,
-            void * recv_buff, int recv_count, MPI_Datatype recv_type,
-            MPI_Comm comm)
+int smpi_coll_tuned_alltoall_rdb(void *send_buff, int send_count,
+                                 MPI_Datatype send_type,
+                                 void *recv_buff, int recv_count,
+                                 MPI_Datatype recv_type, MPI_Comm comm)
 {
   /* MPI variables */
   MPI_Status status;
@@ -31,130 +32,117 @@ smpi_coll_tuned_alltoall_rdb(void * send_buff, int send_count, MPI_Datatype send
 
   int dst_tree_root, rank_tree_root, send_offset, recv_offset;
   int rank, num_procs, j, k, dst, curr_size, max_size;
-  int last_recv_count, tmp_mask, tree_root, num_procs_completed;
-  int tag = 1, mask = 1, success = 1, failure = 0, c = 0, i = 0;
+  int last_recv_count = 0, tmp_mask, tree_root, num_procs_completed;
+  int tag = 1, mask = 1, i = 0;
 
-  char * tmp_buff;
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
+  char *tmp_buff;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
 
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Comm_rank(comm, &rank);
-  MPI_Type_extent(send_type, &send_increment);
-  MPI_Type_extent(recv_type, &recv_increment);
-  MPI_Type_extent(recv_type, &extent);
+  num_procs = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  send_increment = smpi_datatype_get_extent(send_type);
+  recv_increment = smpi_datatype_get_extent(recv_type);
+  extent = smpi_datatype_get_extent(recv_type);
 
   send_increment *= (send_count * num_procs);
   recv_increment *= (recv_count * num_procs);
-   
+
   max_size = num_procs * recv_increment;
-  tmp_buff = (char * ) malloc(max_size);
-  if (!tmp_buff)
-    {
-      printf("alltoall-rdb:56: cannot allocate memory\n");
-      MPI_Finalize();
-      exit(failure);
-    }
+
+  tmp_buff = (char *) xbt_malloc(max_size);
 
   curr_size = send_count * num_procs;
 
-  MPI_Sendrecv(send_ptr, curr_size, send_type, rank, tag,
+  smpi_mpi_sendrecv(send_ptr, curr_size, send_type, rank, tag,
                tmp_buff + (rank * recv_increment),
                curr_size, recv_type, rank, tag, comm, &status);
 
-  while (mask < num_procs)
-    {
-      dst = rank ^ mask;
-      dst_tree_root = dst >> i;
-      dst_tree_root <<= i;
-      rank_tree_root = rank >> i;
-      rank_tree_root <<= i;
-      send_offset = rank_tree_root * send_increment;
-      recv_offset = dst_tree_root * recv_increment;
-
-      if (dst < num_procs)
-       {
-         MPI_Sendrecv(tmp_buff + send_offset, curr_size, send_type, dst, tag,
-                       tmp_buff + recv_offset, mask * recv_count * num_procs,
-                       recv_type, dst, tag, comm, &status);
-
-         MPI_Get_count(&status, recv_type, &last_recv_count);
-         curr_size += last_recv_count;
-       }
-     
-     
-      if (dst_tree_root + mask > num_procs)
-       {
-
-         num_procs_completed = num_procs - rank_tree_root - mask;
-         /* num_procs_completed is the number of processes in this
-            subtree that have all the data. Send data to others
-            in a tree fashion. First find root of current tree
-            that is being divided into two. k is the number of
-            least-significant bits in this process's rank that
-            must be zeroed out to find the rank of the root */
-
-         j = mask;
-         k = 0;
-         while (j)
-           {
-             j >>= 1;
-             k++;
-           }
-         k--;
-
-         tmp_mask = mask >> 1;
-                  
-         while (tmp_mask)
-           {
-             dst = rank ^ tmp_mask;
-                      
-             tree_root = rank >> k;
-             tree_root <<= k;
-                      
-             /* send only if this proc has data and destination
-                doesn't have data. at any step, multiple processes
-                can send if they have the data */
-
-             if ((dst > rank)
-                 && (rank < tree_root + num_procs_completed)
-                 && (dst >= tree_root + num_procs_completed))
-               {
-                 MPI_Send(tmp_buff + dst_tree_root * send_increment,
-                           last_recv_count, send_type, dst, tag, comm);
-
-               }
-          
-             /* recv only if this proc. doesn't have data and sender
-                has data */
-                     
-             else if ((dst < rank)
-                      && (dst < tree_root + num_procs_completed)
-                      && (rank >= tree_root + num_procs_completed))
-               {
-                 MPI_Recv(tmp_buff + dst_tree_root * send_increment,
-                           mask * num_procs * send_count, send_type, dst,
-                           tag, comm, &status);
-
-                 MPI_Get_count(&status, send_type, &last_recv_count);
-                 curr_size += last_recv_count;
-               }
-
-             tmp_mask >>= 1;
-             k--;
-           }
-       }
-
-      mask <<= 1;
-      i++;
+  while (mask < num_procs) {
+    dst = rank ^ mask;
+    dst_tree_root = dst >> i;
+    dst_tree_root <<= i;
+    rank_tree_root = rank >> i;
+    rank_tree_root <<= i;
+    send_offset = rank_tree_root * send_increment;
+    recv_offset = dst_tree_root * recv_increment;
+
+    if (dst < num_procs) {
+      smpi_mpi_sendrecv(tmp_buff + send_offset, curr_size, send_type, dst, tag,
+                   tmp_buff + recv_offset, mask * recv_count * num_procs,
+                   recv_type, dst, tag, comm, &status);
+
+      last_recv_count = smpi_mpi_get_count(&status, recv_type);
+      curr_size += last_recv_count;
+    }
+
+
+    if (dst_tree_root + mask > num_procs) {
+
+      num_procs_completed = num_procs - rank_tree_root - mask;
+      /* num_procs_completed is the number of processes in this
+         subtree that have all the data. Send data to others
+         in a tree fashion. First find root of current tree
+         that is being divided into two. k is the number of
+         least-significant bits in this process's rank that
+         must be zeroed out to find the rank of the root */
+
+      j = mask;
+      k = 0;
+      while (j) {
+        j >>= 1;
+        k++;
+      }
+      k--;
+
+      tmp_mask = mask >> 1;
+
+      while (tmp_mask) {
+        dst = rank ^ tmp_mask;
+
+        tree_root = rank >> k;
+        tree_root <<= k;
+
+        /* send only if this proc has data and destination
+           doesn't have data. at any step, multiple processes
+           can send if they have the data */
+
+        if ((dst > rank)
+            && (rank < tree_root + num_procs_completed)
+            && (dst >= tree_root + num_procs_completed)) {
+          smpi_mpi_send(tmp_buff + dst_tree_root * send_increment,
+                   last_recv_count, send_type, dst, tag, comm);
+
+        }
+
+        /* recv only if this proc. doesn't have data and sender
+           has data */
+
+        else if ((dst < rank)
+                 && (dst < tree_root + num_procs_completed)
+                 && (rank >= tree_root + num_procs_completed)) {
+          smpi_mpi_recv(tmp_buff + dst_tree_root * send_increment,
+                   mask * num_procs * send_count, send_type, dst,
+                   tag, comm, &status);
+
+          last_recv_count = smpi_mpi_get_count(&status, send_type);
+          curr_size += last_recv_count;
+        }
+
+        tmp_mask >>= 1;
+        k--;
+      }
     }
 
+    mask <<= 1;
+    i++;
+  }
+
   for (i = 0; i < num_procs; i++)
-     MPI_Sendrecv(tmp_buff + (rank + i * num_procs) * send_count * extent,
-                   send_count, send_type, rank, tag,
-                   recv_ptr + (i * recv_count * extent),
-                   recv_count, recv_type, rank, tag, comm, &status);
+    smpi_mpi_sendrecv(tmp_buff + (rank + i * num_procs) * send_count * extent,
+                 send_count, send_type, rank, tag,
+                 recv_ptr + (i * recv_count * extent),
+                 recv_count, recv_type, rank, tag, comm, &status);
   free(tmp_buff);
-  return success;
+  return MPI_SUCCESS;
 }
index 2508ed1..d45912b 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_ring_light_barrier
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_ring_light_barrier(void * send_buff, int send_count,
-                           MPI_Datatype send_type, void * recv_buff,
-                           int recv_count, MPI_Datatype recv_type,
-                           MPI_Comm comm)
+smpi_coll_tuned_alltoall_ring_light_barrier(void *send_buff, int send_count,
+                                            MPI_Datatype send_type,
+                                            void *recv_buff, int recv_count,
+                                            MPI_Datatype recv_type,
+                                            MPI_Comm comm)
 {
   MPI_Aint send_chunk, recv_chunk;
   MPI_Status s;
   int i, src, dst, rank, num_procs, next_dst, next_src;
-  int tag = 1, success = 1; /*, failure = 0;*/
+  int tag = 1;
 
   char send_sync = 'a', recv_sync = 'b';
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
   recv_chunk *= recv_count;
 
-  MPI_Sendrecv(send_ptr + rank * send_chunk, send_count, send_type, rank, tag,
-              recv_ptr + rank * recv_chunk, recv_count, recv_type, rank, tag,
-              comm, &s);
+  smpi_mpi_sendrecv(send_ptr + rank * send_chunk, send_count, send_type, rank, tag,
+               recv_ptr + rank * recv_chunk, recv_count, recv_type, rank, tag,
+               comm, &s);
+
+  for (i = 1; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type,
+                 dst, tag, recv_ptr + src * recv_chunk, recv_count,
+                 recv_type, src, tag, comm, &s);
 
-  for (i = 1; i < num_procs; i++)
-    {
-      src = (rank - i + num_procs) % num_procs;
-      dst = (rank + i) % num_procs;
-      
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type,
-                  dst, tag, recv_ptr + src * recv_chunk, recv_count,
-                  recv_type, src, tag, comm, &s);
+    if ((i + 1) < num_procs) {
+      next_src = (rank - (i + 1) + num_procs) % num_procs;
+      next_dst = (rank + (i + 1) + num_procs) % num_procs;
+      smpi_mpi_sendrecv(&send_sync, 1, MPI_CHAR, next_src, tag,
+                   &recv_sync, 1, MPI_CHAR, next_dst, tag, comm, &s);
 
-      if ((i + 1) < num_procs)
-       {
-         next_src = (rank - (i + 1) + num_procs) % num_procs;
-         next_dst = (rank + (i + 1) + num_procs) % num_procs;
-         MPI_Sendrecv(&send_sync, 1, MPI_CHAR, next_src, tag,
-                      &recv_sync, 1, MPI_CHAR, next_dst, tag,
-                      comm, &s);
-         
-       }
     }
+  }
 
-  return success;
+  return MPI_SUCCESS;
 }
index c5621b3..e3a3f2d 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_ring_mpi_barrier
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_ring_mpi_barrier(void * send_buff, int send_count,
-                           MPI_Datatype send_type, void * recv_buff,
-                           int recv_count, MPI_Datatype recv_type,
-                           MPI_Comm comm)
+smpi_coll_tuned_alltoall_ring_mpi_barrier(void *send_buff, int send_count,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int recv_count,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
 {
   MPI_Status s;
   MPI_Aint send_chunk, recv_chunk;
   int i, src, dst, rank, num_procs;
-  int tag = 1, success = 1; /*, failure = 0, pof2 = 1;*/
+  int tag = 1;
 
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
-
-  for (i = 0; i < num_procs; i++)
-    {
-      src = (rank - i + num_procs) % num_procs;
-      dst = (rank + i) % num_procs;
-      
-      MPI_Barrier(comm);
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
-                  tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
-                  src, tag, comm, &s);
-    }
-
-  return success;
+  recv_chunk *= recv_count;
+
+  for (i = 0; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_barrier(comm);
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
+                 tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
+                 src, tag, comm, &s);
+  }
+
+  return MPI_SUCCESS;
 }
index 13bedcb..97b912b 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_ring
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_ring_one_barrier(void * send_buff, int send_count, MPI_Datatype send_type,
-                         void * recv_buff, int recv_count, MPI_Datatype recv_type,
-                         MPI_Comm comm)
+smpi_coll_tuned_alltoall_ring_one_barrier(void *send_buff, int send_count,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int recv_count,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
 {
   MPI_Status s;
   MPI_Aint send_chunk, recv_chunk;
   int i, src, dst, rank, num_procs;
-  int tag = 1, success = 1; /*, failure = 0, pof2 = 1; */
+  int tag = 1;
 
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
-
-  MPI_Barrier(comm);
-  for (i = 0; i < num_procs; i++)
-    {
-      src = (rank - i + num_procs) % num_procs;
-      dst = (rank + i) % num_procs;
-      
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
-                  tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
-                  src, tag, comm, &s);
-    }
-  return success;
+  recv_chunk *= recv_count;
+
+  smpi_mpi_barrier(comm);
+  for (i = 0; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
+                 tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
+                 src, tag, comm, &s);
+  }
+  return MPI_SUCCESS;
 }
index e5e4e2b..622fd9d 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 /*****************************************************************************
 
  * Function: alltoall_ring
 
  ****************************************************************************/
 int
-smpi_coll_tuned_alltoall_ring(void * send_buff, int send_count, MPI_Datatype send_type,
-             void * recv_buff, int recv_count, MPI_Datatype recv_type,
-             MPI_Comm comm)
+smpi_coll_tuned_alltoall_ring(void *send_buff, int send_count,
+                              MPI_Datatype send_type, void *recv_buff,
+                              int recv_count, MPI_Datatype recv_type,
+                              MPI_Comm comm)
 {
   MPI_Status s;
   MPI_Aint send_chunk, recv_chunk;
   int i, src, dst, rank, num_procs;
-  int tag = 1, success = 1; /*, failure = 0, pof2 = 1*/;
+  int tag = 11;
 
-  char * send_ptr = (char *) send_buff;
-  char * recv_ptr = (char *) recv_buff;
-  
-  MPI_Comm_rank(comm, &rank);
-  MPI_Comm_size(comm, &num_procs);
-  MPI_Type_extent(send_type, &send_chunk);
-  MPI_Type_extent(recv_type, &recv_chunk);
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
 
   send_chunk *= send_count;
-  recv_chunk *= recv_count;  
-
-  for (i = 0; i < num_procs; i++)
-    {
-      src = (rank - i + num_procs) % num_procs;
-      dst = (rank + i) % num_procs;
-      
-      MPI_Sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
-                  tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
-                  src, tag, comm, &s);
-    }
-  return success;
+  recv_chunk *= recv_count;
+
+  for (i = 0; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_sendrecv(send_ptr + dst * send_chunk, send_count, send_type, dst,
+                 tag, recv_ptr + src * recv_chunk, recv_count, recv_type,
+                 src, tag, comm, &s);
+  }
+  return MPI_SUCCESS;
 }
index df2be4e..fa50a8c 100644 (file)
@@ -1,4 +1,4 @@
-#include "colls.h"
+#include "colls_private.h"
 
 /*****************************************************************************
 
  * Auther: Ahmad Faraj
 
  ****************************************************************************/
-int
-smpi_coll_tuned_alltoall_simple(void * send_buff, int send_count,
-               MPI_Datatype send_type, void * recv_buff,
-               int recv_count, MPI_Datatype recv_type,
-               MPI_Comm comm)
+int smpi_coll_tuned_alltoall_simple(void *send_buff, int send_count,
+                                    MPI_Datatype send_type,
+                                    void *recv_buff, int recv_count,
+                                    MPI_Datatype recv_type, MPI_Comm comm)
 {
-  int i, rank, size, nreqs, err, src, dst, tag = 101;
+  int i, rank, size, nreqs, src, dst, tag = 101;
   char *psnd;
   char *prcv;
   MPI_Aint sndinc;
@@ -36,91 +35,67 @@ smpi_coll_tuned_alltoall_simple(void * send_buff, int send_count,
   MPI_Request *req;
   MPI_Request *preq;
   MPI_Request *qreq;
-  MPI_Status s, * statuses;
+  MPI_Status s, *statuses;
 
 
-  MPI_Comm_size(comm, &size);
-  MPI_Comm_rank(comm, &rank);
-  MPI_Type_extent(send_type, &sndinc);
-  MPI_Type_extent(recv_type, &rcvinc);
+  size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+  sndinc = smpi_datatype_get_extent(send_type);
+  rcvinc = smpi_datatype_get_extent(recv_type);
   sndinc *= send_count;
   rcvinc *= recv_count;
 
   /* Allocate arrays of requests. */
 
   nreqs = 2 * (size - 1);
-  if (nreqs > 0)
-    {
-      req = (MPI_Request *) malloc(nreqs * sizeof(MPI_Request));
-      statuses = (MPI_Status *) malloc(nreqs * sizeof(MPI_Status));
-      if (!req || !statuses)
-       {
-         free(req);
-         free(statuses);
-         return 0;
-       }
-    }
-  else
-    req = 0;
+  if (nreqs > 0) {
+    req = (MPI_Request *) xbt_malloc(nreqs * sizeof(MPI_Request));
+    statuses = (MPI_Status *) xbt_malloc(nreqs * sizeof(MPI_Status));
+  } else {
+    req = NULL;
+    statuses = NULL;
+  }
 
   /* simple optimization */
 
   psnd = ((char *) send_buff) + (rank * sndinc);
   prcv = ((char *) recv_buff) + (rank * rcvinc);
-  MPI_Sendrecv (psnd, send_count, send_type, rank, tag,
-               prcv, recv_count, recv_type,
-               rank, tag, comm, &s);
+  smpi_mpi_sendrecv(psnd, send_count, send_type, rank, tag,
+               prcv, recv_count, recv_type, rank, tag, comm, &s);
 
 
   /* Initiate all send/recv to/from others. */
 
   preq = req;
   qreq = req + size - 1;
-  prcv = (char*) recv_buff;
-  psnd = (char*) send_buff;
-  for (i = 0; i < size; i++)
-    {
-      src = dst = (rank + i) % size;
-      if (src == rank) continue;
-      if (dst == rank) continue;      
-      MPI_Recv_init(prcv + (src * rcvinc), recv_count, recv_type, src,
-                   tag, comm, preq++);
-      MPI_Send_init(psnd + (dst * sndinc), send_count, send_type, dst,
-                   tag, comm, qreq++);
-    }
+  prcv = (char *) recv_buff;
+  psnd = (char *) send_buff;
+  for (i = 0; i < size; i++) {
+    src = dst = (rank + i) % size;
+    if (src == rank)
+      continue;
+    if (dst == rank)
+      continue;
+    *(preq++) = smpi_mpi_recv_init(prcv + (src * rcvinc), recv_count, recv_type, src,
+                  tag, comm);
+    *(qreq++) = smpi_mpi_send_init(psnd + (dst * sndinc), send_count, send_type, dst,
+                  tag, comm);
+  }
 
   /* Start all the requests. */
 
-  err = MPI_Startall(nreqs, req);
+  smpi_mpi_startall(nreqs, req);
 
   /* Wait for them all. */
 
-  err = MPI_Waitall(nreqs, req, statuses);
+  smpi_mpi_waitall(nreqs, req, statuses);
 
-  if (err != MPI_SUCCESS) {
-    if (req)
-      free((char *) req);
-    return err;
-  }
-
-  for (i = 0, preq = req; i < nreqs; ++i, ++preq) {
-    err = MPI_Request_free(preq);
-    if (err != MPI_SUCCESS) {
-      if (req)
-       free((char *) req);
-      if (statuses)
-       free(statuses);
-      return err;
-    }
-  }
 
   /* All done */
 
   if (req)
-    free((char *) req);
+    xbt_free((char *) req);
   if (statuses)
-    free(statuses);
-  return (1);
+    xbt_free(statuses);
+  return MPI_SUCCESS;
 }
-
-
diff --git a/src/smpi/colls/alltoallv-bruck.c b/src/smpi/colls/alltoallv-bruck.c
new file mode 100644 (file)
index 0000000..0296798
--- /dev/null
@@ -0,0 +1,70 @@
+#include "colls_private.h"
+
+/**
+ * Alltoall Bruck
+ *
+ * Openmpi calls this routine when the message size sent to each rank < 2000 bytes and size < 12
+ * FIXME: uh, check smpi_pmpi again, but this routine is called for > 12, not
+ * less...
+ **/
+int smpi_coll_tuned_alltoallv_bruck(void *sendbuf, int *sendcounts, int *senddisps,
+                                   MPI_Datatype sendtype, void *recvbuf,
+                                   int *recvcounts, int *recvdisps, MPI_Datatype recvtype,
+                                   MPI_Comm comm)
+{
+  int system_tag = 777;
+  int i, rank, size, err, count;
+  MPI_Aint lb;
+  MPI_Aint sendext = 0;
+  MPI_Aint recvext = 0;
+  MPI_Request *requests;
+
+  // FIXME: check implementation
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+  XBT_DEBUG("<%d> algorithm alltoall_bruck() called.", rank);
+
+  err = smpi_datatype_extent(sendtype, &lb, &sendext);
+  err = smpi_datatype_extent(recvtype, &lb, &recvext);
+  /* Local copy from self */
+  err =
+      smpi_datatype_copy((char *)sendbuf + senddisps[rank] * sendext, 
+                         sendcounts[rank], sendtype, 
+                         (char *)recvbuf + recvdisps[rank] * recvext,
+                         recvcounts[rank], recvtype);
+  if (err == MPI_SUCCESS && size > 1) {
+    /* Initiate all send/recv to/from others. */
+    requests = xbt_new(MPI_Request, 2 * (size - 1));
+    count = 0;
+    /* Create all receives that will be posted first */
+    for (i = 0; i < size; ++i) {
+      if (i == rank) {
+        XBT_DEBUG("<%d> skip request creation [src = %d, recvcount = %d]",
+               rank, i, recvcounts[i]);
+        continue;
+      }
+      requests[count] =
+          smpi_irecv_init((char *)recvbuf + recvdisps[i] * recvext, recvcounts[i],
+                          recvtype, i, system_tag, comm);
+      count++;
+    }
+    /* Now create all sends  */
+    for (i = 0; i < size; ++i) {
+      if (i == rank) {
+        XBT_DEBUG("<%d> skip request creation [dst = %d, sendcount = %d]",
+               rank, i, sendcounts[i]);
+        continue;
+      }
+      requests[count] =
+          smpi_isend_init((char *)sendbuf + senddisps[i] * sendext, sendcounts[i],
+                          sendtype, i, system_tag, comm);
+      count++;
+    }
+    /* Wait for them all. */
+    smpi_mpi_startall(count, requests);
+    XBT_DEBUG("<%d> wait for %d requests", rank, count);
+    smpi_mpi_waitall(count, requests, MPI_STATUS_IGNORE);
+    xbt_free(requests);
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-pair-light-barrier.c b/src/smpi/colls/alltoallv-pair-light-barrier.c
new file mode 100644 (file)
index 0000000..45a864b
--- /dev/null
@@ -0,0 +1,63 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_pair_light_barrier
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works in P - 1 steps. In step i, node j exchanges data
+           with node i ^ j. Light barriers are inserted between
+           communications in different phases.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_pair_light_barrier(void *send_buff, int *send_counts, int *send_disps,
+                                            MPI_Datatype send_type,
+                                            void *recv_buff, int *recv_counts, int *recv_disps,
+                                            MPI_Datatype recv_type,
+                                            MPI_Comm comm)
+{
+  MPI_Aint send_chunk, recv_chunk;
+  MPI_Status s;
+  int i, src, dst, rank, num_procs, next_partner;
+  int tag = 1;     /*, failure = 0; */
+
+  char send_sync = 'a', recv_sync = 'b';
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  smpi_mpi_sendrecv(send_ptr + send_disps[rank] * send_chunk, send_counts[rank], send_type, rank, tag,
+               recv_ptr + recv_disps[rank] * recv_chunk, recv_counts[rank], recv_type, rank, tag,
+               comm, &s);
+
+  for (i = 1; i < num_procs; i++) {
+    src = dst = rank ^ i;
+
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type,
+                 dst, tag, recv_ptr + recv_disps[src] *recv_chunk, recv_counts[dst],
+                 recv_type, src, tag, comm, &s);
+
+    if ((i + 1) < num_procs) {
+      next_partner = rank ^ (i + 1);
+      smpi_mpi_sendrecv(&send_sync, 1, MPI_CHAR, next_partner, tag,
+                   &recv_sync, 1, MPI_CHAR, next_partner, tag, comm, &s);
+    }
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-pair-mpi-barrier.c b/src/smpi/colls/alltoallv-pair-mpi-barrier.c
new file mode 100644 (file)
index 0000000..9944493
--- /dev/null
@@ -0,0 +1,50 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_pair_mpi_barrier
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works when P is power of two. In each phase of P - 1
+           phases, nodes in pair communicate their data. MPI barriers are
+           inserted between each two phases.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_pair_mpi_barrier(void *send_buff, int *send_counts, int *send_disps,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int *recv_counts, int *recv_disps,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
+{
+  MPI_Status s;
+  MPI_Aint send_chunk, recv_chunk;
+  int i, src, dst, rank, num_procs;
+  int tag = 101;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_barrier(comm);
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type, dst,
+                 tag, recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src], recv_type,
+                 src, tag, comm, &s);
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-pair-one-barrier.c b/src/smpi/colls/alltoallv-pair-one-barrier.c
new file mode 100644 (file)
index 0000000..ab1f48e
--- /dev/null
@@ -0,0 +1,51 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_pair
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works when P is power of two. In each phase of P - 1
+           phases, nodes in pair communicate their data.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_pair_one_barrier(void *send_buff, int *send_counts, int *send_disps,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff,  int *recv_counts, int *recv_disps,                                                                                  MPI_Datatype recv_type, MPI_Comm comm)
+{
+
+  MPI_Aint send_chunk, recv_chunk;
+  MPI_Status s;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  smpi_mpi_barrier(comm);
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type, dst,
+                 tag, recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src], recv_type,
+                 src, tag, comm, &s);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-pair.c b/src/smpi/colls/alltoallv-pair.c
new file mode 100644 (file)
index 0000000..50839df
--- /dev/null
@@ -0,0 +1,49 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+ * Function: alltoall_pair
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works when P is power of two. In each phase of P - 1
+           phases, nodes in pair communicate their data.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int smpi_coll_tuned_alltoallv_pair(void *send_buff, int *send_counts, int *send_disps,
+                                  MPI_Datatype send_type,
+                                  void *recv_buff, int *recv_counts, int *recv_disps,
+                                  MPI_Datatype recv_type, MPI_Comm comm)
+{
+
+  MPI_Aint send_chunk, recv_chunk;
+  MPI_Status s;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  for (i = 0; i < num_procs; i++) {
+    src = dst = rank ^ i;
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type, dst, tag,
+                recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src], recv_type, src, tag,
+                comm, &s);
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-ring-light-barrier.c b/src/smpi/colls/alltoallv-ring-light-barrier.c
new file mode 100644 (file)
index 0000000..7a42ab9
--- /dev/null
@@ -0,0 +1,67 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_ring_light_barrier
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works in P - 1 steps. In step i, node j - i -> j -> j + i.
+           Light barriers are inserted between communications in different
+           phases.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_ring_light_barrier(void *send_buff, int *send_counts, int *send_disps,
+                                            MPI_Datatype send_type,
+                                            void *recv_buff, int *recv_counts, int *recv_disps,
+                                            MPI_Datatype recv_type,
+                                            MPI_Comm comm)
+{
+  MPI_Aint send_chunk, recv_chunk;
+  MPI_Status s;
+  int i, src, dst, rank, num_procs, next_dst, next_src;
+  int tag = 1;
+
+  char send_sync = 'a', recv_sync = 'b';
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  smpi_mpi_sendrecv(send_ptr + send_disps[rank] * send_chunk, send_counts[rank], send_type, rank, tag,
+               recv_ptr + recv_disps[rank] * recv_chunk, recv_counts[rank], recv_type, rank, tag,
+               comm, &s);
+
+  for (i = 1; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type,
+                 dst, tag, recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src],
+                 recv_type, src, tag, comm, &s);
+
+    if ((i + 1) < num_procs) {
+      next_src = (rank - (i + 1) + num_procs) % num_procs;
+      next_dst = (rank + (i + 1) + num_procs) % num_procs;
+      smpi_mpi_sendrecv(&send_sync, 1, MPI_CHAR, next_src, tag,
+                   &recv_sync, 1, MPI_CHAR, next_dst, tag, comm, &s);
+
+    }
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-ring-mpi-barrier.c b/src/smpi/colls/alltoallv-ring-mpi-barrier.c
new file mode 100644 (file)
index 0000000..273f15c
--- /dev/null
@@ -0,0 +1,53 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_ring_mpi_barrier
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works in P - 1 steps. In step i, node j - i -> j -> j + i.
+           MPI barriers are added between each two phases.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_ring_mpi_barrier(void *send_buff, int *send_counts, int *send_disps,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int *recv_counts, int *recv_disps,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
+{
+  MPI_Status s;
+  MPI_Aint send_chunk, recv_chunk;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  for (i = 0; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_barrier(comm);
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type, dst,
+                 tag, recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src], recv_type,
+                 src, tag, comm, &s);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-ring-one-barrier.c b/src/smpi/colls/alltoallv-ring-one-barrier.c
new file mode 100644 (file)
index 0000000..8e2d0cd
--- /dev/null
@@ -0,0 +1,51 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_ring
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works in P - 1 steps. In step i, node j - i -> j -> j + i.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_ring_one_barrier(void *send_buff, int *send_counts, int *send_disps,
+                                          MPI_Datatype send_type,
+                                          void *recv_buff, int *recv_counts, int *recv_disps,
+                                          MPI_Datatype recv_type, MPI_Comm comm)
+{
+  MPI_Status s;
+  MPI_Aint send_chunk, recv_chunk;
+  int i, src, dst, rank, num_procs;
+  int tag = 1;
+
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  smpi_mpi_barrier(comm);
+  for (i = 0; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type, dst,
+                 tag, recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src], recv_type,
+                 src, tag, comm, &s);
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/alltoallv-ring.c b/src/smpi/colls/alltoallv-ring.c
new file mode 100644 (file)
index 0000000..dcd4b35
--- /dev/null
@@ -0,0 +1,51 @@
+#include "colls_private.h"
+/*****************************************************************************
+
+ * Function: alltoall_ring
+
+ * Return: int
+
+ * Inputs:
+    send_buff: send input buffer
+    send_count: number of elements to send
+    send_type: data type of elements being sent
+    recv_buff: receive output buffer
+    recv_count: number of elements to received
+    recv_type: data type of elements being received
+    comm: communicator
+
+ * Descrp: Function works in P - 1 steps. In step i, node j - i -> j -> j + i.
+
+ * Auther: Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_alltoallv_ring(void *send_buff, int *send_counts, int *send_disps,
+                             MPI_Datatype send_type,
+                             void *recv_buff, int *recv_counts, int *recv_disps, 
+                             MPI_Datatype recv_type,
+                              MPI_Comm comm)
+{
+  MPI_Status s;
+  MPI_Aint send_chunk, recv_chunk;
+  int i, src, dst, rank, num_procs;
+  int tag = 11;
+
+  char *send_ptr = (char *) send_buff;
+  char *recv_ptr = (char *) recv_buff;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  send_chunk = smpi_datatype_get_extent(send_type);
+  recv_chunk = smpi_datatype_get_extent(recv_type);
+
+  for (i = 0; i < num_procs; i++) {
+    src = (rank - i + num_procs) % num_procs;
+    dst = (rank + i) % num_procs;
+
+    smpi_mpi_sendrecv(send_ptr + send_disps[dst] * send_chunk, send_counts[dst], send_type, dst,
+                 tag, recv_ptr + recv_disps[src] * recv_chunk, recv_counts[src], recv_type,
+                 src, tag, comm, &s);
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-NTSB.c b/src/smpi/colls/bcast-NTSB.c
new file mode 100644 (file)
index 0000000..93ace1d
--- /dev/null
@@ -0,0 +1,179 @@
+#include "colls_private.h"
+
+int bcast_NTSB_segment_size_in_byte = 8192;
+
+int smpi_coll_tuned_bcast_NTSB(void *buf, int count, MPI_Datatype datatype,
+                               int root, MPI_Comm comm)
+{
+  int tag = 5000;
+  MPI_Status status;
+  int rank, size;
+  int i;
+
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* source node and destination nodes (same through out the functions) */
+  int from = (rank - 1) / 2;
+  int to_left = rank * 2 + 1;
+  int to_right = rank * 2 + 2;
+  if (to_left >= size)
+    to_left = -1;
+  if (to_right >= size)
+    to_right = -1;
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = bcast_NTSB_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+    }
+  }
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+
+    /* case: root */
+    if (rank == 0) {
+      /* case root has only a left child */
+      if (to_right == -1) {
+        smpi_mpi_send(buf, count, datatype, to_left, tag, comm);
+      }
+      /* case root has both left and right children */
+      else {
+        smpi_mpi_send(buf, count, datatype, to_left, tag, comm);
+        smpi_mpi_send(buf, count, datatype, to_right, tag, comm);
+      }
+    }
+
+    /* case: leaf ==> receive only */
+    else if (to_left == -1) {
+      smpi_mpi_recv(buf, count, datatype, from, tag, comm, &status);
+    }
+
+    /* case: intermidiate node with only left child ==> relay message */
+    else if (to_right == -1) {
+      smpi_mpi_recv(buf, count, datatype, from, tag, comm, &status);
+      smpi_mpi_send(buf, count, datatype, to_left, tag, comm);
+    }
+
+    /* case: intermidiate node with both left and right children ==> relay message */
+    else {
+      smpi_mpi_recv(buf, count, datatype, from, tag, comm, &status);
+      smpi_mpi_send(buf, count, datatype, to_left, tag, comm);
+      smpi_mpi_send(buf, count, datatype, to_right, tag, comm);
+    }
+    return MPI_SUCCESS;
+  }
+  // pipelining
+  else {
+
+    send_request_array =
+        (MPI_Request *) xbt_malloc(2 * (size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc(2 * (size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+
+
+    /* case: root */
+    if (rank == 0) {
+      /* case root has only a left child */
+      if (to_right == -1) {
+        for (i = 0; i < pipe_length; i++) {
+          send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to_left,
+                    tag + i, comm);
+        }
+        smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+      }
+      /* case root has both left and right children */
+      else {
+        for (i = 0; i < pipe_length; i++) {
+          send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to_left,
+                    tag + i, comm);
+          send_request_array[i + pipe_length] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to_right,
+                    tag + i, comm);
+        }
+        smpi_mpi_waitall((2 * pipe_length), send_request_array, send_status_array);
+      }
+    }
+
+    /* case: leaf ==> receive only */
+    else if (to_left == -1) {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  tag + i, comm);
+      }
+      smpi_mpi_waitall((pipe_length), recv_request_array, recv_status_array);
+    }
+
+    /* case: intermidiate node with only left child ==> relay message */
+    else if (to_right == -1) {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  tag + i, comm);
+      }
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], &status);
+        send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to_left,
+                  tag + i, comm);
+      }
+      smpi_mpi_waitall(pipe_length, send_request_array, send_status_array);
+
+    }
+    /* case: intermidiate node with both left and right children ==> relay message */
+    else {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  tag + i, comm);
+      }
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], &status);
+        send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to_left,
+                  tag + i, comm);
+        send_request_array[i + pipe_length] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to_right,
+                  tag + i, comm);
+      }
+      smpi_mpi_waitall((2 * pipe_length), send_request_array, send_status_array);
+    }
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+  }                             /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_NTSB use default MPI_bcast.");           
+    smpi_mpi_bcast((char *) buf + (pipe_length * increment), remainder, datatype,
+              root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-NTSL-Isend.c b/src/smpi/colls/bcast-NTSL-Isend.c
new file mode 100644 (file)
index 0000000..89f8f5c
--- /dev/null
@@ -0,0 +1,126 @@
+#include "colls_private.h"
+
+static int bcast_NTSL_segment_size_in_byte = 8192;
+
+/* Non-topology-specific pipelined linear-bcast function 
+   0->1, 1->2 ,2->3, ....., ->last node : in a pipeline fashion
+*/
+int smpi_coll_tuned_bcast_NTSL_Isend(void *buf, int count, MPI_Datatype datatype,
+                               int root, MPI_Comm comm)
+{
+  int tag = 50;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+  int rank, size;
+  int i;
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* source node and destination nodes (same through out the functions) */
+  int to = (rank + 1) % size;
+  int from = (rank + size - 1) % size;
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = bcast_NTSL_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+    }
+  }
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+    if (rank == 0) {
+      smpi_mpi_send(buf, count, datatype, to, tag, comm);
+    } else if (rank == (size - 1)) {
+      request = smpi_mpi_irecv(buf, count, datatype, from, tag, comm);
+      smpi_mpi_wait(&request, &status);
+    } else {
+      request = smpi_mpi_irecv(buf, count, datatype, from, tag, comm);
+      smpi_mpi_wait(&request, &status);
+      smpi_mpi_send(buf, count, datatype, to, tag, comm);
+    }
+    return MPI_SUCCESS;
+  }
+
+  /* pipeline bcast */
+  else {
+    send_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    /* root send data */
+    if (rank == 0) {
+      for (i = 0; i < pipe_length; i++) {
+        send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    /* last node only receive data */
+    else if (rank == (size - 1)) {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), recv_request_array, recv_status_array);
+    }
+
+    /* intermediate nodes relay (receive, then send) data */
+    else {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  (tag + i), comm);
+      }
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], &status);
+        send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+  }                             /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_NTSL_Isend_nb use default MPI_bcast.");                  
+    smpi_mpi_bcast((char *) buf + (pipe_length * increment), remainder, datatype,
+              root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-NTSL.c b/src/smpi/colls/bcast-NTSL.c
new file mode 100644 (file)
index 0000000..090edc7
--- /dev/null
@@ -0,0 +1,126 @@
+#include "colls_private.h"
+
+static int bcast_NTSL_segment_size_in_byte = 8192;
+
+/* Non-topology-specific pipelined linear-bcast function 
+   0->1, 1->2 ,2->3, ....., ->last node : in a pipeline fashion
+*/
+int smpi_coll_tuned_bcast_NTSL(void *buf, int count, MPI_Datatype datatype,
+                               int root, MPI_Comm comm)
+{
+  int tag = 50;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+  int rank, size;
+  int i;
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* source node and destination nodes (same through out the functions) */
+  int to = (rank + 1) % size;
+  int from = (rank + size - 1) % size;
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = bcast_NTSL_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+    }
+  }
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+    if (rank == 0) {
+      smpi_mpi_send(buf, count, datatype, to, tag, comm);
+    } else if (rank == (size - 1)) {
+      request = smpi_mpi_irecv(buf, count, datatype, from, tag, comm);
+      smpi_mpi_wait(&request, &status);
+    } else {
+      request = smpi_mpi_irecv(buf, count, datatype, from, tag, comm);
+      smpi_mpi_wait(&request, &status);
+      smpi_mpi_send(buf, count, datatype, to, tag, comm);
+    }
+    return MPI_SUCCESS;
+  }
+
+  /* pipeline bcast */
+  else {
+    send_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    /* root send data */
+    if (rank == 0) {
+      for (i = 0; i < pipe_length; i++) {
+        send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    /* last node only receive data */
+    else if (rank == (size - 1)) {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), recv_request_array, recv_status_array);
+    }
+
+    /* intermediate nodes relay (receive, then send) data */
+    else {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype, from,
+                  (tag + i), comm);
+      }
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], &status);
+        send_request_array[i] = smpi_mpi_isend((char *) buf + (i * increment), segment, datatype, to,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+  }                             /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_arrival_NTSL use default MPI_bcast.");
+    smpi_mpi_bcast((char *) buf + (pipe_length * increment), remainder, datatype,
+              root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-SMP-binary.c b/src/smpi/colls/bcast-SMP-binary.c
new file mode 100644 (file)
index 0000000..ec717e2
--- /dev/null
@@ -0,0 +1,215 @@
+#include "colls_private.h"
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+int bcast_SMP_binary_segment_byte = 8192;
+
+int smpi_coll_tuned_bcast_SMP_binary(void *buf, int count,
+                                     MPI_Datatype datatype, int root,
+                                     MPI_Comm comm)
+{
+  int tag = 5000;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *request_array;
+  MPI_Status *status_array;
+  int rank, size;
+  int i;
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+
+  int segment = bcast_SMP_binary_segment_byte / extent;
+  int pipe_length = count / segment;
+  int remainder = count % segment;
+
+  int to_intra_left = (rank / NUM_CORE) * NUM_CORE + (rank % NUM_CORE) * 2 + 1;
+  int to_intra_right = (rank / NUM_CORE) * NUM_CORE + (rank % NUM_CORE) * 2 + 2;
+  int to_inter_left = ((rank / NUM_CORE) * 2 + 1) * NUM_CORE;
+  int to_inter_right = ((rank / NUM_CORE) * 2 + 2) * NUM_CORE;
+  int from_inter = (((rank / NUM_CORE) - 1) / 2) * NUM_CORE;
+  int from_intra = (rank / NUM_CORE) * NUM_CORE + ((rank % NUM_CORE) - 1) / 2;
+  int increment = segment * extent;
+
+  int base = (rank / NUM_CORE) * NUM_CORE;
+  int num_core = NUM_CORE;
+  if (((rank / NUM_CORE) * NUM_CORE) == ((size / NUM_CORE) * NUM_CORE))
+    num_core = size - (rank / NUM_CORE) * NUM_CORE;
+
+  // if root is not zero send to rank zero first
+  if (root != 0) {
+    if (rank == root)
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    else if (rank == 0)
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+  }
+  // when a message is smaller than a block size => no pipeline 
+  if (count <= segment) {
+    // case ROOT-of-each-SMP
+    if (rank % NUM_CORE == 0) {
+      // case ROOT
+      if (rank == 0) {
+        //printf("node %d left %d right %d\n",rank,to_inter_left,to_inter_right);
+        if (to_inter_left < size)
+          smpi_mpi_send(buf, count, datatype, to_inter_left, tag, comm);
+        if (to_inter_right < size)
+          smpi_mpi_send(buf, count, datatype, to_inter_right, tag, comm);
+        if ((to_intra_left - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_left, tag, comm);
+        if ((to_intra_right - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_right, tag, comm);
+      }
+      // case LEAVES ROOT-of-eash-SMP
+      else if (to_inter_left >= size) {
+        //printf("node %d from %d\n",rank,from_inter);
+        request = smpi_mpi_irecv(buf, count, datatype, from_inter, tag, comm);
+        smpi_mpi_wait(&request, &status);
+        if ((to_intra_left - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_left, tag, comm);
+        if ((to_intra_right - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_right, tag, comm);
+      }
+      // case INTERMEDIAT ROOT-of-each-SMP
+      else {
+        //printf("node %d left %d right %d from %d\n",rank,to_inter_left,to_inter_right,from_inter);
+        request = smpi_mpi_irecv(buf, count, datatype, from_inter, tag, comm);
+        smpi_mpi_wait(&request, &status);
+        smpi_mpi_send(buf, count, datatype, to_inter_left, tag, comm);
+        if (to_inter_right < size)
+          smpi_mpi_send(buf, count, datatype, to_inter_right, tag, comm);
+        if ((to_intra_left - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_left, tag, comm);
+        if ((to_intra_right - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_right, tag, comm);
+      }
+    }
+    // case non ROOT-of-each-SMP
+    else {
+      // case leaves
+      if ((to_intra_left - base) >= num_core) {
+        request = smpi_mpi_irecv(buf, count, datatype, from_intra, tag, comm);
+        smpi_mpi_wait(&request, &status);
+      }
+      // case intermediate
+      else {
+        request = smpi_mpi_irecv(buf, count, datatype, from_intra, tag, comm);
+        smpi_mpi_wait(&request, &status);
+        smpi_mpi_send(buf, count, datatype, to_intra_left, tag, comm);
+        if ((to_intra_right - base) < num_core)
+          smpi_mpi_send(buf, count, datatype, to_intra_right, tag, comm);
+      }
+    }
+
+    return MPI_SUCCESS;
+  }
+
+  // pipeline bcast
+  else {
+    request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    // case ROOT-of-each-SMP
+    if (rank % NUM_CORE == 0) {
+      // case ROOT
+      if (rank == 0) {
+        for (i = 0; i < pipe_length; i++) {
+          //printf("node %d left %d right %d\n",rank,to_inter_left,to_inter_right);
+          if (to_inter_left < size)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_inter_left, (tag + i), comm);
+          if (to_inter_right < size)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_inter_right, (tag + i), comm);
+          if ((to_intra_left - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_left, (tag + i), comm);
+          if ((to_intra_right - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_right, (tag + i), comm);
+        }
+      }
+      // case LEAVES ROOT-of-eash-SMP
+      else if (to_inter_left >= size) {
+        //printf("node %d from %d\n",rank,from_inter);
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_inter, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+          if ((to_intra_left - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_left, (tag + i), comm);
+          if ((to_intra_right - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_right, (tag + i), comm);
+        }
+      }
+      // case INTERMEDIAT ROOT-of-each-SMP
+      else {
+        //printf("node %d left %d right %d from %d\n",rank,to_inter_left,to_inter_right,from_inter);
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_inter, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                   to_inter_left, (tag + i), comm);
+          if (to_inter_right < size)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_inter_right, (tag + i), comm);
+          if ((to_intra_left - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_left, (tag + i), comm);
+          if ((to_intra_right - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_right, (tag + i), comm);
+        }
+      }
+    }
+    // case non-ROOT-of-each-SMP
+    else {
+      // case leaves
+      if ((to_intra_left - base) >= num_core) {
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_intra, (tag + i), comm);
+        }
+        smpi_mpi_waitall((pipe_length), request_array, status_array);
+      }
+      // case intermediate
+      else {
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_intra, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                   to_intra_left, (tag + i), comm);
+          if ((to_intra_right - base) < num_core)
+            smpi_mpi_send((char *) buf + (i * increment), segment, datatype,
+                     to_intra_right, (tag + i), comm);
+        }
+      }
+    }
+
+    free(request_array);
+    free(status_array);
+  }
+
+  // when count is not divisible by block size, use default BCAST for the remainder
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_SMP_binary use default MPI_bcast.");     
+    smpi_mpi_bcast((char *) buf + (pipe_length * increment), remainder, datatype,
+              root, comm);
+  }
+
+  return 1;
+}
diff --git a/src/smpi/colls/bcast-SMP-binomial.c b/src/smpi/colls/bcast-SMP-binomial.c
new file mode 100644 (file)
index 0000000..9919302
--- /dev/null
@@ -0,0 +1,95 @@
+#include "colls_private.h"
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+int smpi_coll_tuned_bcast_SMP_binomial(void *buf, int count,
+                                       MPI_Datatype datatype, int root,
+                                       MPI_Comm comm)
+{
+  int mask = 1;
+  int size;
+  int rank;
+  MPI_Status status;
+  int tag = 50;
+
+  size = smpi_comm_size(comm);
+  rank = smpi_comm_rank(comm);
+
+  int to_intra, to_inter;
+  int from_intra, from_inter;
+  int inter_rank = rank / NUM_CORE;
+  int inter_size = (size - 1) / NUM_CORE + 1;
+  int intra_rank = rank % NUM_CORE;
+  int intra_size = NUM_CORE;
+  if (((rank / NUM_CORE) * NUM_CORE) == ((size / NUM_CORE) * NUM_CORE))
+    intra_size = size - (rank / NUM_CORE) * NUM_CORE;
+
+  // if root is not zero send to rank zero first
+  if (root != 0) {
+    if (rank == root)
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    else if (rank == 0)
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+  }
+  //FIRST STEP node 0 send to every root-of-each-SMP with binomial tree
+
+  //printf("node %d inter_rank = %d, inter_size = %d\n",rank,inter_rank, inter_size);
+
+  if (intra_rank == 0) {
+    mask = 1;
+    while (mask < inter_size) {
+      if (inter_rank & mask) {
+        from_inter = (inter_rank - mask) * NUM_CORE;
+        //printf("Node %d recv from node %d when mask is %d\n", rank, from_inter, mask);
+        smpi_mpi_recv(buf, count, datatype, from_inter, tag, comm, &status);
+        break;
+      }
+      mask <<= 1;
+    }
+
+    mask >>= 1;
+    //printf("My rank = %d my mask = %d\n", rank,mask);
+
+    while (mask > 0) {
+      if (inter_rank < inter_size) {
+        to_inter = (inter_rank + mask) * NUM_CORE;
+        if (to_inter < size) {
+          //printf("Node %d send to node %d when mask is %d\n", rank, to_inter, mask);
+          smpi_mpi_send(buf, count, datatype, to_inter, tag, comm);
+        }
+      }
+      mask >>= 1;
+    }
+  }
+  // SECOND STEP every root-of-each-SMP send to all children with binomial tree
+  // base is a rank of root-of-each-SMP
+  int base = (rank / NUM_CORE) * NUM_CORE;
+  mask = 1;
+  while (mask < intra_size) {
+    if (intra_rank & mask) {
+      from_intra = base + (intra_rank - mask);
+      //printf("Node %d recv from node %d when mask is %d\n", rank, from_inter, mask);
+      smpi_mpi_recv(buf, count, datatype, from_intra, tag, comm, &status);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  mask >>= 1;
+
+  //printf("My rank = %d my mask = %d\n", rank,mask);
+
+  while (mask > 0) {
+    if (intra_rank < intra_size) {
+      to_intra = base + (intra_rank + mask);
+      if (to_intra < size) {
+        //printf("Node %d send to node %d when mask is %d\n", rank, to_inter, mask);
+        smpi_mpi_send(buf, count, datatype, to_intra, tag, comm);
+      }
+    }
+    mask >>= 1;
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-SMP-linear.c b/src/smpi/colls/bcast-SMP-linear.c
new file mode 100644 (file)
index 0000000..673f6cf
--- /dev/null
@@ -0,0 +1,163 @@
+#include "colls_private.h"
+#ifndef NUM_CORE
+#define NUM_CORE 8
+#endif
+
+int bcast_SMP_linear_segment_byte = 8192;
+
+int smpi_coll_tuned_bcast_SMP_linear(void *buf, int count,
+                                     MPI_Datatype datatype, int root,
+                                     MPI_Comm comm)
+{
+  int tag = 5000;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *request_array;
+  MPI_Status *status_array;
+  int rank, size;
+  int i;
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+
+  int segment = bcast_SMP_linear_segment_byte / extent;
+  int pipe_length = count / segment;
+  int remainder = count % segment;
+  int increment = segment * extent;
+
+
+  /* leader of each SMP do inter-communication
+     and act as a root for intra-communication */
+  int to_inter = (rank + NUM_CORE) % size;
+  int to_intra = (rank + 1) % size;
+  int from_inter = (rank - NUM_CORE + size) % size;
+  int from_intra = (rank + size - 1) % size;
+
+  // call native when MPI communication size is too small
+  if (size <= NUM_CORE) {
+    XBT_WARN("MPI_bcast_SMP_linear use default MPI_bcast.");             
+    smpi_mpi_bcast(buf, count, datatype, root, comm);
+    return MPI_SUCCESS;            
+  }
+  // if root is not zero send to rank zero first
+  if (root != 0) {
+    if (rank == root)
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    else if (rank == 0)
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+  }
+  // when a message is smaller than a block size => no pipeline 
+  if (count <= segment) {
+    // case ROOT
+    if (rank == 0) {
+      smpi_mpi_send(buf, count, datatype, to_inter, tag, comm);
+      smpi_mpi_send(buf, count, datatype, to_intra, tag, comm);
+    }
+    // case last ROOT of each SMP
+    else if (rank == (((size - 1) / NUM_CORE) * NUM_CORE)) {
+      request = smpi_mpi_irecv(buf, count, datatype, from_inter, tag, comm);
+      smpi_mpi_wait(&request, &status);
+      smpi_mpi_send(buf, count, datatype, to_intra, tag, comm);
+    }
+    // case intermediate ROOT of each SMP
+    else if (rank % NUM_CORE == 0) {
+      request = smpi_mpi_irecv(buf, count, datatype, from_inter, tag, comm);
+      smpi_mpi_wait(&request, &status);
+      smpi_mpi_send(buf, count, datatype, to_inter, tag, comm);
+      smpi_mpi_send(buf, count, datatype, to_intra, tag, comm);
+    }
+    // case last non-ROOT of each SMP
+    else if (((rank + 1) % NUM_CORE == 0) || (rank == (size - 1))) {
+      request = smpi_mpi_irecv(buf, count, datatype, from_intra, tag, comm);
+      smpi_mpi_wait(&request, &status);
+    }
+    // case intermediate non-ROOT of each SMP
+    else {
+      request = smpi_mpi_irecv(buf, count, datatype, from_intra, tag, comm);
+      smpi_mpi_wait(&request, &status);
+      smpi_mpi_send(buf, count, datatype, to_intra, tag, comm);
+    }
+    return MPI_SUCCESS;
+  }
+  // pipeline bcast
+  else {
+    request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    // case ROOT of each SMP
+    if (rank % NUM_CORE == 0) {
+      // case real root
+      if (rank == 0) {
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype, to_inter,
+                   (tag + i), comm);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype, to_intra,
+                   (tag + i), comm);
+        }
+      }
+      // case last ROOT of each SMP
+      else if (rank == (((size - 1) / NUM_CORE) * NUM_CORE)) {
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_inter, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype, to_intra,
+                   (tag + i), comm);
+        }
+      }
+      // case intermediate ROOT of each SMP
+      else {
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_inter, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype, to_inter,
+                   (tag + i), comm);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype, to_intra,
+                   (tag + i), comm);
+        }
+      }
+    } else {                    // case last non-ROOT of each SMP
+      if (((rank + 1) % NUM_CORE == 0) || (rank == (size - 1))) {
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_intra, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+        }
+      }
+      // case intermediate non-ROOT of each SMP
+      else {
+        for (i = 0; i < pipe_length; i++) {
+          request_array[i] = smpi_mpi_irecv((char *) buf + (i * increment), segment, datatype,
+                    from_intra, (tag + i), comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&request_array[i], &status);
+          smpi_mpi_send((char *) buf + (i * increment), segment, datatype, to_intra,
+                   (tag + i), comm);
+        }
+      }
+    }
+    free(request_array);
+    free(status_array);
+  }
+
+  // when count is not divisible by block size, use default BCAST for the remainder
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_SMP_linear use default MPI_bcast.");                    
+    smpi_mpi_bcast((char *) buf + (pipe_length * increment), remainder, datatype,
+              root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-arrival-nb.c b/src/smpi/colls/bcast-arrival-nb.c
new file mode 100644 (file)
index 0000000..9ff27b4
--- /dev/null
@@ -0,0 +1,386 @@
+#include "colls_private.h"
+
+static int bcast_NTSL_segment_size_in_byte = 8192;
+
+#define HEADER_SIZE 1024
+#define MAX_NODE 1024
+
+/* Non-topology-specific pipelined linear-bcast function */
+int smpi_coll_tuned_bcast_arrival_nb(void *buf, int count,
+                                     MPI_Datatype datatype, int root,
+                                     MPI_Comm comm)
+{
+  int tag = 50;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+
+  MPI_Status temp_status_array[MAX_NODE];
+
+  int rank, size;
+  int i, j;
+
+  int sent_count;
+  int header_index;
+  int flag_array[MAX_NODE];
+  int already_sent[MAX_NODE];
+
+  int header_buf[HEADER_SIZE];
+  char temp_buf[MAX_NODE];
+
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  /* destination */
+  int to;
+
+
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = bcast_NTSL_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+    }
+  }
+
+  /* value == 0 means root has not send data (or header) to the node yet */
+  for (i = 0; i < MAX_NODE; i++) {
+    already_sent[i] = 0;
+  }
+  //  printf("YYY\n");
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+    if (rank == 0) {
+      sent_count = 0;
+
+      while (sent_count < (size - 1)) {
+
+        //      for (j=0;j<1000;j++) {
+        for (i = 1; i < size; i++) {
+          if (already_sent[i] == 0)
+            smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                       MPI_STATUSES_IGNORE);
+        }
+        //}
+
+        header_index = 0;
+        /* recv 1-byte message */
+        for (i = 1; i < size; i++) {
+
+          /* message arrive */
+          if ((flag_array[i] == 1) && (already_sent[i] == 0)) {
+            smpi_mpi_recv(temp_buf, 1, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status);
+            header_buf[header_index] = i;
+            header_index++;
+            sent_count++;
+
+            /* will send in the next step */
+            already_sent[i] = 1;
+          }
+        }
+
+        /* send header followed by data */
+        if (header_index != 0) {
+          header_buf[header_index] = -1;
+          to = header_buf[0];
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+          smpi_mpi_send(buf, count, datatype, to, tag, comm);
+        }
+
+        /* randomly MPI_Send to one */
+        else {
+          /* search for the first node that never received data before */
+          for (i = 1; i < size; i++) {
+            if (already_sent[i] == 0) {
+              header_buf[0] = i;
+              header_buf[1] = -1;
+              smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, i, tag, comm);
+              smpi_mpi_send(buf, count, datatype, i, tag, comm);
+              already_sent[i] = 1;
+              sent_count++;
+              break;
+            }
+          }
+        }
+
+
+      }                         /* while loop */
+    }
+
+    /* non-root */
+    else {
+
+      /* send 1-byte message to root */
+      smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+      /* wait for header and data, forward when required */
+      smpi_mpi_recv(header_buf, HEADER_SIZE, MPI_INT, MPI_ANY_SOURCE, tag, comm,
+               &status);
+      smpi_mpi_recv(buf, count, datatype, MPI_ANY_SOURCE, tag, comm, &status);
+
+      /* search for where it is */
+      int myordering = 0;
+      while (rank != header_buf[myordering]) {
+        myordering++;
+      }
+
+      /* send header followed by data */
+      if (header_buf[myordering + 1] != -1) {
+        smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, header_buf[myordering + 1],
+                 tag, comm);
+        smpi_mpi_send(buf, count, datatype, header_buf[myordering + 1], tag, comm);
+      }
+    }
+  }
+  /* pipeline bcast */
+  else {
+    send_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    if (rank == 0) {
+      sent_count = 0;
+      int iteration = 0;
+
+      int will_send[1000];
+      for (i = 0; i < 1000; i++)
+        will_send[i] = 0;
+      while (sent_count < (size - 1)) {
+        iteration++;
+        //start = MPI_Wtime();
+
+        int k;
+        for (k = 0; k < 3; k++) {
+          for (i = 1; i < size; i++) {
+            if ((already_sent[i] == 0) && (will_send[i] == 0)) {
+              smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                         &temp_status_array[i]);
+              if (flag_array[i] == 1) {
+                will_send[i] = 1;
+                smpi_mpi_recv(&temp_buf[i], 1, MPI_CHAR, i, tag, MPI_COMM_WORLD,
+                         &status);
+                i = 1;
+              }
+            }
+          }
+        }
+
+        //total = MPI_Wtime() - start;
+        //total *= 1000;
+        //printf("Iprobe time = %.2f\n",total);
+        header_index = 0;
+
+        //start = MPI_Wtime();
+        /* recv 1-byte message */
+        for (i = 1; i < size; i++) {
+          /* message arrive */
+          if ((will_send[i] == 1) && (already_sent[i] == 0)) {
+            header_buf[header_index] = i;
+            header_index++;
+            sent_count++;
+
+            /* will send in the next step */
+            already_sent[i] = 1;
+          }
+        }
+        //printf("sent_count = %d\n",sent_count);
+
+
+        //total = MPI_Wtime() - start;
+        //total *= 1000;
+        //printf("Recv 1-byte time = %.2f\n",total);
+
+        /*      
+           if (header_index != 0) {
+           printf("header index = %d node = ",header_index);
+           for (i=0;i<header_index;i++) {
+           printf("%d ",header_buf[i]);
+           }
+           printf("\n");
+           }
+         */
+
+        /* send header followed by data */
+        if (header_index != 0) {
+          header_buf[header_index] = -1;
+          to = header_buf[0];
+
+          //start = MPI_Wtime();
+
+          /* send header */
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+
+          //total = MPI_Wtime() - start;
+          //total *= 1000;
+          //printf("\tSend header to %d time = %.2f\n",to,total);
+
+          //start = MPI_Wtime();
+
+          /* send data - non-pipeline case */
+
+          if (0 == 1) {
+            //if (header_index == 1) {
+            smpi_mpi_send(buf, count, datatype, to, tag, comm);
+          }
+
+
+          /* send data - pipeline */
+          else {
+            for (i = 0; i < pipe_length; i++) {
+              smpi_mpi_send((char *)buf + (i * increment), segment, datatype, to, tag, comm);
+            }
+            //smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+          }
+          //total = MPI_Wtime() - start;
+          //total *= 1000;
+          //printf("\tSend data to %d time = %.2f\n",to,total);
+
+        }
+
+
+
+        /* randomly MPI_Send to one node */
+        else {
+          /* search for the first node that never received data before */
+          for (i = 1; i < size; i++) {
+            if (already_sent[i] == 0) {
+              header_buf[0] = i;
+              header_buf[1] = -1;
+              to = i;
+
+              //start = MPI_Wtime();
+              smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+
+              /* still need to chop data so that we can use the same non-root code */
+              for (j = 0; j < pipe_length; j++) {
+                smpi_mpi_send((char *)buf + (j * increment), segment, datatype, to, tag,
+                         comm);
+              }
+
+              //smpi_mpi_send(buf,count,datatype,to,tag,comm);
+              //smpi_mpi_wait(&request,MPI_STATUS_IGNORE);
+
+              //total = MPI_Wtime() - start;
+              //total *= 1000;
+              //printf("SEND TO SINGLE node %d time = %.2f\n",i,total);
+
+
+              already_sent[i] = 1;
+              sent_count++;
+              break;
+            }
+          }
+        }
+
+      }                         /* while loop */
+
+      //total = MPI_Wtime() - start2;
+      //total *= 1000;
+      //printf("Node zero iter = %d time = %.2f\n",iteration,total);
+
+      /* probe before exit in case there are messages to recv */
+      for (i = 1; i < size; i++) {
+        smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                   &temp_status_array[i]);
+        if (flag_array[i] == 1)
+          smpi_mpi_recv(&temp_buf[i], 1, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status);
+      }
+    }
+
+    /* rank 0 */
+    /* none root */
+    else {
+
+      /* if root already send a message to this node, don't send one-byte message */
+      smpi_mpi_iprobe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[0], &status);
+
+      /* send 1-byte message to root */
+      if (flag_array[0] == 0)
+        smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+      /* wait for header forward when required */
+      request = smpi_mpi_irecv(header_buf, HEADER_SIZE, MPI_INT, MPI_ANY_SOURCE, tag, comm);
+      smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+
+      /* search for where it is */
+      int myordering = 0;
+      while (rank != header_buf[myordering]) {
+        myordering++;
+      }
+
+      /* send header when required */
+      if (header_buf[myordering + 1] != -1) {
+        smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, header_buf[myordering + 1],
+                 tag, comm);
+      }
+
+      /* receive data */
+
+      if (0 == -1) {
+        //if (header_buf[1] == -1) {
+        request = smpi_mpi_irecv(buf, count, datatype, 0, tag, comm);
+        smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+        //printf("\t\tnode %d ordering = %d receive data from root\n",rank,myordering);
+      } else {
+        for (i = 0; i < pipe_length; i++) {
+          recv_request_array[i] = smpi_mpi_irecv((char *)buf + (i * increment), segment, datatype, MPI_ANY_SOURCE,
+                    tag, comm);
+        }
+      }
+
+      /* send data */
+      if (header_buf[myordering + 1] != -1) {
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&recv_request_array[i], MPI_STATUS_IGNORE);
+          send_request_array[i] = smpi_mpi_isend((char *)buf + (i * increment), segment, datatype,
+                    header_buf[myordering + 1], tag, comm);
+        }
+        smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+      }
+
+    }
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+  }                             /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_arrival_nb use default MPI_bcast.");     
+    smpi_mpi_bcast((char *)buf + (pipe_length * increment), remainder, datatype, root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-arrival-pattern-aware-wait.c b/src/smpi/colls/bcast-arrival-pattern-aware-wait.c
new file mode 100644 (file)
index 0000000..0a12246
--- /dev/null
@@ -0,0 +1,248 @@
+#include "colls_private.h"
+
+int bcast_arrival_pattern_aware_wait_segment_size_in_byte = 8192;
+
+#ifndef BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE
+#define BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE 1024
+#endif
+
+#ifndef BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE
+#define BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE 128
+#endif
+
+/* Non-topology-specific pipelined linear-bcast function */
+int smpi_coll_tuned_bcast_arrival_pattern_aware_wait(void *buf, int count,
+                                                     MPI_Datatype datatype,
+                                                     int root, MPI_Comm comm)
+{
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+
+
+  MPI_Status temp_status_array[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+
+  int rank, size;
+  int i, j, k;
+  int tag = 50;
+  int will_send[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+
+  int sent_count;
+  int header_index;
+  int flag_array[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+  int already_sent[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+
+  int header_buf[BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE];
+  char temp_buf[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+
+  int max_node = BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE;
+  int header_size = BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE;
+
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  /* source and destination */
+  int to, from;
+
+
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = bcast_arrival_pattern_aware_wait_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+    }
+  }
+
+
+  /* value == 0 means root has not send data (or header) to the node yet */
+  for (i = 0; i < max_node; i++) {
+    already_sent[i] = 0;
+  }
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+    segment = count;
+    pipe_length = 1;
+  }
+
+  /* start pipeline bcast */
+
+  send_request_array =
+      (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+  recv_request_array =
+      (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+  send_status_array =
+      (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+  recv_status_array =
+      (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+  /* root */
+  if (rank == 0) {
+    sent_count = 0;
+    int iteration = 0;
+
+    for (i = 0; i < BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE; i++)
+      will_send[i] = 0;
+    while (sent_count < (size - 1)) {
+      iteration++;
+
+      /* loop k times to let more processes arrive before start sending data */
+      for (k = 0; k < 3; k++) {
+        for (i = 1; i < size; i++) {
+          if ((already_sent[i] == 0) && (will_send[i] == 0)) {
+            smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                       &temp_status_array[i]);
+            if (flag_array[i] == 1) {
+              will_send[i] = 1;
+              smpi_mpi_recv(&temp_buf[i], 1, MPI_CHAR, i, tag, MPI_COMM_WORLD,
+                       &status);
+              i = 0;
+            }
+          }
+        }
+      }
+
+      header_index = 0;
+
+      /* recv 1-byte message */
+      for (i = 1; i < size; i++) {
+        /* message arrive */
+        if ((will_send[i] == 1) && (already_sent[i] == 0)) {
+          header_buf[header_index] = i;
+          header_index++;
+          sent_count++;
+
+          /* will send in the next step */
+          already_sent[i] = 1;
+        }
+      }
+
+      /* send header followed by data */
+      if (header_index != 0) {
+        header_buf[header_index] = -1;
+        to = header_buf[0];
+
+        /* send header */
+        smpi_mpi_send(header_buf, header_size, MPI_INT, to, tag, comm);
+
+        /* send data - pipeline */
+        for (i = 0; i < pipe_length; i++) {
+          send_request_array[i] = smpi_mpi_isend((char *)buf + (i * increment), segment, datatype, to, tag, comm);
+        }
+        smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+      }
+
+
+      /* end - send header followed by data */
+      /* randomly MPI_Send to one node */
+      /* this part has been commented out - performance-wise */
+      else if (2 == 3) {
+        /* search for the first node that never received data before */
+        for (i = 0; i < size; i++) {
+          if (i == root)
+            continue;
+          if (already_sent[i] == 0) {
+            header_buf[0] = i;
+            header_buf[1] = -1;
+            to = i;
+
+            smpi_mpi_send(header_buf, header_size, MPI_INT, to, tag, comm);
+
+            /* still need to chop data so that we can use the same non-root code */
+            for (j = 0; j < pipe_length; j++) {
+              smpi_mpi_send((char *)buf + (j * increment), segment, datatype, to, tag, comm);
+            }
+          }
+        }
+      }
+    }                           /* end - while (send_count < size-1) loop */
+  }
+
+  /* end - root */
+  /* none root */
+  else {
+
+    /* send 1-byte message to root */
+    smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+    /* wait for header forward when required */
+    request = smpi_mpi_irecv(header_buf, header_size, MPI_INT, MPI_ANY_SOURCE, tag, comm);
+    smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+
+    /* search for where it is */
+    int myordering = 0;
+    while (rank != header_buf[myordering]) {
+      myordering++;
+    }
+
+    to = header_buf[myordering + 1];
+    if (myordering == 0) {
+      from = 0;
+    } else {
+      from = header_buf[myordering - 1];
+    }
+
+    /* send header when required */
+    if (to != -1) {
+      smpi_mpi_send(header_buf, header_size, MPI_INT, to, tag, comm);
+    }
+
+    /* receive data */
+
+    for (i = 0; i < pipe_length; i++) {
+      recv_request_array[i] = smpi_mpi_irecv((char *)buf + (i * increment), segment, datatype, from, tag, comm);
+    }
+
+    /* forward data */
+    if (to != -1) {
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], MPI_STATUS_IGNORE);
+        send_request_array[i] = smpi_mpi_isend((char *)buf + (i * increment), segment, datatype, to, tag, comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    /* recv only */
+    else {
+      smpi_mpi_waitall((pipe_length), recv_request_array, recv_status_array);
+    }
+  }
+
+  free(send_request_array);
+  free(recv_request_array);
+  free(send_status_array);
+  free(recv_status_array);
+  /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_arrival_pattern_aware_wait use default MPI_bcast.");             
+    smpi_mpi_bcast((char *)buf + (pipe_length * increment), remainder, datatype, root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-arrival-pattern-aware.c b/src/smpi/colls/bcast-arrival-pattern-aware.c
new file mode 100644 (file)
index 0000000..f4a482c
--- /dev/null
@@ -0,0 +1,351 @@
+#include "colls_private.h"
+
+static int bcast_NTSL_segment_size_in_byte = 8192;
+
+#define HEADER_SIZE 1024
+#define MAX_NODE 1024
+
+/* Non-topology-specific pipelined linear-bcast function */
+int smpi_coll_tuned_bcast_arrival_pattern_aware(void *buf, int count,
+                                                MPI_Datatype datatype, int root,
+                                                MPI_Comm comm)
+{
+  int tag = 50;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+
+  MPI_Status temp_status_array[MAX_NODE];
+
+  int rank, size;
+  int i, j;
+
+  int sent_count;
+  int header_index;
+  int flag_array[MAX_NODE];
+  int already_sent[MAX_NODE];
+
+  int header_buf[HEADER_SIZE];
+  char temp_buf[MAX_NODE];
+
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  /* destination */
+  int to;
+
+
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = bcast_NTSL_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag, comm, &status);
+    }
+  }
+
+  /* value == 0 means root has not send data (or header) to the node yet */
+  for (i = 0; i < MAX_NODE; i++) {
+    already_sent[i] = 0;
+  }
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+    if (rank == 0) {
+      sent_count = 0;
+
+      while (sent_count < (size - 1)) {
+        for (i = 1; i < size; i++) {
+          smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                     MPI_STATUSES_IGNORE);
+        }
+
+        header_index = 0;
+        /* recv 1-byte message */
+        for (i = 1; i < size; i++) {
+
+          /* message arrive */
+          if ((flag_array[i] == 1) && (already_sent[i] == 0)) {
+            smpi_mpi_recv(temp_buf, 1, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status);
+            header_buf[header_index] = i;
+            header_index++;
+            sent_count++;
+
+            /* will send in the next step */
+            already_sent[i] = 1;
+          }
+        }
+
+        /* send header followed by data */
+        if (header_index != 0) {
+          header_buf[header_index] = -1;
+          to = header_buf[0];
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+          smpi_mpi_send(buf, count, datatype, to, tag, comm);
+        }
+
+        /* randomly MPI_Send to one */
+        else {
+          /* search for the first node that never received data before */
+          for (i = 1; i < size; i++) {
+            if (already_sent[i] == 0) {
+              header_buf[0] = i;
+              header_buf[1] = -1;
+              smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, i, tag, comm);
+              smpi_mpi_send(buf, count, datatype, i, tag, comm);
+              already_sent[i] = 1;
+              sent_count++;
+              break;
+            }
+          }
+        }
+
+
+      }                         /* while loop */
+    }
+
+    /* non-root */
+    else {
+
+      /* send 1-byte message to root */
+      smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+      /* wait for header and data, forward when required */
+      smpi_mpi_recv(header_buf, HEADER_SIZE, MPI_INT, MPI_ANY_SOURCE, tag, comm,
+               &status);
+      smpi_mpi_recv(buf, count, datatype, MPI_ANY_SOURCE, tag, comm, &status);
+
+      /* search for where it is */
+      int myordering = 0;
+      while (rank != header_buf[myordering]) {
+        myordering++;
+      }
+
+      /* send header followed by data */
+      if (header_buf[myordering + 1] != -1) {
+        smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, header_buf[myordering + 1],
+                 tag, comm);
+        smpi_mpi_send(buf, count, datatype, header_buf[myordering + 1], tag, comm);
+      }
+    }
+  }
+  /* pipeline bcast */
+  else {
+    send_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    if (rank == 0) {
+      //double start2 = MPI_Wtime();
+      sent_count = 0;
+      //int iteration = 0;
+      while (sent_count < (size - 1)) {
+        //iteration++;
+        //start = MPI_Wtime();
+        for (i = 1; i < size; i++) {
+          smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                     &temp_status_array[i]);
+        }
+        //total = MPI_Wtime() - start;
+        //total *= 1000;
+        //printf("Iprobe time = %.2f\n",total);
+        header_index = 0;
+
+        MPI_Wtime();
+        /* recv 1-byte message */
+        for (i = 1; i < size; i++) {
+          /* message arrive */
+          if ((flag_array[i] == 1) && (already_sent[i] == 0)) {
+            smpi_mpi_recv(&temp_buf[i], 1, MPI_CHAR, i, tag, MPI_COMM_WORLD,
+                     &status);
+            header_buf[header_index] = i;
+            header_index++;
+            sent_count++;
+
+            /* will send in the next step */
+            already_sent[i] = 1;
+          }
+        }
+        //total = MPI_Wtime() - start;
+        //total *= 1000;
+        //printf("Recv 1-byte time = %.2f\n",total);
+
+        /*
+           if (header_index != 0) {
+           printf("header index = %d node = ",header_index);
+           for (i=0;i<header_index;i++) {
+           printf("%d ",header_buf[i]);
+           }
+           printf("\n");
+           }
+         */
+
+        /* send header followed by data */
+        if (header_index != 0) {
+          header_buf[header_index] = -1;
+          to = header_buf[0];
+
+          //start = MPI_Wtime();
+
+          /* send header */
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+
+          //total = MPI_Wtime() - start;
+          //total *= 1000;
+          //printf("\tSend header to %d time = %.2f\n",to,total);
+
+          //start = MPI_Wtime();
+
+          /* send data - non-pipeline case */
+
+          if (0 == 1) {
+            //if (header_index == 1) {
+            smpi_mpi_send(buf, count, datatype, to, tag, comm);
+          }
+
+
+          /* send data - pipeline */
+          else {
+            for (i = 0; i < pipe_length; i++) {
+              smpi_mpi_send((char *)buf + (i * increment), segment, datatype, to, tag, comm);
+            }
+            //smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+          }
+          //total = MPI_Wtime() - start;
+          //total *= 1000;
+          //printf("\tSend data to %d time = %.2f\n",to,total);
+
+        }
+
+
+
+        /* randomly MPI_Send to one node */
+        else {
+          /* search for the first node that never received data before */
+          for (i = 1; i < size; i++) {
+            if (already_sent[i] == 0) {
+              header_buf[0] = i;
+              header_buf[1] = -1;
+              to = i;
+
+              //start = MPI_Wtime();
+              smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+
+              /* still need to chop data so that we can use the same non-root code */
+              for (j = 0; j < pipe_length; j++) {
+                smpi_mpi_send((char *)buf + (j * increment), segment, datatype, to, tag,
+                         comm);
+              }
+
+              //smpi_mpi_send(buf,count,datatype,to,tag,comm);
+              //smpi_mpi_wait(&request,MPI_STATUS_IGNORE);
+
+              //total = MPI_Wtime() - start;
+              //total *= 1000;
+              //printf("SEND TO SINGLE node %d time = %.2f\n",i,total);
+
+
+              already_sent[i] = 1;
+              sent_count++;
+              break;
+            }
+          }
+        }
+
+      }                         /* while loop */
+
+      //total = MPI_Wtime() - start2;
+      //total *= 1000;
+      //printf("Node zero iter = %d time = %.2f\n",iteration,total);
+    }
+
+    /* rank 0 */
+    /* none root */
+    else {
+      /* send 1-byte message to root */
+      smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+      /* wait for header forward when required */
+      request = smpi_mpi_irecv(header_buf, HEADER_SIZE, MPI_INT, MPI_ANY_SOURCE, tag, comm);
+      smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+
+      /* search for where it is */
+      int myordering = 0;
+      while (rank != header_buf[myordering]) {
+        myordering++;
+      }
+
+      /* send header when required */
+      if (header_buf[myordering + 1] != -1) {
+        smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, header_buf[myordering + 1],
+                 tag, comm);
+      }
+
+      /* receive data */
+
+      if (0 == -1) {
+        //if (header_buf[1] == -1) {
+        request = smpi_mpi_irecv(buf, count, datatype, 0, tag, comm);
+        smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+        //printf("\t\tnode %d ordering = %d receive data from root\n",rank,myordering);
+      } else {
+        for (i = 0; i < pipe_length; i++) {
+          recv_request_array[i] = smpi_mpi_irecv((char *)buf + (i * increment), segment, datatype, MPI_ANY_SOURCE,
+                                                 tag, comm);
+        }
+      }
+
+      /* send data */
+      if (header_buf[myordering + 1] != -1) {
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&recv_request_array[i], MPI_STATUS_IGNORE);
+          send_request_array[i] = smpi_mpi_isend((char *)buf + (i * increment), segment, datatype,
+                    header_buf[myordering + 1], tag, comm);
+        }
+        smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+      }
+
+    }
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+  }                             /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_bcast_arrival_pattern_aware use default MPI_bcast.");          
+    smpi_mpi_bcast((char *)buf + (pipe_length * increment), remainder, datatype, root, comm);
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-arrival-scatter.c b/src/smpi/colls/bcast-arrival-scatter.c
new file mode 100644 (file)
index 0000000..6ad805d
--- /dev/null
@@ -0,0 +1,230 @@
+#include "colls_private.h"
+
+#ifndef BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE
+#define BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE 128
+#endif
+
+#ifndef BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE
+#define BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE 128
+#endif
+
+/* Non-topology-specific pipelined linear-bcast function */
+int smpi_coll_tuned_bcast_arrival_scatter(void *buf, int count,
+                                          MPI_Datatype datatype, int root,
+                                          MPI_Comm comm)
+{
+  int tag = 50;
+  int header_tag = 10;
+  MPI_Status status;
+
+  int curr_remainder;
+  int curr_size;
+  int curr_increment;
+  int send_offset;
+  int recv_offset;
+  int send_count;
+  int recv_count;
+
+  MPI_Status temp_status_array[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+
+  int rank, size;
+  int i, k;
+
+  int sent_count;
+  int header_index;
+  int flag_array[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+  int already_sent[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+  int header_buf[BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE];
+  char temp_buf[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+  int will_send[BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE];
+  int max_node = BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE;
+  int header_size = BCAST_ARRIVAL_PATTERN_AWARE_HEADER_SIZE;
+
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+
+  /* source and destination */
+  int to, from;
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* message too small */
+  if (count < size) {
+    XBT_WARN("MPI_bcast_arrival_scatter use default MPI_bcast.");
+    smpi_mpi_bcast(buf, count, datatype, root, comm);
+    return MPI_SUCCESS;        
+  }
+
+
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == root) {
+      smpi_mpi_send(buf, count, datatype, 0, tag - 1, comm);
+    } else if (rank == 0) {
+      smpi_mpi_recv(buf, count, datatype, root, tag - 1, comm, &status);
+    }
+  }
+
+
+  /* value == 0 means root has not send data (or header) to the node yet */
+  for (i = 0; i < max_node; i++) {
+    already_sent[i] = 0;
+  }
+
+  /* start bcast */
+
+  /* root */
+  if (rank == 0) {
+
+    for (i = 0; i < max_node; i++)
+      will_send[i] = 0;
+
+    sent_count = 0;
+    while (sent_count < (size - 1)) {
+
+      for (k = 0; k < 3; k++) {
+        for (i = 1; i < size; i++) {
+          if ((already_sent[i] == 0) && (will_send[i] == 0)) {
+            smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                       &temp_status_array[i]);
+            if (flag_array[i] == 1) {
+              will_send[i] = 1;
+              smpi_mpi_recv(&temp_buf[i], 1, MPI_CHAR, i, tag, MPI_COMM_WORLD,
+                       &status);
+              i = 0;
+            }
+          }
+        }
+      }
+      header_index = 0;
+
+      /* recv 1-byte message in this round */
+      for (i = 1; i < size; i++) {
+        /* message arrive */
+        if ((will_send[i] == 1) && (already_sent[i] == 0)) {
+          header_buf[header_index] = i;
+          header_index++;
+          sent_count++;
+
+          /* will send in the next step */
+          already_sent[i] = 1;
+        }
+      }
+
+      /*
+         if (header_index != 0) {
+         printf("header index = %d node = ",header_index);
+         for (i=0;i<header_index;i++) {
+         printf("%d ",header_buf[i]);
+         }
+         printf("\n");
+         }
+       */
+
+      /* send header followed by data */
+      if (header_index != 0) {
+        header_buf[header_index] = -1;
+
+        /* send header */
+        for (i = 0; i < header_index; i++) {
+          to = header_buf[i];
+          smpi_mpi_send(header_buf, header_size, MPI_INT, to, header_tag, comm);
+        }
+
+        curr_remainder = count % header_index;
+        curr_size = (count / header_index);
+        curr_increment = curr_size * extent;
+
+        /* send data */
+
+        for (i = 0; i < header_index; i++) {
+          to = header_buf[i];
+          if ((i == (header_index - 1)) || (curr_size == 0))
+            curr_size += curr_remainder;
+          //printf("Root send to %d index %d\n",to,(i*curr_increment));
+          smpi_mpi_send((char *) buf + (i * curr_increment), curr_size, datatype, to,
+                   tag, comm);
+        }
+      }
+    }                           /* while (sent_count < size-1) */
+  }
+
+  /* rank 0 */
+  /* none root */
+  else {
+    /* send 1-byte message to root */
+    smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+    /* wait for header forward when required */
+    smpi_mpi_recv(header_buf, header_size, MPI_INT, 0, header_tag, comm, &status);
+
+    /* search for where it is */
+    int myordering = 0;
+    while (rank != header_buf[myordering]) {
+      myordering++;
+    }
+
+    int total_nodes = 0;
+    while (header_buf[total_nodes] != -1) {
+      total_nodes++;
+    }
+
+    curr_remainder = count % total_nodes;
+    curr_size = (count / total_nodes);
+    curr_increment = curr_size * extent;
+    int recv_size = curr_size;
+
+    /* receive data */
+    if (myordering == (total_nodes - 1))
+      recv_size += curr_remainder;
+    smpi_mpi_recv((char *) buf + (myordering * curr_increment), recv_size, datatype,
+             0, tag, comm, &status);
+
+    /* at this point all nodes in this set perform all-gather operation */
+    to = header_buf[myordering + 1];
+    from = header_buf[myordering - 1];
+    if (myordering == 0)
+      from = header_buf[total_nodes - 1];
+    if (myordering == (total_nodes - 1))
+      to = header_buf[0];
+
+
+    /* last segment may have a larger size since it also include the remainder */
+    int last_segment_ptr = (total_nodes - 1) * (count / total_nodes) * extent;
+
+
+    /* allgather */
+    for (i = 0; i < total_nodes - 1; i++) {
+      send_offset =
+          ((myordering - i + total_nodes) % total_nodes) * curr_increment;
+      recv_offset =
+          ((myordering - i - 1 + total_nodes) % total_nodes) * curr_increment;
+
+      /* adjust size */
+      if (send_offset != last_segment_ptr)
+        send_count = curr_size;
+      else
+        send_count = curr_size + curr_remainder;
+
+      if (recv_offset != last_segment_ptr)
+        recv_count = curr_size;
+      else
+        recv_count = curr_size + curr_remainder;
+
+      //printf("\t\tnode %d sent_to %d recv_from %d send_size %d recv_size %d\n",rank,to,from,send_count,recv_count);
+      //printf("\tnode %d sent_offset %d send_count %d\n",rank,send_offset,send_count);
+
+
+      smpi_mpi_sendrecv((char *) buf + send_offset, send_count, datatype, to,
+                   tag + i, (char *) buf + recv_offset, recv_count, datatype,
+                   from, tag + i, comm, &status);
+    }
+  }                             /* non-root */
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-binomial-tree.c b/src/smpi/colls/bcast-binomial-tree.c
new file mode 100644 (file)
index 0000000..e840c02
--- /dev/null
@@ -0,0 +1,102 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+
+ * Function: bcast_binomial_tree
+
+ * Return: int
+
+ * Inputs:
+    buff: send input buffer
+    count: number of elements to send
+    data_type: data type of elements being sent
+    root: source of data
+    comm: communicator
+
+ * Descrp: broadcasts using a bionomial tree.
+
+ * Auther: MPIH / modified by Ahmad Faraj
+
+ ****************************************************************************/
+
+int
+smpi_coll_tuned_bcast_binomial_tree(void *buff, int count,
+                                    MPI_Datatype data_type, int root,
+                                    MPI_Comm comm)
+{
+  int src, dst, rank, num_procs, mask, relative_rank;
+  int tag = 1;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+
+  relative_rank = (rank >= root) ? rank - root : rank - root + num_procs;
+
+  mask = 0x1;
+  while (mask < num_procs) {
+    if (relative_rank & mask) {
+      src = rank - mask;
+      if (src < 0)
+        src += num_procs;
+      smpi_mpi_recv(buff, count, data_type, src, tag, comm, MPI_STATUS_IGNORE);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  mask >>= 1;
+  while (mask > 0) {
+    if (relative_rank + mask < num_procs) {
+      dst = rank + mask;
+      if (dst >= num_procs)
+        dst -= num_procs;
+      smpi_mpi_send(buff, count, data_type, dst, tag, comm);
+    }
+    mask >>= 1;
+  }
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-flattree-pipeline.c b/src/smpi/colls/bcast-flattree-pipeline.c
new file mode 100644 (file)
index 0000000..9033bf5
--- /dev/null
@@ -0,0 +1,56 @@
+#include "colls_private.h"
+
+int flattree_segment_in_byte = 8192;
+
+int
+smpi_coll_tuned_bcast_flattree_pipeline(void *buff, int count,
+                                        MPI_Datatype data_type, int root,
+                                        MPI_Comm comm)
+{
+  int i, j, rank, num_procs;
+  int tag = 1;
+
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(data_type);
+
+  int segment = flattree_segment_in_byte / extent;
+  int pipe_length = count / segment;
+  int increment = segment * extent;
+  if (pipe_length==0) {
+    XBT_WARN("MPI_bcast_flattree_pipeline use default MPI_bcast_flattree.");
+    return smpi_coll_tuned_bcast_flattree(buff, count, data_type, root, comm);
+  }
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+
+  MPI_Request *request_array;
+  MPI_Status *status_array;
+
+  request_array = (MPI_Request *) xbt_malloc(pipe_length * sizeof(MPI_Request));
+  status_array = (MPI_Status *) xbt_malloc(pipe_length * sizeof(MPI_Status));
+
+  if (rank != root) {
+    for (i = 0; i < pipe_length; i++) {
+      request_array[i] = smpi_mpi_irecv((char *)buff + (i * increment), segment, data_type, root, tag, comm);
+    }
+    smpi_mpi_waitall(pipe_length, request_array, status_array);
+  }
+
+  else {
+    // Root sends data to all others
+    for (j = 0; j < num_procs; j++) {
+      if (j == rank)
+        continue;
+      else {
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_send((char *)buff + (i * increment), segment, data_type, j, tag, comm);
+        }
+      }
+    }
+
+  }
+
+  free(request_array);
+  free(status_array);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-flattree.c b/src/smpi/colls/bcast-flattree.c
new file mode 100644 (file)
index 0000000..626c203
--- /dev/null
@@ -0,0 +1,37 @@
+#include "colls_private.h"
+
+int
+smpi_coll_tuned_bcast_flattree(void *buff, int count, MPI_Datatype data_type,
+                               int root, MPI_Comm comm)
+{
+  MPI_Request *req_ptr;
+  MPI_Request *reqs;
+
+  int i, rank, num_procs;
+  int tag = 1;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+
+  if (rank != root) {
+    smpi_mpi_recv(buff, count, data_type, root, tag, comm, MPI_STATUS_IGNORE);
+  }
+
+  else {
+    reqs = (MPI_Request *) xbt_malloc((num_procs - 1) * sizeof(MPI_Request));
+    req_ptr = reqs;
+
+    // Root sends data to all others
+    for (i = 0; i < num_procs; i++) {
+      if (i == rank)
+        continue;
+      *(req_ptr++) = smpi_mpi_isend(buff, count, data_type, i, tag, comm);
+    }
+
+    // wait on all requests
+    smpi_mpi_waitall(num_procs - 1, reqs, MPI_STATUSES_IGNORE);
+
+    free(reqs);
+  }
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-scatter-LR-allgather.c b/src/smpi/colls/bcast-scatter-LR-allgather.c
new file mode 100644 (file)
index 0000000..ebd5539
--- /dev/null
@@ -0,0 +1,172 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+
+ * Function: bcast_scatter_LR_allgather
+
+ * Return: int
+
+ * Inputs:
+    buff: send input buffer
+    count: number of elements to send
+    data_type: data type of elements being sent
+    root: source of data
+    comm: communicator
+
+ * Descrp: broadcasts using a scatter followed by LR allgather.
+
+ * Auther: MPIH / modified by Ahmad Faraj
+
+ ****************************************************************************/
+int
+smpi_coll_tuned_bcast_scatter_LR_allgather(void *buff, int count,
+                                           MPI_Datatype data_type, int root,
+                                           MPI_Comm comm)
+{
+  MPI_Aint extent;
+  MPI_Status status;
+  int i, src, dst, rank, num_procs;
+  int mask, relative_rank, curr_size, recv_size, send_size, nbytes;
+  int scatter_size, left, right, next_src, *recv_counts, *disps;
+  int tag = 1;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(data_type);
+
+
+  nbytes = extent * count;
+  scatter_size = (nbytes + num_procs - 1) / num_procs;  // ceiling division 
+  curr_size = (rank == root) ? nbytes : 0;      // root starts with all the data
+  relative_rank = (rank >= root) ? rank - root : rank - root + num_procs;
+
+  mask = 0x1;
+  while (mask < num_procs) {
+    if (relative_rank & mask) {
+      src = rank - mask;
+      if (src < 0)
+        src += num_procs;
+      recv_size = nbytes - relative_rank * scatter_size;
+      //  recv_size is larger than what might actually be sent by the
+      //  sender. We don't need compute the exact value because MPI
+      //  allows you to post a larger recv.
+      if (recv_size <= 0)
+        curr_size = 0;          // this process doesn't receive any data
+      // because of uneven division 
+      else {
+        smpi_mpi_recv((char *) buff + relative_rank * scatter_size, recv_size,
+                 MPI_BYTE, src, tag, comm, &status);
+        curr_size = smpi_mpi_get_count(&status, MPI_BYTE);
+      }
+      break;
+    }
+    mask <<= 1;
+  }
+
+  // This process is responsible for all processes that have bits
+  // set from the LSB upto (but not including) mask.  Because of
+  // the "not including", we start by shifting mask back down
+  // one.
+
+  mask >>= 1;
+  while (mask > 0) {
+    if (relative_rank + mask < num_procs) {
+      send_size = curr_size - scatter_size * mask;
+      // mask is also the size of this process's subtree 
+
+      if (send_size > 0) {
+        dst = rank + mask;
+        if (dst >= num_procs)
+          dst -= num_procs;
+        smpi_mpi_send((char *) buff + scatter_size * (relative_rank + mask),
+                 send_size, MPI_BYTE, dst, tag, comm);
+
+        curr_size -= send_size;
+      }
+    }
+    mask >>= 1;
+  }
+
+  // done scatter now do allgather
+  recv_counts = (int *) xbt_malloc(sizeof(int) * num_procs);
+  disps = (int *) xbt_malloc(sizeof(int) * num_procs);
+
+  for (i = 0; i < num_procs; i++) {
+    recv_counts[i] = nbytes - i * scatter_size;
+    if (recv_counts[i] > scatter_size)
+      recv_counts[i] = scatter_size;
+    if (recv_counts[i] < 0)
+      recv_counts[i] = 0;
+  }
+
+  disps[0] = 0;
+  for (i = 1; i < num_procs; i++)
+    disps[i] = disps[i - 1] + recv_counts[i - 1];
+
+  left = (num_procs + rank - 1) % num_procs;
+  right = (rank + 1) % num_procs;
+
+  src = rank;
+  next_src = left;
+
+  for (i = 1; i < num_procs; i++) {
+    smpi_mpi_sendrecv((char *) buff + disps[(src - root + num_procs) % num_procs],
+                 recv_counts[(src - root + num_procs) % num_procs],
+                 MPI_BYTE, right, tag,
+                 (char *) buff +
+                 disps[(next_src - root + num_procs) % num_procs],
+                 recv_counts[(next_src - root + num_procs) % num_procs],
+                 MPI_BYTE, left, tag, comm, &status);
+    src = next_src;
+    next_src = (num_procs + next_src - 1) % num_procs;
+  }
+
+
+  free(recv_counts);
+  free(disps);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/bcast-scatter-rdb-allgather.c b/src/smpi/colls/bcast-scatter-rdb-allgather.c
new file mode 100644 (file)
index 0000000..ab458e4
--- /dev/null
@@ -0,0 +1,236 @@
+#include "colls_private.h"
+
+/*****************************************************************************
+
+Copyright (c) 2006, Ahmad Faraj & Xin Yuan,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the name of the Florida State University nor the names of its
+    contributors may be used to endorse or promote products derived from this
+    software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  *************************************************************************
+  *     Any results obtained from executing this software require the     *
+  *     acknowledgment and citation of the software and its owners.       *
+  *     The full citation is given below:                                 *
+  *                                                                       *
+  *     A. Faraj and X. Yuan. "Automatic Generation and Tuning of MPI     *
+  *     Collective Communication Routines." The 19th ACM International    *
+  *     Conference on Supercomputing (ICS), Cambridge, Massachusetts,     *
+  *     June 20-22, 2005.                                                 *
+  *************************************************************************
+
+*****************************************************************************/
+
+/*****************************************************************************
+
+ * Function: bcast_scatter_rdb_allgather
+
+ * Return: int
+
+ * Inputs:
+    buff: send input buffer
+    count: number of elements to send
+    data_type: data type of elements being sent
+    root: source of data
+    comm: communicator
+
+ * Descrp: broadcasts using a scatter followed by rdb allgather.
+
+ * Auther: MPICH / modified by Ahmad Faraj
+
+ ****************************************************************************/
+
+int
+smpi_coll_tuned_bcast_scatter_rdb_allgather(void *buff, int count, MPI_Datatype
+                                            data_type, int root, MPI_Comm comm)
+{
+  MPI_Aint extent;
+  MPI_Status status;
+
+  int i, j, k, src, dst, rank, num_procs, send_offset, recv_offset;
+  int mask, relative_rank, curr_size, recv_size = 0, send_size, nbytes;
+  int scatter_size, tree_root, relative_dst, dst_tree_root;
+  int my_tree_root, offset, tmp_mask, num_procs_completed;
+  int tag = 1;
+
+  rank = smpi_comm_rank(comm);
+  num_procs = smpi_comm_size(comm);
+  extent = smpi_datatype_get_extent(data_type);
+
+  nbytes = extent * count;
+  scatter_size = (nbytes + num_procs - 1) / num_procs;  // ceiling division 
+  curr_size = (rank == root) ? nbytes : 0;      // root starts with all the data
+  relative_rank = (rank >= root) ? rank - root : rank - root + num_procs;
+
+  mask = 0x1;
+  while (mask < num_procs) {
+    if (relative_rank & mask) {
+      src = rank - mask;
+      if (src < 0)
+        src += num_procs;
+      recv_size = nbytes - relative_rank * scatter_size;
+      //  recv_size is larger than what might actually be sent by the
+      //  sender. We don't need compute the exact value because MPI
+      //  allows you to post a larger recv.
+      if (recv_size <= 0)
+        curr_size = 0;          // this process doesn't receive any data
+      // because of uneven division 
+      else {
+        smpi_mpi_recv((char *)buff + relative_rank * scatter_size, recv_size,
+                 MPI_BYTE, src, tag, comm, &status);
+        curr_size = smpi_mpi_get_count(&status, MPI_BYTE);
+      }
+      break;
+    }
+    mask <<= 1;
+  }
+
+  // This process is responsible for all processes that have bits
+  // set from the LSB upto (but not including) mask.  Because of
+  // the "not including", we start by shifting mask back down
+  // one.
+
+  mask >>= 1;
+  while (mask > 0) {
+    if (relative_rank + mask < num_procs) {
+      send_size = curr_size - scatter_size * mask;
+      // mask is also the size of this process's subtree 
+
+      if (send_size > 0) {
+        dst = rank + mask;
+        if (dst >= num_procs)
+          dst -= num_procs;
+        smpi_mpi_send((char *)buff + scatter_size * (relative_rank + mask),
+                 send_size, MPI_BYTE, dst, tag, comm);
+
+        curr_size -= send_size;
+      }
+    }
+    mask >>= 1;
+  }
+
+  // done scatter now do allgather
+
+
+  mask = 0x1;
+  i = 0;
+  while (mask < num_procs) {
+    relative_dst = relative_rank ^ mask;
+
+    dst = (relative_dst + root) % num_procs;
+
+    /* find offset into send and recv buffers.
+       zero out the least significant "i" bits of relative_rank and
+       relative_dst to find root of src and dst
+       subtrees. Use ranks of roots as index to send from
+       and recv into  buffer */
+
+    dst_tree_root = relative_dst >> i;
+    dst_tree_root <<= i;
+
+    my_tree_root = relative_rank >> i;
+    my_tree_root <<= i;
+
+    send_offset = my_tree_root * scatter_size;
+    recv_offset = dst_tree_root * scatter_size;
+
+    if (relative_dst < num_procs) {
+      smpi_mpi_sendrecv((char *)buff + send_offset, curr_size, MPI_BYTE, dst, tag,
+                   (char *)buff + recv_offset, scatter_size * mask, MPI_BYTE, dst,
+                   tag, comm, &status);
+      recv_size = smpi_mpi_get_count(&status, MPI_BYTE);
+      curr_size += recv_size;
+    }
+
+    /* if some processes in this process's subtree in this step
+       did not have any destination process to communicate with
+       because of non-power-of-two, we need to send them the
+       data that they would normally have received from those
+       processes. That is, the haves in this subtree must send to
+       the havenots. We use a logarithmic recursive-halfing algorithm
+       for this. */
+
+    if (dst_tree_root + mask > num_procs) {
+      num_procs_completed = num_procs - my_tree_root - mask;
+      /* num_procs_completed is the number of processes in this
+         subtree that have all the data. Send data to others
+         in a tree fashion. First find root of current tree
+         that is being divided into two. k is the number of
+         least-significant bits in this process's rank that
+         must be zeroed out to find the rank of the root */
+      j = mask;
+      k = 0;
+      while (j) {
+        j >>= 1;
+        k++;
+      }
+      k--;
+
+      offset = scatter_size * (my_tree_root + mask);
+      tmp_mask = mask >> 1;
+
+      while (tmp_mask) {
+        relative_dst = relative_rank ^ tmp_mask;
+        dst = (relative_dst + root) % num_procs;
+
+        tree_root = relative_rank >> k;
+        tree_root <<= k;
+
+        /* send only if this proc has data and destination
+           doesn't have data. */
+
+        if ((relative_dst > relative_rank)
+            && (relative_rank < tree_root + num_procs_completed)
+            && (relative_dst >= tree_root + num_procs_completed)) {
+          smpi_mpi_send((char *)buff + offset, recv_size, MPI_BYTE, dst, tag, comm);
+
+          /* recv_size was set in the previous
+             receive. that's the amount of data to be
+             sent now. */
+        }
+        /* recv only if this proc. doesn't have data and sender
+           has data */
+        else if ((relative_dst < relative_rank)
+                 && (relative_dst < tree_root + num_procs_completed)
+                 && (relative_rank >= tree_root + num_procs_completed)) {
+
+          smpi_mpi_recv((char *)buff + offset, scatter_size * num_procs_completed,
+                   MPI_BYTE, dst, tag, comm, &status);
+
+          /* num_procs_completed is also equal to the no. of processes
+             whose data we don't have */
+          recv_size = smpi_mpi_get_count(&status, MPI_BYTE);
+          curr_size += recv_size;
+        }
+        tmp_mask >>= 1;
+        k--;
+      }
+    }
+    mask <<= 1;
+    i++;
+  }
+
+  return MPI_SUCCESS;
+}
index 15d28ff..17c245d 100644 (file)
 #ifndef SMPI_COLLS_H
 #define SMPI_COLLS_H
 
+#include <math.h>
 #include "smpi/mpi.h"
+#include "smpi/private.h"
 #include "xbt.h"
 
-int smpi_coll_tuned_alltoall_2dmesh(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_3dmesh(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-/*int smpi_coll_tuned_alltoall_bruck(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);*/
-int smpi_coll_tuned_alltoall_pair(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_pair_light_barrier(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_pair_mpi_barrier(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_pair_one_barrier(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_rdb(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_ring(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_ring_light_barrier(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_ring_mpi_barrier(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_ring_one_barrier(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-int smpi_coll_tuned_alltoall_simple(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
-
-
-int smpi_coll_tuned_allgather_2dmesh(
-  void * send_buff, int send_count, MPI_Datatype send_type,
-  void * recv_buff, int recv_count, MPI_Datatype recv_type,
-  MPI_Comm comm);
+#define COLL_DESCRIPTION(cat, ret, args, name) \
+  {# name,\
+   # cat " " # name " collective",\
+   smpi_coll_tuned_ ## cat ## _ ## name}
+
+#define COLL_PROTO(cat, ret, args, name) \
+  ret smpi_coll_tuned_ ## cat ## _ ## name(COLL_UNPAREN args);
+#define COLL_UNPAREN(...)  __VA_ARGS__
+
+#define COLL_APPLY(action, sig, name) action(sig, name)
+#define COLL_COMMA ,
+#define COLL_NOsep 
+#define COLL_NOTHING(...) 
+
+
+/*************
+ * ALLGATHER *
+ *************/
+#define COLL_ALLGATHER_SIG allgather, int, \
+                         (void *send_buff, int send_count, MPI_Datatype send_type, \
+                          void *recv_buff, int recv_count, MPI_Datatype recv_type, \
+                           MPI_Comm comm)
+
+#define COLL_ALLGATHERS(action, COLL_sep) \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, 2dmesh) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, 3dmesh) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, bruck) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, GB) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, loosely_lr) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, lr) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, NTSLR) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, NTSLR_NB) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, pair) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, rdb) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, rhv) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, ring) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, SMP_NTS) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, smp_simple) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHER_SIG, spreading_simple)
+
+COLL_ALLGATHERS(COLL_PROTO, COLL_NOsep)
+
+/**************
+ * ALLGATHERV *
+ **************/
+#define COLL_ALLGATHERV_SIG allgatherv, int, \
+                         (void *send_buff, int send_count, MPI_Datatype send_type, \
+                          void *recv_buff, int *recv_count, int *recv_disps, \
+                          MPI_Datatype recv_type, MPI_Comm comm)
+
+#define COLL_ALLGATHERVS(action, COLL_sep) \
+COLL_APPLY(action, COLL_ALLGATHERV_SIG, GB) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHERV_SIG, pair) COLL_sep \
+COLL_APPLY(action, COLL_ALLGATHERV_SIG, ring)
+
+COLL_ALLGATHERVS(COLL_PROTO, COLL_NOsep)
+
+/*************
+ * ALLREDUCE *
+ *************/
+#define COLL_ALLREDUCE_SIG allreduce, int, \
+                         (void *sbuf, void *rbuf, int rcount, \
+                           MPI_Datatype dtype, MPI_Op op, MPI_Comm comm)
+
+#define COLL_ALLREDUCES(action, COLL_sep) \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, lr) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, NTS) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, rab1) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, rab2) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, rab_rdb) COLL_sep \
+COLL_NOTHING(COLL_APPLY(action, COLL_ALLREDUCE_SIG, rab_reduce_scatter) COLL_sep) \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, rab_rsag) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, rdb) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, smp_binomial) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, smp_binomial_pipeline) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, smp_rdb) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, smp_rsag) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, smp_rsag_lr) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, smp_rsag_rab) COLL_sep \
+COLL_APPLY(action, COLL_ALLREDUCE_SIG, redbcast)
+
+COLL_ALLREDUCES(COLL_PROTO, COLL_NOsep)
+
+
+/************
+ * ALLTOALL *
+ ************/
+#define COLL_ALLTOALL_SIG alltoall, int, \
+                        (void *send_buff, int send_count, MPI_Datatype send_type, \
+                         void *recv_buff, int recv_count, MPI_Datatype recv_type, \
+                          MPI_Comm com)
+
+#define COLL_ALLTOALLS(action, COLL_sep) \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, 2dmesh) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, 3dmesh) COLL_sep \
+COLL_NOTHING(COLL_APPLY(action, COLL_ALLTOALL_SIG, bruck) COLL_sep) \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, pair) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, pair_light_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, pair_mpi_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, pair_one_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, rdb) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, ring) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, ring_light_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, ring_mpi_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, ring_one_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALL_SIG, simple)
+
+COLL_ALLTOALLS(COLL_PROTO, COLL_NOsep)
+
+/*************
+ * ALLTOALLV *
+ *************/
+#define COLL_ALLTOALLV_SIG alltoallv, int, \
+                        (void *send_buff, int *send_counts, int *send_disps, MPI_Datatype send_type, \
+                         void *recv_buff, int *recv_counts, int *recv_disps, MPI_Datatype recv_type, \
+                          MPI_Comm com)
+
+#define COLL_ALLTOALLVS(action, COLL_sep) \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, bruck) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, pair) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, pair_light_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, pair_mpi_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, pair_one_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_light_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_mpi_barrier) COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_one_barrier)
+
+COLL_ALLTOALLVS(COLL_PROTO, COLL_NOsep)
+
+/*********
+ * BCAST *
+ *********/
+#define COLL_BCAST_SIG bcast, int, \
+                     (void *buf, int count, MPI_Datatype datatype, \
+                      int root, MPI_Comm comm)
+
+#define COLL_BCASTS(action, COLL_sep) \
+COLL_APPLY(action, COLL_BCAST_SIG, arrival_nb) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, arrival_pattern_aware) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, arrival_pattern_aware_wait) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, arrival_scatter) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, binomial_tree) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, flattree) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, flattree_pipeline) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, NTSB) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, NTSL) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, NTSL_Isend) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, scatter_LR_allgather) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, scatter_rdb_allgather) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, SMP_binary) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, SMP_binomial) COLL_sep \
+COLL_APPLY(action, COLL_BCAST_SIG, SMP_linear)
+
+COLL_BCASTS(COLL_PROTO, COLL_NOsep)
+
+
+/**********
+ * REDUCE *
+ **********/
+#define COLL_REDUCE_SIG reduce, int, \
+                      (void *buf, void *rbuf, int count, MPI_Datatype datatype, \
+                        MPI_Op op, int root, MPI_Comm comm)
+
+#define COLL_REDUCES(action, COLL_sep) \
+COLL_APPLY(action, COLL_REDUCE_SIG, arrival_pattern_aware) COLL_sep \
+COLL_APPLY(action, COLL_REDUCE_SIG, binomial) COLL_sep \
+COLL_APPLY(action, COLL_REDUCE_SIG, flat_tree) COLL_sep \
+COLL_APPLY(action, COLL_REDUCE_SIG, NTSL) COLL_sep \
+COLL_APPLY(action, COLL_REDUCE_SIG, scatter_gather)
+
+COLL_REDUCES(COLL_PROTO, COLL_NOsep)
 
 #endif
diff --git a/src/smpi/colls/colls_global.c b/src/smpi/colls/colls_global.c
new file mode 100644 (file)
index 0000000..65d5285
--- /dev/null
@@ -0,0 +1,4 @@
+#include "xbt.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_colls, smpi,
+                                "Logging specific to SMPI collectives");
diff --git a/src/smpi/colls/colls_private.h b/src/smpi/colls/colls_private.h
new file mode 100644 (file)
index 0000000..66a2114
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef SMPI_COLLS_PRIVATE_H
+#define SMPI_COLLS_PRIVATE_H
+
+#include "colls.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_colls);
+
+#endif
diff --git a/src/smpi/colls/reduce-NTSL.c b/src/smpi/colls/reduce-NTSL.c
new file mode 100644 (file)
index 0000000..5a3b887
--- /dev/null
@@ -0,0 +1,146 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+int reduce_NTSL_segment_size_in_byte = 8192;
+
+/* Non-topology-specific pipelined linear-bcast function 
+   0->1, 1->2 ,2->3, ....., ->last node : in a pipeline fashion
+*/
+int smpi_coll_tuned_reduce_NTSL(void *buf, void *rbuf, int count,
+                                MPI_Datatype datatype, MPI_Op op, int root,
+                                MPI_Comm comm)
+{
+  int tag = 50;
+  MPI_Status status;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+  int rank, size;
+  int i;
+  MPI_Aint extent;
+  extent = smpi_datatype_get_extent(datatype);
+
+  rank = smpi_comm_rank(MPI_COMM_WORLD);
+  size = smpi_comm_size(MPI_COMM_WORLD);
+
+  /* source node and destination nodes (same through out the functions) */
+  int to = (rank - 1 + size) % size;
+  int from = (rank + 1) % size;
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = reduce_NTSL_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+  /* if root is not zero send to rank zero first
+     this can be modified to make it faster by using logical src, dst.
+   */
+
+  /*
+     if (root != 0) {
+     if (rank == root){
+     smpi_mpi_send(buf,count,datatype,0,tag,comm);
+     }
+     else if (rank == 0) {
+     smpi_mpi_recv(buf,count,datatype,root,tag,comm,&status);        
+     }
+     }
+   */
+
+  char *tmp_buf;
+  tmp_buf = (char *) xbt_malloc(count * extent);
+
+  smpi_mpi_sendrecv(buf, count, datatype, rank, tag, rbuf, count, datatype, rank,
+               tag, comm, &status);
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+    if (rank == root) {
+      smpi_mpi_recv(tmp_buf, count, datatype, from, tag, comm, &status);
+      smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+    } else if (rank == ((root - 1 + size) % size)) {
+      smpi_mpi_send(rbuf, count, datatype, to, tag, comm);
+    } else {
+      smpi_mpi_recv(tmp_buf, count, datatype, from, tag, comm, &status);
+      smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+      smpi_mpi_send(rbuf, count, datatype, to, tag, comm);
+    }
+    free(tmp_buf);
+    return MPI_SUCCESS;
+  }
+
+  /* pipeline */
+  else {
+    send_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    /* root recv data */
+    if (rank == root) {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) tmp_buf + (i * increment), segment, datatype, from,
+                  (tag + i), comm);
+      }
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], &status);
+        smpi_op_apply(op, tmp_buf + (i * increment), (char *)rbuf + (i * increment),
+                       &segment, &datatype);
+      }
+    }
+
+    /* last node only sends data */
+    else if (rank == ((root - 1 + size) % size)) {
+      for (i = 0; i < pipe_length; i++) {
+        send_request_array[i] = smpi_mpi_isend((char *)rbuf + (i * increment), segment, datatype, to, (tag + i),
+                  comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    /* intermediate nodes relay (receive, reduce, then send) data */
+    else {
+      for (i = 0; i < pipe_length; i++) {
+        recv_request_array[i] = smpi_mpi_irecv((char *) tmp_buf + (i * increment), segment, datatype, from,
+                  (tag + i), comm);
+      }
+      for (i = 0; i < pipe_length; i++) {
+        smpi_mpi_wait(&recv_request_array[i], &status);
+        smpi_op_apply(op, tmp_buf + (i * increment), (char *)rbuf + (i * increment),
+                       &segment, &datatype);
+        send_request_array[i] = smpi_mpi_isend((char *) rbuf + (i * increment), segment, datatype, to,
+                  (tag + i), comm);
+      }
+      smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+    }
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+  }                             /* end pipeline */
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    XBT_WARN("MPI_reduce_NTSL use default MPI_reduce.");         
+    smpi_mpi_reduce((char *)buf + (pipe_length * increment),
+               (char *)rbuf + (pipe_length * increment), remainder, datatype, op, root,
+               comm);
+  }
+
+  free(tmp_buf);
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/reduce-arrival-pattern-aware.c b/src/smpi/colls/reduce-arrival-pattern-aware.c
new file mode 100644 (file)
index 0000000..1e25250
--- /dev/null
@@ -0,0 +1,356 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+int reduce_arrival_pattern_aware_segment_size_in_byte = 8192;
+
+#ifndef HEADER_SIZE
+#define HEADER_SIZE 1024
+#endif
+
+#ifndef MAX_NODE
+#define MAX_NODE 1024
+#endif
+
+/* Non-topology-specific pipelined linear-reduce function */
+int smpi_coll_tuned_reduce_arrival_pattern_aware(void *buf, void *rbuf,
+                                                 int count,
+                                                 MPI_Datatype datatype,
+                                                 MPI_Op op, int root,
+                                                 MPI_Comm comm)
+{
+  int rank;
+  rank = smpi_comm_rank(comm);
+
+  int tag = 50;
+  MPI_Status status;
+  MPI_Request request;
+  MPI_Request *send_request_array;
+  MPI_Request *recv_request_array;
+  MPI_Status *send_status_array;
+  MPI_Status *recv_status_array;
+
+  MPI_Status temp_status_array[MAX_NODE];
+
+  int size;
+  int i;
+
+  int sent_count;
+  int header_index;
+  int flag_array[MAX_NODE];
+  int already_received[MAX_NODE];
+
+  int header_buf[HEADER_SIZE];
+  char temp_buf[MAX_NODE];
+
+  MPI_Aint extent, lb;
+  smpi_datatype_extent(datatype, &lb, &extent);
+
+  /* source and destination */
+  int to, from;
+
+  size=smpi_comm_size(comm);
+  rank=smpi_comm_rank(comm);
+
+
+  /* segment is segment size in number of elements (not bytes) */
+  int segment = reduce_arrival_pattern_aware_segment_size_in_byte / extent;
+
+  /* pipeline length */
+  int pipe_length = count / segment;
+
+  /* use for buffer offset for sending and receiving data = segment size in byte */
+  int increment = segment * extent;
+
+  /* if the input size is not divisible by segment size => 
+     the small remainder will be done with native implementation */
+  int remainder = count % segment;
+
+
+  /* value == 0 means root has not send data (or header) to the node yet */
+  for (i = 0; i < MAX_NODE; i++) {
+    already_received[i] = 0;
+  }
+
+  char *tmp_buf;
+  tmp_buf = (char *) xbt_malloc(count * extent);
+
+  smpi_mpi_sendrecv(buf, count, datatype, rank, tag, rbuf, count, datatype, rank,
+               tag, comm, &status);
+
+
+
+  /* when a message is smaller than a block size => no pipeline */
+  if (count <= segment) {
+
+    if (rank == 0) {
+      sent_count = 0;
+
+      while (sent_count < (size - 1)) {
+
+        for (i = 1; i < size; i++) {
+          if (already_received[i] == 0) {
+            smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                             MPI_STATUSES_IGNORE);
+            simcall_process_sleep(0.0001);
+            }
+        }
+
+        header_index = 0;
+        /* recv 1-byte message */
+        for (i = 0; i < size; i++) {
+          if (i == rank)
+            continue;
+
+          /* 1-byte message arrive */
+          if ((flag_array[i] == 1) && (already_received[i] == 0)) {
+            smpi_mpi_recv(temp_buf, 1, MPI_CHAR, i, tag, MPI_COMM_WORLD, &status);
+            header_buf[header_index] = i;
+            header_index++;
+            sent_count++;
+
+
+            //printf("root send to %d recv from %d : data = ",to,from);
+            /*
+               for (i=0;i<=header_index;i++) {
+               printf("%d ",header_buf[i]);
+               }
+               printf("\n");
+             */
+            /* will receive in the next step */
+            already_received[i] = 1;
+          }
+        }
+
+        /* send header followed by receive and reduce data */
+        if (header_index != 0) {
+          header_buf[header_index] = -1;
+          to = header_buf[0];
+          from = header_buf[header_index - 1];
+
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+          smpi_mpi_recv(tmp_buf, count, datatype, from, tag, comm, &status);
+          smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+        }
+      }                         /* while loop */
+    }
+
+    /* root */
+    /* non-root */
+    else {
+
+      /* send 1-byte message to root */
+      smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+      /* wait for header and data, forward when required */
+      smpi_mpi_recv(header_buf, HEADER_SIZE, MPI_INT, MPI_ANY_SOURCE, tag, comm,
+               &status);
+      //      smpi_mpi_recv(buf,count,datatype,MPI_ANY_SOURCE,tag,comm,&status);
+
+      /* search for where it is */
+      int myordering = 0;
+      while (rank != header_buf[myordering]) {
+        myordering++;
+      }
+
+      /* forward header */
+      if (header_buf[myordering + 1] != -1) {
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, header_buf[myordering + 1],
+                 tag, comm);
+      }
+      //printf("node %d ordering %d\n",rank,myordering);
+
+      /* receive, reduce, and forward data */
+
+      /* send only */
+      if (myordering == 0) {
+        if (header_buf[myordering + 1] == -1) {
+          to = 0;
+        } else {
+          to = header_buf[myordering + 1];
+        }
+        smpi_mpi_send(rbuf, count, datatype, to, tag, comm);
+      }
+
+      /* recv, reduce, send */
+      else {
+        if (header_buf[myordering + 1] == -1) {
+          to = 0;
+        } else {
+          to = header_buf[myordering + 1];
+        }
+        from = header_buf[myordering - 1];
+        smpi_mpi_recv(tmp_buf, count, datatype, header_buf[myordering - 1], tag,
+                 comm, &status);
+        smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+        smpi_mpi_send(rbuf, count, datatype, to, tag, comm);
+      }
+    }                           /* non-root */
+  }
+  /* pipeline bcast */
+  else {
+    //    printf("node %d start\n",rank);
+
+    send_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    recv_request_array =
+        (MPI_Request *) xbt_malloc((size + pipe_length) * sizeof(MPI_Request));
+    send_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+    recv_status_array =
+        (MPI_Status *) xbt_malloc((size + pipe_length) * sizeof(MPI_Status));
+
+    if (rank == 0) {
+      sent_count = 0;
+
+      int will_send[MAX_NODE];
+      for (i = 0; i < MAX_NODE; i++)
+        will_send[i] = 0;
+
+      /* loop until all data are received (sent) */
+      while (sent_count < (size - 1)) {
+        int k;
+        for (k = 0; k < 1; k++) {
+          for (i = 1; i < size; i++) {
+            //if (i == rank)
+            //continue;
+            if ((already_received[i] == 0) && (will_send[i] == 0)) {
+                smpi_mpi_iprobe(i, MPI_ANY_TAG, MPI_COMM_WORLD, &flag_array[i],
+                         &temp_status_array[i]);
+              if (flag_array[i] == 1) {
+                will_send[i] = 1;
+                smpi_mpi_recv(&temp_buf[i], 1, MPI_CHAR, i, tag, MPI_COMM_WORLD,
+                         &status);
+                //printf("recv from %d\n",i);
+                i = 1;
+              }
+            }
+          }
+        }                       /* end of probing */
+
+        header_index = 0;
+
+        /* recv 1-byte message */
+        for (i = 1; i < size; i++) {
+          //if (i==rank)
+          //continue;
+          /* message arrived in this round (put in the header) */
+          if ((will_send[i] == 1) && (already_received[i] == 0)) {
+            header_buf[header_index] = i;
+            header_index++;
+            sent_count++;
+
+            /* will send in the next step */
+            already_received[i] = 1;
+          }
+        }
+
+        /* send header followed by data */
+        if (header_index != 0) {
+          header_buf[header_index] = -1;
+          to = header_buf[0];
+
+          /* send header */
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
+
+          /* recv data - pipeline */
+          from = header_buf[header_index - 1];
+          for (i = 0; i < pipe_length; i++) {
+            smpi_mpi_recv(tmp_buf + (i * increment), segment, datatype, from, tag,
+                     comm, &status);
+            smpi_op_apply(op, tmp_buf + (i * increment),
+                           (char *)rbuf + (i * increment), &segment, &datatype);
+          }
+        }
+      }                         /* while loop (sent_count < size-1 ) */
+    }
+
+    /* root */
+    /* none root */
+    else {
+      /* send 1-byte message to root */
+      smpi_mpi_send(temp_buf, 1, MPI_CHAR, 0, tag, comm);
+
+
+      /* wait for header forward when required */
+      request=smpi_mpi_irecv(header_buf, HEADER_SIZE, MPI_INT, MPI_ANY_SOURCE, tag, comm);
+      smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+
+      /* search for where it is */
+      int myordering = 0;
+
+      while (rank != header_buf[myordering]) {
+        myordering++;
+      }
+
+      /* send header when required */
+      if (header_buf[myordering + 1] != -1) {
+          smpi_mpi_send(header_buf, HEADER_SIZE, MPI_INT, header_buf[myordering + 1],
+                 tag, comm);
+      }
+
+      /* (receive, reduce), and send data */
+      if (header_buf[myordering + 1] == -1) {
+        to = 0;
+      } else {
+        to = header_buf[myordering + 1];
+      }
+
+      /* send only */
+      if (myordering == 0) {
+        for (i = 0; i < pipe_length; i++) {
+            send_request_array[i]= smpi_mpi_isend((char *)rbuf + (i * increment), segment, datatype, to, tag, comm);
+        }
+        smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+      }
+
+      /* receive, reduce, and send */
+      else {
+        from = header_buf[myordering - 1];
+        for (i = 0; i < pipe_length; i++) {
+          recv_request_array[i]=smpi_mpi_irecv(tmp_buf + (i * increment), segment, datatype, from, tag, comm);
+        }
+        for (i = 0; i < pipe_length; i++) {
+          smpi_mpi_wait(&recv_request_array[i], MPI_STATUS_IGNORE);
+          smpi_op_apply(op, tmp_buf + (i * increment), (char *)rbuf + (i * increment),
+                         &segment, &datatype);
+          send_request_array[i]=smpi_mpi_isend((char *)rbuf + (i * increment), segment, datatype, to, tag, comm);
+        }
+        smpi_mpi_waitall((pipe_length), send_request_array, send_status_array);
+      }
+    }                           /* non-root */
+
+
+
+
+    free(send_request_array);
+    free(recv_request_array);
+    free(send_status_array);
+    free(recv_status_array);
+
+    //printf("node %d done\n",rank);
+  }                             /* end pipeline */
+
+
+  /* if root is not zero send root after finished
+     this can be modified to make it faster by using logical src, dst.
+   */
+  if (root != 0) {
+    if (rank == 0) {
+      smpi_mpi_send(rbuf, count, datatype, root, tag, comm);
+    } else if (rank == root) {
+      smpi_mpi_recv(rbuf, count, datatype, 0, tag, comm, &status);
+    }
+  }
+
+
+  /* when count is not divisible by block size, use default BCAST for the remainder */
+  if ((remainder != 0) && (count > segment)) {
+    smpi_mpi_reduce((char *)buf + (pipe_length * increment),
+              (char *)rbuf + (pipe_length * increment), remainder, datatype, op, root,
+               comm);
+  }
+
+  free(tmp_buf);
+
+  return MPI_SUCCESS;
+}
diff --git a/src/smpi/colls/reduce-binomial.c b/src/smpi/colls/reduce-binomial.c
new file mode 100644 (file)
index 0000000..63de8fe
--- /dev/null
@@ -0,0 +1,51 @@
+#include "colls_private.h"
+
+//#include <star-reduction.c>
+
+int smpi_coll_tuned_reduce_binomial(void *sendbuf, void *recvbuf, int count,
+                                    MPI_Datatype datatype, MPI_Op op, int root,
+                                    MPI_Comm comm)
+{
+  MPI_Status status;
+  int comm_size, rank;
+  int mask, relrank, source;
+  int dst;
+  int tag = 4321;
+  MPI_Aint extent;
+  void *tmp_buf;
+
+  if (count == 0)
+    return 0;
+  rank = smpi_comm_rank(comm);
+  comm_size = smpi_comm_size(comm);
+
+  extent = smpi_datatype_get_extent(datatype);
+
+  tmp_buf = (void *) xbt_malloc(count * extent);
+
+  smpi_mpi_sendrecv(sendbuf, count, datatype, rank, tag,
+               recvbuf, count, datatype, rank, tag, comm, &status);
+  mask = 1;
+  relrank = (rank - root + comm_size) % comm_size;
+
+  while (mask < comm_size) {
+    /* Receive */
+    if ((mask & relrank) == 0) {
+      source = (relrank | mask);
+      if (source < comm_size) {
+        source = (source + root) % comm_size;
+        smpi_mpi_recv(tmp_buf, count, datatype, source, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recvbuf, &count, &datatype);
+      }
+    } else {
+      dst = ((relrank & (~mask)) + root) % comm_size;
+      smpi_mpi_send(recvbuf, count, datatype, dst, tag, comm);
+      break;
+    }
+    mask <<= 1;
+  }
+
+  free(tmp_buf);
+
+  return 0;
+}
diff --git a/src/smpi/colls/reduce-flat-tree.c b/src/smpi/colls/reduce-flat-tree.c
new file mode 100644 (file)
index 0000000..f304e78
--- /dev/null
@@ -0,0 +1,62 @@
+#include "colls_private.h"
+//#include <star-reduction.c>
+
+int
+smpi_coll_tuned_reduce_flat_tree(void *sbuf, void *rbuf, int count,
+                                 MPI_Datatype dtype, MPI_Op op,
+                                 int root, MPI_Comm comm)
+{
+  int i, tag = 4321;
+  int size;
+  int rank;
+  MPI_Aint extent;
+  char *origin = 0;
+  char *inbuf;
+  MPI_Status status;
+
+  rank = smpi_comm_rank(comm);
+  size = smpi_comm_size(comm);
+
+  /* If not root, send data to the root. */
+  extent = smpi_datatype_get_extent(dtype);
+
+  if (rank != root) {
+    smpi_mpi_send(sbuf, count, dtype, root, tag, comm);
+    return 0;
+  }
+
+  /* Root receives and reduces messages.  Allocate buffer to receive
+     messages. */
+
+  if (size > 1)
+    origin = (char *) xbt_malloc(count * extent);
+
+
+  /* Initialize the receive buffer. */
+  if (rank == (size - 1))
+    smpi_mpi_sendrecv(sbuf, count, dtype, rank, tag,
+                 rbuf, count, dtype, rank, tag, comm, &status);
+  else
+    smpi_mpi_recv(rbuf, count, dtype, size - 1, tag, comm, &status);
+
+  /* Loop receiving and calling reduction function (C or Fortran). */
+
+  for (i = size - 2; i >= 0; --i) {
+    if (rank == i)
+      inbuf = sbuf;
+    else {
+      smpi_mpi_recv(origin, count, dtype, i, tag, comm, &status);
+      inbuf = origin;
+    }
+
+    /* Call reduction function. */
+    smpi_op_apply(op, inbuf, rbuf, &count, &dtype);
+
+  }
+
+  if (origin)
+    free(origin);
+
+  /* All done */
+  return 0;
+}
diff --git a/src/smpi/colls/reduce-scatter-gather.c b/src/smpi/colls/reduce-scatter-gather.c
new file mode 100644 (file)
index 0000000..2c61d48
--- /dev/null
@@ -0,0 +1,396 @@
+#include "colls_private.h"
+
+/*
+  reduce
+  Author: MPICH
+ */
+
+int smpi_coll_tuned_reduce_scatter_gather(void *sendbuf, void *recvbuf,
+                                          int count, MPI_Datatype datatype,
+                                          MPI_Op op, int root, MPI_Comm comm)
+{
+  MPI_Status status;
+  int comm_size, rank, pof2, rem, newrank;
+  int mask, *cnts, *disps, i, j, send_idx = 0;
+  int recv_idx, last_idx = 0, newdst;
+  int dst, send_cnt, recv_cnt, newroot, newdst_tree_root;
+  int newroot_tree_root, new_count;
+  int tag = 4321;
+  void *send_ptr, *recv_ptr, *tmp_buf;
+
+  cnts = NULL;
+  disps = NULL;
+
+  MPI_Aint extent;
+
+  if (count == 0)
+    return 0;
+  rank = smpi_comm_rank(comm);
+  comm_size = smpi_comm_size(comm);
+
+  extent = smpi_datatype_get_extent(datatype);
+
+  /* find nearest power-of-two less than or equal to comm_size */
+  pof2 = 1;
+  while (pof2 <= comm_size)
+    pof2 <<= 1;
+  pof2 >>= 1;
+
+  if (count < comm_size) {
+    new_count = comm_size;
+    send_ptr = (void *) xbt_malloc(new_count * extent);
+    recv_ptr = (void *) xbt_malloc(new_count * extent);
+    tmp_buf = (void *) xbt_malloc(new_count * extent);
+    memcpy(send_ptr, sendbuf, extent * count);
+
+    //if ((rank != root))
+    smpi_mpi_sendrecv(send_ptr, new_count, datatype, rank, tag,
+                 recv_ptr, new_count, datatype, rank, tag, comm, &status);
+
+    rem = comm_size - pof2;
+    if (rank < 2 * rem) {
+      if (rank % 2 != 0) {
+        /* odd */
+        smpi_mpi_send(recv_ptr, new_count, datatype, rank - 1, tag, comm);
+        newrank = -1;
+      } else {
+        smpi_mpi_recv(tmp_buf, count, datatype, rank + 1, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recv_ptr, &new_count, &datatype);
+        newrank = rank / 2;
+      }
+    } else                      /* rank >= 2*rem */
+      newrank = rank - rem;
+
+    cnts = (int *) xbt_malloc(pof2 * sizeof(int));
+    disps = (int *) xbt_malloc(pof2 * sizeof(int));
+
+    if (newrank != -1) {
+      for (i = 0; i < (pof2 - 1); i++)
+        cnts[i] = new_count / pof2;
+      cnts[pof2 - 1] = new_count - (new_count / pof2) * (pof2 - 1);
+
+      disps[0] = 0;
+      for (i = 1; i < pof2; i++)
+        disps[i] = disps[i - 1] + cnts[i - 1];
+
+      mask = 0x1;
+      send_idx = recv_idx = 0;
+      last_idx = pof2;
+      while (mask < pof2) {
+        newdst = newrank ^ mask;
+        /* find real rank of dest */
+        dst = (newdst < rem) ? newdst * 2 : newdst + rem;
+
+        send_cnt = recv_cnt = 0;
+        if (newrank < newdst) {
+          send_idx = recv_idx + pof2 / (mask * 2);
+          for (i = send_idx; i < last_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < send_idx; i++)
+            recv_cnt += cnts[i];
+        } else {
+          recv_idx = send_idx + pof2 / (mask * 2);
+          for (i = send_idx; i < recv_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < last_idx; i++)
+            recv_cnt += cnts[i];
+        }
+
+        /* Send data from recvbuf. Recv into tmp_buf */
+        smpi_mpi_sendrecv((char *) recv_ptr +
+                     disps[send_idx] * extent,
+                     send_cnt, datatype,
+                     dst, tag,
+                     (char *) tmp_buf +
+                     disps[recv_idx] * extent,
+                     recv_cnt, datatype, dst, tag, comm, &status);
+
+        /* tmp_buf contains data received in this step.
+           recvbuf contains data accumulated so far */
+
+        smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+                       (char *) recv_ptr + disps[recv_idx] * extent,
+                       &recv_cnt, &datatype);
+
+        /* update send_idx for next iteration */
+        send_idx = recv_idx;
+        mask <<= 1;
+
+        if (mask < pof2)
+          last_idx = recv_idx + pof2 / mask;
+      }
+    }
+
+    /* now do the gather to root */
+
+    if (root < 2 * rem) {
+      if (root % 2 != 0) {
+        if (rank == root) {
+          /* recv */
+          for (i = 0; i < (pof2 - 1); i++)
+            cnts[i] = new_count / pof2;
+          cnts[pof2 - 1] = new_count - (new_count / pof2) * (pof2 - 1);
+
+          disps[0] = 0;
+          for (i = 1; i < pof2; i++)
+            disps[i] = disps[i - 1] + cnts[i - 1];
+
+          smpi_mpi_recv(recv_ptr, cnts[0], datatype, 0, tag, comm, &status);
+
+          newrank = 0;
+          send_idx = 0;
+          last_idx = 2;
+        } else if (newrank == 0) {
+          smpi_mpi_send(recv_ptr, cnts[0], datatype, root, tag, comm);
+          newrank = -1;
+        }
+        newroot = 0;
+      } else
+        newroot = root / 2;
+    } else
+      newroot = root - rem;
+
+    if (newrank != -1) {
+      j = 0;
+      mask = 0x1;
+      while (mask < pof2) {
+        mask <<= 1;
+        j++;
+      }
+      mask >>= 1;
+      j--;
+      while (mask > 0) {
+        newdst = newrank ^ mask;
+
+        /* find real rank of dest */
+        dst = (newdst < rem) ? newdst * 2 : newdst + rem;
+
+        if ((newdst == 0) && (root < 2 * rem) && (root % 2 != 0))
+          dst = root;
+        newdst_tree_root = newdst >> j;
+        newdst_tree_root <<= j;
+
+        newroot_tree_root = newroot >> j;
+        newroot_tree_root <<= j;
+
+        send_cnt = recv_cnt = 0;
+        if (newrank < newdst) {
+          /* update last_idx except on first iteration */
+          if (mask != pof2 / 2)
+            last_idx = last_idx + pof2 / (mask * 2);
+
+          recv_idx = send_idx + pof2 / (mask * 2);
+          for (i = send_idx; i < recv_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < last_idx; i++)
+            recv_cnt += cnts[i];
+        } else {
+          recv_idx = send_idx - pof2 / (mask * 2);
+          for (i = send_idx; i < last_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < send_idx; i++)
+            recv_cnt += cnts[i];
+        }
+
+        if (newdst_tree_root == newroot_tree_root) {
+          smpi_mpi_send((char *) recv_ptr +
+                   disps[send_idx] * extent,
+                   send_cnt, datatype, dst, tag, comm);
+          break;
+        } else {
+          smpi_mpi_recv((char *) recv_ptr +
+                   disps[recv_idx] * extent,
+                   recv_cnt, datatype, dst, tag, comm, &status);
+        }
+
+        if (newrank > newdst)
+          send_idx = recv_idx;
+
+        mask >>= 1;
+        j--;
+      }
+    }
+    memcpy(recvbuf, recv_ptr, extent * count);
+    free(send_ptr);
+    free(recv_ptr);
+  }
+
+
+  else if (count >= comm_size) {
+    tmp_buf = (void *) xbt_malloc(count * extent);
+
+    //if ((rank != root))
+    smpi_mpi_sendrecv(sendbuf, count, datatype, rank, tag,
+                 recvbuf, count, datatype, rank, tag, comm, &status);
+
+    rem = comm_size - pof2;
+    if (rank < 2 * rem) {
+      if (rank % 2 != 0) {      /* odd */
+        smpi_mpi_send(recvbuf, count, datatype, rank - 1, tag, comm);
+        newrank = -1;
+      }
+
+      else {
+        smpi_mpi_recv(tmp_buf, count, datatype, rank + 1, tag, comm, &status);
+        smpi_op_apply(op, tmp_buf, recvbuf, &count, &datatype);
+        newrank = rank / 2;
+      }
+    } else                      /* rank >= 2*rem */
+      newrank = rank - rem;
+
+    cnts = (int *) xbt_malloc(pof2 * sizeof(int));
+    disps = (int *) xbt_malloc(pof2 * sizeof(int));
+
+    if (newrank != -1) {
+      for (i = 0; i < (pof2 - 1); i++)
+        cnts[i] = count / pof2;
+      cnts[pof2 - 1] = count - (count / pof2) * (pof2 - 1);
+
+      disps[0] = 0;
+      for (i = 1; i < pof2; i++)
+        disps[i] = disps[i - 1] + cnts[i - 1];
+
+      mask = 0x1;
+      send_idx = recv_idx = 0;
+      last_idx = pof2;
+      while (mask < pof2) {
+        newdst = newrank ^ mask;
+        /* find real rank of dest */
+        dst = (newdst < rem) ? newdst * 2 : newdst + rem;
+
+        send_cnt = recv_cnt = 0;
+        if (newrank < newdst) {
+          send_idx = recv_idx + pof2 / (mask * 2);
+          for (i = send_idx; i < last_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < send_idx; i++)
+            recv_cnt += cnts[i];
+        } else {
+          recv_idx = send_idx + pof2 / (mask * 2);
+          for (i = send_idx; i < recv_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < last_idx; i++)
+            recv_cnt += cnts[i];
+        }
+
+        /* Send data from recvbuf. Recv into tmp_buf */
+        smpi_mpi_sendrecv((char *) recvbuf +
+                     disps[send_idx] * extent,
+                     send_cnt, datatype,
+                     dst, tag,
+                     (char *) tmp_buf +
+                     disps[recv_idx] * extent,
+                     recv_cnt, datatype, dst, tag, comm, &status);
+
+        /* tmp_buf contains data received in this step.
+           recvbuf contains data accumulated so far */
+
+        smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+                       (char *) recvbuf + disps[recv_idx] * extent,
+                       &recv_cnt, &datatype);
+
+        /* update send_idx for next iteration */
+        send_idx = recv_idx;
+        mask <<= 1;
+
+        if (mask < pof2)
+          last_idx = recv_idx + pof2 / mask;
+      }
+    }
+
+    /* now do the gather to root */
+
+    if (root < 2 * rem) {
+      if (root % 2 != 0) {
+        if (rank == root) {     /* recv */
+          for (i = 0; i < (pof2 - 1); i++)
+            cnts[i] = count / pof2;
+          cnts[pof2 - 1] = count - (count / pof2) * (pof2 - 1);
+
+          disps[0] = 0;
+          for (i = 1; i < pof2; i++)
+            disps[i] = disps[i - 1] + cnts[i - 1];
+
+          smpi_mpi_recv(recvbuf, cnts[0], datatype, 0, tag, comm, &status);
+
+          newrank = 0;
+          send_idx = 0;
+          last_idx = 2;
+        } else if (newrank == 0) {
+          smpi_mpi_send(recvbuf, cnts[0], datatype, root, tag, comm);
+          newrank = -1;
+        }
+        newroot = 0;
+      } else
+        newroot = root / 2;
+    } else
+      newroot = root - rem;
+
+    if (newrank != -1) {
+      j = 0;
+      mask = 0x1;
+      while (mask < pof2) {
+        mask <<= 1;
+        j++;
+      }
+      mask >>= 1;
+      j--;
+      while (mask > 0) {
+        newdst = newrank ^ mask;
+
+        /* find real rank of dest */
+        dst = (newdst < rem) ? newdst * 2 : newdst + rem;
+
+        if ((newdst == 0) && (root < 2 * rem) && (root % 2 != 0))
+          dst = root;
+        newdst_tree_root = newdst >> j;
+        newdst_tree_root <<= j;
+
+        newroot_tree_root = newroot >> j;
+        newroot_tree_root <<= j;
+
+        send_cnt = recv_cnt = 0;
+        if (newrank < newdst) {
+          /* update last_idx except on first iteration */
+          if (mask != pof2 / 2)
+            last_idx = last_idx + pof2 / (mask * 2);
+
+          recv_idx = send_idx + pof2 / (mask * 2);
+          for (i = send_idx; i < recv_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < last_idx; i++)
+            recv_cnt += cnts[i];
+        } else {
+          recv_idx = send_idx - pof2 / (mask * 2);
+          for (i = send_idx; i < last_idx; i++)
+            send_cnt += cnts[i];
+          for (i = recv_idx; i < send_idx; i++)
+            recv_cnt += cnts[i];
+        }
+
+        if (newdst_tree_root == newroot_tree_root) {
+          smpi_mpi_send((char *) recvbuf +
+                   disps[send_idx] * extent,
+                   send_cnt, datatype, dst, tag, comm);
+          break;
+        } else {
+          smpi_mpi_recv((char *) recvbuf +
+                   disps[recv_idx] * extent,
+                   recv_cnt, datatype, dst, tag, comm, &status);
+        }
+
+        if (newrank > newdst)
+          send_idx = recv_idx;
+
+        mask >>= 1;
+        j--;
+      }
+    }
+  }
+  if (cnts)
+    free(cnts);
+  if (disps)
+    free(disps);
+
+  return 0;
+}
index 43f8c36..f67ad5e 100644 (file)
@@ -252,10 +252,6 @@ int smpi_coll_tuned_alltoall_basic_linear(void *sendbuf, int sendcount,
                                           void *recvbuf, int recvcount,
                                           MPI_Datatype recvtype,
                                           MPI_Comm comm);
-int smpi_coll_tuned_alltoall_pairwise(void *sendbuf, int sendcount,
-                                      MPI_Datatype sendtype, void *recvbuf,
-                                      int recvcount, MPI_Datatype recvtype,
-                                      MPI_Comm comm);
 int smpi_coll_basic_alltoallv(void *sendbuf, int *sendcounts,
                               int *senddisps, MPI_Datatype sendtype,
                               void *recvbuf, int *recvcounts,
@@ -269,87 +265,101 @@ void smpi_bench_end(void);
 void smpi_execute_flops(double flops);
 
 // f77 wrappers
-void mpi_init__(int*);
-void mpi_finalize__(int*);
-void mpi_abort__(int* comm, int* errorcode, int* ierr);
-void mpi_comm_rank__(int* comm, int* rank, int* ierr);
-void mpi_comm_size__(int* comm, int* size, int* ierr);
-double mpi_wtime__(void);
-double mpi_wtick__(void);
-void mpi_initialized__(int* flag, int* ierr);
+void mpi_init_(int*);
+void mpi_finalize_(int*);
+void mpi_abort_(int* comm, int* errorcode, int* ierr);
+void mpi_comm_rank_(int* comm, int* rank, int* ierr);
+void mpi_comm_size_(int* comm, int* size, int* ierr);
+double mpi_wtime_(void);
+double mpi_wtick_(void);
+void mpi_initialized_(int* flag, int* ierr);
 
-void mpi_comm_dup__(int* comm, int* newcomm, int* ierr);
-void mpi_comm_create__(int* comm, int* group, int* newcomm, int* ierr);
-void mpi_comm_free__(int* comm, int* ierr);
-void mpi_comm_split__(int* comm, int* color, int* key, int* comm_out, int* ierr);
-void mpi_group_incl__(int* group, int* n, int* key, int* group_out, int* ierr) ;
-void mpi_comm_group__(int* comm, int* group_out,  int* ierr);
-void mpi_send_init__(void *buf, int* count, int* datatype, int* dst, int* tag,
+void mpi_comm_dup_(int* comm, int* newcomm, int* ierr);
+void mpi_comm_create_(int* comm, int* group, int* newcomm, int* ierr);
+void mpi_comm_free_(int* comm, int* ierr);
+void mpi_comm_split_(int* comm, int* color, int* key, int* comm_out, int* ierr);
+void mpi_group_incl_(int* group, int* n, int* key, int* group_out, int* ierr) ;
+void mpi_comm_group_(int* comm, int* group_out,  int* ierr);
+void mpi_send_init_(void *buf, int* count, int* datatype, int* dst, int* tag,
                      int* comm, int* request, int* ierr);
-void mpi_isend__(void *buf, int* count, int* datatype, int* dst,
+void mpi_isend_(void *buf, int* count, int* datatype, int* dst,
                  int* tag, int* comm, int* request, int* ierr);
-void mpi_irsend__(void *buf, int* count, int* datatype, int* dst,
+void mpi_irsend_(void *buf, int* count, int* datatype, int* dst,
                  int* tag, int* comm, int* request, int* ierr);
-void mpi_send__(void* buf, int* count, int* datatype, int* dst,
+void mpi_send_(void* buf, int* count, int* datatype, int* dst,
                 int* tag, int* comm, int* ierr);
-void mpi_rsend__(void* buf, int* count, int* datatype, int* dst,
+void mpi_rsend_(void* buf, int* count, int* datatype, int* dst,
                 int* tag, int* comm, int* ierr);
-void mpi_recv_init__(void *buf, int* count, int* datatype, int* src, int* tag,
+void mpi_recv_init_(void *buf, int* count, int* datatype, int* src, int* tag,
                      int* comm, int* request, int* ierr);
-void mpi_irecv__(void *buf, int* count, int* datatype, int* src, int* tag,
+void mpi_irecv_(void *buf, int* count, int* datatype, int* src, int* tag,
                  int* comm, int* request, int* ierr);
-void mpi_recv__(void* buf, int* count, int* datatype, int* src,
+void mpi_recv_(void* buf, int* count, int* datatype, int* src,
                 int* tag, int* comm, MPI_Status* status, int* ierr);
-void mpi_start__(int* request, int* ierr);
-void mpi_startall__(int* count, int* requests, int* ierr);
-void mpi_wait__(int* request, MPI_Status* status, int* ierr);
-void mpi_waitany__(int* count, int* requests, int* index, MPI_Status* status, int* ierr);
-void mpi_waitall__(int* count, int* requests, MPI_Status* status, int* ierr);
+void mpi_start_(int* request, int* ierr);
+void mpi_startall_(int* count, int* requests, int* ierr);
+void mpi_wait_(int* request, MPI_Status* status, int* ierr);
+void mpi_waitany_(int* count, int* requests, int* index, MPI_Status* status, int* ierr);
+void mpi_waitall_(int* count, int* requests, MPI_Status* status, int* ierr);
 
-void mpi_barrier__(int* comm, int* ierr);
-void mpi_bcast__(void* buf, int* count, int* datatype, int* root, int* comm, int* ierr);
-void mpi_reduce__(void* sendbuf, void* recvbuf, int* count,
+void mpi_barrier_(int* comm, int* ierr);
+void mpi_bcast_(void* buf, int* count, int* datatype, int* root, int* comm, int* ierr);
+void mpi_reduce_(void* sendbuf, void* recvbuf, int* count,
                   int* datatype, int* op, int* root, int* comm, int* ierr);
-void mpi_allreduce__(void* sendbuf, void* recvbuf, int* count, int* datatype,
+void mpi_allreduce_(void* sendbuf, void* recvbuf, int* count, int* datatype,
                      int* op, int* comm, int* ierr);
-void mpi_reduce_scatter__(void* sendbuf, void* recvbuf, int* recvcounts, int* datatype,
+void mpi_reduce_scatter_(void* sendbuf, void* recvbuf, int* recvcounts, int* datatype,
                      int* op, int* comm, int* ierr) ;
-void mpi_scatter__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_scatter_(void* sendbuf, int* sendcount, int* sendtype,
                    void* recvbuf, int* recvcount, int* recvtype,
                    int* root, int* comm, int* ierr);
-void mpi_scatterv__(void* sendbuf, int* sendcounts, int* displs, int* sendtype,
+void mpi_scatterv_(void* sendbuf, int* sendcounts, int* displs, int* sendtype,
                    void* recvbuf, int* recvcount, int* recvtype,
                    int* root, int* comm, int* ierr);
-void mpi_gather__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_gather_(void* sendbuf, int* sendcount, int* sendtype,
                   void* recvbuf, int* recvcount, int* recvtype,
                   int* root, int* comm, int* ierr);
-void mpi_gatherv__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_gatherv_(void* sendbuf, int* sendcount, int* sendtype,
                   void* recvbuf, int* recvcounts, int* displs, int* recvtype,
                   int* root, int* comm, int* ierr);
-void mpi_allgather__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_allgather_(void* sendbuf, int* sendcount, int* sendtype,
                      void* recvbuf, int* recvcount, int* recvtype,
                      int* comm, int* ierr);
-void mpi_allgatherv__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_allgatherv_(void* sendbuf, int* sendcount, int* sendtype,
                      void* recvbuf, int* recvcount,int* displs, int* recvtype,
                      int* comm, int* ierr) ;
-void mpi_type_size__(int* datatype, int *size, int* ierr);
+void mpi_type_size_(int* datatype, int *size, int* ierr);
 
-void mpi_scan__(void* sendbuf, void* recvbuf, int* count, int* datatype,
+void mpi_scan_(void* sendbuf, void* recvbuf, int* count, int* datatype,
                 int* op, int* comm, int* ierr);
-void mpi_alltoall__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_alltoall_(void* sendbuf, int* sendcount, int* sendtype,
                     void* recvbuf, int* recvcount, int* recvtype, int* comm, int* ierr);
-void mpi_alltoallv__(void* sendbuf, int* sendcounts, int* senddisps, int* sendtype,
+void mpi_alltoallv_(void* sendbuf, int* sendcounts, int* senddisps, int* sendtype,
                     void* recvbuf, int* recvcounts, int* recvdisps, int* recvtype, int* comm, int* ierr);
-void mpi_get_processor_name__(char *name, int *resultlen, int* ierr);
-void mpi_test__ (int * request, int *flag, MPI_Status * status, int* ierr);
-void mpi_testall__ (int* count, int * requests,  int *flag, MPI_Status * statuses, int* ierr);
-void mpi_get_count__(MPI_Status * status, int* datatype, int *count, int* ierr);
-void mpi_type_extent__(int* datatype, MPI_Aint * extent, int* ierr);
-void mpi_attr_get__(int* comm, int* keyval, void* attr_value, int* flag, int* ierr );
-void mpi_type_lb__(int* datatype, MPI_Aint * extent, int* ierr);
-void mpi_type_ub__(int* datatype, MPI_Aint * extent, int* ierr);
-void mpi_error_string__(int* errorcode, char* string, int* resultlen, int* ierr);
-void mpi_sendrecv__(void* sendbuf, int* sendcount, int* sendtype, int* dst,
+void mpi_get_processor_name_(char *name, int *resultlen, int* ierr);
+void mpi_test_ (int * request, int *flag, MPI_Status * status, int* ierr);
+void mpi_testall_ (int* count, int * requests,  int *flag, MPI_Status * statuses, int* ierr);
+void mpi_get_count_(MPI_Status * status, int* datatype, int *count, int* ierr);
+void mpi_type_extent_(int* datatype, MPI_Aint * extent, int* ierr);
+void mpi_attr_get_(int* comm, int* keyval, void* attr_value, int* flag, int* ierr );
+void mpi_type_commit_(int* datatype,  int* ierr);
+void mpi_type_vector_(int* count, int* blocklen, int* stride, int* old_type, int* newtype,  int* ierr);
+void mpi_type_create_vector_(int* count, int* blocklen, int* stride, int* old_type, int* newtype,  int* ierr);
+void mpi_type_hvector_(int* count, int* blocklen, MPI_Aint* stride, int* old_type, int* newtype,  int* ierr);
+void mpi_type_create_hvector_(int* count, int* blocklen, MPI_Aint* stride, int* old_type, int* newtype,  int* ierr);
+void mpi_type_free_(int* datatype, int* ierr);
+void mpi_type_lb_(int* datatype, MPI_Aint * extent, int* ierr);
+void mpi_type_ub_(int* datatype, MPI_Aint * extent, int* ierr);
+void mpi_win_fence_( int* assert,  int* win, int* ierr);
+void mpi_win_free_( int* win, int* ierr);
+void mpi_win_create_( int *base, MPI_Aint* size, int* disp_unit, int* info, int* comm, int *win, int* ierr);
+void mpi_info_create_( int *info, int* ierr);
+void mpi_info_set_( int *info, char *key, char *value, int* ierr);
+void mpi_info_free_(int* info, int* ierr);
+void mpi_get_( int *origin_addr, int* origin_count, int* origin_datatype, int* target_rank,
+    MPI_Aint* target_disp, int* target_count, int* target_datatype, int* win, int* ierr);
+void mpi_error_string_(int* errorcode, char* string, int* resultlen, int* ierr);
+void mpi_sendrecv_(void* sendbuf, int* sendcount, int* sendtype, int* dst,
                 int* sendtag, void *recvbuf, int* recvcount,
                 int* recvtype, int* src, int* recvtag,
                 int* comm, MPI_Status* status, int* ierr);
index 1d5e805..e0cfc66 100644 (file)
@@ -197,7 +197,7 @@ static MPI_Request build_request(void *buf, int count,
   if(datatype->has_subtype == 1){
     // This part handles the problem of non-contiguous memory
     old_buf = buf;
-    buf = xbt_malloc(count*smpi_datatype_size(datatype));
+    buf = count==0 ? NULL : xbt_malloc(count*smpi_datatype_size(datatype));
     if (flags & SEND) {
       subtype->serialize(old_buf, buf, count, datatype->substruct);
     }
@@ -336,7 +336,15 @@ void smpi_mpi_start(MPI_Request request)
 
   } else {
 
+
     int receiver = smpi_group_index(smpi_comm_group(request->comm), request->dst);
+
+    #ifdef HAVE_TRACING
+      int rank = smpi_process_index();
+      if (TRACE_smpi_view_internals()) {
+        TRACE_smpi_send(rank, rank, receiver);
+      }
+    #endif
 /*    if(receiver == MPI_UNDEFINED) {*/
 /*      XBT_WARN("Trying to send a message to a wrong rank");*/
 /*      return;*/
@@ -354,13 +362,14 @@ void smpi_mpi_start(MPI_Request request)
       request->refcount++;
       if(request->old_type->has_subtype == 0){
         oldbuf = request->buf;
-        if (oldbuf){
+        if (oldbuf && request->size!=0){
           request->buf = xbt_malloc(request->size);
           memcpy(request->buf,oldbuf,request->size);
         }
       }
       XBT_DEBUG("Send request %p is detached; buf %p copied into %p",request,oldbuf,request->buf);
     }
+
     // we make a copy here, as the size is modified by simix, and we may reuse the request in another receive later
     request->real_size=request->size;
     smpi_datatype_use(request->old_type);
@@ -390,6 +399,7 @@ void smpi_mpi_start(MPI_Request request)
     /* FIXME: detached sends are not traceable (request->action == NULL) */
     if (request->action)
       simcall_set_category(request->action, TRACE_internal_smpi_get_category());
+
 #endif
 
   }
@@ -499,8 +509,11 @@ void smpi_mpi_send(void *buf, int count, MPI_Datatype datatype, int dst,
 void smpi_mpi_ssend(void *buf, int count, MPI_Datatype datatype,
                            int dst, int tag, MPI_Comm comm)
 {
-  MPI_Request request = smpi_mpi_issend(buf, count, datatype, dst, tag, comm);
-  smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+  MPI_Request request =
+      build_request(buf, count, datatype, smpi_comm_rank(comm), dst, tag,
+                    comm, NON_PERSISTENT | SSEND | SEND);
+
+  smpi_mpi_start(request);  smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
 }
 
 void smpi_mpi_sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
@@ -558,8 +571,19 @@ static void finish_wait(MPI_Request * request, MPI_Status * status)
       if(req->detached == 0) free(req->buf);
     }
     smpi_datatype_unuse(datatype);
+
   }
 
+#ifdef HAVE_TRACING
+    if (TRACE_smpi_view_internals()) {
+      if(req->flags & RECV){
+        int rank = smpi_process_index();
+        int  src_traced = smpi_group_index(smpi_comm_group(req->comm), req->src == MPI_ANY_SOURCE ? req->real_src : req->src);
+        TRACE_smpi_recv(rank, src_traced, rank);
+      }
+    }
+#endif
+
   if(req->detached_sender!=NULL){
     smpi_mpi_request_free(&(req->detached_sender));
   }
@@ -580,8 +604,8 @@ int smpi_mpi_test(MPI_Request * request, MPI_Status * status) {
   else
     flag = simcall_comm_test((*request)->action);
   if(flag) {
-    (*request)->refcount++;
     finish_wait(request, status);
+    request=MPI_REQUEST_NULL;
   }else{
     smpi_empty_status(status);
   }
@@ -787,6 +811,7 @@ int smpi_mpi_waitall(int count, MPI_Request requests[],
       index = smpi_mpi_waitany(count, requests, pstat);
       if (index == MPI_UNDEFINED)
         break;
+      requests[index]=MPI_REQUEST_NULL;
     }
     if (status != MPI_STATUSES_IGNORE) {
       status[index] = *pstat;
@@ -815,6 +840,7 @@ int smpi_mpi_waitsome(int incount, MPI_Request requests[], int *indices,
       if(status != MPI_STATUSES_IGNORE) {
         status[index] = *pstat;
       }
+     requests[index]=MPI_REQUEST_NULL;
     }else{
       return MPI_UNDEFINED;
     }
@@ -839,6 +865,8 @@ int smpi_mpi_testsome(int incount, MPI_Request requests[], int *indices,
          if(status != MPI_STATUSES_IGNORE) {
            status[i] = *pstat;
          }
+         requests[i]=MPI_REQUEST_NULL;
+
       }
     }else{
       count_dead++;
index af699b9..96ccc0d 100644 (file)
 #include "private.h"
 #include "colls/colls.h"
 
+s_mpi_coll_description_t mpi_coll_allgather_description[] = {
+  {"default",
+   "allgather default collective",
+   smpi_mpi_allgather},
+COLL_ALLGATHERS(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_mpi_coll_description_t mpi_coll_allgatherv_description[] = {
+  {"default",
+   "allgatherv default collective",
+   smpi_mpi_allgatherv},
+COLL_ALLGATHERVS(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_mpi_coll_description_t mpi_coll_allreduce_description[] = {
+  {"default",
+   "allreduce default collective",
+   smpi_mpi_allreduce},
+COLL_ALLREDUCES(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
 s_mpi_coll_description_t mpi_coll_alltoall_description[] = {
   {"ompi",
    "Ompi alltoall default collective",
    smpi_coll_tuned_alltoall_ompi},
-
-  {"2dmesh",
-   "Alltoall 2dmesh collective",
-   smpi_coll_tuned_alltoall_2dmesh},
-  {"3dmesh",
-   "Alltoall 3dmesh collective",
-   smpi_coll_tuned_alltoall_3dmesh},
-  /*{"bruck",
-   "Alltoall Bruck collective",
-   smpi_coll_tuned_alltoall_bruck},*/
-  {"pair",
-   "Alltoall pair collective",
-   smpi_coll_tuned_alltoall_pair},
-  {"pair_light_barrier",
-   "Alltoall pair_light_barrier collective",
-   smpi_coll_tuned_alltoall_pair_light_barrier},
-  {"pair_mpi_barrier",
-   "Alltoall pair_mpi_barrier collective",
-   smpi_coll_tuned_alltoall_pair_mpi_barrier},
-  {"rdb",
-   "Alltoall rdb collective",
-   smpi_coll_tuned_alltoall_rdb},
-  {"ring",
-   "Alltoall ring collective",
-   smpi_coll_tuned_alltoall_ring},
-  {"ring_light_barrier",
-   "Alltoall ring_light_barrier collective",
-   smpi_coll_tuned_alltoall_ring_light_barrier},
-  {"ring_light_barrier",
-   "Alltoall ring_light_barrier collective",
-   smpi_coll_tuned_alltoall_ring_light_barrier},
-  {"ring_mpi_barrier",
-   "Alltoall ring_mpi_barrier collective",
-   smpi_coll_tuned_alltoall_ring_mpi_barrier},
-  {"ring_one_barrier",
-   "Alltoall ring_one_barrier collective",
-   smpi_coll_tuned_alltoall_ring_one_barrier},
-  {"simple",
-   "Alltoall simple collective",
-   smpi_coll_tuned_alltoall_simple},
-
+COLL_ALLTOALLS(COLL_DESCRIPTION, COLL_COMMA),
   {"bruck",
    "Alltoall Bruck (SG) collective",
    smpi_coll_tuned_alltoall_bruck},
   {"basic_linear",
    "Alltoall basic linear (SG) collective",
    smpi_coll_tuned_alltoall_basic_linear},
-  {"pairwise",
-   "Alltoall pairwise (SG) collective",
-   smpi_coll_tuned_alltoall_pairwise},
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
 
+s_mpi_coll_description_t mpi_coll_alltoallv_description[] = {
+  {"default",
+   "Ompi alltoallv default collective",
+   smpi_coll_basic_alltoallv},
+COLL_ALLTOALLVS(COLL_DESCRIPTION, COLL_COMMA),
   {NULL, NULL, NULL}      /* this array must be NULL terminated */
 };
 
-s_mpi_coll_description_t mpi_coll_allgather_description[] = {
+s_mpi_coll_description_t mpi_coll_bcast_description[] = {
   {"default",
    "allgather default collective",
-   smpi_mpi_gather},
+   smpi_mpi_bcast},
+COLL_BCASTS(COLL_DESCRIPTION, COLL_COMMA),
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
 
+s_mpi_coll_description_t mpi_coll_reduce_description[] = {
+  {"default",
+   "allgather default collective",
+   smpi_mpi_reduce},
+COLL_REDUCES(COLL_DESCRIPTION, COLL_COMMA),
   {NULL, NULL, NULL}      /* this array must be NULL terminated */
 };
 
 
+
 /** Displays the long description of all registered models, and quit */
 void coll_help(const char *category, s_mpi_coll_description_t * table)
 {
@@ -117,6 +114,14 @@ int find_coll_description(s_mpi_coll_description_t * table,
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_coll, smpi,
                                 "Logging specific to SMPI (coll)");
 
+int (*mpi_coll_allgather_fun)(void *, int, MPI_Datatype, void*, int, MPI_Datatype, MPI_Comm);
+int (*mpi_coll_allgatherv_fun)(void *, int, MPI_Datatype, void*, int*, int*, MPI_Datatype, MPI_Comm);
+int (*mpi_coll_allreduce_fun)(void *sbuf, void *rbuf, int rcount, MPI_Datatype dtype, MPI_Op op, MPI_Comm comm);
+int (*mpi_coll_alltoall_fun)(void *, int, MPI_Datatype, void*, int, MPI_Datatype, MPI_Comm);
+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);
+
 struct s_proc_tree {
   int PROCTREE_A;
   int numChildren;
@@ -314,9 +319,9 @@ int smpi_coll_tuned_alltoall_ompi(void *sendbuf, int sendcount,
                                               recvcount, recvtype, comm);
   } else {
     return
-        smpi_coll_tuned_alltoall_pairwise(sendbuf, sendcount, sendtype,
-                                          recvbuf, recvcount, recvtype,
-                                          comm);
+        smpi_coll_tuned_alltoall_ring(sendbuf, sendcount, sendtype,
+                                      recvbuf, recvcount, recvtype,
+                                      comm);
   }
 }
 
@@ -444,44 +449,6 @@ int smpi_coll_tuned_alltoall_basic_linear(void *sendbuf, int sendcount,
   return err;
 }
 
-/**
- * Alltoall pairwise
- *
- * this algorithm performs size steps (1<=s<=size) and
- * at each step s, a process p sends iand receive to.from a unique distinct remote process
- * size=5 : s=1:  4->0->1, 0->1->2, 1->2->3, ...
- *          s=2:  3->0->2, 4->1->3, 0->2->4, 1->3->0 , 2->4->1
- *          ....
- * Openmpi calls this routine when the message size sent to each rank is greater than 3000 bytes
- **/
-int smpi_coll_tuned_alltoall_pairwise(void *sendbuf, int sendcount,
-                                      MPI_Datatype sendtype, void *recvbuf,
-                                      int recvcount, MPI_Datatype recvtype,
-                                      MPI_Comm comm)
-{
-  int system_tag = 999;
-  int rank, size, step, sendto, recvfrom, sendsize, recvsize;
-
-  rank = smpi_comm_rank(comm);
-  size = smpi_comm_size(comm);
-  XBT_DEBUG("<%d> algorithm alltoall_pairwise() called.", rank);
-  sendsize = smpi_datatype_size(sendtype);
-  recvsize = smpi_datatype_size(recvtype);
-  /* Perform pairwise exchange - starting from 1 so the local copy is last */
-  for (step = 1; step < size + 1; step++) {
-    /* who do we talk to in this step? */
-    sendto = (rank + step) % size;
-    recvfrom = (rank + size - step) % size;
-    /* send and receive */
-    smpi_mpi_sendrecv(&((char *) sendbuf)[sendto * sendsize * sendcount],
-                      sendcount, sendtype, sendto, system_tag,
-                      &((char *) recvbuf)[recvfrom * recvsize * recvcount],
-                      recvcount, recvtype, recvfrom, system_tag, comm,
-                      MPI_STATUS_IGNORE);
-  }
-  return MPI_SUCCESS;
-}
-
 int smpi_coll_basic_alltoallv(void *sendbuf, int *sendcounts,
                               int *senddisps, MPI_Datatype sendtype,
                               void *recvbuf, int *recvcounts,
index e933675..f7a1583 100644 (file)
@@ -83,6 +83,10 @@ static MPI_Datatype get_datatype(int datatype) {
          : MPI_DATATYPE_NULL;
 }
 
+static void free_datatype(int datatype) {
+  xbt_dynar_remove_at(datatype_lookup, datatype, NULL);
+}
+
 static int new_op(MPI_Op op) {
   xbt_dynar_push(op_lookup, &op);
   return (int)xbt_dynar_length(op_lookup) - 1;
@@ -94,56 +98,57 @@ static MPI_Op get_op(int op) {
           : MPI_OP_NULL;
 }
 
-void mpi_init__(int* ierr) {
-   comm_lookup = xbt_dynar_new(sizeof(MPI_Comm), NULL);
-   new_comm(MPI_COMM_WORLD);
-   group_lookup = xbt_dynar_new(sizeof(MPI_Group), NULL);
-
-   request_lookup = xbt_dict_new_homogeneous(NULL);
-
-   datatype_lookup = xbt_dynar_new(sizeof(MPI_Datatype), NULL);
-   new_datatype(MPI_BYTE);
-   new_datatype(MPI_CHAR);
-   new_datatype(MPI_INT);
-   new_datatype(MPI_INT);
-   new_datatype(MPI_INT8_T);
-   new_datatype(MPI_INT16_T);
-   new_datatype(MPI_INT32_T);
-   new_datatype(MPI_INT64_T);
-   new_datatype(MPI_FLOAT);
-   new_datatype(MPI_FLOAT);
-   new_datatype(MPI_DOUBLE);
-   new_datatype(MPI_DOUBLE);
-   new_datatype(MPI_C_FLOAT_COMPLEX);
-   new_datatype(MPI_C_DOUBLE_COMPLEX);
-   new_datatype(MPI_2INT);
-   new_datatype(MPI_UINT8_T);
-   new_datatype(MPI_UINT16_T);
-   new_datatype(MPI_UINT32_T);
-   new_datatype(MPI_UINT64_T);
-   new_datatype(MPI_2FLOAT);
-   new_datatype(MPI_2DOUBLE);
-
-
-   op_lookup = xbt_dynar_new(sizeof(MPI_Op), NULL);
-   new_op(MPI_MAX);
-   new_op(MPI_MIN);
-   new_op(MPI_MAXLOC);
-   new_op(MPI_MINLOC);
-   new_op(MPI_SUM);
-   new_op(MPI_PROD);
-   new_op(MPI_LAND);
-   new_op(MPI_LOR);
-   new_op(MPI_LXOR);
-   new_op(MPI_BAND);
-   new_op(MPI_BOR);
-   new_op(MPI_BXOR);
-
+void mpi_init_(int* ierr) {
+   if(!comm_lookup){
+     comm_lookup = xbt_dynar_new(sizeof(MPI_Comm), NULL);
+     new_comm(MPI_COMM_WORLD);
+     group_lookup = xbt_dynar_new(sizeof(MPI_Group), NULL);
+
+     request_lookup = xbt_dict_new_homogeneous(NULL);
+
+     datatype_lookup = xbt_dynar_new(sizeof(MPI_Datatype), NULL);
+     new_datatype(MPI_BYTE);
+     new_datatype(MPI_CHAR);
+     new_datatype(MPI_INT);
+     new_datatype(MPI_INT);
+     new_datatype(MPI_INT8_T);
+     new_datatype(MPI_INT16_T);
+     new_datatype(MPI_INT32_T);
+     new_datatype(MPI_INT64_T);
+     new_datatype(MPI_FLOAT);
+     new_datatype(MPI_FLOAT);
+     new_datatype(MPI_DOUBLE);
+     new_datatype(MPI_DOUBLE);
+     new_datatype(MPI_C_FLOAT_COMPLEX);
+     new_datatype(MPI_C_DOUBLE_COMPLEX);
+     new_datatype(MPI_2INT);
+     new_datatype(MPI_UINT8_T);
+     new_datatype(MPI_UINT16_T);
+     new_datatype(MPI_UINT32_T);
+     new_datatype(MPI_UINT64_T);
+     new_datatype(MPI_2FLOAT);
+     new_datatype(MPI_2DOUBLE);
+
+
+     op_lookup = xbt_dynar_new(sizeof(MPI_Op), NULL);
+     new_op(MPI_MAX);
+     new_op(MPI_MIN);
+     new_op(MPI_MAXLOC);
+     new_op(MPI_MINLOC);
+     new_op(MPI_SUM);
+     new_op(MPI_PROD);
+     new_op(MPI_LAND);
+     new_op(MPI_LOR);
+     new_op(MPI_LXOR);
+     new_op(MPI_BAND);
+     new_op(MPI_BOR);
+     new_op(MPI_BXOR);
+   }
    /* smpif2c is responsible for generating a call with the final arguments */
    *ierr = MPI_Init(NULL, NULL);
 }
 
-void mpi_finalize__(int* ierr) {
+void mpi_finalize_(int* ierr) {
    *ierr = MPI_Finalize();
    xbt_dynar_free(&op_lookup);
    op_lookup = NULL;
@@ -155,27 +160,27 @@ void mpi_finalize__(int* ierr) {
    comm_lookup = NULL;
 }
 
-void mpi_abort__(int* comm, int* errorcode, int* ierr) {
+void mpi_abort_(int* comm, int* errorcode, int* ierr) {
   *ierr = MPI_Abort(get_comm(*comm), *errorcode);
 }
 
-void mpi_comm_rank__(int* comm, int* rank, int* ierr) {
+void mpi_comm_rank_(int* comm, int* rank, int* ierr) {
    *ierr = MPI_Comm_rank(get_comm(*comm), rank);
 }
 
-void mpi_comm_size__(int* comm, int* size, int* ierr) {
+void mpi_comm_size_(int* comm, int* size, int* ierr) {
    *ierr = MPI_Comm_size(get_comm(*comm), size);
 }
 
-double mpi_wtime__(void) {
+double mpi_wtime_(void) {
    return MPI_Wtime();
 }
 
-double mpi_wtick__(void) {
+double mpi_wtick_(void) {
   return MPI_Wtick();
 }
 
-void mpi_comm_dup__(int* comm, int* newcomm, int* ierr) {
+void mpi_comm_dup_(int* comm, int* newcomm, int* ierr) {
   MPI_Comm tmp;
 
   *ierr = MPI_Comm_dup(get_comm(*comm), &tmp);
@@ -184,7 +189,7 @@ void mpi_comm_dup__(int* comm, int* newcomm, int* ierr) {
   }
 }
 
-void mpi_comm_create__(int* comm, int* group, int* newcomm, int* ierr) {
+void mpi_comm_create_(int* comm, int* group, int* newcomm, int* ierr) {
   MPI_Comm tmp;
 
   *ierr = MPI_Comm_create(get_comm(*comm),get_group(*group), &tmp);
@@ -194,7 +199,7 @@ void mpi_comm_create__(int* comm, int* group, int* newcomm, int* ierr) {
 }
 
 
-void mpi_comm_free__(int* comm, int* ierr) {
+void mpi_comm_free_(int* comm, int* ierr) {
   MPI_Comm tmp = get_comm(*comm);
 
   *ierr = MPI_Comm_free(&tmp);
@@ -204,7 +209,7 @@ void mpi_comm_free__(int* comm, int* ierr) {
   }
 }
 
-void mpi_comm_split__(int* comm, int* color, int* key, int* comm_out, int* ierr) {
+void mpi_comm_split_(int* comm, int* color, int* key, int* comm_out, int* ierr) {
   MPI_Comm tmp;
 
   *ierr = MPI_Comm_split(get_comm(*comm), *color, *key, &tmp);
@@ -213,7 +218,7 @@ void mpi_comm_split__(int* comm, int* color, int* key, int* comm_out, int* ierr)
   }
 }
 
-void mpi_group_incl__(int* group, int* n, int* ranks, int* group_out, int* ierr) {
+void mpi_group_incl_(int* group, int* n, int* ranks, int* group_out, int* ierr) {
   MPI_Group tmp;
 
   *ierr = MPI_Group_incl(get_group(*group), *n, ranks, &tmp);
@@ -222,7 +227,7 @@ void mpi_group_incl__(int* group, int* n, int* ranks, int* group_out, int* ierr)
   }
 }
 
-void mpi_comm_group__(int* comm, int* group_out,  int* ierr) {
+void mpi_comm_group_(int* comm, int* group_out,  int* ierr) {
   MPI_Group tmp;
 
   *ierr = MPI_Comm_group(get_comm(*comm), &tmp);
@@ -232,11 +237,11 @@ void mpi_comm_group__(int* comm, int* group_out,  int* ierr) {
 }
 
 
-void mpi_initialized__(int* flag, int* ierr){
+void mpi_initialized_(int* flag, int* ierr){
   *ierr = MPI_Initialized(flag);
 }
 
-void mpi_send_init__(void *buf, int* count, int* datatype, int* dst, int* tag,
+void mpi_send_init_(void *buf, int* count, int* datatype, int* dst, int* tag,
                      int* comm, int* request, int* ierr) {
   MPI_Request req;
 
@@ -247,7 +252,7 @@ void mpi_send_init__(void *buf, int* count, int* datatype, int* dst, int* tag,
   }
 }
 
-void mpi_isend__(void *buf, int* count, int* datatype, int* dst,
+void mpi_isend_(void *buf, int* count, int* datatype, int* dst,
                  int* tag, int* comm, int* request, int* ierr) {
   MPI_Request req;
 
@@ -258,7 +263,7 @@ void mpi_isend__(void *buf, int* count, int* datatype, int* dst,
   }
 }
 
-void mpi_irsend__(void *buf, int* count, int* datatype, int* dst,
+void mpi_irsend_(void *buf, int* count, int* datatype, int* dst,
                  int* tag, int* comm, int* request, int* ierr) {
   MPI_Request req;
 
@@ -269,19 +274,19 @@ void mpi_irsend__(void *buf, int* count, int* datatype, int* dst,
   }
 }
 
-void mpi_send__(void* buf, int* count, int* datatype, int* dst,
+void mpi_send_(void* buf, int* count, int* datatype, int* dst,
                 int* tag, int* comm, int* ierr) {
    *ierr = MPI_Send(buf, *count, get_datatype(*datatype), *dst, *tag,
                     get_comm(*comm));
 }
 
-void mpi_rsend__(void* buf, int* count, int* datatype, int* dst,
+void mpi_rsend_(void* buf, int* count, int* datatype, int* dst,
                 int* tag, int* comm, int* ierr) {
    *ierr = MPI_Rsend(buf, *count, get_datatype(*datatype), *dst, *tag,
                     get_comm(*comm));
 }
 
-void mpi_sendrecv__(void* sendbuf, int* sendcount, int* sendtype, int* dst,
+void mpi_sendrecv_(void* sendbuf, int* sendcount, int* sendtype, int* dst,
                 int* sendtag, void *recvbuf, int* recvcount,
                 int* recvtype, int* src, int* recvtag,
                 int* comm, MPI_Status* status, int* ierr) {
@@ -290,7 +295,7 @@ void mpi_sendrecv__(void* sendbuf, int* sendcount, int* sendtype, int* dst,
        get_comm(*comm), status);
 }
 
-void mpi_recv_init__(void *buf, int* count, int* datatype, int* src, int* tag,
+void mpi_recv_init_(void *buf, int* count, int* datatype, int* src, int* tag,
                      int* comm, int* request, int* ierr) {
   MPI_Request req;
 
@@ -301,7 +306,7 @@ void mpi_recv_init__(void *buf, int* count, int* datatype, int* src, int* tag,
   }
 }
 
-void mpi_irecv__(void *buf, int* count, int* datatype, int* src, int* tag,
+void mpi_irecv_(void *buf, int* count, int* datatype, int* src, int* tag,
                  int* comm, int* request, int* ierr) {
   MPI_Request req;
 
@@ -312,19 +317,19 @@ void mpi_irecv__(void *buf, int* count, int* datatype, int* src, int* tag,
   }
 }
 
-void mpi_recv__(void* buf, int* count, int* datatype, int* src,
+void mpi_recv_(void* buf, int* count, int* datatype, int* src,
                 int* tag, int* comm, MPI_Status* status, int* ierr) {
    *ierr = MPI_Recv(buf, *count, get_datatype(*datatype), *src, *tag,
                     get_comm(*comm), status);
 }
 
-void mpi_start__(int* request, int* ierr) {
+void mpi_start_(int* request, int* ierr) {
   MPI_Request req = find_request(*request);
 
   *ierr = MPI_Start(&req);
 }
 
-void mpi_startall__(int* count, int* requests, int* ierr) {
+void mpi_startall_(int* count, int* requests, int* ierr) {
   MPI_Request* reqs;
   int i;
 
@@ -336,13 +341,13 @@ void mpi_startall__(int* count, int* requests, int* ierr) {
   free(reqs);
 }
 
-void mpi_wait__(int* request, MPI_Status* status, int* ierr) {
+void mpi_wait_(int* request, MPI_Status* status, int* ierr) {
    MPI_Request req = find_request(*request);
    
    *ierr = MPI_Wait(&req, status);
 }
 
-void mpi_waitany__(int* count, int* requests, int* index, MPI_Status* status, int* ierr) {
+void mpi_waitany_(int* count, int* requests, int* index, MPI_Status* status, int* ierr) {
   MPI_Request* reqs;
   int i;
 
@@ -354,7 +359,7 @@ void mpi_waitany__(int* count, int* requests, int* index, MPI_Status* status, in
   free(reqs);
 }
 
-void mpi_waitall__(int* count, int* requests, MPI_Status* status, int* ierr) {
+void mpi_waitall_(int* count, int* requests, MPI_Status* status, int* ierr) {
   MPI_Request* reqs;
   int i;
 
@@ -366,33 +371,33 @@ void mpi_waitall__(int* count, int* requests, MPI_Status* status, int* ierr) {
   free(reqs);
 }
 
-void mpi_barrier__(int* comm, int* ierr) {
+void mpi_barrier_(int* comm, int* ierr) {
   *ierr = MPI_Barrier(get_comm(*comm));
 }
 
-void mpi_bcast__(void *buf, int* count, int* datatype, int* root, int* comm, int* ierr) {
+void mpi_bcast_(void *buf, int* count, int* datatype, int* root, int* comm, int* ierr) {
   *ierr = MPI_Bcast(buf, *count, get_datatype(*datatype), *root, get_comm(*comm));
 }
 
-void mpi_reduce__(void* sendbuf, void* recvbuf, int* count,
+void mpi_reduce_(void* sendbuf, void* recvbuf, int* count,
                   int* datatype, int* op, int* root, int* comm, int* ierr) {
   *ierr = MPI_Reduce(sendbuf, recvbuf, *count,
                      get_datatype(*datatype), get_op(*op), *root, get_comm(*comm));
 }
 
-void mpi_allreduce__(void* sendbuf, void* recvbuf, int* count, int* datatype,
+void mpi_allreduce_(void* sendbuf, void* recvbuf, int* count, int* datatype,
                      int* op, int* comm, int* ierr) {
   *ierr = MPI_Allreduce(sendbuf, recvbuf, *count, get_datatype(*datatype),
                         get_op(*op), get_comm(*comm));
 }
 
-void mpi_reduce_scatter__(void* sendbuf, void* recvbuf, int* recvcounts, int* datatype,
+void mpi_reduce_scatter_(void* sendbuf, void* recvbuf, int* recvcounts, int* datatype,
                      int* op, int* comm, int* ierr) {
   *ierr = MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, get_datatype(*datatype),
                         get_op(*op), get_comm(*comm));
 }
 
-void mpi_scatter__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_scatter_(void* sendbuf, int* sendcount, int* sendtype,
                    void* recvbuf, int* recvcount, int* recvtype, 
                    int* root, int* comm, int* ierr) {
   *ierr = MPI_Scatter(sendbuf, *sendcount, get_datatype(*sendtype),
@@ -400,66 +405,66 @@ void mpi_scatter__(void* sendbuf, int* sendcount, int* sendtype,
 }
 
 
-void mpi_scatterv__(void* sendbuf, int* sendcounts, int* displs, int* sendtype,
+void mpi_scatterv_(void* sendbuf, int* sendcounts, int* displs, int* sendtype,
                    void* recvbuf, int* recvcount, int* recvtype,
                    int* root, int* comm, int* ierr) {
   *ierr = MPI_Scatterv(sendbuf, sendcounts, displs, get_datatype(*sendtype),
                       recvbuf, *recvcount, get_datatype(*recvtype), *root, get_comm(*comm));
 }
 
-void mpi_gather__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_gather_(void* sendbuf, int* sendcount, int* sendtype,
                   void* recvbuf, int* recvcount, int* recvtype,
                   int* root, int* comm, int* ierr) {
   *ierr = MPI_Gather(sendbuf, *sendcount, get_datatype(*sendtype),
                      recvbuf, *recvcount, get_datatype(*recvtype), *root, get_comm(*comm));
 }
 
-void mpi_gatherv__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_gatherv_(void* sendbuf, int* sendcount, int* sendtype,
                   void* recvbuf, int* recvcounts, int* displs, int* recvtype,
                   int* root, int* comm, int* ierr) {
   *ierr = MPI_Gatherv(sendbuf, *sendcount, get_datatype(*sendtype),
                      recvbuf, recvcounts, displs, get_datatype(*recvtype), *root, get_comm(*comm));
 }
 
-void mpi_allgather__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_allgather_(void* sendbuf, int* sendcount, int* sendtype,
                      void* recvbuf, int* recvcount, int* recvtype,
                      int* comm, int* ierr) {
   *ierr = MPI_Allgather(sendbuf, *sendcount, get_datatype(*sendtype),
                         recvbuf, *recvcount, get_datatype(*recvtype), get_comm(*comm));
 }
 
-void mpi_allgatherv__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_allgatherv_(void* sendbuf, int* sendcount, int* sendtype,
                      void* recvbuf, int* recvcounts,int* displs, int* recvtype,
                      int* comm, int* ierr) {
   *ierr = MPI_Allgatherv(sendbuf, *sendcount, get_datatype(*sendtype),
                         recvbuf, recvcounts, displs, get_datatype(*recvtype), get_comm(*comm));
 }
 
-void mpi_scan__(void* sendbuf, void* recvbuf, int* count, int* datatype,
+void mpi_scan_(void* sendbuf, void* recvbuf, int* count, int* datatype,
                 int* op, int* comm, int* ierr) {
   *ierr = MPI_Scan(sendbuf, recvbuf, *count, get_datatype(*datatype),
                    get_op(*op), get_comm(*comm));
 }
 
-void mpi_alltoall__(void* sendbuf, int* sendcount, int* sendtype,
+void mpi_alltoall_(void* sendbuf, int* sendcount, int* sendtype,
                     void* recvbuf, int* recvcount, int* recvtype, int* comm, int* ierr) {
   *ierr = MPI_Alltoall(sendbuf, *sendcount, get_datatype(*sendtype),
                        recvbuf, *recvcount, get_datatype(*recvtype), get_comm(*comm));
 }
 
-void mpi_alltoallv__(void* sendbuf, int* sendcounts, int* senddisps, int* sendtype,
+void mpi_alltoallv_(void* sendbuf, int* sendcounts, int* senddisps, int* sendtype,
                     void* recvbuf, int* recvcounts, int* recvdisps, int* recvtype, int* comm, int* ierr) {
   *ierr = MPI_Alltoallv(sendbuf, sendcounts, senddisps, get_datatype(*sendtype),
                        recvbuf, recvcounts, recvdisps, get_datatype(*recvtype), get_comm(*comm));
 }
 
-void mpi_test__ (int * request, int *flag, MPI_Status * status, int* ierr){
+void mpi_test_ (int * request, int *flag, MPI_Status * status, int* ierr){
   MPI_Request req = find_request(*request);
   *ierr= MPI_Test(&req, flag, status);
 }
 
 
-void mpi_testall__ (int* count, int * requests,  int *flag, MPI_Status * statuses, int* ierr){
+void mpi_testall_ (int* count, int * requests,  int *flag, MPI_Status * statuses, int* ierr){
   MPI_Request* reqs;
   int i;
   reqs = xbt_new(MPI_Request, *count);
@@ -470,35 +475,110 @@ void mpi_testall__ (int* count, int * requests,  int *flag, MPI_Status * statuse
 }
 
 
-void mpi_get_processor_name__(char *name, int *resultlen, int* ierr){
+void mpi_get_processor_name_(char *name, int *resultlen, int* ierr){
   *ierr = MPI_Get_processor_name(name, resultlen);
 }
 
-void mpi_get_count__(MPI_Status * status, int* datatype, int *count, int* ierr){
+void mpi_get_count_(MPI_Status * status, int* datatype, int *count, int* ierr){
   *ierr = MPI_Get_count(status, get_datatype(*datatype), count);
 }
 
-void mpi_attr_get__(int* comm, int* keyval, void* attr_value, int* flag, int* ierr ){
+void mpi_attr_get_(int* comm, int* keyval, void* attr_value, int* flag, int* ierr ){
   *ierr = MPI_Attr_get(get_comm(*comm), *keyval, attr_value, flag);
 }
 
-void mpi_type_extent__(int* datatype, MPI_Aint * extent, int* ierr){
+void mpi_type_extent_(int* datatype, MPI_Aint * extent, int* ierr){
   *ierr= MPI_Type_extent(get_datatype(*datatype),  extent);
 }
 
-void mpi_type_ub__(int* datatype, MPI_Aint * disp, int* ierr){
+void mpi_type_commit_(int* datatype,  int* ierr){
+  MPI_Datatype tmp= get_datatype(*datatype);
+  *ierr= MPI_Type_commit(&tmp);
+}
+
+void mpi_type_vector_(int* count, int* blocklen, int* stride, int* old_type, int* newtype,  int* ierr){
+  MPI_Datatype tmp;
+  *ierr= MPI_Type_vector(*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
+  if(*ierr == MPI_SUCCESS) {
+    *newtype = new_datatype(tmp);
+  }
+}
+
+void mpi_type_create_vector_(int* count, int* blocklen, int* stride, int* old_type, int* newtype,  int* ierr){
+  MPI_Datatype tmp;
+  *ierr= MPI_Type_vector(*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
+  if(*ierr == MPI_SUCCESS) {
+    *newtype = new_datatype(tmp);
+  }
+}
+
+void mpi_type_hvector_(int* count, int* blocklen, MPI_Aint* stride, int* old_type, int* newtype,  int* ierr){
+  MPI_Datatype tmp;
+  *ierr= MPI_Type_hvector (*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
+  if(*ierr == MPI_SUCCESS) {
+    *newtype = new_datatype(tmp);
+  }
+}
+
+void mpi_type_create_hvector_(int* count, int* blocklen, MPI_Aint* stride, int* old_type, int* newtype,  int* ierr){
+  MPI_Datatype tmp;
+  *ierr= MPI_Type_hvector(*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
+  if(*ierr == MPI_SUCCESS) {
+    *newtype = new_datatype(tmp);
+  }
+}
+
+void mpi_type_free_(int* datatype, int* ierr){
+  MPI_Datatype tmp= get_datatype(*datatype);
+  *ierr= MPI_Type_free (&tmp);
+  if(*ierr == MPI_SUCCESS) {
+    free_datatype(*datatype);
+  }
+}
+
+void mpi_type_ub_(int* datatype, MPI_Aint * disp, int* ierr){
   *ierr= MPI_Type_ub(get_datatype(*datatype), disp);
 }
 
-void mpi_type_lb__(int* datatype, MPI_Aint * extent, int* ierr){
+void mpi_type_lb_(int* datatype, MPI_Aint * extent, int* ierr){
   *ierr= MPI_Type_extent(get_datatype(*datatype), extent);
 }
 
-void mpi_type_size__(int* datatype, int *size, int* ierr)
+void mpi_type_size_(int* datatype, int *size, int* ierr)
 {
   *ierr = MPI_Type_size(get_datatype(*datatype), size);
 }
 
-void mpi_error_string__(int* errorcode, char* string, int* resultlen, int* ierr){
+void mpi_error_string_(int* errorcode, char* string, int* resultlen, int* ierr){
   *ierr = MPI_Error_string(*errorcode, string, resultlen);
 }
+
+void mpi_win_fence_( int* assert,  int* win, int* ierr){
+  *ierr =  MPI_Win_fence(* assert, *(MPI_Win*)win);
+}
+
+void mpi_win_free_( int* win, int* ierr){
+  *ierr =  MPI_Win_free(  (MPI_Win*)win);
+}
+
+void mpi_win_create_( int *base, MPI_Aint* size, int* disp_unit, int* info, int* comm, int *win, int* ierr){
+  *ierr =  MPI_Win_create( (void*)base, *size, *disp_unit, *(MPI_Info*)info, get_comm(*comm),(MPI_Win*)win);
+}
+
+void mpi_info_create_( int *info, int* ierr){
+  *ierr =  MPI_Info_create( (MPI_Info *)info);
+}
+
+void mpi_info_set_( int *info, char *key, char *value, int* ierr){
+  *ierr =  MPI_Info_set( (MPI_Info *)info, key, value);
+}
+
+void mpi_info_free_(int* info, int* ierr){
+  *ierr =  MPI_Info_free((MPI_Info *) info);
+}
+
+void mpi_get_( int *origin_addr, int* origin_count, int* origin_datatype, int *target_rank,
+    MPI_Aint* target_disp, int *target_count, int* target_datatype, int* win, int* ierr){
+  *ierr =  MPI_Get( (void*)origin_addr,*origin_count, get_datatype(*origin_datatype),*target_rank,
+      *target_disp, *target_count,get_datatype(*target_datatype), *(MPI_Win *)win);
+}
index 2722a17..8854995 100644 (file)
@@ -292,30 +292,30 @@ int __attribute__((weak)) xargc;
 char** __attribute__((weak)) xargv;
 
 #ifndef WIN32
-void __attribute__((weak)) user_main__(){
+void __attribute__((weak)) user_main_(){
   xbt_die("Should not be in this smpi_simulated_main");
   return;
 }
-int __attribute__((weak)) smpi_simulated_main__(int argc, char** argv) {
+int __attribute__((weak)) smpi_simulated_main_(int argc, char** argv) {
   smpi_process_init(&argc, &argv);
-  user_main__();
+  user_main_();
   //xbt_die("Should not be in this smpi_simulated_main");
   return 0;
 }
 
 int __attribute__((weak)) main(int argc, char** argv) {
-   return smpi_main(smpi_simulated_main__,argc,argv);
+   return smpi_main(smpi_simulated_main_,argc,argv);
 }
 
 int __attribute__((weak)) MAIN__(){
-  return smpi_main(smpi_simulated_main__,xargc, xargv);
+  return smpi_main(smpi_simulated_main_,xargc, xargv);
 };
 #endif
 
 int smpi_main(int (*realmain) (int argc, char *argv[]),int argc, char *argv[])
 {
   srand(SMPI_RAND_SEED);
-
+  
   if(getenv("SMPI_PRETEND_CC") != NULL) {
   /* Hack to ensure that smpicc can pretend to be a simple compiler. Particularly handy to pass it to the configuration tools */
     return 0;
@@ -339,6 +339,7 @@ int smpi_main(int (*realmain) (int argc, char *argv[]),int argc, char *argv[])
   XBT_LOG_CONNECT(smpi_mpi_dt);
   XBT_LOG_CONNECT(smpi_pmpi);
   XBT_LOG_CONNECT(smpi_replay);
+  XBT_LOG_CONNECT(smpi_colls);
 
 #ifdef HAVE_TRACING
   TRACE_global_init(&argc, argv);
@@ -359,6 +360,48 @@ int smpi_main(int (*realmain) (int argc, char *argv[]),int argc, char *argv[])
   SIMIX_function_register_default(realmain);
   SIMIX_launch_application(argv[2]);
 
+  int allgather_id = find_coll_description(mpi_coll_allgather_description,
+                                           sg_cfg_get_string("smpi/allgather"));
+  mpi_coll_allgather_fun = (int (*)(void *, int, MPI_Datatype,
+                                   void*, int, MPI_Datatype, MPI_Comm))
+                          mpi_coll_allgather_description[allgather_id].coll;
+
+  int allgatherv_id = find_coll_description(mpi_coll_allgatherv_description,
+                                           sg_cfg_get_string("smpi/allgatherv"));
+  mpi_coll_allgatherv_fun = (int (*)(void *, int, MPI_Datatype,
+                                   void*, int*, int*, MPI_Datatype, MPI_Comm))
+                          mpi_coll_allgatherv_description[allgatherv_id].coll;
+
+  int allreduce_id = find_coll_description(mpi_coll_allreduce_description,
+                                           sg_cfg_get_string("smpi/allreduce"));
+  mpi_coll_allreduce_fun = (int (*)(void *sbuf, void *rbuf, int rcount, \
+                                    MPI_Datatype dtype, MPI_Op op, MPI_Comm comm))
+                          mpi_coll_allreduce_description[allreduce_id].coll;
+
+  int alltoall_id = find_coll_description(mpi_coll_alltoall_description,
+                                          sg_cfg_get_string("smpi/alltoall"));
+  mpi_coll_alltoall_fun = (int (*)(void *, int, MPI_Datatype,
+                                  void*, int, MPI_Datatype, MPI_Comm))
+                         mpi_coll_alltoall_description[alltoall_id].coll;
+
+  int alltoallv_id = find_coll_description(mpi_coll_alltoallv_description,
+                                          sg_cfg_get_string("smpi/alltoallv"));
+  mpi_coll_alltoallv_fun = (int (*)(void *, int*, int*, MPI_Datatype,
+                                   void*, int*, int*, MPI_Datatype, MPI_Comm))
+                         mpi_coll_alltoallv_description[alltoallv_id].coll;
+
+  int bcast_id = find_coll_description(mpi_coll_bcast_description,
+                                          sg_cfg_get_string("smpi/bcast"));
+  mpi_coll_bcast_fun = (int (*)(void *buf, int count, MPI_Datatype datatype, \
+                               int root, MPI_Comm com))
+                      mpi_coll_bcast_description[bcast_id].coll;
+
+  int reduce_id = find_coll_description(mpi_coll_reduce_description,
+                                          sg_cfg_get_string("smpi/reduce"));
+  mpi_coll_reduce_fun = (int (*)(void *buf, void *rbuf, int count, MPI_Datatype datatype, \
+                                 MPI_Op op, int root, MPI_Comm comm))
+                       mpi_coll_reduce_description[reduce_id].coll;
+
   smpi_global_init();
 
   /* Clean IO before the run */
index 002ece0..266ec5e 100644 (file)
@@ -5,6 +5,7 @@
   * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "private.h"
+#include "simgrid/sg_config.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi,
                                 "Logging specific to SMPI (mpi)");
@@ -13,17 +14,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi,
 
 int MPI_Init(int *argc, char ***argv)
 {
-  int alltoall_id = find_coll_description(mpi_coll_alltoall_description,
-                                          sg_cfg_get_string("smpi/alltoall"));
-  mpi_coll_alltoall_fun = (int (*)(void *, int, MPI_Datatype,
-                                  void*, int, MPI_Datatype, MPI_Comm))
-                         mpi_coll_alltoall_description[alltoall_id].coll;
-
-  int allgather_id = find_coll_description(mpi_coll_allgather_description,
-                                           sg_cfg_get_string("smpi/allgather"));
-  mpi_coll_allgather_fun = (int (*)(void *, int, MPI_Datatype,
-                                   void*, int, MPI_Datatype, MPI_Comm))
-                          mpi_coll_allgather_description[allgather_id].coll;
 
   return PMPI_Init(argc, argv);
 }
@@ -692,3 +682,33 @@ int MPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status
 int MPI_Initialized(int* flag) {
   return PMPI_Initialized(flag);
 }
+
+int MPI_Win_fence( int assert,  MPI_Win win){
+   return PMPI_Win_fence( assert, win);
+}
+
+int MPI_Win_free( MPI_Win* win){
+   return PMPI_Win_free(  win);
+}
+
+int MPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
+  return PMPI_Win_create( base, size, disp_unit, info, comm,win);
+}
+
+int MPI_Info_create( MPI_Info *info){
+  return PMPI_Info_create( info);
+}
+
+int MPI_Info_set( MPI_Info *info, char *key, char *value){
+  return PMPI_Info_set( info, key, value);
+}
+
+int MPI_Info_free( MPI_Info *info){
+  return PMPI_Info_free( info);
+}
+
+int MPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
+    MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
+  return PMPI_Get( origin_addr,origin_count, origin_datatype,target_rank,
+      target_disp, target_count,target_datatype, win);
+}
index 29471e9..59512b6 100644 (file)
@@ -177,13 +177,12 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     }else{
       s_smpi_subtype_t *subtype =  sendtype->substruct;
 
-      s_smpi_mpi_vector_t* type_c = (s_smpi_mpi_vector_t*)sendtype;
 
-      void * buf_tmp = xbt_malloc(count * type_c->size_oldtype);
+      void * buf_tmp = xbt_malloc(count);
 
       subtype->serialize( sendbuf, buf_tmp,1, subtype);
       subtype =  recvtype->substruct;
-      subtype->unserialize(recvbuf, buf_tmp,1, subtype);
+      subtype->unserialize( buf_tmp, recvbuf,1, subtype);
 
       free(buf_tmp);
     }
index 608beff..656754d 100644 (file)
@@ -42,42 +42,44 @@ extern MPI_Datatype MPI_PTR;
 
 typedef struct s_smpi_mpi_vector{
   s_smpi_subtype_t base;
+  MPI_Datatype old_type;
+  size_t size_oldtype;
   size_t block_stride;
   size_t block_length;
   size_t block_count;
-  MPI_Datatype old_type;
-  size_t size_oldtype;
 } s_smpi_mpi_vector_t;
 
 typedef struct s_smpi_mpi_hvector{
   s_smpi_subtype_t base;
+  MPI_Datatype old_type;
+  size_t size_oldtype;
   MPI_Aint block_stride;
   size_t block_length;
   size_t block_count;
-  MPI_Datatype old_type;
-  size_t size_oldtype;
 } s_smpi_mpi_hvector_t;
 
 typedef struct s_smpi_mpi_indexed{
   s_smpi_subtype_t base;
+  MPI_Datatype old_type;
+  size_t size_oldtype;
   int* block_lengths;
   int* block_indices;
   size_t block_count;
-  MPI_Datatype old_type;
-  size_t size_oldtype;
 } s_smpi_mpi_indexed_t;
 
 typedef struct s_smpi_mpi_hindexed{
   s_smpi_subtype_t base;
+  MPI_Datatype old_type;
+  size_t size_oldtype;
   int* block_lengths;
   MPI_Aint* block_indices;
   size_t block_count;
-  MPI_Datatype old_type;
-  size_t size_oldtype;
 } s_smpi_mpi_hindexed_t;
 
 typedef struct s_smpi_mpi_struct{
   s_smpi_subtype_t base;
+  MPI_Datatype old_type;
+  size_t size_oldtype;
   int* block_lengths;
   MPI_Aint* block_indices;
   size_t block_count;
index 58cfb15..3d91b73 100644 (file)
@@ -1263,18 +1263,18 @@ int PMPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
   //TODO: suboptimal implementation
   void *recvbuf;
   int retval;
-  if ((datatype == MPI_DATATYPE_NULL)||(datatype->has_subtype==1)) {
+  if (datatype == MPI_DATATYPE_NULL) {
       retval = MPI_ERR_TYPE;
   } else if (count < 0) {
       retval = MPI_ERR_COUNT;
   } else {
-    int size = smpi_datatype_size(datatype) * count;
+    int size = smpi_datatype_get_extent(datatype) * count;
     recvbuf = xbt_new(char, size);
     retval =
         MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count,
                      datatype, src, recvtag, comm, status);
     if(retval==MPI_SUCCESS){
-        memcpy(buf, recvbuf, size * sizeof(char));
+        smpi_datatype_copy(recvbuf, count, datatype, buf, count, datatype);
     }
     xbt_free(recvbuf);
 
@@ -1479,7 +1479,7 @@ int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
   int valid_count = 0;
   for (i = 0; i < count; i++) {
     MPI_Request req = requests[i];
-    if(req){
+    if(req!=MPI_REQUEST_NULL){
       srcs[valid_count] = req->src;
       dsts[valid_count] = req->dst;
       recvs[valid_count] = req->recv;
@@ -1558,7 +1558,7 @@ int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm c
   if (comm == MPI_COMM_NULL) {
     retval = MPI_ERR_COMM;
   } else {
-    smpi_mpi_bcast(buf, count, datatype, root, comm);
+    mpi_coll_bcast_fun(buf, count, datatype, root, comm);
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
@@ -1675,8 +1675,8 @@ int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
              || recvtype == MPI_DATATYPE_NULL) {
     retval = MPI_ERR_TYPE;
   } else {
-    smpi_mpi_allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount,
-                       recvtype, comm);
+    mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
+                           recvtype, comm);
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
@@ -1706,7 +1706,7 @@ int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   } else if (recvcounts == NULL || displs == NULL) {
     retval = MPI_ERR_ARG;
   } else {
-    smpi_mpi_allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
+    mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
                         displs, recvtype, comm);
     retval = MPI_SUCCESS;
   }
@@ -1800,7 +1800,7 @@ int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
   } else if (datatype == MPI_DATATYPE_NULL || op == MPI_OP_NULL) {
     retval = MPI_ERR_ARG;
   } else {
-    smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
+    mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
@@ -1829,7 +1829,7 @@ int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
   } else {
-    smpi_mpi_allreduce(sendbuf, recvbuf, count, datatype, op, comm);
+      mpi_coll_allreduce_fun(sendbuf, recvbuf, count, datatype, op, comm);
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
@@ -1899,7 +1899,7 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
       count += recvcounts[i];
       displs[i] = 0;
     }
-    smpi_mpi_reduce(sendbuf, recvbuf, count, datatype, op, 0, comm);
+    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);
@@ -1963,7 +1963,7 @@ int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
     retval = MPI_ERR_ARG;
   } else {
     retval =
-        smpi_coll_basic_alltoallv(sendbuf, sendcounts, senddisps, sendtype,
+        mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, sendtype,
                                   recvbuf, recvcounts, recvdisps, recvtype,
                                   comm);
   }
@@ -2334,4 +2334,32 @@ int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
    return not_yet_implemented();
 }
 
+int PMPI_Win_fence( int assert,  MPI_Win win){
+   return not_yet_implemented();
+}
+
+int PMPI_Win_free( MPI_Win* win){
+   return not_yet_implemented();
+}
+
+int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
+  return not_yet_implemented();
+}
+
+int PMPI_Info_create( MPI_Info *info){
+  return not_yet_implemented();
+}
+
+int PMPI_Info_set( MPI_Info *info, char *key, char *value){
+  return not_yet_implemented();
+}
+
+int PMPI_Info_free( MPI_Info *info){
+  return not_yet_implemented();
+}
+
+int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
+    MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
+  return not_yet_implemented();
+}
 
index dfc0d22..c2002b5 100644 (file)
@@ -452,7 +452,7 @@ static void action_reduce(const char *const *action)
   int root_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), 0);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
-   smpi_mpi_reduce(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, root, MPI_COMM_WORLD);
+   mpi_coll_reduce_fun(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, root, MPI_COMM_WORLD);
    smpi_execute_flops(comp_size);
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
@@ -475,9 +475,9 @@ static void action_allReduce(const char *const *action) {
   TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
-  smpi_mpi_reduce(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
+   mpi_coll_reduce_fun(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
   smpi_execute_flops(comp_size);
-  smpi_mpi_bcast(NULL, comm_size, MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
+   mpi_coll_bcast_fun(NULL, comm_size, MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
   TRACE_smpi_computing_in(rank);
@@ -502,20 +502,8 @@ static void action_allToAll(const char *const *action) {
   TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
-
-  if (send_size < 200 && comm_size > 12) {
-    smpi_coll_tuned_alltoall_bruck(send, send_size, MPI_CURRENT_TYPE,
-                                   recv, recv_size, MPI_CURRENT_TYPE,
-                                   MPI_COMM_WORLD);
-  } else if (send_size < 3000) {  
-    smpi_coll_tuned_alltoall_basic_linear(send, send_size, MPI_CURRENT_TYPE,
-                                          recv, recv_size, MPI_CURRENT_TYPE,
-                                          MPI_COMM_WORLD);
-  } else {
-    smpi_coll_tuned_alltoall_pairwise(send, send_size, MPI_CURRENT_TYPE,
-                                      recv, recv_size, MPI_CURRENT_TYPE,
-                                      MPI_COMM_WORLD);
-  }
+  
+  mpi_coll_alltoall_fun(send, send_size, MPI_CURRENT_TYPE, recv, recv_size, MPI_CURRENT_TYPE, MPI_COMM_WORLD);
 
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
@@ -575,7 +563,7 @@ static void action_allToAllv(const char *const *action) {
   TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
-    smpi_coll_basic_alltoallv(sendbuf, sendcounts, senddisps,  MPI_CURRENT_TYPE,
+    mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps,     MPI_CURRENT_TYPE,
                                recvbuf, recvcounts, recvdisps, MPI_CURRENT_TYPE,
                                MPI_COMM_WORLD);
 #ifdef HAVE_TRACING
index 38240c0..36ddd2b 100755 (executable)
@@ -6,11 +6,11 @@ INCLUDEARGS="@includeflag@"
 CMAKE_LINKARGS="-L@libdir@"
 
 if [ "@WIN32@" != "1" ]; then
-  CFLAGS="-Dmain=smpi_simulated_main__"
-  LINKARGS="-lsimgrid -lsmpi"
+  CFLAGS="-Dmain=smpi_simulated_main_"
+  LINKARGS="-lsimgrid"
 else
   CFLAGS="-include @includedir@/smpi/smpi_main.h"
-  LINKARGS="@libdir@\libsimgrid.dll @libdir@\libsmpi.dll"
+  LINKARGS="@libdir@\libsimgrid.dll"
 fi
 
 CMDLINE=""
index 2b77445..4b99f2b 100755 (executable)
@@ -55,6 +55,7 @@ foreach my $fortran (@ARGV) {
       if(/extern \/\* Subroutine \*\//) {
          $cutext = 1;
       }
+      $_ =~ s/(mpi_[\w]*_)_/$1/g;
       if($cutext) {
          if(/;$/) {
             $cutext = 0;
@@ -62,7 +63,7 @@ foreach my $fortran (@ARGV) {
          next;
       }
       if(/\/* Main program alias \*\/\s*int\s+.*\s*\(\s*\)\s*{(.*)}/) {
-         $_ = "int smpi_simulated_main__(int argc, char** argv) { smpi_process_init(&argc, &argv); $1 }\n";
+         $_ = "int smpi_simulated_main_(int argc, char** argv) { smpi_process_init(&argc, &argv); $1 }\n";
       }
       print $tmp "$_\n";
    }
index 2d76ad2..9864551 100644 (file)
@@ -6,7 +6,7 @@ INCLUDEARGS="@includeflag@"
 CMAKE_LINKARGS="-L@libdir@"
 
 FFLAGS="-ff2c "
-LINKARGS="-lsimgrid -lsmpi -lm -lgfortran"
+LINKARGS="-lsimgrid -lm -lgfortran"
 main_name=main
 TMPFILE=$(mktemp).f90
 CMDLINE=""
index d53e729..e290d20 100755 (executable)
@@ -163,6 +163,24 @@ else
 fi
 shift
 
+# steel --cfg and --logs options
+while [ $# -gt 0 ]; do
+  case "$1" in
+   "--cfg="*|"--log="*)
+     for OPT in ${1#*=}
+     do
+       SIMOPTS="$SIMOPTS ${1%%=*}=$OPT"
+     done
+     shift 1
+   ;;
+    *)
+      PROC_ARGS="${PROC_ARGS:+$PROC_ARGS }$1"
+      shift      
+    ;;
+  esac
+done
+
+
 ##-----------------------------------
 
 # Basic checks on the provided arguments
@@ -246,7 +264,7 @@ if [ -n "${HOSTFILE}" ] && [ -f ${HOSTFILE} ]; then
 fi
 
 if [ "${EXTOPT}" = "smpi_replay" ]; then
-  APP_TRACES=$1;
+  APP_TRACES=$PROC_ARGS
   if [ -n "${APP_TRACES}" ] && [ -f "${APP_TRACES}" ]; then
      hosttraces=(`cat ${APP_TRACES} | tr \\\n " "`)
      NUMTRACES=`cat ${APP_TRACES} | wc -l`
@@ -301,7 +319,7 @@ do
       echo "    <argument value=\"${hosttraces[0]}\"/>" >> ${APPLICATIONTMP}
     fi
   else 
-    for ARG in $*; do
+    for ARG in $PROC_ARGS; do
        echo "    <argument value=\"${ARG}\"/>" >> ${APPLICATIONTMP}
     done
   fi
index 9674277..ed8b8eb 100644 (file)
@@ -82,6 +82,9 @@
 <!ATTLIST cluster availability_file CDATA "">
 <!ATTLIST cluster state_file CDATA "">
 <!ATTLIST cluster router_id CDATA "">
+<!ATTLIST cluster limiter_link CDATA "">
+<!ATTLIST cluster loopback_bw CDATA "">
+<!ATTLIST cluster loopback_lat CDATA "">
 
 <!ELEMENT cabinet EMPTY>
 <!ATTLIST cabinet id CDATA #REQUIRED>
index c069682..eacf7fd 100644 (file)
@@ -403,8 +403,8 @@ static void yy_fatal_error (yyconst char msg[]  );
        *yy_cp = '\0'; \
        (yy_c_buf_p) = yy_cp;
 
-#define YY_NUM_RULES 558
-#define YY_END_OF_BUFFER 559
+#define YY_NUM_RULES 564
+#define YY_END_OF_BUFFER 565
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -412,7 +412,7 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static yyconst flex_int16_t yy_accept[3260] =
+static yyconst flex_int16_t yy_accept[3299] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -441,19 +441,19 @@ static yyconst flex_int16_t yy_accept[3260] =
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  559,  557,   15,   10,   10,   15,   15,  537,
-       10,  537,    5,    6,    5,    8,    9,    8,  553,  545,
-      546,  554,  551,  554,  552,  556,  545,  546,  556,  557,
+        0,    0,  565,  563,   15,   10,   10,   15,   15,  543,
+       10,  543,    5,    6,    5,    8,    9,    8,  559,  551,
+      552,  560,  557,  560,  558,  562,  551,  552,  562,  563,
        22,   10,   22,   22,   22,   20,   22,   26,   10,   26,
-       26,  557,   26,  557,  557,   26,   33,   10,   33,   33,
+       26,  563,   26,  563,  563,   26,   33,   10,   33,   33,
 
        33,   31,   33,   37,   10,   37,   37,   48,   10,   48,
-       48,   48,   46,   48,   48,   48,  554,  553,   78,   10,
+       48,   48,   46,   48,   48,   48,  560,  559,   78,   10,
        78,   78,   78,   76,   78,   78,   78,   78,   78,   82,
        10,   82,  101,   10,  101,  101,  101,   99,  101,  101,
       101,  105,   10,  105,  128,   10,  128,  128,  128,  126,
-      128,  128,  132,   10,  132,  132,  557,  132,  557,  132,
-      132,  557,  557,  132,  557,  132,  557,  132,  145,   10,
+      128,  128,  132,   10,  132,  132,  563,  132,  563,  132,
+      132,  563,  563,  132,  563,  132,  563,  132,  145,   10,
       145,  145,  145,  143,  145,  145,  145,  145,  149,   10,
       149,  149,  160,   10,  160,  160,  160,  158,  160,  160,
       160,  164,   10,  164,  164,  173,   10,  173,  173,  173,
@@ -461,31 +461,31 @@ static yyconst flex_int16_t yy_accept[3260] =
       171,  173,  173,  177,   10,  177,  186,   10,  186,  186,
       186,  184,  186,  186,  190,   10,  190,  213,   10,  213,
       213,  213,  211,  213,  213,  213,  213,  213,  217,   10,
-      217,  557,  217,  224,   10,  224,  224,  224,  222,  224,
+      217,  563,  217,  224,   10,  224,  224,  224,  222,  224,
       228,   10,  228,  239,   10,  239,  239,  239,  237,  239,
-      239,  239,  243,   10,  243,  284,   10,  284,  284,  284,
-      282,  284,  284,  284,  284,  284,  284,  284,  284,  288,
-       10,  288,  307,   10,  307,  307,  307,  305,  307,  307,
-      307,  307,  307,  307,  311,   10,  311,  332,   10,  332,
-      332,  332,  330,  332,  332,  332,  332,  332,  332,  332,
-
-      336,   10,  336,  345,   10,  345,  345,  345,  343,  345,
-      345,  349,   10,  349,  360,   10,  360,  360,  360,  358,
-      360,  360,  360,  364,   10,  364,  391,   10,  391,  391,
-      391,  389,  391,  391,  391,  391,  395,   10,  395,  395,
-      408,   10,  408,  408,  408,  406,  408,  408,  412,   10,
-      412,  557,  412,  429,   10,  429,  429,  429,  427,  429,
-      429,  429,  433,   10,  433,  433,  446,   10,  446,  446,
-      446,  444,  446,  446,  450,   10,  450,  459,   10,  459,
-      459,  459,  457,  459,  459,  463,   10,  463,  463,  476,
-       10,  476,  476,  476,  474,  476,  476,  476,  480,   10,
-
-      480,  480,  497,   10,  497,  497,  497,  495,  497,  497,
-      497,  497,  497,  501,   10,  501,  557,  501,  508,   10,
-      508,  508,  508,  506,  508,  512,   10,  512,  519,   10,
-      519,  519,  519,  517,  519,  523,   10,  523,  523,  532,
-       10,  532,  532,  532,  530,  532,  532,  536,   10,  536,
-       10,    0,    2,    2,    0,    4,    7,  548,  547,    0,
+      239,  239,  243,   10,  243,  290,   10,  290,  290,  290,
+      288,  290,  290,  290,  290,  290,  290,  290,  290,  294,
+       10,  294,  313,   10,  313,  313,  313,  311,  313,  313,
+      313,  313,  313,  313,  317,   10,  317,  338,   10,  338,
+      338,  338,  336,  338,  338,  338,  338,  338,  338,  338,
+
+      342,   10,  342,  351,   10,  351,  351,  351,  349,  351,
+      351,  355,   10,  355,  366,   10,  366,  366,  366,  364,
+      366,  366,  366,  370,   10,  370,  397,   10,  397,  397,
+      397,  395,  397,  397,  397,  397,  401,   10,  401,  401,
+      414,   10,  414,  414,  414,  412,  414,  414,  418,   10,
+      418,  563,  418,  435,   10,  435,  435,  435,  433,  435,
+      435,  435,  439,   10,  439,  439,  452,   10,  452,  452,
+      452,  450,  452,  452,  456,   10,  456,  465,   10,  465,
+      465,  465,  463,  465,  465,  469,   10,  469,  469,  482,
+       10,  482,  482,  482,  480,  482,  482,  482,  486,   10,
+
+      486,  486,  503,   10,  503,  503,  503,  501,  503,  503,
+      503,  503,  503,  507,   10,  507,  563,  507,  514,   10,
+      514,  514,  514,  512,  514,  518,   10,  518,  525,   10,
+      525,  525,  525,  523,  525,  529,   10,  529,  529,  538,
+       10,  538,  538,  538,  536,  538,  538,  542,   10,  542,
+       10,    0,    2,    2,    0,    4,    7,  554,  553,    0,
         0,    0,    0,    0,    0,    0,   21,   23,   23,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -499,279 +499,284 @@ static yyconst flex_int16_t yy_accept[3260] =
       146,    0,  159,  161,  161,  161,  161,    0,  172,  174,
       174,  174,    0,  185,  187,  187,  187,    0,  212,  214,
       214,  214,  214,  214,  214,    0,    0,  223,  225,  225,
-        0,  238,  240,  240,  240,  240,    0,  283,  285,  285,
-      285,  285,  285,  285,  285,  285,  285,  285,  285,  285,
-
-      285,  285,    0,  306,  308,  308,  308,  308,  308,  308,
-      308,  308,    0,  331,  333,  333,  333,  333,  333,  333,
-      333,  333,    0,  344,  346,  346,  346,    0,  359,  361,
-      361,  361,  361,    0,  390,  392,  392,  392,  392,  392,
-      392,    0,  407,  409,  409,  409,  409,    0,    0,  428,
-      430,  430,  430,  430,  430,    0,  445,  447,  447,  447,
-        0,  458,  460,  460,  460,    0,  475,  477,  477,  477,
-      477,    0,  496,  498,  498,  498,  498,  498,  498,    0,
-        0,  507,  509,  509,    0,  518,  520,  520,    0,  531,
-      533,  533,  533,    0,    0,    0,    0,    0,    3,    0,
-
-        0,    0,    0,    0,    0,    0,  555,    0,   23,    0,
-        0,  107,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  238,  240,  240,  240,  240,    0,  289,  291,  291,
+      291,  291,  291,  291,  291,  291,  291,  291,  291,  291,
+
+      291,  291,  291,  291,    0,  312,  314,  314,  314,  314,
+      314,  314,  314,  314,    0,  337,  339,  339,  339,  339,
+      339,  339,  339,  339,    0,  350,  352,  352,  352,    0,
+      365,  367,  367,  367,  367,    0,  396,  398,  398,  398,
+      398,  398,  398,    0,  413,  415,  415,  415,  415,    0,
+        0,  434,  436,  436,  436,  436,  436,    0,  451,  453,
+      453,  453,    0,  464,  466,  466,  466,    0,  481,  483,
+      483,  483,  483,    0,  502,  504,  504,  504,  504,  504,
+      504,    0,    0,  513,  515,  515,    0,  524,  526,  526,
+        0,  537,  539,  539,  539,    0,    0,    0,    0,    0,
+
+        3,    0,    0,    0,    0,    0,    0,    0,  561,    0,
+       23,    0,    0,  107,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  106,    0,    0,    0,    0,    0,    0,
-       34,    0,    0,   49,    0,    0,   49,    0,    0,    0,
-      550,   79,    0,    0,   79,   79,   79,   79,   79,   79,
-        0,    0,  102,  102,  102,    0,    0,    0,    0,  129,
-        0,    0,  107,    0,    0,    0,    0,    0,    0,    0,
-        0,  106,    0,    0,    0,    0,  146,    0,    0,  146,
-      146,    0,    0,  161,    0,    0,  161,    0,    0,    0,
-
-        0,  174,    0,    0,  187,  187,    0,    0,  214,  214,
-      214,    0,    0,  214,  214,    0,    0,    0,    0,  225,
-        0,    0,  240,    0,    0,    0,    0,    0,    0,  285,
-      285,    0,    0,  285,    0,    0,  285,  285,  285,  285,
-      285,  285,  285,  285,    0,    0,    0,    0,    0,    0,
-      308,  308,  308,  308,  308,    0,    0,  333,  333,  333,
-        0,    0,  333,  333,  333,    0,    0,  346,    0,    0,
-        0,    0,  361,    0,    0,  361,    0,    0,  392,    0,
-        0,  392,  392,  392,    0,    0,  409,  409,  409,    0,
-        0,    0,  430,  430,  430,  430,    0,    0,  447,    0,
-
-        0,    0,    0,  460,  460,    0,    0,  477,  477,  477,
-        0,    0,  498,  498,  498,  498,  498,    0,    0,    0,
-      509,    0,    0,    0,    0,    0,    0,    0,    0,  533,
-        0,    0,    0,   14,    1,    0,    0,  543,    0,    0,
-        0,  540,  539,    0,    0,   23,    0,    0,   25,    0,
-      107,    0,    0,    0,    0,    0,    0,    0,  218,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  106,    0,    0,    0,    0,    0,    0,
-       34,    0,    0,   36,    0,   49,    0,   41,   40,   49,
-        0,    0,    0,   51,    0,   79,    0,   55,   54,    0,
-
-        0,   79,    0,    0,   79,   79,   79,    0,    0,   81,
-        0,  102,  102,  102,    0,    0,  104,    0,    0,  109,
-      108,  129,    0,    0,  131,    0,    0,    0,    0,  219,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,  146,
-        0,  136,  135,  146,  146,    0,    0,  148,    0,  161,
-        0,  153,  152,  161,    0,    0,  163,    0,    0,  168,
-      167,  174,    0,    0,  176,    0,  187,  187,    0,    0,
-      189,    0,  214,  214,  214,    0,  194,  193,  214,  214,
-        0,    0,  216,    0,    0,    0,  225,    0,    0,  227,
-        0,  240,    0,  232,  231,    0,  234,  233,    0,    0,
-
-      242,    0,  285,  285,  285,  285,    0,  259,  258,  285,
-        0,  247,  246,    0,    0,  285,  285,  285,  285,  285,
-      285,  285,    0,    0,  287,    0,    0,  302,  301,    0,
-      292,  291,    0,    0,  308,  308,  308,  308,    0,    0,
-      310,    0,  333,  333,  333,  333,    0,  315,  314,    0,
-        0,  333,  333,    0,    0,  335,    0,  346,    0,  340,
-      339,    0,    0,  348,    0,  361,    0,  353,  352,  361,
-        0,    0,  363,    0,  392,    0,  368,  367,  392,  392,
-      392,    0,    0,  394,    0,    0,    0,    0,    0,  409,
-        0,    0,  411,    0,    0,    0,    0,  430,  430,    0,
-
-        0,  430,    0,    0,  432,    0,  447,    0,  437,  436,
-        0,    0,  449,    0,    0,    0,    0,    0,    0,    0,
-      462,    0,    0,    0,  477,  477,    0,    0,    0,    0,
-      479,    0,  498,  498,  498,  498,  498,    0,    0,  500,
-        0,    0,  509,    0,    0,  511,    0,    0,  516,  515,
-        0,    0,  522,    0,    0,  527,  526,  533,    0,    0,
-      535,    0,    0,    0,  544,  538,    0,    0,    0,   23,
-        0,    0,    0,    0,    0,    0,    0,    0,  218,  191,
-        0,  365,    0,    0,  313,    0,    0,  524,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,  312,    0,    0,
-
-        0,    0,    0,    0,    0,   49,    0,    0,   79,    0,
-       59,   58,    0,    0,    0,   57,   56,   79,    0,    0,
-       79,    0,  102,    0,    0,  102,    0,  129,    0,  130,
-        0,    0,    0,  219,  192,  366,  525,    0,    0,    0,
-        0,    0,    0,  146,  146,    0,    0,    0,  161,  161,
-        0,    0,    0,    0,    0,    0,  187,    0,  214,  214,
-        0,    0,  214,  214,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  285,  285,  285,  285,    0,    0,    0,
-      261,  260,  285,  285,  285,  285,  285,  285,  285,    0,
-        0,  304,  303,  308,  308,  308,  308,    0,  333,  333,
-
-      333,  333,    0,  323,  322,  333,  333,    0,  346,    0,
-      361,  361,    0,  392,  392,  392,  392,    0,    0,  401,
-      400,    0,  399,  398,  409,    0,  365,    0,  418,  417,
-      430,  430,    0,  416,  415,  430,    0,  447,    0,    0,
-      456,  455,    0,  454,  453,    0,    0,  469,  468,  477,
-      477,    0,  467,  466,    0,  498,    0,    0,  498,  498,
-      498,    0,    0,  509,    0,    0,  533,    0,    0,    0,
-        0,   12,    0,  541,  542,    0,   23,    0,    0,    0,
-        0,    0,    0,    0,    0,  191,    0,    0,  365,    0,
-      165,    0,  313,    0,    0,  524,    0,  396,    0,   39,
-
-        0,    0,    0,    0,    0,  312,    0,   38,    0,   30,
-       29,    0,    0,   43,   42,   49,    0,    0,   79,    0,
-       61,   60,   79,    0,   65,   64,   79,    0,  102,    0,
-        0,    0,    0,    0,    0,  129,    0,    0,    0,  192,
-        0,  366,  525,  397,    0,    0,    0,  397,  396,  146,
-        0,    0,    0,  140,  139,    0,  161,  161,    0,    0,
-      170,  169,    0,    0,  183,  182,  187,    0,  214,  214,
-        0,  198,  197,    0,    0,    0,    0,  214,    0,  166,
-        0,    0,  221,  220,    0,  226,    0,  236,  235,    0,
-      285,    0,    0,  285,  285,    0,  257,  256,    0,    0,
-
-      285,  285,  285,  285,  285,  285,    0,    0,    0,  308,
-      308,  308,    0,  333,    0,    0,  333,  333,    0,    0,
-      333,    0,  346,    0,  361,  361,    0,  392,  392,  392,
-        0,    0,  392,    0,  409,    0,    0,  430,  430,  430,
-        0,  447,    0,    0,  477,  477,    0,  498,    0,  484,
-      483,  498,  498,  498,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  106,    0,    0,    0,    0,
+        0,    0,   34,    0,    0,   49,    0,    0,   49,    0,
+        0,    0,  556,   79,    0,    0,   79,   79,   79,   79,
+       79,   79,    0,    0,  102,  102,  102,    0,    0,    0,
+        0,  129,    0,    0,  107,    0,    0,    0,    0,    0,
+        0,    0,    0,  106,    0,    0,    0,    0,  146,    0,
+        0,  146,  146,    0,    0,  161,    0,    0,  161,    0,
+
+        0,    0,    0,  174,    0,    0,  187,  187,    0,    0,
+      214,  214,  214,    0,    0,  214,  214,    0,    0,    0,
+        0,  225,    0,    0,  240,    0,    0,    0,    0,    0,
+        0,  291,  291,    0,    0,  291,    0,    0,  291,  291,
+      291,  291,  291,  291,  291,  291,  291,  291,    0,    0,
+        0,    0,    0,    0,  314,  314,  314,  314,  314,    0,
+        0,  339,  339,  339,    0,    0,  339,  339,  339,    0,
+        0,  352,    0,    0,    0,    0,  367,    0,    0,  367,
+        0,    0,  398,    0,    0,  398,  398,  398,    0,    0,
+      415,  415,  415,    0,    0,    0,  436,  436,  436,  436,
+
+        0,    0,  453,    0,    0,    0,    0,  466,  466,    0,
+        0,  483,  483,  483,    0,    0,  504,  504,  504,  504,
+      504,    0,    0,    0,  515,    0,    0,    0,    0,    0,
+        0,    0,    0,  539,    0,    0,    0,   14,    1,    0,
+        0,  549,    0,    0,    0,  546,  545,    0,    0,   23,
+        0,    0,   25,    0,  107,    0,    0,    0,    0,    0,
+        0,    0,  218,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  106,    0,    0,
+        0,    0,    0,    0,   34,    0,    0,   36,    0,   49,
+        0,   41,   40,   49,    0,    0,    0,   51,    0,   79,
+
+        0,   55,   54,    0,    0,   79,    0,    0,   79,   79,
+       79,    0,    0,   81,    0,  102,  102,  102,    0,    0,
+      104,    0,    0,  109,  108,  129,    0,    0,  131,    0,
+        0,    0,    0,  219,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  146,    0,  136,  135,  146,  146,    0,
+        0,  148,    0,  161,    0,  153,  152,  161,    0,    0,
+      163,    0,    0,  168,  167,  174,    0,    0,  176,    0,
+      187,  187,    0,    0,  189,    0,  214,  214,  214,    0,
+      194,  193,  214,  214,    0,    0,  216,    0,    0,    0,
+      225,    0,    0,  227,    0,  240,    0,  232,  231,    0,
+
+      234,  233,    0,    0,  242,    0,  291,  291,  291,  291,
+        0,  259,  258,  291,    0,  247,  246,    0,    0,  291,
+      291,  291,  291,  291,  291,  291,  291,  291,    0,    0,
+      293,    0,    0,  308,  307,    0,  298,  297,    0,    0,
+      314,  314,  314,  314,    0,    0,  316,    0,  339,  339,
+      339,  339,    0,  321,  320,    0,    0,  339,  339,    0,
+        0,  341,    0,  352,    0,  346,  345,    0,    0,  354,
+        0,  367,    0,  359,  358,  367,    0,    0,  369,    0,
+      398,    0,  374,  373,  398,  398,  398,    0,    0,  400,
+        0,    0,    0,    0,    0,  415,    0,    0,  417,    0,
+
+        0,    0,    0,  436,  436,    0,    0,  436,    0,    0,
+      438,    0,  453,    0,  443,  442,    0,    0,  455,    0,
+        0,    0,    0,    0,    0,    0,  468,    0,    0,    0,
+      483,  483,    0,    0,    0,    0,  485,    0,  504,  504,
+      504,  504,  504,    0,    0,  506,    0,    0,  515,    0,
+        0,  517,    0,    0,  522,  521,    0,    0,  528,    0,
+        0,  533,  532,  539,    0,    0,  541,    0,    0,    0,
+      550,  544,    0,    0,    0,   23,    0,    0,    0,    0,
+        0,    0,    0,    0,  218,  191,    0,  371,    0,    0,
+      319,    0,    0,  530,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,  318,    0,    0,    0,    0,    0,    0,
+        0,   49,    0,    0,   79,    0,   59,   58,    0,    0,
+        0,   57,   56,   79,    0,    0,   79,    0,  102,    0,
+        0,  102,    0,  129,    0,  130,    0,    0,    0,  219,
+      192,  372,  531,    0,    0,    0,    0,    0,    0,  146,
+      146,    0,    0,    0,  161,  161,    0,    0,    0,    0,
+        0,    0,  187,    0,  214,  214,    0,    0,  214,  214,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  291,
+      291,  291,  291,    0,    0,    0,  261,  260,  291,  291,
+      291,  291,  291,  291,  291,  291,  291,    0,    0,  310,
+
+      309,  314,  314,  314,  314,    0,  339,  339,  339,  339,
+        0,  329,  328,  339,  339,    0,  352,    0,  367,  367,
+        0,  398,  398,  398,  398,    0,    0,  407,  406,    0,
+      405,  404,  415,    0,  371,    0,  424,  423,  436,  436,
+        0,  422,  421,  436,    0,  453,    0,    0,  462,  461,
+        0,  460,  459,    0,    0,  475,  474,  483,  483,    0,
+      473,  472,    0,  504,    0,    0,  504,  504,  504,    0,
+        0,  515,    0,    0,  539,    0,    0,    0,    0,   12,
+        0,  547,  548,    0,   23,    0,    0,    0,    0,    0,
+        0,    0,    0,  191,    0,    0,  371,    0,  165,    0,
+
+      319,    0,    0,  530,    0,  402,    0,   39,    0,    0,
+        0,    0,    0,  318,    0,   38,    0,   30,   29,    0,
+        0,   43,   42,   49,    0,    0,   79,    0,   61,   60,
+       79,    0,   65,   64,   79,    0,  102,    0,    0,    0,
+        0,    0,    0,  129,    0,    0,    0,  192,    0,  372,
+      531,  403,    0,    0,    0,  403,  402,  146,    0,    0,
+        0,  140,  139,    0,  161,  161,    0,    0,  170,  169,
+        0,    0,  183,  182,  187,    0,  214,  214,    0,  198,
+      197,    0,    0,    0,    0,  214,    0,  166,    0,    0,
+      221,  220,    0,  226,    0,  236,  235,    0,  291,    0,
+
+        0,  291,  291,    0,  257,  256,  291,  291,    0,    0,
+      291,  291,  291,  291,  291,  291,    0,    0,    0,  314,
+      314,  314,    0,  339,    0,    0,  339,  339,    0,    0,
+      339,    0,  352,    0,  367,  367,    0,  398,  398,  398,
+        0,    0,  398,    0,  415,    0,    0,  436,  436,  436,
+        0,  453,    0,    0,  483,  483,    0,  504,    0,  490,
+      489,  504,  504,  504,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,   11,    0,   23,    0,
-        0,    0,    0,    0,    0,    0,  514,    0,    0,    0,
-      165,    0,    0,    0,   53,  396,  337,    0,   39,    0,
-      513,   52,    0,    0,    0,    0,   38,    0,    0,   49,
+        0,    0,    0,    0,    0,    0,  520,    0,    0,    0,
+      165,    0,    0,    0,   53,  402,  343,    0,   39,    0,
 
+      519,   52,    0,    0,    0,    0,   38,    0,    0,   49,
         0,    0,   79,   79,   79,    0,  102,    0,    0,    0,
         0,    0,    0,    0,    0,    0,   96,   95,    0,  129,
-        0,    0,    0,    0,  397,  338,    0,    0,    0,  146,
+        0,    0,    0,    0,  403,  344,    0,    0,    0,  146,
         0,  138,  137,    0,  161,    0,    0,    0,    0,    0,
         0,    0,  214,  214,    0,  196,  195,    0,    0,    0,
-      214,    0,  215,  166,    0,    0,  285,    0,  269,  268,
-        0,    0,  285,    0,  255,  254,    0,    0,  285,  285,
-      285,  285,    0,    0,    0,    0,  300,  299,    0,    0,
-      308,    0,    0,    0,  333,    0,  319,  318,    0,    0,
-      333,    0,  317,  316,  333,    0,  334,  346,    0,  361,
-
-      361,    0,  392,  392,  392,    0,    0,    0,  392,    0,
-      393,  409,    0,    0,    0,    0,    0,    0,  430,    0,
-      447,    0,    0,    0,    0,    0,    0,    0,  498,  498,
-      498,  498,    0,    0,    0,  505,  504,    0,    0,    0,
-      529,  528,    0,  534,    0,    0,    0,    0,    0,    0,
-        0,  413,    0,    0,    0,    0,  290,  245,  514,    0,
-       28,    0,    0,    0,  482,   53,  337,  150,    0,  513,
-       52,  289,  244,   27,  481,    0,    0,   49,    0,    0,
-       50,   79,    0,    0,   79,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      214,    0,  215,  166,    0,    0,  291,    0,  269,  268,
+        0,    0,  291,  291,  291,    0,  255,  254,    0,    0,
+      291,  291,  291,  291,    0,    0,    0,    0,  306,  305,
+        0,    0,  314,    0,    0,    0,  339,    0,  325,  324,
+
+        0,    0,  339,    0,  323,  322,  339,    0,  340,  352,
+        0,  367,  367,    0,  398,  398,  398,    0,    0,    0,
+      398,    0,  399,  415,    0,    0,    0,    0,    0,    0,
+      436,    0,  453,    0,    0,    0,    0,    0,    0,    0,
+      504,  504,  504,  504,    0,    0,    0,  511,  510,    0,
+        0,    0,  535,  534,    0,  540,    0,    0,    0,    0,
+        0,    0,    0,  419,    0,    0,    0,    0,  296,  245,
+      520,    0,   28,    0,    0,    0,  488,   53,  343,  150,
+        0,  519,   52,  295,  244,   27,  487,    0,    0,   49,
+        0,    0,   50,   79,    0,    0,   79,    0,    0,    0,
 
-        0,  414,    0,    0,    0,    0,  338,  151,    0,    0,
-        0,    0,    0,    0,  155,  154,    0,    0,  175,    0,
-      181,  180,    0,  214,  214,    0,    0,  214,    0,    0,
-      285,    0,  271,  270,  285,    0,  249,  248,    0,    0,
-      285,  285,  285,    0,  251,  250,    0,    0,  294,  293,
-        0,    0,    0,  296,  295,    0,  333,    0,  321,  320,
-      333,  333,  346,    0,  361,    0,    0,    0,  392,    0,
-        0,  392,  392,    0,    0,  392,  409,    0,  410,    0,
-        0,  422,  421,    0,  420,  419,  430,    0,  447,    0,
-        0,    0,  473,  472,    0,  471,  470,    0,  498,  498,
-
-      498,  498,    0,    0,    0,    0,    0,    0,    0,   17,
-        0,   19,   18,    0,  413,  502,  350,    0,    0,  290,
-      245,    0,   28,  434,  178,   16,  482,  150,    0,    0,
-      289,  244,   27,  481,    0,    0,   49,  549,   79,    0,
-       67,   66,   79,    0,   80,    0,   98,   97,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  414,  351,    0,    0,    0,  151,    0,    0,
-      142,  141,    0,    0,  157,  156,    0,    0,  214,  214,
-        0,    0,    0,    0,  214,  179,    0,  285,  285,    0,
-      253,  252,  285,  285,  285,    0,    0,  298,  297,    0,
-
-      333,  333,  333,  346,    0,  347,  361,    0,  357,  356,
-        0,  392,    0,  374,  373,  392,  392,    0,    0,    0,
-        0,  392,  409,  435,  430,    0,  447,    0,    0,    0,
-        0,    0,  498,  498,  498,    0,  503,    0,    0,  521,
-        0,    0,    0,   17,    0,  502,  350,    0,    0,  229,
-      434,  178,   16,    0,    0,    0,    0,   35,   49,    0,
-        0,   79,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  420,    0,    0,    0,    0,  344,  151,
+        0,    0,    0,    0,    0,    0,  155,  154,    0,    0,
+      175,    0,  181,  180,    0,  214,  214,    0,    0,  214,
+        0,    0,  291,    0,  271,  270,  291,  291,  291,    0,
+      249,  248,    0,    0,  291,  291,  291,    0,  251,  250,
+        0,    0,  300,  299,    0,    0,    0,  302,  301,    0,
+      339,    0,  327,  326,  339,  339,  352,    0,  367,    0,
+        0,    0,  398,    0,    0,  398,  398,    0,    0,  398,
+      415,    0,  416,    0,    0,  428,  427,    0,  426,  425,
+
+      436,    0,  453,    0,    0,    0,  479,  478,    0,  477,
+      476,    0,  504,  504,  504,  504,    0,    0,    0,    0,
+        0,    0,    0,   17,    0,   19,   18,    0,  419,  508,
+      356,    0,    0,  296,  245,    0,   28,  440,  178,   16,
+      488,  150,    0,    0,  295,  244,   27,  487,    0,    0,
+       49,  555,   79,    0,   67,   66,   79,    0,   80,    0,
+       98,   97,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  420,  357,    0,    0,
+        0,  151,    0,    0,  142,  141,    0,    0,  157,  156,
+        0,    0,  214,  214,    0,    0,    0,    0,  214,  179,
+
+        0,  291,  291,  291,  291,    0,  253,  252,  291,  291,
+      291,    0,    0,  304,  303,    0,  339,  339,  339,  352,
+        0,  353,  367,    0,  363,  362,    0,  398,    0,  380,
+      379,  398,  398,    0,    0,    0,    0,  398,  415,  441,
+      436,    0,  453,    0,    0,    0,    0,    0,  504,  504,
+      504,    0,  509,    0,    0,  527,    0,    0,    0,   17,
+        0,  508,  356,    0,    0,  229,  440,  178,   16,    0,
+        0,    0,    0,   35,   49,    0,    0,   79,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+
+        0,  357,    0,    0,  230,    0,    0,    0,  162,    0,
+      214,  214,    0,  204,    0,  203,  214,  179,    0,  291,
+      291,  291,  291,  291,    0,    0,  291,  291,    0,  292,
+        0,  315,  339,  339,  339,  352,    0,    0,    0,    0,
+        0,  398,  398,  398,    0,  384,    0,  383,  398,  415,
+      441,  436,    0,  437,    0,    0,    0,    0,    0,    0,
+      492,  491,    0,    0,  504,  504,    0,  505,  509,    0,
+        0,    0,    0,    0,   24,    0,    0,  229,    0,    0,
+        0,   49,    0,    0,    0,   79,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  351,    0,    0,  230,    0,
-        0,    0,  162,    0,  214,  214,    0,  204,    0,  203,
-
-      214,  179,    0,  285,  285,    0,    0,  285,  285,    0,
-      286,    0,  309,  333,  333,  333,  346,    0,    0,    0,
-        0,    0,  392,  392,  392,    0,  378,    0,  377,  392,
-      409,  435,  430,    0,  431,    0,    0,    0,    0,    0,
-        0,  486,  485,    0,    0,  498,  498,    0,  499,  503,
-        0,    0,    0,    0,    0,   24,    0,    0,  229,    0,
-        0,    0,   49,    0,    0,    0,   79,    0,    0,    0,
+
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  230,    0,    0,    0,  188,  214,  214,
+      206,  205,    0,    0,    0,  291,  291,  291,  291,  291,
+        0,  281,  280,  291,    0,    0,  339,  339,    0,    0,
+      352,    0,  361,  360,    0,  368,    0,  376,  375,  398,
+      398,  398,  386,  385,    0,    0,  415,  436,    0,    0,
+        0,    0,  454,    0,    0,    0,  496,  495,    0,    0,
+        0,    0,    0,  516,    0,    0,    0,    0,  457,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,  230,    0,    0,    0,  188,  214,
-
-      214,  206,  205,    0,    0,    0,  285,  285,    0,  281,
-      280,  285,    0,    0,  333,  333,    0,    0,  346,    0,
-      355,  354,    0,  362,    0,  370,  369,  392,  392,  392,
-      380,  379,    0,    0,  409,  430,    0,    0,    0,    0,
-      448,    0,    0,    0,  490,  489,    0,    0,    0,    0,
-        0,  510,    0,    0,    0,    0,  451,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,   79,    0,
-        0,    0,    0,   88,    0,    0,    0,    0,   87,    0,
+       79,    0,    0,    0,    0,   88,    0,    0,    0,    0,
+
+       87,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  458,    0,    0,
+      214,    0,    0,    0,  208,  207,    0,  241,  291,  291,
+      291,    0,    0,  291,  291,    0,  279,  278,  339,    0,
+        0,    0,  335,  334,    0,    0,  398,  398,  398,    0,
+      388,  387,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  494,  493,
+        0,    0,    0,    0,  457,  133,    0,    0,    0,   45,
+       44,    0,    0,    0,    0,    0,    0,    0,    0,   79,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  452,    0,    0,  214,    0,
 
-        0,    0,  208,  207,    0,  241,  285,  285,  285,    0,
-      279,  278,  333,    0,    0,    0,  329,  328,    0,    0,
-      392,  392,  392,    0,  382,  381,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  488,  487,    0,    0,    0,    0,  451,  133,
-        0,    0,    0,   45,   44,    0,    0,    0,    0,    0,
-        0,    0,    0,   79,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  458,  134,    0,    0,    0,  214,
+        0,  210,  209,  291,  291,    0,    0,    0,  285,  284,
+        0,    0,  291,  339,    0,  331,  330,    0,  348,  347,
+      398,    0,    0,  398,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,  452,  134,
-        0,    0,    0,  214,    0,  210,  209,  285,  285,  285,
+        0,    0,    0,    0,    0,    0,  470,  133,   84,   83,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,   94,    0,    0,    0,   93,    0,    0,    0,
+        0,    0,  111,  119,    0,    0,    0,    0,    0,  110,
+
+      118,    0,    0,  471,  134,    0,    0,  200,  199,  214,
+      291,  291,    0,  283,  282,    0,  287,  286,  291,  339,
+      398,    0,  382,  381,  398,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  445,    0,    0,  444,    0,
+      467,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,  470,   84,   83,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,   63,   62,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  113,    0,    0,    0,    0,
+      112,    0,    0,  471,    0,  147,  214,  291,  291,    0,
+        0,  339,    0,    0,    0,    0,    0,    0,    0,    0,
 
-      333,    0,  325,  324,    0,  342,  341,  392,    0,    0,
-      392,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  464,  133,   84,   83,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,   94,
-        0,    0,    0,   93,    0,    0,    0,    0,    0,  111,
-      119,    0,    0,    0,    0,    0,  110,  118,    0,    0,
-      465,  134,    0,    0,  200,  199,  214,  285,  285,  285,
-      333,  392,    0,  376,  375,  392,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  439,    0,    0,  438,
-
-        0,  461,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  464,   84,   83,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   63,   62,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  113,    0,    0,    0,
-        0,  112,    0,    0,  465,    0,  147,  214,  285,  285,
-        0,    0,  333,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+       75,   71,    0,    0,   74,   70,    0,   92,    0,    0,
+       91,    0,    0,    0,  103,    0,    0,    0,    0,    0,
+        0,    0,    0,  214,  291,  291,    0,    0,    0,  339,
+        0,  378,  377,    0,    0,    0,  411,    0,  410,    0,
+      432,    0,  431,    0,  447,  449,  446,  448,    0,  484,
+      498,    0,  497,    0,    0,    0,    0,   12,    0,   12,
+        0,    0,    0,    0,    0,   86,   90,   85,   89,  125,
+        0,    0,  123,  124,    0,    0,  122,  214,  291,  291,
+
+        0,    0,    0,    0,  339,    0,    0,    0,    0,  409,
+      408,  430,  429,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  115,    0,    0,  114,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,   75,   71,    0,    0,   74,   70,    0,   92,    0,
-        0,   91,    0,    0,    0,  103,    0,    0,    0,    0,
-
-        0,    0,    0,    0,  214,  285,  285,    0,    0,    0,
-      333,    0,  372,  371,    0,    0,    0,  405,    0,  404,
-        0,  426,    0,  425,    0,  441,  443,  440,  442,    0,
-      478,  492,    0,  491,    0,    0,    0,    0,   12,    0,
-       12,    0,    0,    0,    0,    0,   86,   90,   85,   89,
-      125,    0,    0,  123,  124,    0,    0,  122,  214,  285,
-      285,    0,    0,    0,    0,  333,    0,    0,    0,    0,
-      403,  402,  424,  423,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  115,    0,    0,  114,    0,
+        0,    0,    0,    0,   69,    0,   68,    0,    0,  121,
+        0,  120,    0,  202,  201,    0,  277,  276,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,  333,  332,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,   11,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   69,    0,   68,    0,    0,
-      121,    0,  120,    0,  202,  201,    0,  277,  276,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,  327,
-      326,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       11,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      500,  499,    0,   73,   72,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,  494,  493,    0,   73,   72,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  117,  116,    0,    0,    0,    0,    0,
+        0,  263,    0,    0,  262,    0,    0,  390,    0,    0,
+      389,    0,    0,    0,    0,    0,  267,    0,  266,    0,
+      392,    0,  391,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  273,    0,  272,    0,    0,
 
+        0,    0,    0,    0,  275,  274,  265,  264,  394,  393,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,  117,  116,    0,    0,    0,    0,
-        0,    0,  263,    0,    0,  262,    0,    0,  384,    0,
-        0,  383,    0,    0,    0,    0,    0,  267,    0,  266,
-        0,  386,    0,  385,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  273,    0,  272,    0,
-        0,    0,    0,    0,    0,  275,  274,  265,  264,  388,
-      387,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   13,    0
+        0,    0,    0,    0,    0,    0,   13,    0
+
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -818,7 +823,7 @@ static yyconst flex_int32_t yy_meta[75] =
         5,    5,    5,    5
     } ;
 
-static yyconst flex_int16_t yy_base[3740] =
+static yyconst flex_int16_t yy_base[3779] =
     {   0,
         0,    0,    0,    3,    6,    9,   12,   29,   16,   19,
        14,   17,   33,   36,   49,   55,   45,   61,   66,   72,
@@ -847,1012 +852,1020 @@ static yyconst flex_int16_t yy_base[3740] =
      2209, 2212, 3207, 3274, 2215, 2219, 2266, 2269, 2272, 2276,
      2323, 2326, 3341, 3411, 2329, 2333, 3481, 3538, 2336, 2383,
      2386, 2389, 2393, 2396, 2443, 2446, 3595, 3665, 2449, 2453,
-        0,    0, 8929,11972,11972,   95,  100,   29,   41,11972,
-      103,   51,11972,11972, 8918,11972,11972, 8907,11972, 8918,
-     8918,  202,11972,11972,11972,11972, 8916, 8912, 8867,  153,
-    11972,  161, 8893,    0,  145,11972, 8855,11972,  165, 3731,
-       73, 2462,  315,  357, 8895, 8842,11972,  168, 8881,    0,
-
-      152,11972, 8843,11972,  261, 8887,   31,11972,  266, 8874,
-        0,  245,11972, 8836, 8840, 8834,  421, 8839,11972,  269,
-     8865,    0,  340,11972, 8827, 8827,  271, 8829,  238,11972,
-      441,  484,11972,  504, 8853,    0,  401,11972, 8812, 8814,
-     8800,11972,  561,  548,11972,  571, 8845,    0,  481,11972,
-     8812, 8796,11972,  628, 3795, 8794,  163, 2456,  567,  206,
-       38, 8845,  954, 2465,  639,  907,  437,   79,11972,  634,
-     8283,    0,  546,11972, 8239, 8248, 8236, 8241,11972,  638,
-      313,  368,11972,  697, 8277,    0,  549,11972, 8233, 8243,
-     8221,11972,  704,  426,  497,11972,  707, 8272,    0,  747,
-
-    11972, 8239, 8240,11972,  767,  753,11972,  773, 8261,    0,
-      757,11972, 8231, 8205,11972,  831,  818,11972,  838, 8250,
-        0,  758,11972, 8199, 8204, 8209, 8196, 8186,11972,  841,
-      559,  825,  530,11972,  906, 8233,    0,  815,11972, 8202,
-    11972,  914,  891,11972,  977, 8226,    0,  953,11972, 8182,
-     8186, 8172,11972,  981,  965,11972, 1021, 8215,    0,  966,
-    11972, 8163,  203, 8157, 8167, 8168,   85,  311,  972,11972,
-     1040, 1025,11972, 1048, 8189,    0, 1026,11972, 8137, 8154,
-     8156,  157, 8154, 8129,11972, 1088, 1092,11972, 1105, 8177,
-        0, 1033,11972, 8121, 8119, 8125, 8124, 8126, 8108, 8102,
-
-    11972, 1112, 1154,11972, 1115, 8148,    0, 1089,11972, 8104,
-     8091,11972, 1118, 1160,11972, 1174, 8118,    0, 1090,11972,
-     8088, 8072, 8074,11972, 1180, 1228,11972, 1183, 8101,    0,
-     1158,11972, 8067, 8063, 8064,   15,11972, 1186,  564,  814,
-    11972, 1241, 8088,    0, 1225,11972, 8040,  181,11972, 1248,
-     1294,  367,  303,11972, 1305, 8085,    0, 1226,11972, 8029,
-     8024,  299,11972, 1309, 1224,  350,11972, 1365, 8074,    0,
-     1293,11972, 8034, 8038,11972, 1368, 1352,11972, 1372, 8059,
-        0, 1360,11972, 8011, 8007,11972, 1376, 1426,  424,11972,
-     1433, 8052,    0, 1418,11972, 8003, 7997, 8001,11972, 1438,
-
-     1436,  429,11972, 1503, 8045,    0, 1423,11972, 7990, 7988,
-     7993, 7986, 7974,11972, 1507, 1504,  560,  899,11972, 1510,
-     8021,    0, 1428,11972, 7990,11972, 1568, 1622,11972, 1574,
-     8010,    0, 1482,11972, 7973,11972, 1577,  963, 1007,11972,
-     1635, 7991,    0, 1496,11972, 7953, 7955,11972, 1638, 1623,
-     1697,  677, 7930,11972, 7973, 7958,11972,11972,11972, 1690,
-      253, 7909, 7898, 7896, 7943, 7902,11972,    0, 7894, 7891,
-     7904, 7875,  104, 1383, 7871, 7869, 7863, 7867,  621, 1636,
-      704, 7854, 7845, 1500, 1037, 7871, 1691, 7842, 1699, 7837,
-     1709, 1710, 1711,11972,    0, 7841, 7833,11972,    0, 7828,
-
-     2088, 7821,  666, 7817, 7860,11972,    0, 7817, 2155, 7805,
-     7827, 7799, 7808, 7788, 7788, 7771,11972,    0, 7776, 7757,
-     7769, 7739,11972,    0, 2222, 7737, 7778, 7759,  172, 7733,
-     7732, 7733, 1767, 1105, 7717, 1768, 7744,  707,  724,  814,
-      841, 1297, 1782, 1567,  888,11972,    0, 7720, 2279, 7728,
-     7698, 7700,11972,    0, 7704, 2456, 7700, 7692,11972,    0,
-     2514, 7696, 7695,11972,    0, 7693, 7685, 7687,11972,    0,
-     7697,  758, 2519, 7670, 7690, 7681,  889,11972,    0, 7675,
-     7679,11972,    0, 7657, 2525, 2577, 7664,11972,    0, 7660,
-     7654, 2580, 7635, 2583, 7631, 7617, 7634, 7633, 7611, 7630,
-
-     7627, 7620, 7618,11972,    0, 2586, 2589, 7599, 7595, 7604,
-     7604, 7600, 7598,11972,    0, 7599, 7595, 7579, 2644, 7572,
-     7560, 7579, 7562,11972,    0, 7559, 2647, 7544,11972,    0,
-     7547, 2650, 7539, 7549,11972,    0, 7536, 2653, 7528, 7542,
-     7540, 7527,11972,    0, 7518, 7533, 7510, 7504, 7511,11972,
-        0, 7492, 7509, 7501, 7490, 7527,11972,    0, 7481, 2656,
-     7485,11972,    0, 7476, 7491, 7475,11972,    0, 7456, 7473,
-     7468, 7462,11972,    0, 7449, 7433, 7439, 7447, 7444, 7428,
-     7416,11972,    0, 7421, 7430,11972,    0, 2711, 7420,11972,
-        0, 2714, 7410, 7404, 7447, 7451, 1537, 7398,11972, 1823,
-
-        0, 7393, 7388, 7433, 7428, 7381,11972, 7389, 7370, 2719,
-     2722, 1971, 7380, 7373, 7359, 7371, 7351, 7355, 7342, 7329,
-     7344, 7331, 7315, 7315, 7328, 7327, 7306, 7306, 7297, 7294,
-     7303, 7289, 7283, 1980, 7290, 7270, 7286, 7276, 7265, 7277,
-     7270, 2725, 2732, 7267, 2781, 2038, 7238, 7269, 2786, 2789,
-    11972, 7233, 2793, 2107, 2799, 7223, 2845, 7226, 7230, 7225,
-     2848, 2855, 7194, 7198, 7198, 2858, 2903, 2906, 2174, 7179,
-     2910, 2916, 2353, 7191, 7173, 7165, 7156, 7156, 7153, 7142,
-     7147, 2413, 7144, 7133, 7127, 7125, 7125, 2913, 2539, 7138,
-     7137, 2959, 2962, 7120, 2968, 2608, 7134, 2972, 3029, 2986,
-
-     2675, 7117, 3034, 3037, 7116, 7109, 3040, 3043, 7104, 7087,
-     7095, 3099, 2745, 7093, 7072, 3102, 3109, 7066, 7055, 7069,
-     3112, 3165, 7055, 3105, 2813, 3160, 2991, 3171, 3174, 7057,
-     1910, 3178, 3062, 7054, 3186, 3197, 3228, 7052, 7049, 7045,
-     7028, 7029, 7003, 7013, 3231, 3236, 3239, 3246, 3295, 3298,
-     3306, 3313, 3320, 3376, 3373, 3242, 3361, 7005,   37, 6995,
-     3365, 3387, 3432, 7006, 6967, 3309, 3444, 6968, 3435, 3395,
-     3439, 3458, 6980, 3501, 3463, 6974, 3504, 3511, 6974, 3507,
-     3471, 6960, 6934, 6930, 3514, 3560, 3563, 3567, 3570, 3573,
-     3618, 6934, 3621, 3641, 3630, 3644, 3633, 3686, 6938, 3694,
-
-     3652, 3697, 3700, 3712, 3725, 3730, 3735, 3743, 3757, 3764,
-     3738, 3769, 6929, 6911, 6908, 6910, 6897, 3799, 3802, 6897,
-     6881, 3808, 3811, 3775, 3823, 3833, 3837, 3845, 3863, 6880,
-     3871, 3876, 6925,11972,11972,  940, 6884,11972, 6922, 6921,
-     6869,11972,11972, 6850, 6845, 6854, 3879, 3882,11972, 3885,
-     1704, 6847, 6839, 6841, 6844, 6833, 6818, 6826, 1771, 6804,
-     6809, 6802, 6798, 6795, 6791, 6783, 1109, 6798, 6776, 6767,
-     6777, 6773, 6773, 2047, 6767, 6755, 6754, 6746, 1510, 6760,
-     3890, 3904, 3908,11972, 3911, 3914, 3917,11972,11972, 3933,
-     6784, 3936, 3941,11972, 3944, 6727, 3951,11972,11972, 3947,
-
-     3965, 3973, 3976, 3979, 6740, 3987, 6737, 3995, 3998,11972,
-     4001, 6735, 4005, 6732, 4008, 4023,11972, 4027, 4030,11972,
-    11972, 6726, 4038, 4042,11972, 4046, 6717, 6706, 6714, 2240,
-     6691, 6695, 1912, 6684, 6681, 6697, 6695, 6659, 6658, 6652,
-     4050,11972,11972, 6634, 4065, 4068, 4071,11972, 4075, 6640,
-     4083,11972,11972, 6661, 4078, 4097,11972, 4100, 4103,11972,
-    11972, 4111, 4119, 4122,11972, 4125, 4129, 4132, 4150, 4153,
-    11972, 4156, 6626, 6633, 4162, 4165,11972,11972, 6608, 6620,
-     4175, 4180,11972, 4183, 6604, 6577, 4186, 4189, 4194,11972,
-     4208, 4204, 4213,11972,11972, 4223,11972,11972, 4231, 4234,
-
-    11972, 4237, 6579, 6562, 6582, 6566, 4240,11972,11972, 4256,
-     4259,11972,11972, 4267, 4270, 6555, 6560, 6561, 6558, 6548,
-     6549, 6543, 4278, 4281,11972, 4285, 4288,11972,11972, 4304,
-    11972,11972, 4312, 4315, 6533, 6540, 6538, 6528, 4323, 4326,
-    11972, 4330, 6523, 6520, 6511, 6518, 4333,11972,11972, 4345,
-     4349, 6501, 6509, 4357, 4363,11972, 4366, 6505, 4369,11972,
-    11972, 4385, 4388,11972, 4391, 6484, 4394,11972,11972, 6492,
-     4410, 4413,11972, 4418, 6481, 4422,11972,11972, 6479, 6482,
-     6481, 4432, 4437,11972, 4441, 4444, 4447, 4462, 4468, 6480,
-     4476, 4480,11972, 4484, 6472, 4487, 4505, 6459, 6452, 4491,
-
-     4513, 6464, 4521, 4524,11972, 4527, 6464, 4530,11972,11972,
-     4546, 4552,11972, 4555, 4558, 4561, 4576, 4579, 4587, 4594,
-    11972, 4598, 4601, 4606, 6439, 6421, 4619, 4622, 4630, 4633,
-    11972, 4637, 6408, 4640, 6427, 6420, 6396, 4643, 4652,11972,
-     4662, 6385, 6394, 4665, 4671,11972, 4674, 4677,11972,11972,
-     4685, 4693,11972, 4696, 4700,11972,11972, 6389, 4708, 4715,
-    11972, 4718, 1013, 4728,11972,11972, 6409, 6408, 6366, 6350,
-     4737, 6330, 6336, 6307, 6268, 6259, 6250, 6258, 2297, 2549,
-     6243, 2552, 6188, 6184, 2616, 6191, 6164, 2619, 6153, 6161,
-     6140, 6109, 6083, 6047, 5994, 5948, 5897, 2683, 5797, 5759,
-
-     4740, 4758, 4743, 4749, 4767, 5744, 5715, 4775, 5686, 4780,
-    11972,11972, 4788, 4795, 4806,11972,11972, 5684, 4814, 4818,
-     5679, 4826, 5561, 4832, 4835, 4845, 4850, 5558, 4752,11972,
-     5541,   16,   22, 2686, 2863, 3000, 2753,  141,  269,  315,
-      332,  352,  386,  384, 4853, 4856, 4859, 4877,  416,  447,
-     4880, 4883, 4886, 4901, 4904, 4907,  448, 4915,  461,  470,
-     4922, 4925, 4934, 4945, 4948,  482,  490, 4952, 4956, 4970,
-     4973, 4977, 4985,  569, 4992,  575,  636, 4995, 4998, 5006,
-    11972,11972, 5015,  625,  680,  678,  693,  764,  759, 5018,
-     5021,11972,11972, 5029, 5033, 5037, 5040, 5043,  797, 5047,
-
-      824,  840, 5058,11972,11972, 5068,  854, 5071,  863, 5074,
-      991, 1047, 5077, 1048, 1088, 1096, 5080, 5086, 5105,11972,
-    11972, 5113,11972,11972, 1094, 5100, 3135, 5121,11972,11972,
-     1139, 1171, 5129,11972,11972, 1166, 5137, 1173, 5144, 5147,
-    11972,11972, 5156,11972,11972, 5167, 5170,11972,11972, 1201,
-     1242, 5179,11972,11972, 5187, 1238, 5190, 5193, 1228, 1245,
-     1255, 5202, 1244, 5208, 5211, 5215, 5221, 5226, 1402, 1311,
-     5230,11972, 1335,11972,11972, 1319, 1337, 5235, 1346, 1372,
-     1363, 1383, 1414, 1429, 1433, 2877, 1430, 1439, 3131, 1442,
-     3265, 1485, 3269, 1491, 1488, 3332, 1497, 3404, 1528, 3533,
-
-     1529, 1540, 1571, 1572, 1593, 3368, 1579, 4495, 5239,11972,
-    11972, 5254, 5257,11972,11972, 1606, 1638, 5268, 1618, 5273,
-    11972,11972, 1627, 5289,11972,11972, 1620, 5282, 1624, 5301,
-     2898, 2944, 5309, 5313, 5322, 1642, 1657, 1685, 1682, 3588,
-     1707, 3624, 3761, 5327, 1713, 1727, 1742, 5330, 5333, 1749,
-     5336, 5344, 5354,11972,11972, 5362, 1750, 5365, 5368, 5374,
-    11972,11972, 5383, 5388,11972,11972, 5402, 5398, 1773, 1770,
-     5406,11972,11972, 5420, 5423, 5431, 5434, 1785, 5442, 5445,
-     1792, 5450,11972,11972, 5463,11972, 5466,11972,11972, 5474,
-     1793, 5477, 5482, 5495, 1778, 5498,11972,11972, 5506, 5509,
-
-     5517, 1786, 1889, 1897, 1907, 5524, 5527, 5530, 5535, 5548,
-     5551, 5554, 5557, 1914, 5560, 5572, 5580, 1904, 5583, 5587,
-     1925, 5601, 1918, 5604, 1934, 1931, 5610, 1967, 1954, 1973,
-     5613, 5625, 1976, 5633, 1965, 5636, 1982, 5639, 5642, 5645,
-     5648, 1986, 5667, 5663, 5671, 5674, 5677, 1990, 5682,11972,
-    11972, 2014, 2026, 2026, 5692, 2042, 5697, 5700, 5716, 5719,
-     5722, 5725, 5744, 2077, 2100, 2167,11972, 2032, 5747, 5750,
-     2047, 2046, 2055, 2143, 2050, 2055, 5753, 2081, 2100, 2093,
-     5756, 2109, 2101, 2108, 5759, 5765, 5769, 2131, 5776, 2134,
-     5779, 5782, 2120, 2139, 2175, 2162, 5785, 2180, 5788, 2181,
-
-     2212, 5791, 2175, 5795, 2182, 5798, 5801, 2223, 2226, 2255,
-     2250, 2266, 2253, 2312, 2255, 5813,11972,11972, 5821, 5824,
-     2242, 2234, 2321, 2245, 5827, 5830, 2266, 2323, 2324, 5833,
-     5842,11972,11972, 5851, 5854, 5858, 5861, 5872, 5876, 5879,
-     5882, 5891, 2291, 2303, 5898,11972,11972, 5906, 2322, 2343,
-     2337, 5914,11972, 5917, 2347, 5921, 2346, 5926,11972,11972,
-     5934, 5940, 2348, 5948,11972,11972, 5956, 5959, 5967, 2349,
-     2360, 2355, 5970, 5974, 5988, 5991,11972,11972, 5999, 6003,
-     6011, 6017, 6020, 6029, 2361, 6036,11972,11972, 6044, 6048,
-     2372, 6056,11972,11972, 2365, 6064,11972, 2390, 6067, 2386,
-
-     6070, 6073, 2394, 6076, 2415, 6088, 2429, 2430, 2415, 6096,
-    11972, 2419, 6099, 2409, 6102, 6105, 6123, 6126, 2424, 6135,
-     2419, 6141, 6144, 6147, 6150, 6165, 6168, 6176, 2423, 2425,
-     2419, 2432, 6179, 2450, 6184,11972,11972, 6198, 6202, 6206,
-    11972,11972, 6217,11972, 2575, 2699, 2574, 2453, 6221, 6224,
-     6232, 6245, 2457, 2479, 2495, 2472, 6251, 6256, 6259, 2477,
-     6262, 2484, 2496, 2512, 6265, 6268, 6271, 6274, 2535, 6277,
-     6280, 6283, 6286, 6289, 6292, 2543, 6297, 2550, 2567, 6300,
-    11972, 2549, 6304, 6307, 2567, 6322, 6325, 6328, 2626, 2623,
-     2624, 2630, 2624, 2633, 2634, 2634, 2645, 2639, 6336, 6343,
-
-     6349, 6357, 2630, 2668, 2657, 2669, 6361, 6364, 6367, 6370,
-     6378, 6381, 6386, 6399,11972,11972, 6407, 6412,11972, 6415,
-    11972,11972, 6426, 2672, 2672, 2772, 3024, 2681, 2691, 6431,
-     2693, 6434,11972,11972, 2712, 6446,11972,11972, 6454, 6459,
-     2728, 2717, 2726, 6468,11972,11972, 6476, 6480,11972,11972,
-     6488, 6491, 6499,11972,11972, 6507, 2727, 6510,11972,11972,
-     2730, 2748, 2743, 6518, 2758, 6521, 6526, 6541, 2764, 6544,
-     6547, 2767, 2759, 3034, 3035, 2764, 2790, 6556,11972, 2791,
-     6562,11972,11972, 6575,11972,11972, 2803, 6570, 2794, 6584,
-     6589, 6592,11972,11972, 6604,11972,11972, 6612, 6616, 6622,
-
-     6626, 6634, 6640, 2795, 6644, 6647, 6652, 2917, 3069, 6655,
-     6659,11972,11972, 6667, 6674, 6677, 6680, 2803, 2801, 6686,
-     6694, 2814, 6697, 6700, 6706, 6709, 6712, 6715, 2806, 2814,
-     6718, 6721, 6727, 6730, 2836, 6733, 2854,11972, 6736, 6739,
-    11972,11972, 6747, 6754,11972, 6758,11972,11972, 2899, 2886,
-     2907, 2906, 2942, 2953, 2943, 2958, 2964, 2972, 6766, 6769,
-     6752, 6757, 6794, 6798, 2933, 2932, 2963, 6801, 2960, 6804,
-    11972,11972, 6814, 6817,11972,11972, 6828, 6833, 2972, 2981,
-     3008, 3044, 3028, 3047, 3014, 6836, 6839, 3015, 3040, 6843,
-    11972,11972, 6852, 3033, 3045, 6861, 6864,11972,11972, 6872,
-
-     3042, 3064, 3068, 3070, 6875,11972, 6880, 6885,11972,11972,
-     6894, 6900, 6903,11972,11972, 6913, 6918, 3099, 3121, 3103,
-     3122, 6921, 3107, 6924, 3116, 6931, 6927, 6939, 6951, 6958,
-     6954, 6963, 6973, 6980, 6983, 6986, 6991, 7001, 7005,11972,
-     7008, 3146, 3203, 7013, 7020, 7016, 7027, 3107, 3103, 7035,
-     7039, 7042, 7045, 3111, 3131, 3134, 7048,11972, 3129, 7051,
-     7054, 3147, 3193, 3209, 3224, 3216, 3227, 3247, 3255, 3270,
-     3258, 3280, 7062, 3259, 3269, 3271, 3264, 3269, 3300, 3313,
-     3325, 3325, 3320, 3317, 3343, 7071, 3339, 3335, 7074, 3332,
-     7077, 7081,11972, 7084, 3341, 3373, 3438,11972, 3436,11972,
-
-     7087, 7090, 7096, 3381, 3402, 7106, 7109, 3392, 7117, 7124,
-    11972, 7127,11972, 3385, 3388, 7130, 3389, 7135, 7154, 7139,
-     7148, 7162, 7170, 7173, 7176, 3457,11972, 3459,11972, 7179,
-     3411, 7182, 3416, 7197,11972, 7200, 7203, 7211, 7218, 7223,
-     7226,11972,11972, 7237, 7242, 7250, 7255, 7258,11972, 7261,
-     7264, 3459, 3630, 3505, 7268,11972, 3443, 3469, 7273, 3459,
-     3476, 3477, 7277, 7288, 3795, 4026, 3469, 3503, 3532, 3537,
-     3556, 3573, 3553, 3565, 3564, 3572, 3602, 7296, 3549, 3561,
-     3566, 3570, 3577, 3591, 3587, 3590, 3604, 3601, 3631, 3630,
-     3634, 3625, 3638, 3656, 7299, 3646, 7302, 7305,11972, 3645,
-
-     7308,11972,11972, 7311, 7315, 7329, 3646, 3657, 7332,11972,
-    11972, 3666, 7340, 7344, 3651, 7352, 7358, 7361, 7370, 7376,
-    11972,11972, 7384,11972, 7388,11972,11972, 7396, 7399, 7403,
-    11972,11972, 7406, 7410, 7424, 7427, 7430, 3749, 3835, 7438,
-    11972, 7445, 7452, 7460,11972,11972, 7471, 7474, 7482, 7485,
-     7494,11972, 3736, 3731, 3734, 3658, 7500, 3677, 3697, 3698,
-     7503, 7514, 3731, 3734, 3799, 3737, 3782, 3836, 3761, 3813,
-     3801, 3809, 3848,11972, 3870, 3855, 3853, 3859,11972, 7506,
-     3836, 3845, 3849, 3865, 3874, 3876, 3881, 3865, 3882, 3885,
-     3899, 3910, 3912, 3921, 3904, 7525, 3920, 7528, 7531, 7534,
-
-     7537, 7552,11972,11972, 7560,11972, 3936, 3923, 3936, 7563,
-    11972,11972, 3946, 7571, 7579, 7591,11972,11972, 7599, 7602,
-     7610, 7613, 7617, 7621,11972,11972, 7631, 7635, 7643, 7649,
-     3977, 3978, 3979, 3981, 3983, 3983, 7657, 7661, 7669, 3997,
-     4058, 7680,11972,11972, 4040, 4035, 7688, 3970, 7574, 7691,
-     3969, 3970, 7694,11972,11972, 4035, 4030, 4058, 4066, 4075,
-     4075, 4076, 4088, 7702, 4078, 4097, 4131, 4118, 4101, 4121,
-     4135, 4124, 7709, 4079, 4082, 4098, 4155, 4166, 4152, 4120,
-     4131, 4134, 4150, 4195, 4204, 4195, 4160, 4168, 7712, 7715,
-     7720, 7723, 7729, 4176, 7741,11972,11972, 4177, 4185, 4174,
-
-     4194, 7749,11972,11972, 7759,11972,11972, 7767, 7772, 7775,
-     7785, 7790, 4221, 4258, 7799, 4264, 4267, 4209, 4218, 4249,
-     4221, 4232, 4269, 7807, 7810, 4265, 4270, 4270, 4285, 4302,
-     7813, 7819, 7822, 7832, 7841, 7844, 7847, 4285, 4297, 4313,
-     4301, 4306, 4318, 4320, 4318, 7850, 7853, 4333, 4333,11972,
-     4344, 4347, 4349,11972, 4351, 7861, 4329, 4316, 4379,11972,
-    11972, 4350, 4349, 4349, 4336, 4397,11972,11972, 4358, 4357,
-     7864, 7868, 7871, 7880,11972,11972, 4353, 4361, 4366, 7890,
-     4370, 7893, 7896,11972,11972, 7904, 4393, 4406, 4401, 4416,
-     4418, 4429, 4422, 4433, 4427, 4441,11972, 4433, 4447,11972,
-
-     7911,11972, 7914, 4449, 4437, 4459, 4453, 4482, 7917, 7924,
-     7936, 7967, 8014, 7944, 7947, 7950, 4476, 4499, 4506, 4473,
-     4493, 4511, 4512, 4495, 7955,11972,11972, 4531, 4505, 4507,
-     4533, 4513, 4518, 7978, 4486, 4502,11972, 4502, 4514, 4507,
-     4508,11972, 4509, 4527, 7987, 7990,11972, 4526, 4527, 4541,
-     7993, 7997, 4534, 8005, 8034, 8025, 8043, 4593, 4567, 4602,
-     4574, 4610, 4580, 4618, 4590, 4624, 4642, 4640, 4642, 8051,
-     4646, 4618, 4651, 4621, 4670, 8060, 4664, 4706, 8080, 8127,
-     4657,11972,11972, 4654, 4679,11972,11972, 4669,11972, 4702,
-     4708,11972, 4714, 4715, 8054,11972, 4721, 4684, 4681, 4731,
-
-     4741, 4716, 4713, 4765, 4722, 4727, 4712, 8100, 4761, 4767,
-     4734, 8108,11972,11972, 8116, 4775, 4784,11972, 4787,11972,
-     4787,11972, 4807,11972, 4810,11972,11972,11972,11972, 8073,
-    11972,11972, 4803,11972, 4809, 4812, 4871, 4822, 4834, 4913,
-     4836, 8138, 4835, 4840, 4852, 4843,11972,11972,11972,11972,
-    11972, 4870, 4819,11972,11972, 4890, 4822,11972, 8147, 8150,
-     8153, 4871, 4867, 4898, 4869, 8158, 4920, 4886, 4944, 4901,
-    11972,11972,11972,11972, 4894, 4902, 8161, 4938, 4924, 4948,
-     8176, 4961, 4947, 4961, 4960,11972, 4935, 4985,11972, 4954,
-     4997, 8180, 8183, 8191, 8198, 8209, 8212, 4973, 4993, 5006,
-
-     4989, 5021, 5033, 8220, 8228, 5017, 5025, 5043, 5028, 5036,
-     5070, 5053, 5055, 8223, 5076,11972, 5064,11972, 5067, 5059,
-    11972, 5062,11972, 8238,11972,11972, 8246,11972,11972, 8254,
-     5116, 5127, 5081, 5088, 5088, 5092, 5101, 5106, 8262,11972,
-    11972, 5115, 5128, 5125, 5130, 5142, 5139, 5172, 5171, 5181,
-    11972, 5178, 5177, 5142, 5152, 5198, 5192, 5222, 5218, 5219,
-     5226, 5226, 5224, 5237, 5238, 5235, 5242, 5242, 5243, 5253,
-     5255,11972,11972, 5267,11972,11972, 5241, 5243, 5257, 5277,
-     5261, 5286, 5272, 5273, 5293, 5283, 5286, 5316, 5306, 5303,
-     5324, 5314, 5311, 5329, 5339, 5355, 5353, 5336, 5336, 5344,
-
-     5351, 5369, 5361, 5401, 5387, 5377, 5407, 5393, 5383, 5422,
-     5404, 5394, 5432, 5435,11972,11972, 5412, 5431, 5428, 5434,
-     5457, 5438,11972, 5464, 5441,11972, 5476, 5454,11972, 5480,
-     5457,11972, 5472, 5456, 5470, 5466, 5480,11972, 5490,11972,
-     5491,11972, 5497,11972, 5498, 8270, 5509, 5534, 5516, 5536,
-     5502, 5504, 5521, 5522, 8273, 5562,11972, 5560,11972, 5565,
-     5563, 5574, 5579, 5577, 5598,11972,11972,11972,11972,11972,
-    11972, 5639, 5642, 5672, 5819, 5678, 5745, 5578, 5606, 5580,
-     5589, 5643, 5693, 5605, 5754, 5718, 5790, 5829, 5852, 5688,
-     5787, 5848, 5879, 5846, 5869, 5662, 5786, 5911, 5928, 5927,
-
-     5944, 5913, 5990, 5935, 5964, 5959, 5968, 6033, 6041, 5984,
-     6065, 5976, 6044, 6063, 6066, 6095, 6111, 6015, 6092, 6140,
-     6156, 5936, 6114, 6102, 6174, 6121, 6175, 6178, 6277, 5885,
-     6219, 6171, 6329, 6321, 6334, 6316, 6384, 6187, 6386, 6328,
-     6373, 6387, 6402, 5991, 6433, 6221, 6294, 6446, 6447, 6097,
-     6355, 6484, 6517, 6313, 6008, 8281, 8284,11972,11972, 8304,
-     8313, 8322, 8331, 8340, 8349, 8358, 8367, 8376, 8385, 8394,
-     8403, 8412, 8421, 8430, 8439, 8448, 8457, 8466, 8475, 8484,
-     8493, 8502, 8511, 8520, 8529, 8538, 8547, 8556, 8565, 8574,
-     8583, 8592, 8601, 8610, 8619, 8628, 8637, 8646, 8655, 8664,
-
-     8673, 8682, 8691, 8700, 8709, 8718, 8727, 8736, 8745, 8754,
-     8763, 8772, 8781, 8790, 8799, 8808, 8817, 8826, 8835, 8844,
-     8851, 8858, 8865, 8872, 8879, 8886, 8893, 8900, 8907, 8914,
-     8921, 8928, 8935, 8942, 8949, 8956, 8963, 8970, 8977, 8984,
-     8991, 8998, 9005, 9012, 9019, 9026, 9033, 9040, 9049, 9056,
-     9061, 9068, 9073, 9080, 9085, 9092, 9097, 9104, 9109, 9116,
-     9121, 9128, 9133, 9140, 9145, 9152, 9157, 9164, 9169, 9176,
-     9181, 9188, 9193, 9200, 9205, 9212, 9217, 9224, 9229, 9236,
-     9241, 9248, 9253, 9260, 9265, 9272, 9277, 9284, 9289, 9296,
-     9301, 9308, 9313, 9320, 9325, 9332, 9337, 9344, 9349, 9356,
-
-     9361, 9368, 9373, 9380, 9385, 9394, 9400, 9407, 9415, 9422,
-     9430, 9437, 9445, 9452, 9460, 9467, 9475, 9482, 9490, 9497,
-     9505, 9512, 9520, 9527, 9535, 9542, 9550, 9557, 9565, 9572,
-     9580, 9587, 9595, 9602, 9610, 9618, 9626, 9633, 9641, 9648,
-     9656, 9663, 9671, 9678, 9686, 9694, 9702, 9710, 9718, 9725,
-     9733, 9741, 9749, 9757, 9765, 9772, 9780, 9787, 9795, 9803,
-     9810, 9818, 9827, 9833, 9840, 9848, 9856, 9864, 9872, 9880,
-     9887, 9895, 9902, 9910, 9917, 9925, 9932, 9940, 9947, 9955,
-     9963, 9971, 9979, 9987, 9994,10002,10010,10018,10026,10034,
-    10041,10049,10056,10064,10071,10079,10086,10094,10101,10109,
-
-    10116,10124,10131,10139,10146,10154,10161,10169,10177,10184,
-    10192,10199,10207,10214,10222,10230,10237,10245,10254,10263,
-    10270,10278,10286,10293,10301,10308,10316,10323,10331,10338,
-    10345,10353,10360,10368,10376,10383,10391,10398,10406,10414,
-    10422,10429,10437,10445,10453,10460,10468,10475,10483,10490,
-    10498,10505,10513,10520,10528,10535,10543,10550,10558,10566,
-    10573,10581,10588,10596,10604,10612,10620,10628,10636,10645,
-    10654,10661,10669,10677,10684,10692,10699,10707,10714,10722,
-    10729,10736,10744,10751,10759,10767,10775,10783,10790,10798,
-    10806,10813,10821,10829,10837,10844,10852,10859,10867,10874,
-
-    10882,10889,10897,10904,10912,10920,10928,10935,10943,10951,
-    10959,10967,10974,10982,10990,10998,11006,11015,11024,11032,
-    11040,11048,11055,11063,11070,11078,11086,11094,11102,11110,
-    11118,11126,11134,11142,11150,11157,11165,11172,11180,11188,
-    11196,11203,11210,11218,11225,11233,11240,11247,11255,11262,
-    11270,11277,11285,11293,11301,11308,11316,11324,11332,11341,
-    11350,11358,11366,11373,11380,11388,11396,11404,11412,11420,
-    11427,11435,11442,11450,11458,11465,11472,11480,11487,11495,
-    11502,11509,11516,11524,11531,11539,11547,11555,11563,11571,
-    11579,11587,11596,11605,11613,11621,11628,11636,11644,11652,
-
-    11660,11668,11675,11683,11690,11698,11706,11713,11720,11728,
-    11736,11744,11751,11758,11766,11774,11782,11790,11798,11806,
-    11814,11822,11831,11840,11848,11855,11862,11870,11878,11886,
-    11893,11901,11908,11917,11926,11935,11944,11953,11962
+        0,    0, 9023,12038,12038,   95,  100,   29,   41,12038,
+      103,   51,12038,12038, 9012,12038,12038, 9001,12038, 9012,
+     9012,  202,12038,12038,12038,12038, 9010, 9006, 8961,  153,
+    12038,  161, 8987,    0,  145,12038, 8949,12038,  165, 3731,
+       73, 2462,  315,  357, 8989, 8936,12038,  168, 8975,    0,
+
+      152,12038, 8937,12038,  261, 8981,   31,12038,  266, 8968,
+        0,  245,12038, 8930, 8934, 8928,  421, 8933,12038,  269,
+     8959,    0,  340,12038, 8921, 8921,  271, 8923,  238,12038,
+      441,  484,12038,  504, 8947,    0,  401,12038, 8906, 8908,
+     8894,12038,  561,  548,12038,  571, 8939,    0,  481,12038,
+     8906, 8890,12038,  628, 3795, 8888,  163, 2456,  567,  206,
+       38, 8939,  954, 2465,  639,  907,  437,   79,12038,  634,
+     8926,    0,  546,12038, 8882, 8892, 8876, 8881,12038,  638,
+      313,  368,12038,  697, 8917,    0,  549,12038, 8869, 8879,
+     8857,12038,  704,  426,  497,12038,  707, 8905,    0,  747,
+
+    12038, 8872, 8874,12038,  767,  753,12038,  773, 8349,    0,
+      757,12038, 8319, 8293,12038,  831,  818,12038,  838, 8345,
+        0,  758,12038, 8294, 8300, 8310, 8298, 8292,12038,  841,
+      559,  825,  530,12038,  906, 8338,    0,  815,12038, 8308,
+    12038,  914,  891,12038,  977, 8335,    0,  953,12038, 8284,
+     8294, 8280,12038,  981,  965,12038, 1021, 8316,    0,  966,
+    12038, 8265,  203, 8270, 8275,  378,   85,  311,  972,12038,
+     1040, 1025,12038, 1048, 8305,    0, 1026,12038, 8249, 8267,
+     8268,  157, 8263, 8242,12038, 1088, 1092,12038, 1105, 8284,
+        0, 1033,12038, 8232, 8230, 8236, 8234, 8236, 8220, 8207,
+
+    12038, 1112, 1154,12038, 1115, 8254,    0, 1089,12038, 8209,
+     8219,12038, 1118, 1160,12038, 1174, 8249,    0, 1090,12038,
+     8215, 8211, 8208,12038, 1180, 1228,12038, 1183, 8236,    0,
+     1158,12038, 8205, 8190, 8192,   15,12038, 1186,  564,  814,
+    12038, 1241, 8217,    0, 1225,12038, 8169,  181,12038, 1248,
+     1294,  432,  303,12038, 1305, 8214,    0, 1226,12038, 8166,
+     8138,  299,12038, 1309, 1224,  350,12038, 1365, 8184,    0,
+     1293,12038, 8146, 8138,12038, 1368, 1352,12038, 1372, 8169,
+        0, 1360,12038, 8120, 8116,12038, 1376, 1426,  676,12038,
+     1433, 8161,    0, 1418,12038, 8112, 8103, 8107,12038, 1438,
+
+     1436,  685,12038, 1503, 8151,    0, 1423,12038, 8093, 8098,
+     8103, 8095, 8088,12038, 1507, 1504,  560,  899,12038, 1510,
+     8125,    0, 1428,12038, 8095,12038, 1568, 1622,12038, 1574,
+     8119,    0, 1482,12038, 8086,12038, 1577,  963, 1007,12038,
+     1635, 8116,    0, 1496,12038, 8082, 8084,12038, 1638, 1623,
+     1697,  677, 8059,12038, 8115, 8097,12038,12038,12038, 1690,
+      253, 8048, 8046, 8039, 8087, 8045,12038,    0, 8030, 8027,
+     8038, 8005,  104, 1383, 8006, 8005, 7987, 7987,  889, 1636,
+     1037, 7975, 7965, 1500, 1105, 7991, 1691, 7962, 1699, 7950,
+     1709, 1710, 1711,12038,    0, 7955, 7956,12038,    0, 7948,
+
+     2088, 7941,  666, 7936, 7979,12038,    0, 7934, 2155, 7922,
+     7937, 7923, 7925, 7922, 7922, 7902,12038,    0, 7914, 7903,
+     7905, 7885,12038,    0, 2222, 7882, 7924, 7906,  172, 7875,
+     7874, 7879, 1767, 1297, 7866, 1768, 7890,  707,  724,  814,
+      841, 1567, 1782, 1629,  888,12038,    0, 7866, 2279, 7871,
+     7848, 7843,12038,    0, 7847, 2456, 7843, 7832,12038,    0,
+     2514, 7837, 7826,12038,    0, 7825, 7819, 7814,12038,    0,
+     7816,  373, 2519, 7793, 7804, 7796,  897,12038,    0, 7789,
+     7790,12038,    0, 7773, 2525, 2577, 7786,12038,    0, 7792,
+     7791, 2580, 7768, 2583, 7765, 7766, 7763, 7753, 7760, 7760,
+
+     7741, 7756, 7753, 7743, 7745,12038,    0, 2586, 2589, 7726,
+     7713, 7729, 7724, 7720, 7715,12038,    0, 7716, 7715, 7695,
+     2644, 7688, 7683, 7704, 7687,12038,    0, 7682, 2647, 7671,
+    12038,    0, 7664, 2650, 7651, 7668,12038,    0, 7654, 2653,
+     7637, 7655, 7653, 7637,12038,    0, 7628, 7642, 7630, 7620,
+     7627,12038,    0, 7615, 7626, 7622, 7610, 7644,12038,    0,
+     7599, 2656, 7600,12038,    0, 7591, 7606, 7598,12038,    0,
+     7577, 7595, 7588, 7577,12038,    0, 7564, 7557, 7555, 7565,
+     7559, 7543, 7539,12038,    0, 7537, 7547,12038,    0, 2711,
+     7543,12038,    0, 2714, 7528, 7517, 7560, 7568, 1537, 7507,
+
+    12038, 1823,    0, 7493, 7493, 7537, 7532, 7485,12038, 7497,
+     7477, 2719, 2722, 1971, 7487, 7490, 7454, 7466, 7446, 7450,
+     7441, 7439, 7451, 7431, 7423, 7422, 7429, 7432, 7412, 7410,
+     7390, 7388, 7401, 7382, 7380, 1980, 7388, 7364, 7381, 7372,
+     7349, 7355, 7350, 2725, 2732, 7348, 2781, 2038, 7336, 7368,
+     2786, 2789,12038, 7337, 2793, 2107, 2799, 7327, 2845, 7330,
+     7330, 7333, 2848, 2855, 7313, 7320, 7310, 2858, 2903, 2906,
+     2174, 7292, 2910, 2916, 2353, 7306, 7291, 7281, 7281, 7281,
+     7279, 7271, 7266, 2413, 7264, 7262, 7254, 7251, 7227, 2913,
+     2539, 7240, 7233, 2959, 2962, 7217, 2968, 2608, 7230, 2972,
+
+     3029, 2986, 2675, 7229, 3034, 3037, 7220, 7202, 3040, 3043,
+     7193, 7183, 7194, 3099, 2745, 7189, 7169, 3102, 3109, 7165,
+     7155, 7165, 3112, 3165, 7154, 3105, 2813, 3160, 2991, 3171,
+     3174, 7154, 1910, 3178, 3062, 7157, 3186, 3197, 3228, 7151,
+     7133, 7143, 7140, 7136, 7123, 7124, 7120, 7133, 3231, 3236,
+     3239, 3246, 3295, 3298, 3306, 3313, 3320, 3376, 3373, 3242,
+     3361, 7113,   37, 7103, 3365, 3387, 3432, 7109, 7093, 3309,
+     3444, 7087, 3435, 3395, 3439, 3458, 7096, 3501, 3463, 7093,
+     3504, 3511, 7088, 3507, 3471, 7082, 7057, 7054, 3514, 3560,
+     3563, 3567, 3570, 3573, 3618, 7055, 3621, 3641, 3630, 3644,
+
+     3633, 3686, 7061, 3694, 3652, 3697, 3700, 3712, 3725, 3730,
+     3735, 3743, 3757, 3764, 3738, 3769, 7056, 7037, 7043, 7048,
+     7030, 3799, 3802, 7040, 7002, 3808, 3811, 3775, 3823, 3833,
+     3837, 3845, 3863, 6998, 3871, 3876, 7042,12038,12038, 1138,
+     7001,12038, 7042, 7018, 6967,12038,12038, 6964, 6959, 6969,
+     3879, 3882,12038, 3885, 1704, 6950, 6931, 6939, 6947, 6934,
+     6913, 6925, 1771, 6900, 6904, 6904, 6890, 6887, 6883, 6877,
+      446, 6892, 6871, 6872, 6885, 6864, 6861, 2047, 6854, 6843,
+     6848, 6834, 1109, 6842, 3890, 3904, 3908,12038, 3911, 3914,
+     3917,12038,12038, 3933, 6865, 3936, 3941,12038, 3944, 6819,
+
+     3951,12038,12038, 3947, 3965, 3973, 3976, 3979, 6829, 3987,
+     6820, 3995, 3998,12038, 4001, 6816, 4005, 6808, 4008, 4023,
+    12038, 4027, 4030,12038,12038, 6803, 4038, 4042,12038, 4046,
+     6795, 6798, 6802, 2240, 6782, 6785, 1510, 6765, 6762, 6778,
+     6776, 6756, 6754, 6761, 4050,12038,12038, 6752, 4065, 4068,
+     4071,12038, 4075, 6758, 4083,12038,12038, 6779, 4078, 4097,
+    12038, 4100, 4103,12038,12038, 4111, 4119, 4122,12038, 4125,
+     4129, 4132, 4150, 4153,12038, 4156, 6733, 6739, 4162, 4165,
+    12038,12038, 6723, 6735, 4175, 4180,12038, 4183, 6723, 6720,
+     4186, 4189, 4194,12038, 4208, 4204, 4213,12038,12038, 4223,
+
+    12038,12038, 4231, 4234,12038, 4237, 6720, 6694, 6714, 6703,
+     4240,12038,12038, 4256, 4259,12038,12038, 4267, 4270, 6686,
+     6702, 6681, 6689, 6693, 6674, 6669, 6652, 6637, 4278, 4281,
+    12038, 4285, 4288,12038,12038, 4304,12038,12038, 4312, 4315,
+     6627, 6634, 6635, 6628, 4323, 4326,12038, 4330, 6614, 6611,
+     6597, 6588, 4333,12038,12038, 4345, 4349, 6573, 6580, 4357,
+     4363,12038, 4366, 6579, 4369,12038,12038, 4385, 4388,12038,
+     4391, 6551, 4394,12038,12038, 6559, 4410, 4413,12038, 4418,
+     6546, 4422,12038,12038, 6550, 6554, 6552, 4432, 4437,12038,
+     4441, 4444, 4447, 4462, 4468, 6549, 4476, 4480,12038, 4484,
+
+     6541, 4487, 4505, 6530, 6519, 4491, 4513, 6530, 4521, 4524,
+    12038, 4527, 6531, 4530,12038,12038, 4546, 4552,12038, 4555,
+     4558, 4561, 4576, 4579, 4587, 4594,12038, 4598, 4601, 4606,
+     6513, 6504, 4619, 4622, 4630, 4633,12038, 4637, 6494, 4640,
+     6507, 6505, 6484, 4643, 4652,12038, 4662, 6472, 6486, 4665,
+     4671,12038, 4674, 4677,12038,12038, 4685, 4693,12038, 4696,
+     4700,12038,12038, 6483, 4708, 4715,12038, 4718, 1013, 4728,
+    12038,12038, 6517, 6516, 6477, 6455, 4737, 6446, 6437, 6437,
+     6408, 6397, 6357, 6340, 2297, 2549, 6327, 2552, 6310, 6270,
+     2616, 6281, 6266, 2619, 6255, 6262, 6256, 6192, 6159, 6151,
+
+     6100, 6066, 6044, 2683, 6002, 5974, 4740, 4758, 4743, 4749,
+     4767, 5914, 5881, 4775, 5686, 4780,12038,12038, 4788, 4795,
+     4806,12038,12038,   17, 4814, 4818,   36, 4826,  132, 4832,
+     4835, 4845, 4850,  256, 4752,12038,  313,  349,  338, 2686,
+     2863, 3000, 2753,  393,  429,  432,  460,  497,  503,  556,
+     4853, 4856, 4859, 4877,  581,  632, 4880, 4883, 4886, 4901,
+     4904, 4907,  633, 4915,  680,  698, 4922, 4925, 4934, 4945,
+     4948,  699,  746, 4952, 4956, 4970, 4973, 4977, 4985,  772,
+     4992,  756,  782, 4995, 4998, 5006,12038,12038,  793,  843,
+     5015,  825,  853,  854,  986, 1050, 1033, 5018, 5021,12038,
+
+    12038, 5029, 5033, 5037, 5040, 5043, 1090, 5047, 1139, 1165,
+     5058,12038,12038, 5068, 1186, 5071, 1184, 5074, 1212, 1242,
+     5077, 1238, 1245, 1240, 5080, 5086, 5105,12038,12038, 5113,
+    12038,12038, 1235, 5100, 3135, 5121,12038,12038, 1237, 1280,
+     5129,12038,12038, 1287, 5137, 1314, 5144, 5147,12038,12038,
+     5156,12038,12038, 5167, 5170,12038,12038, 1331, 1363, 5179,
+    12038,12038, 5187, 1365, 5190, 5193, 1357, 1369, 1399, 5202,
+     1389, 5208, 5211, 5215, 5221, 5226, 1538, 1447, 5230,12038,
+     1462,12038,12038, 1425, 1428, 5235, 1423, 1440, 1471, 1487,
+     1502, 1531, 1546, 2877, 1564, 1573, 3131, 1594, 3265, 1597,
+
+     3269, 1600, 1619, 3332, 1626, 3404, 1635, 3533, 1642, 1664,
+     1695, 1696, 1715, 3368, 1701, 4495, 5239,12038,12038, 5254,
+     5257,12038,12038, 1737, 1769, 5268, 1749, 5273,12038,12038,
+     1758, 5289,12038,12038, 1753, 5282, 1764, 5301, 2898, 2944,
+     5309, 5313, 5322, 1784, 1773, 1780, 1777, 3588, 1786, 3624,
+     3761, 5327, 1882, 1885, 1894, 5330, 5333, 1895, 5336, 5344,
+     5354,12038,12038, 5362, 1896, 5365, 5368, 5374,12038,12038,
+     5383, 5388,12038,12038, 5402, 5398, 1916, 1914, 5406,12038,
+    12038, 5420, 5423, 5431, 5434, 1925, 5442, 5445, 1931, 5450,
+    12038,12038, 5463,12038, 5466,12038,12038, 5474, 1936, 5477,
+
+     5482, 5495, 1938, 5498,12038,12038, 1953, 1976, 5506, 5509,
+     5517, 1968, 1982, 1976, 1979, 5524, 5527, 5530, 5535, 5548,
+     5551, 5554, 5557, 1993, 5560, 5572, 5580, 1991, 5583, 5587,
+     2017, 5601, 2024, 5604, 2042, 2022, 5610, 2045, 2025, 2045,
+     5613, 5625, 2054, 5633, 2048, 5636, 2066, 5639, 5642, 5645,
+     5648, 2061, 5667, 5663, 5671, 5674, 5677, 2057, 5682,12038,
+    12038, 2064, 2078, 2085, 5692, 2108, 5697, 5700, 5716, 5719,
+     5722, 5725, 5744, 2144, 2167, 2185,12038, 2096, 5747, 5750,
+     2112, 2105, 2113, 2264, 2116, 2119, 5753, 2131, 2167, 2160,
+     5756, 2176, 2166, 2167, 5759, 5765, 5769, 2186, 5776, 2194,
+
+     5779, 5782, 2194, 2211, 2232, 2221, 5785, 2238, 5788, 2240,
+     2273, 5791, 2233, 5795, 2262, 5798, 5801, 2312, 2306, 2372,
+     2307, 2323, 2310, 2432, 2312, 5813,12038,12038, 5821, 5824,
+     2299, 2296, 2383, 2302, 5827, 5830, 2308, 2384, 2443, 5833,
+     5842,12038,12038, 5851, 5854, 5858, 5861, 5872, 5876, 5879,
+     5882, 5891, 2305, 2330, 5898,12038,12038, 5906, 2367, 2372,
+     2355, 5914,12038, 5917, 2363, 5921, 2382, 5926,12038,12038,
+     5934, 5940, 2406, 2418, 2413, 5948,12038,12038, 5956, 5959,
+     5967, 2419, 2429, 2425, 5970, 5974, 5988, 5991,12038,12038,
+     5999, 6003, 6011, 6017, 6020, 6029, 2428, 6036,12038,12038,
+
+     6044, 6048, 2437, 6056,12038,12038, 2431, 6064,12038, 2440,
+     6067, 2444, 6070, 6073, 2446, 6076, 2477, 6088, 2496, 2498,
+     2478, 6096,12038, 2482, 6099, 2478, 6102, 6105, 6123, 6126,
+     2492, 6135, 2510, 6141, 6144, 6147, 6150, 6165, 6168, 6176,
+     2532, 2534, 2529, 2544, 6179, 2544, 6184,12038,12038, 6198,
+     6202, 6206,12038,12038, 6217,12038, 2587, 2699, 2595, 2555,
+     6221, 6224, 6232, 6245, 2572, 2609, 2625, 2602, 6251, 6256,
+     6259, 2605, 6262, 2606, 2620, 2613, 6265, 6268, 6271, 6274,
+     2617, 6277, 6280, 6283, 6286, 6289, 6292, 2619, 6297, 2626,
+     2661, 6300,12038, 2654, 6304, 6307, 2682, 6322, 6325, 6328,
+
+     2697, 2701, 2701, 2709, 2710, 2739, 2741, 2741, 2751, 2744,
+     6336, 6343, 6349, 6357, 2745, 2760, 2744, 2746, 6361, 6364,
+     6367, 6370, 6378, 6381, 6386, 6399,12038,12038, 6407, 6412,
+    12038, 6415,12038,12038, 6426, 2751, 2746, 3024, 3034, 2760,
+     2768, 6431, 2763, 6434,12038,12038, 2762, 2781, 2805, 6446,
+    12038,12038, 6454, 6459, 2802, 2792, 2803, 6468,12038,12038,
+     6476, 6480,12038,12038, 6488, 6491, 6499,12038,12038, 6507,
+     2809, 6510,12038,12038, 2802, 2813, 2806, 6518, 2820, 6521,
+     6526, 6541, 2842, 6544, 6547, 2868, 2860, 3035, 3096, 2866,
+     2882, 6556,12038, 2875, 6562,12038,12038, 6575,12038,12038,
+
+     2887, 6570, 2906, 6584, 6589, 6592,12038,12038, 6604,12038,
+    12038, 6612, 6616, 6622, 6626, 6634, 6640, 2910, 6644, 6647,
+     6652, 3009, 3069, 6655, 6659,12038,12038, 6667, 6674, 6677,
+     6680, 2914, 2914, 6686, 6694, 2925, 6697, 6700, 6706, 6709,
+     6712, 6715, 2928, 2936, 6718, 6721, 6727, 6730, 2937, 6733,
+     2933,12038, 6736, 6739,12038,12038, 6747, 6754,12038, 6758,
+    12038,12038, 2997, 2988, 3008, 3003, 3024, 3030, 3016, 3041,
+     3063, 3070, 6766, 6769, 6752, 6757, 6794, 6798, 3032, 3030,
+     3058, 6801, 3053, 6804,12038,12038, 6814, 6817,12038,12038,
+     6828, 6833, 3069, 3074, 3103, 3150, 3138, 3157, 3117, 6836,
+
+     6839, 3114, 3129, 3136, 3323, 6843,12038,12038, 6852, 3133,
+     3145, 6861, 6864,12038,12038, 6872, 3145, 3151, 3170, 3183,
+     6875,12038, 6880, 6885,12038,12038, 6894, 6900, 6903,12038,
+    12038, 6913, 6918, 3230, 3253, 3233, 3255, 6921, 3216, 6924,
+     3241, 6931, 6927, 6939, 6951, 6958, 6954, 6963, 6973, 6980,
+     6983, 6986, 6991, 7001, 7005,12038, 7008, 3286, 3283, 7013,
+     7020, 7016, 7027, 3242, 3250, 7035, 7039, 7042, 7045, 3246,
+     3264, 3265, 7048,12038, 3258, 7051, 7054, 3300, 3339, 3337,
+     3351, 3346, 3362, 3359, 3355, 3370, 3361, 3402, 7062, 3384,
+     3388, 3463, 3386, 3381, 3395, 3393, 3398, 3518, 3393, 3394,
+
+     3411, 7071, 3408, 3408, 7074, 3406, 7077, 7081,12038, 7084,
+     3444, 3452, 3516,12038, 3516,12038, 7087, 7090, 7096, 3461,
+     3482, 3471, 3483, 3512, 7106, 7109, 3508, 7117, 7124,12038,
+     7127,12038, 3511, 3516, 7130, 3521, 7135, 7154, 7139, 7148,
+     7162, 7170, 7173, 7176, 3588,12038, 3602,12038, 7179, 3558,
+     7182, 3559, 7197,12038, 7200, 7203, 7211, 7218, 7223, 7226,
+    12038,12038, 7237, 7242, 7250, 7255, 7258,12038, 7261, 7264,
+     3631, 3630, 3644, 7268,12038, 3560, 3577, 7273, 3575, 3604,
+     3606, 7277, 7288, 3795, 4026, 3599, 3662, 3672, 3671, 3687,
+     3704, 3688, 3697, 3697, 3701, 3715, 7296, 3657, 3672, 3685,
+
+     3689, 3689, 3694, 3686, 3700, 3712, 3711, 3715, 3722, 3725,
+     3720, 3724, 3743, 7299, 3754, 7302, 7305,12038, 3748, 7308,
+    12038,12038, 7311, 7315, 7329, 3750, 3770, 3779, 7332, 3775,
+     7335,12038,12038, 3797, 7343, 7350, 3785, 7361, 7364, 7367,
+     7375, 7382,12038,12038, 7393,12038, 7396,12038,12038, 7404,
+     7407, 7412,12038,12038, 7415, 7418, 7426, 7433, 7437, 3835,
+     4268, 7445,12038, 7451, 7454, 7464,12038,12038, 7460, 7474,
+     7482, 7485, 7493,12038, 3878, 3870, 3910, 3803, 7496, 3842,
+     3846, 3850, 7501, 7505, 3865, 3868, 3951, 3884, 3889, 4000,
+     3867, 3916, 3916, 3914, 3921,12038, 3940, 3928, 3939, 3945,
+
+    12038, 7519, 3927, 3954, 3941, 3956, 3964, 3966, 3971, 3956,
+     3978, 3965, 3995, 4004, 4007, 4016, 4015, 7522, 4037, 7525,
+     7528, 7531, 7534, 7549,12038,12038, 7557,12038, 4045, 4031,
+     7560, 7563, 7581, 7567, 4045, 7589,12038,12038, 4049, 7597,
+     7600, 7608,12038,12038, 7616, 7619, 7627, 7630, 7634, 7638,
+    12038,12038, 7648, 7652, 7660, 7666, 4072, 4074, 4074, 4080,
+     4082, 4082, 7674, 7678, 7686, 4112, 4193, 7697,12038,12038,
+     4152, 4120, 7705, 4088, 7571, 7708, 4075, 4076, 7711,12038,
+    12038, 4124, 4112, 4114, 4133, 4158, 4164, 4166, 4174, 7719,
+     4164, 4191, 4215, 4208, 4205, 4225, 4239, 4230, 7726, 4185,
+
+     4188, 4204, 4258, 4260, 4244, 4218, 4227, 4229, 4247, 4291,
+     4293, 4288, 4252, 4267, 7729, 7732, 7737, 7740, 7746, 4268,
+     7758,12038,12038, 4269, 4278, 7766, 7769, 7777,12038,12038,
+     7785, 7789, 4267, 4287, 7797,12038,12038, 7805,12038,12038,
+     7813, 7816, 7819, 7827, 7834, 4339, 4364, 7845, 4392, 4397,
+     4301, 4310, 4350, 4314, 4327, 4354, 7853, 7856, 4346, 4353,
+     4351, 4356, 4438, 7859, 7865, 7868, 7878, 7887, 7890, 7893,
+     4350, 4375, 4377, 4365, 4371, 4381, 4385, 4379, 7899, 7902,
+     4394, 4399,12038, 4424, 4426, 4429,12038, 4432, 7910, 4414,
+     4400, 4467,12038,12038, 4426, 4424, 4432, 4433, 4493,12038,
+
+    12038, 4456, 4460, 7913, 7917, 7923, 7929,12038,12038, 4456,
+     4461, 4463, 7938,12038,12038, 7946,12038,12038, 7954, 4464,
+     7957, 7960,12038,12038, 7968, 4499, 4511, 4502, 4514, 4506,
+     4519, 4510, 4525, 4517, 4542,12038, 4534, 4545,12038, 7977,
+    12038, 7980, 4547, 4535, 4550, 4545, 4566, 7986, 7989, 8008,
+     8033, 8080, 7999, 8016, 8019, 4562, 4586, 4588, 4559, 4581,
+     4602, 4604, 4576, 8023,12038,12038, 4613, 4594, 4597, 4639,
+     4616, 4618, 8044, 4586, 4592,12038, 4593, 4604, 4604, 4605,
+    12038, 4617, 4633, 8053, 8056,12038, 4632, 4633, 4656, 8059,
+     8063, 4648, 8071, 8100, 8091, 8109, 4708, 4676, 4714, 4685,
+
+     4720, 4688, 4724, 4695, 4730, 4731, 4741, 4756, 8117, 4760,
+     4734, 4766, 4740, 4765, 8126, 4782, 4791, 8146, 8193, 4773,
+    12038,12038, 4755, 4780,12038,12038, 4758,12038, 4800, 4807,
+    12038, 4805, 4810, 8120,12038, 4817, 4776, 4779, 4834, 4833,
+     4794, 4792, 4841, 4813, 4814, 4796, 8166, 4893, 4903, 4818,
+     8174,12038,12038, 8182, 4906, 4930,12038, 4867,12038, 4865,
+    12038, 4870,12038, 4868,12038,12038,12038,12038, 8139,12038,
+    12038, 4869,12038, 4871, 4878, 4964, 4894, 4888, 5045, 4887,
+     8204, 4884, 4886, 4907, 4914,12038,12038,12038,12038,12038,
+     4961, 4892,12038,12038, 4982, 4909,12038, 8213, 8216, 8219,
+
+     5088, 4937, 5122, 4953, 8224, 5139, 4974, 5145, 4984,12038,
+    12038,12038,12038, 4988, 4990, 8227, 5023, 5034, 5048, 8242,
+     5052, 5046, 5060, 5070,12038, 5044, 5089,12038, 5047, 5089,
+     8246, 8249, 8257, 8264, 8275, 8278, 5061, 5080, 5096, 5081,
+     5093, 5112, 8286, 8294, 5103, 5119, 5132, 5115, 5133, 5153,
+     5137, 5138, 8289, 5164,12038, 5164,12038, 5167, 5157,12038,
+     5169,12038, 8304,12038,12038, 8312,12038,12038, 8320, 5225,
+     5260, 5184, 5193, 5206, 5210, 5216, 5213, 8328,12038,12038,
+     5217, 5229, 5227, 5230, 5235, 5235, 5272, 5272, 5298,12038,
+     5288, 5287, 5241, 5245, 5284, 5279, 5287, 5285, 5290, 5302,
+
+     5315, 5314, 5324, 5325, 5322, 5329, 5333, 5331, 5337, 5347,
+    12038,12038, 5359,12038,12038, 5321, 5328, 5349, 5373, 5367,
+     5391, 5377, 5375, 5394, 5383, 5387, 5405, 5394, 5400, 5417,
+     5418, 5416, 5433, 5453, 5454, 5452, 5426, 5433, 5437, 5444,
+     5461, 5452, 5484, 5466, 5458, 5494, 5479, 5469, 5510, 5491,
+     5486, 5515, 5520,12038,12038, 5505, 5516, 5515, 5522, 5559,
+     5533,12038, 5559, 5536,12038, 5565, 5539,12038, 5571, 5555,
+    12038, 5589, 5555, 5569, 5560, 5573,12038, 5574,12038, 5575,
+    12038, 5584,12038, 5592, 8336, 5594, 5616, 5599, 5617, 5589,
+     5610, 5611, 5615, 8339, 5656,12038, 5654,12038, 5666, 5673,
+
+     5686, 5689, 5687, 5718,12038,12038,12038,12038,12038,12038,
+     5819, 5822, 5829, 5846, 5745, 5786, 5694, 5717, 5693, 5720,
+     5893, 5919, 5801, 5944, 5755, 5790, 5906, 5927, 5962, 5979,
+     5879, 5913, 5928, 5978, 5935, 5964, 6017, 6033, 6041, 6063,
+     5688, 5818, 6023, 6068, 5990, 6044, 6065, 6102, 5869, 6120,
+     6165, 6178, 6103, 6138, 6145, 6155, 6097, 6277, 6174, 6193,
+     5976, 6092, 6218, 6221, 6061, 6294, 6357, 6373, 6321, 6337,
+     6177, 6355, 6334, 6384, 6386, 6393, 6387, 6444, 6379, 6400,
+     6447, 6449, 6374, 6424, 6301, 6506, 6433, 6517, 5936, 6171,
+     6537, 6547, 6236, 5787, 8347, 8350,12038,12038, 8370, 8379,
+
+     8388, 8397, 8406, 8415, 8424, 8433, 8442, 8451, 8460, 8469,
+     8478, 8487, 8496, 8505, 8514, 8523, 8532, 8541, 8550, 8559,
+     8568, 8577, 8586, 8595, 8604, 8613, 8622, 8631, 8640, 8649,
+     8658, 8667, 8676, 8685, 8694, 8703, 8712, 8721, 8730, 8739,
+     8748, 8757, 8766, 8775, 8784, 8793, 8802, 8811, 8820, 8829,
+     8838, 8847, 8856, 8865, 8874, 8883, 8892, 8901, 8910, 8917,
+     8924, 8931, 8938, 8945, 8952, 8959, 8966, 8973, 8980, 8987,
+     8994, 9001, 9008, 9015, 9022, 9029, 9036, 9043, 9050, 9057,
+     9064, 9071, 9078, 9085, 9092, 9099, 9106, 9115, 9122, 9127,
+     9134, 9139, 9146, 9151, 9158, 9163, 9170, 9175, 9182, 9187,
+
+     9194, 9199, 9206, 9211, 9218, 9223, 9230, 9235, 9242, 9247,
+     9254, 9259, 9266, 9271, 9278, 9283, 9290, 9295, 9302, 9307,
+     9314, 9319, 9326, 9331, 9338, 9343, 9350, 9355, 9362, 9367,
+     9374, 9379, 9386, 9391, 9398, 9403, 9410, 9415, 9422, 9427,
+     9434, 9439, 9446, 9451, 9460, 9466, 9473, 9481, 9488, 9496,
+     9503, 9511, 9518, 9526, 9533, 9541, 9548, 9556, 9563, 9571,
+     9578, 9586, 9593, 9601, 9608, 9616, 9623, 9631, 9638, 9646,
+     9653, 9661, 9668, 9676, 9684, 9692, 9699, 9707, 9714, 9722,
+     9729, 9737, 9744, 9752, 9760, 9768, 9776, 9784, 9791, 9799,
+     9807, 9815, 9823, 9831, 9838, 9846, 9853, 9861, 9869, 9876,
+
+     9884, 9893, 9899, 9906, 9914, 9922, 9930, 9938, 9946, 9953,
+     9961, 9968, 9976, 9983, 9991, 9998,10006,10013,10021,10029,
+    10037,10045,10053,10060,10068,10076,10084,10092,10100,10107,
+    10115,10122,10130,10137,10145,10152,10160,10167,10175,10182,
+    10190,10197,10205,10212,10220,10227,10235,10243,10250,10258,
+    10265,10273,10280,10288,10296,10303,10311,10320,10329,10336,
+    10344,10352,10359,10367,10374,10382,10389,10397,10404,10411,
+    10419,10426,10434,10442,10449,10457,10464,10472,10480,10488,
+    10495,10503,10511,10519,10526,10534,10541,10549,10556,10564,
+    10571,10579,10586,10594,10601,10609,10616,10624,10632,10639,
+
+    10647,10654,10662,10670,10678,10686,10694,10702,10711,10720,
+    10727,10735,10743,10750,10758,10765,10773,10780,10788,10795,
+    10802,10810,10817,10825,10833,10841,10849,10856,10864,10872,
+    10879,10887,10895,10903,10910,10918,10925,10933,10940,10948,
+    10955,10963,10970,10978,10986,10994,11001,11009,11017,11025,
+    11033,11040,11048,11056,11064,11072,11081,11090,11098,11106,
+    11114,11121,11129,11136,11144,11152,11160,11168,11176,11184,
+    11192,11200,11208,11216,11223,11231,11238,11246,11254,11262,
+    11269,11276,11284,11291,11299,11306,11313,11321,11328,11336,
+    11343,11351,11359,11367,11374,11382,11390,11398,11407,11416,
+
+    11424,11432,11439,11446,11454,11462,11470,11478,11486,11493,
+    11501,11508,11516,11524,11531,11538,11546,11553,11561,11568,
+    11575,11582,11590,11597,11605,11613,11621,11629,11637,11645,
+    11653,11662,11671,11679,11687,11694,11702,11710,11718,11726,
+    11734,11741,11749,11756,11764,11772,11779,11786,11794,11802,
+    11810,11817,11824,11832,11840,11848,11856,11864,11872,11880,
+    11888,11897,11906,11914,11921,11928,11936,11944,11952,11959,
+    11967,11974,11983,11992,12001,12010,12019,12028
     } ;
 
-static yyconst flex_int16_t yy_def[3740] =
+static yyconst flex_int16_t yy_def[3779] =
     {   0,
-     3260, 3260, 3261, 3261, 3261, 3261, 3262, 3262, 3263, 3263,
-     3264, 3264, 3265, 3265, 3265, 3265, 3266, 3266, 3260, 3260,
-     3267, 3267, 3268, 3268, 3268, 3268, 3260, 3260, 3268, 3268,
-     3268, 3268, 3260, 3260, 3268, 3268, 3260, 3260, 3268, 3268,
-     3268, 3268, 3269, 3269, 3270, 3270, 3260, 3260, 3270, 3270,
-     3270, 3270, 3271, 3271, 3265, 3265, 3272, 3272, 3273, 3273,
-     3274, 3274, 3275, 3275, 3276, 3276, 3277, 3277, 3277, 3277,
-     3260, 3260, 3277, 3277, 3277, 3277, 3260, 3260, 3277, 3277,
-     3277, 3277, 3260, 3260, 3277, 3277, 3260, 3260, 3277, 3277,
-     3277, 3277, 3260, 3260, 3277, 3277, 3260, 3260, 3277, 3277,
-
-     3277, 3277, 3278, 3278, 3279, 3279, 3260, 3260, 3279, 3279,
-     3279, 3279, 3280, 3280, 3281, 3281, 3260, 3260, 3281, 3281,
-     3281, 3281, 3282, 3282, 3283, 3283, 3284, 3284, 3285, 3285,
-     3286, 3286, 3287, 3287, 3260, 3260, 3287, 3287, 3287, 3287,
-     3288, 3288, 3289, 3289, 3290, 3290, 3291, 3291, 3259,  149,
-     3292, 3292, 3293, 3293, 3294, 3294, 3295, 3295, 3296, 3296,
-     3297, 3297, 3298, 3298, 3299, 3299, 3300, 3300, 3301, 3301,
-     3302, 3302, 3260, 3260, 3302, 3302, 3302, 3302, 3303, 3303,
-     3304, 3304, 3260, 3260, 3304, 3304, 3304, 3304, 3305, 3305,
-     3306, 3306, 3260, 3260, 3306, 3306, 3306, 3306, 3307, 3307,
-
-     3308, 3308, 3309, 3309, 3310, 3310, 3260, 3260, 3310, 3310,
-     3310, 3310, 3311, 3311, 3312, 3312, 3260, 3260, 3312, 3312,
-     3312, 3312, 3313, 3313, 3314, 3314, 3260, 3260, 3314, 3314,
-     3314, 3314, 3315, 3315, 3316, 3316, 3317, 3317, 3318, 3318,
-     3260, 3260, 3318, 3318, 3318, 3318, 3319, 3319, 3320, 3320,
-     3260, 3260, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3321, 3259, 3259, 3321, 3259, 3259, 3259,
-      290,  290,  292,  290,  293,  293, 3259, 3259, 3259, 3322,
-
-     3259, 3259, 3322, 3259, 3259,  294,  293, 3259, 3259, 3259,
-     3323, 3259, 3259, 3323, 3323, 3323, 3259, 3259, 3259, 3259,
-     3259, 3324, 3259, 3259, 3324, 3324, 3324, 3324, 3324, 3259,
-     3259, 3259, 3259, 3259, 3259, 3325, 3259, 3259, 3325, 3325,
-     3325, 3259, 3259, 3259, 3259, 3259, 3259, 3326, 3259, 3259,
-     3326, 3326, 3259, 3259, 3259,  355,  293,  293,  294,  359,
-      358,  358,  358,  358,  359,  365,  363,  363, 3259, 3259,
-     3259, 3327, 3259, 3259, 3327, 3327, 3327, 3327, 3259, 3259,
-      293,  293, 3259, 3259, 3259, 3328, 3259, 3259, 3328, 3328,
-     3328, 3259, 3259,  293,  293, 3259, 3259, 3259, 3329, 3259,
-
-     3259, 3329, 3329, 3259, 3259, 3259, 3259, 3259, 3259, 3330,
-     3259, 3259, 3330, 3330, 3259, 3259, 3259, 3259, 3259, 3259,
-     3331, 3259, 3259, 3331, 3331, 3331, 3331, 3331, 3259, 3259,
-      293,  293,  293, 3259, 3259, 3259, 3332, 3259, 3259, 3332,
-     3259, 3259, 3259, 3259, 3259, 3259, 3333, 3259, 3259, 3333,
-     3333, 3333, 3259, 3259, 3259, 3259, 3259, 3259, 3334, 3259,
-     3259, 3334, 3334, 3334, 3334, 3334, 3334, 3334, 3334, 3259,
-     3259, 3259, 3259, 3259, 3259, 3335, 3259, 3259, 3335, 3335,
-     3335, 3335, 3335, 3335, 3259, 3259, 3259, 3259, 3259, 3259,
-     3336, 3259, 3259, 3336, 3336, 3336, 3336, 3336, 3336, 3336,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3337, 3259, 3259, 3337,
-     3337, 3259, 3259, 3259, 3259, 3259, 3259, 3338, 3259, 3259,
-     3338, 3338, 3338, 3259, 3259, 3259, 3259, 3259, 3259, 3339,
-     3259, 3259, 3339, 3339, 3339, 3339, 3259, 3259,  293,  293,
-     3259, 3259, 3259, 3340, 3259, 3259, 3340, 3340, 3259, 3259,
-      293,  363,  363, 3259, 3259, 3259, 3341, 3259, 3259, 3341,
-     3341, 3341, 3259, 3259,  363,  363, 3259, 3259, 3259, 3342,
-     3259, 3259, 3342, 3342, 3259, 3259, 3259, 3259, 3259, 3259,
-     3343, 3259, 3259, 3343, 3343, 3259, 3259,  363,  363, 3259,
-     3259, 3259, 3344, 3259, 3259, 3344, 3344, 3344, 3259, 3259,
-
-      363,  363, 3259, 3259, 3259, 3345, 3259, 3259, 3345, 3345,
-     3345, 3345, 3345, 3259, 3259,  293,  432,  293, 3259, 3259,
-     3259, 3346, 3259, 3259, 3346, 3259, 3259, 3259, 3259, 3259,
-     3259, 3347, 3259, 3259, 3347, 3259, 3259,  293,  293, 3259,
-     3259, 3259, 3348, 3259, 3259, 3348, 3348, 3259, 3259, 3259,
-     3259, 3349, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3350, 3350, 3351,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3352, 3352, 3353, 3259, 3354, 3354,
-
-     3354, 3354, 3259, 3355, 3259, 3259, 3356, 3356, 3356, 3356,
-     3356, 3356, 3356, 3356, 3356, 3357, 3259, 3358, 3358, 3358,
-     3358, 3359, 3259, 3360, 3360, 3360, 3361, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3362, 3362, 3362, 3362,
-     3362, 3363, 3259, 3364, 3364, 3364, 3364, 3365, 3259, 3366,
-     3366, 3366, 3367, 3259, 3368, 3368, 3368, 3369, 3259, 3370,
-     3370, 3370, 3370, 3370, 3370, 3371, 3259, 3259, 3372, 3372,
-     3373, 3259, 3374, 3374, 3374, 3374, 3375, 3259, 3376, 3376,
-     3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376,
-
-     3376, 3376, 3377, 3259, 3378, 3378, 3378, 3378, 3378, 3378,
-     3378, 3378, 3379, 3259, 3380, 3380, 3380, 3380, 3380, 3380,
-     3380, 3380, 3381, 3259, 3382, 3382, 3382, 3383, 3259, 3384,
-     3384, 3384, 3384, 3385, 3259, 3386, 3386, 3386, 3386, 3386,
-     3386, 3387, 3259, 3388, 3388, 3388, 3388, 3389, 3259, 3259,
-     3390, 3390, 3390, 3390, 3390, 3391, 3259, 3392, 3392, 3392,
-     3393, 3259, 3394, 3394, 3394, 3395, 3259, 3396, 3396, 3396,
-     3396, 3397, 3259, 3398, 3398, 3398, 3398, 3398, 3398, 3399,
-     3259, 3259, 3400, 3400, 3401, 3259, 3402, 3402, 3403, 3259,
-     3404, 3404, 3404, 3405, 3406, 3259, 3406, 3259, 3259, 3259,
-
-     3407, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3408, 3409,
-     3409, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3410, 3411, 3411, 3412, 3259, 3259, 3412, 3259, 3413, 3413,
-     3259, 3414, 3259, 3259, 3414, 3414, 3414, 3414, 3414, 3414,
-     3415, 3415, 3416, 3416, 3416, 3417, 3417, 3259, 3259, 3418,
-     3419, 3419, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3420, 3259, 3259, 3420,
-     3420, 3421, 3421, 3422, 3259, 3259, 3422, 3423, 3423, 3259,
-
-     3259, 3424, 3425, 3425, 3426, 3426, 3427, 3427, 3428, 3428,
-     3428, 3259, 3259, 3428, 3428, 3429, 3429, 3259, 3259, 3430,
-     3431, 3431, 3432, 3259, 3259, 3259, 3259, 3433, 3433, 3434,
-     3434, 3259, 3259, 3434, 3259, 3259, 3434, 3434, 3434, 3434,
-     3434, 3434, 3434, 3434, 3435, 3435, 3259, 3259, 3259, 3259,
-     3436, 3436, 3436, 3436, 3436, 3437, 3437, 3438, 3438, 3438,
-     3259, 3259, 3438, 3438, 3438, 3439, 3439, 3440, 3259, 3259,
-     3441, 3441, 3442, 3259, 3259, 3442, 3443, 3443, 3444, 3259,
-     3259, 3444, 3444, 3444, 3445, 3445, 3446, 3446, 3446, 3447,
-     3447, 3259, 3448, 3448, 3448, 3448, 3449, 3449, 3450, 3259,
-
-     3259, 3451, 3451, 3452, 3452, 3453, 3453, 3454, 3454, 3454,
-     3455, 3455, 3456, 3456, 3456, 3456, 3456, 3457, 3457, 3259,
-     3458, 3459, 3459, 3259, 3259, 3460, 3460, 3259, 3259, 3461,
-     3462, 3462, 3463, 3259, 3259, 3463, 3259, 3259, 3464, 3259,
-     3259, 3259, 3259, 3259, 3259, 3465, 3259, 3466, 3259, 3466,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3467, 3259, 3468, 3259, 3468, 3469, 3259, 3259, 3259, 3469,
-     3259, 3259, 3470, 3259, 3470, 3471, 3259, 3259, 3259, 3259,
-
-     3259, 3471, 3259, 3259, 3471, 3471, 3471, 3259, 3472, 3259,
-     3472, 3473, 3473, 3473, 3259, 3474, 3259, 3474, 3259, 3259,
-     3259, 3475, 3259, 3476, 3259, 3476, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3477,
-     3259, 3259, 3259, 3477, 3477, 3259, 3478, 3259, 3478, 3479,
-     3259, 3259, 3259, 3479, 3259, 3480, 3259, 3480, 3259, 3259,
-     3259, 3481, 3259, 3482, 3259, 3482, 3483, 3483, 3259, 3484,
-     3259, 3484, 3485, 3485, 3485, 3259, 3259, 3259, 3485, 3485,
-     3259, 3486, 3259, 3486, 3259, 3259, 3487, 3259, 3488, 3259,
-     3488, 3489, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3490,
-
-     3259, 3490, 3491, 3491, 3491, 3491, 3259, 3259, 3259, 3491,
-     3259, 3259, 3259, 3259, 3259, 3491, 3491, 3491, 3491, 3491,
-     3491, 3491, 3259, 3492, 3259, 3492, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3493, 3493, 3493, 3493, 3259, 3494,
-     3259, 3494, 3495, 3495, 3495, 3495, 3259, 3259, 3259, 3259,
-     3259, 3495, 3495, 3259, 3496, 3259, 3496, 3497, 3259, 3259,
-     3259, 3259, 3498, 3259, 3498, 3499, 3259, 3259, 3259, 3499,
-     3259, 3500, 3259, 3500, 3501, 3259, 3259, 3259, 3501, 3501,
-     3501, 3259, 3502, 3259, 3502, 3259, 3259, 3259, 3259, 3503,
-     3259, 3504, 3259, 3504, 3259, 3259, 3259, 3505, 3505, 3259,
-
-     3259, 3505, 3259, 3506, 3259, 3506, 3507, 3259, 3259, 3259,
-     3259, 3508, 3259, 3508, 3259, 3259, 3259, 3259, 3259, 3509,
-     3259, 3509, 3259, 3259, 3510, 3510, 3259, 3259, 3259, 3511,
-     3259, 3511, 3512, 3512, 3512, 3512, 3512, 3259, 3513, 3259,
-     3513, 3259, 3514, 3259, 3515, 3259, 3515, 3259, 3259, 3259,
-     3259, 3516, 3259, 3516, 3259, 3259, 3259, 3517, 3259, 3518,
-     3259, 3518, 3519, 3520, 3259, 3259, 3259, 3259, 3259, 3521,
-     3522, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3523, 3259, 3259, 3524, 3259, 3525, 3526, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3526, 3259, 3259,
-     3526, 3527, 3528, 3259, 3259, 3528, 3529, 3530, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3531, 3531, 3259, 3259, 3532, 3533, 3533,
-     3534, 3259, 3259, 3535, 3259, 3259, 3536, 3537, 3538, 3538,
-     3259, 3259, 3538, 3538, 3539, 3259, 3259, 3259, 3259, 3540,
-     3259, 3259, 3541, 3542, 3542, 3542, 3542, 3259, 3259, 3259,
-     3259, 3259, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3543,
-     3259, 3259, 3259, 3544, 3544, 3544, 3544, 3545, 3546, 3546,
-
-     3546, 3546, 3259, 3259, 3259, 3546, 3546, 3547, 3548, 3549,
-     3550, 3550, 3551, 3552, 3552, 3552, 3552, 3553, 3259, 3259,
-     3259, 3259, 3259, 3259, 3554, 3555, 3259, 3259, 3259, 3259,
-     3556, 3556, 3259, 3259, 3259, 3556, 3557, 3558, 3559, 3259,
-     3259, 3259, 3259, 3259, 3259, 3560, 3259, 3259, 3259, 3561,
-     3561, 3259, 3259, 3259, 3562, 3563, 3259, 3259, 3563, 3563,
-     3563, 3564, 3259, 3565, 3566, 3567, 3568, 3569, 3570, 3571,
-     3571, 3259, 3571, 3259, 3259, 3259, 3572, 3573, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3574, 3259, 3259, 3259, 3575, 3259, 3576, 3577, 3259,
-     3259, 3259, 3577, 3259, 3259, 3259, 3577, 3578, 3579, 3259,
-     3259, 3259, 3259, 3259, 3580, 3581, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3582,
-     3259, 3259, 3259, 3259, 3259, 3583, 3584, 3584, 3585, 3259,
-     3259, 3259, 3586, 3259, 3259, 3259, 3587, 3588, 3589, 3589,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3589, 3590, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3591,
-     3592, 3259, 3259, 3592, 3592, 3259, 3259, 3259, 3259, 3259,
-
-     3592, 3592, 3592, 3592, 3592, 3592, 3593, 3259, 3259, 3594,
-     3594, 3594, 3595, 3596, 3259, 3259, 3596, 3596, 3259, 3259,
-     3596, 3597, 3598, 3599, 3600, 3600, 3601, 3602, 3602, 3602,
-     3259, 3259, 3602, 3603, 3604, 3605, 3259, 3606, 3606, 3606,
-     3607, 3608, 3609, 3610, 3611, 3611, 3612, 3613, 3259, 3259,
-     3259, 3613, 3613, 3613, 3614, 3259, 3259, 3259, 3615, 3616,
-     3259, 3259, 3617, 3618, 3619, 3619, 3259, 3259, 3620, 3621,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3622, 3623,
-
-     3259, 3624, 3625, 3625, 3625, 3626, 3627, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3628, 3629,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3630,
-     3259, 3259, 3259, 3631, 3632, 3259, 3259, 3633, 3634, 3259,
-     3259, 3635, 3636, 3636, 3259, 3259, 3259, 3259, 3259, 3259,
-     3636, 3259, 3259, 3259, 3259, 3637, 3638, 3259, 3259, 3259,
-     3259, 3259, 3638, 3259, 3259, 3259, 3259, 3259, 3638, 3638,
-     3638, 3638, 3259, 3259, 3639, 3259, 3259, 3259, 3259, 3259,
-     3640, 3259, 3259, 3641, 3642, 3259, 3259, 3259, 3259, 3259,
-     3642, 3259, 3259, 3259, 3642, 3259, 3259, 3643, 3644, 3645,
-
-     3645, 3646, 3647, 3647, 3647, 3259, 3259, 3259, 3647, 3259,
-     3259, 3648, 3649, 3259, 3259, 3259, 3259, 3259, 3650, 3651,
-     3652, 3653, 3654, 3259, 3259, 3259, 3259, 3655, 3656, 3656,
-     3656, 3656, 3657, 3259, 3259, 3259, 3259, 3658, 3659, 3259,
-     3259, 3259, 3259, 3259, 3660, 3661, 3661, 3259, 3259, 3259,
-     3662, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3663, 3664, 3259, 3259,
-     3259, 3665, 3259, 3259, 3665, 3666, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3667, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3668, 3259, 3259, 3259, 3259, 3259, 3669, 3259, 3259, 3259,
-     3259, 3259, 3670, 3671, 3671, 3259, 3259, 3671, 3259, 3672,
-     3673, 3259, 3259, 3259, 3673, 3259, 3259, 3259, 3259, 3259,
-     3673, 3673, 3673, 3259, 3259, 3259, 3674, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3675, 3676, 3259, 3259, 3259,
-     3676, 3676, 3677, 3678, 3679, 3259, 3259, 3680, 3681, 3259,
-     3259, 3681, 3681, 3259, 3259, 3681, 3682, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3683, 3684, 3685, 3686,
-     3687, 3259, 3259, 3259, 3259, 3259, 3259, 3688, 3689, 3689,
-
-     3689, 3689, 3690, 3259, 3691, 3692, 3693, 3694, 3694, 3259,
-     3259, 3259, 3259, 3695, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3696, 3697, 3259, 3698, 3259,
-     3259, 3259, 3698, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3699, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3700, 3259, 3259, 3259, 3701, 3702, 3703, 3703,
-     3259, 3259, 3259, 3259, 3703, 3259, 3704, 3705, 3705, 3259,
-     3259, 3259, 3705, 3705, 3705, 3706, 3259, 3259, 3259, 3707,
-
-     3708, 3708, 3708, 3709, 3259, 3259, 3710, 3259, 3259, 3259,
-     3711, 3712, 3259, 3259, 3259, 3712, 3712, 3259, 3259, 3259,
-     3259, 3712, 3713, 3259, 3714, 3715, 3716, 3717, 3718, 3719,
-     3259, 3259, 3720, 3720, 3720, 3721, 3259, 3722, 3259, 3259,
-     3723, 3724, 3724, 3259, 3725, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3726, 3259,
-     3259, 3727, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3728, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3729, 3259, 3259, 3730, 3731, 3731, 3259, 3259, 3259, 3259,
-
-     3731, 3259, 3732, 3733, 3733, 3259, 3259, 3733, 3733, 3259,
-     3259, 3259, 3259, 3708, 3708, 3708, 3709, 3259, 3259, 3711,
-     3259, 3259, 3712, 3712, 3712, 3259, 3259, 3259, 3259, 3712,
-     3713, 3259, 3714, 3259, 3259, 3259, 3259, 3717, 3718, 3719,
-     3259, 3259, 3259, 3259, 3259, 3720, 3720, 3259, 3259, 3259,
-     3722, 3723, 3724, 3724, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3726, 3259, 3259, 3259, 3727, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3728, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3729, 3259, 3259, 3731,
-
-     3731, 3259, 3259, 3259, 3259, 3732, 3733, 3733, 3259, 3259,
-     3259, 3733, 3259, 3259, 3708, 3708, 3259, 3259, 3709, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3712, 3712, 3712,
-     3259, 3259, 3259, 3259, 3713, 3714, 3259, 3259, 3259, 3259,
-     3259, 3718, 3719, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3723, 3724, 3724, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3727, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3728,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3729, 3731, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3733, 3733, 3733, 3259,
-     3259, 3259, 3708, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3712, 3712, 3712, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3718, 3719, 3259, 3259,
-     3259, 3259, 3259, 3259, 3723, 3724, 3724, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3727, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3728, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3729, 3259, 3259, 3731, 3259, 3259, 3259, 3733, 3733, 3733,
-
-     3708, 3259, 3259, 3259, 3259, 3259, 3259, 3712, 3259, 3259,
-     3712, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3718, 3719, 3259, 3259, 3259, 3259, 3723,
-     3724, 3724, 3724, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3728, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3729, 3259, 3259, 3259, 3731, 3733, 3733, 3733,
-     3708, 3712, 3259, 3259, 3259, 3712, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3719, 3259, 3259, 3259, 3259, 3723, 3724, 3724,
-     3724, 3734, 3735, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3728, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3731, 3733, 3733,
-     3259, 3259, 3708, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3719,
-     3259, 3259, 3259, 3259, 3723, 3724, 3736, 3737, 3734, 3735,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3731, 3733, 3733, 3259, 3259, 3259,
-     3708, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3723, 3736, 3724, 3738, 3737,
-     3739, 3724, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3731, 3733,
-     3733, 3259, 3259, 3259, 3259, 3708, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3723, 3738, 3259, 3739,
-     3724, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3723, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3723,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3723, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3723, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3723, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3723, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3723, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3723, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3723, 3723, 3259, 3259, 3259, 3259, 3259,
-     3259, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3723, 3723, 3723, 3723, 3723, 3723, 3723, 3259,    0, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259
+     3299, 3299, 3300, 3300, 3300, 3300, 3301, 3301, 3302, 3302,
+     3303, 3303, 3304, 3304, 3304, 3304, 3305, 3305, 3299, 3299,
+     3306, 3306, 3307, 3307, 3307, 3307, 3299, 3299, 3307, 3307,
+     3307, 3307, 3299, 3299, 3307, 3307, 3299, 3299, 3307, 3307,
+     3307, 3307, 3308, 3308, 3309, 3309, 3299, 3299, 3309, 3309,
+     3309, 3309, 3310, 3310, 3304, 3304, 3311, 3311, 3312, 3312,
+     3313, 3313, 3314, 3314, 3315, 3315, 3316, 3316, 3316, 3316,
+     3299, 3299, 3316, 3316, 3316, 3316, 3299, 3299, 3316, 3316,
+     3316, 3316, 3299, 3299, 3316, 3316, 3299, 3299, 3316, 3316,
+     3316, 3316, 3299, 3299, 3316, 3316, 3299, 3299, 3316, 3316,
+
+     3316, 3316, 3317, 3317, 3318, 3318, 3299, 3299, 3318, 3318,
+     3318, 3318, 3319, 3319, 3320, 3320, 3299, 3299, 3320, 3320,
+     3320, 3320, 3321, 3321, 3322, 3322, 3323, 3323, 3324, 3324,
+     3325, 3325, 3326, 3326, 3299, 3299, 3326, 3326, 3326, 3326,
+     3327, 3327, 3328, 3328, 3329, 3329, 3330, 3330, 3298,  149,
+     3331, 3331, 3332, 3332, 3333, 3333, 3334, 3334, 3335, 3335,
+     3336, 3336, 3337, 3337, 3338, 3338, 3339, 3339, 3340, 3340,
+     3341, 3341, 3299, 3299, 3341, 3341, 3341, 3341, 3342, 3342,
+     3343, 3343, 3299, 3299, 3343, 3343, 3343, 3343, 3344, 3344,
+     3345, 3345, 3299, 3299, 3345, 3345, 3345, 3345, 3346, 3346,
+
+     3347, 3347, 3348, 3348, 3349, 3349, 3299, 3299, 3349, 3349,
+     3349, 3349, 3350, 3350, 3351, 3351, 3299, 3299, 3351, 3351,
+     3351, 3351, 3352, 3352, 3353, 3353, 3299, 3299, 3353, 3353,
+     3353, 3353, 3354, 3354, 3355, 3355, 3356, 3356, 3357, 3357,
+     3299, 3299, 3357, 3357, 3357, 3357, 3358, 3358, 3359, 3359,
+     3299, 3299, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3360, 3298, 3298, 3360, 3298, 3298, 3298,
+      290,  290,  292,  290,  293,  293, 3298, 3298, 3298, 3361,
+
+     3298, 3298, 3361, 3298, 3298,  294,  293, 3298, 3298, 3298,
+     3362, 3298, 3298, 3362, 3362, 3362, 3298, 3298, 3298, 3298,
+     3298, 3363, 3298, 3298, 3363, 3363, 3363, 3363, 3363, 3298,
+     3298, 3298, 3298, 3298, 3298, 3364, 3298, 3298, 3364, 3364,
+     3364, 3298, 3298, 3298, 3298, 3298, 3298, 3365, 3298, 3298,
+     3365, 3365, 3298, 3298, 3298,  355,  293,  293,  294,  359,
+      358,  358,  358,  358,  359,  365,  363,  363, 3298, 3298,
+     3298, 3366, 3298, 3298, 3366, 3366, 3366, 3366, 3298, 3298,
+      293,  293, 3298, 3298, 3298, 3367, 3298, 3298, 3367, 3367,
+     3367, 3298, 3298,  293,  293, 3298, 3298, 3298, 3368, 3298,
+
+     3298, 3368, 3368, 3298, 3298, 3298, 3298, 3298, 3298, 3369,
+     3298, 3298, 3369, 3369, 3298, 3298, 3298, 3298, 3298, 3298,
+     3370, 3298, 3298, 3370, 3370, 3370, 3370, 3370, 3298, 3298,
+      293,  293,  293, 3298, 3298, 3298, 3371, 3298, 3298, 3371,
+     3298, 3298, 3298, 3298, 3298, 3298, 3372, 3298, 3298, 3372,
+     3372, 3372, 3298, 3298, 3298, 3298, 3298, 3298, 3373, 3298,
+     3298, 3373, 3373, 3373, 3373, 3373, 3373, 3373, 3373, 3298,
+     3298, 3298, 3298, 3298, 3298, 3374, 3298, 3298, 3374, 3374,
+     3374, 3374, 3374, 3374, 3298, 3298, 3298, 3298, 3298, 3298,
+     3375, 3298, 3298, 3375, 3375, 3375, 3375, 3375, 3375, 3375,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3376, 3298, 3298, 3376,
+     3376, 3298, 3298, 3298, 3298, 3298, 3298, 3377, 3298, 3298,
+     3377, 3377, 3377, 3298, 3298, 3298, 3298, 3298, 3298, 3378,
+     3298, 3298, 3378, 3378, 3378, 3378, 3298, 3298,  293,  293,
+     3298, 3298, 3298, 3379, 3298, 3298, 3379, 3379, 3298, 3298,
+      293,  363,  363, 3298, 3298, 3298, 3380, 3298, 3298, 3380,
+     3380, 3380, 3298, 3298,  363,  363, 3298, 3298, 3298, 3381,
+     3298, 3298, 3381, 3381, 3298, 3298, 3298, 3298, 3298, 3298,
+     3382, 3298, 3298, 3382, 3382, 3298, 3298,  363,  363, 3298,
+     3298, 3298, 3383, 3298, 3298, 3383, 3383, 3383, 3298, 3298,
+
+      363,  363, 3298, 3298, 3298, 3384, 3298, 3298, 3384, 3384,
+     3384, 3384, 3384, 3298, 3298,  293,  432,  293, 3298, 3298,
+     3298, 3385, 3298, 3298, 3385, 3298, 3298, 3298, 3298, 3298,
+     3298, 3386, 3298, 3298, 3386, 3298, 3298,  293,  293, 3298,
+     3298, 3298, 3387, 3298, 3298, 3387, 3387, 3298, 3298, 3298,
+     3298, 3388, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3389, 3389, 3390,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3391, 3391, 3392, 3298, 3393, 3393,
+
+     3393, 3393, 3298, 3394, 3298, 3298, 3395, 3395, 3395, 3395,
+     3395, 3395, 3395, 3395, 3395, 3396, 3298, 3397, 3397, 3397,
+     3397, 3398, 3298, 3399, 3399, 3399, 3400, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3401, 3401, 3401, 3401,
+     3401, 3402, 3298, 3403, 3403, 3403, 3403, 3404, 3298, 3405,
+     3405, 3405, 3406, 3298, 3407, 3407, 3407, 3408, 3298, 3409,
+     3409, 3409, 3409, 3409, 3409, 3410, 3298, 3298, 3411, 3411,
+     3412, 3298, 3413, 3413, 3413, 3413, 3414, 3298, 3415, 3415,
+     3415, 3415, 3415, 3415, 3415, 3415, 3415, 3415, 3415, 3415,
+
+     3415, 3415, 3415, 3415, 3416, 3298, 3417, 3417, 3417, 3417,
+     3417, 3417, 3417, 3417, 3418, 3298, 3419, 3419, 3419, 3419,
+     3419, 3419, 3419, 3419, 3420, 3298, 3421, 3421, 3421, 3422,
+     3298, 3423, 3423, 3423, 3423, 3424, 3298, 3425, 3425, 3425,
+     3425, 3425, 3425, 3426, 3298, 3427, 3427, 3427, 3427, 3428,
+     3298, 3298, 3429, 3429, 3429, 3429, 3429, 3430, 3298, 3431,
+     3431, 3431, 3432, 3298, 3433, 3433, 3433, 3434, 3298, 3435,
+     3435, 3435, 3435, 3436, 3298, 3437, 3437, 3437, 3437, 3437,
+     3437, 3438, 3298, 3298, 3439, 3439, 3440, 3298, 3441, 3441,
+     3442, 3298, 3443, 3443, 3443, 3444, 3445, 3298, 3445, 3298,
+
+     3298, 3298, 3446, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3447, 3448, 3448, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3449, 3450, 3450, 3451, 3298, 3298, 3451, 3298,
+     3452, 3452, 3298, 3453, 3298, 3298, 3453, 3453, 3453, 3453,
+     3453, 3453, 3454, 3454, 3455, 3455, 3455, 3456, 3456, 3298,
+     3298, 3457, 3458, 3458, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3459, 3298,
+     3298, 3459, 3459, 3460, 3460, 3461, 3298, 3298, 3461, 3462,
+
+     3462, 3298, 3298, 3463, 3464, 3464, 3465, 3465, 3466, 3466,
+     3467, 3467, 3467, 3298, 3298, 3467, 3467, 3468, 3468, 3298,
+     3298, 3469, 3470, 3470, 3471, 3298, 3298, 3298, 3298, 3472,
+     3472, 3473, 3473, 3298, 3298, 3473, 3298, 3298, 3473, 3473,
+     3473, 3473, 3473, 3473, 3473, 3473, 3473, 3473, 3474, 3474,
+     3298, 3298, 3298, 3298, 3475, 3475, 3475, 3475, 3475, 3476,
+     3476, 3477, 3477, 3477, 3298, 3298, 3477, 3477, 3477, 3478,
+     3478, 3479, 3298, 3298, 3480, 3480, 3481, 3298, 3298, 3481,
+     3482, 3482, 3483, 3298, 3298, 3483, 3483, 3483, 3484, 3484,
+     3485, 3485, 3485, 3486, 3486, 3298, 3487, 3487, 3487, 3487,
+
+     3488, 3488, 3489, 3298, 3298, 3490, 3490, 3491, 3491, 3492,
+     3492, 3493, 3493, 3493, 3494, 3494, 3495, 3495, 3495, 3495,
+     3495, 3496, 3496, 3298, 3497, 3498, 3498, 3298, 3298, 3499,
+     3499, 3298, 3298, 3500, 3501, 3501, 3502, 3298, 3298, 3502,
+     3298, 3298, 3503, 3298, 3298, 3298, 3298, 3298, 3298, 3504,
+     3298, 3505, 3298, 3505, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3506, 3298, 3507, 3298, 3507, 3508,
+     3298, 3298, 3298, 3508, 3298, 3298, 3509, 3298, 3509, 3510,
+
+     3298, 3298, 3298, 3298, 3298, 3510, 3298, 3298, 3510, 3510,
+     3510, 3298, 3511, 3298, 3511, 3512, 3512, 3512, 3298, 3513,
+     3298, 3513, 3298, 3298, 3298, 3514, 3298, 3515, 3298, 3515,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3516, 3298, 3298, 3298, 3516, 3516, 3298,
+     3517, 3298, 3517, 3518, 3298, 3298, 3298, 3518, 3298, 3519,
+     3298, 3519, 3298, 3298, 3298, 3520, 3298, 3521, 3298, 3521,
+     3522, 3522, 3298, 3523, 3298, 3523, 3524, 3524, 3524, 3298,
+     3298, 3298, 3524, 3524, 3298, 3525, 3298, 3525, 3298, 3298,
+     3526, 3298, 3527, 3298, 3527, 3528, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3529, 3298, 3529, 3530, 3530, 3530, 3530,
+     3298, 3298, 3298, 3530, 3298, 3298, 3298, 3298, 3298, 3530,
+     3530, 3530, 3530, 3530, 3530, 3530, 3530, 3530, 3298, 3531,
+     3298, 3531, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3532, 3532, 3532, 3532, 3298, 3533, 3298, 3533, 3534, 3534,
+     3534, 3534, 3298, 3298, 3298, 3298, 3298, 3534, 3534, 3298,
+     3535, 3298, 3535, 3536, 3298, 3298, 3298, 3298, 3537, 3298,
+     3537, 3538, 3298, 3298, 3298, 3538, 3298, 3539, 3298, 3539,
+     3540, 3298, 3298, 3298, 3540, 3540, 3540, 3298, 3541, 3298,
+     3541, 3298, 3298, 3298, 3298, 3542, 3298, 3543, 3298, 3543,
+
+     3298, 3298, 3298, 3544, 3544, 3298, 3298, 3544, 3298, 3545,
+     3298, 3545, 3546, 3298, 3298, 3298, 3298, 3547, 3298, 3547,
+     3298, 3298, 3298, 3298, 3298, 3548, 3298, 3548, 3298, 3298,
+     3549, 3549, 3298, 3298, 3298, 3550, 3298, 3550, 3551, 3551,
+     3551, 3551, 3551, 3298, 3552, 3298, 3552, 3298, 3553, 3298,
+     3554, 3298, 3554, 3298, 3298, 3298, 3298, 3555, 3298, 3555,
+     3298, 3298, 3298, 3556, 3298, 3557, 3298, 3557, 3558, 3559,
+     3298, 3298, 3298, 3298, 3298, 3560, 3561, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3562, 3298,
+     3298, 3563, 3298, 3564, 3565, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3565, 3298, 3298, 3565, 3566, 3567, 3298,
+     3298, 3567, 3568, 3569, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3570,
+     3570, 3298, 3298, 3571, 3572, 3572, 3573, 3298, 3298, 3574,
+     3298, 3298, 3575, 3576, 3577, 3577, 3298, 3298, 3577, 3577,
+     3578, 3298, 3298, 3298, 3298, 3579, 3298, 3298, 3580, 3581,
+     3581, 3581, 3581, 3298, 3298, 3298, 3298, 3298, 3581, 3581,
+     3581, 3581, 3581, 3581, 3581, 3581, 3581, 3582, 3298, 3298,
+
+     3298, 3583, 3583, 3583, 3583, 3584, 3585, 3585, 3585, 3585,
+     3298, 3298, 3298, 3585, 3585, 3586, 3587, 3588, 3589, 3589,
+     3590, 3591, 3591, 3591, 3591, 3592, 3298, 3298, 3298, 3298,
+     3298, 3298, 3593, 3594, 3298, 3298, 3298, 3298, 3595, 3595,
+     3298, 3298, 3298, 3595, 3596, 3597, 3598, 3298, 3298, 3298,
+     3298, 3298, 3298, 3599, 3298, 3298, 3298, 3600, 3600, 3298,
+     3298, 3298, 3601, 3602, 3298, 3298, 3602, 3602, 3602, 3603,
+     3298, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3610, 3298,
+     3610, 3298, 3298, 3298, 3611, 3612, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3613,
+     3298, 3298, 3298, 3614, 3298, 3615, 3616, 3298, 3298, 3298,
+     3616, 3298, 3298, 3298, 3616, 3617, 3618, 3298, 3298, 3298,
+     3298, 3298, 3619, 3620, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3621, 3298, 3298,
+     3298, 3298, 3298, 3622, 3623, 3623, 3624, 3298, 3298, 3298,
+     3625, 3298, 3298, 3298, 3626, 3627, 3628, 3628, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3628, 3629, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3630, 3631, 3298,
+
+     3298, 3631, 3631, 3298, 3298, 3298, 3631, 3631, 3298, 3298,
+     3631, 3631, 3631, 3631, 3631, 3631, 3632, 3298, 3298, 3633,
+     3633, 3633, 3634, 3635, 3298, 3298, 3635, 3635, 3298, 3298,
+     3635, 3636, 3637, 3638, 3639, 3639, 3640, 3641, 3641, 3641,
+     3298, 3298, 3641, 3642, 3643, 3644, 3298, 3645, 3645, 3645,
+     3646, 3647, 3648, 3649, 3650, 3650, 3651, 3652, 3298, 3298,
+     3298, 3652, 3652, 3652, 3653, 3298, 3298, 3298, 3654, 3655,
+     3298, 3298, 3656, 3657, 3658, 3658, 3298, 3298, 3659, 3660,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3661, 3662,
+     3298, 3663, 3664, 3664, 3664, 3665, 3666, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3667, 3668,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3669,
+     3298, 3298, 3298, 3670, 3671, 3298, 3298, 3672, 3673, 3298,
+     3298, 3674, 3675, 3675, 3298, 3298, 3298, 3298, 3298, 3298,
+     3675, 3298, 3298, 3298, 3298, 3676, 3677, 3298, 3298, 3298,
+     3298, 3298, 3677, 3677, 3677, 3298, 3298, 3298, 3298, 3298,
+     3677, 3677, 3677, 3677, 3298, 3298, 3678, 3298, 3298, 3298,
+     3298, 3298, 3679, 3298, 3298, 3680, 3681, 3298, 3298, 3298,
+
+     3298, 3298, 3681, 3298, 3298, 3298, 3681, 3298, 3298, 3682,
+     3683, 3684, 3684, 3685, 3686, 3686, 3686, 3298, 3298, 3298,
+     3686, 3298, 3298, 3687, 3688, 3298, 3298, 3298, 3298, 3298,
+     3689, 3690, 3691, 3692, 3693, 3298, 3298, 3298, 3298, 3694,
+     3695, 3695, 3695, 3695, 3696, 3298, 3298, 3298, 3298, 3697,
+     3698, 3298, 3298, 3298, 3298, 3298, 3699, 3700, 3700, 3298,
+     3298, 3298, 3701, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3702, 3703,
+     3298, 3298, 3298, 3704, 3298, 3298, 3704, 3705, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3706, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3707, 3298, 3298, 3298, 3298, 3298, 3708, 3298,
+     3298, 3298, 3298, 3298, 3709, 3710, 3710, 3298, 3298, 3710,
+     3298, 3711, 3712, 3298, 3298, 3298, 3712, 3712, 3712, 3298,
+     3298, 3298, 3298, 3298, 3712, 3712, 3712, 3298, 3298, 3298,
+     3713, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3714,
+     3715, 3298, 3298, 3298, 3715, 3715, 3716, 3717, 3718, 3298,
+     3298, 3719, 3720, 3298, 3298, 3720, 3720, 3298, 3298, 3720,
+     3721, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3722, 3723, 3724, 3725, 3726, 3298, 3298, 3298, 3298, 3298,
+     3298, 3727, 3728, 3728, 3728, 3728, 3729, 3298, 3730, 3731,
+     3732, 3733, 3733, 3298, 3298, 3298, 3298, 3734, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3735,
+     3736, 3298, 3737, 3298, 3298, 3298, 3737, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3738, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3739, 3298, 3298, 3298,
+     3740, 3741, 3742, 3742, 3298, 3298, 3298, 3298, 3742, 3298,
+
+     3743, 3744, 3744, 3744, 3744, 3298, 3298, 3298, 3744, 3744,
+     3744, 3745, 3298, 3298, 3298, 3746, 3747, 3747, 3747, 3748,
+     3298, 3298, 3749, 3298, 3298, 3298, 3750, 3751, 3298, 3298,
+     3298, 3751, 3751, 3298, 3298, 3298, 3298, 3751, 3752, 3298,
+     3753, 3754, 3755, 3756, 3757, 3758, 3298, 3298, 3759, 3759,
+     3759, 3760, 3298, 3761, 3298, 3298, 3762, 3763, 3763, 3298,
+     3764, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3765, 3298, 3298, 3766, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3767, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3768, 3298, 3298, 3769,
+     3770, 3770, 3298, 3298, 3298, 3298, 3770, 3298, 3771, 3772,
+     3772, 3772, 3772, 3772, 3298, 3298, 3772, 3772, 3298, 3298,
+     3298, 3298, 3747, 3747, 3747, 3748, 3298, 3298, 3750, 3298,
+     3298, 3751, 3751, 3751, 3298, 3298, 3298, 3298, 3751, 3752,
+     3298, 3753, 3298, 3298, 3298, 3298, 3756, 3757, 3758, 3298,
+     3298, 3298, 3298, 3298, 3759, 3759, 3298, 3298, 3298, 3761,
+     3762, 3763, 3763, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3765, 3298, 3298, 3298, 3766, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3767, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3768, 3298, 3298, 3770, 3770,
+     3298, 3298, 3298, 3298, 3771, 3772, 3772, 3772, 3772, 3772,
+     3298, 3298, 3298, 3772, 3298, 3298, 3747, 3747, 3298, 3298,
+     3748, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3751,
+     3751, 3751, 3298, 3298, 3298, 3298, 3752, 3753, 3298, 3298,
+     3298, 3298, 3298, 3757, 3758, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3762, 3763, 3763, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3766, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3767, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3768,
+     3770, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3772, 3772,
+     3772, 3298, 3298, 3772, 3772, 3298, 3298, 3298, 3747, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3751, 3751, 3751, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3757, 3758, 3298, 3298, 3298, 3298, 3298, 3298,
+     3762, 3763, 3763, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3766,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3767, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3768, 3298, 3298, 3770,
+     3298, 3298, 3298, 3772, 3772, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3772, 3747, 3298, 3298, 3298, 3298, 3298, 3298,
+     3751, 3298, 3298, 3751, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3757, 3758, 3298, 3298,
+     3298, 3298, 3762, 3763, 3763, 3763, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3767, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3768, 3298, 3298, 3298, 3770,
+     3772, 3772, 3298, 3298, 3298, 3298, 3298, 3298, 3772, 3747,
+     3751, 3298, 3298, 3298, 3751, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3758, 3298, 3298, 3298, 3298, 3762, 3763, 3763, 3763,
+     3773, 3774, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3767, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3770, 3772, 3772, 3298,
+     3298, 3747, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3758, 3298,
+     3298, 3298, 3298, 3762, 3763, 3775, 3776, 3773, 3774, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3770, 3772, 3772, 3298, 3298, 3298, 3747,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3762, 3775, 3763, 3777, 3776, 3778,
+     3763, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3770, 3772, 3772,
+
+     3298, 3298, 3298, 3298, 3747, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3762, 3777, 3298, 3778, 3763,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3762, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3762, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3762, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3762, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3762, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3762, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3762, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3762, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3762, 3762, 3298, 3298, 3298, 3298, 3298, 3298,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762, 3762,
+     3762, 3762, 3762, 3762, 3762, 3762, 3298,    0, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298
     } ;
 
-static yyconst flex_int16_t yy_nxt[12047] =
+static yyconst flex_int16_t yy_nxt[12113] =
     {   0,
-     3259,  256,  257,  256,  256,  257,  256,  256,  257,  256,
+     3298,  256,  257,  256,  256,  257,  256,  256,  257,  256,
       256,  257,  256,  261,  257,  261,  267,  258,  264,  267,
-      258,  264, 3259,  259, 3259,  265,  259, 3259,  265,  262,
+      258,  264, 3298,  259, 3298,  265,  259, 3298,  265,  262,
       261,  257,  261,  652,  268,  270,  271,  268,  270,  271,
       272,  273,  697,  272,  273,  652,  262,  277,  278,  653,
       274,  270,  271,  274,  275,  655,  272,  270,  271,  686,
-      275,  654,  272,  277,  278, 1738,  274,  257,  257,  257,
-      840,  654,  274,  257,  257,  257,  289,  257,  289,  289,
-      257,  289,  841,  280,  289,  257,  289,  673, 1739,  280,
-      727,  279,  290, 1344,  689,  290,  651,  651,  651, 1345,
+      275,  654,  272,  277,  278, 1731,  274,  257,  257,  257,
+      842,  654,  274,  257,  257,  257,  289,  257,  289,  289,
+      257,  289,  843,  280,  289,  257,  289,  673, 1735,  280,
+      727,  279,  290, 1350,  689,  290,  651,  651,  651, 1351,
 
       291,  651,  651,  651,  651,  651,  651,  279,  281,  282,
       257,  282,  281,  281,  281,  281,  281,  281,  281,  283,
       281,  281,  281,  684,  281,  285,  281,  286,  281,  289,
       257,  289,  257,  257,  257,  257,  257,  257,  685,  289,
-      257,  289,  289,  257,  289,  291,  690,  796,  292,  655,
-      797,  292,  914,  281,  281,  290,  655,  655,  290,  289,
+      257,  289,  289,  257,  289,  291,  690,  798,  292,  655,
+      799,  292,  916,  281,  281,  290,  655,  655,  290,  289,
       257,  289,  651,  651,  651,  654,  651,  651,  651,  651,
-      651,  651,  654,  654, 3259,  293,  915,  287,  281,  282,
+      651,  651,  654,  654, 3298,  293,  917,  287,  281,  282,
       257,  282,  281,  281,  281,  281,  281,  281,  281,  283,
-      281,  281,  281, 1744,  281,  285,  281,  286,  281,  289,
+      281,  281,  281, 1737,  281,  285,  281,  286,  281,  289,
 
       257,  289,  257,  257,  257,  257,  257,  257,  660,  289,
-      257,  289,  289,  257,  289,  293,  666,  727,  294,  809,
-      974,  294,  810,  281,  281,  291,  736,  728,  291,  257,
+      257,  289,  289,  257,  289,  293,  666,  727,  294,  811,
+      976,  294,  812,  281,  281,  291,  736,  728,  291,  257,
       257,  257,  257,  257,  257,  289,  257,  289,  289,  257,
-      289,  289,  257,  289,  975,  295,  846,  287,  295,  655,
-      661,  293,  791,  847,  293,  740,  662,  296,  289,  257,
+      289,  289,  257,  289,  977,  295,  848,  287,  295,  655,
+      661,  293,  791,  849,  293,  740,  662,  296,  289,  257,
       289,  663,  651,  651,  651,  654,  664,  651,  651,  651,
       651,  651,  651,  792,  296,  297,  298,  257,  298,  297,
       297,  297,  297,  297,  297,  297,  299,  297,  297,  297,
       714,  297,  301,  297,  302,  297,  305,  257,  305,  305,
 
       257,  305,  257,  257,  257,  715,  257,  257,  257,  305,
-      257,  305,  306,  902,  848,  306,  903, 1745,  294,  710,
+      257,  305,  306,  904,  850,  306,  905, 1744,  294,  710,
       297,  297,  294,  711,  752,  306,  670,  712,  303,  297,
       298,  257,  298,  297,  297,  297,  297,  297,  297,  297,
       299,  297,  297,  297,  655,  297,  301,  297,  302,  297,
-      305,  257,  305,  305,  257,  305,  305,  257,  305,  798,
-      654,  856,  270,  271,  854,  691,  306,  272, 3259,  307,
-      690,  855,  307,  799,  297,  297,  736,  317,  692,  752,
-      685, 1746,  303,  308,  309,  257,  309,  308,  308,  308,
-      308,  308,  308,  308,  310,  308,  308,  308, 1747,  308,
+      305,  257,  305,  305,  257,  305,  305,  257,  305,  800,
+      654,  858,  270,  271,  856,  691,  306,  272, 3298,  307,
+      690,  857,  307,  801,  297,  297,  736,  317,  692,  752,
+      685, 1745,  303,  308,  309,  257,  309,  308,  308,  308,
+      308,  308,  308,  308,  310,  308,  308,  308, 1746,  308,
 
-      312,  308,  313,  308, 1748,  655,  318,  684,  331,  257,
+      312,  308,  313,  308, 1747,  655,  318,  684,  331,  257,
       331,  331,  257,  331,  343,  257,  343,  690,  270,  271,
-      693,  654,  685,  272,  332,  703,  849,  332,  308,  308,
-      344,  689,  704,  317,  690,  866,  314,  758, 1749,  315,
-      872,  654,  651,  651,  651, 1750,  316,  308,  309,  257,
+      693,  654,  685,  272,  332,  703,  795,  332,  308,  308,
+      344,  689,  704,  317,  796, 1012,  314,  758, 1013,  315,
+      797,  654,  651,  651,  651, 1752,  316,  308,  309,  257,
       309,  308,  308,  308,  308,  308,  308,  308,  310,  308,
       308,  308,  318,  308,  312,  308,  313,  308,  343,  257,
-      343,  354,  257,  354,  354,  257,  354, 1757,  354,  257,
+      343,  354,  257,  354,  354,  257,  354, 1753,  354,  257,
       354,  354,  257,  354,  344,  655,  741,  355,  655,  736,
-      355,  690,  308,  308,  356,  716,  690,  356, 1758, 1767,
+      355,  851,  308,  308,  356,  716, 1493,  356, 1754,  690,
 
-      314,  654,  742,  315,  654,  651,  651,  651,  758, 1769,
+      314,  654,  742,  315,  654,  651,  651,  651,  758, 1494,
       316,  319,  320,  257,  320,  319,  319,  319,  319,  319,
-      319,  319,  321,  319,  319,  319, 1770,  319,  323,  319,
+      319,  319,  321,  319,  319,  319, 1755,  319,  323,  319,
       324,  319,  257,  257,  257,  257,  257,  257,  354,  257,
-      354,  776,  354,  257,  354,  354,  257,  354,  357, 1780,
-      655,  357,  655,  655,  355, 1781,  319,  319,  355,  722,
+      354,  776,  354,  257,  354,  354,  257,  354,  357, 1756,
+      655,  357,  655,  655,  355, 1757,  319,  319,  355,  722,
       689,  358,  651,  651,  651,  325,  654,  326,  654,  654,
-      776,  327,  651,  651,  651,  842,  328,  329,  319,  320,
+      776,  327,  651,  651,  651,  844,  328,  329,  319,  320,
       257,  320,  319,  319,  319,  319,  319,  319,  319,  321,
       319,  319,  319,  689,  319,  323,  319,  324,  319,  354,
 
-      257,  354,  257,  257,  257,  257,  257,  257,  881,  354,
-      257,  354,  354,  257,  354,  358,  739, 1791,  359,  777,
+      257,  354,  257,  257,  257,  257,  257,  257,  883,  354,
+      257,  354,  354,  257,  354,  358,  739, 1758,  359,  777,
       679,  359,  736,  319,  319,  360,  732,  736,  360,  651,
       651,  651,  325,  735,  326,  651,  651,  651,  327,  651,
-      651,  651, 1794,  328,  329,  333,  334,  257,  334,  333,
+      651,  651, 1765,  328,  329,  333,  334,  257,  334,  333,
       333,  333,  333,  333,  333,  333,  335,  333,  333,  333,
       686,  333,  337,  333,  338,  333,  354,  257,  354,  354,
-      257,  354,  257,  257,  257,  896,  257,  257,  257,  354,
-      257,  354,  361,  923, 1795,  361,  896,  924,  362,  743,
-      333,  333,  362,  730,  731,  358, 1801,  339,  651,  651,
+      257,  354,  257,  257,  257,  898,  257,  257,  257,  354,
+      257,  354,  361, 1766, 1775,  361,  898,  868,  362,  743,
+      333,  333,  362,  730,  731,  358,  874,  339,  651,  651,
 
-      651,  897,  689,  340,  744,  651,  651,  651,  651,  651,
-      651,  948,  341,  333,  334,  257,  334,  333,  333,  333,
-      333,  333,  333,  333,  335,  333,  333,  333, 1802,  333,
+      651,  899,  689,  340,  744,  651,  651,  651,  651,  651,
+      651,  950,  341,  333,  334,  257,  334,  333,  333,  333,
+      333,  333,  333,  333,  335,  333,  333,  333, 1777,  333,
       337,  333,  338,  333,  354,  257,  354,  257,  257,  257,
-      257,  257,  257, 1803,  354,  257,  354,  354,  257,  354,
-      358,  655,  928,  363, 1804,  914,  363,  655,  333,  333,
-      361,  655,  655,  361,  763,  339,  929,  654,  651,  651,
-      651,  340,  974,  654,  651,  651,  651,  654,  654,  983,
+      257,  257,  257,  690,  354,  257,  354,  354,  257,  354,
+      358,  655,  690,  363, 1778,  916,  363,  655,  333,  333,
+      361,  655,  655,  361,  763,  339, 1788,  654,  651,  651,
+      651,  340,  976,  654,  651,  651,  651,  654,  654,  985,
       341,  345,  346,  257,  346,  345,  345,  345,  345,  345,
-      345,  345,  347,  345,  345,  345,  915,  345,  349,  345,
+      345,  345,  347,  345,  345,  345,  917,  345,  349,  345,
 
       350,  345,  354,  257,  354,  354,  257,  354,  257,  257,
-      257, 1805,  257,  257,  257,  354,  257,  354,  364,  655,
-     1010,  364,  655, 1011,  365,  842,  345,  345,  365,  768,
-     1806,  366,  651,  651,  651,  654, 3259,  351,  654,  651,
-      651,  651,  651,  651,  651, 1814,  352,  345,  346,  257,
+      257, 1789,  257,  257,  257,  354,  257,  354,  364,  655,
+     1799,  364,  655, 1802,  365,  844,  345,  345,  365,  768,
+     1803,  366,  651,  651,  651,  654, 3298,  351,  654,  651,
+      651,  651,  651,  651,  651, 1807,  352,  345,  346,  257,
       346,  345,  345,  345,  345,  345,  345,  345,  347,  345,
-      345,  345,  974,  345,  349,  345,  350,  345,  354,  257,
+      345,  345,  976,  345,  349,  345,  350,  345,  354,  257,
       354,  257,  257,  257,  257,  257,  257,  689,  354,  257,
-      354,  354,  257,  354,  366,  777,  983,  367,  736,  914,
-      367, 1817,  345,  345,  364,  655, 1818,  364,  354,  257,
+      354,  354,  257,  354,  366,  777,  985,  367,  736,  916,
+      367, 1808,  345,  345,  364,  655, 1811,  364,  354,  257,
 
-      354, 1821,  781,  351,  354,  257,  354,  651,  651,  651,
-      880,  654,  352,  984,  368,  651,  651,  651,  727, 1823,
+      354, 1812,  781,  351,  354,  257,  354,  651,  651,  651,
+      882,  654,  352,  986,  368,  651,  651,  651,  727, 1813,
       368,  369,  370,  257,  370,  369,  369,  369,  369,  369,
-      369,  369,  371,  369,  369,  369,  974,  369,  373,  369,
+      369,  369,  371,  369,  369,  369,  976,  369,  373,  369,
       374,  369,  380,  257,  380,  380,  257,  380,  257,  257,
-      257, 1018,  257,  257,  257, 1019,  745,  655,  381, 1134,
-      984,  381,  689, 1463,  357, 3259,  369,  369,  357,  655,
-      655,  375,  734,  654,  889,  686,  787,  376,  651,  651,
+      257,  925,  257,  257,  257,  926,  745,  655,  381, 1020,
+      986,  381,  689, 1021,  357, 3298,  369,  369,  357,  655,
+      655,  375,  734,  654,  891,  686,  787,  376,  651,  651,
       651,  377,  651,  651,  651,  654,  654,  378,  369,  370,
       257,  370,  369,  369,  369,  369,  369,  369,  369,  371,
 
       369,  369,  369,  673,  369,  373,  369,  374,  369,  380,
-      257,  380,  380,  257,  380,  380,  257,  380,  889,  380,
-      257,  380,  651,  651,  651,  381,  736,  800,  381,  655,
-      655,  382, 1134,  369,  369,  382,  803,  655,  375,  801,
-      802,  651,  651,  651,  376,  654,  654, 1825,  377,  651,
-      651,  651, 1669,  654,  378,  383,  384,  257,  384,  383,
+      257,  380,  380,  257,  380,  380,  257,  380,  891,  380,
+      257,  380,  651,  651,  651,  381,  736,  802,  381,  655,
+      655,  382, 1138,  369,  369,  382,  805,  655,  375,  803,
+      804,  651,  651,  651,  376,  654,  654, 1814,  377,  651,
+      651,  651, 1677,  654,  378,  383,  384,  257,  384,  383,
       383,  383,  383,  383,  383,  383,  385,  383,  383,  383,
       689,  383,  387,  383,  388,  383,  393,  257,  393,  393,
-      257,  393,  257,  257,  257,  933,  257,  257,  257,  651,
-      651,  651,  394,  655,  655,  394,  655, 1826,  357,  929,
+      257,  393,  257,  257,  257,  930,  257,  257,  257,  651,
+      651,  651,  394,  655,  655,  394,  655, 1815,  357,  931,
 
-      383,  383,  357,  813, 1828,  389,  651,  651,  651,  654,
+      383,  383,  357,  815, 1816,  389,  651,  651,  651,  654,
       654,  390,  654,  651,  651,  651,  651,  651,  651,  651,
       651,  651,  391,  383,  384,  257,  384,  383,  383,  383,
-      383,  383,  383,  383,  385,  383,  383,  383, 1829,  383,
+      383,  383,  383,  383,  385,  383,  383,  383, 1824,  383,
       387,  383,  388,  383,  393,  257,  393,  393,  257,  393,
-      393,  257,  393,  933,  393,  257,  393, 1830,  655, 1487,
-      394, 1835,  655,  394,  655,  823,  395,  980,  383,  383,
-      395,  828, 1488,  389,  654,  651,  651,  651,  654,  390,
+      393,  257,  393,  935,  393,  257,  393, 1138,  655, 1505,
+      394, 1469,  655,  394,  655,  825,  395,  931,  383,  383,
+      395,  830, 1494,  389,  654,  651,  651,  651,  654,  390,
       654,  651,  651,  651,  651,  651,  651,  651,  651,  651,
       391,  396,  397,  257,  397,  396,  396,  396,  396,  396,
 
-      396,  396,  398,  396,  396,  396, 1838,  396,  400,  396,
+      396,  396,  398,  396,  396,  396, 1827,  396,  400,  396,
       401,  396,  405,  257,  405,  405,  257,  405,  416,  257,
-      416, 1839,  416,  257,  416,  430,  257,  430,  406,  655,
-      655,  406,  655, 1840,  417,  856,  396,  396,  417,  834,
-     1842,  431,  651,  651,  651,  654,  654,  402,  654,  651,
+      416, 1828,  416,  257,  416,  430,  257,  430,  406,  655,
+      655,  406,  655, 1831,  417,  858,  396,  396,  417,  836,
+     1833,  431,  651,  651,  651,  654,  654,  402,  654,  651,
       651,  651,  403,  396,  397,  257,  397,  396,  396,  396,
-      396,  396,  396,  396,  398,  396,  396,  396, 1845,  396,
+      396,  396,  396,  396,  398,  396,  396,  396, 1835,  396,
       400,  396,  401,  396,  430,  257,  430,  257,  257,  257,
-      257,  257,  257,  849,  430,  257,  430,  430,  257,  430,
-      431,  690, 1846,  432, 1848, 1852,  432,  655,  396,  396,
+      257,  257,  257,  851,  430,  257,  430,  430,  257,  430,
+      431,  690, 1836,  432, 1838, 1839,  432,  655,  396,  396,
 
-      431, 1853, 1854,  431, 1856,  848,  651,  651,  651,  402,
+      431, 1840, 1845,  431, 1848,  850,  651,  651,  651,  402,
       651,  651,  651,  654,  403,  407,  408,  257,  408,  407,
       407,  407,  407,  407,  407,  407,  409,  407,  407,  407,
-     1672,  407,  411,  407,  412,  407,  430,  257,  430,  430,
-      257,  430,  442,  257,  442,  933,  442,  257,  442,  454,
-      257,  454,  433,  849, 1867,  433,  655,  689,  443,  985,
-      407,  407,  443,  861,  655,  455,  651,  651,  651,  651,
+     1849,  407,  411,  407,  412,  407,  430,  257,  430,  430,
+      257,  430,  442,  257,  442,  935,  442,  257,  442,  454,
+      257,  454,  433,  851, 1850,  433,  655,  689,  443,  982,
+      407,  407,  443,  863,  655,  455,  651,  651,  651,  651,
       651,  651,  654,  651,  651,  651,  413,  651,  651,  651,
-      654, 1868,  414,  407,  408,  257,  408,  407,  407,  407,
-      407,  407,  407,  407,  409,  407,  407,  407, 1869,  407,
+      654, 1852,  414,  407,  408,  257,  408,  407,  407,  407,
+      407,  407,  407,  407,  409,  407,  407,  407, 1855,  407,
 
       411,  407,  412,  407,  454,  257,  454,  471,  257,  471,
-      471,  257,  471, 1871,  486,  257,  486,  486,  257,  486,
-      455, 1134,  655,  472, 1872, 1873,  472,  655,  407,  407,
-      487,  916,  655,  487,  651,  651,  651,  866,  654,  651,
-      651,  651,  917,  654,  413,  918, 1864,  872,  654, 1874,
+      471,  257,  471, 1856,  486,  257,  486,  486,  257,  486,
+      455, 1858,  655,  472, 1862, 1863,  472,  655,  407,  407,
+      487,  918,  655,  487,  651,  651,  651,  868,  654,  651,
+      651,  651,  919,  654,  413,  920, 1864,  874,  654, 1866,
       414,  418,  419,  257,  419,  418,  418,  418,  418,  418,
-      418,  418,  420,  418,  418,  418, 1875,  418,  422,  418,
+      418,  418,  420,  418,  418,  418, 1680,  418,  422,  418,
       423,  418,  502,  257,  502,  502,  257,  502,  513,  257,
-      513, 1876,  513,  257,  513,  849,  655, 1877,  503, 1878,
-     1879,  503, 1880,  690,  514,  849,  418,  418,  514,  424,
+      513, 1877,  513,  257,  513,  851,  655, 1878,  503, 1879,
+     1881,  503, 1882,  690,  514,  851,  418,  418,  514,  424,
 
       655,  425,  654,  690,  651,  651,  651,  426,  651,  651,
-      651,  651,  651,  651,  427,  880,  654,  428,  418,  419,
+      651,  651,  651,  651,  427,  882,  654,  428,  418,  419,
       257,  419,  418,  418,  418,  418,  418,  418,  418,  420,
-      418,  418,  418, 1882,  418,  422,  418,  423,  418,  525,
-      257,  525,  525,  257,  525,  538,  257,  538,  916,  538,
-      257,  538,  881, 1883, 1884,  526, 1134, 1885,  526,  917,
-     1499,  539,  932,  418,  418,  539,  424,  736,  425,  651,
-      651,  651, 1136, 1488,  426,  651,  651,  651,  651,  651,
-      651,  427, 1888, 1891,  428,  434,  435,  257,  435,  434,
+      418,  418,  418, 1883,  418,  422,  418,  423,  418,  525,
+      257,  525,  525,  257,  525,  538,  257,  538,  918,  538,
+      257,  538,  883, 1884, 1885,  526, 1138, 1138,  526,  919,
+     1505,  539,  934,  418,  418,  539,  424,  736,  425,  651,
+      651,  651, 1140, 1543,  426,  651,  651,  651,  651,  651,
+      651,  427, 1874, 1886,  428,  434,  435,  257,  435,  434,
       434,  434,  434,  434,  434,  434,  436,  434,  434,  434,
 
-     1892,  434,  438,  434,  439,  434,  257,  257,  257,  257,
-      257,  257,  538,  257,  538,  933,  538,  257,  538,  538,
-      257,  538,  357, 1893, 1894,  357,  655,  655,  539,  986,
-      434,  434,  539,  885,  894,  540,  651,  651,  651,  651,
-      651,  651,  654,  654, 1895, 1896,  440,  434,  435,  257,
+     1887,  434,  438,  434,  439,  434,  257,  257,  257,  257,
+      257,  257,  538,  257,  538,  935,  538,  257,  538,  538,
+      257,  538,  357, 1888, 1889,  357,  655,  655,  539,  987,
+      434,  434,  539,  887,  896,  540,  651,  651,  651,  651,
+      651,  651,  654,  654, 1890, 1892,  440,  434,  435,  257,
       435,  434,  434,  434,  434,  434,  434,  434,  436,  434,
-      434,  434, 1900,  434,  438,  434,  439,  434,  538,  257,
-      538,  550,  257,  550,  550,  257,  550, 1901,  257,  257,
-      257,  257,  257,  257,  540, 1903, 1904,  551,  925, 1905,
-      551, 1907,  434,  434,  552,  926, 1920,  552,  651,  651,
+      434,  434, 1893,  434,  438,  434,  439,  434,  538,  257,
+      538,  550,  257,  550,  550,  257,  550,  935,  257,  257,
+      257,  257,  257,  257,  540, 1894, 1895,  551,  927, 1898,
+      551,  988,  434,  434,  552,  928, 1901,  552,  651,  651,
 
-      651,  927,  900,  900,  900, 1151, 1151, 1151,  440,  444,
+      651,  929,  902,  902,  902, 1155, 1155, 1155,  440,  444,
       445,  257,  445,  444,  444,  444,  444,  444,  444,  444,
-      446,  444,  444,  444, 1921,  444,  448,  444,  449,  444,
-      550,  257,  550,  550,  257,  550,  550,  257,  550,  935,
-      550,  257,  550,  564,  257,  564,  551, 1922, 1923,  551,
-      936,  938,  553,  918,  444,  444,  553,  935,  926,  565,
-      450,  901,  938,  925,  939,  451, 1924, 1927,  936,  926,
-      926,  932, 1479, 1479, 1479,  927,  939,  452,  444,  445,
+      446,  444,  444,  444, 1902,  444,  448,  444,  449,  444,
+      550,  257,  550,  550,  257,  550,  550,  257,  550,  937,
+      550,  257,  550,  564,  257,  564,  551, 1903, 1904,  551,
+      938,  940,  553,  920,  444,  444,  553,  937,  928,  565,
+      450,  903,  940,  927,  941,  451, 1905, 1906,  938,  928,
+      928,  934, 1485, 1485, 1485,  929,  941,  452,  444,  445,
       257,  445,  444,  444,  444,  444,  444,  444,  444,  446,
-      444,  444,  444, 1928,  444,  448,  444,  449,  444,  564,
+      444,  444,  444, 1910,  444,  448,  444,  449,  444,  564,
 
-      257,  564,  257,  257,  257,  257,  257,  257, 1929,  564,
-      257,  564,  564,  257,  564,  565, 1930, 1935,  552,  925,
-      938,  552, 1943,  444,  444,  565,  926,  926,  565,  450,
-      916, 1944,  979,  979,  451,  900,  900,  900, 1951, 1138,
-     1955,  936, 1957, 1963,  932, 1969,  452,  456,  457,  257,
+      257,  564,  257,  257,  257,  257,  257,  257, 1911,  564,
+      257,  564,  564,  257,  564,  565, 1913, 1914,  552,  927,
+      940,  552, 1915,  444,  444,  565,  928,  928,  565,  450,
+      918, 1917,  981,  981,  451,  902,  902,  902, 1930, 1142,
+     1931,  938, 1932, 1933,  934, 1934,  452,  456,  457,  257,
       457,  456,  456,  456,  456,  456,  456,  456,  458,  456,
       456,  456,  459,  456,  460,  456,  461,  456,  459,  459,
       459,  459,  459,  459,  459,  459,  459,  459,  459,  459,
@@ -1862,1122 +1875,1130 @@ static yyconst flex_int16_t yy_nxt[12047] =
       459,  459,  459,  465,  459,  459,  466,  459,  459,  459,
       467,  459,  468,  469,  459,  459,  459,  459,  459,  459,
       459,  473,  474,  257,  474,  473,  473,  473,  473,  473,
-      473,  473,  475,  473,  473,  473, 1970,  473,  477,  473,
+      473,  473,  475,  473,  473,  473, 1937,  473,  477,  473,
       478,  473,  564,  257,  564,  564,  257,  564,  576,  257,
-      576, 1971,  576,  257,  576,  587,  257,  587,  566, 1304,
-     1972,  566, 1499, 1985,  577, 1991,  473,  473,  577, 1305,
-      479,  588, 1151, 1151, 1151, 1537, 1306,  480, 1995, 1998,
-      481, 1174, 1174, 1174,  482, 2000,  483,  484,  473,  474,
+      576, 1938,  576,  257,  576,  587,  257,  587,  566, 1308,
+     1939,  566, 1940, 1945,  577, 1953,  473,  473,  577, 1309,
+      479,  588, 1155, 1155, 1155, 1954, 1310,  480, 1961, 1965,
+      481, 1178, 1178, 1178,  482, 1967,  483,  484,  473,  474,
       257,  474,  473,  473,  473,  473,  473,  473,  473,  475,
 
-      473,  473,  473, 2001,  473,  477,  473,  478,  473,  587,
-      257,  587,  257,  257,  257,  257,  257,  257, 2003,  587,
-      257,  587,  587,  257,  587,  588, 2004, 2005,  552, 2009,
-     2012,  552, 2014,  473,  473,  588, 1152,  479,  588, 1187,
-     1187, 1187, 2021, 1188,  480, 1152, 1189,  481, 1174, 1174,
-     1174,  482, 2029,  483,  484,  488,  489,  257,  489,  488,
+      473,  473,  473, 1973,  473,  477,  473,  478,  473,  587,
+      257,  587,  257,  257,  257,  257,  257,  257, 1974,  587,
+      257,  587,  587,  257,  587,  588, 1975, 1981,  552, 1982,
+     1983,  552, 1984,  473,  473,  588, 1156,  479,  588, 1191,
+     1191, 1191, 1997, 1192,  480, 1156, 1193,  481, 1178, 1178,
+     1178,  482, 2003,  483,  484,  488,  489,  257,  489,  488,
       488,  488,  488,  488,  488,  488,  490,  488,  488,  488,
-     2030,  488,  492,  488,  493,  488,  587,  257,  587,  587,
-      257,  587,  600,  257,  600, 2031,  600,  257,  600,  945,
-      945,  945,  589, 2032, 2034,  589, 1134, 2048,  601, 2052,
-
-      488,  488,  601,  494,  495,  496,  946, 2053, 1197, 1197,
-     1197,  497, 1198, 2045,  498, 1199, 2054, 2057,  499, 1672,
-     2058,  500,  488,  489,  257,  489,  488,  488,  488,  488,
-      488,  488,  488,  490,  488,  488,  488, 2060,  488,  492,
+     2007,  488,  492,  488,  493,  488,  587,  257,  587,  587,
+      257,  587,  600,  257,  600, 2010,  600,  257,  600,  947,
+      947,  947,  589, 2012, 2013,  589, 2015, 2016,  601, 2017,
+
+      488,  488,  601,  494,  495,  496,  948, 2021, 1201, 1201,
+     1201,  497, 1202, 2024,  498, 1203, 2026, 2033,  499, 2041,
+     2042,  500,  488,  489,  257,  489,  488,  488,  488,  488,
+      488,  488,  488,  490,  488,  488,  488, 2043,  488,  492,
       488,  493,  488,  257,  257,  257,  257,  257,  257,  600,
-      257,  600, 2061,  600,  257,  600,  953,  953,  953,  552,
-     2062, 2046,  552, 2063, 2055,  601, 2064,  488,  488,  601,
-      494,  495,  496,  954, 2065, 1219, 1219, 1219,  497, 1220,
-     2056,  498, 1221, 2068, 2069,  499, 1672, 2072,  500,  504,
+      257,  600, 2044,  600,  257,  600,  955,  955,  955,  552,
+     2046, 2060,  552, 1138, 2064,  601, 2065,  488,  488,  601,
+      494,  495,  496,  956, 2066, 1223, 1223, 1223,  497, 1224,
+     2057,  498, 1225, 2069, 2070,  499, 1680, 2072,  500,  504,
       505,  257,  505,  504,  504,  504,  504,  504,  504,  504,
 
-      506,  504,  504,  504, 2073,  504,  508,  504,  509,  504,
-      600,  257,  600,  600,  257,  600,  615,  257,  615, 2047,
-      615,  257,  615,  968,  968,  968,  602, 2074, 2075,  602,
-     2076, 2078,  616, 2079,  504,  504,  616, 2082, 2085,  510,
-      969, 1534, 1534, 1534, 2089,  511,  504,  505,  257,  505,
+      506,  504,  504,  504, 1680,  504,  508,  504,  509,  504,
+      600,  257,  600,  600,  257,  600,  615,  257,  615, 2073,
+      615,  257,  615,  970,  970,  970,  602, 2074, 2058,  602,
+     2075, 2076,  616, 2077,  504,  504,  616, 2059, 2080,  510,
+      971, 1540, 1540, 1540, 2081,  511,  504,  505,  257,  505,
       504,  504,  504,  504,  504,  504,  504,  506,  504,  504,
-      504, 2090,  504,  508,  504,  509,  504,  257,  257,  257,
-      257,  257,  257,  615,  257,  615, 2091,  615,  257,  615,
-      988,  988,  988,  617, 2092, 2093,  617, 2094, 2095,  616,
-     2098,  504,  504,  616, 2102, 2103,  510,  989, 1479, 1479,
+      504, 2084,  504,  508,  504,  509,  504,  257,  257,  257,
+      257,  257,  257,  615,  257,  615, 2085,  615,  257,  615,
+      990,  990,  990,  617, 2086, 2067,  617, 2087, 2088,  616,
+     2090,  504,  504,  616, 2091, 2094,  510,  991, 1485, 1485,
 
-     1479, 2106,  511,  515,  516,  257,  516,  515,  515,  515,
-      515,  515,  515,  515,  517,  515,  515,  515, 2108,  515,
+     1485, 2068,  511,  515,  516,  257,  516,  515,  515,  515,
+      515,  515,  515,  515,  517,  515,  515,  515, 2097,  515,
       519,  515,  520,  515,  615,  257,  615,  615,  257,  615,
-      627,  257,  627, 2096,  627,  257,  627,  637,  257,  637,
-      618, 2097, 2104,  618, 2104, 2055,  628, 2124,  515,  515,
-      628, 2125,  521,  638, 1151, 1151, 1151, 2126, 2105,  522,
-     2056, 2105,  523,  515,  516,  257,  516,  515,  515,  515,
-      515,  515,  515,  515,  517,  515,  515,  515, 2127,  515,
+      627,  257,  627, 2101,  627,  257,  627,  637,  257,  637,
+      618, 2102, 2105,  618, 2106, 2107,  628, 2110,  515,  515,
+      628, 2114,  521,  638, 1155, 1155, 1155, 2115, 2118,  522,
+     2120, 2136,  523,  515,  516,  257,  516,  515,  515,  515,
+      515,  515,  515,  515,  517,  515,  515,  515, 2137,  515,
       519,  515,  520,  515,  637,  257,  637,  257,  257,  257,
-      257,  257,  257, 2128,  637,  257,  637,  637,  257,  637,
+      257,  257,  257, 2103,  637,  257,  637,  637,  257,  637,
 
-      638, 2129, 2131,  357, 2135, 2141,  357, 2142,  515,  515,
-      638, 2143,  521,  638, 1174, 1174, 1174, 2157, 1227,  522,
-     2161, 2162,  523,  527,  528,  257,  528,  527,  527,  527,
-      527,  527,  527,  527,  529,  527,  527,  527, 2163,  527,
+      638, 2104, 2138,  357, 2116, 2116,  357, 2139,  515,  515,
+      638, 2140,  521,  638, 1178, 1178, 1178, 2141, 1231,  522,
+     2117, 2068,  523,  527,  528,  257,  528,  527,  527,  527,
+      527,  527,  527,  527,  529,  527,  527,  527, 2143,  527,
       531,  527,  532,  527,  637,  257,  637,  637,  257,  637,
-      649,  257,  649, 2165,  649,  257,  649,  995,  995,  995,
-      639, 2169, 2173,  639, 2174, 2175,  650,  727,  527,  527,
-      650, 2176,  533, 3259,  996, 2177, 2180,  737, 1227,  534,
-     2187, 2189,  535,  686, 2199, 2200,  686, 2201, 2202,  536,
+      649,  257,  649, 2108,  649,  257,  649,  997,  997,  997,
+      639, 2109, 2147,  639, 2067, 2148,  650,  727,  527,  527,
+      650, 2149,  533, 3298,  998, 2155, 2156,  737, 1231,  534,
+     2117, 2157,  535,  686, 2171, 2175,  686, 2176, 2177,  536,
       527,  528,  257,  528,  527,  527,  527,  527,  527,  527,
 
       527,  529,  527,  527,  527,  738,  527,  531,  527,  532,
-      527, 2204,  687, 2210,  741, 1000, 1000, 1000,  688,  689,
-     1012, 1012, 1012,  683, 2216,  689, 1024, 1024, 1024,  690,
-      742, 2217, 1001, 2218, 2219,  527,  527, 1013, 2222,  533,
-     1241, 1241, 1241, 1025, 1242, 2224,  534, 1243, 2225,  535,
-     1686, 1686, 1686, 1689, 1689, 1689,  536,  541,  542,  257,
+      527, 2179,  687, 2183,  741, 1002, 1002, 1002,  688,  689,
+     1014, 1014, 1014,  683, 2187,  689, 1026, 1026, 1026,  690,
+      742, 2188, 1003, 2189, 2190,  527,  527, 1015, 2191,  533,
+     1245, 1245, 1245, 1027, 1246, 2194,  534, 1247, 2201,  535,
+     1694, 1694, 1694, 1697, 1697, 1697,  536,  541,  542,  257,
       542,  541,  541,  541,  541,  541,  541,  541,  543,  541,
-      541,  541, 2226,  541,  545,  541,  546,  541, 1026, 1026,
-     1026, 1032, 1032, 1032, 1035, 1035, 1035, 1047, 1047, 1047,
-     1049, 1049, 1049, 1672, 1134, 1027, 1687, 2230, 1033, 1690,
-
-     2207, 1036,  541,  541, 1048, 2235, 2237, 1050,  547, 1251,
-     1251, 1251, 2238, 1252, 2239, 2243, 1253, 1693, 1693, 1693,
-     1696, 1696, 1696,  548,  541,  542,  257,  542,  541,  541,
-      541,  541,  541,  541,  541,  543,  541,  541,  541, 2209,
-      541,  545,  541,  546,  541, 1061, 1061, 1061, 1069, 1069,
-     1069, 1074, 1074, 1074, 1080, 1080, 1080, 1100, 1100, 1100,
-     2249, 2250, 1062, 2251, 2252, 1070, 2253, 2254, 1075,  541,
-      541, 1081, 2255, 2256, 1101,  547, 1259, 1259, 1259, 2257,
-     1260, 2258, 2264, 1261, 1706, 1706, 1706, 1534, 1534, 1534,
+      541,  541, 2203,  541,  545,  541,  546,  541, 1028, 1028,
+     1028, 1034, 1034, 1034, 1037, 1037, 1037, 1051, 1051, 1051,
+     1053, 1053, 1053, 2213, 2214, 1029, 1695, 2215, 1035, 1698,
+
+     2216, 1038,  541,  541, 1052, 2218, 1138, 1054,  547, 1255,
+     1255, 1255, 2221, 1256, 1680, 2224, 1257, 1701, 1701, 1701,
+     1704, 1704, 1704,  548,  541,  542,  257,  542,  541,  541,
+      541,  541,  541,  541,  541,  543,  541,  541,  541, 2230,
+      541,  545,  541,  546,  541, 1065, 1065, 1065, 1073, 1073,
+     1073, 1078, 1078, 1078, 1084, 1084, 1084, 1104, 1104, 1104,
+     2223, 2231, 1066, 2232, 2233, 1074, 2236, 2238, 1079,  541,
+      541, 1085, 2239, 2240, 1105,  547, 1263, 1263, 1263, 2244,
+     1264, 2249, 2251, 1265, 1714, 1714, 1714, 1540, 1540, 1540,
       548,  554,  555,  257,  555,  554,  554,  554,  554,  554,
 
-      554,  554,  556,  554,  554,  554, 2265,  554,  558,  554,
-      559,  554, 1124, 1124, 1124, 1128, 1128, 1128, 1672, 2266,
-     1147, 1147, 1147, 1147, 1147, 1147, 1182, 1182, 1182, 1125,
-     2267, 2279, 1129, 1182, 1182, 1182,  554,  554, 1149, 2280,
-     2285, 1149,  560, 2286, 1184,  561, 1276, 1276, 1276, 2208,
-     1277, 1184, 2288, 1278, 1743, 1743, 1743,  562,  554,  555,
+      554,  554,  556,  554,  554,  554, 2252,  554,  558,  554,
+      559,  554, 1128, 1128, 1128, 1132, 1132, 1132, 1680, 2253,
+     1151, 1151, 1151, 1151, 1151, 1151, 1186, 1186, 1186, 1129,
+     2257, 2263, 1133, 1186, 1186, 1186,  554,  554, 1153, 2264,
+     2265, 1153,  560, 2266, 1188,  561, 1280, 1280, 1280, 2222,
+     1281, 1188, 2267, 1282, 1751, 1751, 1751,  562,  554,  555,
       257,  555,  554,  554,  554,  554,  554,  554,  554,  556,
-      554,  554,  554, 2289,  554,  558,  554,  559,  554, 2293,
-     2294, 1150,  945,  945,  945, 2295, 2301, 1192, 1192, 1192,
-     1192, 1192, 1192, 1185,  953,  953,  953, 2302, 2281,  946,
+      554,  554,  554, 2268,  554,  558,  554,  559,  554, 2269,
+     2270, 1154,  947,  947,  947, 2271, 2272, 1196, 1196, 1196,
+     1196, 1196, 1196, 1189,  955,  955,  955, 2278, 2279,  948,
 
-     1200, 1200, 1200,  554,  554, 1194, 2282, 2303, 1194,  560,
-     2304,  954,  561, 2307, 1293, 1293, 1293, 1201, 1294, 2312,
-     2316, 1295, 2317, 2322,  562,  567,  568,  257,  568,  567,
+     1204, 1204, 1204,  554,  554, 1198, 2280, 2281, 1198,  560,
+     2293,  956,  561, 2294, 1297, 1297, 1297, 1205, 1298, 2299,
+     2300, 1299, 2302, 2303,  562,  567,  568,  257,  568,  567,
       567,  567,  567,  567,  567,  567,  569,  567,  567,  567,
-     2323,  567,  571,  567,  572,  567, 1203, 1203, 1203, 1208,
-     1208, 1208, 2324, 2325, 1195, 2327, 1208, 1208, 1208, 1215,
-     1215, 1215, 2337, 1204, 1740, 1740, 1740, 1210, 2348, 2349,
-      567,  567, 2350, 2354, 1210, 2355,  573, 1217, 1686, 1686,
-     1686,  574,  567,  568,  257,  568,  567,  567,  567,  567,
-      567,  567,  567,  569,  567,  567,  567, 2356,  567,  571,
-
-      567,  572,  567, 1211, 1215, 1215, 1215,  968,  968,  968,
-     1741, 1223, 1223, 1223,  988,  988,  988, 1223, 1223, 1223,
-     1908, 2359, 1217, 2363,  969, 2364, 1909,  567,  567, 1225,
-     1910,  989, 2365,  573, 1911, 1225, 1672, 2366,  574,  578,
+     2304,  567,  571,  567,  572,  567, 1207, 1207, 1207, 1212,
+     1212, 1212, 2305, 2309, 1199, 2310, 1212, 1212, 1212, 1219,
+     1219, 1219, 2311, 1208, 1748, 1748, 1748, 1214, 2317, 2318,
+      567,  567, 2319, 2320, 1214, 2323,  573, 1221, 1694, 1694,
+     1694,  574,  567,  568,  257,  568,  567,  567,  567,  567,
+      567,  567,  567,  569,  567,  567,  567, 2328,  567,  571,
+
+      567,  572,  567, 1215, 1219, 1219, 1219,  970,  970,  970,
+     1749, 1227, 1227, 1227,  990,  990,  990, 1227, 1227, 1227,
+     1918, 2332, 1221, 2333,  971, 2338, 1919,  567,  567, 1229,
+     1920,  991, 2339,  573, 1921, 1229, 2340, 2341,  574,  578,
       579,  257,  579,  578,  578,  578,  578,  578,  578,  578,
-      580,  578,  578,  578, 1226,  578,  582,  578,  583,  578,
-     1246, 1246, 1246, 1246, 1246, 1246, 1912, 2367, 1218,  995,
-      995,  995, 1913, 1255, 1255, 1255, 1914, 2368, 1248, 2342,
-     1915, 1248, 2369, 2370,  578,  578,  996, 1000, 1000, 1000,
-      584, 1257, 1296, 1296, 1296, 2371, 1297, 2372, 2387, 1298,
+      580,  578,  578,  578, 1230,  578,  582,  578,  583,  578,
+     1250, 1250, 1250, 1250, 1250, 1250, 1922, 2343, 1222,  997,
+      997,  997, 1923, 1259, 1259, 1259, 1924, 2353, 1252, 2364,
+     1925, 1252, 2365, 2366,  578,  578,  998, 1002, 1002, 1002,
+      584, 1261, 1300, 1300, 1300, 2370, 1301, 2371, 2372, 1302,
 
-     2388, 1742, 1742, 1742, 1001,  585,  578,  579,  257,  579,
+     2375, 1750, 1750, 1750, 1003,  585,  578,  579,  257,  579,
       578,  578,  578,  578,  578,  578,  578,  580,  578,  578,
-      578, 2389,  578,  582,  578,  583,  578, 2390, 2395, 1249,
-     1255, 1255, 1255, 2396, 2397, 1263, 1263, 1263, 1263, 1263,
-     1263, 1269, 1269, 1269, 1269, 1269, 1269, 1690, 1257, 2398,
-     2283,  578,  578, 1265, 2399, 2400, 1265,  584, 2284, 1271,
-     2318, 2320, 1271, 1307, 1307, 1307, 2401, 1308, 2319, 2321,
-     1309, 2404,  585,  590,  591,  257,  591,  590,  590,  590,
-      590,  590,  590,  590,  592,  590,  590,  590, 1672,  590,
-      594,  590,  595,  590, 2405, 2408, 1258, 2409, 2414, 1266,
-
-     1012, 1012, 1012, 1281, 1281, 1281, 1024, 1024, 1024, 1272,
-     1281, 1281, 1281, 1288, 1288, 1288, 2415, 1013,  590,  590,
-     2416, 1283, 2417, 1025,  596, 2426, 2427,  597, 1283, 2428,
-     2429, 1290, 1689, 1689, 1689, 2343, 1689, 1689, 1689,  598,
+      578, 2379,  578,  582,  578,  583,  578, 2380, 1680, 1253,
+     1259, 1259, 1259, 2381, 2382, 1267, 1267, 1267, 1267, 1267,
+     1267, 1273, 1273, 1273, 1273, 1273, 1273, 1698, 1261, 2383,
+     2295,  578,  578, 1269, 2384, 2385, 1269,  584, 2296, 1275,
+     2297, 2334, 1275, 1311, 1311, 1311, 2386, 1312, 2298, 2335,
+     1313, 2358,  585,  590,  591,  257,  591,  590,  590,  590,
+      590,  590,  590,  590,  592,  590,  590,  590, 1680,  590,
+      594,  590,  595,  590, 2387, 2388, 1262, 2403, 2404, 1270,
+
+     1014, 1014, 1014, 1285, 1285, 1285, 1026, 1026, 1026, 1276,
+     1285, 1285, 1285, 1292, 1292, 1292, 2405, 1015,  590,  590,
+     2406, 1287, 2336, 1027,  596, 2411, 2412,  597, 1287, 2413,
+     2337, 1294, 1697, 1697, 1697, 2359, 1697, 1697, 1697,  598,
       590,  591,  257,  591,  590,  590,  590,  590,  590,  590,
-      590,  592,  590,  590,  590, 2431,  590,  594,  590,  595,
-      590, 1026, 1026, 1026, 2433, 1672, 1288, 1288, 1288, 2457,
-     2458, 1284, 1299, 1299, 1299, 1299, 1299, 1299, 1027, 1032,
-     1032, 1032, 1837, 2460, 1290,  590,  590, 1035, 1035, 1035,
-     1301,  596, 2461, 1301,  597, 2462, 1033, 2453, 1311, 1311,
+      590,  592,  590,  590,  590, 2414,  590,  594,  590,  595,
+      590, 1028, 1028, 1028, 2415, 2416, 1292, 1292, 1292, 2417,
+     2420, 1288, 1303, 1303, 1303, 1303, 1303, 1303, 1029, 1034,
+     1034, 1034, 1847, 2421, 1294,  590,  590, 1037, 1037, 1037,
+     1305,  596, 2422, 1305,  597, 2427, 1035, 2428, 1315, 1315,
 
-     1311, 2463, 1312, 2467, 1036, 1313,  598,  603,  604,  257,
+     1315, 2433, 1316, 2434, 1038, 1317,  598,  603,  604,  257,
       604,  603,  603,  603,  603,  603,  603,  603,  605,  603,
-      603,  603, 1672,  603,  607,  603,  608,  603, 1291, 1314,
-     1314, 1314, 1323, 1323, 1323, 2468, 1302, 1323, 1323, 1323,
-     1047, 1047, 1047, 1339, 1339, 1339, 1315, 1327, 1327, 1327,
-     1325, 1328,  603,  603, 1329, 1325, 2469, 1048, 2470, 2454,
-      609, 1341,  610, 2471, 2472,  611, 1881, 1881, 1881,  612,
-     1693, 1693, 1693,  613,  603,  604,  257,  604,  603,  603,
-      603,  603,  603,  603,  603,  605,  603,  603,  603, 2473,
-      603,  607,  603,  608,  603, 1326, 1049, 1049, 1049, 1330,
-
-     1330, 1330, 2474, 1331, 2475, 2476, 1332, 1333, 1333, 1333,
-     1354, 1354, 1354, 1050, 3259, 3259, 3259, 2477, 2479,  603,
-      603, 3259, 3259, 3259, 1334, 2480, 2483,  609, 1356,  610,
-     2481, 3259,  611, 1696, 1696, 1696,  612, 2484, 3259, 2482,
+      603,  603, 2435,  603,  607,  603,  608,  603, 1295, 1318,
+     1318, 1318, 1329, 1329, 1329, 2436, 1306, 1329, 1329, 1329,
+     1051, 1051, 1051, 1345, 1345, 1345, 1319, 1333, 1333, 1333,
+     1331, 1334,  603,  603, 1335, 1331, 2445, 1052, 2446, 2447,
+      609, 1347,  610, 2448, 2450,  611, 1891, 1891, 1891,  612,
+     1701, 1701, 1701,  613,  603,  604,  257,  604,  603,  603,
+      603,  603,  603,  603,  603,  605,  603,  603,  603, 2452,
+      603,  607,  603,  608,  603, 1332, 1053, 1053, 1053, 1336,
+
+     1336, 1336, 1680, 1337, 2476, 1680, 1338, 1339, 1339, 1339,
+     1360, 1360, 1360, 1054, 3298, 3298, 3298, 2477, 2479,  603,
+      603, 3298, 3298, 3298, 1340, 2480, 2481,  609, 1362,  610,
+     2482, 3298,  611, 1704, 1704, 1704,  612, 2472, 3298, 2473,
       613,  619,  620,  257,  620,  619,  619,  619,  619,  619,
-      619,  619,  621,  619,  619,  619, 2485,  619,  623,  619,
-      624,  619, 1339, 1339, 1339, 1335, 1061, 1061, 1061, 1706,
-     1706, 1706, 2486, 1336, 3259, 3259, 3259, 3259, 3259, 3259,
-     1341, 2487, 2490, 1062, 2488, 2491,  619,  619, 1347, 1347,
-     1347, 3259, 1348, 2489, 3259, 1349, 1359, 1359, 1359, 2492,
+      619,  619,  621,  619,  619,  619, 2486,  619,  623,  619,
+      624,  619, 1345, 1345, 1345, 1341, 1065, 1065, 1065, 1714,
+     1714, 1714, 2423, 1342, 3298, 3298, 3298, 3298, 3298, 3298,
+     1347, 2487, 2424, 1066, 2488, 2489,  619,  619, 1353, 1353,
+     1353, 3298, 1354, 2490, 3298, 1355, 1365, 1365, 1365, 2491,
 
-     1360, 2493, 2494, 1361, 2496, 1886, 1886, 1886, 2500, 1342,
+     1366, 2492, 2493, 1367, 2494, 1896, 1896, 1896, 2495, 1348,
       625,  619,  620,  257,  620,  619,  619,  619,  619,  619,
-      619,  619,  621,  619,  619,  619, 1338,  619,  623,  619,
-      624,  619, 1337, 1350, 1350, 1350, 1069, 1069, 1069, 2501,
-     1362, 1362, 1362, 2502, 2503, 1354, 1354, 1354, 2507, 2508,
-     1351, 2512, 2515, 1070, 2516, 2519,  619,  619, 1364, 1362,
-     1362, 1362, 2531, 1356, 1367, 1367, 1367, 2532, 1368, 1887,
-     2535, 1369, 1376, 1376, 1376, 2536, 1377, 1364, 1134, 1378,
+      619,  619,  621,  619,  619,  619, 1344,  619,  623,  619,
+      624,  619, 1343, 1356, 1356, 1356, 1073, 1073, 1073, 2496,
+     1368, 1368, 1368, 2498, 2499, 1360, 1360, 1360, 2502, 2503,
+     1357, 2504, 2505, 1074, 2506, 2509,  619,  619, 1370, 1368,
+     1368, 1368, 2510, 1362, 1373, 1373, 1373, 2511, 1374, 1897,
+     2512, 1375, 1382, 1382, 1382, 2513, 1383, 1370, 2515, 1384,
       625,  629,  630,  257,  630,  629,  629,  629,  629,  629,
-      629,  629,  631,  629,  629,  629, 1357,  629,  633,  629,
+      629,  629,  631,  629,  629,  629, 1363,  629,  633,  629,
 
-      634,  629, 1074, 1074, 1074, 1371, 1371, 1371, 1080, 1080,
-     1080, 2556, 1371, 1371, 1371, 1382, 1382, 1382, 2553, 1075,
-     1365, 2557, 2558, 1373, 1672, 1081,  629,  629, 2559, 2560,
-     1373, 2569, 2570, 1384, 1889, 1889, 1889,  635,  629,  630,
+      634,  629, 1078, 1078, 1078, 1377, 1377, 1377, 1084, 1084,
+     1084, 2519, 1377, 1377, 1377, 1388, 1388, 1388, 2520, 1079,
+     1371, 2521, 2500, 1379, 2522, 1085,  629,  629, 2526, 2527,
+     1379, 2501, 2528, 1390, 1899, 1899, 1899,  635,  629,  630,
       257,  630,  629,  629,  629,  629,  629,  629,  629,  631,
-      629,  629,  629, 2571,  629,  633,  629,  634,  629, 1374,
-     2572, 1382, 1382, 1382, 1386, 1386, 1386, 2555, 1388, 1388,
-     1388, 3259, 3259, 3259, 1391, 1391, 1391, 2573, 2574, 1384,
-     1890, 1387, 2575,  629,  629, 1389, 2576, 2577, 3259, 1740,
-     1740, 1740, 1393, 2578,  635,  640,  641,  257,  641,  640,
+      629,  629,  629, 2529,  629,  633,  629,  634,  629, 1380,
+     2530, 1388, 1388, 1388, 1392, 1392, 1392, 2534, 1394, 1394,
+     1394, 3298, 3298, 3298, 1397, 1397, 1397, 2507, 2537, 1390,
+     1900, 1393, 2538,  629,  629, 1395, 2508, 2541, 3298, 1748,
+     1748, 1748, 1399, 2553,  635,  640,  641,  257,  641,  640,
 
       640,  640,  640,  640,  640,  640,  642,  640,  640,  640,
-     2579,  640,  644,  640,  645,  640, 1385, 2581, 2582, 1391,
-     1391, 1391, 1396, 1396, 1396, 1742, 1742, 1742, 2583, 2584,
-     1390, 1400, 1400, 1400, 1403, 1403, 1403, 1393, 2585, 1397,
-      640,  640, 3259, 3259, 3259, 3259, 3259, 3259, 1401, 1672,
-     2586,  646, 1405, 1408, 1408, 1408, 2587, 1409, 2588, 3259,
-     1410, 2589, 3259, 2590,  647,  640,  641,  257,  641,  640,
+     2554,  640,  644,  640,  645,  640, 1391, 2557, 2558, 1397,
+     1397, 1397, 1402, 1402, 1402, 1750, 1750, 1750, 2578, 2579,
+     1396, 1406, 1406, 1406, 1409, 1409, 1409, 1399, 2580, 1403,
+      640,  640, 3298, 3298, 3298, 3298, 3298, 3298, 1407, 1680,
+     1138,  646, 1411, 1414, 1414, 1414, 2581, 1415, 2582, 3298,
+     1416, 2591, 3298, 1680,  647,  640,  641,  257,  641,  640,
       640,  640,  640,  640,  640,  640,  642,  640,  640,  640,
-     1394,  640,  644,  640,  645,  640, 2554, 1403, 1403, 1403,
-     2591, 2592, 1398, 2593, 2594, 1100, 1100, 1100, 1411, 1411,
-
-     1411, 1411, 1411, 1411, 1402, 1405, 2595, 1399, 2596, 2597,
-      640,  640, 1101, 1415, 1415, 1415, 1413, 2599, 2607, 1413,
-     2608,  646, 2609, 2613, 1406, 2648, 1417, 1417, 1417, 2650,
-     1416, 1419, 1419, 1419,  647,  655, 1419, 1419, 1419, 1429,
-     1429, 1429,  670, 1418, 1423, 1423, 1423, 2651, 2652, 1421,
-     1672,  654,  671, 1672, 1421, 1134, 1414, 1431, 3259, 3259,
-     3259, 1424, 1743, 1743, 1743, 1427, 1427, 1427, 2656, 2657,
-     1429, 1429, 1429, 2631, 2660, 3259, 1124, 1124, 1124,  672,
-      673,  674, 1428, 2632, 2645,  675,  676,  677, 1431, 2633,
-      678,  679, 2646, 1125,  680, 2647,  681,  682,  683,  655,
-
-     1438, 1438, 1438, 1438, 1438, 1438,  727, 1422, 1425, 1444,
-     1444, 1444, 1444, 1444, 1444,  654,  728, 2661, 1440, 2563,
-     2658, 1440, 2664, 1426, 1448, 1448, 1448, 1446, 1449, 2564,
-     1446, 1450, 2565, 2659, 1451, 1451, 1451, 2665, 1451, 1451,
-     1451, 1432, 2666,  672,  729,  684, 1128, 1128, 1128,  730,
-      731,  677, 1453, 2667,  732,  679, 1453, 2662,  733, 2634,
-      734,  735,  683, 1129, 1455, 1455, 1455, 1441, 1456, 2635,
-     2663, 1457, 1459, 1459, 1459, 2636, 1447, 1459, 1459, 1459,
-     1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 2668,
-     1461, 1501, 1501, 1501, 2669, 1461, 2670, 2671, 1149, 1454,
-
-     2672, 1149, 2674, 2675, 1149, 1182, 1182, 1182, 1502, 1182,
-     1182, 1182, 1182, 1182, 1182, 1504, 1504, 1504, 1187, 1187,
-     1187, 2676, 1188, 1184, 2677, 1189, 2678, 1184, 2679, 2680,
-     1184, 2681, 1505, 1471, 3259, 3259, 3259, 1192, 1192, 1192,
-     2682, 1462, 1192, 1192, 1192, 1192, 1192, 1192, 1200, 1200,
-     1200, 3259, 1197, 1197, 1197, 1194, 1198, 2683, 2684, 1199,
-     1194, 1503, 2685, 1194, 2686, 1201, 1510, 1510, 1510, 2687,
-     1511, 2688, 2690, 1512, 1513, 1513, 1513, 1203, 1203, 1203,
-     1515, 1515, 1515, 2698, 1516, 2699, 2700, 1517, 1519, 1519,
-     1519, 1514, 1508, 2701, 1204, 1506, 1208, 1208, 1208, 1208,
-
-     1208, 1208, 1208, 1208, 1208, 1520, 1524, 1524, 1524, 1215,
-     1215, 1215, 2718, 2719, 1210, 2720, 2721, 1210, 2722, 2723,
-     1210, 2726, 2734, 1525, 1215, 1215, 1215, 1217, 1215, 1215,
-     1215, 1219, 1219, 1219, 2727, 1220, 2736, 2737, 1221, 1223,
-     1223, 1223, 1217, 1223, 1223, 1223, 1217, 1529, 1529, 1529,
-     2566, 1241, 1241, 1241, 1672, 1242, 2738, 1225, 1243, 1134,
-     2567, 1225, 1522, 2568, 2739, 1530, 1546, 1546, 1546, 1246,
-     1246, 1246, 1246, 1246, 1246, 1527, 1246, 1246, 1246, 1255,
-     1255, 1255, 2728, 1547, 1251, 1251, 1251, 1248, 1252, 2731,
-     1248, 1253, 2740, 2741, 1248, 2729, 2742, 1257, 1255, 1255,
-
-     1255, 1255, 1255, 1255, 1259, 1259, 1259, 2730, 1260, 2743,
-     2744, 1261, 1552, 1552, 1552, 2745, 1257, 2748, 2749, 1257,
-     1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1263, 1553,
-     1555, 1555, 1555, 3259, 3259, 3259, 2750, 1548, 1265, 2751,
-     2752, 1265, 2753, 2754, 1265, 2755, 2757, 1556, 2758, 2759,
-     3259, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269, 1269,
-     2760, 1557, 1551, 1561, 1561, 1561, 1276, 1276, 1276, 1271,
-     1277, 2761, 1271, 1278, 2762, 1271, 1281, 1281, 1281, 2763,
-     1562, 1281, 1281, 1281, 1281, 1281, 1281, 1568, 1568, 1568,
-     1288, 1288, 1288, 1554, 1283, 1288, 1288, 1288, 2764, 1283,
-
-     2765, 2766, 1283, 2767, 1569, 1571, 1571, 1571, 1290, 1288,
-     1288, 1288, 2768, 1290, 1293, 1293, 1293, 2769, 1294, 2770,
-     2771, 1295, 1572, 1558, 1296, 1296, 1296, 1290, 1297, 2777,
-     2778, 1298, 1299, 1299, 1299, 1299, 1299, 1299, 1299, 1299,
-     1299, 1307, 1307, 1307, 2779, 1308, 2780, 2781, 1309, 1565,
-     1301, 2795, 2796, 1301, 2797, 2787, 1301, 1578, 1578, 1578,
-     1311, 1311, 1311, 2798, 1312, 2788, 2799, 1313, 1314, 1314,
-     1314, 1580, 1580, 1580, 1579, 1581, 1570, 2800, 1582, 1323,
-     1323, 1323, 1323, 1323, 1323, 1315, 1323, 1323, 1323, 1327,
-     1327, 1327, 2789, 1328, 2804, 2805, 1329, 1325, 2791, 2806,
-
-     1325, 2793, 2790, 1573, 1325, 1330, 1330, 1330, 2792, 1331,
-     2807, 2794, 1332, 1333, 1333, 1333, 1591, 1591, 1591, 2817,
-     1592, 1134, 2818, 1593, 1339, 1339, 1339, 1339, 1339, 1339,
-     1334, 1339, 1339, 1339, 1347, 1347, 1347, 2819, 1348, 2820,
-     2821, 1349, 1341, 2822, 2823, 1341, 1350, 1350, 1350, 1341,
-     1603, 1603, 1603, 1590, 1604, 2808, 2824, 1605, 1354, 1354,
-     1354, 2828, 2829, 1351, 1354, 1354, 1354, 1354, 1354, 1354,
-     1359, 1359, 1359, 2830, 1360, 2831, 1356, 1361, 2832, 1598,
-     2833, 2835, 1356, 2836, 2837, 1356, 1362, 1362, 1362, 1362,
-     1362, 1362, 1362, 1362, 1362, 1367, 1367, 1367, 2838, 1368,
-
-     2839, 2840, 1369, 2841, 1364, 2842, 2843, 1364, 2844, 2848,
-     1364, 1371, 1371, 1371, 1371, 1371, 1371, 2849, 1608, 1371,
-     1371, 1371, 2850, 1376, 1376, 1376, 2853, 1377, 2858, 1373,
-     1378, 2859, 1373, 1382, 1382, 1382, 2860, 1373, 1382, 1382,
-     1382, 2861, 1382, 1382, 1382, 1386, 1386, 1386, 1619, 1619,
-     1619, 1384, 1620, 2862, 2863, 1621, 1384, 2864, 2865, 1610,
-     1384, 2866, 1387, 1388, 1388, 1388, 2867, 2868, 1613, 1622,
-     1622, 1622, 2869, 1623, 2871, 2872, 1624, 1391, 1391, 1391,
-     1389, 1391, 1391, 1391, 2873, 1391, 1391, 1391, 1396, 1396,
-     1396, 2874, 1400, 1400, 1400, 1393, 1897, 1897, 1897, 1393,
-
-     2881, 1134, 1618, 1393, 2882, 1397, 1628, 1628, 1628, 1401,
-     1629, 2883, 2884, 1630, 1633, 1633, 1633, 2885, 1634, 2886,
-     2887, 1635, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403,
-     1403, 1408, 1408, 1408, 2888, 1409, 2889, 2890, 1410, 2891,
-     1405, 2892, 1898, 1405, 2875, 2893, 1405, 1411, 1411, 1411,
-     2894, 2897, 1626, 1411, 1411, 1411, 1411, 1411, 1411, 1415,
-     1415, 1415, 1640, 1640, 1640, 1413, 1641, 2898, 2899, 1642,
-     2900, 1413, 2901, 2902, 1413, 2903, 1416, 1417, 1417, 1417,
-     1643, 1643, 1643, 2904, 1644, 2905, 2906, 1645, 1419, 1419,
-     1419, 2907, 1637, 2911, 1418, 1419, 1419, 1419, 2918, 1419,
-
-     1419, 1419, 1423, 1423, 1423, 2919, 1421, 1647, 1647, 1647,
-     2920, 1648, 2921, 1421, 1649, 2922, 1639, 1421, 2923, 1424,
-     1427, 1427, 1427, 1652, 1652, 1652, 2924, 1653, 2925, 2926,
-     1654, 1429, 1429, 1429, 1429, 1429, 1429, 1428, 1429, 1429,
-     1429, 1657, 1657, 1657, 1438, 1438, 1438, 2927, 2928, 1431,
-     2929, 2932, 1431, 1438, 1438, 1438, 1431, 2933, 1658, 2934,
-     2935, 1646, 1440, 1438, 1438, 1438, 1444, 1444, 1444, 2938,
-     2943, 1440, 1444, 1444, 1444, 1444, 1444, 1444, 1448, 1448,
-     1448, 1440, 1449, 2939, 1446, 1450, 1451, 1451, 1451, 1134,
-     1446, 2944, 2945, 1446, 1451, 1451, 1451, 1451, 1451, 1451,
-
-     1655, 1455, 1455, 1455, 1453, 1456, 2946, 2947, 1457, 1459,
-     1459, 1459, 1453, 2948, 2938, 1453, 1459, 1459, 1459, 1459,
-     1459, 1459, 2949, 2950, 1662, 2941, 2951, 1461, 1665, 1671,
-     1671, 1671, 2952, 2953, 1461, 2936, 2954, 1461, 1147, 1147,
-     1147, 1501, 1501, 1501, 1182, 1182, 1182, 1672, 1673, 2955,
-     1504, 1504, 1504, 1529, 1529, 1529, 1149, 1666, 1502, 1709,
-     1709, 1709, 1184, 1710, 2956, 2957, 1711, 1505, 1713, 1713,
-     1713, 1530, 1714, 2958, 2959, 1715, 1192, 1192, 1192, 2960,
-     1668, 1510, 1510, 1510, 2961, 1511, 2966, 2962, 1512, 1513,
-     1513, 1513, 2971, 2964, 1194, 2972, 1720, 1720, 1720, 2963,
-
-     1721, 2967, 1712, 1722, 1678, 2965, 1514, 1515, 1515, 1515,
-     2969, 1516, 2973, 2968, 1517, 1519, 1519, 1519, 2974, 1724,
-     1724, 1724, 2970, 1725, 2975, 1718, 1726, 1208, 1208, 1208,
-     2976, 1134, 1520, 1524, 1524, 1524, 1730, 1730, 1730, 2979,
-     1731, 1672, 1673, 1732, 2979, 1210, 1733, 1733, 1733, 2982,
-     1525, 1215, 1215, 1215, 1751, 1751, 1751, 1546, 1546, 1546,
-     1753, 1753, 1753, 1734, 1754, 2983, 2984, 1755, 2985, 1217,
-     2988, 1752, 2977, 2991, 1547, 2986, 2938, 1728, 1246, 1246,
-     1246, 1255, 1255, 1255, 1552, 1552, 1552, 1760, 1760, 1760,
-     2939, 1761, 2998, 2987, 1762, 3000, 1248, 3003, 2989, 1257,
-
-     1735, 1553, 1263, 1263, 1263, 1555, 1555, 1555, 1764, 1764,
-     1764, 2999, 1765, 2990, 3008, 1766, 1269, 1269, 1269, 3001,
-     1265, 2938, 1556, 1561, 1561, 1561, 1771, 1771, 1771, 3011,
-     1772, 3012, 2941, 1773, 1271, 1774, 1774, 1774, 3002, 3013,
-     1562, 3006, 1756, 2979, 3015, 1759, 1776, 1776, 1776, 1281,
-     1281, 1281, 1775, 1568, 1568, 1568, 2979, 1782, 1782, 1782,
-     3007, 1783, 1763, 1777, 1784, 3009, 3016, 1283, 3017, 3018,
-     1569, 1785, 1785, 1785, 1571, 1571, 1571, 1768, 1787, 1787,
-     1787, 3019, 1788, 3020, 3010, 1789, 1299, 1299, 1299, 1786,
-     3021, 1572, 1778, 1792, 1792, 1792, 1578, 1578, 1578, 1796,
-
-     1796, 1796, 3022, 1797, 1301, 3023, 1798, 1580, 1580, 1580,
-     1793, 1581, 3033, 1579, 1582, 1779, 1799, 1799, 1799, 1323,
-     1323, 1323, 1591, 1591, 1591, 3034, 1592, 3035, 3036, 1593,
-     1808, 1808, 1808, 1800, 3259, 3259, 3259, 1325, 3259, 3259,
-     3259, 3259, 3259, 3259, 1339, 1339, 1339, 1809, 1815, 1815,
-     1815, 3259, 1790, 3037, 3038, 3259, 3042, 3043, 3259, 1603,
-     1603, 1603, 1341, 1604, 3044, 1816, 1605, 3045, 3046, 1819,
-     1819, 1819, 1354, 1354, 1354, 1362, 1362, 1362, 1371, 1371,
-     1371, 1831, 1831, 1831, 1807, 1811, 1820, 1382, 1382, 1382,
-     1356, 3047, 3048, 1364, 3049, 3051, 1373, 3052, 1832, 1813,
-
-     3053, 1391, 1391, 1391, 1810, 1384, 1619, 1619, 1619, 3054,
-     1620, 1812, 3055, 1621, 1622, 1622, 1622, 3060, 1623, 1393,
-     3061, 1624, 1628, 1628, 1628, 3062, 1629, 1833, 3063, 1630,
-     1633, 1633, 1633, 3064, 1634, 1827, 1822, 1635, 1403, 1403,
-     1403, 1824, 3056, 3065, 1834, 1411, 1411, 1411, 1640, 1640,
-     1640, 3066, 1641, 3058, 3057, 1642, 1405, 1643, 1643, 1643,
-     3067, 1644, 3068, 1413, 1645, 3059, 3069, 1836, 1419, 1419,
-     1419, 1647, 1647, 1647, 3070, 1648, 3071, 3072, 1649, 3073,
-     1652, 1652, 1652, 3075, 1653, 3076, 1421, 1654, 1429, 1429,
-     1429, 1657, 1657, 1657, 1849, 1849, 1849, 3077, 1850, 1841,
-
-     1134, 1851, 1843, 1438, 1438, 1438, 1431, 3078, 1658, 1857,
-     1857, 1857, 1444, 1444, 1444, 1844, 1451, 1451, 1451, 3079,
-     3080, 1440, 1861, 1861, 1861, 3074, 1858, 1459, 1459, 1459,
-     1446, 1671, 1671, 1671, 1453, 1847, 1147, 1147, 1147, 1862,
-     1709, 1709, 1709, 3081, 1710, 1461, 3082, 1711, 3083, 1672,
-     3084, 3085, 1855, 3086, 1149, 1182, 1182, 1182, 1713, 1713,
-     1713, 3087, 1714, 3088, 3089, 1715, 3090, 3091, 1860, 1192,
-     1192, 1192, 3092, 1184, 1720, 1720, 1720, 3093, 1721, 1859,
-     3094, 1722, 1865, 1208, 1208, 1208, 1134, 1194, 1870, 1863,
-     1724, 1724, 1724, 3096, 1725, 3097, 3098, 1726, 3099, 1866,
-
-     3100, 1210, 1730, 1730, 1730, 3095, 1731, 3101, 3102, 1732,
-     1733, 1733, 1733, 3103, 1916, 1916, 1916, 3104, 1917, 3105,
-     1902, 1918, 1899, 1215, 1215, 1215, 3106, 1734, 1925, 1925,
-     1925, 1925, 1925, 1925, 1886, 1886, 1886, 1751, 1751, 1751,
-     3107, 1217, 3108, 3109, 1906, 1931, 1931, 1931, 3110, 1932,
-     3111, 3112, 1933, 3113, 1752, 1753, 1753, 1753, 1134, 1754,
-     3115, 3116, 1755, 1246, 1246, 1246, 1936, 1936, 1936, 1255,
-     1255, 1255, 3117, 3118, 1919, 1760, 1760, 1760, 3114, 1761,
-     3119, 1248, 1762, 1937, 1263, 1263, 1263, 1257, 3120, 1764,
-     1764, 1764, 1926, 1765, 3121, 1887, 1766, 3122, 1926, 1269,
-
-     1269, 1269, 1265, 1940, 1940, 1940, 3123, 1771, 1771, 1771,
-     1934, 1772, 3124, 3125, 1773, 3126, 1938, 1271, 3127, 3128,
-     1941, 1774, 1774, 1774, 1945, 1945, 1945, 3129, 1946, 3130,
-     3131, 1947, 1776, 1776, 1776, 1948, 1948, 1948, 1775, 1949,
-     3132, 3134, 1950, 1952, 1952, 1952, 1954, 1954, 1954, 1777,
-     1939, 1782, 1782, 1782, 1134, 1783, 3135, 3136, 1784, 3137,
-     3133, 1953, 3138, 1942, 1785, 1785, 1785, 1787, 1787, 1787,
-     3139, 1788, 3140, 3141, 1789, 1299, 1299, 1299, 1792, 1792,
-     1792, 3142, 1786, 1958, 1958, 1958, 3143, 1959, 3144, 3145,
-     1960, 1134, 3147, 1301, 3148, 1793, 1961, 1961, 1961, 1796,
-
-     1796, 1796, 3149, 1797, 3150, 3146, 1798, 1799, 1799, 1799,
-     1964, 1964, 1964, 1962, 1965, 3151, 3152, 1966, 1967, 1967,
-     1967, 1956, 3153, 3154, 1800, 1973, 1973, 1973, 1323, 1323,
-     1323, 1808, 1808, 1808, 3156, 1968, 1976, 1976, 1976, 3157,
-     1977, 3158, 1974, 1978, 3159, 3160, 1325, 3161, 1809, 1979,
-     1979, 1979, 3259, 3259, 3259, 1982, 1982, 1982, 1339, 1339,
-     1339, 1815, 1815, 1815, 3162, 3163, 1980, 3166, 3167, 3259,
-     3168, 3169, 1983, 1986, 1986, 1986, 1341, 1987, 1816, 3170,
-     1988, 1989, 1989, 1989, 1819, 1819, 1819, 3171, 1992, 1992,
-     1992, 3182, 1993, 3180, 1975, 1994, 1134, 1134, 1990, 1134,
-
-     3183, 1820, 1996, 1996, 1996, 1362, 1362, 1362, 1134, 1737,
-     1981, 1371, 1371, 1371, 1831, 1831, 1831, 1134, 1984, 1736,
-     1997, 3181, 1729, 1364, 1134, 1134, 2006, 2006, 2006, 1373,
-     2007, 1832, 3172, 2008, 2010, 2010, 2010, 1391, 1391, 1391,
-     2015, 2015, 2015, 2017, 2017, 2017, 3259, 3259, 3259, 1403,
-     1403, 1403, 2011, 3173, 3184, 1393, 1999, 2016, 1134, 2002,
-     2018, 1134, 1134, 3259, 1419, 1419, 1419, 1405, 1411, 1411,
-     1411, 3186, 2024, 2024, 2024, 2026, 2026, 2026, 1429, 1429,
-     1429, 1134, 1421, 1849, 1849, 1849, 1413, 1850, 2013, 2025,
-     1851, 1134, 2027, 1438, 1438, 1438, 1431, 1134, 1857, 1857,
-
-     1857, 2035, 2035, 2035, 3185, 2036, 3174, 1134, 2037, 3175,
-     2019, 1440, 1134, 3198, 2022, 1858, 2020, 1444, 1444, 1444,
-     1451, 1451, 1451, 1861, 1861, 1861, 2040, 2040, 2040, 2023,
-     2041, 1727, 1723, 2042, 1719, 1446, 1717, 1134, 1453, 3176,
-     1862, 3178, 3192, 2028, 2033, 2043, 2043, 2043, 2049, 2049,
-     2049, 1147, 1147, 1147, 2059, 2059, 2059, 1881, 1881, 1881,
-     2066, 2066, 2066, 2044, 1134, 2050, 1886, 1886, 1886, 1149,
-     2067, 2067, 2067, 1134, 3188, 2039, 2038, 1889, 1889, 1889,
-     2070, 2070, 2070, 2071, 2071, 2071, 1897, 1897, 1897, 1182,
-     1182, 1182, 2080, 2080, 2080, 1716, 2083, 2083, 2083, 1208,
-
-     1208, 1208, 2087, 2087, 2087, 1134, 1134, 1184, 3179, 1134,
-     2081, 1708, 2051, 2084, 1916, 1916, 1916, 1210, 1917, 2088,
-     3187, 1918, 1215, 1215, 1215, 2100, 2100, 2100, 1925, 1925,
-     1925, 2107, 2107, 2107, 2109, 2109, 2109, 3199, 1134, 2077,
-     1217, 3193, 2101, 1931, 1931, 1931, 3189, 1932, 1134, 1707,
-     1933, 2110, 1246, 1246, 1246, 2112, 2112, 2112, 2086, 1936,
-     1936, 1936, 2114, 2114, 2114, 1134, 2115, 1134, 2099, 2116,
-     1248, 1134, 2113, 1255, 1255, 1255, 1937, 2118, 2118, 2118,
-     1940, 1940, 1940, 2120, 2120, 2120, 3177, 2121, 1134, 3190,
-     2122, 1257, 1269, 1269, 1269, 2119, 3232, 1941, 1134, 1945,
-
-     1945, 1945, 3196, 1946, 1134, 2111, 1947, 1948, 1948, 1948,
-     1271, 1949, 3191, 3194, 1950, 1952, 1952, 1952, 1954, 1954,
-     1954, 3200, 1299, 1299, 1299, 3197, 2117, 1958, 1958, 1958,
-     1134, 1959, 1134, 1953, 1960, 1961, 1961, 1961, 3201, 2123,
-     1301, 2132, 2132, 2132, 3195, 2133, 1134, 1134, 2134, 1964,
-     1964, 1964, 1962, 1965, 1134, 1134, 1966, 1967, 1967, 1967,
-     2136, 2136, 2136, 1134, 2137, 1705, 3204, 2138, 2139, 2139,
-     2139, 1973, 1973, 1973, 1968, 2144, 2144, 2144, 1134, 2145,
-     2130, 3202, 2146, 1134, 3224, 2140, 3214, 1134, 1974, 1323,
-     1323, 1323, 1976, 1976, 1976, 1134, 1977, 3206, 3203, 1978,
-
-     1979, 1979, 1979, 1134, 2148, 2148, 2148, 1325, 2149, 1134,
-     1134, 2150, 2151, 2151, 2151, 1704, 3256, 1980, 1982, 1982,
-     1982, 2153, 2153, 2153, 3208, 2154, 3207, 1134, 2155, 2152,
-     1339, 1339, 1339, 3209, 1134, 1983, 3212, 1986, 1986, 1986,
-     2147, 1987, 3246, 3205, 1988, 1989, 1989, 1989, 1341, 2158,
-     2158, 2158, 1134, 2159, 3215, 1703, 2160, 1992, 1992, 1992,
-     1134, 1993, 1990, 1134, 1994, 1996, 1996, 1996, 1362, 1362,
-     1362, 2166, 2166, 2166, 1371, 1371, 1371, 2170, 2170, 2170,
-     3220, 2156, 1134, 1997, 1134, 1134, 1364, 3210, 2167, 2006,
-     2006, 2006, 1373, 2007, 2171, 3211, 2008, 2010, 2010, 2010,
-
-     2178, 2178, 2178, 2015, 2015, 2015, 2181, 2181, 2181, 1702,
-     2182, 1134, 3226, 2183, 1134, 2011, 1134, 3213, 2179, 3216,
-     2016, 1134, 3217, 2172, 2017, 2017, 2017, 2184, 2184, 2184,
-     1134, 2185, 2164, 1134, 2186, 2168, 1403, 1403, 1403, 1701,
-     1134, 2018, 1411, 1411, 1411, 1419, 1419, 1419, 2024, 2024,
-     2024, 2192, 2192, 2192, 1405, 2193, 3218, 3221, 2194, 1134,
-     1413, 1700, 3225, 1421, 3252, 2025, 2026, 2026, 2026, 2195,
-     2195, 2195, 3219, 2196, 3228, 1134, 2197, 1429, 1429, 1429,
-     1438, 1438, 1438, 2027, 3227, 2035, 2035, 2035, 1699, 2036,
-     1134, 2190, 2037, 1134, 1134, 1431, 3222, 1134, 1440, 1444,
-
-     1444, 1444, 2188, 1451, 1451, 1451, 1134, 2040, 2040, 2040,
-     2191, 2041, 3223, 1698, 2042, 1697, 1695, 1446, 2043, 2043,
-     2043, 1453, 2049, 2049, 2049, 2211, 2211, 2211, 3229, 2212,
-     3233, 3248, 2213, 1147, 1147, 1147, 2044, 3234, 1134, 2050,
-     1134, 3240, 2198, 3230, 1694, 2203, 2215, 2215, 2215, 1692,
-     2205, 1149, 2220, 2220, 2220, 1691, 2206, 2221, 2221, 2221,
-     2059, 2059, 2059, 2223, 2223, 2223, 2227, 2227, 2227, 2066,
-     2066, 2066, 2067, 2067, 2067, 2228, 2228, 2228, 2070, 2070,
-     2070, 2071, 2071, 2071, 2231, 2231, 2231, 2232, 2232, 2232,
-     2233, 2233, 2233, 2234, 2234, 2234, 1134, 2214, 1182, 1182,
-
-     1182, 2080, 2080, 2080, 3249, 2083, 2083, 2083, 2240, 2240,
-     2240, 1688, 2241, 1134, 1685, 2242, 1184, 1684, 3256, 2081,
-     1683, 2229, 2084, 2244, 2244, 2244, 2087, 2087, 2087, 2246,
-     2246, 2246, 1134, 2247, 1682, 1134, 2248, 1215, 1215, 1215,
-     1134, 2245, 3231, 2088, 2100, 2100, 2100, 1134, 1134, 2236,
-     2260, 2260, 2260, 1134, 2261, 1217, 1681, 2262, 2263, 2263,
-     2263, 2101, 2107, 2107, 2107, 2268, 2268, 2268, 2109, 2109,
-     2109, 2270, 2270, 2270, 1134, 2271, 3238, 3236, 2272, 1246,
-     1246, 1246, 2112, 2112, 2112, 2110, 2259, 2274, 2274, 2274,
-     3237, 2275, 1134, 3242, 2276, 3235, 1680, 1248, 1679, 2113,
-
-     2114, 2114, 2114, 1134, 2115, 1134, 1134, 2116, 1255, 1255,
-     1255, 2269, 1677, 2118, 2118, 2118, 2120, 2120, 2120, 1676,
-     2121, 1134, 3253, 2122, 1675, 1674, 1257, 1269, 1269, 1269,
-     2273, 2119, 1299, 1299, 1299, 2132, 2132, 2132, 3243, 2133,
-     3241, 1667, 2134, 3244, 3239, 1271, 1664, 2136, 2136, 2136,
-     1301, 2137, 1134, 1663, 2138, 2139, 2139, 2139, 3245, 2277,
-     2290, 2290, 2290, 1661, 2291, 1134, 1134, 2292, 1660, 2144,
-     2144, 2144, 2140, 2145, 1659, 1656, 2146, 1323, 1323, 1323,
-     2278, 2148, 2148, 2148, 3247, 2149, 1651, 2287, 2150, 2151,
-     2151, 2151, 2297, 2297, 2297, 1325, 2298, 3250, 3251, 2299,
-
-     2153, 2153, 2153, 1134, 2154, 1650, 2152, 2155, 1339, 1339,
-     1339, 2158, 2158, 2158, 1638, 2159, 1636, 1632, 2160, 2305,
-     2305, 2305, 2166, 2166, 2166, 1631, 1341, 2308, 2308, 2308,
-     1627, 2309, 1625, 1617, 2310, 3254, 1134, 2306, 1616, 2167,
-     1615, 2296, 1371, 1371, 1371, 2170, 2170, 2170, 2313, 2313,
-     2313, 1614, 2314, 1612, 1611, 2315, 1609, 2178, 2178, 2178,
-     1373, 1607, 2171, 2181, 2181, 2181, 1606, 2182, 3255, 1602,
-     2183, 1403, 1403, 1403, 2300, 2179, 2184, 2184, 2184, 1601,
-     2185, 1600, 1599, 2186, 1597, 1411, 1411, 1411, 1596, 1405,
-     1419, 1419, 1419, 2192, 2192, 2192, 1595, 2193, 1594, 1589,
-
-     2194, 1588, 2311, 1413, 1587, 2195, 2195, 2195, 1421, 2196,
-     1586, 1585, 2197, 1429, 1429, 1429, 1584, 2331, 2331, 2331,
-     1583, 1577, 2326, 3259, 3259, 3259, 2329, 3259, 3259, 3259,
-     1576, 1431, 1575, 2330, 2332, 3259, 3259, 3259, 1574, 1567,
-     3259, 1438, 1438, 1438, 3259, 1444, 1444, 1444, 2339, 2339,
-     2339, 2328, 3259, 2341, 2341, 2341, 2344, 2344, 2344, 1440,
-     2211, 2211, 2211, 1446, 2212, 1566, 2340, 2213, 1147, 1147,
-     1147, 1134, 1564, 1563, 2333, 2215, 2215, 2215, 2346, 2346,
-     2346, 2347, 2347, 2347, 1560, 1559, 1149, 2220, 2220, 2220,
-     1550, 2334, 1549, 1545, 2335, 2221, 2221, 2221, 2223, 2223,
-
-     2223, 2351, 2351, 2351, 1544, 2338, 2336, 2352, 2352, 2352,
-     2353, 2353, 2353, 2227, 2227, 2227, 2228, 2228, 2228, 2231,
-     2231, 2231, 2232, 2232, 2232, 1543, 1542, 2345, 2233, 2233,
-     2233, 2234, 2234, 2234, 2357, 2357, 2357, 2360, 2360, 2360,
-     2240, 2240, 2240, 1541, 2241, 1540, 1539, 2242, 3259, 3259,
-     3259, 1538, 2358, 1536, 2361, 2244, 2244, 2244, 1535, 2246,
-     2246, 2246, 1533, 2247, 1532, 3259, 2248, 1215, 1215, 1215,
-     2260, 2260, 2260, 2245, 2261, 2374, 2375, 2262, 2376, 1531,
-     2380, 2381, 1528, 2382, 1526, 1217, 2377, 1523, 1521, 2378,
-     1518, 2383, 1509, 2379, 2384, 2263, 2263, 2263, 2385, 2386,
-
-     2386, 2386, 2268, 2268, 2268, 2270, 2270, 2270, 1507, 2271,
-     1500, 1498, 2272, 1497, 2362, 1246, 1246, 1246, 2274, 2274,
-     2274, 1496, 2275, 1495, 1494, 2276, 1493, 1492, 2373, 2392,
-     2392, 2392, 1491, 1248, 1269, 1269, 1269, 2402, 2402, 2402,
-     1299, 1299, 1299, 1490, 2290, 2290, 2290, 2393, 2291, 1489,
-     1486, 2292, 1271, 2406, 2406, 2406, 1485, 1484, 1301, 1483,
-     1482, 2391, 2410, 2410, 2410, 2297, 2297, 2297, 1481, 2298,
-     2407, 1480, 2299, 2412, 2412, 2412, 2305, 2305, 2305, 1478,
-     2411, 2418, 2418, 2418, 1477, 2394, 2308, 2308, 2308, 1476,
-     2309, 2413, 1475, 2310, 2306, 1371, 1371, 1371, 2419, 1474,
-
-     2403, 2421, 2421, 2421, 2313, 2313, 2313, 1473, 2314, 1472,
-     1470, 2315, 1469, 1373, 3259, 3259, 3259, 1468, 2422, 3259,
-     3259, 3259, 3259, 3259, 3259, 2432, 2432, 2432, 2436, 2436,
-     2436, 3259, 2434, 2434, 2434, 1467, 3259, 1466, 1465, 3259,
-     1411, 1411, 1411, 1464, 1134, 2437, 2420, 2423, 1458, 1443,
-     2435, 1442, 1419, 1419, 1419, 2331, 2331, 2331, 1413, 1429,
-     1429, 1429, 1437, 1436, 2441, 2441, 2441, 1435, 2442, 2424,
-     1421, 2443, 2332, 2430, 2444, 2444, 2444, 1431, 1434, 1433,
-     2425, 3259, 3259, 3259, 3259, 3259, 3259, 2448, 2448, 2448,
-     1407, 2445, 2450, 2450, 2450, 1395, 2440, 1381, 3259, 1380,
-
-     2438, 3259, 1444, 1444, 1444, 2449, 2339, 2339, 2339, 2341,
-     2341, 2341, 1379, 2439, 2344, 2344, 2344, 2346, 2346, 2346,
-     1446, 2455, 2455, 2455, 2340, 1375, 1370, 1134, 2347, 2347,
-     2347, 1366, 2446, 1358, 1353, 2447, 2459, 2459, 2459, 2456,
-     2351, 2351, 2351, 2352, 2352, 2352, 2353, 2353, 2353, 2357,
-     2357, 2357, 2360, 2360, 2360, 2464, 2464, 2464, 1352, 2465,
-     1346, 1343, 2466, 1215, 1215, 1215, 1322, 2358, 2451, 2361,
-     1321, 2452, 2386, 2386, 2386, 2495, 2495, 2495, 1246, 1246,
-     1246, 1217, 2392, 2392, 2392, 2498, 2498, 2498, 2504, 2504,
-     2504, 2402, 2402, 2402, 1320, 1319, 1248, 1299, 1299, 1299,
-
-     2393, 1318, 1317, 2499, 1316, 2505, 1310, 2406, 2406, 2406,
-     2509, 2509, 2509, 1303, 2510, 1301, 1292, 2511, 2513, 2513,
-     2513, 1287, 1286, 2478, 2407, 2410, 2410, 2410, 2412, 2412,
-     2412, 2517, 2517, 2517, 1285, 2514, 2418, 2418, 2418, 1280,
-     2523, 2523, 2523, 2411, 2497, 1279, 2413, 1275, 2518, 2421,
-     2421, 2421, 1274, 2419, 2506, 2520, 2520, 2520, 2524, 2521,
-     1273, 1268, 2522, 2525, 2525, 2525, 2422, 2526, 1267, 1262,
-     2527, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     2533, 2533, 2533, 2432, 2432, 2432, 1254, 1250, 3259, 1245,
-     1244, 3259, 1240, 1239, 3259, 1238, 1237, 2534, 2434, 2434,
-
-     2434, 2436, 2436, 2436, 2537, 2537, 2537, 1236, 2538, 1235,
-     1234, 2539, 2540, 2540, 2540, 1233, 2435, 1232, 2437, 1419,
-     1419, 1419, 1231, 2528, 1429, 1429, 1429, 2441, 2441, 2441,
-     2541, 2442, 2529, 1230, 2443, 2530, 1229, 1421, 2444, 2444,
-     2444, 1228, 1431, 2544, 2544, 2544, 1222, 2545, 1214, 1213,
-     2546, 2547, 2547, 2547, 1212, 2445, 2549, 2549, 2549, 2448,
-     2448, 2448, 2450, 2450, 2450, 2551, 2551, 2551, 2548, 2455,
-     2455, 2455, 1207, 2550, 2459, 2459, 2459, 2449, 2561, 2561,
-     2561, 1206, 1205, 2552, 1202, 1196, 2542, 2456, 2543, 2464,
-     2464, 2464, 1191, 2465, 1190, 2562, 2466, 1215, 1215, 1215,
-
-     2495, 2495, 2495, 1246, 1246, 1246, 2498, 2498, 2498, 2600,
-     2600, 2600, 2504, 2504, 2504, 1217, 2602, 2602, 2602, 1186,
-     2603, 1248, 1181, 2604, 2499, 1180, 2601, 1179, 1178, 2505,
-     2605, 2605, 2605, 2509, 2509, 2509, 1177, 2510, 1176, 1175,
-     2511, 2513, 2513, 2513, 1173, 2610, 2610, 2610, 2606, 2611,
-     1172, 1171, 2612, 2614, 2614, 2614, 1170, 2580, 2514, 2517,
-     2517, 2517, 2616, 2616, 2616, 1169, 2617, 1168, 1167, 2618,
-     2615, 2619, 2619, 2619, 2598, 1166, 2518, 2520, 2520, 2520,
-     1165, 2521, 1164, 1163, 2522, 2523, 2523, 2523, 2620, 2525,
-     2525, 2525, 1162, 2526, 1161, 1160, 2527, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 2524, 3259, 3259, 3259, 2533, 2533, 2533,
-     1159, 2624, 2624, 2624, 3259, 2625, 1158, 3259, 2626, 1157,
-     1156, 3259, 1155, 1154, 2534, 2627, 2627, 2627, 2629, 2629,
-     2629, 2537, 2537, 2537, 1153, 2538, 1146, 1145, 2539, 2540,
-     2540, 2540, 2628, 1144, 1143, 2630, 1419, 1419, 1419, 1142,
-     1141, 2622, 2621, 1429, 1429, 1429, 1140, 2541, 1137, 2623,
-     1135, 2544, 2544, 2544, 1421, 2545, 1134, 1132, 2546, 1130,
-     1127, 1431, 2547, 2547, 2547, 2639, 2639, 2639, 1123, 2640,
-     1121, 1120, 2641, 2549, 2549, 2549, 2642, 2642, 2642, 2548,
-     2643, 1119, 1117, 2644, 1116, 2551, 2551, 2551, 1115, 1114,
-
-     2550, 2649, 2649, 2649, 2561, 2561, 2561, 1215, 1215, 1215,
-     1113, 1112, 2637, 2552, 2638, 2653, 2653, 2653, 1110, 2654,
-     1109, 2562, 2655, 1108, 1107, 1217, 2689, 2689, 2689, 1246,
-     1246, 1246, 2692, 2692, 2692, 2600, 2600, 2600, 2695, 2695,
-     2695, 1105, 2696, 1104, 1103, 2697, 1099, 1248, 1098, 2693,
-     1096, 1095, 2601, 2602, 2602, 2602, 1094, 2603, 2673, 1093,
-     2604, 2605, 2605, 2605, 2610, 2610, 2610, 1092, 2611, 1091,
-     1089, 2612, 2614, 2614, 2614, 2649, 2649, 2649, 2694, 2606,
-     2702, 2702, 2702, 1088, 2703, 1087, 1086, 2704, 1084, 2615,
-     1083, 2691, 2616, 2616, 2616, 1082, 2617, 1079, 1078, 2618,
-
-     2619, 2619, 2619, 2705, 2705, 2705, 1076, 2706, 1073, 1072,
-     2707, 3259, 3259, 3259, 2709, 2709, 2709, 2620, 3259, 3259,
-     3259, 1068, 2624, 2624, 2624, 1067, 2625, 1065, 3259, 2626,
-     1064, 2710, 2627, 2627, 2627, 3259, 2712, 2712, 2712, 1063,
-     2713, 1060, 1059, 2714, 2629, 2629, 2629, 1058, 1057, 2628,
-     2715, 2715, 2715, 1055, 2716, 1054, 1053, 2717, 1419, 1419,
-     1419, 2630, 1429, 1429, 1429, 1052, 1051, 2711, 1046, 2708,
-     2639, 2639, 2639, 1044, 2640, 1043, 1421, 2641, 1042, 1041,
-     1431, 2642, 2642, 2642, 1040, 2643, 1039, 1038, 2644, 2732,
-     2732, 2732, 2735, 2735, 2735, 2653, 2653, 2653, 1037, 2654,
-
-     1034, 1031, 2655, 2746, 2746, 2746, 2733, 1672, 1030, 2724,
-     1215, 1215, 1215, 2689, 2689, 2689, 2772, 2772, 2772, 1029,
-     2747, 1246, 1246, 1246, 2692, 2692, 2692, 1023, 1217, 2725,
-     2774, 2774, 2774, 1022, 2775, 1020, 1017, 2776, 1015, 1248,
-     1014, 2693, 2695, 2695, 2695, 1009, 2696, 1008, 1006, 2697,
-     2702, 2702, 2702, 1005, 2703, 1004, 1002, 2704,  999, 2756,
-     2705, 2705, 2705,  997, 2706,  994,  993, 2707, 3259, 3259,
-     3259,  991, 2773, 2709, 2709, 2709, 2783, 2783, 2783,  990,
-     2784,  987,  982, 2785,  981, 3259, 3259, 3259, 3259,  978,
-     2710, 2712, 2712, 2712,  977, 2713,  976,  973, 2714,  972,
-
-     2715, 2715, 2715, 3259, 2716,  970,  967, 2717, 2801, 2801,
-     2801, 1429, 1429, 1429, 2809, 2809, 2809,  965,  964, 2782,
-     2732, 2732, 2732, 2811, 2811, 2811, 2802, 2812,  963, 1431,
-     2813, 2810, 1672, 2814, 2814, 2814,  962, 2733, 1672,  960,
-      959, 1672, 2735, 2735, 2735, 2815, 2815, 2815, 2816, 2816,
-     2816, 2746, 2746, 2746, 2825, 2825, 2825, 2786, 2826,  958,
-      957, 2827, 1215, 1215, 1215, 2845, 2845, 2845, 2747, 2772,
-     2772, 2772, 2846, 2846, 2846,  956,  955, 2803,  952,  951,
-     1217, 2774, 2774, 2774,  950, 2775,  947,  944, 2776,  943,
-     2847, 2851, 2851, 2851, 2854, 2854, 2854, 2783, 2783, 2783,
-
-      941, 2784,  940,  937, 2785, 2856, 2856, 2856, 2852,  934,
-      931, 2855, 2801, 2801, 2801, 1429, 1429, 1429, 2809, 2809,
-     2809,  930, 2857,  922,  921, 2876, 2876, 2876, 2834, 2877,
-     2802,  920, 2878, 1431,  919, 2810, 1672, 2811, 2811, 2811,
-      913, 2812,  912, 1672, 2813, 2814, 2814, 2814, 2815, 2815,
-     2815, 2816, 2816, 2816,  911, 1672, 2825, 2825, 2825,  909,
-     2826,  908,  907, 2827,  906,  905, 2870, 1670, 1670, 1670,
-     1670, 1670, 1670, 1670, 1670, 1670,  904,  899, 1670, 2895,
-     2895, 2895,  896, 1670, 1670, 1670, 1672, 1670, 2845, 2845,
-     2845, 2846, 2846, 2846, 2851, 2851, 2851, 2896, 2908, 2908,
-
-     2908,  898, 2909,  893,  892, 2910, 2854, 2854, 2854, 2847,
-      890, 2852, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670,
-     1670, 1670, 1670, 2855,  888, 1670, 2856, 2856, 2856,  886,
-     1670, 1670, 1670, 1672, 1670, 2912, 2912, 2912,  884, 2913,
-      882,  879, 2914, 2857, 2915, 2915, 2915,  878, 2916,  877,
-      876, 2917, 2930, 2930, 2930, 2895, 2895, 2895,  875, 1670,
-     1670, 2876, 2876, 2876,  873, 2877,  871,  870, 2878,  869,
-     2931,  867,  865, 2896, 2930, 2930, 2930,  864,  862, 1672,
-     1670, 1670, 1670, 1670, 1670, 2942, 1670, 1670, 1670,  860,
-      859, 1670, 2931,  857,  853,  852, 1670, 1670, 1670, 1672,
-
-     1670, 2908, 2908, 2908,  850, 2909,  845,  843, 2910, 2912,
-     2912, 2912,  839, 2913,  838,  837, 2914, 2915, 2915, 2915,
-      835, 2916,  833,  832, 2917, 1670, 1670, 1670, 1670, 1670,
-     1670, 1670, 1670, 1670, 1670, 2942,  831,  829, 1670, 2981,
-     2981, 2981,  827, 1670, 1670, 1670, 1672, 1670, 2992, 2992,
-     2992, 2994, 2994, 2994, 2996, 2996, 2996, 1672, 1673, 3004,
-     3004, 3004, 3014, 3014, 3014, 2993,  826,  824, 2995,  822,
-      821, 2997, 1670, 1670,  820,  819, 3005, 2981, 2981, 2981,
-     1134, 2992, 2992, 2992, 3024, 3024, 3024,  818, 3025,  817,
-      816, 3026, 2994, 2994, 2994, 1672,  814,  812, 2993, 3027,
-
-     3027, 3027,  811, 3028,  808,  807, 3029,  806,  804, 2995,
-     2996, 2996, 2996, 3030, 3030, 3030,  795, 3031,  794,  793,
-     3032, 3004, 3004, 3004, 3014, 3014, 3014, 2997, 1865, 3039,
-     3039, 3039,  790, 3040,  788,  786, 3041,  785, 3005, 3024,
-     3024, 3024, 1134, 3025,  784,  782, 3026, 3027, 3027, 3027,
-      780, 3028,  778,  775, 3029, 3030, 3030, 3030,  774, 3031,
-      773, 3050, 3032, 3039, 3039, 3039,  772, 3040,  771,  769,
-     3041, 3155, 3155, 3155, 3155, 3155, 3155,  767, 3164,  766,
-      764, 3165, 3257, 3257, 3257, 3257, 3257, 3257,  762, 1134,
-      761,  759, 1134,  757,  756,  755,  753,  751,  750,  749,
-
-     3258,  748,  746, 3258,  254,  254,  254,  254,  254,  254,
-      254,  254,  254,  255,  255,  255,  255,  255,  255,  255,
-      255,  255,  260,  260,  260,  260,  260,  260,  260,  260,
-      260,  263,  263,  263,  263,  263,  263,  263,  263,  263,
-      266,  266,  266,  266,  266,  266,  266,  266,  266,  269,
-      269,  269,  269,  269,  269,  269,  269,  269,  276,  276,
-      276,  276,  276,  276,  276,  276,  276,  284,  284,  284,
-      284,  284,  284,  284,  284,  284,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  300,  300,  300,  300,  300,
-      300,  300,  300,  300,  304,  304,  304,  304,  304,  304,
-
-      304,  304,  304,  311,  311,  311,  311,  311,  311,  311,
-      311,  311,  322,  322,  322,  322,  322,  322,  322,  322,
-      322,  330,  330,  330,  330,  330,  330,  330,  330,  330,
-      336,  336,  336,  336,  336,  336,  336,  336,  336,  342,
-      342,  342,  342,  342,  342,  342,  342,  342,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  353,  353,  353,
-      353,  353,  353,  353,  353,  353,  372,  372,  372,  372,
-      372,  372,  372,  372,  372,  379,  379,  379,  379,  379,
-      379,  379,  379,  379,  386,  386,  386,  386,  386,  386,
-      386,  386,  386,  392,  392,  392,  392,  392,  392,  392,
-
-      392,  392,  399,  399,  399,  399,  399,  399,  399,  399,
-      399,  404,  404,  404,  404,  404,  404,  404,  404,  404,
-      410,  410,  410,  410,  410,  410,  410,  410,  410,  415,
-      415,  415,  415,  415,  415,  415,  415,  415,  421,  421,
-      421,  421,  421,  421,  421,  421,  421,  429,  429,  429,
-      429,  429,  429,  429,  429,  429,  437,  437,  437,  437,
-      437,  437,  437,  437,  437,  441,  441,  441,  441,  441,
-      441,  441,  441,  441,  447,  447,  447,  447,  447,  447,
-      447,  447,  447,  453,  453,  453,  453,  453,  453,  453,
-      453,  453,  470,  470,  470,  470,  470,  470,  470,  470,
-
-      470,  476,  476,  476,  476,  476,  476,  476,  476,  476,
-      485,  485,  485,  485,  485,  485,  485,  485,  485,  491,
-      491,  491,  491,  491,  491,  491,  491,  491,  501,  501,
-      501,  501,  501,  501,  501,  501,  501,  507,  507,  507,
-      507,  507,  507,  507,  507,  507,  512,  512,  512,  512,
-      512,  512,  512,  512,  512,  518,  518,  518,  518,  518,
-      518,  518,  518,  518,  524,  524,  524,  524,  524,  524,
-      524,  524,  524,  530,  530,  530,  530,  530,  530,  530,
-      530,  530,  537,  537,  537,  537,  537,  537,  537,  537,
-      537,  544,  544,  544,  544,  544,  544,  544,  544,  544,
-
-      549,  549,  549,  549,  549,  549,  549,  549,  549,  557,
-      557,  557,  557,  557,  557,  557,  557,  557,  563,  563,
-      563,  563,  563,  563,  563,  563,  563,  570,  570,  570,
-      570,  570,  570,  570,  570,  570,  575,  575,  575,  575,
-      575,  575,  575,  575,  575,  581,  581,  581,  581,  581,
-      581,  581,  581,  581,  586,  586,  586,  586,  586,  586,
-      586,  586,  586,  593,  593,  593,  593,  593,  593,  593,
-      593,  593,  599,  599,  599,  599,  599,  599,  599,  599,
-      599,  606,  606,  606,  606,  606,  606,  606,  606,  606,
-      614,  614,  614,  614,  614,  614,  614,  614,  614,  622,
-
-      622,  622,  622,  622,  622,  622,  622,  622,  626,  626,
-      626,  626,  626,  626,  626,  626,  626,  632,  632,  632,
-      632,  632,  632,  632,  632,  632,  636,  636,  636,  636,
-      636,  636,  636,  636,  636,  643,  643,  643,  643,  643,
-      643,  643,  643,  643,  648,  648,  648,  648,  648,  648,
-      648,  648,  648,  668,  668,  668, 3259,  693,  726,  668,
-      695,  695,  695,  725,  723,  721,  695,  699,  699,  699,
-      720,  719,  717,  699,  707,  707,  707,  713,  709,  708,
-      707,  718,  718,  718,  706,  705,  702,  718,  724,  724,
-      724,  701,  700,  698,  724,  747,  747,  747,  697,  696,
-
-      694,  747,  754,  754,  754,  689, 3259,  669,  754,  760,
-      760,  760,  667,  665,  659,  760,  765,  765,  765,  658,
-      659,  658,  765,  770,  770,  770,  657,  656, 3259,  770,
-      779,  779,  779, 3259, 3259, 3259,  779,  783,  783,  783,
-     3259, 3259, 3259,  783,  789,  789,  789, 3259, 3259, 3259,
-      789,  805,  805,  805, 3259, 3259, 3259,  805,  815,  815,
-      815, 3259, 3259, 3259,  815,  825,  825,  825, 3259, 3259,
-     3259,  825,  830,  830,  830, 3259, 3259, 3259,  830,  836,
-      836,  836, 3259, 3259, 3259,  836,  844,  844,  844, 3259,
-     3259, 3259,  844,  851,  851,  851, 3259, 3259, 3259,  851,
-
-      858,  858,  858, 3259, 3259, 3259,  858,  863,  863,  863,
-     3259, 3259, 3259,  863,  868,  868,  868, 3259, 3259, 3259,
-      868,  874,  874,  874, 3259, 3259, 3259,  874,  883,  883,
-      883, 3259, 3259, 3259,  883,  887,  887,  887, 3259, 3259,
-     3259,  887,  891,  891,  891, 3259, 3259, 3259,  891,  895,
-      895,  895,  895,  895,  895,  895, 3259,  895,  668,  668,
-      668, 3259, 3259, 3259,  668,  910, 3259, 3259, 3259,  910,
-      695,  695,  695, 3259, 3259, 3259,  695,  942, 3259, 3259,
-     3259,  942,  699,  699,  699, 3259, 3259, 3259,  699,  949,
-     3259, 3259, 3259,  949,  707,  707,  707, 3259, 3259, 3259,
-
-      707,  961, 3259, 3259, 3259,  961,  718,  718,  718, 3259,
-     3259, 3259,  718,  966, 3259, 3259, 3259,  966,  724,  724,
-      724, 3259, 3259, 3259,  724,  971, 3259, 3259, 3259,  971,
-      747,  747,  747, 3259, 3259, 3259,  747,  992, 3259, 3259,
-     3259,  992,  754,  754,  754, 3259, 3259, 3259,  754,  998,
-     3259, 3259, 3259,  998,  760,  760,  760, 3259, 3259, 3259,
-      760, 1003, 3259, 3259, 3259, 1003,  765,  765,  765, 3259,
-     3259, 3259,  765, 1007, 3259, 3259, 3259, 1007,  770,  770,
-      770, 3259, 3259, 3259,  770, 1016, 3259, 3259, 3259, 1016,
-      779,  779,  779, 3259, 3259, 3259,  779, 1021, 3259, 3259,
-
-     3259, 1021,  783,  783,  783, 3259, 3259, 3259,  783, 1028,
-     3259, 3259, 3259, 1028,  789,  789,  789, 3259, 3259, 3259,
-      789, 1045, 3259, 3259, 3259, 1045,  805,  805,  805, 3259,
-     3259, 3259,  805, 1056, 3259, 3259, 3259, 1056,  815,  815,
-      815, 3259, 3259, 3259,  815, 1066, 3259, 3259, 3259, 1066,
-      825,  825,  825, 3259, 3259, 3259,  825, 1071, 3259, 3259,
-     3259, 1071,  830,  830,  830, 3259, 3259, 3259,  830, 1077,
-     3259, 3259, 3259, 1077,  836,  836,  836, 3259, 3259, 3259,
-      836, 1085, 3259, 3259, 3259, 1085,  844,  844,  844, 3259,
-     3259, 3259,  844, 1090, 3259, 3259, 3259, 1090,  851,  851,
-
-      851, 3259, 3259, 3259,  851, 1097, 3259, 3259, 3259, 1097,
-      858,  858,  858, 3259, 3259, 3259,  858, 1102, 3259, 3259,
-     3259, 1102,  863,  863,  863, 3259, 3259, 3259,  863, 1106,
-     3259, 3259, 3259, 1106,  868,  868,  868, 3259, 3259, 3259,
-      868, 1111, 3259, 3259, 3259, 1111,  874,  874,  874, 3259,
-     3259, 3259,  874, 1118, 3259, 3259, 3259, 1118,  883,  883,
-      883, 3259, 3259, 3259,  883, 1122, 3259, 3259, 3259, 1122,
-      887,  887,  887, 3259, 3259, 3259,  887, 1126, 3259, 3259,
-     3259, 1126,  891,  891,  891, 3259, 3259, 3259,  891, 1131,
-     3259, 3259, 3259, 1131, 1133, 1133, 1133, 1133, 1133, 1133,
-
-     1133, 1133, 1133, 1139, 3259, 3259, 3259, 3259, 1139,  668,
-      668,  668, 3259, 3259, 3259,  668, 1148, 1148, 1148, 1148,
-     3259, 3259, 1148, 1148,  695,  695,  695, 3259, 3259, 3259,
-      695, 1183, 1183, 1183, 1183, 3259, 3259, 1183, 1183,  699,
-      699,  699, 3259, 3259, 3259,  699, 1193, 1193, 1193, 1193,
-     3259, 3259, 1193, 1193,  707,  707,  707, 3259, 3259, 3259,
-      707, 1209, 1209, 1209, 1209, 3259, 3259, 1209, 1209,  718,
-      718,  718, 3259, 3259, 3259,  718, 1216, 1216, 1216, 1216,
-     3259, 3259, 1216, 1216,  724,  724,  724, 3259, 3259, 3259,
-      724, 1224, 1224, 1224, 1224, 3259, 3259, 1224, 1224,  747,
-
-      747,  747, 3259, 3259, 3259,  747, 1247, 1247, 1247, 1247,
-     3259, 3259, 1247, 1247,  754,  754,  754, 3259, 3259, 3259,
-      754, 1256, 1256, 1256, 1256, 3259, 3259, 1256, 1256,  760,
-      760,  760, 3259, 3259, 3259,  760, 1264, 1264, 1264, 1264,
-     3259, 3259, 1264, 1264,  765,  765,  765, 3259, 3259, 3259,
-      765, 1270, 1270, 1270, 1270, 3259, 3259, 1270, 1270,  770,
-      770,  770, 3259, 3259, 3259,  770, 1282, 1282, 1282, 1282,
-     3259, 3259, 1282, 1282,  779,  779,  779, 3259, 3259, 3259,
-      779, 1289, 1289, 1289, 1289, 3259, 3259, 1289, 1289,  783,
-      783,  783, 3259, 3259, 3259,  783, 1300, 1300, 1300, 1300,
-
-     3259, 3259, 1300, 1300,  789,  789,  789, 3259, 3259, 3259,
-      789, 1324, 1324, 1324, 1324, 3259, 3259, 1324, 1324,  805,
-      805,  805,  805, 3259,  805, 3259,  805, 1340, 1340, 1340,
-     1340, 3259, 3259, 1340, 1340,  815,  815,  815, 3259, 3259,
-     3259,  815, 1355, 1355, 1355, 1355, 3259, 3259, 1355, 1355,
-      825,  825,  825, 3259, 3259, 3259,  825, 1363, 1363, 1363,
-     1363, 3259, 3259, 1363, 1363,  830,  830,  830, 3259, 3259,
-     3259,  830, 1372, 1372, 1372, 1372, 3259, 3259, 1372, 1372,
-      836,  836,  836, 3259, 3259, 3259,  836, 1383, 1383, 1383,
-     1383, 3259, 3259, 1383, 1383,  844,  844,  844,  844, 3259,
-
-      844, 3259,  844, 1392, 1392, 1392, 1392, 3259, 3259, 1392,
-     1392,  851,  851,  851,  851, 3259,  851, 3259,  851, 1404,
-     1404, 1404, 1404, 3259, 3259, 1404, 1404,  858,  858,  858,
-     3259, 3259, 3259,  858, 1412, 1412, 1412, 1412, 3259, 3259,
-     1412, 1412,  863,  863,  863,  863, 3259,  863, 3259,  863,
-     1420, 1420, 1420, 1420, 3259, 3259, 1420, 1420,  868,  868,
-      868,  868, 3259,  868, 3259,  868, 1430, 1430, 1430, 1430,
-     3259, 3259, 1430, 1430,  874,  874,  874, 3259, 3259, 3259,
-      874, 1439, 1439, 1439, 1439, 3259, 3259, 1439, 1439,  883,
-      883,  883, 3259, 3259, 3259,  883, 1445, 1445, 1445, 1445,
-
-     3259, 3259, 1445, 1445, 1452, 1452, 1452, 1452, 3259, 3259,
-     1452, 1452,  891,  891,  891, 3259, 3259, 3259,  891, 1460,
-     1460, 1460, 1460, 3259, 3259, 1460, 1460, 1133, 1133, 1133,
-     1133, 1133, 1133, 1133, 1133, 1133, 1139, 3259, 1139, 3259,
-     3259, 1139,  668,  668,  668, 3259, 3259, 3259,  668, 1148,
-     1148, 1148, 1148, 3259, 3259, 1148, 1148,  695,  695,  695,
-      695, 3259,  695, 3259,  695, 1183, 1183, 1183, 1183, 3259,
-     3259, 1183, 1183,  699,  699,  699,  699, 3259,  699, 3259,
-      699, 1193, 1193, 1193, 1193, 3259, 3259, 1193, 1193,  707,
-      707,  707, 3259, 3259, 3259,  707, 1209, 1209, 1209, 1209,
-
-     3259, 3259, 1209, 1209,  718,  718,  718, 3259, 3259, 3259,
-      718, 1216, 1216, 1216, 1216, 3259, 3259, 1216, 1216,  724,
-      724,  724, 3259, 3259, 3259,  724, 1224, 1224, 1224, 1224,
-     3259, 3259, 1224, 1224,  747,  747,  747, 3259, 3259, 3259,
-      747, 1247, 1247, 1247, 1247, 3259, 3259, 1247, 1247,  754,
-      754,  754, 3259, 3259, 3259,  754, 1256, 1256, 1256, 1256,
-     3259, 3259, 1256, 1256,  760,  760,  760,  760, 3259,  760,
-     3259,  760, 1264, 1264, 1264, 1264, 3259, 3259, 1264, 1264,
-      765,  765,  765,  765, 3259,  765, 3259,  765, 1270, 1270,
-     1270, 1270, 3259, 3259, 1270, 1270,  770,  770,  770, 3259,
-
-     3259, 3259,  770, 1282, 1282, 1282, 1282, 3259, 3259, 1282,
-     1282,  779,  779,  779,  779, 3259,  779, 3259,  779, 1289,
-     1289, 1289, 1289, 3259, 3259, 1289, 1289,  783,  783,  783,
-      783, 3259,  783, 3259,  783, 1300, 1300, 1300, 1300, 3259,
-     3259, 1300, 1300,  789,  789,  789, 3259, 3259, 3259,  789,
-     1324, 1324, 1324, 1324, 3259, 3259, 1324, 1324,  805,  805,
-      805, 3259, 3259, 3259,  805, 1340, 1340, 1340, 1340, 3259,
-     3259, 1340, 1340,  815,  815,  815, 3259, 3259, 3259,  815,
-     1355, 1355, 1355, 1355, 3259, 3259, 1355, 1355,  825,  825,
-      825, 3259, 3259, 3259,  825, 1363, 1363, 1363, 1363, 3259,
-
-     3259, 1363, 1363,  830,  830,  830, 3259, 3259, 3259,  830,
-     1372, 1372, 1372, 1372, 3259, 3259, 1372, 1372,  836,  836,
-      836, 3259, 3259, 3259,  836, 1383, 1383, 1383, 1383, 3259,
-     3259, 1383, 1383,  844,  844,  844, 3259, 3259, 3259,  844,
-     1392, 1392, 1392, 1392, 3259, 3259, 1392, 1392,  851,  851,
-      851, 3259, 3259, 3259,  851, 1404, 1404, 1404, 1404, 3259,
-     3259, 1404, 1404,  858,  858,  858, 3259, 3259, 3259,  858,
-     1412, 1412, 1412, 1412, 3259, 3259, 1412, 1412, 1420, 1420,
-     1420, 1420, 3259, 3259, 1420, 1420,  868,  868,  868, 3259,
-     3259, 3259,  868, 1430, 1430, 1430, 1430, 3259, 3259, 1430,
-
-     1430,  874,  874,  874, 3259, 3259, 3259,  874, 1439, 1439,
-     1439, 1439, 3259, 3259, 1439, 1439,  883,  883,  883, 3259,
-     3259, 3259,  883, 1445, 1445, 1445, 1445, 3259, 3259, 1445,
-     1445, 1452, 1452, 1452, 1452, 3259, 3259, 1452, 1452,  891,
-      891,  891, 3259, 3259, 3259,  891, 1460, 1460, 1460, 1460,
-     3259, 3259, 1460, 1460, 1133, 1133, 1133, 1133, 1133, 1133,
-     1133, 1133, 1133, 1670, 1670, 1670, 1670, 1670, 1670, 1670,
-     1670, 1670,  668,  668,  668, 3259, 3259, 3259,  668, 1148,
-     1148, 1148, 1148, 3259, 3259, 1148, 1148, 1183, 1183, 1183,
-     1183, 3259, 3259, 1183, 1183,  699,  699,  699, 3259, 3259,
-
-     3259,  699, 1193, 1193, 1193, 1193, 3259, 3259, 1193, 1193,
-      707,  707,  707, 3259, 3259, 3259,  707, 1209, 1209, 1209,
-     1209, 3259, 3259, 1209, 1209,  718,  718,  718, 3259, 3259,
-     3259,  718, 1216, 1216, 1216, 1216, 3259, 3259, 1216, 1216,
-      724,  724,  724, 3259, 3259, 3259,  724,  747,  747,  747,
-     3259, 3259, 3259,  747, 1247, 1247, 1247, 1247, 3259, 3259,
-     1247, 1247,  754,  754,  754, 3259, 3259, 3259,  754, 1256,
-     1256, 1256, 1256, 3259, 3259, 1256, 1256, 1264, 1264, 1264,
-     1264, 3259, 3259, 1264, 1264,  765,  765,  765, 3259, 3259,
-     3259,  765, 1270, 1270, 1270, 1270, 3259, 3259, 1270, 1270,
-
-      770,  770,  770, 3259, 3259, 3259,  770, 1282, 1282, 1282,
-     1282, 3259, 3259, 1282, 1282, 1289, 1289, 1289, 1289, 3259,
-     3259, 1289, 1289, 1300, 1300, 1300, 1300, 3259, 3259, 1300,
-     1300,  789,  789,  789, 3259, 3259, 3259,  789, 1324, 1324,
-     1324, 1324, 3259, 3259, 1324, 1324,  805,  805,  805,  805,
-     3259,  805, 3259,  805, 1340, 1340, 1340, 1340, 3259, 3259,
-     1340, 1340,  815,  815,  815, 3259, 3259, 3259,  815, 1355,
-     1355, 1355, 1355, 3259, 3259, 1355, 1355,  825,  825,  825,
-     3259, 3259, 3259,  825, 1363, 1363, 1363, 1363, 3259, 3259,
-     1363, 1363,  830,  830,  830, 3259, 3259, 3259,  830, 1372,
-
-     1372, 1372, 1372, 3259, 3259, 1372, 1372,  836,  836,  836,
-     3259, 3259, 3259,  836, 1383, 1383, 1383, 1383, 3259, 3259,
-     1383, 1383,  844,  844,  844, 3259, 3259, 3259,  844, 1392,
-     1392, 1392, 1392, 3259, 3259, 1392, 1392,  851,  851,  851,
-     3259, 3259, 3259,  851, 1404, 1404, 1404, 1404, 3259, 3259,
-     1404, 1404,  858,  858,  858, 3259, 3259, 3259,  858, 1412,
-     1412, 1412, 1412, 3259, 3259, 1412, 1412, 1420, 1420, 1420,
-     1420, 3259, 3259, 1420, 1420,  868,  868,  868, 3259, 3259,
-     3259,  868, 1430, 1430, 1430, 1430, 3259, 3259, 1430, 1430,
-      874,  874,  874, 3259, 3259, 3259,  874, 1439, 1439, 1439,
-
-     1439, 3259, 3259, 1439, 1439,  883,  883,  883,  883, 3259,
-      883, 3259,  883, 1445, 1445, 1445, 1445, 3259, 3259, 1445,
-     1445, 1452, 1452, 1452, 1452, 3259, 3259, 1452, 1452,  891,
-      891,  891,  891, 3259,  891, 3259,  891, 1460, 1460, 1460,
-     1460, 3259, 3259, 1460, 1460, 1133, 1133, 1133, 1133, 1133,
-     1133, 1133, 1133, 1133, 1670, 1670, 1670, 1670, 1670, 1670,
-     1670, 1670, 1670,  668,  668,  668, 3259, 3259, 3259,  668,
-     1148, 1148, 1148, 1148, 3259, 3259, 1148, 1148, 1183, 1183,
-     1183, 1183, 3259, 3259, 1183, 1183,  699,  699,  699, 3259,
-     3259, 3259,  699, 1193, 1193, 1193, 1193, 3259, 3259, 1193,
-
-     1193,  707,  707,  707, 3259, 3259, 3259,  707, 1209, 1209,
-     1209, 1209, 3259, 3259, 1209, 1209,  718,  718,  718, 3259,
-     3259, 3259,  718, 1216, 1216, 1216, 1216, 3259, 3259, 1216,
-     1216,  724,  724,  724, 3259, 3259, 3259,  724,  747,  747,
-      747, 3259, 3259, 3259,  747, 1247, 1247, 1247, 1247, 3259,
-     3259, 1247, 1247,  754,  754,  754, 3259, 3259, 3259,  754,
-     1256, 1256, 1256, 1256, 3259, 3259, 1256, 1256, 1264, 1264,
-     1264, 1264, 3259, 3259, 1264, 1264,  765,  765,  765,  765,
-     3259,  765, 3259,  765, 1270, 1270, 1270, 1270, 3259, 3259,
-     1270, 1270,  770,  770,  770, 3259, 3259, 3259,  770, 1282,
-
-     1282, 1282, 1282, 3259, 3259, 1282, 1282, 1300, 1300, 1300,
-     1300, 3259, 3259, 1300, 1300,  789,  789,  789, 3259, 3259,
-     3259,  789, 1324, 1324, 1324, 1324, 3259, 3259, 1324, 1324,
-      805,  805,  805,  805, 3259,  805, 3259,  805, 1340, 1340,
-     1340, 1340, 3259, 3259, 1340, 1340,  815,  815,  815, 3259,
-     3259, 3259,  815, 1355, 1355, 1355, 1355, 3259, 3259, 1355,
-     1355,  825,  825,  825, 3259, 3259, 3259,  825, 1363, 1363,
-     1363, 1363, 3259, 3259, 1363, 1363,  830,  830,  830, 3259,
-     3259, 3259,  830, 1372, 1372, 1372, 1372, 3259, 3259, 1372,
-     1372,  836,  836,  836, 3259, 3259, 3259,  836, 1383, 1383,
-
-     1383, 1383, 3259, 3259, 1383, 1383,  844,  844,  844, 3259,
-     3259, 3259,  844, 1392, 1392, 1392, 1392, 3259, 3259, 1392,
-     1392,  851,  851,  851,  851, 3259,  851, 3259,  851, 1404,
-     1404, 1404, 1404, 3259, 3259, 1404, 1404,  858,  858,  858,
-     3259, 3259, 3259,  858, 1412, 1412, 1412, 1412, 3259, 3259,
-     1412, 1412, 1420, 1420, 1420, 1420, 3259, 3259, 1420, 1420,
-      868,  868,  868,  868, 3259,  868, 3259,  868, 1430, 1430,
-     1430, 1430, 3259, 3259, 1430, 1430,  874,  874,  874, 3259,
-     3259, 3259,  874, 1439, 1439, 1439, 1439, 3259, 3259, 1439,
-     1439, 1445, 1445, 1445, 1445, 3259, 3259, 1445, 1445, 1452,
-
-     1452, 1452, 1452, 3259, 3259, 1452, 1452, 1460, 1460, 1460,
-     1460, 3259, 3259, 1460, 1460, 1133, 1133, 1133, 1133, 1133,
-     1133, 1133, 1133, 1133, 1670, 1670, 1670, 1670, 1670, 1670,
-     1670, 1670, 1670,  668,  668,  668,  668, 3259,  668, 3259,
-      668, 1148, 1148, 1148, 1148, 3259, 3259, 1148, 1148, 1183,
-     1183, 1183, 1183, 3259, 3259, 1183, 1183,  699,  699,  699,
-     3259, 3259, 3259,  699, 1193, 1193, 1193, 1193, 3259, 3259,
-     1193, 1193,  707,  707,  707, 3259, 3259, 3259,  707, 1209,
-     1209, 1209, 1209, 3259, 3259, 1209, 1209,  718,  718,  718,
-      718, 3259,  718, 3259,  718, 1216, 1216, 1216, 1216, 3259,
-
-     3259, 1216, 1216,  724,  724,  724,  724, 3259,  724, 3259,
-      724,  747,  747,  747,  747, 3259,  747, 3259,  747, 1247,
-     1247, 1247, 1247, 3259, 3259, 1247, 1247,  754,  754,  754,
-      754, 3259,  754, 3259,  754, 1256, 1256, 1256, 1256, 3259,
-     3259, 1256, 1256, 1264, 1264, 1264, 1264, 3259, 3259, 1264,
-     1264, 1270, 1270, 1270, 1270, 3259, 3259, 1270, 1270,  770,
-      770,  770, 3259, 3259, 3259,  770, 1300, 1300, 1300, 1300,
-     3259, 3259, 1300, 1300,  789,  789,  789, 3259, 3259, 3259,
-      789, 1324, 1324, 1324, 1324, 3259, 3259, 1324, 1324,  805,
-      805,  805,  805, 3259,  805, 3259,  805, 1340, 1340, 1340,
-
-     1340, 3259, 3259, 1340, 1340,  815,  815,  815, 3259, 3259,
-     3259,  815,  825,  825,  825, 3259, 3259, 3259,  825, 1363,
-     1363, 1363, 1363, 3259, 3259, 1363, 1363,  830,  830,  830,
-     3259, 3259, 3259,  830, 1372, 1372, 1372, 1372, 3259, 3259,
-     1372, 1372,  836,  836,  836, 3259, 3259, 3259,  836,  844,
-      844,  844, 3259, 3259, 3259,  844, 1392, 1392, 1392, 1392,
-     3259, 3259, 1392, 1392,  851,  851,  851, 3259, 3259, 3259,
-      851, 1404, 1404, 1404, 1404, 3259, 3259, 1404, 1404,  858,
-      858,  858, 3259, 3259, 3259,  858, 1412, 1412, 1412, 1412,
-     3259, 3259, 1412, 1412, 1420, 1420, 1420, 1420, 3259, 3259,
-
-     1420, 1420, 1430, 1430, 1430, 1430, 3259, 3259, 1430, 1430,
-      874,  874,  874, 3259, 3259, 3259,  874, 1439, 1439, 1439,
-     1439, 3259, 3259, 1439, 1439, 1445, 1445, 1445, 1445, 3259,
-     3259, 1445, 1445, 1452, 1452, 1452, 1452, 3259, 3259, 1452,
-     1452, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133,
-     1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1148,
-     1148, 1148, 1148, 3259, 3259, 1148, 1148, 1183, 1183, 1183,
-     1183, 3259, 3259, 1183, 1183,  699,  699,  699, 3259, 3259,
-     3259,  699,  707,  707,  707, 3259, 3259, 3259,  707, 1209,
-     1209, 1209, 1209, 3259, 3259, 1209, 1209, 1216, 1216, 1216,
-
-     1216, 3259, 3259, 1216, 1216, 1247, 1247, 1247, 1247, 3259,
-     3259, 1247, 1247, 1256, 1256, 1256, 1256, 3259, 3259, 1256,
-     1256, 1270, 1270, 1270, 1270, 3259, 3259, 1270, 1270,  770,
-      770,  770, 3259, 3259, 3259,  770, 1300, 1300, 1300, 1300,
-     3259, 3259, 1300, 1300,  789,  789,  789, 3259, 3259, 3259,
-      789, 1324, 1324, 1324, 1324, 3259, 3259, 1324, 1324, 1340,
-     1340, 1340, 1340, 3259, 3259, 1340, 1340,  815,  815,  815,
-     3259, 3259, 3259,  815,  825,  825,  825, 3259, 3259, 3259,
-      825, 1363, 1363, 1363, 1363, 3259, 3259, 1363, 1363,  830,
-      830,  830, 3259, 3259, 3259,  830, 1372, 1372, 1372, 1372,
-
-     3259, 3259, 1372, 1372,  836,  836,  836, 3259, 3259, 3259,
-      836,  844,  844,  844, 3259, 3259, 3259,  844,  851,  851,
-      851, 3259, 3259, 3259,  851, 1404, 1404, 1404, 1404, 3259,
-     3259, 1404, 1404,  858,  858,  858, 3259, 3259, 3259,  858,
-     1412, 1412, 1412, 1412, 3259, 3259, 1412, 1412, 1420, 1420,
-     1420, 1420, 3259, 3259, 1420, 1420, 1430, 1430, 1430, 1430,
-     3259, 3259, 1430, 1430,  874,  874,  874,  874, 3259,  874,
-     3259,  874, 1439, 1439, 1439, 1439, 3259, 3259, 1439, 1439,
-     1445, 1445, 1445, 1445, 3259, 3259, 1445, 1445, 1452, 1452,
-     1452, 1452, 3259, 3259, 1452, 1452, 1133, 1133, 1133, 1133,
-
-     1133, 1133, 1133, 1133, 1133, 1670, 1670, 1670, 1670, 1670,
-     1670, 1670, 1670, 1670, 1148, 1148, 1148, 1148, 3259, 3259,
-     1148, 1148, 1183, 1183, 1183, 1183, 3259, 3259, 1183, 1183,
-      699,  699,  699, 3259, 3259, 3259,  699,  707,  707,  707,
-      707, 3259,  707, 3259,  707, 1216, 1216, 1216, 1216, 3259,
-     3259, 1216, 1216, 1247, 1247, 1247, 1247, 3259, 3259, 1247,
-     1247, 1256, 1256, 1256, 1256, 3259, 3259, 1256, 1256, 1270,
-     1270, 1270, 1270, 3259, 3259, 1270, 1270,  770,  770,  770,
-     3259, 3259, 3259,  770, 1300, 1300, 1300, 1300, 3259, 3259,
-     1300, 1300,  789,  789,  789, 3259, 3259, 3259,  789, 1324,
-
-     1324, 1324, 1324, 3259, 3259, 1324, 1324, 1340, 1340, 1340,
-     1340, 3259, 3259, 1340, 1340,  815,  815,  815, 3259, 3259,
-     3259,  815,  825,  825,  825, 3259, 3259, 3259,  825,  830,
-      830,  830,  830, 3259,  830, 3259,  830, 1372, 1372, 1372,
-     1372, 3259, 3259, 1372, 1372,  836,  836,  836,  836, 3259,
-      836, 3259,  836,  844,  844,  844, 3259, 3259, 3259,  844,
-      851,  851,  851, 3259, 3259, 3259,  851, 1404, 1404, 1404,
-     1404, 3259, 3259, 1404, 1404,  858,  858,  858,  858, 3259,
-      858, 3259,  858, 1412, 1412, 1412, 1412, 3259, 3259, 1412,
-     1412, 1420, 1420, 1420, 1420, 3259, 3259, 1420, 1420, 1430,
-
-     1430, 1430, 1430, 3259, 3259, 1430, 1430,  874,  874,  874,
-      874, 3259,  874, 3259,  874, 1439, 1439, 1439, 1439, 3259,
-     3259, 1439, 1439, 1445, 1445, 1445, 1445, 3259, 3259, 1445,
-     1445, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133,
-     1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, 1148,
-     1148, 1148, 1148, 3259, 3259, 1148, 1148,  699,  699,  699,
-     3259, 3259, 3259,  699,  707,  707,  707, 3259, 3259, 3259,
-      707, 1216, 1216, 1216, 1216, 3259, 3259, 1216, 1216, 1247,
-     1247, 1247, 1247, 3259, 3259, 1247, 1247, 1270, 1270, 1270,
-     1270, 3259, 3259, 1270, 1270,  770,  770,  770, 3259, 3259,
-
-     3259,  770, 1300, 1300, 1300, 1300, 3259, 3259, 1300, 1300,
-      789,  789,  789, 3259, 3259, 3259,  789, 2879, 2879, 2879,
-     2879, 2879, 2879, 2879, 2879, 2879, 2880, 2880, 2880, 2880,
-     2880, 2880, 2880, 2880, 2880, 2937, 2937, 2937, 2937, 2937,
-     2937, 2937, 2937, 2937, 2940, 2940, 2940, 2940, 2940, 2940,
-     2940, 2940, 2940, 2978, 2978, 2978, 2978, 2978, 2978, 2978,
-     2978, 2978, 2980, 2980, 2980, 2980, 2980, 2980, 2980, 2980,
-     2980,  253, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259
+     1400,  640,  644,  640,  645,  640, 2576, 1409, 1409, 1409,
+     2575, 2592, 1404, 2593, 2594, 1104, 1104, 1104, 1417, 1417,
+
+     1417, 1417, 1417, 1417, 1408, 1411, 2577, 1405, 2595, 2596,
+      640,  640, 1105, 1421, 1421, 1421, 1419, 2597, 2598, 1419,
+     2599,  646, 2600, 2601, 1412, 2603, 1423, 1423, 1423, 2604,
+     1422, 1425, 1425, 1425,  647,  655, 1425, 1425, 1425, 1435,
+     1435, 1435,  670, 1424, 1429, 1429, 1429, 2605, 2606, 1427,
+     2607,  654,  671, 2608, 1427, 2609, 1420, 1437, 3298, 3298,
+     3298, 1430, 1751, 1751, 1751, 1433, 1433, 1433, 2610, 2611,
+     1435, 1435, 1435, 2612, 2613, 3298, 1128, 1128, 1128,  672,
+      673,  674, 1434, 2614, 2615,  675,  676,  677, 1437, 2616,
+      678,  679, 2617, 1129,  680, 2618,  681,  682,  683,  655,
+
+     1444, 1444, 1444, 1444, 1444, 1444,  727, 1428, 1431, 1450,
+     1450, 1450, 1450, 1450, 1450,  654,  728, 2619, 1446, 2585,
+     2621, 1446, 2629, 1432, 1454, 1454, 1454, 1452, 1455, 2586,
+     1452, 1456, 2587, 2630, 1457, 1457, 1457, 2631, 1457, 1457,
+     1457, 1438, 2634,  672,  729,  684, 1132, 1132, 1132,  730,
+      731,  677, 1459, 2635,  732,  679, 1459, 2639,  733, 2657,
+      734,  735,  683, 1133, 1461, 1461, 1461, 1447, 1462, 2658,
+     2674, 1463, 1465, 1465, 1465, 2659, 1453, 1465, 1465, 1465,
+     1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1151, 1680,
+     1467, 1507, 1507, 1507, 2676, 1467, 2677, 1138, 1153, 1460,
+
+     2678, 1153, 2682, 2683, 1153, 1186, 1186, 1186, 1508, 1186,
+     1186, 1186, 1186, 1186, 1186, 1510, 1510, 1510, 1191, 1191,
+     1191, 2686, 1192, 1188, 2687, 1193, 2671, 1188, 2690, 1680,
+     1188, 2672, 1511, 1477, 3298, 3298, 3298, 1196, 1196, 1196,
+     2691, 1468, 1196, 1196, 1196, 1196, 1196, 1196, 1204, 1204,
+     1204, 3298, 1201, 1201, 1201, 1198, 1202, 2692, 2693, 1203,
+     1198, 1509, 2694, 1198, 2695, 1205, 1516, 1516, 1516, 2696,
+     1517, 2673, 2684, 1518, 1519, 1519, 1519, 1207, 1207, 1207,
+     1521, 1521, 1521, 2697, 1522, 2685, 2698, 1523, 1525, 1525,
+     1525, 1520, 1514, 2700, 1208, 1512, 1212, 1212, 1212, 1212,
+
+     1212, 1212, 1212, 1212, 1212, 1526, 1530, 1530, 1530, 1219,
+     1219, 1219, 2701, 2702, 1214, 2703, 2704, 1214, 2705, 2706,
+     1214, 2688, 2707, 1531, 1219, 1219, 1219, 1221, 1219, 1219,
+     1219, 1223, 1223, 1223, 2689, 1224, 2708, 2709, 1225, 1227,
+     1227, 1227, 1221, 1227, 1227, 1227, 1221, 1535, 1535, 1535,
+     2588, 1245, 1245, 1245, 2710, 1246, 2711, 1229, 1247, 2712,
+     2589, 1229, 1528, 2590, 2713, 1536, 1552, 1552, 1552, 1250,
+     1250, 1250, 1250, 1250, 1250, 1533, 1250, 1250, 1250, 1259,
+     1259, 1259, 2714, 1553, 1255, 1255, 1255, 1252, 1256, 2716,
+     1252, 1257, 2724, 2725, 1252, 2733, 2734, 1261, 1259, 1259,
+
+     1259, 1259, 1259, 1259, 1263, 1263, 1263, 2751, 1264, 2752,
+     2753, 1265, 1558, 1558, 1558, 2754, 1261, 2755, 2756, 1261,
+     1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1559,
+     1561, 1561, 1561, 3298, 3298, 3298, 2759, 1554, 1269, 1680,
+     2767, 1269, 2769, 2770, 1269, 2771, 2772, 1562, 2773, 2760,
+     3298, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+     2774, 1563, 1557, 1567, 1567, 1567, 1280, 1280, 1280, 1275,
+     1281, 1138, 1275, 1282, 2764, 1275, 1285, 1285, 1285, 2775,
+     1568, 1285, 1285, 1285, 1285, 1285, 1285, 1574, 1574, 1574,
+     1292, 1292, 1292, 1560, 1287, 1292, 1292, 1292, 2776, 1287,
+
+     2777, 2778, 1287, 2781, 1575, 1577, 1577, 1577, 1294, 1292,
+     1292, 1292, 2782, 1294, 1297, 1297, 1297, 2761, 1298, 2763,
+     2783, 1299, 1578, 1564, 1300, 1300, 1300, 1294, 1301, 2784,
+     2762, 1302, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303,
+     1303, 1311, 1311, 1311, 2785, 1312, 2786, 2787, 1313, 1571,
+     1305, 2788, 2790, 1305, 2791, 2792, 1305, 1584, 1584, 1584,
+     1315, 1315, 1315, 2793, 1316, 2794, 2795, 1317, 1318, 1318,
+     1318, 1586, 1586, 1586, 1585, 1587, 1576, 2796, 1588, 1329,
+     1329, 1329, 1329, 1329, 1329, 1319, 1329, 1329, 1329, 1333,
+     1333, 1333, 2660, 1334, 2797, 2798, 1335, 1331, 2799, 2800,
+
+     1331, 2801, 2661, 1579, 1331, 1336, 1336, 1336, 2662, 1337,
+     2802, 2803, 1338, 1339, 1339, 1339, 1599, 1599, 1599, 2804,
+     1600, 2810, 2811, 1601, 1345, 1345, 1345, 1345, 1345, 1345,
+     1340, 1345, 1345, 1345, 1353, 1353, 1353, 2812, 1354, 2819,
+     2820, 1355, 1347, 2834, 2835, 1347, 1356, 1356, 1356, 1347,
+     1611, 1611, 1611, 1598, 1612, 2836, 2837, 1613, 1360, 1360,
+     1360, 2838, 2839, 1357, 1360, 1360, 1360, 1360, 1360, 1360,
+     1365, 1365, 1365, 2826, 1366, 2843, 1362, 1367, 2844, 1606,
+     2845, 2846, 1362, 2827, 2856, 1362, 1368, 1368, 1368, 1368,
+     1368, 1368, 1368, 1368, 1368, 1373, 1373, 1373, 2828, 1374,
+
+     2857, 2858, 1375, 2859, 1370, 2860, 2861, 1370, 2829, 2862,
+     1370, 1377, 1377, 1377, 1377, 1377, 1377, 2863, 1616, 1377,
+     1377, 1377, 2867, 1382, 1382, 1382, 2830, 1383, 2868, 1379,
+     1384, 2832, 1379, 1388, 1388, 1388, 2831, 1379, 1388, 1388,
+     1388, 2833, 1388, 1388, 1388, 1392, 1392, 1392, 1627, 1627,
+     1627, 1390, 1628, 2869, 2870, 1629, 1390, 1138, 2871, 1618,
+     1390, 2872, 1393, 1394, 1394, 1394, 2874, 2875, 1621, 1630,
+     1630, 1630, 2876, 1631, 2877, 2878, 1632, 1397, 1397, 1397,
+     1395, 1397, 1397, 1397, 2879, 1397, 1397, 1397, 1402, 1402,
+     1402, 2847, 1406, 1406, 1406, 1399, 1907, 1907, 1907, 1399,
+
+     2880, 2881, 1626, 1399, 2882, 1403, 1636, 1636, 1636, 1407,
+     1637, 2883, 2887, 1638, 1641, 1641, 1641, 2888, 1642, 2889,
+     2892, 1643, 1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
+     1409, 1414, 1414, 1414, 2897, 1415, 2898, 2899, 1416, 2900,
+     1411, 2901, 1908, 1411, 2902, 2903, 1411, 1417, 1417, 1417,
+     2904, 2905, 1634, 1417, 1417, 1417, 1417, 1417, 1417, 1421,
+     1421, 1421, 1648, 1648, 1648, 1419, 1649, 2906, 2907, 1650,
+     2908, 1419, 2910, 2911, 1419, 2912, 1422, 1423, 1423, 1423,
+     1651, 1651, 1651, 2913, 1652, 1138, 2920, 1653, 1425, 1425,
+     1425, 2921, 1645, 2922, 1424, 1425, 1425, 1425, 2923, 1425,
+
+     1425, 1425, 1429, 1429, 1429, 2924, 1427, 1655, 1655, 1655,
+     2925, 1656, 2926, 1427, 1657, 2927, 1647, 1427, 2928, 1430,
+     1433, 1433, 1433, 1660, 1660, 1660, 2929, 1661, 2914, 2930,
+     1662, 1435, 1435, 1435, 1435, 1435, 1435, 1434, 1435, 1435,
+     1435, 1665, 1665, 1665, 1444, 1444, 1444, 2931, 2932, 1437,
+     2933, 2936, 1437, 1444, 1444, 1444, 1437, 2937, 1666, 2938,
+     2939, 1654, 1446, 1444, 1444, 1444, 1450, 1450, 1450, 2940,
+     2941, 1446, 1450, 1450, 1450, 1450, 1450, 1450, 1454, 1454,
+     1454, 1446, 1455, 2942, 1452, 1456, 1457, 1457, 1457, 2943,
+     1452, 2944, 2945, 1452, 1457, 1457, 1457, 1457, 1457, 1457,
+
+     1663, 1461, 1461, 1461, 1459, 1462, 2946, 2950, 1463, 1465,
+     1465, 1465, 1459, 2957, 2958, 1459, 1465, 1465, 1465, 1465,
+     1465, 1465, 2959, 2960, 1670, 2961, 2962, 1467, 1673, 1679,
+     1679, 1679, 2963, 2964, 1467, 2965, 2966, 1467, 1151, 1151,
+     1151, 1507, 1507, 1507, 1186, 1186, 1186, 1680, 1681, 2967,
+     1510, 1510, 1510, 1535, 1535, 1535, 1153, 1674, 1508, 1717,
+     1717, 1717, 1188, 1718, 2968, 2971, 1719, 1511, 1721, 1721,
+     1721, 1536, 1722, 2972, 2973, 1723, 1196, 1196, 1196, 2974,
+     1676, 1516, 1516, 1516, 1138, 1517, 2982, 2977, 1518, 1519,
+     1519, 1519, 2983, 2984, 1198, 2985, 1728, 1728, 1728, 2977,
+
+     1729, 2978, 1720, 1730, 1686, 2986, 1520, 1521, 1521, 1521,
+     2980, 1522, 2987, 2988, 1523, 1525, 1525, 1525, 2989, 1732,
+     1732, 1732, 2990, 1733, 2991, 1726, 1734, 1212, 1212, 1212,
+     2975, 2992, 1526, 1530, 1530, 1530, 1738, 1738, 1738, 2993,
+     1739, 2994, 2995, 1740, 2996, 1214, 1741, 1741, 1741, 2997,
+     1531, 1219, 1219, 1219, 1759, 1759, 1759, 1552, 1552, 1552,
+     1761, 1761, 1761, 1742, 1762, 2998, 2999, 1763, 3000, 1221,
+     3005, 1760, 3010, 3011, 1553, 3012, 3013, 1736, 1250, 1250,
+     1250, 1259, 1259, 1259, 1558, 1558, 1558, 1768, 1768, 1768,
+     3014, 1769, 3015, 3018, 1770, 3018, 1252, 1138, 3021, 1261,
+
+     1743, 1559, 1267, 1267, 1267, 1561, 1561, 1561, 1772, 1772,
+     1772, 3022, 1773, 1680, 1681, 1774, 1273, 1273, 1273, 3001,
+     1269, 3023, 1562, 1567, 1567, 1567, 1779, 1779, 1779, 3003,
+     1780, 3002, 3006, 1781, 1275, 1782, 1782, 1782, 3016, 3024,
+     1568, 3004, 1764, 3027, 3007, 1767, 1784, 1784, 1784, 1285,
+     1285, 1285, 1783, 1574, 1574, 1574, 3008, 1790, 1790, 1790,
+     3030, 1791, 1771, 1785, 1792, 3039, 3025, 1287, 3009, 2977,
+     1575, 1793, 1793, 1793, 1577, 1577, 1577, 1776, 1795, 1795,
+     1795, 3042, 1796, 2978, 3026, 1797, 1303, 1303, 1303, 1794,
+     3028, 1578, 1786, 1800, 1800, 1800, 1584, 1584, 1584, 1804,
+
+     1804, 1804, 3047, 1805, 1305, 3029, 1806, 1586, 1586, 1586,
+     1801, 1587, 3050, 1585, 1588, 1787, 1809, 1809, 1809, 1329,
+     1329, 1329, 1599, 1599, 1599, 3051, 1600, 3052, 3018, 1601,
+     1818, 1818, 1818, 1810, 3298, 3298, 3298, 1331, 3298, 3298,
+     3298, 3298, 3298, 3298, 1345, 1345, 1345, 1819, 1825, 1825,
+     1825, 3298, 1798, 2977, 3054, 3298, 3018, 3055, 3298, 1611,
+     1611, 1611, 1347, 1612, 2980, 1826, 1613, 3056, 3057, 1829,
+     1829, 1829, 1360, 1360, 1360, 1368, 1368, 1368, 1377, 1377,
+     1377, 1841, 1841, 1841, 1817, 1821, 1830, 1388, 1388, 1388,
+     1362, 3058, 3059, 1370, 3060, 3061, 1379, 3062, 1842, 1823,
+
+     3072, 1397, 1397, 1397, 1820, 1390, 1627, 1627, 1627, 3037,
+     1628, 1822, 3073, 1629, 1630, 1630, 1630, 3074, 1631, 1399,
+     3075, 1632, 1636, 1636, 1636, 3076, 1637, 1843, 3038, 1638,
+     1641, 1641, 1641, 3077, 1642, 1837, 1832, 1643, 1409, 1409,
+     1409, 1834, 3081, 3040, 1844, 1417, 1417, 1417, 1648, 1648,
+     1648, 3082, 1649, 3083, 3084, 1650, 1411, 1651, 1651, 1651,
+     3045, 1652, 3041, 1419, 1653, 3085, 3048, 1846, 1425, 1425,
+     1425, 1655, 1655, 1655, 3086, 1656, 3087, 3088, 1657, 3046,
+     1660, 1660, 1660, 3090, 1661, 3049, 1427, 1662, 1435, 1435,
+     1435, 1665, 1665, 1665, 1859, 1859, 1859, 3091, 1860, 1851,
+
+     3092, 1861, 1853, 1444, 1444, 1444, 1437, 3093, 1666, 1867,
+     1867, 1867, 1450, 1450, 1450, 1854, 1457, 1457, 1457, 3094,
+     3099, 1446, 1871, 1871, 1871, 3100, 1868, 1465, 1465, 1465,
+     1452, 1679, 1679, 1679, 1459, 1857, 1151, 1151, 1151, 1872,
+     1717, 1717, 1717, 3101, 1718, 1467, 3102, 1719, 3103, 1680,
+     3104, 3095, 1865, 3105, 1153, 1186, 1186, 1186, 1721, 1721,
+     1721, 3106, 1722, 3096, 3107, 1723, 3108, 3109, 1870, 1196,
+     1196, 1196, 3110, 1188, 1728, 1728, 1728, 3111, 1729, 1869,
+     3112, 1730, 1875, 1212, 1212, 1212, 3097, 1198, 1880, 1873,
+     1732, 1732, 1732, 3114, 1733, 3115, 3116, 1734, 3098, 1876,
+
+     3117, 1214, 1738, 1738, 1738, 3118, 1739, 3119, 3120, 1740,
+     1741, 1741, 1741, 3121, 1926, 1926, 1926, 1138, 1927, 3122,
+     1912, 1928, 1909, 1219, 1219, 1219, 3123, 1742, 1935, 1935,
+     1935, 1935, 1935, 1935, 1896, 1896, 1896, 1759, 1759, 1759,
+     3124, 1221, 3113, 3125, 1916, 1941, 1941, 1941, 3126, 1942,
+     3127, 3128, 1943, 3129, 1760, 1761, 1761, 1761, 3130, 1762,
+     3131, 3132, 1763, 1250, 1250, 1250, 1946, 1946, 1946, 1259,
+     1259, 1259, 3133, 3135, 1929, 1768, 1768, 1768, 1138, 1769,
+     3136, 1252, 1770, 1947, 1267, 1267, 1267, 1261, 3137, 1772,
+     1772, 1772, 1936, 1773, 3138, 1897, 1774, 3134, 1936, 1273,
+
+     1273, 1273, 1269, 1950, 1950, 1950, 3139, 1779, 1779, 1779,
+     1944, 1780, 3140, 3141, 1781, 3142, 1948, 1275, 3143, 3144,
+     1951, 1782, 1782, 1782, 1955, 1955, 1955, 3145, 1956, 3146,
+     3147, 1957, 1784, 1784, 1784, 1958, 1958, 1958, 1783, 1959,
+     3148, 3149, 1960, 1962, 1962, 1962, 1964, 1964, 1964, 1785,
+     1949, 1790, 1790, 1790, 3150, 1791, 3151, 3152, 1792, 3154,
+     3155, 1963, 3156, 1952, 1793, 1793, 1793, 1795, 1795, 1795,
+     3157, 1796, 1138, 3158, 1797, 1303, 1303, 1303, 1800, 1800,
+     1800, 3159, 1794, 1968, 1968, 1968, 3160, 1969, 3161, 3162,
+     1970, 3163, 3153, 1305, 3164, 1801, 1971, 1971, 1971, 1804,
+
+     1804, 1804, 3165, 1805, 3166, 3167, 1806, 1809, 1809, 1809,
+     1976, 1976, 1976, 1972, 1977, 3168, 3169, 1978, 1979, 1979,
+     1979, 1966, 3170, 3171, 1810, 1985, 1985, 1985, 1329, 1329,
+     1329, 1818, 1818, 1818, 3173, 1980, 1988, 1988, 1988, 1138,
+     1989, 3174, 1986, 1990, 3175, 3172, 1331, 3176, 1819, 1991,
+     1991, 1991, 3298, 3298, 3298, 1994, 1994, 1994, 1345, 1345,
+     1345, 1825, 1825, 1825, 3177, 3178, 1992, 3179, 3180, 3298,
+     3181, 3182, 1995, 1998, 1998, 1998, 1347, 1999, 1826, 3183,
+     2000, 2001, 2001, 2001, 1829, 1829, 1829, 3184, 2004, 2004,
+     2004, 3186, 2005, 3187, 1987, 2006, 3188, 3189, 2002, 3190,
+
+     3191, 1830, 2008, 2008, 2008, 1368, 1368, 1368, 1138, 3192,
+     1993, 1377, 1377, 1377, 1841, 1841, 1841, 3193, 1996, 3195,
+     2009, 3196, 3185, 1370, 3197, 3198, 2018, 2018, 2018, 1379,
+     2019, 1842, 3199, 2020, 2022, 2022, 2022, 1397, 1397, 1397,
+     2027, 2027, 2027, 2029, 2029, 2029, 3298, 3298, 3298, 1409,
+     1409, 1409, 2023, 3200, 3201, 1399, 2011, 2028, 3202, 2014,
+     2030, 3205, 3206, 3298, 1425, 1425, 1425, 1411, 1417, 1417,
+     1417, 3207, 2036, 2036, 2036, 2038, 2038, 2038, 1435, 1435,
+     1435, 3208, 1427, 1859, 1859, 1859, 1419, 1860, 2025, 2037,
+     1861, 3209, 2039, 1444, 1444, 1444, 1437, 3210, 1867, 1867,
+
+     1867, 2047, 2047, 2047, 3221, 2048, 1138, 1138, 2049, 3219,
+     2031, 1446, 1138, 1138, 2034, 1868, 2032, 1450, 1450, 1450,
+     1457, 1457, 1457, 1871, 1871, 1871, 2052, 2052, 2052, 2035,
+     2053, 3222, 3220, 2054, 1727, 1452, 1138, 1138, 1459, 1138,
+     1872, 3243, 3211, 2040, 2045, 2055, 2055, 2055, 2061, 2061,
+     2061, 1151, 1151, 1151, 2071, 2071, 2071, 1891, 1891, 1891,
+     2078, 2078, 2078, 2056, 1138, 2062, 1896, 1896, 1896, 1153,
+     2079, 2079, 2079, 3212, 1138, 2051, 2050, 1899, 1899, 1899,
+     2082, 2082, 2082, 2083, 2083, 2083, 1907, 1907, 1907, 1186,
+     1186, 1186, 2092, 2092, 2092, 3295, 2095, 2095, 2095, 1212,
+
+     1212, 1212, 2099, 2099, 2099, 1138, 1138, 1188, 3217, 1138,
+     2093, 3227, 2063, 2096, 1926, 1926, 1926, 1214, 1927, 2100,
+     1138, 1928, 1219, 1219, 1219, 2112, 2112, 2112, 1935, 1935,
+     1935, 2119, 2119, 2119, 2121, 2121, 2121, 1138, 1138, 2089,
+     1221, 1138, 2113, 1941, 1941, 1941, 3228, 1942, 1138, 3218,
+     1943, 2122, 1250, 1250, 1250, 2124, 2124, 2124, 2098, 1946,
+     1946, 1946, 2126, 2126, 2126, 1138, 2127, 3225, 2111, 2128,
+     1252, 3244, 2125, 1259, 1259, 1259, 1947, 2130, 2130, 2130,
+     1950, 1950, 1950, 2132, 2132, 2132, 3213, 2133, 1138, 3214,
+     2134, 1261, 1273, 1273, 1273, 2131, 3215, 1951, 1138, 1955,
+
+     1955, 1955, 1725, 1956, 3223, 2123, 1957, 1958, 1958, 1958,
+     1275, 1959, 1138, 3216, 1960, 1962, 1962, 1962, 1964, 1964,
+     1964, 3251, 1303, 1303, 1303, 1138, 2129, 1968, 1968, 1968,
+     3224, 1969, 1138, 1963, 1970, 1971, 1971, 1971, 1138, 2135,
+     1305, 2144, 2144, 2144, 3233, 2145, 1138, 1138, 2146, 1976,
+     1976, 1976, 1972, 1977, 1138, 1138, 1978, 1979, 1979, 1979,
+     2150, 2150, 2150, 1138, 2151, 1724, 3229, 2152, 2153, 2153,
+     2153, 1985, 1985, 1985, 1980, 2158, 2158, 2158, 3234, 2159,
+     2142, 1138, 2160, 1138, 3235, 2154, 3237, 3230, 1986, 1329,
+     1329, 1329, 1988, 1988, 1988, 1138, 1989, 1138, 1138, 1990,
+
+     1991, 1991, 1991, 3291, 2162, 2162, 2162, 1331, 2163, 1138,
+     3226, 2164, 2165, 2165, 2165, 3238, 3231, 1992, 1994, 1994,
+     1994, 2167, 2167, 2167, 3263, 2168, 1716, 3239, 2169, 2166,
+     1345, 1345, 1345, 3232, 3236, 1995, 1138, 1998, 1998, 1998,
+     2161, 1999, 1138, 3240, 2000, 2001, 2001, 2001, 1347, 2172,
+     2172, 2172, 1138, 2173, 1715, 3247, 2174, 2004, 2004, 2004,
+     1138, 2005, 2002, 1138, 2006, 2008, 2008, 2008, 1368, 1368,
+     1368, 2180, 2180, 2180, 1377, 1377, 1377, 2184, 2184, 2184,
+     1138, 2170, 1138, 2009, 1138, 3245, 1370, 1138, 2181, 2018,
+     2018, 2018, 1379, 2019, 2185, 3241, 2020, 2022, 2022, 2022,
+
+     2192, 2192, 2192, 2027, 2027, 2027, 2195, 2195, 2195, 3248,
+     2196, 1138, 1713, 2197, 3267, 2023, 1138, 3242, 2193, 3249,
+     2028, 1138, 1138, 2186, 2029, 2029, 2029, 2198, 2198, 2198,
+     3246, 2199, 2178, 1712, 2200, 2182, 1409, 1409, 1409, 1138,
+     3264, 2030, 1417, 1417, 1417, 1425, 1425, 1425, 2036, 2036,
+     2036, 2206, 2206, 2206, 1411, 2207, 3250, 1138, 2208, 3255,
+     1419, 1711, 3259, 1427, 1138, 2037, 2038, 2038, 2038, 2209,
+     2209, 2209, 3252, 2210, 1138, 3253, 2211, 1435, 1435, 1435,
+     1444, 1444, 1444, 2039, 1138, 2047, 2047, 2047, 3254, 2048,
+     1138, 2204, 2049, 1138, 3256, 1437, 1138, 1138, 1446, 1450,
+
+     1450, 1450, 2202, 1457, 1457, 1457, 3257, 2052, 2052, 2052,
+     2205, 2053, 1138, 1710, 2054, 1709, 3258, 1452, 2055, 2055,
+     2055, 1459, 2061, 2061, 2061, 2225, 2225, 2225, 3265, 2226,
+     3261, 3266, 2227, 1151, 1151, 1151, 2056, 1138, 3292, 2062,
+     1138, 3295, 2212, 3273, 1708, 2217, 2229, 2229, 2229, 3262,
+     2219, 1153, 2234, 2234, 2234, 1138, 2220, 2235, 2235, 2235,
+     2071, 2071, 2071, 2237, 2237, 2237, 2241, 2241, 2241, 2078,
+     2078, 2078, 2079, 2079, 2079, 2242, 2242, 2242, 2082, 2082,
+     2082, 2083, 2083, 2083, 2245, 2245, 2245, 2246, 2246, 2246,
+     2247, 2247, 2247, 2248, 2248, 2248, 1138, 2228, 1186, 1186,
+
+     1186, 2092, 2092, 2092, 1707, 2095, 2095, 2095, 2254, 2254,
+     2254, 3287, 2255, 1138, 1706, 2256, 1188, 1705, 1703, 2093,
+     1138, 2243, 2096, 2258, 2258, 2258, 2099, 2099, 2099, 2260,
+     2260, 2260, 3271, 2261, 1702, 1700, 2262, 1219, 1219, 1219,
+     1138, 2259, 3260, 2100, 2112, 2112, 2112, 3268, 3272, 2250,
+     2274, 2274, 2274, 1138, 2275, 1221, 1138, 2276, 2277, 2277,
+     2277, 2113, 2119, 2119, 2119, 2282, 2282, 2282, 2121, 2121,
+     2121, 2284, 2284, 2284, 1138, 2285, 1138, 1699, 2286, 1250,
+     1250, 1250, 2124, 2124, 2124, 2122, 2273, 2288, 2288, 2288,
+     3275, 2289, 1138, 1138, 2290, 1696, 1693, 1252, 1138, 2125,
+
+     2126, 2126, 2126, 1138, 2127, 1138, 1138, 2128, 1259, 1259,
+     1259, 2283, 1138, 2130, 2130, 2130, 2132, 2132, 2132, 1138,
+     2133, 3274, 3269, 2134, 1692, 3285, 1261, 1273, 1273, 1273,
+     2287, 2131, 1303, 1303, 1303, 2144, 2144, 2144, 3270, 2145,
+     3276, 3279, 2146, 1138, 3281, 1275, 3277, 2150, 2150, 2150,
+     1305, 2151, 1138, 3278, 2152, 2153, 2153, 2153, 1691, 2291,
+     2306, 2306, 2306, 1138, 2307, 3282, 1138, 2308, 1138, 2158,
+     2158, 2158, 2154, 2159, 1690, 3286, 2160, 1329, 1329, 1329,
+     2292, 2162, 2162, 2162, 3289, 2163, 1689, 2301, 2164, 2165,
+     2165, 2165, 2313, 2313, 2313, 1331, 2314, 1688, 3280, 2315,
+
+     2167, 2167, 2167, 3283, 2168, 3284, 2166, 2169, 1345, 1345,
+     1345, 2172, 2172, 2172, 1687, 2173, 3288, 1685, 2174, 2321,
+     2321, 2321, 2180, 2180, 2180, 1138, 1347, 2324, 2324, 2324,
+     1684, 2325, 1683, 1682, 2326, 1675, 1138, 2322, 1672, 2181,
+     1671, 2312, 1377, 1377, 1377, 2184, 2184, 2184, 2329, 2329,
+     2329, 1669, 2330, 1668, 1667, 2331, 1138, 2192, 2192, 2192,
+     1379, 1664, 2185, 2195, 2195, 2195, 1138, 2196, 3290, 1659,
+     2197, 1409, 1409, 1409, 2316, 2193, 2198, 2198, 2198, 1658,
+     2199, 1646, 1644, 2200, 1640, 1417, 1417, 1417, 3293, 1411,
+     1425, 1425, 1425, 2206, 2206, 2206, 1639, 2207, 3294, 1635,
+
+     2208, 1633, 2327, 1419, 1625, 2209, 2209, 2209, 1427, 2210,
+     1624, 1623, 2211, 1435, 1435, 1435, 1622, 2347, 2347, 2347,
+     1620, 1619, 2342, 3298, 3298, 3298, 2345, 3298, 3298, 3298,
+     1617, 1437, 1615, 2346, 2348, 3298, 3298, 3298, 1614, 1610,
+     3298, 1444, 1444, 1444, 3298, 1450, 1450, 1450, 2355, 2355,
+     2355, 2344, 3298, 2357, 2357, 2357, 2360, 2360, 2360, 1446,
+     2225, 2225, 2225, 1452, 2226, 1609, 2356, 2227, 1151, 1151,
+     1151, 1138, 1608, 1607, 2349, 2229, 2229, 2229, 2362, 2362,
+     2362, 2363, 2363, 2363, 1605, 1604, 1153, 2234, 2234, 2234,
+     1603, 2350, 1602, 1597, 2351, 2235, 2235, 2235, 2237, 2237,
+
+     2237, 2367, 2367, 2367, 1596, 2354, 2352, 2368, 2368, 2368,
+     2369, 2369, 2369, 2241, 2241, 2241, 2242, 2242, 2242, 2245,
+     2245, 2245, 2246, 2246, 2246, 1595, 1594, 2361, 2247, 2247,
+     2247, 2248, 2248, 2248, 2373, 2373, 2373, 2376, 2376, 2376,
+     2254, 2254, 2254, 1593, 2255, 1592, 1591, 2256, 3298, 3298,
+     3298, 1590, 2374, 1589, 2377, 2258, 2258, 2258, 1583, 2260,
+     2260, 2260, 1582, 2261, 1581, 3298, 2262, 1219, 1219, 1219,
+     2274, 2274, 2274, 2259, 2275, 2390, 2391, 2276, 2392, 1580,
+     2396, 2397, 1573, 2398, 1572, 1221, 2393, 1570, 1569, 2394,
+     1566, 2399, 1565, 2395, 2400, 2277, 2277, 2277, 2401, 2402,
+
+     2402, 2402, 2282, 2282, 2282, 2284, 2284, 2284, 1556, 2285,
+     1555, 1551, 2286, 1550, 2378, 1250, 1250, 1250, 2288, 2288,
+     2288, 1549, 2289, 1548, 1547, 2290, 1546, 1545, 2389, 2408,
+     2408, 2408, 1544, 1252, 1273, 1273, 1273, 2418, 2418, 2418,
+     1303, 1303, 1303, 1542, 2306, 2306, 2306, 2409, 2307, 1541,
+     1539, 2308, 1275, 2425, 2425, 2425, 1538, 1537, 1305, 1534,
+     1532, 2407, 2429, 2429, 2429, 2313, 2313, 2313, 1529, 2314,
+     2426, 1527, 2315, 2431, 2431, 2431, 2321, 2321, 2321, 1524,
+     2430, 2437, 2437, 2437, 1515, 2410, 2324, 2324, 2324, 1513,
+     2325, 2432, 1506, 2326, 2322, 1377, 1377, 1377, 2438, 1504,
+
+     2419, 2440, 2440, 2440, 2329, 2329, 2329, 1503, 2330, 1502,
+     1501, 2331, 1500, 1379, 3298, 3298, 3298, 1499, 2441, 3298,
+     3298, 3298, 3298, 3298, 3298, 2451, 2451, 2451, 2455, 2455,
+     2455, 3298, 2453, 2453, 2453, 1498, 3298, 1497, 1496, 3298,
+     1417, 1417, 1417, 1495, 1492, 2456, 2439, 2442, 1491, 1490,
+     2454, 1489, 1425, 1425, 1425, 2347, 2347, 2347, 1419, 1435,
+     1435, 1435, 1488, 1487, 2460, 2460, 2460, 1486, 2461, 2443,
+     1427, 2462, 2348, 2449, 2463, 2463, 2463, 1437, 1484, 1483,
+     2444, 3298, 3298, 3298, 3298, 3298, 3298, 2467, 2467, 2467,
+     1482, 2464, 2469, 2469, 2469, 1481, 2459, 1480, 3298, 1479,
+
+     2457, 3298, 1450, 1450, 1450, 2468, 2355, 2355, 2355, 2357,
+     2357, 2357, 1478, 2458, 2360, 2360, 2360, 2362, 2362, 2362,
+     1452, 2474, 2474, 2474, 2356, 1476, 1475, 1138, 2363, 2363,
+     2363, 1474, 2465, 1473, 1472, 2466, 2478, 2478, 2478, 2475,
+     2367, 2367, 2367, 2368, 2368, 2368, 2369, 2369, 2369, 2373,
+     2373, 2373, 2376, 2376, 2376, 2483, 2483, 2483, 1471, 2484,
+     1470, 1138, 2485, 1219, 1219, 1219, 1464, 2374, 2470, 2377,
+     1449, 2471, 2402, 2402, 2402, 2514, 2514, 2514, 1250, 1250,
+     1250, 1221, 2408, 2408, 2408, 2517, 2517, 2517, 2523, 2523,
+     2523, 2418, 2418, 2418, 1448, 1443, 1252, 1303, 1303, 1303,
+
+     2409, 1442, 1441, 2518, 1440, 2524, 1439, 2425, 2425, 2425,
+     2531, 2531, 2531, 1413, 2532, 1305, 1401, 2533, 2535, 2535,
+     2535, 1387, 1386, 2497, 2426, 2429, 2429, 2429, 2431, 2431,
+     2431, 2539, 2539, 2539, 1385, 2536, 2437, 2437, 2437, 1381,
+     2545, 2545, 2545, 2430, 2516, 1376, 2432, 1372, 2540, 2440,
+     2440, 2440, 1364, 2438, 2525, 2542, 2542, 2542, 2546, 2543,
+     1359, 1358, 2544, 2547, 2547, 2547, 2441, 2548, 1352, 1349,
+     2549, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     2555, 2555, 2555, 2451, 2451, 2451, 1328, 1327, 3298, 1326,
+     1325, 3298, 1324, 1323, 3298, 1322, 1321, 2556, 2453, 2453,
+
+     2453, 2455, 2455, 2455, 2559, 2559, 2559, 1320, 2560, 1314,
+     1307, 2561, 2562, 2562, 2562, 1296, 2454, 1291, 2456, 1425,
+     1425, 1425, 1290, 2550, 1435, 1435, 1435, 2460, 2460, 2460,
+     2563, 2461, 2551, 1289, 2462, 2552, 1284, 1427, 2463, 2463,
+     2463, 1283, 1437, 2566, 2566, 2566, 1279, 2567, 1278, 1277,
+     2568, 2569, 2569, 2569, 1272, 2464, 2571, 2571, 2571, 2467,
+     2467, 2467, 2469, 2469, 2469, 2573, 2573, 2573, 2570, 2474,
+     2474, 2474, 1271, 2572, 2478, 2478, 2478, 2468, 2583, 2583,
+     2583, 1266, 1258, 2574, 1254, 1249, 2564, 2475, 2565, 2483,
+     2483, 2483, 1248, 2484, 1244, 2584, 2485, 1219, 1219, 1219,
+
+     2514, 2514, 2514, 1250, 1250, 1250, 2517, 2517, 2517, 2622,
+     2622, 2622, 2523, 2523, 2523, 1221, 2624, 2624, 2624, 1243,
+     2625, 1252, 1242, 2626, 2518, 1241, 2623, 1240, 1239, 2524,
+     2627, 2627, 2627, 2632, 2632, 2632, 2531, 2531, 2531, 1238,
+     2532, 1237, 1236, 2533, 2535, 2535, 2535, 1235, 2628, 1234,
+     2633, 2636, 2636, 2636, 1233, 2637, 1232, 2602, 2638, 1226,
+     1218, 2536, 2640, 2640, 2640, 2539, 2539, 2539, 2642, 2642,
+     2642, 1217, 2643, 1216, 2620, 2644, 2645, 2645, 2645, 2641,
+     1211, 1210, 2540, 2542, 2542, 2542, 1209, 2543, 1206, 1200,
+     2544, 1195, 1194, 2646, 2545, 2545, 2545, 2547, 2547, 2547,
+
+     1190, 2548, 1185, 1184, 2549, 3298, 3298, 3298, 3298, 3298,
+     3298, 1183, 2546, 3298, 3298, 3298, 2555, 2555, 2555, 2650,
+     2650, 2650, 3298, 2651, 1182, 3298, 2652, 2653, 2653, 2653,
+     3298, 1181, 1180, 2556, 2655, 2655, 2655, 1179, 2559, 2559,
+     2559, 1177, 2560, 1176, 2654, 2561, 2562, 2562, 2562, 1175,
+     1174, 2656, 1425, 1425, 1425, 1435, 1435, 1435, 1173, 2648,
+     2647, 2569, 2569, 2569, 2563, 2566, 2566, 2566, 2649, 2567,
+     1427, 1172, 2568, 1437, 1171, 2665, 2665, 2665, 2570, 2666,
+     1170, 1169, 2667, 2571, 2571, 2571, 2668, 2668, 2668, 1168,
+     2669, 1167, 1166, 2670, 2573, 2573, 2573, 2675, 2675, 2675,
+
+     2572, 1165, 2583, 2583, 2583, 1164, 2679, 2679, 2679, 1163,
+     2680, 1162, 2574, 2681, 1161, 1160, 2664, 1159, 2663, 2584,
+     1219, 1219, 1219, 2715, 2715, 2715, 1250, 1250, 1250, 2718,
+     2718, 2718, 2622, 2622, 2622, 2721, 2721, 2721, 1221, 2722,
+     1158, 1157, 2723, 1150, 1252, 1149, 2719, 1148, 1147, 2623,
+     2624, 2624, 2624, 1146, 2625, 1145, 1144, 2626, 2627, 2627,
+     2627, 2726, 2726, 2726, 2632, 2632, 2632, 1141, 2731, 2731,
+     2731, 2699, 2675, 2675, 2675, 2720, 2628, 1139, 2727, 1138,
+     1136, 2633, 2728, 2728, 2728, 2732, 2729, 1134, 2717, 2730,
+     2636, 2636, 2636, 1131, 2637, 1127, 1125, 2638, 2640, 2640,
+
+     2640, 2735, 2735, 2735, 1124, 2736, 1123, 1121, 2737, 2642,
+     2642, 2642, 1120, 2643, 1119, 2641, 2644, 2645, 2645, 2645,
+     2738, 2738, 2738, 1118, 2739, 1117, 1116, 2740, 3298, 3298,
+     3298, 2742, 2742, 2742, 2646, 3298, 3298, 3298, 1114, 2650,
+     2650, 2650, 1113, 2651, 1112, 3298, 2652, 1111, 2743, 2653,
+     2653, 2653, 3298, 2745, 2745, 2745, 1109, 2746, 1108, 1107,
+     2747, 2655, 2655, 2655, 1103, 1102, 2654, 2748, 2748, 2748,
+     1100, 2749, 1099, 1098, 2750, 1425, 1425, 1425, 2656, 1435,
+     1435, 1435, 1097, 1096, 2744, 1095, 2741, 2665, 2665, 2665,
+     1093, 2666, 1092, 1427, 2667, 1091, 1090, 1437, 2668, 2668,
+
+     2668, 1088, 2669, 1087, 1086, 2670, 2765, 2765, 2765, 2768,
+     2768, 2768, 2679, 2679, 2679, 1083, 2680, 1082, 1080, 2681,
+     2779, 2779, 2779, 2766, 1680, 1077, 2757, 1219, 1219, 1219,
+     2715, 2715, 2715, 2805, 2805, 2805, 1076, 2780, 1250, 1250,
+     1250, 2718, 2718, 2718, 1072, 1221, 2758, 2807, 2807, 2807,
+     1071, 2808, 1069, 1068, 2809, 1067, 1252, 1064, 2719, 2721,
+     2721, 2721, 1063, 2722, 1062, 1061, 2723, 2726, 2726, 2726,
+     2813, 2813, 2813, 1059, 2814, 1058, 2789, 2815, 2728, 2728,
+     2728, 1057, 2729, 1056, 2727, 2730, 2731, 2731, 2731, 2806,
+     2816, 2816, 2816, 1055, 2817, 1050, 1048, 2818, 2735, 2735,
+
+     2735, 1047, 2736, 2732, 1046, 2737, 2738, 2738, 2738, 1045,
+     2739, 1044, 1043, 2740, 3298, 3298, 3298, 2742, 2742, 2742,
+     2822, 2822, 2822, 1042, 2823, 1041, 1040, 2824, 3298, 3298,
+     3298, 3298, 1039, 1036, 2743, 2745, 2745, 2745, 1033, 2746,
+     1032, 1031, 2747, 1025, 1024, 3298, 2748, 2748, 2748, 1022,
+     2749, 1019, 1017, 2750, 2840, 2840, 2840, 1435, 1435, 1435,
+     2848, 2848, 2848, 1016, 1011, 2821, 2765, 2765, 2765, 2850,
+     2850, 2850, 2841, 2851, 1010, 1437, 2852, 2849, 1680, 2853,
+     2853, 2853, 1008, 2766, 1680, 1007, 1006, 1680, 2768, 2768,
+     2768, 2854, 2854, 2854, 2855, 2855, 2855, 1004, 1001, 2825,
+
+     2779, 2779, 2779, 2864, 2864, 2864,  999, 2865,  996,  995,
+     2866, 1219, 1219, 1219, 2884, 2884, 2884, 2780, 2805, 2805,
+     2805,  993,  992, 2842, 2885, 2885, 2885,  989,  984, 1221,
+     2807, 2807, 2807,  983, 2808,  980,  979, 2809,  978, 2813,
+     2813, 2813, 2886, 2814,  975,  974, 2815, 2816, 2816, 2816,
+      972, 2817,  969,  967, 2818, 2890, 2890, 2890, 2893, 2893,
+     2893, 2822, 2822, 2822,  966, 2823,  965,  964, 2824, 2895,
+     2895, 2895, 2891,  962,  961, 2894,  960, 2873, 2840, 2840,
+     2840, 1435, 1435, 1435,  959,  958, 2896, 2848, 2848, 2848,
+     2915, 2915, 2915,  957, 2916,  954, 2841, 2917,  953, 1437,
+
+     2853, 2853, 2853,  952, 2849, 1680,  949,  946, 1680, 2850,
+     2850, 2850,  945, 2851,  943,  942, 2852, 2854, 2854, 2854,
+     2855, 2855, 2855,  939, 2864, 2864, 2864, 1680, 2865,  936,
+      933, 2866, 2909, 1678, 1678, 1678, 1678, 1678, 1678, 1678,
+     1678, 1678,  932,  924, 1678, 2934, 2934, 2934,  923, 1678,
+     1678, 1678, 1680, 1678, 2884, 2884, 2884, 2885, 2885, 2885,
+     2890, 2890, 2890, 2935, 2947, 2947, 2947,  922, 2948,  921,
+      915, 2949, 2893, 2893, 2893, 2886,  914, 2891, 1678, 1678,
+     1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 2894,
+      913, 1678, 2895, 2895, 2895,  911, 1678, 1678, 1678, 1680,
+
+     1678, 2951, 2951, 2951,  910, 2952,  909,  908, 2953, 2896,
+     2954, 2954, 2954,  907, 2955,  906,  901, 2956, 2969, 2969,
+     2969, 2934, 2934, 2934,  898, 1678, 1678, 2915, 2915, 2915,
+      900, 2916,  895,  894, 2917,  892, 2970,  890,  888, 2935,
+     2969, 2969, 2969,  886,  884, 1680, 1678, 1678, 1678, 1678,
+     1678, 2981, 1678, 1678, 1678,  881,  880, 1678, 2970,  879,
+      878,  877, 1678, 1678, 1678, 1680, 1678, 2947, 2947, 2947,
+      875, 2948,  873,  872, 2949, 2951, 2951, 2951,  871, 2952,
+      869,  867, 2953, 2954, 2954, 2954,  866, 2955,  864,  862,
+     2956, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678,
+
+     1678, 2981,  861,  859, 1678, 3020, 3020, 3020,  855, 1678,
+     1678, 1678, 1680, 1678, 3031, 3031, 3031, 3033, 3033, 3033,
+     3035, 3035, 3035, 1680, 1681, 3043, 3043, 3043, 3053, 3053,
+     3053, 3032,  854,  852, 3034,  847,  845, 3036, 1678, 1678,
+      841,  840, 3044, 3020, 3020, 3020, 1138, 3031, 3031, 3031,
+     3063, 3063, 3063,  839, 3064,  837,  835, 3065, 3033, 3033,
+     3033, 1680,  834,  833, 3032, 3066, 3066, 3066,  831, 3067,
+      829,  828, 3068,  826,  824, 3034, 3035, 3035, 3035, 3069,
+     3069, 3069,  823, 3070,  822,  821, 3071, 3043, 3043, 3043,
+     3053, 3053, 3053, 3036, 1875, 3078, 3078, 3078,  820, 3079,
+
+      819,  818, 3080,  816, 3044, 3063, 3063, 3063, 1138, 3064,
+      814,  813, 3065, 3066, 3066, 3066,  810, 3067,  809,  808,
+     3068, 3069, 3069, 3069,  806, 3070,  794, 3089, 3071, 3078,
+     3078, 3078,  793, 3079,  790,  788, 3080, 3194, 3194, 3194,
+     3194, 3194, 3194,  786, 3203,  785,  784, 3204, 3296, 3296,
+     3296, 3296, 3296, 3296,  782, 1138,  780,  778, 1138,  775,
+      774,  773,  772,  771,  769,  767, 3297,  766,  764, 3297,
+      254,  254,  254,  254,  254,  254,  254,  254,  254,  255,
+      255,  255,  255,  255,  255,  255,  255,  255,  260,  260,
+      260,  260,  260,  260,  260,  260,  260,  263,  263,  263,
+
+      263,  263,  263,  263,  263,  263,  266,  266,  266,  266,
+      266,  266,  266,  266,  266,  269,  269,  269,  269,  269,
+      269,  269,  269,  269,  276,  276,  276,  276,  276,  276,
+      276,  276,  276,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  288,  288,  288,  288,  288,  288,  288,  288,
+      288,  300,  300,  300,  300,  300,  300,  300,  300,  300,
+      304,  304,  304,  304,  304,  304,  304,  304,  304,  311,
+      311,  311,  311,  311,  311,  311,  311,  311,  322,  322,
+      322,  322,  322,  322,  322,  322,  322,  330,  330,  330,
+      330,  330,  330,  330,  330,  330,  336,  336,  336,  336,
+
+      336,  336,  336,  336,  336,  342,  342,  342,  342,  342,
+      342,  342,  342,  342,  348,  348,  348,  348,  348,  348,
+      348,  348,  348,  353,  353,  353,  353,  353,  353,  353,
+      353,  353,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  379,  379,  379,  379,  379,  379,  379,  379,  379,
+      386,  386,  386,  386,  386,  386,  386,  386,  386,  392,
+      392,  392,  392,  392,  392,  392,  392,  392,  399,  399,
+      399,  399,  399,  399,  399,  399,  399,  404,  404,  404,
+      404,  404,  404,  404,  404,  404,  410,  410,  410,  410,
+      410,  410,  410,  410,  410,  415,  415,  415,  415,  415,
+
+      415,  415,  415,  415,  421,  421,  421,  421,  421,  421,
+      421,  421,  421,  429,  429,  429,  429,  429,  429,  429,
+      429,  429,  437,  437,  437,  437,  437,  437,  437,  437,
+      437,  441,  441,  441,  441,  441,  441,  441,  441,  441,
+      447,  447,  447,  447,  447,  447,  447,  447,  447,  453,
+      453,  453,  453,  453,  453,  453,  453,  453,  470,  470,
+      470,  470,  470,  470,  470,  470,  470,  476,  476,  476,
+      476,  476,  476,  476,  476,  476,  485,  485,  485,  485,
+      485,  485,  485,  485,  485,  491,  491,  491,  491,  491,
+      491,  491,  491,  491,  501,  501,  501,  501,  501,  501,
+
+      501,  501,  501,  507,  507,  507,  507,  507,  507,  507,
+      507,  507,  512,  512,  512,  512,  512,  512,  512,  512,
+      512,  518,  518,  518,  518,  518,  518,  518,  518,  518,
+      524,  524,  524,  524,  524,  524,  524,  524,  524,  530,
+      530,  530,  530,  530,  530,  530,  530,  530,  537,  537,
+      537,  537,  537,  537,  537,  537,  537,  544,  544,  544,
+      544,  544,  544,  544,  544,  544,  549,  549,  549,  549,
+      549,  549,  549,  549,  549,  557,  557,  557,  557,  557,
+      557,  557,  557,  557,  563,  563,  563,  563,  563,  563,
+      563,  563,  563,  570,  570,  570,  570,  570,  570,  570,
+
+      570,  570,  575,  575,  575,  575,  575,  575,  575,  575,
+      575,  581,  581,  581,  581,  581,  581,  581,  581,  581,
+      586,  586,  586,  586,  586,  586,  586,  586,  586,  593,
+      593,  593,  593,  593,  593,  593,  593,  593,  599,  599,
+      599,  599,  599,  599,  599,  599,  599,  606,  606,  606,
+      606,  606,  606,  606,  606,  606,  614,  614,  614,  614,
+      614,  614,  614,  614,  614,  622,  622,  622,  622,  622,
+      622,  622,  622,  622,  626,  626,  626,  626,  626,  626,
+      626,  626,  626,  632,  632,  632,  632,  632,  632,  632,
+      632,  632,  636,  636,  636,  636,  636,  636,  636,  636,
+
+      636,  643,  643,  643,  643,  643,  643,  643,  643,  643,
+      648,  648,  648,  648,  648,  648,  648,  648,  648,  668,
+      668,  668,  762,  761,  759,  668,  695,  695,  695,  757,
+      756,  755,  695,  699,  699,  699,  753,  751,  750,  699,
+      707,  707,  707,  749,  748,  746,  707,  718,  718,  718,
+     3298,  693,  726,  718,  724,  724,  724,  725,  723,  721,
+      724,  747,  747,  747,  720,  719,  717,  747,  754,  754,
+      754,  713,  709,  708,  754,  760,  760,  760,  706,  705,
+      702,  760,  765,  765,  765,  701,  700,  698,  765,  770,
+      770,  770,  697,  696,  694,  770,  779,  779,  779,  689,
+
+     3298,  669,  779,  783,  783,  783,  667,  665,  659,  783,
+      789,  789,  789,  658,  659,  658,  789,  807,  807,  807,
+      657,  656, 3298,  807,  817,  817,  817, 3298, 3298, 3298,
+      817,  827,  827,  827, 3298, 3298, 3298,  827,  832,  832,
+      832, 3298, 3298, 3298,  832,  838,  838,  838, 3298, 3298,
+     3298,  838,  846,  846,  846, 3298, 3298, 3298,  846,  853,
+      853,  853, 3298, 3298, 3298,  853,  860,  860,  860, 3298,
+     3298, 3298,  860,  865,  865,  865, 3298, 3298, 3298,  865,
+      870,  870,  870, 3298, 3298, 3298,  870,  876,  876,  876,
+     3298, 3298, 3298,  876,  885,  885,  885, 3298, 3298, 3298,
+
+      885,  889,  889,  889, 3298, 3298, 3298,  889,  893,  893,
+      893, 3298, 3298, 3298,  893,  897,  897,  897,  897,  897,
+      897,  897, 3298,  897,  668,  668,  668, 3298, 3298, 3298,
+      668,  912, 3298, 3298, 3298,  912,  695,  695,  695, 3298,
+     3298, 3298,  695,  944, 3298, 3298, 3298,  944,  699,  699,
+      699, 3298, 3298, 3298,  699,  951, 3298, 3298, 3298,  951,
+      707,  707,  707, 3298, 3298, 3298,  707,  963, 3298, 3298,
+     3298,  963,  718,  718,  718, 3298, 3298, 3298,  718,  968,
+     3298, 3298, 3298,  968,  724,  724,  724, 3298, 3298, 3298,
+      724,  973, 3298, 3298, 3298,  973,  747,  747,  747, 3298,
+
+     3298, 3298,  747,  994, 3298, 3298, 3298,  994,  754,  754,
+      754, 3298, 3298, 3298,  754, 1000, 3298, 3298, 3298, 1000,
+      760,  760,  760, 3298, 3298, 3298,  760, 1005, 3298, 3298,
+     3298, 1005,  765,  765,  765, 3298, 3298, 3298,  765, 1009,
+     3298, 3298, 3298, 1009,  770,  770,  770, 3298, 3298, 3298,
+      770, 1018, 3298, 3298, 3298, 1018,  779,  779,  779, 3298,
+     3298, 3298,  779, 1023, 3298, 3298, 3298, 1023,  783,  783,
+      783, 3298, 3298, 3298,  783, 1030, 3298, 3298, 3298, 1030,
+      789,  789,  789, 3298, 3298, 3298,  789, 1049, 3298, 3298,
+     3298, 1049,  807,  807,  807, 3298, 3298, 3298,  807, 1060,
+
+     3298, 3298, 3298, 1060,  817,  817,  817, 3298, 3298, 3298,
+      817, 1070, 3298, 3298, 3298, 1070,  827,  827,  827, 3298,
+     3298, 3298,  827, 1075, 3298, 3298, 3298, 1075,  832,  832,
+      832, 3298, 3298, 3298,  832, 1081, 3298, 3298, 3298, 1081,
+      838,  838,  838, 3298, 3298, 3298,  838, 1089, 3298, 3298,
+     3298, 1089,  846,  846,  846, 3298, 3298, 3298,  846, 1094,
+     3298, 3298, 3298, 1094,  853,  853,  853, 3298, 3298, 3298,
+      853, 1101, 3298, 3298, 3298, 1101,  860,  860,  860, 3298,
+     3298, 3298,  860, 1106, 3298, 3298, 3298, 1106,  865,  865,
+      865, 3298, 3298, 3298,  865, 1110, 3298, 3298, 3298, 1110,
+
+      870,  870,  870, 3298, 3298, 3298,  870, 1115, 3298, 3298,
+     3298, 1115,  876,  876,  876, 3298, 3298, 3298,  876, 1122,
+     3298, 3298, 3298, 1122,  885,  885,  885, 3298, 3298, 3298,
+      885, 1126, 3298, 3298, 3298, 1126,  889,  889,  889, 3298,
+     3298, 3298,  889, 1130, 3298, 3298, 3298, 1130,  893,  893,
+      893, 3298, 3298, 3298,  893, 1135, 3298, 3298, 3298, 1135,
+     1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1143,
+     3298, 3298, 3298, 3298, 1143,  668,  668,  668, 3298, 3298,
+     3298,  668, 1152, 1152, 1152, 1152, 3298, 3298, 1152, 1152,
+      695,  695,  695, 3298, 3298, 3298,  695, 1187, 1187, 1187,
+
+     1187, 3298, 3298, 1187, 1187,  699,  699,  699, 3298, 3298,
+     3298,  699, 1197, 1197, 1197, 1197, 3298, 3298, 1197, 1197,
+      707,  707,  707, 3298, 3298, 3298,  707, 1213, 1213, 1213,
+     1213, 3298, 3298, 1213, 1213,  718,  718,  718, 3298, 3298,
+     3298,  718, 1220, 1220, 1220, 1220, 3298, 3298, 1220, 1220,
+      724,  724,  724, 3298, 3298, 3298,  724, 1228, 1228, 1228,
+     1228, 3298, 3298, 1228, 1228,  747,  747,  747, 3298, 3298,
+     3298,  747, 1251, 1251, 1251, 1251, 3298, 3298, 1251, 1251,
+      754,  754,  754, 3298, 3298, 3298,  754, 1260, 1260, 1260,
+     1260, 3298, 3298, 1260, 1260,  760,  760,  760, 3298, 3298,
+
+     3298,  760, 1268, 1268, 1268, 1268, 3298, 3298, 1268, 1268,
+      765,  765,  765, 3298, 3298, 3298,  765, 1274, 1274, 1274,
+     1274, 3298, 3298, 1274, 1274,  770,  770,  770, 3298, 3298,
+     3298,  770, 1286, 1286, 1286, 1286, 3298, 3298, 1286, 1286,
+      779,  779,  779, 3298, 3298, 3298,  779, 1293, 1293, 1293,
+     1293, 3298, 3298, 1293, 1293,  783,  783,  783, 3298, 3298,
+     3298,  783, 1304, 1304, 1304, 1304, 3298, 3298, 1304, 1304,
+      789,  789,  789, 3298, 3298, 3298,  789, 1330, 1330, 1330,
+     1330, 3298, 3298, 1330, 1330,  807,  807,  807,  807, 3298,
+      807, 3298,  807, 1346, 1346, 1346, 1346, 3298, 3298, 1346,
+
+     1346,  817,  817,  817, 3298, 3298, 3298,  817, 1361, 1361,
+     1361, 1361, 3298, 3298, 1361, 1361,  827,  827,  827, 3298,
+     3298, 3298,  827, 1369, 1369, 1369, 1369, 3298, 3298, 1369,
+     1369,  832,  832,  832, 3298, 3298, 3298,  832, 1378, 1378,
+     1378, 1378, 3298, 3298, 1378, 1378,  838,  838,  838, 3298,
+     3298, 3298,  838, 1389, 1389, 1389, 1389, 3298, 3298, 1389,
+     1389,  846,  846,  846,  846, 3298,  846, 3298,  846, 1398,
+     1398, 1398, 1398, 3298, 3298, 1398, 1398,  853,  853,  853,
+      853, 3298,  853, 3298,  853, 1410, 1410, 1410, 1410, 3298,
+     3298, 1410, 1410,  860,  860,  860, 3298, 3298, 3298,  860,
+
+     1418, 1418, 1418, 1418, 3298, 3298, 1418, 1418,  865,  865,
+      865,  865, 3298,  865, 3298,  865, 1426, 1426, 1426, 1426,
+     3298, 3298, 1426, 1426,  870,  870,  870,  870, 3298,  870,
+     3298,  870, 1436, 1436, 1436, 1436, 3298, 3298, 1436, 1436,
+      876,  876,  876, 3298, 3298, 3298,  876, 1445, 1445, 1445,
+     1445, 3298, 3298, 1445, 1445,  885,  885,  885, 3298, 3298,
+     3298,  885, 1451, 1451, 1451, 1451, 3298, 3298, 1451, 1451,
+     1458, 1458, 1458, 1458, 3298, 3298, 1458, 1458,  893,  893,
+      893, 3298, 3298, 3298,  893, 1466, 1466, 1466, 1466, 3298,
+     3298, 1466, 1466, 1137, 1137, 1137, 1137, 1137, 1137, 1137,
+
+     1137, 1137, 1143, 3298, 1143, 3298, 3298, 1143,  668,  668,
+      668, 3298, 3298, 3298,  668, 1152, 1152, 1152, 1152, 3298,
+     3298, 1152, 1152,  695,  695,  695,  695, 3298,  695, 3298,
+      695, 1187, 1187, 1187, 1187, 3298, 3298, 1187, 1187,  699,
+      699,  699,  699, 3298,  699, 3298,  699, 1197, 1197, 1197,
+     1197, 3298, 3298, 1197, 1197,  707,  707,  707, 3298, 3298,
+     3298,  707, 1213, 1213, 1213, 1213, 3298, 3298, 1213, 1213,
+      718,  718,  718, 3298, 3298, 3298,  718, 1220, 1220, 1220,
+     1220, 3298, 3298, 1220, 1220,  724,  724,  724, 3298, 3298,
+     3298,  724, 1228, 1228, 1228, 1228, 3298, 3298, 1228, 1228,
+
+      747,  747,  747, 3298, 3298, 3298,  747, 1251, 1251, 1251,
+     1251, 3298, 3298, 1251, 1251,  754,  754,  754, 3298, 3298,
+     3298,  754, 1260, 1260, 1260, 1260, 3298, 3298, 1260, 1260,
+      760,  760,  760,  760, 3298,  760, 3298,  760, 1268, 1268,
+     1268, 1268, 3298, 3298, 1268, 1268,  765,  765,  765,  765,
+     3298,  765, 3298,  765, 1274, 1274, 1274, 1274, 3298, 3298,
+     1274, 1274,  770,  770,  770, 3298, 3298, 3298,  770, 1286,
+     1286, 1286, 1286, 3298, 3298, 1286, 1286,  779,  779,  779,
+      779, 3298,  779, 3298,  779, 1293, 1293, 1293, 1293, 3298,
+     3298, 1293, 1293,  783,  783,  783,  783, 3298,  783, 3298,
+
+      783, 1304, 1304, 1304, 1304, 3298, 3298, 1304, 1304,  789,
+      789,  789, 3298, 3298, 3298,  789, 1330, 1330, 1330, 1330,
+     3298, 3298, 1330, 1330,  807,  807,  807, 3298, 3298, 3298,
+      807, 1346, 1346, 1346, 1346, 3298, 3298, 1346, 1346,  817,
+      817,  817, 3298, 3298, 3298,  817, 1361, 1361, 1361, 1361,
+     3298, 3298, 1361, 1361,  827,  827,  827, 3298, 3298, 3298,
+      827, 1369, 1369, 1369, 1369, 3298, 3298, 1369, 1369,  832,
+      832,  832, 3298, 3298, 3298,  832, 1378, 1378, 1378, 1378,
+     3298, 3298, 1378, 1378,  838,  838,  838, 3298, 3298, 3298,
+      838, 1389, 1389, 1389, 1389, 3298, 3298, 1389, 1389,  846,
+
+      846,  846, 3298, 3298, 3298,  846, 1398, 1398, 1398, 1398,
+     3298, 3298, 1398, 1398,  853,  853,  853, 3298, 3298, 3298,
+      853, 1410, 1410, 1410, 1410, 3298, 3298, 1410, 1410,  860,
+      860,  860, 3298, 3298, 3298,  860, 1418, 1418, 1418, 1418,
+     3298, 3298, 1418, 1418, 1426, 1426, 1426, 1426, 3298, 3298,
+     1426, 1426,  870,  870,  870, 3298, 3298, 3298,  870, 1436,
+     1436, 1436, 1436, 3298, 3298, 1436, 1436,  876,  876,  876,
+     3298, 3298, 3298,  876, 1445, 1445, 1445, 1445, 3298, 3298,
+     1445, 1445,  885,  885,  885, 3298, 3298, 3298,  885, 1451,
+     1451, 1451, 1451, 3298, 3298, 1451, 1451, 1458, 1458, 1458,
+
+     1458, 3298, 3298, 1458, 1458,  893,  893,  893, 3298, 3298,
+     3298,  893, 1466, 1466, 1466, 1466, 3298, 3298, 1466, 1466,
+     1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1678,
+     1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678,  668,  668,
+      668, 3298, 3298, 3298,  668, 1152, 1152, 1152, 1152, 3298,
+     3298, 1152, 1152, 1187, 1187, 1187, 1187, 3298, 3298, 1187,
+     1187,  699,  699,  699, 3298, 3298, 3298,  699, 1197, 1197,
+     1197, 1197, 3298, 3298, 1197, 1197,  707,  707,  707, 3298,
+     3298, 3298,  707, 1213, 1213, 1213, 1213, 3298, 3298, 1213,
+     1213,  718,  718,  718, 3298, 3298, 3298,  718, 1220, 1220,
+
+     1220, 1220, 3298, 3298, 1220, 1220,  724,  724,  724, 3298,
+     3298, 3298,  724,  747,  747,  747, 3298, 3298, 3298,  747,
+     1251, 1251, 1251, 1251, 3298, 3298, 1251, 1251,  754,  754,
+      754, 3298, 3298, 3298,  754, 1260, 1260, 1260, 1260, 3298,
+     3298, 1260, 1260, 1268, 1268, 1268, 1268, 3298, 3298, 1268,
+     1268,  765,  765,  765, 3298, 3298, 3298,  765, 1274, 1274,
+     1274, 1274, 3298, 3298, 1274, 1274,  770,  770,  770, 3298,
+     3298, 3298,  770, 1286, 1286, 1286, 1286, 3298, 3298, 1286,
+     1286, 1293, 1293, 1293, 1293, 3298, 3298, 1293, 1293, 1304,
+     1304, 1304, 1304, 3298, 3298, 1304, 1304,  789,  789,  789,
+
+     3298, 3298, 3298,  789, 1330, 1330, 1330, 1330, 3298, 3298,
+     1330, 1330,  807,  807,  807,  807, 3298,  807, 3298,  807,
+     1346, 1346, 1346, 1346, 3298, 3298, 1346, 1346,  817,  817,
+      817, 3298, 3298, 3298,  817, 1361, 1361, 1361, 1361, 3298,
+     3298, 1361, 1361,  827,  827,  827, 3298, 3298, 3298,  827,
+     1369, 1369, 1369, 1369, 3298, 3298, 1369, 1369,  832,  832,
+      832, 3298, 3298, 3298,  832, 1378, 1378, 1378, 1378, 3298,
+     3298, 1378, 1378,  838,  838,  838, 3298, 3298, 3298,  838,
+     1389, 1389, 1389, 1389, 3298, 3298, 1389, 1389,  846,  846,
+      846, 3298, 3298, 3298,  846, 1398, 1398, 1398, 1398, 3298,
+
+     3298, 1398, 1398,  853,  853,  853, 3298, 3298, 3298,  853,
+     1410, 1410, 1410, 1410, 3298, 3298, 1410, 1410,  860,  860,
+      860, 3298, 3298, 3298,  860, 1418, 1418, 1418, 1418, 3298,
+     3298, 1418, 1418, 1426, 1426, 1426, 1426, 3298, 3298, 1426,
+     1426,  870,  870,  870, 3298, 3298, 3298,  870, 1436, 1436,
+     1436, 1436, 3298, 3298, 1436, 1436,  876,  876,  876, 3298,
+     3298, 3298,  876, 1445, 1445, 1445, 1445, 3298, 3298, 1445,
+     1445,  885,  885,  885,  885, 3298,  885, 3298,  885, 1451,
+     1451, 1451, 1451, 3298, 3298, 1451, 1451, 1458, 1458, 1458,
+     1458, 3298, 3298, 1458, 1458,  893,  893,  893,  893, 3298,
+
+      893, 3298,  893, 1466, 1466, 1466, 1466, 3298, 3298, 1466,
+     1466, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137,
+     1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678,  668,
+      668,  668, 3298, 3298, 3298,  668, 1152, 1152, 1152, 1152,
+     3298, 3298, 1152, 1152, 1187, 1187, 1187, 1187, 3298, 3298,
+     1187, 1187,  699,  699,  699, 3298, 3298, 3298,  699, 1197,
+     1197, 1197, 1197, 3298, 3298, 1197, 1197,  707,  707,  707,
+     3298, 3298, 3298,  707, 1213, 1213, 1213, 1213, 3298, 3298,
+     1213, 1213,  718,  718,  718, 3298, 3298, 3298,  718, 1220,
+     1220, 1220, 1220, 3298, 3298, 1220, 1220,  724,  724,  724,
+
+     3298, 3298, 3298,  724,  747,  747,  747, 3298, 3298, 3298,
+      747, 1251, 1251, 1251, 1251, 3298, 3298, 1251, 1251,  754,
+      754,  754, 3298, 3298, 3298,  754, 1260, 1260, 1260, 1260,
+     3298, 3298, 1260, 1260, 1268, 1268, 1268, 1268, 3298, 3298,
+     1268, 1268,  765,  765,  765,  765, 3298,  765, 3298,  765,
+     1274, 1274, 1274, 1274, 3298, 3298, 1274, 1274,  770,  770,
+      770, 3298, 3298, 3298,  770, 1286, 1286, 1286, 1286, 3298,
+     3298, 1286, 1286, 1304, 1304, 1304, 1304, 3298, 3298, 1304,
+     1304,  789,  789,  789, 3298, 3298, 3298,  789, 1330, 1330,
+     1330, 1330, 3298, 3298, 1330, 1330,  807,  807,  807,  807,
+
+     3298,  807, 3298,  807, 1346, 1346, 1346, 1346, 3298, 3298,
+     1346, 1346,  817,  817,  817, 3298, 3298, 3298,  817, 1361,
+     1361, 1361, 1361, 3298, 3298, 1361, 1361,  827,  827,  827,
+     3298, 3298, 3298,  827, 1369, 1369, 1369, 1369, 3298, 3298,
+     1369, 1369,  832,  832,  832, 3298, 3298, 3298,  832, 1378,
+     1378, 1378, 1378, 3298, 3298, 1378, 1378,  838,  838,  838,
+     3298, 3298, 3298,  838, 1389, 1389, 1389, 1389, 3298, 3298,
+     1389, 1389,  846,  846,  846, 3298, 3298, 3298,  846, 1398,
+     1398, 1398, 1398, 3298, 3298, 1398, 1398,  853,  853,  853,
+      853, 3298,  853, 3298,  853, 1410, 1410, 1410, 1410, 3298,
+
+     3298, 1410, 1410,  860,  860,  860, 3298, 3298, 3298,  860,
+     1418, 1418, 1418, 1418, 3298, 3298, 1418, 1418, 1426, 1426,
+     1426, 1426, 3298, 3298, 1426, 1426,  870,  870,  870,  870,
+     3298,  870, 3298,  870, 1436, 1436, 1436, 1436, 3298, 3298,
+     1436, 1436,  876,  876,  876, 3298, 3298, 3298,  876, 1445,
+     1445, 1445, 1445, 3298, 3298, 1445, 1445, 1451, 1451, 1451,
+     1451, 3298, 3298, 1451, 1451, 1458, 1458, 1458, 1458, 3298,
+     3298, 1458, 1458, 1466, 1466, 1466, 1466, 3298, 3298, 1466,
+     1466, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137,
+     1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678,  668,
+
+      668,  668,  668, 3298,  668, 3298,  668, 1152, 1152, 1152,
+     1152, 3298, 3298, 1152, 1152, 1187, 1187, 1187, 1187, 3298,
+     3298, 1187, 1187,  699,  699,  699, 3298, 3298, 3298,  699,
+     1197, 1197, 1197, 1197, 3298, 3298, 1197, 1197,  707,  707,
+      707, 3298, 3298, 3298,  707, 1213, 1213, 1213, 1213, 3298,
+     3298, 1213, 1213,  718,  718,  718,  718, 3298,  718, 3298,
+      718, 1220, 1220, 1220, 1220, 3298, 3298, 1220, 1220,  724,
+      724,  724,  724, 3298,  724, 3298,  724,  747,  747,  747,
+      747, 3298,  747, 3298,  747, 1251, 1251, 1251, 1251, 3298,
+     3298, 1251, 1251,  754,  754,  754,  754, 3298,  754, 3298,
+
+      754, 1260, 1260, 1260, 1260, 3298, 3298, 1260, 1260, 1268,
+     1268, 1268, 1268, 3298, 3298, 1268, 1268, 1274, 1274, 1274,
+     1274, 3298, 3298, 1274, 1274,  770,  770,  770, 3298, 3298,
+     3298,  770, 1304, 1304, 1304, 1304, 3298, 3298, 1304, 1304,
+      789,  789,  789, 3298, 3298, 3298,  789, 1330, 1330, 1330,
+     1330, 3298, 3298, 1330, 1330,  807,  807,  807,  807, 3298,
+      807, 3298,  807, 1346, 1346, 1346, 1346, 3298, 3298, 1346,
+     1346,  817,  817,  817, 3298, 3298, 3298,  817,  827,  827,
+      827, 3298, 3298, 3298,  827, 1369, 1369, 1369, 1369, 3298,
+     3298, 1369, 1369,  832,  832,  832, 3298, 3298, 3298,  832,
+
+     1378, 1378, 1378, 1378, 3298, 3298, 1378, 1378,  838,  838,
+      838, 3298, 3298, 3298,  838,  846,  846,  846, 3298, 3298,
+     3298,  846, 1398, 1398, 1398, 1398, 3298, 3298, 1398, 1398,
+      853,  853,  853, 3298, 3298, 3298,  853, 1410, 1410, 1410,
+     1410, 3298, 3298, 1410, 1410,  860,  860,  860, 3298, 3298,
+     3298,  860, 1418, 1418, 1418, 1418, 3298, 3298, 1418, 1418,
+     1426, 1426, 1426, 1426, 3298, 3298, 1426, 1426, 1436, 1436,
+     1436, 1436, 3298, 3298, 1436, 1436,  876,  876,  876, 3298,
+     3298, 3298,  876, 1445, 1445, 1445, 1445, 3298, 3298, 1445,
+     1445, 1451, 1451, 1451, 1451, 3298, 3298, 1451, 1451, 1458,
+
+     1458, 1458, 1458, 3298, 3298, 1458, 1458, 1137, 1137, 1137,
+     1137, 1137, 1137, 1137, 1137, 1137, 1678, 1678, 1678, 1678,
+     1678, 1678, 1678, 1678, 1678, 1152, 1152, 1152, 1152, 3298,
+     3298, 1152, 1152, 1187, 1187, 1187, 1187, 3298, 3298, 1187,
+     1187,  699,  699,  699, 3298, 3298, 3298,  699,  707,  707,
+      707, 3298, 3298, 3298,  707, 1213, 1213, 1213, 1213, 3298,
+     3298, 1213, 1213, 1220, 1220, 1220, 1220, 3298, 3298, 1220,
+     1220, 1251, 1251, 1251, 1251, 3298, 3298, 1251, 1251, 1260,
+     1260, 1260, 1260, 3298, 3298, 1260, 1260, 1274, 1274, 1274,
+     1274, 3298, 3298, 1274, 1274,  770,  770,  770, 3298, 3298,
+
+     3298,  770, 1304, 1304, 1304, 1304, 3298, 3298, 1304, 1304,
+      789,  789,  789, 3298, 3298, 3298,  789, 1330, 1330, 1330,
+     1330, 3298, 3298, 1330, 1330, 1346, 1346, 1346, 1346, 3298,
+     3298, 1346, 1346,  817,  817,  817, 3298, 3298, 3298,  817,
+      827,  827,  827, 3298, 3298, 3298,  827, 1369, 1369, 1369,
+     1369, 3298, 3298, 1369, 1369,  832,  832,  832, 3298, 3298,
+     3298,  832, 1378, 1378, 1378, 1378, 3298, 3298, 1378, 1378,
+      838,  838,  838, 3298, 3298, 3298,  838,  846,  846,  846,
+     3298, 3298, 3298,  846,  853,  853,  853, 3298, 3298, 3298,
+      853, 1410, 1410, 1410, 1410, 3298, 3298, 1410, 1410,  860,
+
+      860,  860, 3298, 3298, 3298,  860, 1418, 1418, 1418, 1418,
+     3298, 3298, 1418, 1418, 1426, 1426, 1426, 1426, 3298, 3298,
+     1426, 1426, 1436, 1436, 1436, 1436, 3298, 3298, 1436, 1436,
+      876,  876,  876,  876, 3298,  876, 3298,  876, 1445, 1445,
+     1445, 1445, 3298, 3298, 1445, 1445, 1451, 1451, 1451, 1451,
+     3298, 3298, 1451, 1451, 1458, 1458, 1458, 1458, 3298, 3298,
+     1458, 1458, 1137, 1137, 1137, 1137, 1137, 1137, 1137, 1137,
+     1137, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678,
+     1152, 1152, 1152, 1152, 3298, 3298, 1152, 1152, 1187, 1187,
+     1187, 1187, 3298, 3298, 1187, 1187,  699,  699,  699, 3298,
+
+     3298, 3298,  699,  707,  707,  707,  707, 3298,  707, 3298,
+      707, 1220, 1220, 1220, 1220, 3298, 3298, 1220, 1220, 1251,
+     1251, 1251, 1251, 3298, 3298, 1251, 1251, 1260, 1260, 1260,
+     1260, 3298, 3298, 1260, 1260, 1274, 1274, 1274, 1274, 3298,
+     3298, 1274, 1274,  770,  770,  770, 3298, 3298, 3298,  770,
+     1304, 1304, 1304, 1304, 3298, 3298, 1304, 1304,  789,  789,
+      789, 3298, 3298, 3298,  789, 1330, 1330, 1330, 1330, 3298,
+     3298, 1330, 1330, 1346, 1346, 1346, 1346, 3298, 3298, 1346,
+     1346,  817,  817,  817, 3298, 3298, 3298,  817,  827,  827,
+      827, 3298, 3298, 3298,  827,  832,  832,  832,  832, 3298,
+
+      832, 3298,  832, 1378, 1378, 1378, 1378, 3298, 3298, 1378,
+     1378,  838,  838,  838,  838, 3298,  838, 3298,  838,  846,
+      846,  846, 3298, 3298, 3298,  846,  853,  853,  853, 3298,
+     3298, 3298,  853, 1410, 1410, 1410, 1410, 3298, 3298, 1410,
+     1410,  860,  860,  860,  860, 3298,  860, 3298,  860, 1418,
+     1418, 1418, 1418, 3298, 3298, 1418, 1418, 1426, 1426, 1426,
+     1426, 3298, 3298, 1426, 1426, 1436, 1436, 1436, 1436, 3298,
+     3298, 1436, 1436,  876,  876,  876,  876, 3298,  876, 3298,
+      876, 1445, 1445, 1445, 1445, 3298, 3298, 1445, 1445, 1451,
+     1451, 1451, 1451, 3298, 3298, 1451, 1451, 1137, 1137, 1137,
+
+     1137, 1137, 1137, 1137, 1137, 1137, 1678, 1678, 1678, 1678,
+     1678, 1678, 1678, 1678, 1678, 1152, 1152, 1152, 1152, 3298,
+     3298, 1152, 1152,  699,  699,  699, 3298, 3298, 3298,  699,
+      707,  707,  707, 3298, 3298, 3298,  707, 1220, 1220, 1220,
+     1220, 3298, 3298, 1220, 1220, 1251, 1251, 1251, 1251, 3298,
+     3298, 1251, 1251, 1274, 1274, 1274, 1274, 3298, 3298, 1274,
+     1274,  770,  770,  770, 3298, 3298, 3298,  770, 1304, 1304,
+     1304, 1304, 3298, 3298, 1304, 1304,  789,  789,  789, 3298,
+     3298, 3298,  789, 2918, 2918, 2918, 2918, 2918, 2918, 2918,
+     2918, 2918, 2919, 2919, 2919, 2919, 2919, 2919, 2919, 2919,
+
+     2919, 2976, 2976, 2976, 2976, 2976, 2976, 2976, 2976, 2976,
+     2979, 2979, 2979, 2979, 2979, 2979, 2979, 2979, 2979, 3017,
+     3017, 3017, 3017, 3017, 3017, 3017, 3017, 3017, 3019, 3019,
+     3019, 3019, 3019, 3019, 3019, 3019, 3019,  253, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298
     } ;
 
-static yyconst flex_int16_t yy_chk[12047] =
+static yyconst flex_int16_t yy_chk[12113] =
     {   0,
         0,    3,    3,    3,    4,    4,    4,    5,    5,    5,
         6,    6,    6,    7,    7,    7,   11,    3,    9,   12,
@@ -2985,10 +3006,10 @@ static yyconst flex_int16_t yy_chk[12047] =
         8,    8,    8,  258,   11,   13,   13,   12,   14,   14,
        13,   13,  307,   14,   14,  259,    8,   17,   17,  258,
        13,   15,   15,   14,   15,  262,   15,   16,   16,  361,
-       16,  259,   16,   18,   18, 1532,   15,   19,   19,   19,
+       16,  259,   16,   18,   18, 1524,   15,   19,   19,   19,
       536,  262,   16,   20,   20,   20,   23,   23,   23,   24,
-       24,   24,  536,   19,   25,   25,   25,  361, 1533,   20,
-      368,   17,   23, 1059,  307,   24,  256,  256,  256, 1059,
+       24,   24,  536,   19,   25,   25,   25,  361, 1527,   20,
+      368,   17,   23, 1063,  307,   24,  256,  256,  256, 1063,
 
        25,  257,  257,  257,  261,  261,  261,   18,   21,   21,
        21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
@@ -2999,7 +3020,7 @@ static yyconst flex_int16_t yy_chk[12047] =
        31,   31,  282,  282,  282,  285,  289,  289,  289,  298,
       298,  298,  301,  280,  357,   31,  673,   21,   22,   22,
        22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
-       22,   22,   22, 1538,   22,   22,   22,   22,   22,   32,
+       22,   22,   22, 1529,   22,   22,   22,   22,   22,   32,
 
        32,   32,   33,   33,   33,   34,   34,   34,  272,   35,
        35,   35,   36,   36,   36,   32,  280,  360,   33,  482,
@@ -3013,78 +3034,78 @@ static yyconst flex_int16_t yy_chk[12047] =
       329,   43,   43,   43,   43,   43,   45,   45,   45,   46,
 
        46,   46,   47,   47,   47,  329,   48,   48,   48,   49,
-       49,   49,   45,  661,  553,   46,  661, 1539,   47,  327,
+       49,   49,   45,  661,  553,   46,  661, 1534,   47,  327,
        43,   43,   48,  327,  381,   49,  293,  327,   43,   44,
        44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
        44,   44,   44,   44,  323,   44,   44,   44,   44,   44,
        50,   50,   50,   51,   51,   51,   52,   52,   52,  468,
       323,  566,   55,   55,  562,  293,   50,   55,  294,   51,
       553,  562,   52,  468,   44,   44,  381,   55,  293,  382,
-      293, 1540,   44,   53,   53,   53,   53,   53,   53,   53,
-       53,   53,   53,   53,   53,   53,   53,   53, 1541,   53,
+      293, 1537,   44,   53,   53,   53,   53,   53,   53,   53,
+       53,   53,   53,   53,   53,   53,   53,   53, 1538,   53,
 
-       53,   53,   53,   53, 1542,  337,   55,  294,   59,   59,
+       53,   53,   53,   53, 1539,  337,   55,  294,   59,   59,
        59,   60,   60,   60,   63,   63,   63,  566,   56,   56,
-      294,  337,  294,   56,   59,  317,  552,   60,   53,   53,
-       63,  382,  317,   56,  552,  589,   53,  394, 1543,   53,
-      602,  317,  331,  331,  331, 1544,   53,   54,   54,   54,
+      294,  337,  294,   56,   59,  317,  466,   60,   53,   53,
+       63,  382,  317,   56,  466,  772,   53,  394,  772,   53,
+      466,  317,  331,  331,  331, 1544,   53,   54,   54,   54,
        54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
        54,   54,   56,   54,   54,   54,   54,   54,   64,   64,
-       64,   67,   67,   67,   68,   68,   68, 1549,   69,   69,
+       64,   67,   67,   67,   68,   68,   68, 1545,   69,   69,
        69,   70,   70,   70,   64,  349,  367,   67,  332,  394,
-       68,  589,   54,   54,   69,  332,  602,   70, 1550, 1557,
+       68,  552,   54,   54,   69,  332, 1171,   70, 1546,  552,
 
-       54,  349,  367,   54,  332,  334,  334,  334,  395, 1559,
+       54,  349,  367,   54,  332,  334,  334,  334,  395, 1171,
        54,   57,   57,   57,   57,   57,   57,   57,   57,   57,
-       57,   57,   57,   57,   57,   57, 1560,   57,   57,   57,
+       57,   57,   57,   57,   57,   57, 1547,   57,   57,   57,
        57,   57,   71,   71,   71,   72,   72,   72,   73,   73,
-       73,  433,   74,   74,   74,   75,   75,   75,   71, 1566,
-      373,   72,  344,  387,   73, 1567,   57,   57,   74,  344,
+       73,  433,   74,   74,   74,   75,   75,   75,   71, 1548,
+      373,   72,  344,  387,   73, 1549,   57,   57,   74,  344,
       395,   75,  343,  343,  343,   57,  373,   57,  344,  387,
       431,   57,  346,  346,  346,  539,   57,   57,   58,   58,
        58,   58,   58,   58,   58,   58,   58,   58,   58,   58,
        58,   58,   58,  433,   58,   58,   58,   58,   58,   76,
 
        76,   76,   77,   77,   77,   78,   78,   78,  617,   79,
-       79,   79,   80,   80,   80,   76,  359, 1574,   77,  431,
+       79,   79,   80,   80,   80,   76,  359, 1550,   77,  431,
       617,   78,  431,   58,   58,   79,  359,  539,   80,  354,
       354,  354,   58,  359,   58,  370,  370,  370,   58,  380,
-      380,  380, 1576,   58,   58,   61,   61,   61,   61,   61,
+      380,  380, 1555,   58,   58,   61,   61,   61,   61,   61,
        61,   61,   61,   61,   61,   61,   61,   61,   61,   61,
       365,   61,   61,   61,   61,   61,   81,   81,   81,   82,
        82,   82,   83,   83,   83,  703,   84,   84,   84,   85,
-       85,   85,   81,  679, 1577,   82,  652,  679,   83,  365,
-       61,   61,   84,  365,  365,   85, 1584,   61,  384,  384,
+       85,   85,   81, 1556, 1563,   82,  652,  589,   83,  365,
+       61,   61,   84,  365,  365,   85,  602,   61,  384,  384,
 
       384,  652,  365,   61,  365,  393,  393,  393,  397,  397,
       397,  703,   61,   62,   62,   62,   62,   62,   62,   62,
-       62,   62,   62,   62,   62,   62,   62,   62, 1585,   62,
+       62,   62,   62,   62,   62,   62,   62,   62, 1565,   62,
        62,   62,   62,   62,   86,   86,   86,   87,   87,   87,
-       88,   88,   88, 1586,   89,   89,   89,   90,   90,   90,
-       86,  400,  681,   87, 1587,  738,   88,  406,   62,   62,
-       89,  411,  422,   90,  406,   62,  681,  400,  405,  405,
+       88,   88,   88,  589,   89,   89,   89,   90,   90,   90,
+       86,  400,  602,   87, 1566,  738,   88,  406,   62,   62,
+       89,  411,  422,   90,  406,   62, 1572,  400,  405,  405,
       405,   62,  739,  406,  408,  408,  408,  411,  422,  738,
        62,   65,   65,   65,   65,   65,   65,   65,   65,   65,
        65,   65,   65,   65,   65,   65,  739,   65,   65,   65,
 
        65,   65,   91,   91,   91,   92,   92,   92,   93,   93,
-       93, 1588,   94,   94,   94,   95,   95,   95,   91,  438,
-      772,   92,  417,  772,   93,  540,   65,   65,   94,  417,
-     1589,   95,  416,  416,  416,  438,  432,   65,  417,  419,
-      419,  419,  430,  430,  430, 1599,   65,   66,   66,   66,
+       93, 1573,   94,   94,   94,   95,   95,   95,   91,  438,
+     1580,   92,  417, 1582,   93,  540,   65,   65,   94,  417,
+     1583,   95,  416,  416,  416,  438,  432,   65,  417,  419,
+      419,  419,  430,  430,  430, 1589,   65,   66,   66,   66,
        66,   66,   66,   66,   66,   66,   66,   66,   66,   66,
        66,   66,  740,   66,   66,   66,   66,   66,   96,   96,
        96,   97,   97,   97,   98,   98,   98,  540,   99,   99,
        99,  100,  100,  100,   96,  432,  740,   97,  432,  741,
-       98, 1601,   66,   66,   99,  443, 1602,  100,  101,  101,
+       98, 1590,   66,   66,   99,  443, 1592,  100,  101,  101,
 
-      101, 1607,  443,   66,  102,  102,  102,  435,  435,  435,
-      618,  443,   66,  741,  101,  442,  442,  442,  366, 1609,
+      101, 1593,  443,   66,  102,  102,  102,  435,  435,  435,
+      618,  443,   66,  741,  101,  442,  442,  442,  366, 1594,
       102,  103,  103,  103,  103,  103,  103,  103,  103,  103,
       103,  103,  103,  103,  103,  103,  745,  103,  103,  103,
       103,  103,  105,  105,  105,  106,  106,  106,  107,  107,
-      107,  777,  108,  108,  108,  777,  366,  448,  105, 1136,
-      745,  106,  618, 1136,  107,  363,  103,  103,  108,  455,
+      107,  679,  108,  108,  108,  679,  366,  448,  105,  777,
+      745,  106,  618,  777,  107,  363,  103,  103,  108,  455,
       460,  103,  366,  448,  638,  363,  455,  103,  445,  445,
       445,  103,  454,  454,  454,  455,  460,  103,  104,  104,
       104,  104,  104,  104,  104,  104,  104,  104,  104,  104,
@@ -3092,96 +3113,96 @@ static yyconst flex_int16_t yy_chk[12047] =
       104,  104,  104,  363,  104,  104,  104,  104,  104,  109,
       109,  109,  110,  110,  110,  111,  111,  111,  639,  112,
       112,  112,  457,  457,  457,  109,  638,  469,  110,  472,
-      477,  111, 1463,  104,  104,  112,  472,  492,  104,  469,
-      469,  471,  471,  471,  104,  472,  477, 1611,  104,  474,
-      474,  474, 1463,  492,  104,  113,  113,  113,  113,  113,
+      477,  111, 1469,  104,  104,  112,  472,  492,  104,  469,
+      469,  471,  471,  471,  104,  472,  477, 1595,  104,  474,
+      474,  474, 1469,  492,  104,  113,  113,  113,  113,  113,
       113,  113,  113,  113,  113,  113,  113,  113,  113,  113,
       639,  113,  113,  113,  113,  113,  115,  115,  115,  116,
-      116,  116,  117,  117,  117,  685,  118,  118,  118,  486,
-      486,  486,  115,  508,  519,  116,  487, 1612,  117,  685,
+      116,  116,  117,  117,  117,  681,  118,  118,  118,  486,
+      486,  486,  115,  508,  519,  116,  487, 1596,  117,  681,
 
-      113,  113,  118,  487, 1614,  113,  489,  489,  489,  508,
+      113,  113,  118,  487, 1597,  113,  489,  489,  489,  508,
       519,  113,  487,  502,  502,  502,  505,  505,  505,  513,
       513,  513,  113,  114,  114,  114,  114,  114,  114,  114,
-      114,  114,  114,  114,  114,  114,  114,  114, 1615,  114,
+      114,  114,  114,  114,  114,  114,  114,  114, 1607,  114,
       114,  114,  114,  114,  119,  119,  119,  120,  120,  120,
-      121,  121,  121,  734,  122,  122,  122, 1616,  503, 1167,
-      119, 1625,  531,  120,  514,  503,  121,  734,  114,  114,
-      122,  514, 1167,  114,  503,  516,  516,  516,  531,  114,
+      121,  121,  121,  685,  122,  122,  122, 1140,  503, 1183,
+      119, 1140,  531,  120,  514,  503,  121,  685,  114,  114,
+      122,  514, 1183,  114,  503,  516,  516,  516,  531,  114,
       514,  525,  525,  525,  528,  528,  528,  538,  538,  538,
       114,  123,  123,  123,  123,  123,  123,  123,  123,  123,
 
-      123,  123,  123,  123,  123,  123, 1631,  123,  123,  123,
+      123,  123,  123,  123,  123,  123, 1609,  123,  123,  123,
       123,  123,  125,  125,  125,  126,  126,  126,  129,  129,
-      129, 1632,  130,  130,  130,  133,  133,  133,  125,  545,
-      558,  126,  526, 1636,  129,  565,  123,  123,  130,  526,
-     1638,  133,  542,  542,  542,  545,  558,  123,  526,  550,
+      129, 1610,  130,  130,  130,  133,  133,  133,  125,  545,
+      558,  126,  526, 1615,  129,  565,  123,  123,  130,  526,
+     1617,  133,  542,  542,  542,  545,  558,  123,  526,  550,
       550,  550,  123,  124,  124,  124,  124,  124,  124,  124,
-      124,  124,  124,  124,  124,  124,  124,  124, 1650,  124,
+      124,  124,  124,  124,  124,  124,  124,  124, 1619,  124,
       124,  124,  124,  124,  134,  134,  134,  135,  135,  135,
       136,  136,  136,  565,  137,  137,  137,  138,  138,  138,
-      134,  565, 1651,  135, 1656, 1659,  136,  571,  124,  124,
+      134,  565, 1620,  135, 1622, 1623,  136,  571,  124,  124,
 
-      137, 1660, 1661,  138, 1663,  551,  555,  555,  555,  124,
+      137, 1624, 1633,  138, 1639,  551,  555,  555,  555,  124,
       564,  564,  564,  571,  124,  127,  127,  127,  127,  127,
       127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-     1670,  127,  127,  127,  127,  127,  139,  139,  139,  140,
-      140,  140,  143,  143,  143,  742,  144,  144,  144,  147,
-      147,  147,  139,  551, 1673,  140,  577,  551,  143,  742,
+     1640,  127,  127,  127,  127,  127,  139,  139,  139,  140,
+      140,  140,  143,  143,  143,  734,  144,  144,  144,  147,
+      147,  147,  139,  551, 1644,  140,  577,  551,  143,  734,
       127,  127,  144,  577,  582,  147,  568,  568,  568,  576,
       576,  576,  577,  579,  579,  579,  127,  587,  587,  587,
-      582, 1676,  127,  128,  128,  128,  128,  128,  128,  128,
-      128,  128,  128,  128,  128,  128,  128,  128, 1677,  128,
+      582, 1646,  127,  128,  128,  128,  128,  128,  128,  128,
+      128,  128,  128,  128,  128,  128,  128,  128, 1658,  128,
 
       128,  128,  128,  128,  148,  148,  148,  151,  151,  151,
-      152,  152,  152, 1679,  155,  155,  155,  156,  156,  156,
-      148, 1669,  594,  151, 1680, 1681,  152,  607,  128,  128,
+      152,  152,  152, 1659,  155,  155,  155,  156,  156,  156,
+      148, 1664,  594,  151, 1667, 1668,  152,  607,  128,  128,
       155,  674,  623,  156,  591,  591,  591,  588,  594,  600,
-      600,  600,  674,  607,  128,  674, 1669,  601,  623, 1682,
+      600,  600,  674,  607,  128,  674, 1669,  601,  623, 1671,
       128,  131,  131,  131,  131,  131,  131,  131,  131,  131,
-      131,  131,  131,  131,  131,  131, 1683,  131,  131,  131,
+      131,  131,  131,  131,  131,  131, 1678,  131,  131,  131,
       131,  131,  159,  159,  159,  160,  160,  160,  163,  163,
-      163, 1684,  164,  164,  164,  588,  633, 1685,  159, 1687,
-     1688,  160, 1690,  588,  163,  601,  131,  131,  164,  131,
+      163, 1681,  164,  164,  164,  588,  633, 1684,  159, 1685,
+     1687,  160, 1688,  588,  163,  601,  131,  131,  164,  131,
 
       644,  131,  633,  601,  604,  604,  604,  131,  615,  615,
       615,  620,  620,  620,  131,  616,  644,  131,  132,  132,
       132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
-      132,  132,  132, 1692,  132,  132,  132,  132,  132,  167,
+      132,  132,  132, 1689,  132,  132,  132,  132,  132,  167,
       167,  167,  168,  168,  168,  171,  171,  171,  684,  172,
-      172,  172,  616, 1694, 1695,  167,  897, 1697,  168,  684,
-     1179,  171,  684,  132,  132,  172,  132,  616,  132,  627,
-      627,  627,  897, 1179,  132,  630,  630,  630,  637,  637,
-      637,  132, 1699, 1701,  132,  141,  141,  141,  141,  141,
+      172,  172,  616, 1690, 1691,  167,  899, 1677,  168,  684,
+     1237,  171,  684,  132,  132,  172,  132,  616,  132,  627,
+      627,  627,  899, 1237,  132,  630,  630,  630,  637,  637,
+      637,  132, 1677, 1692,  132,  141,  141,  141,  141,  141,
       141,  141,  141,  141,  141,  141,  141,  141,  141,  141,
 
-     1702,  141,  141,  141,  141,  141,  173,  173,  173,  174,
-      174,  174,  175,  175,  175,  744,  176,  176,  176,  177,
-      177,  177,  173, 1703, 1704,  174,  628,  650,  175,  744,
+     1693,  141,  141,  141,  141,  141,  173,  173,  173,  174,
+      174,  174,  175,  175,  175,  742,  176,  176,  176,  177,
+      177,  177,  173, 1695, 1696,  174,  628,  650,  175,  742,
       141,  141,  176,  628,  650,  177,  641,  641,  641,  649,
-      649,  649,  628,  650, 1705, 1707,  141,  142,  142,  142,
+      649,  649,  628,  650, 1698, 1700,  141,  142,  142,  142,
       142,  142,  142,  142,  142,  142,  142,  142,  142,  142,
-      142,  142, 1716,  142,  142,  142,  142,  142,  178,  178,
-      178,  181,  181,  181,  182,  182,  182, 1717,  183,  183,
-      183,  184,  184,  184,  178, 1719, 1723,  181,  680, 1727,
-      182, 1729,  142,  142,  183,  680, 1736,  184,  651,  651,
+      142,  142, 1702,  142,  142,  142,  142,  142,  178,  178,
+      178,  181,  181,  181,  182,  182,  182,  744,  183,  183,
+      183,  184,  184,  184,  178, 1703, 1705,  181,  680, 1707,
+      182,  744,  142,  142,  183,  680, 1709,  184,  651,  651,
 
-      651,  680,  660,  660,  660, 1151, 1151, 1151,  142,  145,
+      651,  680,  660,  660,  660, 1155, 1155, 1155,  142,  145,
       145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
-      145,  145,  145,  145, 1737,  145,  145,  145,  145,  145,
+      145,  145,  145,  145, 1710,  145,  145,  145,  145,  145,
       185,  185,  185,  186,  186,  186,  187,  187,  187,  687,
-      188,  188,  188,  191,  191,  191,  185, 1738, 1739,  186,
+      188,  188,  188,  191,  191,  191,  185, 1711, 1712,  186,
       687,  689,  187,  687,  145,  145,  188,  691,  689,  191,
-      145,  660,  692,  693,  689,  145, 1741, 1745,  691,  692,
-      693,  691, 1159, 1159, 1159,  692,  693,  145,  146,  146,
+      145,  660,  692,  693,  689,  145, 1713, 1715,  691,  692,
+      693,  691, 1163, 1163, 1163,  692,  693,  145,  146,  146,
       146,  146,  146,  146,  146,  146,  146,  146,  146,  146,
-      146,  146,  146, 1746,  146,  146,  146,  146,  146,  192,
+      146,  146,  146, 1724,  146,  146,  146,  146,  146,  192,
 
-      192,  192,  193,  193,  193,  194,  194,  194, 1747,  195,
-      195,  195,  196,  196,  196,  192, 1750, 1757,  193,  733,
-      736,  194, 1769,  146,  146,  195,  733,  736,  196,  146,
-      743, 1770,  733,  736,  146,  900,  900,  900, 1778,  900,
-     1781,  743, 1791, 1795,  743, 1802,  146,  149,  149,  149,
+      192,  192,  193,  193,  193,  194,  194,  194, 1725,  195,
+      195,  195,  196,  196,  196,  192, 1727, 1731,  193,  733,
+      736,  194, 1735,  146,  146,  195,  733,  736,  196,  146,
+      743, 1737,  733,  736,  146,  902,  902,  902, 1744,  902,
+     1745,  743, 1746, 1747,  743, 1749,  146,  149,  149,  149,
       149,  149,  149,  149,  149,  149,  149,  149,  149,  149,
       149,  149,  149,  149,  149,  149,  149,  149,  149,  149,
       149,  149,  149,  149,  149,  149,  149,  149,  149,  149,
@@ -3191,1123 +3212,1131 @@ static yyconst flex_int16_t yy_chk[12047] =
       149,  149,  149,  149,  149,  149,  149,  149,  149,  149,
       149,  149,  149,  149,  149,  149,  149,  149,  149,  149,
       149,  153,  153,  153,  153,  153,  153,  153,  153,  153,
-      153,  153,  153,  153,  153,  153, 1803,  153,  153,  153,
+      153,  153,  153,  153,  153,  153, 1753,  153,  153,  153,
       153,  153,  197,  197,  197,  198,  198,  198,  201,  201,
-      201, 1804,  202,  202,  202,  205,  205,  205,  197, 1031,
-     1805,  198, 1233, 1814,  201, 1818,  153,  153,  202, 1031,
-      153,  205,  912,  912,  912, 1233, 1031,  153, 1821, 1823,
-      153,  934,  934,  934,  153, 1825,  153,  153,  154,  154,
+      201, 1754,  202,  202,  202,  205,  205,  205,  197, 1033,
+     1755,  198, 1758, 1765,  201, 1777,  153,  153,  202, 1033,
+      153,  205,  914,  914,  914, 1778, 1033,  153, 1786, 1789,
+      153,  936,  936,  936,  153, 1799,  153,  153,  154,  154,
       154,  154,  154,  154,  154,  154,  154,  154,  154,  154,
 
-      154,  154,  154, 1826,  154,  154,  154,  154,  154,  206,
-      206,  206,  207,  207,  207,  208,  208,  208, 1828,  209,
-      209,  209,  210,  210,  210,  206, 1829, 1830,  207, 1833,
-     1835,  208, 1837,  154,  154,  209,  912,  154,  210,  946,
-      946,  946, 1842,  946,  154,  934,  946,  154, 1174, 1174,
-     1174,  154, 1848,  154,  154,  157,  157,  157,  157,  157,
+      154,  154,  154, 1803,  154,  154,  154,  154,  154,  206,
+      206,  206,  207,  207,  207,  208,  208,  208, 1807,  209,
+      209,  209,  210,  210,  210,  206, 1808, 1812,  207, 1813,
+     1814,  208, 1815,  154,  154,  209,  914,  154,  210,  948,
+      948,  948, 1824,  948,  154,  936,  948,  154, 1178, 1178,
+     1178,  154, 1828,  154,  154,  157,  157,  157,  157,  157,
       157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-     1852,  157,  157,  157,  157,  157,  211,  211,  211,  212,
-      212,  212,  215,  215,  215, 1853,  216,  216,  216,  701,
-      701,  701,  211, 1854, 1856,  212, 1864, 1868,  215, 1871,
-
-      157,  157,  216,  157,  157,  157,  701, 1872,  954,  954,
-      954,  157,  954, 1864,  157,  954, 1873, 1875,  157, 1865,
-     1876,  157,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158, 1878,  158,  158,
+     1831,  157,  157,  157,  157,  157,  211,  211,  211,  212,
+      212,  212,  215,  215,  215, 1833,  216,  216,  216,  701,
+      701,  701,  211, 1835, 1836,  212, 1838, 1839,  215, 1840,
+
+      157,  157,  216,  157,  157,  157,  701, 1843,  956,  956,
+      956,  157,  956, 1845,  157,  956, 1847, 1852,  157, 1858,
+     1862,  157,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158, 1863,  158,  158,
       158,  158,  158,  217,  217,  217,  218,  218,  218,  219,
-      219,  219, 1879,  220,  220,  220,  709,  709,  709,  217,
-     1880, 1865,  218, 1882, 1874,  219, 1883,  158,  158,  220,
-      158,  158,  158,  709, 1884,  969,  969,  969,  158,  969,
-     1874,  158,  969, 1888, 1890,  158, 1866, 1893,  158,  161,
+      219,  219, 1864,  220,  220,  220,  709,  709,  709,  217,
+     1866, 1878,  218, 1874, 1881,  219, 1882,  158,  158,  220,
+      158,  158,  158,  709, 1883,  971,  971,  971,  158,  971,
+     1874,  158,  971, 1885, 1886,  158, 1875, 1888,  158,  161,
       161,  161,  161,  161,  161,  161,  161,  161,  161,  161,
 
-      161,  161,  161,  161, 1894,  161,  161,  161,  161,  161,
-      221,  221,  221,  222,  222,  222,  225,  225,  225, 1866,
-      226,  226,  226,  725,  725,  725,  221, 1895, 1896,  222,
-     1898, 1900,  225, 1901,  161,  161,  226, 1903, 1905,  161,
-      725, 1230, 1230, 1230, 1908,  161,  162,  162,  162,  162,
+      161,  161,  161,  161, 1876,  161,  161,  161,  161,  161,
+      221,  221,  221,  222,  222,  222,  225,  225,  225, 1889,
+      226,  226,  226,  725,  725,  725,  221, 1890, 1875,  222,
+     1892, 1893,  225, 1894,  161,  161,  226, 1876, 1898,  161,
+      725, 1234, 1234, 1234, 1900,  161,  162,  162,  162,  162,
       162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162, 1909,  162,  162,  162,  162,  162,  227,  227,  227,
-      228,  228,  228,  229,  229,  229, 1910,  230,  230,  230,
-      749,  749,  749,  227, 1910, 1911,  228, 1912, 1913,  229,
-     1915,  162,  162,  230, 1921, 1922,  162,  749, 1479, 1479,
+      162, 1903,  162,  162,  162,  162,  162,  227,  227,  227,
+      228,  228,  228,  229,  229,  229, 1904,  230,  230,  230,
+      749,  749,  749,  227, 1905, 1884,  228, 1906, 1908,  229,
+     1910,  162,  162,  230, 1911, 1913,  162,  749, 1485, 1485,
 
-     1479, 1924,  162,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165,  165,  165,  165,  165, 1927,  165,
+     1485, 1884,  162,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165, 1915,  165,
       165,  165,  165,  165,  231,  231,  231,  232,  232,  232,
-      235,  235,  235, 1914,  236,  236,  236,  239,  239,  239,
-      231, 1914, 1923,  232, 1928, 1929,  235, 1943,  165,  165,
-      236, 1944,  165,  239,  973,  973,  973, 1949, 1923,  165,
-     1928, 1929,  165,  166,  166,  166,  166,  166,  166,  166,
-      166,  166,  166,  166,  166,  166,  166,  166, 1950,  166,
+      235,  235,  235, 1918,  236,  236,  236,  239,  239,  239,
+      231, 1919, 1921,  232, 1922, 1923,  235, 1925,  165,  165,
+      236, 1931,  165,  239,  975,  975,  975, 1932, 1934,  165,
+     1937, 1953,  165,  166,  166,  166,  166,  166,  166,  166,
+      166,  166,  166,  166,  166,  166,  166,  166, 1954,  166,
       166,  166,  166,  166,  240,  240,  240,  241,  241,  241,
-      242,  242,  242, 1951,  243,  243,  243,  244,  244,  244,
+      242,  242,  242, 1920,  243,  243,  243,  244,  244,  244,
 
-      240, 1955, 1957,  241, 1963, 1970,  242, 1971,  166,  166,
-      243, 1972,  166,  244,  982,  982,  982, 1985,  973,  166,
-     1991, 1995,  166,  169,  169,  169,  169,  169,  169,  169,
-      169,  169,  169,  169,  169,  169,  169,  169, 1998,  169,
+      240, 1920, 1959,  241, 1933, 1938,  242, 1960,  166,  166,
+      243, 1961,  166,  244,  984,  984,  984, 1965,  975,  166,
+     1933, 1938,  166,  169,  169,  169,  169,  169,  169,  169,
+      169,  169,  169,  169,  169,  169,  169,  169, 1967,  169,
       169,  169,  169,  169,  245,  245,  245,  246,  246,  246,
-      249,  249,  249, 2000,  250,  250,  250,  756,  756,  756,
-      245, 2003, 2005,  246, 2007, 2008,  249,  358,  169,  169,
-      250, 2009,  169,  292,  756, 2012, 2014,  358,  982,  169,
-     2019, 2021,  169,  292, 2029, 2030,  364, 2031, 2032,  169,
+      249,  249,  249, 1924,  250,  250,  250,  756,  756,  756,
+      245, 1924, 1973,  246, 1939, 1974,  249,  358,  169,  169,
+      250, 1975,  169,  292,  756, 1982, 1983,  358,  984,  169,
+     1939, 1984,  169,  292, 1997, 2003,  364, 2007, 2010,  169,
       170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
 
       170,  170,  170,  170,  170,  358,  170,  170,  170,  170,
-      170, 2034,  292, 2048,  364,  761,  761,  761,  292,  358,
-      773,  773,  773,  358, 2053,  292,  785,  785,  785,  292,
-      364, 2054,  761, 2055, 2056,  170,  170,  773, 2060,  170,
-      989,  989,  989,  785,  989, 2062,  170,  989, 2063,  170,
-     1480, 1480, 1480, 1482, 1482, 1482,  170,  179,  179,  179,
+      170, 2012,  292, 2015,  364,  761,  761,  761,  292,  358,
+      773,  773,  773,  358, 2017,  292,  785,  785,  785,  292,
+      364, 2019,  761, 2020, 2021,  170,  170,  773, 2024,  170,
+      991,  991,  991,  785,  991, 2026,  170,  991, 2031,  170,
+     1486, 1486, 1486, 1488, 1488, 1488,  170,  179,  179,  179,
       179,  179,  179,  179,  179,  179,  179,  179,  179,  179,
-      179,  179, 2064,  179,  179,  179,  179,  179,  786,  786,
-      786,  792,  792,  792,  794,  794,  794,  806,  806,  806,
-      807,  807,  807, 2047, 2045,  786, 1480, 2069,  792, 1482,
-
-     2045,  794,  179,  179,  806, 2076, 2078,  807,  179,  996,
-      996,  996, 2079,  996, 2082, 2085,  996, 1485, 1485, 1485,
-     1488, 1488, 1488,  179,  180,  180,  180,  180,  180,  180,
-      180,  180,  180,  180,  180,  180,  180,  180,  180, 2047,
-      180,  180,  180,  180,  180,  819,  819,  819,  827,  827,
-      827,  832,  832,  832,  838,  838,  838,  860,  860,  860,
-     2089, 2090,  819, 2091, 2092,  827, 2093, 2094,  832,  180,
-      180,  838, 2095, 2096,  860,  180, 1001, 1001, 1001, 2097,
-     1001, 2098, 2103, 1001, 1498, 1498, 1498, 1534, 1534, 1534,
+      179,  179, 2033,  179,  179,  179,  179,  179,  786,  786,
+      786,  792,  792,  792,  794,  794,  794,  808,  808,  808,
+      809,  809,  809, 2041, 2042,  786, 1486, 2043,  792, 1488,
+
+     2044,  794,  179,  179,  808, 2046, 2057,  809,  179,  998,
+      998,  998, 2057,  998, 2059, 2060,  998, 1491, 1491, 1491,
+     1494, 1494, 1494,  179,  180,  180,  180,  180,  180,  180,
+      180,  180,  180,  180,  180,  180,  180,  180,  180, 2065,
+      180,  180,  180,  180,  180,  821,  821,  821,  829,  829,
+      829,  834,  834,  834,  840,  840,  840,  862,  862,  862,
+     2059, 2066,  821, 2067, 2068,  829, 2072, 2074,  834,  180,
+      180,  840, 2075, 2076,  862,  180, 1003, 1003, 1003, 2081,
+     1003, 2088, 2090, 1003, 1504, 1504, 1504, 1540, 1540, 1540,
       180,  189,  189,  189,  189,  189,  189,  189,  189,  189,
 
-      189,  189,  189,  189,  189,  189, 2104,  189,  189,  189,
-      189,  189,  888,  888,  888,  892,  892,  892, 2046, 2105,
-      910,  910,  910,  911,  911,  911,  942,  942,  942,  888,
-     2106, 2124,  892,  943,  943,  943,  189,  189,  910, 2125,
-     2128,  911,  189, 2129,  942,  189, 1013, 1013, 1013, 2046,
-     1013,  943, 2131, 1013, 1537, 1537, 1537,  189,  190,  190,
+      189,  189,  189,  189,  189,  189, 2091,  189,  189,  189,
+      189,  189,  890,  890,  890,  894,  894,  894, 2058, 2094,
+      912,  912,  912,  913,  913,  913,  944,  944,  944,  890,
+     2097, 2101,  894,  945,  945,  945,  189,  189,  912, 2102,
+     2103,  913,  189, 2104,  944,  189, 1015, 1015, 1015, 2058,
+     1015,  945, 2105, 1015, 1543, 1543, 1543,  189,  190,  190,
       190,  190,  190,  190,  190,  190,  190,  190,  190,  190,
-      190,  190,  190, 2135,  190,  190,  190,  190,  190, 2141,
-     2142,  911,  945,  945,  945, 2143, 2157,  949,  949,  949,
-      950,  950,  950,  943,  953,  953,  953, 2161, 2126,  945,
+      190,  190,  190, 2106,  190,  190,  190,  190,  190, 2107,
+     2108,  913,  947,  947,  947, 2109, 2110,  951,  951,  951,
+      952,  952,  952,  945,  955,  955,  955, 2115, 2116,  947,
 
-      955,  955,  955,  190,  190,  949, 2126, 2162,  950,  190,
-     2163,  953,  190, 2165, 1025, 1025, 1025,  955, 1025, 2169,
-     2172, 1025, 2173, 2176,  190,  199,  199,  199,  199,  199,
+      957,  957,  957,  190,  190,  951, 2117, 2118,  952,  190,
+     2136,  955,  190, 2137, 1027, 1027, 1027,  957, 1027, 2140,
+     2141, 1027, 2143, 2147,  190,  199,  199,  199,  199,  199,
       199,  199,  199,  199,  199,  199,  199,  199,  199,  199,
-     2177,  199,  199,  199,  199,  199,  957,  957,  957,  961,
-      961,  961, 2180, 2187,  950, 2189,  962,  962,  962,  966,
-      966,  966, 2204,  957, 1535, 1535, 1535,  961, 2218, 2219,
-      199,  199, 2222, 2229,  962, 2230,  199,  966, 1686, 1686,
-     1686,  199,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200, 2235,  200,  200,
-
-      200,  200,  200,  962,  967,  967,  967,  968,  968,  968,
-     1535,  971,  971,  971,  988,  988,  988,  972,  972,  972,
-     1731, 2237,  967, 2249,  968, 2250, 1731,  200,  200,  971,
-     1731,  988, 2251,  200, 1731,  972, 2208, 2252,  200,  203,
+     2148,  199,  199,  199,  199,  199,  959,  959,  959,  963,
+      963,  963, 2149, 2155,  952, 2156,  964,  964,  964,  968,
+      968,  968, 2157,  959, 1541, 1541, 1541,  963, 2171, 2175,
+      199,  199, 2176, 2177,  964, 2179,  199,  968, 1694, 1694,
+     1694,  199,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200, 2183,  200,  200,
+
+      200,  200,  200,  964,  969,  969,  969,  970,  970,  970,
+     1541,  973,  973,  973,  990,  990,  990,  974,  974,  974,
+     1739, 2186,  969, 2187,  970, 2190, 1739,  200,  200,  973,
+     1739,  990, 2191,  200, 1739,  974, 2194, 2201,  200,  203,
       203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
-      203,  203,  203,  203,  972,  203,  203,  203,  203,  203,
-      992,  992,  992,  993,  993,  993, 1732, 2253,  967,  995,
-      995,  995, 1732,  998,  998,  998, 1732, 2254,  992, 2208,
-     1732,  993, 2255, 2256,  203,  203,  995, 1000, 1000, 1000,
-      203,  998, 1027, 1027, 1027, 2257, 1027, 2258, 2265, 1027,
+      203,  203,  203,  203,  974,  203,  203,  203,  203,  203,
+      994,  994,  994,  995,  995,  995, 1740, 2203,  969,  997,
+      997,  997, 1740, 1000, 1000, 1000, 1740, 2218,  994, 2232,
+     1740,  995, 2233, 2236,  203,  203,  997, 1002, 1002, 1002,
+      203, 1000, 1029, 1029, 1029, 2243, 1029, 2244, 2249, 1029,
 
-     2266, 1536, 1536, 1536, 1000,  203,  204,  204,  204,  204,
+     2251, 1542, 1542, 1542, 1002,  203,  204,  204,  204,  204,
       204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204, 2267,  204,  204,  204,  204,  204, 2269, 2279,  993,
-      999,  999,  999, 2280, 2281, 1003, 1003, 1003, 1004, 1004,
-     1004, 1007, 1007, 1007, 1008, 1008, 1008, 1536,  999, 2282,
-     2127,  204,  204, 1003, 2283, 2284, 1004,  204, 2127, 1007,
-     2174, 2175, 1008, 1033, 1033, 1033, 2285, 1033, 2174, 2175,
-     1033, 2288,  204,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213, 2209,  213,
-      213,  213,  213,  213, 2289, 2294,  999, 2295, 2301, 1004,
-
-     1012, 1012, 1012, 1016, 1016, 1016, 1024, 1024, 1024, 1008,
-     1017, 1017, 1017, 1021, 1021, 1021, 2302, 1012,  213,  213,
-     2303, 1016, 2304, 1024,  213, 2318, 2319,  213, 1017, 2320,
-     2321, 1021, 1689, 1689, 1689, 2209, 1627, 1627, 1627,  213,
+      204, 2263,  204,  204,  204,  204,  204, 2264, 2222,  995,
+     1001, 1001, 1001, 2265, 2266, 1005, 1005, 1005, 1006, 1006,
+     1006, 1009, 1009, 1009, 1010, 1010, 1010, 1542, 1001, 2267,
+     2138,  204,  204, 1005, 2268, 2269, 1006,  204, 2138, 1009,
+     2139, 2188, 1010, 1035, 1035, 1035, 2270, 1035, 2139, 2188,
+     1035, 2222,  204,  213,  213,  213,  213,  213,  213,  213,
+      213,  213,  213,  213,  213,  213,  213,  213, 2223,  213,
+      213,  213,  213,  213, 2271, 2272, 1001, 2279, 2280, 1006,
+
+     1014, 1014, 1014, 1018, 1018, 1018, 1026, 1026, 1026, 1010,
+     1019, 1019, 1019, 1023, 1023, 1023, 2281, 1014,  213,  213,
+     2283, 1018, 2189, 1026,  213, 2293, 2294,  213, 1019, 2295,
+     2189, 1023, 1697, 1697, 1697, 2223, 1635, 1635, 1635,  213,
       214,  214,  214,  214,  214,  214,  214,  214,  214,  214,
-      214,  214,  214,  214,  214, 2323,  214,  214,  214,  214,
-      214, 1026, 1026, 1026, 2325, 2342, 1022, 1022, 1022, 2348,
-     2349, 1017, 1028, 1028, 1028, 1029, 1029, 1029, 1026, 1032,
-     1032, 1032, 1627, 2354, 1022,  214,  214, 1035, 1035, 1035,
-     1028,  214, 2355, 1029,  214, 2356, 1032, 2342, 1036, 1036,
+      214,  214,  214,  214,  214, 2296,  214,  214,  214,  214,
+      214, 1028, 1028, 1028, 2297, 2298, 1024, 1024, 1024, 2299,
+     2302, 1019, 1030, 1030, 1030, 1031, 1031, 1031, 1028, 1034,
+     1034, 1034, 1635, 2303, 1024,  214,  214, 1037, 1037, 1037,
+     1030,  214, 2304, 1031,  214, 2310, 1034, 2311, 1038, 1038,
 
-     1036, 2359, 1036, 2362, 1035, 1036,  214,  223,  223,  223,
+     1038, 2317, 1038, 2318, 1037, 1038,  214,  223,  223,  223,
       223,  223,  223,  223,  223,  223,  223,  223,  223,  223,
-      223,  223, 2343,  223,  223,  223,  223,  223, 1022, 1037,
-     1037, 1037, 1045, 1045, 1045, 2363, 1029, 1046, 1046, 1046,
-     1047, 1047, 1047, 1056, 1056, 1056, 1037, 1048, 1048, 1048,
-     1045, 1048,  223,  223, 1048, 1046, 2364, 1047, 2365, 2343,
-      223, 1056,  223, 2366, 2367,  223, 1691, 1691, 1691,  223,
-     1693, 1693, 1693,  223,  224,  224,  224,  224,  224,  224,
-      224,  224,  224,  224,  224,  224,  224,  224,  224, 2368,
-      224,  224,  224,  224,  224, 1046, 1049, 1049, 1049, 1050,
-
-     1050, 1050, 2369, 1050, 2370, 2371, 1050, 1051, 1051, 1051,
-     1066, 1066, 1066, 1049, 1052, 1052, 1052, 2372, 2374,  224,
-      224, 1053, 1053, 1053, 1051, 2375, 2377,  224, 1066,  224,
-     2376, 1052,  224, 1696, 1696, 1696,  224, 2378, 1053, 2376,
+      223,  223, 2319,  223,  223,  223,  223,  223, 1024, 1039,
+     1039, 1039, 1049, 1049, 1049, 2320, 1031, 1050, 1050, 1050,
+     1051, 1051, 1051, 1060, 1060, 1060, 1039, 1052, 1052, 1052,
+     1049, 1052,  223,  223, 1052, 1050, 2334, 1051, 2335, 2336,
+      223, 1060,  223, 2337, 2339,  223, 1699, 1699, 1699,  223,
+     1701, 1701, 1701,  223,  224,  224,  224,  224,  224,  224,
+      224,  224,  224,  224,  224,  224,  224,  224,  224, 2341,
+      224,  224,  224,  224,  224, 1050, 1053, 1053, 1053, 1054,
+
+     1054, 1054, 2359, 1054, 2364, 2358, 1054, 1055, 1055, 1055,
+     1070, 1070, 1070, 1053, 1056, 1056, 1056, 2365, 2370,  224,
+      224, 1057, 1057, 1057, 1055, 2371, 2372,  224, 1070,  224,
+     2375, 1056,  224, 1704, 1704, 1704,  224, 2358, 1057, 2359,
       224,  233,  233,  233,  233,  233,  233,  233,  233,  233,
-      233,  233,  233,  233,  233,  233, 2379,  233,  233,  233,
-      233,  233, 1057, 1057, 1057, 1052, 1061, 1061, 1061, 1706,
-     1706, 1706, 2380, 1053, 1055, 1055, 1055, 1054, 1054, 1054,
-     1057, 2381, 2383, 1061, 2382, 2384,  233,  233, 1062, 1062,
-     1062, 1055, 1062, 2382, 1054, 1062, 1070, 1070, 1070, 2385,
+      233,  233,  233,  233,  233,  233, 2378,  233,  233,  233,
+      233,  233, 1061, 1061, 1061, 1056, 1065, 1065, 1065, 1714,
+     1714, 1714, 2305, 1057, 1059, 1059, 1059, 1058, 1058, 1058,
+     1061, 2379, 2305, 1065, 2380, 2381,  233,  233, 1066, 1066,
+     1066, 1059, 1066, 2382, 1058, 1066, 1074, 1074, 1074, 2383,
 
-     1070, 2387, 2388, 1070, 2390, 1698, 1698, 1698, 2395, 1057,
+     1074, 2384, 2385, 1074, 2386, 1706, 1706, 1706, 2387, 1061,
       233,  234,  234,  234,  234,  234,  234,  234,  234,  234,
-      234,  234,  234,  234,  234,  234, 1055,  234,  234,  234,
-      234,  234, 1054, 1063, 1063, 1063, 1069, 1069, 1069, 2396,
-     1071, 1071, 1071, 2397, 2399, 1067, 1067, 1067, 2404, 2405,
-     1063, 2408, 2414, 1069, 2415, 2417,  234,  234, 1071, 1072,
-     1072, 1072, 2426, 1067, 1075, 1075, 1075, 2428, 1075, 1698,
-     2431, 1075, 1081, 1081, 1081, 2433, 1081, 1072, 2452, 1081,
+      234,  234,  234,  234,  234,  234, 1059,  234,  234,  234,
+      234,  234, 1058, 1067, 1067, 1067, 1073, 1073, 1073, 2388,
+     1075, 1075, 1075, 2390, 2391, 1071, 1071, 1071, 2393, 2394,
+     1067, 2395, 2396, 1073, 2397, 2399,  234,  234, 1075, 1076,
+     1076, 1076, 2400, 1071, 1079, 1079, 1079, 2401, 1079, 1706,
+     2403, 1079, 1085, 1085, 1085, 2404, 1085, 1076, 2406, 1085,
       234,  237,  237,  237,  237,  237,  237,  237,  237,  237,
-      237,  237,  237,  237,  237,  237, 1067,  237,  237,  237,
+      237,  237,  237,  237,  237,  237, 1071,  237,  237,  237,
 
-      237,  237, 1074, 1074, 1074, 1077, 1077, 1077, 1080, 1080,
-     1080, 2457, 1078, 1078, 1078, 1085, 1085, 1085, 2452, 1074,
-     1072, 2458, 2460, 1077, 2454, 1080,  237,  237, 2461, 2462,
-     1078, 2467, 2468, 1085, 1700, 1700, 1700,  237,  238,  238,
+      237,  237, 1078, 1078, 1078, 1081, 1081, 1081, 1084, 1084,
+     1084, 2411, 1082, 1082, 1082, 1089, 1089, 1089, 2412, 1078,
+     1076, 2413, 2392, 1081, 2415, 1084,  237,  237, 2420, 2421,
+     1082, 2392, 2422, 1089, 1708, 1708, 1708,  237,  238,  238,
       238,  238,  238,  238,  238,  238,  238,  238,  238,  238,
-      238,  238,  238, 2469,  238,  238,  238,  238,  238, 1078,
-     2470, 1086, 1086, 1086, 1087, 1087, 1087, 2454, 1088, 1088,
-     1088, 1089, 1089, 1089, 1090, 1090, 1090, 2471, 2472, 1086,
-     1700, 1087, 2473,  238,  238, 1088, 2474, 2475, 1089, 1740,
-     1740, 1740, 1090, 2476,  238,  247,  247,  247,  247,  247,
+      238,  238,  238, 2423,  238,  238,  238,  238,  238, 1082,
+     2424, 1090, 1090, 1090, 1091, 1091, 1091, 2427, 1092, 1092,
+     1092, 1093, 1093, 1093, 1094, 1094, 1094, 2398, 2433, 1090,
+     1708, 1091, 2434,  238,  238, 1092, 2398, 2436, 1093, 1748,
+     1748, 1748, 1094, 2445,  238,  247,  247,  247,  247,  247,
 
       247,  247,  247,  247,  247,  247,  247,  247,  247,  247,
-     2477,  247,  247,  247,  247,  247, 1086, 2479, 2480, 1091,
-     1091, 1091, 1093, 1093, 1093, 1742, 1742, 1742, 2481, 2482,
-     1089, 1095, 1095, 1095, 1097, 1097, 1097, 1091, 2483, 1093,
-      247,  247, 1094, 1094, 1094, 1096, 1096, 1096, 1095, 2453,
-     2484,  247, 1097, 1101, 1101, 1101, 2485, 1101, 2486, 1094,
-     1101, 2487, 1096, 2488,  247,  248,  248,  248,  248,  248,
+     2447,  247,  247,  247,  247,  247, 1090, 2450, 2452, 1095,
+     1095, 1095, 1097, 1097, 1097, 1750, 1750, 1750, 2476, 2477,
+     1093, 1099, 1099, 1099, 1101, 1101, 1101, 1095, 2479, 1097,
+      247,  247, 1098, 1098, 1098, 1100, 1100, 1100, 1099, 2472,
+     2471,  247, 1101, 1105, 1105, 1105, 2480, 1105, 2481, 1098,
+     1105, 2486, 1100, 2473,  247,  248,  248,  248,  248,  248,
       248,  248,  248,  248,  248,  248,  248,  248,  248,  248,
-     1091,  248,  248,  248,  248,  248, 2453, 1098, 1098, 1098,
-     2489, 2490, 1094, 2491, 2492, 1100, 1100, 1100, 1102, 1102,
-
-     1102, 1103, 1103, 1103, 1096, 1098, 2493, 1094, 2494, 2496,
-      248,  248, 1100, 1104, 1104, 1104, 1102, 2500, 2507, 1103,
-     2508,  248, 2512, 2515, 1098, 2556, 1105, 1105, 1105, 2558,
-     1104, 1106, 1106, 1106,  248,  290, 1107, 1107, 1107, 1111,
-     1111, 1111,  290, 1105, 1108, 1108, 1108, 2559, 2560, 1106,
-     2554,  290,  290, 2555, 1107, 2553, 1103, 1111, 1109, 1109,
-     1109, 1108, 1743, 1743, 1743, 1110, 1110, 1110, 2563, 2564,
-     1112, 1112, 1112, 2538, 2566, 1109, 1124, 1124, 1124,  290,
-      290,  290, 1110, 2538, 2553,  290,  290,  290, 1112, 2538,
-      290,  290, 2554, 1124,  290, 2555,  290,  290,  290,  355,
-
-     1118, 1118, 1118, 1119, 1119, 1119,  355, 1107, 1109, 1122,
-     1122, 1122, 1123, 1123, 1123,  355,  355, 2567, 1118, 2465,
-     2565, 1119, 2569, 1109, 1125, 1125, 1125, 1122, 1125, 2465,
-     1123, 1125, 2465, 2565, 1126, 1126, 1126, 2570, 1127, 1127,
-     1127, 1112, 2571,  355,  355,  355, 1128, 1128, 1128,  355,
-      355,  355, 1126, 2572,  355,  355, 1127, 2568,  355, 2539,
-      355,  355,  355, 1128, 1129, 1129, 1129, 1119, 1129, 2539,
-     2568, 1129, 1131, 1131, 1131, 2539, 1123, 1132, 1132, 1132,
-     1147, 1147, 1147, 1148, 1148, 1148, 1150, 1150, 1150, 2573,
-     1131, 1181, 1181, 1181, 2575, 1132, 2576, 2577, 1147, 1127,
-
-     2578, 1148, 2581, 2582, 1150, 1182, 1182, 1182, 1181, 1183,
-     1183, 1183, 1185, 1185, 1185, 1186, 1186, 1186, 1187, 1187,
-     1187, 2583, 1187, 1182, 2584, 1187, 2585, 1183, 2586, 2587,
-     1185, 2588, 1186, 1150, 1190, 1190, 1190, 1192, 1192, 1192,
-     2589, 1132, 1193, 1193, 1193, 1195, 1195, 1195, 1200, 1200,
-     1200, 1190, 1197, 1197, 1197, 1192, 1197, 2590, 2591, 1197,
-     1193, 1185, 2592, 1195, 2593, 1200, 1201, 1201, 1201, 2594,
-     1201, 2595, 2597, 1201, 1202, 1202, 1202, 1203, 1203, 1203,
-     1204, 1204, 1204, 2607, 1204, 2608, 2609, 1204, 1206, 1206,
-     1206, 1202, 1195, 2613, 1203, 1190, 1208, 1208, 1208, 1209,
-
-     1209, 1209, 1211, 1211, 1211, 1206, 1213, 1213, 1213, 1215,
-     1215, 1215, 2631, 2632, 1208, 2633, 2634, 1209, 2635, 2636,
-     1211, 2640, 2648, 1213, 1216, 1216, 1216, 1215, 1218, 1218,
-     1218, 1219, 1219, 1219, 2640, 1219, 2651, 2652, 1219, 1223,
-     1223, 1223, 1216, 1224, 1224, 1224, 1218, 1226, 1226, 1226,
-     2466, 1241, 1241, 1241, 2646, 1241, 2656, 1223, 1241, 2645,
-     2466, 1224, 1211, 2466, 2657, 1226, 1245, 1245, 1245, 1246,
-     1246, 1246, 1247, 1247, 1247, 1218, 1249, 1249, 1249, 1255,
-     1255, 1255, 2641, 1245, 1251, 1251, 1251, 1246, 1251, 2646,
-     1247, 1251, 2658, 2659, 1249, 2641, 2660, 1255, 1256, 1256,
-
-     1256, 1258, 1258, 1258, 1259, 1259, 1259, 2645, 1259, 2661,
-     2662, 1259, 1262, 1262, 1262, 2663, 1256, 2665, 2666, 1258,
-     1263, 1263, 1263, 1264, 1264, 1264, 1266, 1266, 1266, 1262,
-     1267, 1267, 1267, 1268, 1268, 1268, 2667, 1249, 1263, 2668,
-     2669, 1264, 2670, 2671, 1266, 2672, 2674, 1267, 2675, 2676,
-     1268, 1269, 1269, 1269, 1270, 1270, 1270, 1272, 1272, 1272,
-     2677, 1268, 1258, 1275, 1275, 1275, 1276, 1276, 1276, 1269,
-     1276, 2678, 1270, 1276, 2679, 1272, 1281, 1281, 1281, 2680,
-     1275, 1282, 1282, 1282, 1284, 1284, 1284, 1287, 1287, 1287,
-     1288, 1288, 1288, 1266, 1281, 1289, 1289, 1289, 2681, 1282,
-
-     2682, 2683, 1284, 2684, 1287, 1292, 1292, 1292, 1288, 1291,
-     1291, 1291, 2685, 1289, 1293, 1293, 1293, 2686, 1293, 2687,
-     2688, 1293, 1292, 1272, 1296, 1296, 1296, 1291, 1296, 2694,
-     2698, 1296, 1299, 1299, 1299, 1300, 1300, 1300, 1302, 1302,
-     1302, 1307, 1307, 1307, 2699, 1307, 2700, 2701, 1307, 1284,
-     1299, 2718, 2719, 1300, 2720, 2713, 1302, 1310, 1310, 1310,
-     1311, 1311, 1311, 2721, 1311, 2713, 2722, 1311, 1314, 1314,
-     1314, 1315, 1315, 1315, 1310, 1315, 1291, 2723, 1315, 1323,
-     1323, 1323, 1324, 1324, 1324, 1314, 1326, 1326, 1326, 1327,
-     1327, 1327, 2714, 1327, 2726, 2727, 1327, 1323, 2716, 2728,
-
-     1324, 2717, 2714, 1302, 1326, 1330, 1330, 1330, 2716, 1330,
-     2729, 2717, 1330, 1333, 1333, 1333, 1334, 1334, 1334, 2738,
-     1334, 2730, 2739, 1334, 1339, 1339, 1339, 1340, 1340, 1340,
-     1333, 1342, 1342, 1342, 1347, 1347, 1347, 2740, 1347, 2741,
-     2742, 1347, 1339, 2743, 2744, 1340, 1350, 1350, 1350, 1342,
-     1351, 1351, 1351, 1326, 1351, 2730, 2745, 1351, 1354, 1354,
-     1354, 2748, 2749, 1350, 1355, 1355, 1355, 1357, 1357, 1357,
-     1359, 1359, 1359, 2751, 1359, 2752, 1354, 1359, 2753, 1342,
-     2755, 2757, 1355, 2758, 2759, 1357, 1362, 1362, 1362, 1363,
-     1363, 1363, 1365, 1365, 1365, 1367, 1367, 1367, 2762, 1367,
-
-     2763, 2764, 1367, 2765, 1362, 2766, 2769, 1363, 2770, 2777,
-     1365, 1371, 1371, 1371, 1372, 1372, 1372, 2778, 1357, 1374,
-     1374, 1374, 2779, 1376, 1376, 1376, 2781, 1376, 2787, 1371,
-     1376, 2788, 1372, 1382, 1382, 1382, 2789, 1374, 1383, 1383,
-     1383, 2790, 1385, 1385, 1385, 1386, 1386, 1386, 1387, 1387,
-     1387, 1382, 1387, 2791, 2792, 1387, 1383, 2793, 2794, 1365,
-     1385, 2795, 1386, 1388, 1388, 1388, 2796, 2798, 1374, 1389,
-     1389, 1389, 2799, 1389, 2804, 2805, 1389, 1391, 1391, 1391,
-     1388, 1392, 1392, 1392, 2806, 1394, 1394, 1394, 1396, 1396,
-     1396, 2807, 1400, 1400, 1400, 1391, 1708, 1708, 1708, 1392,
-
-     2817, 2808, 1385, 1394, 2818, 1396, 1397, 1397, 1397, 1400,
-     1397, 2819, 2820, 1397, 1401, 1401, 1401, 2821, 1401, 2822,
-     2823, 1401, 1403, 1403, 1403, 1404, 1404, 1404, 1406, 1406,
-     1406, 1408, 1408, 1408, 2824, 1408, 2828, 2829, 1408, 2830,
-     1403, 2831, 1708, 1404, 2808, 2832, 1406, 1411, 1411, 1411,
-     2833, 2835, 1394, 1412, 1412, 1412, 1414, 1414, 1414, 1415,
-     1415, 1415, 1416, 1416, 1416, 1411, 1416, 2836, 2838, 1416,
-     2839, 1412, 2840, 2841, 1414, 2843, 1415, 1417, 1417, 1417,
-     1418, 1418, 1418, 2844, 1418, 2848, 2849, 1418, 1419, 1419,
-     1419, 2850, 1406, 2853, 1417, 1420, 1420, 1420, 2858, 1422,
-
-     1422, 1422, 1423, 1423, 1423, 2859, 1419, 1424, 1424, 1424,
-     2860, 1424, 2861, 1420, 1424, 2862, 1414, 1422, 2863, 1423,
-     1427, 1427, 1427, 1428, 1428, 1428, 2864, 1428, 2865, 2866,
-     1428, 1429, 1429, 1429, 1430, 1430, 1430, 1427, 1432, 1432,
-     1432, 1434, 1434, 1434, 1438, 1438, 1438, 2867, 2868, 1429,
-     2869, 2871, 1430, 1439, 1439, 1439, 1432, 2872, 1434, 2873,
-     2874, 1422, 1438, 1441, 1441, 1441, 1444, 1444, 1444, 2877,
-     2881, 1439, 1445, 1445, 1445, 1447, 1447, 1447, 1448, 1448,
-     1448, 1441, 1448, 2877, 1444, 1448, 1451, 1451, 1451, 2875,
-     1445, 2884, 2885, 1447, 1452, 1452, 1452, 1454, 1454, 1454,
-
-     1432, 1455, 1455, 1455, 1451, 1455, 2888, 2890, 1455, 1459,
-     1459, 1459, 1452, 2891, 2878, 1454, 1460, 1460, 1460, 1462,
-     1462, 1462, 2893, 2894, 1441, 2878, 2897, 1459, 1447, 1464,
-     1464, 1464, 2898, 2899, 1460, 2875, 2900, 1462, 1471, 1471,
-     1471, 1501, 1501, 1501, 1503, 1503, 1503, 1464, 1464, 2901,
-     1504, 1504, 1504, 1529, 1529, 1529, 1471, 1454, 1501, 1502,
-     1502, 1502, 1503, 1502, 2902, 2903, 1502, 1504, 1505, 1505,
-     1505, 1529, 1505, 2904, 2905, 1505, 1508, 1508, 1508, 2906,
-     1462, 1510, 1510, 1510, 2907, 1510, 2911, 2909, 1510, 1513,
-     1513, 1513, 2919, 2910, 1508, 2921, 1514, 1514, 1514, 2909,
-
-     1514, 2916, 1503, 1514, 1471, 2910, 1513, 1515, 1515, 1515,
-     2917, 1515, 2923, 2916, 1515, 1519, 1519, 1519, 2925, 1520,
-     1520, 1520, 2917, 1520, 2933, 1508, 1520, 1522, 1522, 1522,
-     2935, 2936, 1519, 1524, 1524, 1524, 1525, 1525, 1525, 2939,
-     1525, 2938, 2938, 1525, 2941, 1522, 1526, 1526, 1526, 2943,
-     1524, 1527, 1527, 1527, 1545, 1545, 1545, 1546, 1546, 1546,
-     1547, 1547, 1547, 1526, 1547, 2944, 2945, 1547, 2946, 1527,
-     2953, 1545, 2936, 2957, 1546, 2952, 2937, 1522, 1548, 1548,
-     1548, 1551, 1551, 1551, 1552, 1552, 1552, 1553, 1553, 1553,
-     2937, 1553, 2962, 2952, 1553, 2963, 1548, 2965, 2956, 1551,
-
-     1527, 1552, 1554, 1554, 1554, 1555, 1555, 1555, 1556, 1556,
-     1556, 2962, 1556, 2956, 2968, 1556, 1558, 1558, 1558, 2964,
-     1554, 2940, 1555, 1561, 1561, 1561, 1562, 1562, 1562, 2970,
-     1562, 2975, 2940, 1562, 1558, 1563, 1563, 1563, 2964, 2976,
-     1561, 2967, 1548, 2978, 2979, 1551, 1564, 1564, 1564, 1565,
-     1565, 1565, 1563, 1568, 1568, 1568, 2980, 1569, 1569, 1569,
-     2967, 1569, 1554, 1564, 1569, 2969, 2982, 1565, 2983, 2984,
-     1568, 1570, 1570, 1570, 1571, 1571, 1571, 1558, 1572, 1572,
-     1572, 2985, 1572, 2987, 2969, 1572, 1573, 1573, 1573, 1570,
-     2988, 1571, 1564, 1575, 1575, 1575, 1578, 1578, 1578, 1579,
-
-     1579, 1579, 2990, 1579, 1573, 2991, 1579, 1580, 1580, 1580,
-     1575, 1580, 2998, 1578, 1580, 1565, 1583, 1583, 1583, 1590,
-     1590, 1590, 1591, 1591, 1591, 2999, 1591, 3000, 3001, 1591,
-     1594, 1594, 1594, 1583, 1595, 1595, 1595, 1590, 1596, 1596,
-     1596, 1597, 1597, 1597, 1598, 1598, 1598, 1594, 1600, 1600,
-     1600, 1595, 1573, 3002, 3003, 1596, 3006, 3007, 1597, 1603,
-     1603, 1603, 1598, 1603, 3008, 1600, 1603, 3009, 3010, 1606,
-     1606, 1606, 1608, 1608, 1608, 1610, 1610, 1610, 1613, 1613,
-     1613, 1617, 1617, 1617, 1590, 1596, 1606, 1618, 1618, 1618,
-     1608, 3011, 3012, 1610, 3013, 3015, 1613, 3017, 1617, 1598,
-
-     3019, 1626, 1626, 1626, 1595, 1618, 1619, 1619, 1619, 3020,
-     1619, 1597, 3022, 1619, 1622, 1622, 1622, 3033, 1622, 1626,
-     3034, 1622, 1628, 1628, 1628, 3035, 1628, 1617, 3036, 1628,
-     1633, 1633, 1633, 3037, 1633, 1613, 1608, 1633, 1637, 1637,
-     1637, 1610, 3031, 3038, 1618, 1639, 1639, 1639, 1640, 1640,
-     1640, 3042, 1640, 3032, 3031, 1640, 1637, 1643, 1643, 1643,
-     3043, 1643, 3044, 1639, 1643, 3032, 3045, 1626, 1646, 1646,
-     1646, 1647, 1647, 1647, 3046, 1647, 3047, 3048, 1647, 3049,
-     1652, 1652, 1652, 3052, 1652, 3053, 1646, 1652, 1655, 1655,
-     1655, 1657, 1657, 1657, 1658, 1658, 1658, 3054, 1658, 1637,
-
-     3050, 1658, 1639, 1662, 1662, 1662, 1655, 3055, 1657, 1664,
-     1664, 1664, 1665, 1665, 1665, 1646, 1666, 1666, 1666, 3056,
-     3057, 1662, 1667, 1667, 1667, 3050, 1664, 1668, 1668, 1668,
-     1665, 1671, 1671, 1671, 1666, 1655, 1678, 1678, 1678, 1667,
-     1709, 1709, 1709, 3058, 1709, 1668, 3059, 1709, 3060, 1671,
-     3061, 3062, 1662, 3063, 1678, 1712, 1712, 1712, 1713, 1713,
-     1713, 3064, 1713, 3065, 3066, 1713, 3067, 3068, 1666, 1718,
-     1718, 1718, 3069, 1712, 1720, 1720, 1720, 3070, 1720, 1665,
-     3071, 1720, 1671, 1728, 1728, 1728, 3074, 1718, 1678, 1668,
-     1724, 1724, 1724, 3077, 1724, 3078, 3079, 1724, 3080, 1671,
-
-     3081, 1728, 1730, 1730, 1730, 3074, 1730, 3082, 3083, 1730,
-     1733, 1733, 1733, 3084, 1734, 1734, 1734, 3085, 1734, 3086,
-     1718, 1734, 1712, 1735, 1735, 1735, 3087, 1733, 1744, 1744,
-     1744, 1748, 1748, 1748, 1749, 1749, 1749, 1751, 1751, 1751,
-     3088, 1735, 3089, 3090, 1728, 1752, 1752, 1752, 3091, 1752,
-     3092, 3093, 1752, 3094, 1751, 1753, 1753, 1753, 3095, 1753,
-     3096, 3097, 1753, 1756, 1756, 1756, 1758, 1758, 1758, 1759,
-     1759, 1759, 3098, 3099, 1735, 1760, 1760, 1760, 3095, 1760,
-     3100, 1756, 1760, 1758, 1763, 1763, 1763, 1759, 3101, 1764,
-     1764, 1764, 1744, 1764, 3102, 1748, 1764, 3103, 1749, 1768,
-
-     1768, 1768, 1763, 1767, 1767, 1767, 3104, 1771, 1771, 1771,
-     1756, 1771, 3105, 3106, 1771, 3107, 1759, 1768, 3108, 3109,
-     1767, 1774, 1774, 1774, 1775, 1775, 1775, 3110, 1775, 3111,
-     3112, 1775, 1776, 1776, 1776, 1777, 1777, 1777, 1774, 1777,
-     3113, 3117, 1777, 1779, 1779, 1779, 1780, 1780, 1780, 1776,
-     1763, 1782, 1782, 1782, 3114, 1782, 3118, 3119, 1782, 3120,
-     3114, 1779, 3121, 1768, 1785, 1785, 1785, 1787, 1787, 1787,
-     3122, 1787, 3124, 3125, 1787, 1790, 1790, 1790, 1792, 1792,
-     1792, 3127, 1785, 1793, 1793, 1793, 3128, 1793, 3130, 3131,
-     1793, 3133, 3134, 1790, 3135, 1792, 1794, 1794, 1794, 1796,
-
-     1796, 1796, 3136, 1796, 3137, 3133, 1796, 1799, 1799, 1799,
-     1800, 1800, 1800, 1794, 1800, 3139, 3141, 1800, 1801, 1801,
-     1801, 1790, 3143, 3145, 1799, 1806, 1806, 1806, 1807, 1807,
-     1807, 1808, 1808, 1808, 3147, 1801, 1809, 1809, 1809, 3148,
-     1809, 3149, 1806, 1809, 3150, 3151, 1807, 3152, 1808, 1810,
-     1810, 1810, 1811, 1811, 1811, 1812, 1812, 1812, 1813, 1813,
-     1813, 1815, 1815, 1815, 3153, 3154, 1810, 3156, 3158, 1811,
-     3160, 3161, 1812, 1816, 1816, 1816, 1813, 1816, 1815, 3162,
-     1816, 1817, 1817, 1817, 1819, 1819, 1819, 3163, 1820, 1820,
-     1820, 3180, 1820, 3178, 1807, 1820, 3164, 3178, 1817, 3180,
-
-     3181, 1819, 1822, 1822, 1822, 1824, 1824, 1824, 3181, 1531,
-     1811, 1827, 1827, 1827, 1831, 1831, 1831, 3165, 1813, 1528,
-     1822, 3179, 1523, 1824, 3184, 3179, 1832, 1832, 1832, 1827,
-     1832, 1831, 3164, 1832, 1834, 1834, 1834, 1836, 1836, 1836,
-     1838, 1838, 1838, 1839, 1839, 1839, 1840, 1840, 1840, 1841,
-     1841, 1841, 1834, 3165, 3182, 1836, 1824, 1838, 3172, 1827,
-     1839, 3173, 3182, 1840, 1844, 1844, 1844, 1841, 1843, 1843,
-     1843, 3184, 1845, 1845, 1845, 1846, 1846, 1846, 1847, 1847,
-     1847, 3196, 1844, 1849, 1849, 1849, 1843, 1849, 1836, 1845,
-     1849, 3174, 1846, 1855, 1855, 1855, 1847, 3176, 1857, 1857,
-
-     1857, 1858, 1858, 1858, 3183, 1858, 3172, 3190, 1858, 3173,
-     1840, 1855, 3183, 3196, 1843, 1857, 1841, 1859, 1859, 1859,
-     1860, 1860, 1860, 1861, 1861, 1861, 1862, 1862, 1862, 1844,
-     1862, 1521, 1518, 1862, 1509, 1859, 1507, 3186, 1860, 3174,
-     1861, 3176, 3190, 1847, 1855, 1863, 1863, 1863, 1869, 1869,
-     1869, 1870, 1870, 1870, 1877, 1877, 1877, 1881, 1881, 1881,
-     1885, 1885, 1885, 1863, 3177, 1869, 1886, 1886, 1886, 1870,
-     1887, 1887, 1887, 3185, 3186, 1860, 1859, 1889, 1889, 1889,
-     1891, 1891, 1891, 1892, 1892, 1892, 1897, 1897, 1897, 1899,
-     1899, 1899, 1902, 1902, 1902, 1506, 1904, 1904, 1904, 1906,
-
-     1906, 1906, 1907, 1907, 1907, 3197, 3191, 1899, 3177, 3187,
-     1902, 1500, 1870, 1904, 1916, 1916, 1916, 1906, 1916, 1907,
-     3185, 1916, 1919, 1919, 1919, 1920, 1920, 1920, 1925, 1925,
-     1925, 1926, 1926, 1926, 1930, 1930, 1930, 3197, 3175, 1899,
-     1919, 3191, 1920, 1931, 1931, 1931, 3187, 1931, 3188, 1499,
-     1931, 1930, 1934, 1934, 1934, 1935, 1935, 1935, 1906, 1936,
-     1936, 1936, 1937, 1937, 1937, 3194, 1937, 3192, 1919, 1937,
-     1934, 3189, 1935, 1938, 1938, 1938, 1936, 1939, 1939, 1939,
-     1940, 1940, 1940, 1941, 1941, 1941, 3175, 1941, 3195, 3188,
-     1941, 1938, 1942, 1942, 1942, 1939, 3230, 1940, 3193, 1945,
-
-     1945, 1945, 3194, 1945, 3230, 1934, 1945, 1948, 1948, 1948,
-     1942, 1948, 3189, 3192, 1948, 1952, 1952, 1952, 1954, 1954,
-     1954, 3198, 1956, 1956, 1956, 3195, 1938, 1958, 1958, 1958,
-     3198, 1958, 3202, 1952, 1958, 1961, 1961, 1961, 3199, 1942,
-     1956, 1962, 1962, 1962, 3193, 1962, 3200, 3199, 1962, 1964,
-     1964, 1964, 1961, 1964, 3204, 3222, 1964, 1967, 1967, 1967,
-     1968, 1968, 1968, 3201, 1968, 1497, 3202, 1968, 1969, 1969,
-     1969, 1973, 1973, 1973, 1967, 1974, 1974, 1974, 3206, 1974,
-     1956, 3200, 1974, 3205, 3222, 1969, 3212, 3207, 1973, 1975,
-     1975, 1975, 1976, 1976, 1976, 3212, 1976, 3204, 3201, 1976,
-
-     1979, 1979, 1979, 3210, 1980, 1980, 1980, 1975, 1980, 3203,
-     3244, 1980, 1981, 1981, 1981, 1496, 3255, 1979, 1982, 1982,
-     1982, 1983, 1983, 1983, 3206, 1983, 3205, 3255, 1983, 1981,
-     1984, 1984, 1984, 3207, 3218, 1982, 3210, 1986, 1986, 1986,
-     1975, 1986, 3244, 3203, 1986, 1989, 1989, 1989, 1984, 1990,
-     1990, 1990, 3208, 1990, 3213, 1495, 1990, 1992, 1992, 1992,
-     3209, 1992, 1989, 3213, 1992, 1996, 1996, 1996, 1999, 1999,
-     1999, 2001, 2001, 2001, 2002, 2002, 2002, 2004, 2004, 2004,
-     3218, 1984, 3214, 1996, 3211, 3215, 1999, 3208, 2001, 2006,
-     2006, 2006, 2002, 2006, 2004, 3209, 2006, 2010, 2010, 2010,
-
-     2013, 2013, 2013, 2015, 2015, 2015, 2016, 2016, 2016, 1494,
-     2016, 3219, 3224, 2016, 3216, 2010, 3250, 3211, 2013, 3214,
-     2015, 3224, 3215, 2004, 2017, 2017, 2017, 2018, 2018, 2018,
-     3217, 2018, 1999, 3223, 2018, 2002, 2020, 2020, 2020, 1493,
-     3226, 2017, 2022, 2022, 2022, 2023, 2023, 2023, 2024, 2024,
-     2024, 2025, 2025, 2025, 2020, 2025, 3216, 3219, 2025, 3220,
-     2022, 1492, 3223, 2023, 3250, 2024, 2026, 2026, 2026, 2027,
-     2027, 2027, 3217, 2027, 3226, 3221, 2027, 2028, 2028, 2028,
-     2033, 2033, 2033, 2026, 3225, 2035, 2035, 2035, 1491, 2035,
-     3232, 2022, 2035, 3225, 3227, 2028, 3220, 3228, 2033, 2038,
-
-     2038, 2038, 2020, 2039, 2039, 2039, 3238, 2040, 2040, 2040,
-     2023, 2040, 3221, 1490, 2040, 1489, 1487, 2038, 2043, 2043,
-     2043, 2039, 2049, 2049, 2049, 2050, 2050, 2050, 3227, 2050,
-     3231, 3246, 2050, 2051, 2051, 2051, 2043, 3232, 3231, 2049,
-     3246, 3238, 2028, 3228, 1486, 2033, 2052, 2052, 2052, 1484,
-     2038, 2051, 2057, 2057, 2057, 1483, 2039, 2058, 2058, 2058,
-     2059, 2059, 2059, 2061, 2061, 2061, 2065, 2065, 2065, 2066,
-     2066, 2066, 2067, 2067, 2067, 2068, 2068, 2068, 2070, 2070,
-     2070, 2071, 2071, 2071, 2072, 2072, 2072, 2073, 2073, 2073,
-     2074, 2074, 2074, 2075, 2075, 2075, 3229, 2051, 2077, 2077,
-
-     2077, 2080, 2080, 2080, 3247, 2083, 2083, 2083, 2084, 2084,
-     2084, 1481, 2084, 3247, 1478, 2084, 2077, 1477, 3254, 2080,
-     1476, 2068, 2083, 2086, 2086, 2086, 2087, 2087, 2087, 2088,
-     2088, 2088, 3254, 2088, 1475, 3236, 2088, 2099, 2099, 2099,
-     3234, 2086, 3229, 2087, 2100, 2100, 2100, 3240, 3233, 2077,
-     2101, 2101, 2101, 3235, 2101, 2099, 1474, 2101, 2102, 2102,
-     2102, 2100, 2107, 2107, 2107, 2108, 2108, 2108, 2109, 2109,
-     2109, 2110, 2110, 2110, 3251, 2110, 3236, 3234, 2110, 2111,
-     2111, 2111, 2112, 2112, 2112, 2109, 2099, 2113, 2113, 2113,
-     3235, 2113, 3241, 3240, 2113, 3233, 1473, 2111, 1472, 2112,
-
-     2114, 2114, 2114, 3237, 2114, 3239, 3242, 2114, 2117, 2117,
-     2117, 2108, 1470, 2118, 2118, 2118, 2120, 2120, 2120, 1469,
-     2120, 3243, 3251, 2120, 1468, 1467, 2117, 2123, 2123, 2123,
-     2111, 2118, 2130, 2130, 2130, 2132, 2132, 2132, 3241, 2132,
-     3239, 1458, 2132, 3242, 3237, 2123, 1443, 2136, 2136, 2136,
-     2130, 2136, 3245, 1442, 2136, 2139, 2139, 2139, 3243, 2117,
-     2140, 2140, 2140, 1437, 2140, 3248, 3249, 2140, 1436, 2144,
-     2144, 2144, 2139, 2144, 1435, 1433, 2144, 2147, 2147, 2147,
-     2123, 2148, 2148, 2148, 3245, 2148, 1426, 2130, 2148, 2151,
-     2151, 2151, 2152, 2152, 2152, 2147, 2152, 3248, 3249, 2152,
-
-     2153, 2153, 2153, 3252, 2153, 1425, 2151, 2153, 2156, 2156,
-     2156, 2158, 2158, 2158, 1407, 2158, 1402, 1399, 2158, 2164,
-     2164, 2164, 2166, 2166, 2166, 1398, 2156, 2167, 2167, 2167,
-     1395, 2167, 1390, 1381, 2167, 3252, 3253, 2164, 1380, 2166,
-     1379, 2147, 2168, 2168, 2168, 2170, 2170, 2170, 2171, 2171,
-     2171, 1375, 2171, 1370, 1366, 2171, 1358, 2178, 2178, 2178,
-     2168, 1353, 2170, 2181, 2181, 2181, 1352, 2181, 3253, 1346,
-     2181, 2188, 2188, 2188, 2156, 2178, 2184, 2184, 2184, 1345,
-     2184, 1344, 1343, 2184, 1338, 2190, 2190, 2190, 1337, 2188,
-     2191, 2191, 2191, 2192, 2192, 2192, 1336, 2192, 1335, 1322,
-
-     2192, 1321, 2168, 2190, 1320, 2195, 2195, 2195, 2191, 2195,
-     1319, 1318, 2195, 2198, 2198, 2198, 1317, 2199, 2199, 2199,
-     1316, 1306, 2188, 2200, 2200, 2200, 2191, 2201, 2201, 2201,
-     1305, 2198, 1304, 2198, 2199, 2202, 2202, 2202, 1303, 1286,
-     2200, 2203, 2203, 2203, 2201, 2205, 2205, 2205, 2206, 2206,
-     2206, 2190, 2202, 2207, 2207, 2207, 2210, 2210, 2210, 2203,
-     2211, 2211, 2211, 2205, 2211, 1285, 2206, 2211, 2214, 2214,
-     2214, 2207, 1280, 1279, 2200, 2215, 2215, 2215, 2216, 2216,
-     2216, 2217, 2217, 2217, 1274, 1273, 2214, 2220, 2220, 2220,
-     1254, 2201, 1250, 1244, 2202, 2221, 2221, 2221, 2223, 2223,
-
-     2223, 2224, 2224, 2224, 1240, 2205, 2203, 2225, 2225, 2225,
-     2226, 2226, 2226, 2227, 2227, 2227, 2228, 2228, 2228, 2231,
-     2231, 2231, 2232, 2232, 2232, 1239, 1238, 2214, 2233, 2233,
-     2233, 2234, 2234, 2234, 2236, 2236, 2236, 2239, 2239, 2239,
-     2240, 2240, 2240, 1237, 2240, 1236, 1235, 2240, 2243, 2243,
-     2243, 1234, 2236, 1232, 2239, 2244, 2244, 2244, 1231, 2246,
-     2246, 2246, 1229, 2246, 1228, 2243, 2246, 2259, 2259, 2259,
-     2260, 2260, 2260, 2244, 2260, 2261, 2261, 2260, 2261, 1227,
-     2262, 2262, 1222, 2262, 1214, 2259, 2261, 1212, 1207, 2261,
-     1205, 2262, 1196, 2261, 2262, 2263, 2263, 2263, 2262, 2264,
-
-     2264, 2264, 2268, 2268, 2268, 2270, 2270, 2270, 1191, 2270,
-     1180, 1178, 2270, 1177, 2243, 2273, 2273, 2273, 2274, 2274,
-     2274, 1176, 2274, 1175, 1173, 2274, 1172, 1171, 2259, 2277,
-     2277, 2277, 1170, 2273, 2278, 2278, 2278, 2286, 2286, 2286,
-     2287, 2287, 2287, 1169, 2290, 2290, 2290, 2277, 2290, 1168,
-     1166, 2290, 2278, 2293, 2293, 2293, 1165, 1164, 2287, 1163,
-     1162, 2273, 2296, 2296, 2296, 2297, 2297, 2297, 1161, 2297,
-     2293, 1160, 2297, 2300, 2300, 2300, 2305, 2305, 2305, 1158,
-     2296, 2307, 2307, 2307, 1157, 2278, 2308, 2308, 2308, 1156,
-     2308, 2300, 1155, 2308, 2305, 2311, 2311, 2311, 2307, 1154,
-
-     2287, 2312, 2312, 2312, 2313, 2313, 2313, 1153, 2313, 1152,
-     1146, 2313, 1145, 2311, 2316, 2316, 2316, 1144, 2312, 2317,
-     2317, 2317, 2322, 2322, 2322, 2324, 2324, 2324, 2327, 2327,
-     2327, 2316, 2326, 2326, 2326, 1141, 2317, 1140, 1139, 2322,
-     2328, 2328, 2328, 1137, 1133, 2327, 2311, 2312, 1130, 1121,
-     2326, 1120, 2329, 2329, 2329, 2331, 2331, 2331, 2328, 2330,
-     2330, 2330, 1117, 1116, 2332, 2332, 2332, 1115, 2332, 2316,
-     2329, 2332, 2331, 2322, 2333, 2333, 2333, 2330, 1114, 1113,
-     2317, 2334, 2334, 2334, 2335, 2335, 2335, 2336, 2336, 2336,
-     1099, 2333, 2337, 2337, 2337, 1092, 2330, 1084, 2334, 1083,
-
-     2328, 2335, 2338, 2338, 2338, 2336, 2339, 2339, 2339, 2341,
-     2341, 2341, 1082, 2329, 2344, 2344, 2344, 2346, 2346, 2346,
-     2338, 2345, 2345, 2345, 2339, 1079, 1076, 2341, 2347, 2347,
-     2347, 1073, 2334, 1068, 1065, 2335, 2350, 2350, 2350, 2345,
-     2351, 2351, 2351, 2352, 2352, 2352, 2353, 2353, 2353, 2357,
-     2357, 2357, 2360, 2360, 2360, 2361, 2361, 2361, 1064, 2361,
-     1060, 1058, 2361, 2373, 2373, 2373, 1044, 2357, 2338, 2360,
-     1043, 2341, 2386, 2386, 2386, 2389, 2389, 2389, 2391, 2391,
-     2391, 2373, 2392, 2392, 2392, 2394, 2394, 2394, 2401, 2401,
-     2401, 2402, 2402, 2402, 1042, 1041, 2391, 2403, 2403, 2403,
-
-     2392, 1040, 1039, 2394, 1038, 2401, 1034, 2406, 2406, 2406,
-     2407, 2407, 2407, 1030, 2407, 2403, 1023, 2407, 2409, 2409,
-     2409, 1020, 1019, 2373, 2406, 2410, 2410, 2410, 2412, 2412,
-     2412, 2416, 2416, 2416, 1018, 2409, 2418, 2418, 2418, 1015,
-     2420, 2420, 2420, 2410, 2391, 1014, 2412, 1011, 2416, 2421,
-     2421, 2421, 1010, 2418, 2403, 2419, 2419, 2419, 2420, 2419,
-     1009, 1006, 2419, 2422, 2422, 2422, 2421, 2422, 1005, 1002,
-     2422, 2423, 2423, 2423, 2424, 2424, 2424, 2425, 2425, 2425,
-     2430, 2430, 2430, 2432, 2432, 2432,  997,  994, 2423,  991,
-      990, 2424,  987,  986, 2425,  985,  984, 2430, 2434, 2434,
-
-     2434, 2436, 2436, 2436, 2437, 2437, 2437,  983, 2437,  981,
-      980, 2437, 2438, 2438, 2438,  979, 2434,  978, 2436, 2439,
-     2439, 2439,  977, 2423, 2440, 2440, 2440, 2441, 2441, 2441,
-     2438, 2441, 2424,  976, 2441, 2425,  975, 2439, 2444, 2444,
-     2444,  974, 2440, 2445, 2445, 2445,  970, 2445,  965,  964,
-     2445, 2446, 2446, 2446,  963, 2444, 2447, 2447, 2447, 2448,
-     2448, 2448, 2450, 2450, 2450, 2451, 2451, 2451, 2446, 2455,
-     2455, 2455,  960, 2447, 2459, 2459, 2459, 2448, 2463, 2463,
-     2463,  959,  958, 2451,  956,  952, 2439, 2455, 2440, 2464,
-     2464, 2464,  948, 2464,  947, 2463, 2464, 2478, 2478, 2478,
-
-     2495, 2495, 2495, 2497, 2497, 2497, 2498, 2498, 2498, 2501,
-     2501, 2501, 2504, 2504, 2504, 2478, 2505, 2505, 2505,  944,
-     2505, 2497,  941, 2505, 2498,  940, 2501,  939,  938, 2504,
-     2506, 2506, 2506, 2509, 2509, 2509,  937, 2509,  936,  935,
-     2509, 2513, 2513, 2513,  933, 2514, 2514, 2514, 2506, 2514,
-      932,  931, 2514, 2516, 2516, 2516,  930, 2478, 2513, 2517,
-     2517, 2517, 2518, 2518, 2518,  929, 2518,  928,  927, 2518,
-     2516, 2519, 2519, 2519, 2497,  926, 2517, 2520, 2520, 2520,
-      925, 2520,  924,  923, 2520, 2523, 2523, 2523, 2519, 2525,
-     2525, 2525,  922, 2525,  921,  920, 2525, 2528, 2528, 2528,
-
-     2529, 2529, 2529, 2523, 2530, 2530, 2530, 2533, 2533, 2533,
-      919, 2534, 2534, 2534, 2528, 2534,  918, 2529, 2534,  917,
-      916, 2530,  915,  914, 2533, 2535, 2535, 2535, 2536, 2536,
-     2536, 2537, 2537, 2537,  913, 2537,  909,  908, 2537, 2540,
-     2540, 2540, 2535,  906,  905, 2536, 2542, 2542, 2542,  904,
-      903, 2529, 2528, 2543, 2543, 2543,  902, 2540,  898, 2530,
-      896, 2544, 2544, 2544, 2542, 2544,  895,  894, 2544,  893,
-      889, 2543, 2547, 2547, 2547, 2548, 2548, 2548,  885, 2548,
-      884,  881, 2548, 2549, 2549, 2549, 2550, 2550, 2550, 2547,
-     2550,  880,  879, 2550,  878, 2551, 2551, 2551,  877,  876,
-
-     2549, 2557, 2557, 2557, 2561, 2561, 2561, 2580, 2580, 2580,
-      875,  872, 2542, 2551, 2543, 2562, 2562, 2562,  871, 2562,
-      870, 2561, 2562,  869,  866, 2580, 2596, 2596, 2596, 2598,
-     2598, 2598, 2599, 2599, 2599, 2600, 2600, 2600, 2601, 2601,
-     2601,  865, 2601,  864,  861, 2601,  859, 2598,  856, 2599,
-      855,  854, 2600, 2602, 2602, 2602,  853, 2602, 2580,  852,
-     2602, 2605, 2605, 2605, 2610, 2610, 2610,  849, 2610,  848,
-      847, 2610, 2614, 2614, 2614, 2649, 2649, 2649, 2599, 2605,
-     2615, 2615, 2615,  846, 2615,  845,  842, 2615,  841, 2614,
-      840, 2598, 2616, 2616, 2616,  839, 2616,  837,  834, 2616,
-
-     2619, 2619, 2619, 2620, 2620, 2620,  833, 2620,  831,  828,
-     2620, 2621, 2621, 2621, 2622, 2622, 2622, 2619, 2623, 2623,
-     2623,  826, 2624, 2624, 2624,  823, 2624,  822, 2621, 2624,
-      821, 2622, 2627, 2627, 2627, 2623, 2628, 2628, 2628,  820,
-     2628,  818,  817, 2628, 2629, 2629, 2629,  816,  813, 2627,
-     2630, 2630, 2630,  812, 2630,  811,  810, 2630, 2637, 2637,
-     2637, 2629, 2638, 2638, 2638,  809,  808, 2623,  803, 2621,
-     2639, 2639, 2639,  802, 2639,  801, 2637, 2639,  800,  799,
-     2638, 2642, 2642, 2642,  798, 2642,  797,  796, 2642, 2647,
-     2647, 2647, 2650, 2650, 2650, 2653, 2653, 2653,  795, 2653,
-
-      793,  791, 2653, 2664, 2664, 2664, 2647, 2647,  790, 2637,
-     2673, 2673, 2673, 2689, 2689, 2689, 2690, 2690, 2690,  787,
-     2664, 2691, 2691, 2691, 2692, 2692, 2692,  784, 2673, 2638,
-     2693, 2693, 2693,  781, 2693,  780,  776, 2693,  775, 2691,
-      774, 2692, 2695, 2695, 2695,  771, 2695,  768,  767, 2695,
-     2702, 2702, 2702,  766, 2702,  763,  762, 2702,  758, 2673,
-     2705, 2705, 2705,  757, 2705,  755,  752, 2705, 2708, 2708,
-     2708,  751, 2691, 2709, 2709, 2709, 2710, 2710, 2710,  750,
-     2710,  748,  737, 2710,  735, 2708, 2711, 2711, 2711,  732,
-     2709, 2712, 2712, 2712,  731, 2712,  730,  728, 2712,  727,
-
-     2715, 2715, 2715, 2711, 2715,  726,  722, 2715, 2724, 2724,
-     2724, 2725, 2725, 2725, 2731, 2731, 2731,  721,  720, 2708,
-     2732, 2732, 2732, 2733, 2733, 2733, 2724, 2733,  719, 2725,
-     2733, 2731, 2731, 2734, 2734, 2734,  716, 2732, 2732,  715,
-      714, 2733, 2735, 2735, 2735, 2736, 2736, 2736, 2737, 2737,
-     2737, 2746, 2746, 2746, 2747, 2747, 2747, 2711, 2747,  713,
-      712, 2747, 2756, 2756, 2756, 2771, 2771, 2771, 2746, 2772,
-     2772, 2772, 2773, 2773, 2773,  711,  710, 2725,  708,  705,
-     2756, 2774, 2774, 2774,  704, 2774,  702,  700, 2774,  697,
-     2773, 2780, 2780, 2780, 2782, 2782, 2782, 2783, 2783, 2783,
-
-      696, 2783,  690,  688, 2783, 2786, 2786, 2786, 2780,  686,
-      683, 2782, 2801, 2801, 2801, 2803, 2803, 2803, 2809, 2809,
-     2809,  682, 2786,  678,  677, 2810, 2810, 2810, 2756, 2810,
-     2801,  676, 2810, 2803,  675, 2809, 2809, 2811, 2811, 2811,
-      672, 2811,  671, 2810, 2811, 2814, 2814, 2814, 2815, 2815,
-     2815, 2816, 2816, 2816,  670, 2811, 2825, 2825, 2825,  669,
-     2825,  666,  665, 2825,  664,  663, 2803, 2812, 2812, 2812,
-     2812, 2812, 2812, 2812, 2812, 2812,  662,  656, 2812, 2834,
-     2834, 2834,  655, 2812, 2812, 2812, 2812, 2812, 2845, 2845,
-     2845, 2846, 2846, 2846, 2851, 2851, 2851, 2834, 2852, 2852,
-
-     2852,  653, 2852,  647,  646, 2852, 2854, 2854, 2854, 2846,
-      642, 2851, 2812, 2812, 2813, 2813, 2813, 2813, 2813, 2813,
-     2813, 2813, 2813, 2854,  635, 2813, 2856, 2856, 2856,  631,
-     2813, 2813, 2813, 2813, 2813, 2855, 2855, 2855,  625, 2855,
-      621,  613, 2855, 2856, 2857, 2857, 2857,  612, 2857,  611,
-      610, 2857, 2870, 2870, 2870, 2895, 2895, 2895,  609, 2813,
-     2813, 2876, 2876, 2876,  605, 2876,  598,  597, 2876,  596,
-     2870,  592,  585, 2895, 2930, 2930, 2930,  584,  580, 2876,
-     2879, 2879, 2879, 2879, 2879, 2879, 2879, 2879, 2879,  574,
-      573, 2879, 2930,  569,  561,  560, 2879, 2879, 2879, 2879,
-
-     2879, 2908, 2908, 2908,  556, 2908,  547,  543, 2908, 2912,
-     2912, 2912,  535, 2912,  534,  533, 2912, 2915, 2915, 2915,
-      529, 2915,  523,  522, 2915, 2879, 2879, 2880, 2880, 2880,
-     2880, 2880, 2880, 2880, 2880, 2880,  521,  517, 2880, 2942,
-     2942, 2942,  511, 2880, 2880, 2880, 2880, 2880, 2959, 2959,
-     2959, 2960, 2960, 2960, 2961, 2961, 2961, 2942, 2942, 2966,
-     2966, 2966, 2977, 2977, 2977, 2959,  510,  506, 2960,  500,
-      499, 2961, 2880, 2880,  498,  497, 2966, 2981, 2981, 2981,
-     2977, 2992, 2992, 2992, 2993, 2993, 2993,  496, 2993,  495,
-      494, 2993, 2994, 2994, 2994, 2981,  490,  484, 2992, 2995,
-
-     2995, 2995,  483, 2995,  481,  480, 2995,  479,  475, 2994,
-     2996, 2996, 2996, 2997, 2997, 2997,  466, 2997,  465,  464,
-     2997, 3004, 3004, 3004, 3014, 3014, 3014, 2996, 2981, 3005,
-     3005, 3005,  462, 3005,  458,  452, 3005,  451, 3004, 3024,
-     3024, 3024, 3014, 3024,  450,  446, 3024, 3027, 3027, 3027,
-      440, 3027,  436,  428, 3027, 3030, 3030, 3030,  427, 3030,
-      426, 3014, 3030, 3039, 3039, 3039,  425, 3039,  424,  420,
-     3039, 3146, 3146, 3146, 3155, 3155, 3155,  414, 3155,  413,
-      409, 3155, 3256, 3256, 3256, 3257, 3257, 3257,  403, 3146,
-      402,  398, 3155,  391,  390,  389,  385,  378,  377,  376,
-
-     3256,  375,  371, 3257, 3260, 3260, 3260, 3260, 3260, 3260,
-     3260, 3260, 3260, 3261, 3261, 3261, 3261, 3261, 3261, 3261,
-     3261, 3261, 3262, 3262, 3262, 3262, 3262, 3262, 3262, 3262,
-     3262, 3263, 3263, 3263, 3263, 3263, 3263, 3263, 3263, 3263,
-     3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3265,
-     3265, 3265, 3265, 3265, 3265, 3265, 3265, 3265, 3266, 3266,
-     3266, 3266, 3266, 3266, 3266, 3266, 3266, 3267, 3267, 3267,
-     3267, 3267, 3267, 3267, 3267, 3267, 3268, 3268, 3268, 3268,
-     3268, 3268, 3268, 3268, 3268, 3269, 3269, 3269, 3269, 3269,
-     3269, 3269, 3269, 3269, 3270, 3270, 3270, 3270, 3270, 3270,
-
-     3270, 3270, 3270, 3271, 3271, 3271, 3271, 3271, 3271, 3271,
-     3271, 3271, 3272, 3272, 3272, 3272, 3272, 3272, 3272, 3272,
-     3272, 3273, 3273, 3273, 3273, 3273, 3273, 3273, 3273, 3273,
-     3274, 3274, 3274, 3274, 3274, 3274, 3274, 3274, 3274, 3275,
-     3275, 3275, 3275, 3275, 3275, 3275, 3275, 3275, 3276, 3276,
-     3276, 3276, 3276, 3276, 3276, 3276, 3276, 3277, 3277, 3277,
-     3277, 3277, 3277, 3277, 3277, 3277, 3278, 3278, 3278, 3278,
-     3278, 3278, 3278, 3278, 3278, 3279, 3279, 3279, 3279, 3279,
-     3279, 3279, 3279, 3279, 3280, 3280, 3280, 3280, 3280, 3280,
-     3280, 3280, 3280, 3281, 3281, 3281, 3281, 3281, 3281, 3281,
-
-     3281, 3281, 3282, 3282, 3282, 3282, 3282, 3282, 3282, 3282,
-     3282, 3283, 3283, 3283, 3283, 3283, 3283, 3283, 3283, 3283,
-     3284, 3284, 3284, 3284, 3284, 3284, 3284, 3284, 3284, 3285,
-     3285, 3285, 3285, 3285, 3285, 3285, 3285, 3285, 3286, 3286,
-     3286, 3286, 3286, 3286, 3286, 3286, 3286, 3287, 3287, 3287,
-     3287, 3287, 3287, 3287, 3287, 3287, 3288, 3288, 3288, 3288,
-     3288, 3288, 3288, 3288, 3288, 3289, 3289, 3289, 3289, 3289,
-     3289, 3289, 3289, 3289, 3290, 3290, 3290, 3290, 3290, 3290,
-     3290, 3290, 3290, 3291, 3291, 3291, 3291, 3291, 3291, 3291,
-     3291, 3291, 3292, 3292, 3292, 3292, 3292, 3292, 3292, 3292,
-
-     3292, 3293, 3293, 3293, 3293, 3293, 3293, 3293, 3293, 3293,
-     3294, 3294, 3294, 3294, 3294, 3294, 3294, 3294, 3294, 3295,
-     3295, 3295, 3295, 3295, 3295, 3295, 3295, 3295, 3296, 3296,
-     3296, 3296, 3296, 3296, 3296, 3296, 3296, 3297, 3297, 3297,
-     3297, 3297, 3297, 3297, 3297, 3297, 3298, 3298, 3298, 3298,
-     3298, 3298, 3298, 3298, 3298, 3299, 3299, 3299, 3299, 3299,
-     3299, 3299, 3299, 3299, 3300, 3300, 3300, 3300, 3300, 3300,
-     3300, 3300, 3300, 3301, 3301, 3301, 3301, 3301, 3301, 3301,
-     3301, 3301, 3302, 3302, 3302, 3302, 3302, 3302, 3302, 3302,
-     3302, 3303, 3303, 3303, 3303, 3303, 3303, 3303, 3303, 3303,
-
-     3304, 3304, 3304, 3304, 3304, 3304, 3304, 3304, 3304, 3305,
-     3305, 3305, 3305, 3305, 3305, 3305, 3305, 3305, 3306, 3306,
-     3306, 3306, 3306, 3306, 3306, 3306, 3306, 3307, 3307, 3307,
-     3307, 3307, 3307, 3307, 3307, 3307, 3308, 3308, 3308, 3308,
-     3308, 3308, 3308, 3308, 3308, 3309, 3309, 3309, 3309, 3309,
-     3309, 3309, 3309, 3309, 3310, 3310, 3310, 3310, 3310, 3310,
-     3310, 3310, 3310, 3311, 3311, 3311, 3311, 3311, 3311, 3311,
-     3311, 3311, 3312, 3312, 3312, 3312, 3312, 3312, 3312, 3312,
-     3312, 3313, 3313, 3313, 3313, 3313, 3313, 3313, 3313, 3313,
-     3314, 3314, 3314, 3314, 3314, 3314, 3314, 3314, 3314, 3315,
-
-     3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3316, 3316,
-     3316, 3316, 3316, 3316, 3316, 3316, 3316, 3317, 3317, 3317,
-     3317, 3317, 3317, 3317, 3317, 3317, 3318, 3318, 3318, 3318,
-     3318, 3318, 3318, 3318, 3318, 3319, 3319, 3319, 3319, 3319,
-     3319, 3319, 3319, 3319, 3320, 3320, 3320, 3320, 3320, 3320,
-     3320, 3320, 3320, 3321, 3321, 3321,  362,  356,  352, 3321,
-     3322, 3322, 3322,  351,  347,  341, 3322, 3323, 3323, 3323,
-      340,  339,  335, 3323, 3324, 3324, 3324,  328,  326,  325,
-     3324, 3325, 3325, 3325,  321,  318,  316, 3325, 3326, 3326,
-     3326,  315,  314,  310, 3326, 3327, 3327, 3327,  306,  303,
-
-      299, 3327, 3328, 3328, 3328,  296,  295,  287, 3328, 3329,
-     3329, 3329,  283,  279,  278, 3329, 3330, 3330, 3330,  277,
-      271,  270, 3330, 3331, 3331, 3331,  268,  265,  253, 3331,
-     3332, 3332, 3332,    0,    0,    0, 3332, 3333, 3333, 3333,
-        0,    0,    0, 3333, 3334, 3334, 3334,    0,    0,    0,
-     3334, 3335, 3335, 3335,    0,    0,    0, 3335, 3336, 3336,
-     3336,    0,    0,    0, 3336, 3337, 3337, 3337,    0,    0,
-        0, 3337, 3338, 3338, 3338,    0,    0,    0, 3338, 3339,
-     3339, 3339,    0,    0,    0, 3339, 3340, 3340, 3340,    0,
-        0,    0, 3340, 3341, 3341, 3341,    0,    0,    0, 3341,
-
-     3342, 3342, 3342,    0,    0,    0, 3342, 3343, 3343, 3343,
-        0,    0,    0, 3343, 3344, 3344, 3344,    0,    0,    0,
-     3344, 3345, 3345, 3345,    0,    0,    0, 3345, 3346, 3346,
-     3346,    0,    0,    0, 3346, 3347, 3347, 3347,    0,    0,
-        0, 3347, 3348, 3348, 3348,    0,    0,    0, 3348, 3349,
-     3349, 3349, 3349, 3349, 3349, 3349,    0, 3349, 3350, 3350,
-     3350,    0,    0,    0, 3350, 3351,    0,    0,    0, 3351,
-     3352, 3352, 3352,    0,    0,    0, 3352, 3353,    0,    0,
-        0, 3353, 3354, 3354, 3354,    0,    0,    0, 3354, 3355,
-        0,    0,    0, 3355, 3356, 3356, 3356,    0,    0,    0,
-
-     3356, 3357,    0,    0,    0, 3357, 3358, 3358, 3358,    0,
-        0,    0, 3358, 3359,    0,    0,    0, 3359, 3360, 3360,
-     3360,    0,    0,    0, 3360, 3361,    0,    0,    0, 3361,
-     3362, 3362, 3362,    0,    0,    0, 3362, 3363,    0,    0,
-        0, 3363, 3364, 3364, 3364,    0,    0,    0, 3364, 3365,
-        0,    0,    0, 3365, 3366, 3366, 3366,    0,    0,    0,
-     3366, 3367,    0,    0,    0, 3367, 3368, 3368, 3368,    0,
-        0,    0, 3368, 3369,    0,    0,    0, 3369, 3370, 3370,
-     3370,    0,    0,    0, 3370, 3371,    0,    0,    0, 3371,
-     3372, 3372, 3372,    0,    0,    0, 3372, 3373,    0,    0,
-
-        0, 3373, 3374, 3374, 3374,    0,    0,    0, 3374, 3375,
-        0,    0,    0, 3375, 3376, 3376, 3376,    0,    0,    0,
-     3376, 3377,    0,    0,    0, 3377, 3378, 3378, 3378,    0,
-        0,    0, 3378, 3379,    0,    0,    0, 3379, 3380, 3380,
-     3380,    0,    0,    0, 3380, 3381,    0,    0,    0, 3381,
-     3382, 3382, 3382,    0,    0,    0, 3382, 3383,    0,    0,
-        0, 3383, 3384, 3384, 3384,    0,    0,    0, 3384, 3385,
-        0,    0,    0, 3385, 3386, 3386, 3386,    0,    0,    0,
-     3386, 3387,    0,    0,    0, 3387, 3388, 3388, 3388,    0,
-        0,    0, 3388, 3389,    0,    0,    0, 3389, 3390, 3390,
-
-     3390,    0,    0,    0, 3390, 3391,    0,    0,    0, 3391,
-     3392, 3392, 3392,    0,    0,    0, 3392, 3393,    0,    0,
-        0, 3393, 3394, 3394, 3394,    0,    0,    0, 3394, 3395,
-        0,    0,    0, 3395, 3396, 3396, 3396,    0,    0,    0,
-     3396, 3397,    0,    0,    0, 3397, 3398, 3398, 3398,    0,
-        0,    0, 3398, 3399,    0,    0,    0, 3399, 3400, 3400,
-     3400,    0,    0,    0, 3400, 3401,    0,    0,    0, 3401,
-     3402, 3402, 3402,    0,    0,    0, 3402, 3403,    0,    0,
-        0, 3403, 3404, 3404, 3404,    0,    0,    0, 3404, 3405,
-        0,    0,    0, 3405, 3406, 3406, 3406, 3406, 3406, 3406,
-
-     3406, 3406, 3406, 3407,    0,    0,    0,    0, 3407, 3408,
-     3408, 3408,    0,    0,    0, 3408, 3409, 3409, 3409, 3409,
-        0,    0, 3409, 3409, 3410, 3410, 3410,    0,    0,    0,
-     3410, 3411, 3411, 3411, 3411,    0,    0, 3411, 3411, 3412,
-     3412, 3412,    0,    0,    0, 3412, 3413, 3413, 3413, 3413,
-        0,    0, 3413, 3413, 3414, 3414, 3414,    0,    0,    0,
-     3414, 3415, 3415, 3415, 3415,    0,    0, 3415, 3415, 3416,
-     3416, 3416,    0,    0,    0, 3416, 3417, 3417, 3417, 3417,
-        0,    0, 3417, 3417, 3418, 3418, 3418,    0,    0,    0,
-     3418, 3419, 3419, 3419, 3419,    0,    0, 3419, 3419, 3420,
-
-     3420, 3420,    0,    0,    0, 3420, 3421, 3421, 3421, 3421,
-        0,    0, 3421, 3421, 3422, 3422, 3422,    0,    0,    0,
-     3422, 3423, 3423, 3423, 3423,    0,    0, 3423, 3423, 3424,
-     3424, 3424,    0,    0,    0, 3424, 3425, 3425, 3425, 3425,
-        0,    0, 3425, 3425, 3426, 3426, 3426,    0,    0,    0,
-     3426, 3427, 3427, 3427, 3427,    0,    0, 3427, 3427, 3428,
-     3428, 3428,    0,    0,    0, 3428, 3429, 3429, 3429, 3429,
-        0,    0, 3429, 3429, 3430, 3430, 3430,    0,    0,    0,
-     3430, 3431, 3431, 3431, 3431,    0,    0, 3431, 3431, 3432,
-     3432, 3432,    0,    0,    0, 3432, 3433, 3433, 3433, 3433,
-
-        0,    0, 3433, 3433, 3434, 3434, 3434,    0,    0,    0,
-     3434, 3435, 3435, 3435, 3435,    0,    0, 3435, 3435, 3436,
-     3436, 3436, 3436,    0, 3436,    0, 3436, 3437, 3437, 3437,
-     3437,    0,    0, 3437, 3437, 3438, 3438, 3438,    0,    0,
-        0, 3438, 3439, 3439, 3439, 3439,    0,    0, 3439, 3439,
-     3440, 3440, 3440,    0,    0,    0, 3440, 3441, 3441, 3441,
-     3441,    0,    0, 3441, 3441, 3442, 3442, 3442,    0,    0,
-        0, 3442, 3443, 3443, 3443, 3443,    0,    0, 3443, 3443,
-     3444, 3444, 3444,    0,    0,    0, 3444, 3445, 3445, 3445,
-     3445,    0,    0, 3445, 3445, 3446, 3446, 3446, 3446,    0,
-
-     3446,    0, 3446, 3447, 3447, 3447, 3447,    0,    0, 3447,
-     3447, 3448, 3448, 3448, 3448,    0, 3448,    0, 3448, 3449,
-     3449, 3449, 3449,    0,    0, 3449, 3449, 3450, 3450, 3450,
-        0,    0,    0, 3450, 3451, 3451, 3451, 3451,    0,    0,
-     3451, 3451, 3452, 3452, 3452, 3452,    0, 3452,    0, 3452,
-     3453, 3453, 3453, 3453,    0,    0, 3453, 3453, 3454, 3454,
-     3454, 3454,    0, 3454,    0, 3454, 3455, 3455, 3455, 3455,
-        0,    0, 3455, 3455, 3456, 3456, 3456,    0,    0,    0,
-     3456, 3457, 3457, 3457, 3457,    0,    0, 3457, 3457, 3458,
-     3458, 3458,    0,    0,    0, 3458, 3459, 3459, 3459, 3459,
-
-        0,    0, 3459, 3459, 3460, 3460, 3460, 3460,    0,    0,
-     3460, 3460, 3461, 3461, 3461,    0,    0,    0, 3461, 3462,
-     3462, 3462, 3462,    0,    0, 3462, 3462, 3463, 3463, 3463,
-     3463, 3463, 3463, 3463, 3463, 3463, 3464,    0, 3464,    0,
-        0, 3464, 3465, 3465, 3465,    0,    0,    0, 3465, 3466,
-     3466, 3466, 3466,    0,    0, 3466, 3466, 3467, 3467, 3467,
-     3467,    0, 3467,    0, 3467, 3468, 3468, 3468, 3468,    0,
-        0, 3468, 3468, 3469, 3469, 3469, 3469,    0, 3469,    0,
-     3469, 3470, 3470, 3470, 3470,    0,    0, 3470, 3470, 3471,
-     3471, 3471,    0,    0,    0, 3471, 3472, 3472, 3472, 3472,
-
-        0,    0, 3472, 3472, 3473, 3473, 3473,    0,    0,    0,
-     3473, 3474, 3474, 3474, 3474,    0,    0, 3474, 3474, 3475,
-     3475, 3475,    0,    0,    0, 3475, 3476, 3476, 3476, 3476,
-        0,    0, 3476, 3476, 3477, 3477, 3477,    0,    0,    0,
-     3477, 3478, 3478, 3478, 3478,    0,    0, 3478, 3478, 3479,
-     3479, 3479,    0,    0,    0, 3479, 3480, 3480, 3480, 3480,
-        0,    0, 3480, 3480, 3481, 3481, 3481, 3481,    0, 3481,
-        0, 3481, 3482, 3482, 3482, 3482,    0,    0, 3482, 3482,
-     3483, 3483, 3483, 3483,    0, 3483,    0, 3483, 3484, 3484,
-     3484, 3484,    0,    0, 3484, 3484, 3485, 3485, 3485,    0,
-
-        0,    0, 3485, 3486, 3486, 3486, 3486,    0,    0, 3486,
-     3486, 3487, 3487, 3487, 3487,    0, 3487,    0, 3487, 3488,
-     3488, 3488, 3488,    0,    0, 3488, 3488, 3489, 3489, 3489,
-     3489,    0, 3489,    0, 3489, 3490, 3490, 3490, 3490,    0,
-        0, 3490, 3490, 3491, 3491, 3491,    0,    0,    0, 3491,
-     3492, 3492, 3492, 3492,    0,    0, 3492, 3492, 3493, 3493,
-     3493,    0,    0,    0, 3493, 3494, 3494, 3494, 3494,    0,
-        0, 3494, 3494, 3495, 3495, 3495,    0,    0,    0, 3495,
-     3496, 3496, 3496, 3496,    0,    0, 3496, 3496, 3497, 3497,
-     3497,    0,    0,    0, 3497, 3498, 3498, 3498, 3498,    0,
-
-        0, 3498, 3498, 3499, 3499, 3499,    0,    0,    0, 3499,
-     3500, 3500, 3500, 3500,    0,    0, 3500, 3500, 3501, 3501,
-     3501,    0,    0,    0, 3501, 3502, 3502, 3502, 3502,    0,
-        0, 3502, 3502, 3503, 3503, 3503,    0,    0,    0, 3503,
-     3504, 3504, 3504, 3504,    0,    0, 3504, 3504, 3505, 3505,
-     3505,    0,    0,    0, 3505, 3506, 3506, 3506, 3506,    0,
-        0, 3506, 3506, 3507, 3507, 3507,    0,    0,    0, 3507,
-     3508, 3508, 3508, 3508,    0,    0, 3508, 3508, 3509, 3509,
-     3509, 3509,    0,    0, 3509, 3509, 3510, 3510, 3510,    0,
-        0,    0, 3510, 3511, 3511, 3511, 3511,    0,    0, 3511,
-
-     3511, 3512, 3512, 3512,    0,    0,    0, 3512, 3513, 3513,
-     3513, 3513,    0,    0, 3513, 3513, 3514, 3514, 3514,    0,
-        0,    0, 3514, 3515, 3515, 3515, 3515,    0,    0, 3515,
-     3515, 3516, 3516, 3516, 3516,    0,    0, 3516, 3516, 3517,
-     3517, 3517,    0,    0,    0, 3517, 3518, 3518, 3518, 3518,
-        0,    0, 3518, 3518, 3519, 3519, 3519, 3519, 3519, 3519,
-     3519, 3519, 3519, 3520, 3520, 3520, 3520, 3520, 3520, 3520,
-     3520, 3520, 3521, 3521, 3521,    0,    0,    0, 3521, 3522,
-     3522, 3522, 3522,    0,    0, 3522, 3522, 3523, 3523, 3523,
-     3523,    0,    0, 3523, 3523, 3524, 3524, 3524,    0,    0,
-
-        0, 3524, 3525, 3525, 3525, 3525,    0,    0, 3525, 3525,
-     3526, 3526, 3526,    0,    0,    0, 3526, 3527, 3527, 3527,
-     3527,    0,    0, 3527, 3527, 3528, 3528, 3528,    0,    0,
-        0, 3528, 3529, 3529, 3529, 3529,    0,    0, 3529, 3529,
-     3530, 3530, 3530,    0,    0,    0, 3530, 3531, 3531, 3531,
-        0,    0,    0, 3531, 3532, 3532, 3532, 3532,    0,    0,
-     3532, 3532, 3533, 3533, 3533,    0,    0,    0, 3533, 3534,
-     3534, 3534, 3534,    0,    0, 3534, 3534, 3535, 3535, 3535,
-     3535,    0,    0, 3535, 3535, 3536, 3536, 3536,    0,    0,
-        0, 3536, 3537, 3537, 3537, 3537,    0,    0, 3537, 3537,
-
-     3538, 3538, 3538,    0,    0,    0, 3538, 3539, 3539, 3539,
-     3539,    0,    0, 3539, 3539, 3540, 3540, 3540, 3540,    0,
-        0, 3540, 3540, 3541, 3541, 3541, 3541,    0,    0, 3541,
-     3541, 3542, 3542, 3542,    0,    0,    0, 3542, 3543, 3543,
-     3543, 3543,    0,    0, 3543, 3543, 3544, 3544, 3544, 3544,
-        0, 3544,    0, 3544, 3545, 3545, 3545, 3545,    0,    0,
-     3545, 3545, 3546, 3546, 3546,    0,    0,    0, 3546, 3547,
-     3547, 3547, 3547,    0,    0, 3547, 3547, 3548, 3548, 3548,
-        0,    0,    0, 3548, 3549, 3549, 3549, 3549,    0,    0,
-     3549, 3549, 3550, 3550, 3550,    0,    0,    0, 3550, 3551,
-
-     3551, 3551, 3551,    0,    0, 3551, 3551, 3552, 3552, 3552,
-        0,    0,    0, 3552, 3553, 3553, 3553, 3553,    0,    0,
-     3553, 3553, 3554, 3554, 3554,    0,    0,    0, 3554, 3555,
-     3555, 3555, 3555,    0,    0, 3555, 3555, 3556, 3556, 3556,
-        0,    0,    0, 3556, 3557, 3557, 3557, 3557,    0,    0,
-     3557, 3557, 3558, 3558, 3558,    0,    0,    0, 3558, 3559,
-     3559, 3559, 3559,    0,    0, 3559, 3559, 3560, 3560, 3560,
-     3560,    0,    0, 3560, 3560, 3561, 3561, 3561,    0,    0,
-        0, 3561, 3562, 3562, 3562, 3562,    0,    0, 3562, 3562,
-     3563, 3563, 3563,    0,    0,    0, 3563, 3564, 3564, 3564,
-
-     3564,    0,    0, 3564, 3564, 3565, 3565, 3565, 3565,    0,
-     3565,    0, 3565, 3566, 3566, 3566, 3566,    0,    0, 3566,
-     3566, 3567, 3567, 3567, 3567,    0,    0, 3567, 3567, 3568,
-     3568, 3568, 3568,    0, 3568,    0, 3568, 3569, 3569, 3569,
-     3569,    0,    0, 3569, 3569, 3570, 3570, 3570, 3570, 3570,
-     3570, 3570, 3570, 3570, 3571, 3571, 3571, 3571, 3571, 3571,
-     3571, 3571, 3571, 3572, 3572, 3572,    0,    0,    0, 3572,
-     3573, 3573, 3573, 3573,    0,    0, 3573, 3573, 3574, 3574,
-     3574, 3574,    0,    0, 3574, 3574, 3575, 3575, 3575,    0,
-        0,    0, 3575, 3576, 3576, 3576, 3576,    0,    0, 3576,
-
-     3576, 3577, 3577, 3577,    0,    0,    0, 3577, 3578, 3578,
-     3578, 3578,    0,    0, 3578, 3578, 3579, 3579, 3579,    0,
-        0,    0, 3579, 3580, 3580, 3580, 3580,    0,    0, 3580,
-     3580, 3581, 3581, 3581,    0,    0,    0, 3581, 3582, 3582,
-     3582,    0,    0,    0, 3582, 3583, 3583, 3583, 3583,    0,
-        0, 3583, 3583, 3584, 3584, 3584,    0,    0,    0, 3584,
-     3585, 3585, 3585, 3585,    0,    0, 3585, 3585, 3586, 3586,
-     3586, 3586,    0,    0, 3586, 3586, 3587, 3587, 3587, 3587,
-        0, 3587,    0, 3587, 3588, 3588, 3588, 3588,    0,    0,
-     3588, 3588, 3589, 3589, 3589,    0,    0,    0, 3589, 3590,
-
-     3590, 3590, 3590,    0,    0, 3590, 3590, 3591, 3591, 3591,
-     3591,    0,    0, 3591, 3591, 3592, 3592, 3592,    0,    0,
-        0, 3592, 3593, 3593, 3593, 3593,    0,    0, 3593, 3593,
-     3594, 3594, 3594, 3594,    0, 3594,    0, 3594, 3595, 3595,
-     3595, 3595,    0,    0, 3595, 3595, 3596, 3596, 3596,    0,
-        0,    0, 3596, 3597, 3597, 3597, 3597,    0,    0, 3597,
-     3597, 3598, 3598, 3598,    0,    0,    0, 3598, 3599, 3599,
-     3599, 3599,    0,    0, 3599, 3599, 3600, 3600, 3600,    0,
-        0,    0, 3600, 3601, 3601, 3601, 3601,    0,    0, 3601,
-     3601, 3602, 3602, 3602,    0,    0,    0, 3602, 3603, 3603,
-
-     3603, 3603,    0,    0, 3603, 3603, 3604, 3604, 3604,    0,
-        0,    0, 3604, 3605, 3605, 3605, 3605,    0,    0, 3605,
-     3605, 3606, 3606, 3606, 3606,    0, 3606,    0, 3606, 3607,
-     3607, 3607, 3607,    0,    0, 3607, 3607, 3608, 3608, 3608,
-        0,    0,    0, 3608, 3609, 3609, 3609, 3609,    0,    0,
-     3609, 3609, 3610, 3610, 3610, 3610,    0,    0, 3610, 3610,
-     3611, 3611, 3611, 3611,    0, 3611,    0, 3611, 3612, 3612,
-     3612, 3612,    0,    0, 3612, 3612, 3613, 3613, 3613,    0,
-        0,    0, 3613, 3614, 3614, 3614, 3614,    0,    0, 3614,
-     3614, 3615, 3615, 3615, 3615,    0,    0, 3615, 3615, 3616,
-
-     3616, 3616, 3616,    0,    0, 3616, 3616, 3617, 3617, 3617,
-     3617,    0,    0, 3617, 3617, 3618, 3618, 3618, 3618, 3618,
-     3618, 3618, 3618, 3618, 3619, 3619, 3619, 3619, 3619, 3619,
-     3619, 3619, 3619, 3620, 3620, 3620, 3620,    0, 3620,    0,
-     3620, 3621, 3621, 3621, 3621,    0,    0, 3621, 3621, 3622,
-     3622, 3622, 3622,    0,    0, 3622, 3622, 3623, 3623, 3623,
-        0,    0,    0, 3623, 3624, 3624, 3624, 3624,    0,    0,
-     3624, 3624, 3625, 3625, 3625,    0,    0,    0, 3625, 3626,
-     3626, 3626, 3626,    0,    0, 3626, 3626, 3627, 3627, 3627,
-     3627,    0, 3627,    0, 3627, 3628, 3628, 3628, 3628,    0,
-
-        0, 3628, 3628, 3629, 3629, 3629, 3629,    0, 3629,    0,
-     3629, 3630, 3630, 3630, 3630,    0, 3630,    0, 3630, 3631,
-     3631, 3631, 3631,    0,    0, 3631, 3631, 3632, 3632, 3632,
-     3632,    0, 3632,    0, 3632, 3633, 3633, 3633, 3633,    0,
-        0, 3633, 3633, 3634, 3634, 3634, 3634,    0,    0, 3634,
-     3634, 3635, 3635, 3635, 3635,    0,    0, 3635, 3635, 3636,
-     3636, 3636,    0,    0,    0, 3636, 3637, 3637, 3637, 3637,
-        0,    0, 3637, 3637, 3638, 3638, 3638,    0,    0,    0,
-     3638, 3639, 3639, 3639, 3639,    0,    0, 3639, 3639, 3640,
-     3640, 3640, 3640,    0, 3640,    0, 3640, 3641, 3641, 3641,
-
-     3641,    0,    0, 3641, 3641, 3642, 3642, 3642,    0,    0,
-        0, 3642, 3643, 3643, 3643,    0,    0,    0, 3643, 3644,
+     1095,  248,  248,  248,  248,  248, 2472, 1102, 1102, 1102,
+     2471, 2487, 1098, 2488, 2489, 1104, 1104, 1104, 1106, 1106,
+
+     1106, 1107, 1107, 1107, 1100, 1102, 2473, 1098, 2490, 2491,
+      248,  248, 1104, 1108, 1108, 1108, 1106, 2492, 2493, 1107,
+     2494,  248, 2495, 2496, 1102, 2498, 1109, 1109, 1109, 2499,
+     1108, 1110, 1110, 1110,  248,  290, 1111, 1111, 1111, 1115,
+     1115, 1115,  290, 1109, 1112, 1112, 1112, 2500, 2501, 1110,
+     2502,  290,  290, 2503, 1111, 2504, 1107, 1115, 1113, 1113,
+     1113, 1112, 1751, 1751, 1751, 1114, 1114, 1114, 2505, 2506,
+     1116, 1116, 1116, 2507, 2508, 1113, 1128, 1128, 1128,  290,
+      290,  290, 1114, 2509, 2510,  290,  290,  290, 1116, 2511,
+      290,  290, 2512, 1128,  290, 2513,  290,  290,  290,  355,
+
+     1122, 1122, 1122, 1123, 1123, 1123,  355, 1111, 1113, 1126,
+     1126, 1126, 1127, 1127, 1127,  355,  355, 2515, 1122, 2484,
+     2519, 1123, 2526, 1113, 1129, 1129, 1129, 1126, 1129, 2484,
+     1127, 1129, 2484, 2527, 1130, 1130, 1130, 2528, 1131, 1131,
+     1131, 1116, 2530,  355,  355,  355, 1132, 1132, 1132,  355,
+      355,  355, 1130, 2534,  355,  355, 1131, 2537,  355, 2560,
+      355,  355,  355, 1132, 1133, 1133, 1133, 1123, 1133, 2560,
+     2578, 1133, 1135, 1135, 1135, 2560, 1127, 1136, 1136, 1136,
+     1151, 1151, 1151, 1152, 1152, 1152, 1154, 1154, 1154, 2576,
+     1135, 1185, 1185, 1185, 2580, 1136, 2581, 2575, 1151, 1131,
+
+     2582, 1152, 2585, 2586, 1154, 1186, 1186, 1186, 1185, 1187,
+     1187, 1187, 1189, 1189, 1189, 1190, 1190, 1190, 1191, 1191,
+     1191, 2588, 1191, 1186, 2589, 1191, 2575, 1187, 2591, 2577,
+     1189, 2576, 1190, 1154, 1194, 1194, 1194, 1196, 1196, 1196,
+     2592, 1136, 1197, 1197, 1197, 1199, 1199, 1199, 1204, 1204,
+     1204, 1194, 1201, 1201, 1201, 1196, 1201, 2593, 2594, 1201,
+     1197, 1189, 2595, 1199, 2597, 1204, 1205, 1205, 1205, 2598,
+     1205, 2577, 2587, 1205, 1206, 1206, 1206, 1207, 1207, 1207,
+     1208, 1208, 1208, 2599, 1208, 2587, 2600, 1208, 1210, 1210,
+     1210, 1206, 1199, 2603, 1207, 1194, 1212, 1212, 1212, 1213,
+
+     1213, 1213, 1215, 1215, 1215, 1210, 1217, 1217, 1217, 1219,
+     1219, 1219, 2604, 2605, 1212, 2606, 2607, 1213, 2608, 2609,
+     1215, 2590, 2610, 1217, 1220, 1220, 1220, 1219, 1222, 1222,
+     1222, 1223, 1223, 1223, 2590, 1223, 2611, 2612, 1223, 1227,
+     1227, 1227, 1220, 1228, 1228, 1228, 1222, 1230, 1230, 1230,
+     2485, 1245, 1245, 1245, 2613, 1245, 2614, 1227, 1245, 2615,
+     2485, 1228, 1215, 2485, 2616, 1230, 1249, 1249, 1249, 1250,
+     1250, 1250, 1251, 1251, 1251, 1222, 1253, 1253, 1253, 1259,
+     1259, 1259, 2617, 1249, 1255, 1255, 1255, 1250, 1255, 2619,
+     1251, 1255, 2629, 2630, 1253, 2635, 2639, 1259, 1260, 1260,
+
+     1260, 1262, 1262, 1262, 1263, 1263, 1263, 2657, 1263, 2658,
+     2659, 1263, 1266, 1266, 1266, 2660, 1260, 2661, 2662, 1262,
+     1267, 1267, 1267, 1268, 1268, 1268, 1270, 1270, 1270, 1266,
+     1271, 1271, 1271, 1272, 1272, 1272, 2666, 1253, 1267, 2672,
+     2674, 1268, 2677, 2678, 1270, 2682, 2683, 1271, 2684, 2666,
+     1272, 1273, 1273, 1273, 1274, 1274, 1274, 1276, 1276, 1276,
+     2685, 1272, 1262, 1279, 1279, 1279, 1280, 1280, 1280, 1273,
+     1280, 2671, 1274, 1280, 2672, 1276, 1285, 1285, 1285, 2686,
+     1279, 1286, 1286, 1286, 1288, 1288, 1288, 1291, 1291, 1291,
+     1292, 1292, 1292, 1270, 1285, 1293, 1293, 1293, 2687, 1286,
+
+     2688, 2689, 1288, 2691, 1291, 1296, 1296, 1296, 1292, 1295,
+     1295, 1295, 2692, 1293, 1297, 1297, 1297, 2667, 1297, 2671,
+     2693, 1297, 1296, 1276, 1300, 1300, 1300, 1295, 1300, 2694,
+     2667, 1300, 1303, 1303, 1303, 1304, 1304, 1304, 1306, 1306,
+     1306, 1311, 1311, 1311, 2695, 1311, 2696, 2697, 1311, 1288,
+     1303, 2698, 2700, 1304, 2701, 2702, 1306, 1314, 1314, 1314,
+     1315, 1315, 1315, 2703, 1315, 2704, 2705, 1315, 1318, 1318,
+     1318, 1319, 1319, 1319, 1314, 1319, 1295, 2706, 1319, 1329,
+     1329, 1329, 1330, 1330, 1330, 1318, 1332, 1332, 1332, 1333,
+     1333, 1333, 2561, 1333, 2707, 2708, 1333, 1329, 2709, 2710,
+
+     1330, 2711, 2561, 1306, 1332, 1336, 1336, 1336, 2561, 1336,
+     2712, 2713, 1336, 1339, 1339, 1339, 1340, 1340, 1340, 2714,
+     1340, 2720, 2724, 1340, 1345, 1345, 1345, 1346, 1346, 1346,
+     1339, 1348, 1348, 1348, 1353, 1353, 1353, 2725, 1353, 2733,
+     2734, 1353, 1345, 2751, 2752, 1346, 1356, 1356, 1356, 1348,
+     1357, 1357, 1357, 1332, 1357, 2753, 2754, 1357, 1360, 1360,
+     1360, 2755, 2756, 1356, 1361, 1361, 1361, 1363, 1363, 1363,
+     1365, 1365, 1365, 2746, 1365, 2759, 1360, 1365, 2760, 1348,
+     2761, 2762, 1361, 2746, 2771, 1363, 1368, 1368, 1368, 1369,
+     1369, 1369, 1371, 1371, 1371, 1373, 1373, 1373, 2747, 1373,
+
+     2772, 2773, 1373, 2774, 1368, 2775, 2776, 1369, 2747, 2777,
+     1371, 1377, 1377, 1377, 1378, 1378, 1378, 2778, 1363, 1380,
+     1380, 1380, 2781, 1382, 1382, 1382, 2749, 1382, 2782, 1377,
+     1382, 2750, 1378, 1388, 1388, 1388, 2749, 1380, 1389, 1389,
+     1389, 2750, 1391, 1391, 1391, 1392, 1392, 1392, 1393, 1393,
+     1393, 1388, 1393, 2784, 2785, 1393, 1389, 2763, 2786, 1371,
+     1391, 2788, 1392, 1394, 1394, 1394, 2790, 2791, 1380, 1395,
+     1395, 1395, 2792, 1395, 2795, 2796, 1395, 1397, 1397, 1397,
+     1394, 1398, 1398, 1398, 2797, 1400, 1400, 1400, 1402, 1402,
+     1402, 2763, 1406, 1406, 1406, 1397, 1716, 1716, 1716, 1398,
+
+     2798, 2799, 1391, 1400, 2802, 1402, 1403, 1403, 1403, 1406,
+     1403, 2803, 2810, 1403, 1407, 1407, 1407, 2811, 1407, 2812,
+     2820, 1407, 1409, 1409, 1409, 1410, 1410, 1410, 1412, 1412,
+     1412, 1414, 1414, 1414, 2826, 1414, 2827, 2828, 1414, 2829,
+     1409, 2830, 1716, 1410, 2831, 2832, 1412, 1417, 1417, 1417,
+     2833, 2834, 1400, 1418, 1418, 1418, 1420, 1420, 1420, 1421,
+     1421, 1421, 1422, 1422, 1422, 1417, 1422, 2835, 2837, 1422,
+     2838, 1418, 2843, 2844, 1420, 2845, 1421, 1423, 1423, 1423,
+     1424, 1424, 1424, 2846, 1424, 2847, 2856, 1424, 1425, 1425,
+     1425, 2857, 1412, 2858, 1423, 1426, 1426, 1426, 2859, 1428,
+
+     1428, 1428, 1429, 1429, 1429, 2860, 1425, 1430, 1430, 1430,
+     2861, 1430, 2862, 1426, 1430, 2863, 1420, 1428, 2867, 1429,
+     1433, 1433, 1433, 1434, 1434, 1434, 2868, 1434, 2847, 2869,
+     1434, 1435, 1435, 1435, 1436, 1436, 1436, 1433, 1438, 1438,
+     1438, 1440, 1440, 1440, 1444, 1444, 1444, 2870, 2871, 1435,
+     2872, 2874, 1436, 1445, 1445, 1445, 1438, 2875, 1440, 2877,
+     2878, 1428, 1444, 1447, 1447, 1447, 1450, 1450, 1450, 2879,
+     2880, 1445, 1451, 1451, 1451, 1453, 1453, 1453, 1454, 1454,
+     1454, 1447, 1454, 2882, 1450, 1454, 1457, 1457, 1457, 2883,
+     1451, 2887, 2888, 1453, 1458, 1458, 1458, 1460, 1460, 1460,
+
+     1438, 1461, 1461, 1461, 1457, 1461, 2889, 2892, 1461, 1465,
+     1465, 1465, 1458, 2897, 2898, 1460, 1466, 1466, 1466, 1468,
+     1468, 1468, 2899, 2900, 1447, 2901, 2902, 1465, 1453, 1470,
+     1470, 1470, 2903, 2904, 1466, 2905, 2906, 1468, 1477, 1477,
+     1477, 1507, 1507, 1507, 1509, 1509, 1509, 1470, 1470, 2907,
+     1510, 1510, 1510, 1535, 1535, 1535, 1477, 1460, 1507, 1508,
+     1508, 1508, 1509, 1508, 2908, 2910, 1508, 1510, 1511, 1511,
+     1511, 1535, 1511, 2911, 2912, 1511, 1514, 1514, 1514, 2913,
+     1468, 1516, 1516, 1516, 2914, 1516, 2920, 2916, 1516, 1519,
+     1519, 1519, 2923, 2924, 1514, 2927, 1520, 1520, 1520, 2917,
+
+     1520, 2916, 1509, 1520, 1477, 2929, 1519, 1521, 1521, 1521,
+     2917, 1521, 2930, 2932, 1521, 1525, 1525, 1525, 2933, 1526,
+     1526, 1526, 2936, 1526, 2937, 1514, 1526, 1528, 1528, 1528,
+     2914, 2938, 1525, 1530, 1530, 1530, 1531, 1531, 1531, 2939,
+     1531, 2940, 2941, 1531, 2942, 1528, 1532, 1532, 1532, 2943,
+     1530, 1533, 1533, 1533, 1551, 1551, 1551, 1552, 1552, 1552,
+     1553, 1553, 1553, 1532, 1553, 2944, 2945, 1553, 2946, 1533,
+     2950, 1551, 2958, 2960, 1552, 2962, 2964, 1528, 1554, 1554,
+     1554, 1557, 1557, 1557, 1558, 1558, 1558, 1559, 1559, 1559,
+     2972, 1559, 2974, 2978, 1559, 2980, 1554, 2975, 2982, 1557,
+
+     1533, 1558, 1560, 1560, 1560, 1561, 1561, 1561, 1562, 1562,
+     1562, 2983, 1562, 2977, 2977, 1562, 1564, 1564, 1564, 2948,
+     1560, 2984, 1561, 1567, 1567, 1567, 1568, 1568, 1568, 2949,
+     1568, 2948, 2955, 1568, 1564, 1569, 1569, 1569, 2975, 2985,
+     1567, 2949, 1554, 2992, 2955, 1557, 1570, 1570, 1570, 1571,
+     1571, 1571, 1569, 1574, 1574, 1574, 2956, 1575, 1575, 1575,
+     2996, 1575, 1560, 1570, 1575, 3002, 2991, 1571, 2956, 2976,
+     1574, 1576, 1576, 1576, 1577, 1577, 1577, 1564, 1578, 1578,
+     1578, 3004, 1578, 2976, 2991, 1578, 1579, 1579, 1579, 1576,
+     2995, 1577, 1570, 1581, 1581, 1581, 1584, 1584, 1584, 1585,
+
+     1585, 1585, 3007, 1585, 1579, 2995, 1585, 1586, 1586, 1586,
+     1581, 1586, 3009, 1584, 1586, 1571, 1591, 1591, 1591, 1598,
+     1598, 1598, 1599, 1599, 1599, 3014, 1599, 3015, 3017, 1599,
+     1602, 1602, 1602, 1591, 1603, 1603, 1603, 1598, 1604, 1604,
+     1604, 1605, 1605, 1605, 1606, 1606, 1606, 1602, 1608, 1608,
+     1608, 1603, 1579, 2979, 3018, 1604, 3019, 3021, 1605, 1611,
+     1611, 1611, 1606, 1611, 2979, 1608, 1611, 3022, 3023, 1614,
+     1614, 1614, 1616, 1616, 1616, 1618, 1618, 1618, 1621, 1621,
+     1621, 1625, 1625, 1625, 1598, 1604, 1614, 1626, 1626, 1626,
+     1616, 3024, 3026, 1618, 3027, 3029, 1621, 3030, 1625, 1606,
+
+     3037, 1634, 1634, 1634, 1603, 1626, 1627, 1627, 1627, 3001,
+     1627, 1605, 3038, 1627, 1630, 1630, 1630, 3039, 1630, 1634,
+     3040, 1630, 1636, 1636, 1636, 3041, 1636, 1625, 3001, 1636,
+     1641, 1641, 1641, 3042, 1641, 1621, 1616, 1641, 1645, 1645,
+     1645, 1618, 3045, 3003, 1626, 1647, 1647, 1647, 1648, 1648,
+     1648, 3046, 1648, 3047, 3048, 1648, 1645, 1651, 1651, 1651,
+     3006, 1651, 3003, 1647, 1651, 3049, 3008, 1634, 1654, 1654,
+     1654, 1655, 1655, 1655, 3050, 1655, 3051, 3052, 1655, 3006,
+     1660, 1660, 1660, 3054, 1660, 3008, 1654, 1660, 1663, 1663,
+     1663, 1665, 1665, 1665, 1666, 1666, 1666, 3056, 1666, 1645,
+
+     3058, 1666, 1647, 1670, 1670, 1670, 1663, 3059, 1665, 1672,
+     1672, 1672, 1673, 1673, 1673, 1654, 1674, 1674, 1674, 3061,
+     3072, 1670, 1675, 1675, 1675, 3073, 1672, 1676, 1676, 1676,
+     1673, 1679, 1679, 1679, 1674, 1663, 1686, 1686, 1686, 1675,
+     1717, 1717, 1717, 3074, 1717, 1676, 3075, 1717, 3076, 1679,
+     3077, 3070, 1670, 3081, 1686, 1720, 1720, 1720, 1721, 1721,
+     1721, 3082, 1721, 3070, 3083, 1721, 3084, 3085, 1674, 1726,
+     1726, 1726, 3086, 1720, 1728, 1728, 1728, 3087, 1728, 1673,
+     3088, 1728, 1679, 1736, 1736, 1736, 3071, 1726, 1686, 1676,
+     1732, 1732, 1732, 3091, 1732, 3092, 3093, 1732, 3071, 1679,
+
+     3094, 1736, 1738, 1738, 1738, 3095, 1738, 3096, 3097, 1738,
+     1741, 1741, 1741, 3098, 1742, 1742, 1742, 3089, 1742, 3099,
+     1726, 1742, 1720, 1743, 1743, 1743, 3100, 1741, 1752, 1752,
+     1752, 1756, 1756, 1756, 1757, 1757, 1757, 1759, 1759, 1759,
+     3101, 1743, 3089, 3102, 1736, 1760, 1760, 1760, 3103, 1760,
+     3104, 3105, 1760, 3106, 1759, 1761, 1761, 1761, 3107, 1761,
+     3108, 3109, 1761, 1764, 1764, 1764, 1766, 1766, 1766, 1767,
+     1767, 1767, 3110, 3116, 1743, 1768, 1768, 1768, 3113, 1768,
+     3117, 1764, 1768, 1766, 1771, 1771, 1771, 1767, 3118, 1772,
+     1772, 1772, 1752, 1772, 3119, 1756, 1772, 3113, 1757, 1776,
+
+     1776, 1776, 1771, 1775, 1775, 1775, 3120, 1779, 1779, 1779,
+     1764, 1779, 3121, 3122, 1779, 3123, 1767, 1776, 3124, 3125,
+     1775, 1782, 1782, 1782, 1783, 1783, 1783, 3126, 1783, 3127,
+     3128, 1783, 1784, 1784, 1784, 1785, 1785, 1785, 1782, 1785,
+     3129, 3130, 1785, 1787, 1787, 1787, 1788, 1788, 1788, 1784,
+     1771, 1790, 1790, 1790, 3131, 1790, 3132, 3133, 1790, 3135,
+     3136, 1787, 3137, 1776, 1793, 1793, 1793, 1795, 1795, 1795,
+     3138, 1795, 3134, 3139, 1795, 1798, 1798, 1798, 1800, 1800,
+     1800, 3140, 1793, 1801, 1801, 1801, 3141, 1801, 3142, 3143,
+     1801, 3144, 3134, 1798, 3145, 1800, 1802, 1802, 1802, 1804,
+
+     1804, 1804, 3146, 1804, 3147, 3148, 1804, 1809, 1809, 1809,
+     1810, 1810, 1810, 1802, 1810, 3149, 3150, 1810, 1811, 1811,
+     1811, 1798, 3151, 3152, 1809, 1816, 1816, 1816, 1817, 1817,
+     1817, 1818, 1818, 1818, 3156, 1811, 1819, 1819, 1819, 3153,
+     1819, 3157, 1816, 1819, 3158, 3153, 1817, 3159, 1818, 1820,
+     1820, 1820, 1821, 1821, 1821, 1822, 1822, 1822, 1823, 1823,
+     1823, 1825, 1825, 1825, 3160, 3161, 1820, 3163, 3164, 1821,
+     3166, 3167, 1822, 1826, 1826, 1826, 1823, 1826, 1825, 3169,
+     1826, 1827, 1827, 1827, 1829, 1829, 1829, 3170, 1830, 1830,
+     1830, 3173, 1830, 3174, 1817, 1830, 3175, 3176, 1827, 3178,
+
+     3180, 1829, 1832, 1832, 1832, 1834, 1834, 1834, 3172, 3182,
+     1821, 1837, 1837, 1837, 1841, 1841, 1841, 3184, 1823, 3186,
+     1832, 3187, 3172, 1834, 3188, 3189, 1842, 1842, 1842, 1837,
+     1842, 1841, 3190, 1842, 1844, 1844, 1844, 1846, 1846, 1846,
+     1848, 1848, 1848, 1849, 1849, 1849, 1850, 1850, 1850, 1851,
+     1851, 1851, 1844, 3191, 3192, 1846, 1834, 1848, 3193, 1837,
+     1849, 3195, 3197, 1850, 1854, 1854, 1854, 1851, 1853, 1853,
+     1853, 3199, 1855, 1855, 1855, 1856, 1856, 1856, 1857, 1857,
+     1857, 3200, 1854, 1859, 1859, 1859, 1853, 1859, 1846, 1855,
+     1859, 3201, 1856, 1865, 1865, 1865, 1857, 3202, 1867, 1867,
+
+     1867, 1868, 1868, 1868, 3219, 1868, 3203, 3241, 1868, 3217,
+     1850, 1865, 3219, 3217, 1853, 1867, 1851, 1869, 1869, 1869,
+     1870, 1870, 1870, 1871, 1871, 1871, 1872, 1872, 1872, 1854,
+     1872, 3220, 3218, 1872, 1515, 1869, 3218, 3204, 1870, 3220,
+     1871, 3241, 3203, 1857, 1865, 1873, 1873, 1873, 1879, 1879,
+     1879, 1880, 1880, 1880, 1887, 1887, 1887, 1891, 1891, 1891,
+     1895, 1895, 1895, 1873, 3215, 1879, 1896, 1896, 1896, 1880,
+     1897, 1897, 1897, 3204, 3225, 1870, 1869, 1899, 1899, 1899,
+     1901, 1901, 1901, 1902, 1902, 1902, 1907, 1907, 1907, 1909,
+     1909, 1909, 1912, 1912, 1912, 3294, 1914, 1914, 1914, 1916,
+
+     1916, 1916, 1917, 1917, 1917, 3216, 3294, 1909, 3215, 3226,
+     1912, 3225, 1880, 1914, 1926, 1926, 1926, 1916, 1926, 1917,
+     3223, 1926, 1929, 1929, 1929, 1930, 1930, 1930, 1935, 1935,
+     1935, 1936, 1936, 1936, 1940, 1940, 1940, 3242, 3211, 1909,
+     1929, 3212, 1930, 1941, 1941, 1941, 3226, 1941, 3213, 3216,
+     1941, 1940, 1944, 1944, 1944, 1945, 1945, 1945, 1916, 1946,
+     1946, 1946, 1947, 1947, 1947, 3214, 1947, 3223, 1929, 1947,
+     1944, 3242, 1945, 1948, 1948, 1948, 1946, 1949, 1949, 1949,
+     1950, 1950, 1950, 1951, 1951, 1951, 3211, 1951, 3249, 3212,
+     1951, 1948, 1952, 1952, 1952, 1949, 3213, 1950, 3231, 1955,
+
+     1955, 1955, 1513, 1955, 3221, 1944, 1955, 1958, 1958, 1958,
+     1952, 1958, 3221, 3214, 1958, 1962, 1962, 1962, 1964, 1964,
+     1964, 3249, 1966, 1966, 1966, 3227, 1948, 1968, 1968, 1968,
+     3222, 1968, 3232, 1962, 1968, 1971, 1971, 1971, 3222, 1952,
+     1966, 1972, 1972, 1972, 3231, 1972, 3228, 3233, 1972, 1976,
+     1976, 1976, 1971, 1976, 3235, 3289, 1976, 1979, 1979, 1979,
+     1980, 1980, 1980, 3224, 1980, 1512, 3227, 1980, 1981, 1981,
+     1981, 1985, 1985, 1985, 1979, 1986, 1986, 1986, 3232, 1986,
+     1966, 3229, 1986, 3236, 3233, 1981, 3235, 3228, 1985, 1987,
+     1987, 1987, 1988, 1988, 1988, 3261, 1988, 3234, 3230, 1988,
+
+     1991, 1991, 1991, 3289, 1992, 1992, 1992, 1987, 1992, 3245,
+     3224, 1992, 1993, 1993, 1993, 3236, 3229, 1991, 1994, 1994,
+     1994, 1995, 1995, 1995, 3261, 1995, 1506, 3237, 1995, 1993,
+     1996, 1996, 1996, 3230, 3234, 1994, 3237, 1998, 1998, 1998,
+     1987, 1998, 3243, 3238, 1998, 2001, 2001, 2001, 1996, 2002,
+     2002, 2002, 3238, 2002, 1505, 3245, 2002, 2004, 2004, 2004,
+     3239, 2004, 2001, 3246, 2004, 2008, 2008, 2008, 2011, 2011,
+     2011, 2013, 2013, 2013, 2014, 2014, 2014, 2016, 2016, 2016,
+     3265, 1996, 3240, 2008, 3247, 3243, 2011, 3244, 2013, 2018,
+     2018, 2018, 2014, 2018, 2016, 3239, 2018, 2022, 2022, 2022,
+
+     2025, 2025, 2025, 2027, 2027, 2027, 2028, 2028, 2028, 3246,
+     2028, 3262, 1503, 2028, 3265, 2022, 3257, 3240, 2025, 3247,
+     2027, 3248, 3253, 2016, 2029, 2029, 2029, 2030, 2030, 2030,
+     3244, 2030, 2011, 1502, 2030, 2014, 2032, 2032, 2032, 3250,
+     3262, 2029, 2034, 2034, 2034, 2035, 2035, 2035, 2036, 2036,
+     2036, 2037, 2037, 2037, 2032, 2037, 3248, 3254, 2037, 3253,
+     2034, 1501, 3257, 2035, 3255, 2036, 2038, 2038, 2038, 2039,
+     2039, 2039, 3250, 2039, 3256, 3251, 2039, 2040, 2040, 2040,
+     2045, 2045, 2045, 2038, 3251, 2047, 2047, 2047, 3252, 2047,
+     3290, 2034, 2047, 3259, 3254, 2040, 3271, 3252, 2045, 2050,
+
+     2050, 2050, 2032, 2051, 2051, 2051, 3255, 2052, 2052, 2052,
+     2035, 2052, 3260, 1500, 2052, 1499, 3256, 2050, 2055, 2055,
+     2055, 2051, 2061, 2061, 2061, 2062, 2062, 2062, 3263, 2062,
+     3259, 3264, 2062, 2063, 2063, 2063, 2055, 3263, 3290, 2061,
+     3264, 3293, 2040, 3271, 1498, 2045, 2064, 2064, 2064, 3260,
+     2050, 2063, 2069, 2069, 2069, 3293, 2051, 2070, 2070, 2070,
+     2071, 2071, 2071, 2073, 2073, 2073, 2077, 2077, 2077, 2078,
+     2078, 2078, 2079, 2079, 2079, 2080, 2080, 2080, 2082, 2082,
+     2082, 2083, 2083, 2083, 2084, 2084, 2084, 2085, 2085, 2085,
+     2086, 2086, 2086, 2087, 2087, 2087, 3258, 2063, 2089, 2089,
+
+     2089, 2092, 2092, 2092, 1497, 2095, 2095, 2095, 2096, 2096,
+     2096, 3285, 2096, 3266, 1496, 2096, 2089, 1495, 1493, 2092,
+     3285, 2080, 2095, 2098, 2098, 2098, 2099, 2099, 2099, 2100,
+     2100, 2100, 3269, 2100, 1492, 1490, 2100, 2111, 2111, 2111,
+     3269, 2098, 3258, 2099, 2112, 2112, 2112, 3266, 3270, 2089,
+     2113, 2113, 2113, 3273, 2113, 2111, 3270, 2113, 2114, 2114,
+     2114, 2112, 2119, 2119, 2119, 2120, 2120, 2120, 2121, 2121,
+     2121, 2122, 2122, 2122, 3272, 2122, 3267, 1489, 2122, 2123,
+     2123, 2123, 2124, 2124, 2124, 2121, 2111, 2125, 2125, 2125,
+     3273, 2125, 3268, 3283, 2125, 1487, 1484, 2123, 3279, 2124,
+
+     2126, 2126, 2126, 3274, 2126, 3275, 3277, 2126, 2129, 2129,
+     2129, 2120, 3276, 2130, 2130, 2130, 2132, 2132, 2132, 3280,
+     2132, 3272, 3267, 2132, 1483, 3283, 2129, 2135, 2135, 2135,
+     2123, 2130, 2142, 2142, 2142, 2144, 2144, 2144, 3268, 2144,
+     3274, 3277, 2144, 3284, 3279, 2135, 3275, 2150, 2150, 2150,
+     2142, 2150, 3287, 3276, 2150, 2153, 2153, 2153, 1482, 2129,
+     2154, 2154, 2154, 3278, 2154, 3280, 3281, 2154, 3282, 2158,
+     2158, 2158, 2153, 2158, 1481, 3284, 2158, 2161, 2161, 2161,
+     2135, 2162, 2162, 2162, 3287, 2162, 1480, 2142, 2162, 2165,
+     2165, 2165, 2166, 2166, 2166, 2161, 2166, 1479, 3278, 2166,
+
+     2167, 2167, 2167, 3281, 2167, 3282, 2165, 2167, 2170, 2170,
+     2170, 2172, 2172, 2172, 1478, 2172, 3286, 1476, 2172, 2178,
+     2178, 2178, 2180, 2180, 2180, 3286, 2170, 2181, 2181, 2181,
+     1475, 2181, 1474, 1473, 2181, 1464, 3288, 2178, 1449, 2180,
+     1448, 2161, 2182, 2182, 2182, 2184, 2184, 2184, 2185, 2185,
+     2185, 1443, 2185, 1442, 1441, 2185, 3291, 2192, 2192, 2192,
+     2182, 1439, 2184, 2195, 2195, 2195, 3292, 2195, 3288, 1432,
+     2195, 2202, 2202, 2202, 2170, 2192, 2198, 2198, 2198, 1431,
+     2198, 1413, 1408, 2198, 1405, 2204, 2204, 2204, 3291, 2202,
+     2205, 2205, 2205, 2206, 2206, 2206, 1404, 2206, 3292, 1401,
+
+     2206, 1396, 2182, 2204, 1387, 2209, 2209, 2209, 2205, 2209,
+     1386, 1385, 2209, 2212, 2212, 2212, 1381, 2213, 2213, 2213,
+     1376, 1372, 2202, 2214, 2214, 2214, 2205, 2215, 2215, 2215,
+     1364, 2212, 1359, 2212, 2213, 2216, 2216, 2216, 1358, 1352,
+     2214, 2217, 2217, 2217, 2215, 2219, 2219, 2219, 2220, 2220,
+     2220, 2204, 2216, 2221, 2221, 2221, 2224, 2224, 2224, 2217,
+     2225, 2225, 2225, 2219, 2225, 1351, 2220, 2225, 2228, 2228,
+     2228, 2221, 1350, 1349, 2214, 2229, 2229, 2229, 2230, 2230,
+     2230, 2231, 2231, 2231, 1344, 1343, 2228, 2234, 2234, 2234,
+     1342, 2215, 1341, 1328, 2216, 2235, 2235, 2235, 2237, 2237,
+
+     2237, 2238, 2238, 2238, 1327, 2219, 2217, 2239, 2239, 2239,
+     2240, 2240, 2240, 2241, 2241, 2241, 2242, 2242, 2242, 2245,
+     2245, 2245, 2246, 2246, 2246, 1326, 1325, 2228, 2247, 2247,
+     2247, 2248, 2248, 2248, 2250, 2250, 2250, 2253, 2253, 2253,
+     2254, 2254, 2254, 1324, 2254, 1323, 1322, 2254, 2257, 2257,
+     2257, 1321, 2250, 1320, 2253, 2258, 2258, 2258, 1310, 2260,
+     2260, 2260, 1309, 2260, 1308, 2257, 2260, 2273, 2273, 2273,
+     2274, 2274, 2274, 2258, 2274, 2275, 2275, 2274, 2275, 1307,
+     2276, 2276, 1290, 2276, 1289, 2273, 2275, 1284, 1283, 2275,
+     1278, 2276, 1277, 2275, 2276, 2277, 2277, 2277, 2276, 2278,
+
+     2278, 2278, 2282, 2282, 2282, 2284, 2284, 2284, 1258, 2284,
+     1254, 1248, 2284, 1244, 2257, 2287, 2287, 2287, 2288, 2288,
+     2288, 1243, 2288, 1242, 1241, 2288, 1240, 1239, 2273, 2291,
+     2291, 2291, 1238, 2287, 2292, 2292, 2292, 2300, 2300, 2300,
+     2301, 2301, 2301, 1236, 2306, 2306, 2306, 2291, 2306, 1235,
+     1233, 2306, 2292, 2309, 2309, 2309, 1232, 1231, 2301, 1226,
+     1218, 2287, 2312, 2312, 2312, 2313, 2313, 2313, 1216, 2313,
+     2309, 1211, 2313, 2316, 2316, 2316, 2321, 2321, 2321, 1209,
+     2312, 2323, 2323, 2323, 1200, 2292, 2324, 2324, 2324, 1195,
+     2324, 2316, 1184, 2324, 2321, 2327, 2327, 2327, 2323, 1182,
+
+     2301, 2328, 2328, 2328, 2329, 2329, 2329, 1181, 2329, 1180,
+     1179, 2329, 1177, 2327, 2332, 2332, 2332, 1176, 2328, 2333,
+     2333, 2333, 2338, 2338, 2338, 2340, 2340, 2340, 2343, 2343,
+     2343, 2332, 2342, 2342, 2342, 1175, 2333, 1174, 1173, 2338,
+     2344, 2344, 2344, 1172, 1170, 2343, 2327, 2328, 1169, 1168,
+     2342, 1167, 2345, 2345, 2345, 2347, 2347, 2347, 2344, 2346,
+     2346, 2346, 1166, 1165, 2348, 2348, 2348, 1164, 2348, 2332,
+     2345, 2348, 2347, 2338, 2349, 2349, 2349, 2346, 1162, 1161,
+     2333, 2350, 2350, 2350, 2351, 2351, 2351, 2352, 2352, 2352,
+     1160, 2349, 2353, 2353, 2353, 1159, 2346, 1158, 2350, 1157,
+
+     2344, 2351, 2354, 2354, 2354, 2352, 2355, 2355, 2355, 2357,
+     2357, 2357, 1156, 2345, 2360, 2360, 2360, 2362, 2362, 2362,
+     2354, 2361, 2361, 2361, 2355, 1150, 1149, 2357, 2363, 2363,
+     2363, 1148, 2350, 1145, 1144, 2351, 2366, 2366, 2366, 2361,
+     2367, 2367, 2367, 2368, 2368, 2368, 2369, 2369, 2369, 2373,
+     2373, 2373, 2376, 2376, 2376, 2377, 2377, 2377, 1143, 2377,
+     1141, 1137, 2377, 2389, 2389, 2389, 1134, 2373, 2354, 2376,
+     1125, 2357, 2402, 2402, 2402, 2405, 2405, 2405, 2407, 2407,
+     2407, 2389, 2408, 2408, 2408, 2410, 2410, 2410, 2417, 2417,
+     2417, 2418, 2418, 2418, 1124, 1121, 2407, 2419, 2419, 2419,
+
+     2408, 1120, 1119, 2410, 1118, 2417, 1117, 2425, 2425, 2425,
+     2426, 2426, 2426, 1103, 2426, 2419, 1096, 2426, 2428, 2428,
+     2428, 1088, 1087, 2389, 2425, 2429, 2429, 2429, 2431, 2431,
+     2431, 2435, 2435, 2435, 1086, 2428, 2437, 2437, 2437, 1083,
+     2439, 2439, 2439, 2429, 2407, 1080, 2431, 1077, 2435, 2440,
+     2440, 2440, 1072, 2437, 2419, 2438, 2438, 2438, 2439, 2438,
+     1069, 1068, 2438, 2441, 2441, 2441, 2440, 2441, 1064, 1062,
+     2441, 2442, 2442, 2442, 2443, 2443, 2443, 2444, 2444, 2444,
+     2449, 2449, 2449, 2451, 2451, 2451, 1048, 1047, 2442, 1046,
+     1045, 2443, 1044, 1043, 2444, 1042, 1041, 2449, 2453, 2453,
+
+     2453, 2455, 2455, 2455, 2456, 2456, 2456, 1040, 2456, 1036,
+     1032, 2456, 2457, 2457, 2457, 1025, 2453, 1022, 2455, 2458,
+     2458, 2458, 1021, 2442, 2459, 2459, 2459, 2460, 2460, 2460,
+     2457, 2460, 2443, 1020, 2460, 2444, 1017, 2458, 2463, 2463,
+     2463, 1016, 2459, 2464, 2464, 2464, 1013, 2464, 1012, 1011,
+     2464, 2465, 2465, 2465, 1008, 2463, 2466, 2466, 2466, 2467,
+     2467, 2467, 2469, 2469, 2469, 2470, 2470, 2470, 2465, 2474,
+     2474, 2474, 1007, 2466, 2478, 2478, 2478, 2467, 2482, 2482,
+     2482, 1004,  999, 2470,  996,  993, 2458, 2474, 2459, 2483,
+     2483, 2483,  992, 2483,  989, 2482, 2483, 2497, 2497, 2497,
+
+     2514, 2514, 2514, 2516, 2516, 2516, 2517, 2517, 2517, 2520,
+     2520, 2520, 2523, 2523, 2523, 2497, 2524, 2524, 2524,  988,
+     2524, 2516,  987, 2524, 2517,  986, 2520,  985,  983, 2523,
+     2525, 2525, 2525, 2529, 2529, 2529, 2531, 2531, 2531,  982,
+     2531,  981,  980, 2531, 2535, 2535, 2535,  979, 2525,  978,
+     2529, 2536, 2536, 2536,  977, 2536,  976, 2497, 2536,  972,
+      967, 2535, 2538, 2538, 2538, 2539, 2539, 2539, 2540, 2540,
+     2540,  966, 2540,  965, 2516, 2540, 2541, 2541, 2541, 2538,
+      962,  961, 2539, 2542, 2542, 2542,  960, 2542,  958,  954,
+     2542,  950,  949, 2541, 2545, 2545, 2545, 2547, 2547, 2547,
+
+      946, 2547,  943,  942, 2547, 2550, 2550, 2550, 2551, 2551,
+     2551,  941, 2545, 2552, 2552, 2552, 2555, 2555, 2555, 2556,
+     2556, 2556, 2550, 2556,  940, 2551, 2556, 2557, 2557, 2557,
+     2552,  939,  938, 2555, 2558, 2558, 2558,  937, 2559, 2559,
+     2559,  935, 2559,  934, 2557, 2559, 2562, 2562, 2562,  933,
+      932, 2558, 2564, 2564, 2564, 2565, 2565, 2565,  931, 2551,
+     2550, 2569, 2569, 2569, 2562, 2566, 2566, 2566, 2552, 2566,
+     2564,  930, 2566, 2565,  929, 2570, 2570, 2570, 2569, 2570,
+      928,  927, 2570, 2571, 2571, 2571, 2572, 2572, 2572,  926,
+     2572,  925,  924, 2572, 2573, 2573, 2573, 2579, 2579, 2579,
+
+     2571,  923, 2583, 2583, 2583,  922, 2584, 2584, 2584,  921,
+     2584,  920, 2573, 2584,  919,  918, 2565,  917, 2564, 2583,
+     2602, 2602, 2602, 2618, 2618, 2618, 2620, 2620, 2620, 2621,
+     2621, 2621, 2622, 2622, 2622, 2623, 2623, 2623, 2602, 2623,
+      916,  915, 2623,  911, 2620,  910, 2621,  908,  907, 2622,
+     2624, 2624, 2624,  906, 2624,  905,  904, 2624, 2627, 2627,
+     2627, 2631, 2631, 2631, 2632, 2632, 2632,  900, 2634, 2634,
+     2634, 2602, 2675, 2675, 2675, 2621, 2627,  898, 2631,  897,
+      896, 2632, 2633, 2633, 2633, 2634, 2633,  895, 2620, 2633,
+     2636, 2636, 2636,  891, 2636,  887,  886, 2636, 2640, 2640,
+
+     2640, 2641, 2641, 2641,  883, 2641,  882,  881, 2641, 2642,
+     2642, 2642,  880, 2642,  879, 2640, 2642, 2645, 2645, 2645,
+     2646, 2646, 2646,  878, 2646,  877,  874, 2646, 2647, 2647,
+     2647, 2648, 2648, 2648, 2645, 2649, 2649, 2649,  873, 2650,
+     2650, 2650,  872, 2650,  871, 2647, 2650,  868, 2648, 2653,
+     2653, 2653, 2649, 2654, 2654, 2654,  867, 2654,  866,  863,
+     2654, 2655, 2655, 2655,  861,  858, 2653, 2656, 2656, 2656,
+      857, 2656,  856,  855, 2656, 2663, 2663, 2663, 2655, 2664,
+     2664, 2664,  854,  851, 2649,  850, 2647, 2665, 2665, 2665,
+      849, 2665,  848, 2663, 2665,  847,  844, 2664, 2668, 2668,
+
+     2668,  843, 2668,  842,  841, 2668, 2673, 2673, 2673, 2676,
+     2676, 2676, 2679, 2679, 2679,  839, 2679,  836,  835, 2679,
+     2690, 2690, 2690, 2673, 2673,  833, 2663, 2699, 2699, 2699,
+     2715, 2715, 2715, 2716, 2716, 2716,  830, 2690, 2717, 2717,
+     2717, 2718, 2718, 2718,  828, 2699, 2664, 2719, 2719, 2719,
+      825, 2719,  824,  823, 2719,  822, 2717,  820, 2718, 2721,
+     2721, 2721,  819, 2721,  818,  815, 2721, 2726, 2726, 2726,
+     2727, 2727, 2727,  814, 2727,  813, 2699, 2727, 2728, 2728,
+     2728,  812, 2728,  811, 2726, 2728, 2731, 2731, 2731, 2717,
+     2732, 2732, 2732,  810, 2732,  805,  804, 2732, 2735, 2735,
+
+     2735,  803, 2735, 2731,  802, 2735, 2738, 2738, 2738,  801,
+     2738,  800,  799, 2738, 2741, 2741, 2741, 2742, 2742, 2742,
+     2743, 2743, 2743,  798, 2743,  797,  796, 2743, 2744, 2744,
+     2744, 2741,  795,  793, 2742, 2745, 2745, 2745,  791, 2745,
+      790,  787, 2745,  784,  781, 2744, 2748, 2748, 2748,  780,
+     2748,  776,  775, 2748, 2757, 2757, 2757, 2758, 2758, 2758,
+     2764, 2764, 2764,  774,  771, 2741, 2765, 2765, 2765, 2766,
+     2766, 2766, 2757, 2766,  768, 2758, 2766, 2764, 2764, 2767,
+     2767, 2767,  767, 2765, 2765,  766,  763, 2766, 2768, 2768,
+     2768, 2769, 2769, 2769, 2770, 2770, 2770,  762,  758, 2744,
+
+     2779, 2779, 2779, 2780, 2780, 2780,  757, 2780,  755,  752,
+     2780, 2789, 2789, 2789, 2804, 2804, 2804, 2779, 2805, 2805,
+     2805,  751,  750, 2758, 2806, 2806, 2806,  748,  737, 2789,
+     2807, 2807, 2807,  735, 2807,  732,  731, 2807,  730, 2813,
+     2813, 2813, 2806, 2813,  728,  727, 2813, 2816, 2816, 2816,
+      726, 2816,  722,  721, 2816, 2819, 2819, 2819, 2821, 2821,
+     2821, 2822, 2822, 2822,  720, 2822,  719,  716, 2822, 2825,
+     2825, 2825, 2819,  715,  714, 2821,  713, 2789, 2840, 2840,
+     2840, 2842, 2842, 2842,  712,  711, 2825, 2848, 2848, 2848,
+     2849, 2849, 2849,  710, 2849,  708, 2840, 2849,  705, 2842,
+
+     2853, 2853, 2853,  704, 2848, 2848,  702,  700, 2849, 2850,
+     2850, 2850,  697, 2850,  696,  690, 2850, 2854, 2854, 2854,
+     2855, 2855, 2855,  688, 2864, 2864, 2864, 2850, 2864,  686,
+      683, 2864, 2842, 2851, 2851, 2851, 2851, 2851, 2851, 2851,
+     2851, 2851,  682,  678, 2851, 2873, 2873, 2873,  677, 2851,
+     2851, 2851, 2851, 2851, 2884, 2884, 2884, 2885, 2885, 2885,
+     2890, 2890, 2890, 2873, 2891, 2891, 2891,  676, 2891,  675,
+      672, 2891, 2893, 2893, 2893, 2885,  671, 2890, 2851, 2851,
+     2852, 2852, 2852, 2852, 2852, 2852, 2852, 2852, 2852, 2893,
+      670, 2852, 2895, 2895, 2895,  669, 2852, 2852, 2852, 2852,
+
+     2852, 2894, 2894, 2894,  666, 2894,  665,  664, 2894, 2895,
+     2896, 2896, 2896,  663, 2896,  662,  656, 2896, 2909, 2909,
+     2909, 2934, 2934, 2934,  655, 2852, 2852, 2915, 2915, 2915,
+      653, 2915,  647,  646, 2915,  642, 2909,  635,  631, 2934,
+     2969, 2969, 2969,  625,  621, 2915, 2918, 2918, 2918, 2918,
+     2918, 2918, 2918, 2918, 2918,  613,  612, 2918, 2969,  611,
+      610,  609, 2918, 2918, 2918, 2918, 2918, 2947, 2947, 2947,
+      605, 2947,  598,  597, 2947, 2951, 2951, 2951,  596, 2951,
+      592,  585, 2951, 2954, 2954, 2954,  584, 2954,  580,  574,
+     2954, 2918, 2918, 2919, 2919, 2919, 2919, 2919, 2919, 2919,
+
+     2919, 2919,  573,  569, 2919, 2981, 2981, 2981,  561, 2919,
+     2919, 2919, 2919, 2919, 2998, 2998, 2998, 2999, 2999, 2999,
+     3000, 3000, 3000, 2981, 2981, 3005, 3005, 3005, 3016, 3016,
+     3016, 2998,  560,  556, 2999,  547,  543, 3000, 2919, 2919,
+      535,  534, 3005, 3020, 3020, 3020, 3016, 3031, 3031, 3031,
+     3032, 3032, 3032,  533, 3032,  529,  523, 3032, 3033, 3033,
+     3033, 3020,  522,  521, 3031, 3034, 3034, 3034,  517, 3034,
+      511,  510, 3034,  506,  500, 3033, 3035, 3035, 3035, 3036,
+     3036, 3036,  499, 3036,  498,  497, 3036, 3043, 3043, 3043,
+     3053, 3053, 3053, 3035, 3020, 3044, 3044, 3044,  496, 3044,
+
+      495,  494, 3044,  490, 3043, 3063, 3063, 3063, 3053, 3063,
+      484,  483, 3063, 3066, 3066, 3066,  481, 3066,  480,  479,
+     3066, 3069, 3069, 3069,  475, 3069,  465, 3053, 3069, 3078,
+     3078, 3078,  464, 3078,  462,  458, 3078, 3185, 3185, 3185,
+     3194, 3194, 3194,  452, 3194,  451,  450, 3194, 3295, 3295,
+     3295, 3296, 3296, 3296,  446, 3185,  440,  436, 3194,  428,
+      427,  426,  425,  424,  420,  414, 3295,  413,  409, 3296,
+     3299, 3299, 3299, 3299, 3299, 3299, 3299, 3299, 3299, 3300,
+     3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3301, 3301,
+     3301, 3301, 3301, 3301, 3301, 3301, 3301, 3302, 3302, 3302,
+
+     3302, 3302, 3302, 3302, 3302, 3302, 3303, 3303, 3303, 3303,
+     3303, 3303, 3303, 3303, 3303, 3304, 3304, 3304, 3304, 3304,
+     3304, 3304, 3304, 3304, 3305, 3305, 3305, 3305, 3305, 3305,
+     3305, 3305, 3305, 3306, 3306, 3306, 3306, 3306, 3306, 3306,
+     3306, 3306, 3307, 3307, 3307, 3307, 3307, 3307, 3307, 3307,
+     3307, 3308, 3308, 3308, 3308, 3308, 3308, 3308, 3308, 3308,
+     3309, 3309, 3309, 3309, 3309, 3309, 3309, 3309, 3309, 3310,
+     3310, 3310, 3310, 3310, 3310, 3310, 3310, 3310, 3311, 3311,
+     3311, 3311, 3311, 3311, 3311, 3311, 3311, 3312, 3312, 3312,
+     3312, 3312, 3312, 3312, 3312, 3312, 3313, 3313, 3313, 3313,
+
+     3313, 3313, 3313, 3313, 3313, 3314, 3314, 3314, 3314, 3314,
+     3314, 3314, 3314, 3314, 3315, 3315, 3315, 3315, 3315, 3315,
+     3315, 3315, 3315, 3316, 3316, 3316, 3316, 3316, 3316, 3316,
+     3316, 3316, 3317, 3317, 3317, 3317, 3317, 3317, 3317, 3317,
+     3317, 3318, 3318, 3318, 3318, 3318, 3318, 3318, 3318, 3318,
+     3319, 3319, 3319, 3319, 3319, 3319, 3319, 3319, 3319, 3320,
+     3320, 3320, 3320, 3320, 3320, 3320, 3320, 3320, 3321, 3321,
+     3321, 3321, 3321, 3321, 3321, 3321, 3321, 3322, 3322, 3322,
+     3322, 3322, 3322, 3322, 3322, 3322, 3323, 3323, 3323, 3323,
+     3323, 3323, 3323, 3323, 3323, 3324, 3324, 3324, 3324, 3324,
+
+     3324, 3324, 3324, 3324, 3325, 3325, 3325, 3325, 3325, 3325,
+     3325, 3325, 3325, 3326, 3326, 3326, 3326, 3326, 3326, 3326,
+     3326, 3326, 3327, 3327, 3327, 3327, 3327, 3327, 3327, 3327,
+     3327, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328,
+     3329, 3329, 3329, 3329, 3329, 3329, 3329, 3329, 3329, 3330,
+     3330, 3330, 3330, 3330, 3330, 3330, 3330, 3330, 3331, 3331,
+     3331, 3331, 3331, 3331, 3331, 3331, 3331, 3332, 3332, 3332,
+     3332, 3332, 3332, 3332, 3332, 3332, 3333, 3333, 3333, 3333,
+     3333, 3333, 3333, 3333, 3333, 3334, 3334, 3334, 3334, 3334,
+     3334, 3334, 3334, 3334, 3335, 3335, 3335, 3335, 3335, 3335,
+
+     3335, 3335, 3335, 3336, 3336, 3336, 3336, 3336, 3336, 3336,
+     3336, 3336, 3337, 3337, 3337, 3337, 3337, 3337, 3337, 3337,
+     3337, 3338, 3338, 3338, 3338, 3338, 3338, 3338, 3338, 3338,
+     3339, 3339, 3339, 3339, 3339, 3339, 3339, 3339, 3339, 3340,
+     3340, 3340, 3340, 3340, 3340, 3340, 3340, 3340, 3341, 3341,
+     3341, 3341, 3341, 3341, 3341, 3341, 3341, 3342, 3342, 3342,
+     3342, 3342, 3342, 3342, 3342, 3342, 3343, 3343, 3343, 3343,
+     3343, 3343, 3343, 3343, 3343, 3344, 3344, 3344, 3344, 3344,
+     3344, 3344, 3344, 3344, 3345, 3345, 3345, 3345, 3345, 3345,
+     3345, 3345, 3345, 3346, 3346, 3346, 3346, 3346, 3346, 3346,
+
+     3346, 3346, 3347, 3347, 3347, 3347, 3347, 3347, 3347, 3347,
+     3347, 3348, 3348, 3348, 3348, 3348, 3348, 3348, 3348, 3348,
+     3349, 3349, 3349, 3349, 3349, 3349, 3349, 3349, 3349, 3350,
+     3350, 3350, 3350, 3350, 3350, 3350, 3350, 3350, 3351, 3351,
+     3351, 3351, 3351, 3351, 3351, 3351, 3351, 3352, 3352, 3352,
+     3352, 3352, 3352, 3352, 3352, 3352, 3353, 3353, 3353, 3353,
+     3353, 3353, 3353, 3353, 3353, 3354, 3354, 3354, 3354, 3354,
+     3354, 3354, 3354, 3354, 3355, 3355, 3355, 3355, 3355, 3355,
+     3355, 3355, 3355, 3356, 3356, 3356, 3356, 3356, 3356, 3356,
+     3356, 3356, 3357, 3357, 3357, 3357, 3357, 3357, 3357, 3357,
+
+     3357, 3358, 3358, 3358, 3358, 3358, 3358, 3358, 3358, 3358,
+     3359, 3359, 3359, 3359, 3359, 3359, 3359, 3359, 3359, 3360,
+     3360, 3360,  403,  402,  398, 3360, 3361, 3361, 3361,  391,
+      390,  389, 3361, 3362, 3362, 3362,  385,  378,  377, 3362,
+     3363, 3363, 3363,  376,  375,  371, 3363, 3364, 3364, 3364,
+      362,  356,  352, 3364, 3365, 3365, 3365,  351,  347,  341,
+     3365, 3366, 3366, 3366,  340,  339,  335, 3366, 3367, 3367,
+     3367,  328,  326,  325, 3367, 3368, 3368, 3368,  321,  318,
+      316, 3368, 3369, 3369, 3369,  315,  314,  310, 3369, 3370,
+     3370, 3370,  306,  303,  299, 3370, 3371, 3371, 3371,  296,
+
+      295,  287, 3371, 3372, 3372, 3372,  283,  279,  278, 3372,
+     3373, 3373, 3373,  277,  271,  270, 3373, 3374, 3374, 3374,
+      268,  265,  253, 3374, 3375, 3375, 3375,    0,    0,    0,
+     3375, 3376, 3376, 3376,    0,    0,    0, 3376, 3377, 3377,
+     3377,    0,    0,    0, 3377, 3378, 3378, 3378,    0,    0,
+        0, 3378, 3379, 3379, 3379,    0,    0,    0, 3379, 3380,
+     3380, 3380,    0,    0,    0, 3380, 3381, 3381, 3381,    0,
+        0,    0, 3381, 3382, 3382, 3382,    0,    0,    0, 3382,
+     3383, 3383, 3383,    0,    0,    0, 3383, 3384, 3384, 3384,
+        0,    0,    0, 3384, 3385, 3385, 3385,    0,    0,    0,
+
+     3385, 3386, 3386, 3386,    0,    0,    0, 3386, 3387, 3387,
+     3387,    0,    0,    0, 3387, 3388, 3388, 3388, 3388, 3388,
+     3388, 3388,    0, 3388, 3389, 3389, 3389,    0,    0,    0,
+     3389, 3390,    0,    0,    0, 3390, 3391, 3391, 3391,    0,
+        0,    0, 3391, 3392,    0,    0,    0, 3392, 3393, 3393,
+     3393,    0,    0,    0, 3393, 3394,    0,    0,    0, 3394,
+     3395, 3395, 3395,    0,    0,    0, 3395, 3396,    0,    0,
+        0, 3396, 3397, 3397, 3397,    0,    0,    0, 3397, 3398,
+        0,    0,    0, 3398, 3399, 3399, 3399,    0,    0,    0,
+     3399, 3400,    0,    0,    0, 3400, 3401, 3401, 3401,    0,
+
+        0,    0, 3401, 3402,    0,    0,    0, 3402, 3403, 3403,
+     3403,    0,    0,    0, 3403, 3404,    0,    0,    0, 3404,
+     3405, 3405, 3405,    0,    0,    0, 3405, 3406,    0,    0,
+        0, 3406, 3407, 3407, 3407,    0,    0,    0, 3407, 3408,
+        0,    0,    0, 3408, 3409, 3409, 3409,    0,    0,    0,
+     3409, 3410,    0,    0,    0, 3410, 3411, 3411, 3411,    0,
+        0,    0, 3411, 3412,    0,    0,    0, 3412, 3413, 3413,
+     3413,    0,    0,    0, 3413, 3414,    0,    0,    0, 3414,
+     3415, 3415, 3415,    0,    0,    0, 3415, 3416,    0,    0,
+        0, 3416, 3417, 3417, 3417,    0,    0,    0, 3417, 3418,
+
+        0,    0,    0, 3418, 3419, 3419, 3419,    0,    0,    0,
+     3419, 3420,    0,    0,    0, 3420, 3421, 3421, 3421,    0,
+        0,    0, 3421, 3422,    0,    0,    0, 3422, 3423, 3423,
+     3423,    0,    0,    0, 3423, 3424,    0,    0,    0, 3424,
+     3425, 3425, 3425,    0,    0,    0, 3425, 3426,    0,    0,
+        0, 3426, 3427, 3427, 3427,    0,    0,    0, 3427, 3428,
+        0,    0,    0, 3428, 3429, 3429, 3429,    0,    0,    0,
+     3429, 3430,    0,    0,    0, 3430, 3431, 3431, 3431,    0,
+        0,    0, 3431, 3432,    0,    0,    0, 3432, 3433, 3433,
+     3433,    0,    0,    0, 3433, 3434,    0,    0,    0, 3434,
+
+     3435, 3435, 3435,    0,    0,    0, 3435, 3436,    0,    0,
+        0, 3436, 3437, 3437, 3437,    0,    0,    0, 3437, 3438,
+        0,    0,    0, 3438, 3439, 3439, 3439,    0,    0,    0,
+     3439, 3440,    0,    0,    0, 3440, 3441, 3441, 3441,    0,
+        0,    0, 3441, 3442,    0,    0,    0, 3442, 3443, 3443,
+     3443,    0,    0,    0, 3443, 3444,    0,    0,    0, 3444,
+     3445, 3445, 3445, 3445, 3445, 3445, 3445, 3445, 3445, 3446,
+        0,    0,    0,    0, 3446, 3447, 3447, 3447,    0,    0,
+        0, 3447, 3448, 3448, 3448, 3448,    0,    0, 3448, 3448,
+     3449, 3449, 3449,    0,    0,    0, 3449, 3450, 3450, 3450,
+
+     3450,    0,    0, 3450, 3450, 3451, 3451, 3451,    0,    0,
+        0, 3451, 3452, 3452, 3452, 3452,    0,    0, 3452, 3452,
+     3453, 3453, 3453,    0,    0,    0, 3453, 3454, 3454, 3454,
+     3454,    0,    0, 3454, 3454, 3455, 3455, 3455,    0,    0,
+        0, 3455, 3456, 3456, 3456, 3456,    0,    0, 3456, 3456,
+     3457, 3457, 3457,    0,    0,    0, 3457, 3458, 3458, 3458,
+     3458,    0,    0, 3458, 3458, 3459, 3459, 3459,    0,    0,
+        0, 3459, 3460, 3460, 3460, 3460,    0,    0, 3460, 3460,
+     3461, 3461, 3461,    0,    0,    0, 3461, 3462, 3462, 3462,
+     3462,    0,    0, 3462, 3462, 3463, 3463, 3463,    0,    0,
+
+        0, 3463, 3464, 3464, 3464, 3464,    0,    0, 3464, 3464,
+     3465, 3465, 3465,    0,    0,    0, 3465, 3466, 3466, 3466,
+     3466,    0,    0, 3466, 3466, 3467, 3467, 3467,    0,    0,
+        0, 3467, 3468, 3468, 3468, 3468,    0,    0, 3468, 3468,
+     3469, 3469, 3469,    0,    0,    0, 3469, 3470, 3470, 3470,
+     3470,    0,    0, 3470, 3470, 3471, 3471, 3471,    0,    0,
+        0, 3471, 3472, 3472, 3472, 3472,    0,    0, 3472, 3472,
+     3473, 3473, 3473,    0,    0,    0, 3473, 3474, 3474, 3474,
+     3474,    0,    0, 3474, 3474, 3475, 3475, 3475, 3475,    0,
+     3475,    0, 3475, 3476, 3476, 3476, 3476,    0,    0, 3476,
+
+     3476, 3477, 3477, 3477,    0,    0,    0, 3477, 3478, 3478,
+     3478, 3478,    0,    0, 3478, 3478, 3479, 3479, 3479,    0,
+        0,    0, 3479, 3480, 3480, 3480, 3480,    0,    0, 3480,
+     3480, 3481, 3481, 3481,    0,    0,    0, 3481, 3482, 3482,
+     3482, 3482,    0,    0, 3482, 3482, 3483, 3483, 3483,    0,
+        0,    0, 3483, 3484, 3484, 3484, 3484,    0,    0, 3484,
+     3484, 3485, 3485, 3485, 3485,    0, 3485,    0, 3485, 3486,
+     3486, 3486, 3486,    0,    0, 3486, 3486, 3487, 3487, 3487,
+     3487,    0, 3487,    0, 3487, 3488, 3488, 3488, 3488,    0,
+        0, 3488, 3488, 3489, 3489, 3489,    0,    0,    0, 3489,
+
+     3490, 3490, 3490, 3490,    0,    0, 3490, 3490, 3491, 3491,
+     3491, 3491,    0, 3491,    0, 3491, 3492, 3492, 3492, 3492,
+        0,    0, 3492, 3492, 3493, 3493, 3493, 3493,    0, 3493,
+        0, 3493, 3494, 3494, 3494, 3494,    0,    0, 3494, 3494,
+     3495, 3495, 3495,    0,    0,    0, 3495, 3496, 3496, 3496,
+     3496,    0,    0, 3496, 3496, 3497, 3497, 3497,    0,    0,
+        0, 3497, 3498, 3498, 3498, 3498,    0,    0, 3498, 3498,
+     3499, 3499, 3499, 3499,    0,    0, 3499, 3499, 3500, 3500,
+     3500,    0,    0,    0, 3500, 3501, 3501, 3501, 3501,    0,
+        0, 3501, 3501, 3502, 3502, 3502, 3502, 3502, 3502, 3502,
+
+     3502, 3502, 3503,    0, 3503,    0,    0, 3503, 3504, 3504,
+     3504,    0,    0,    0, 3504, 3505, 3505, 3505, 3505,    0,
+        0, 3505, 3505, 3506, 3506, 3506, 3506,    0, 3506,    0,
+     3506, 3507, 3507, 3507, 3507,    0,    0, 3507, 3507, 3508,
+     3508, 3508, 3508,    0, 3508,    0, 3508, 3509, 3509, 3509,
+     3509,    0,    0, 3509, 3509, 3510, 3510, 3510,    0,    0,
+        0, 3510, 3511, 3511, 3511, 3511,    0,    0, 3511, 3511,
+     3512, 3512, 3512,    0,    0,    0, 3512, 3513, 3513, 3513,
+     3513,    0,    0, 3513, 3513, 3514, 3514, 3514,    0,    0,
+        0, 3514, 3515, 3515, 3515, 3515,    0,    0, 3515, 3515,
+
+     3516, 3516, 3516,    0,    0,    0, 3516, 3517, 3517, 3517,
+     3517,    0,    0, 3517, 3517, 3518, 3518, 3518,    0,    0,
+        0, 3518, 3519, 3519, 3519, 3519,    0,    0, 3519, 3519,
+     3520, 3520, 3520, 3520,    0, 3520,    0, 3520, 3521, 3521,
+     3521, 3521,    0,    0, 3521, 3521, 3522, 3522, 3522, 3522,
+        0, 3522,    0, 3522, 3523, 3523, 3523, 3523,    0,    0,
+     3523, 3523, 3524, 3524, 3524,    0,    0,    0, 3524, 3525,
+     3525, 3525, 3525,    0,    0, 3525, 3525, 3526, 3526, 3526,
+     3526,    0, 3526,    0, 3526, 3527, 3527, 3527, 3527,    0,
+        0, 3527, 3527, 3528, 3528, 3528, 3528,    0, 3528,    0,
+
+     3528, 3529, 3529, 3529, 3529,    0,    0, 3529, 3529, 3530,
+     3530, 3530,    0,    0,    0, 3530, 3531, 3531, 3531, 3531,
+        0,    0, 3531, 3531, 3532, 3532, 3532,    0,    0,    0,
+     3532, 3533, 3533, 3533, 3533,    0,    0, 3533, 3533, 3534,
+     3534, 3534,    0,    0,    0, 3534, 3535, 3535, 3535, 3535,
+        0,    0, 3535, 3535, 3536, 3536, 3536,    0,    0,    0,
+     3536, 3537, 3537, 3537, 3537,    0,    0, 3537, 3537, 3538,
+     3538, 3538,    0,    0,    0, 3538, 3539, 3539, 3539, 3539,
+        0,    0, 3539, 3539, 3540, 3540, 3540,    0,    0,    0,
+     3540, 3541, 3541, 3541, 3541,    0,    0, 3541, 3541, 3542,
+
+     3542, 3542,    0,    0,    0, 3542, 3543, 3543, 3543, 3543,
+        0,    0, 3543, 3543, 3544, 3544, 3544,    0,    0,    0,
+     3544, 3545, 3545, 3545, 3545,    0,    0, 3545, 3545, 3546,
+     3546, 3546,    0,    0,    0, 3546, 3547, 3547, 3547, 3547,
+        0,    0, 3547, 3547, 3548, 3548, 3548, 3548,    0,    0,
+     3548, 3548, 3549, 3549, 3549,    0,    0,    0, 3549, 3550,
+     3550, 3550, 3550,    0,    0, 3550, 3550, 3551, 3551, 3551,
+        0,    0,    0, 3551, 3552, 3552, 3552, 3552,    0,    0,
+     3552, 3552, 3553, 3553, 3553,    0,    0,    0, 3553, 3554,
+     3554, 3554, 3554,    0,    0, 3554, 3554, 3555, 3555, 3555,
+
+     3555,    0,    0, 3555, 3555, 3556, 3556, 3556,    0,    0,
+        0, 3556, 3557, 3557, 3557, 3557,    0,    0, 3557, 3557,
+     3558, 3558, 3558, 3558, 3558, 3558, 3558, 3558, 3558, 3559,
+     3559, 3559, 3559, 3559, 3559, 3559, 3559, 3559, 3560, 3560,
+     3560,    0,    0,    0, 3560, 3561, 3561, 3561, 3561,    0,
+        0, 3561, 3561, 3562, 3562, 3562, 3562,    0,    0, 3562,
+     3562, 3563, 3563, 3563,    0,    0,    0, 3563, 3564, 3564,
+     3564, 3564,    0,    0, 3564, 3564, 3565, 3565, 3565,    0,
+        0,    0, 3565, 3566, 3566, 3566, 3566,    0,    0, 3566,
+     3566, 3567, 3567, 3567,    0,    0,    0, 3567, 3568, 3568,
+
+     3568, 3568,    0,    0, 3568, 3568, 3569, 3569, 3569,    0,
+        0,    0, 3569, 3570, 3570, 3570,    0,    0,    0, 3570,
+     3571, 3571, 3571, 3571,    0,    0, 3571, 3571, 3572, 3572,
+     3572,    0,    0,    0, 3572, 3573, 3573, 3573, 3573,    0,
+        0, 3573, 3573, 3574, 3574, 3574, 3574,    0,    0, 3574,
+     3574, 3575, 3575, 3575,    0,    0,    0, 3575, 3576, 3576,
+     3576, 3576,    0,    0, 3576, 3576, 3577, 3577, 3577,    0,
+        0,    0, 3577, 3578, 3578, 3578, 3578,    0,    0, 3578,
+     3578, 3579, 3579, 3579, 3579,    0,    0, 3579, 3579, 3580,
+     3580, 3580, 3580,    0,    0, 3580, 3580, 3581, 3581, 3581,
+
+        0,    0,    0, 3581, 3582, 3582, 3582, 3582,    0,    0,
+     3582, 3582, 3583, 3583, 3583, 3583,    0, 3583,    0, 3583,
+     3584, 3584, 3584, 3584,    0,    0, 3584, 3584, 3585, 3585,
+     3585,    0,    0,    0, 3585, 3586, 3586, 3586, 3586,    0,
+        0, 3586, 3586, 3587, 3587, 3587,    0,    0,    0, 3587,
+     3588, 3588, 3588, 3588,    0,    0, 3588, 3588, 3589, 3589,
+     3589,    0,    0,    0, 3589, 3590, 3590, 3590, 3590,    0,
+        0, 3590, 3590, 3591, 3591, 3591,    0,    0,    0, 3591,
+     3592, 3592, 3592, 3592,    0,    0, 3592, 3592, 3593, 3593,
+     3593,    0,    0,    0, 3593, 3594, 3594, 3594, 3594,    0,
+
+        0, 3594, 3594, 3595, 3595, 3595,    0,    0,    0, 3595,
+     3596, 3596, 3596, 3596,    0,    0, 3596, 3596, 3597, 3597,
+     3597,    0,    0,    0, 3597, 3598, 3598, 3598, 3598,    0,
+        0, 3598, 3598, 3599, 3599, 3599, 3599,    0,    0, 3599,
+     3599, 3600, 3600, 3600,    0,    0,    0, 3600, 3601, 3601,
+     3601, 3601,    0,    0, 3601, 3601, 3602, 3602, 3602,    0,
+        0,    0, 3602, 3603, 3603, 3603, 3603,    0,    0, 3603,
+     3603, 3604, 3604, 3604, 3604,    0, 3604,    0, 3604, 3605,
+     3605, 3605, 3605,    0,    0, 3605, 3605, 3606, 3606, 3606,
+     3606,    0,    0, 3606, 3606, 3607, 3607, 3607, 3607,    0,
+
+     3607,    0, 3607, 3608, 3608, 3608, 3608,    0,    0, 3608,
+     3608, 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3609,
+     3610, 3610, 3610, 3610, 3610, 3610, 3610, 3610, 3610, 3611,
+     3611, 3611,    0,    0,    0, 3611, 3612, 3612, 3612, 3612,
+        0,    0, 3612, 3612, 3613, 3613, 3613, 3613,    0,    0,
+     3613, 3613, 3614, 3614, 3614,    0,    0,    0, 3614, 3615,
+     3615, 3615, 3615,    0,    0, 3615, 3615, 3616, 3616, 3616,
+        0,    0,    0, 3616, 3617, 3617, 3617, 3617,    0,    0,
+     3617, 3617, 3618, 3618, 3618,    0,    0,    0, 3618, 3619,
+     3619, 3619, 3619,    0,    0, 3619, 3619, 3620, 3620, 3620,
+
+        0,    0,    0, 3620, 3621, 3621, 3621,    0,    0,    0,
+     3621, 3622, 3622, 3622, 3622,    0,    0, 3622, 3622, 3623,
+     3623, 3623,    0,    0,    0, 3623, 3624, 3624, 3624, 3624,
+        0,    0, 3624, 3624, 3625, 3625, 3625, 3625,    0,    0,
+     3625, 3625, 3626, 3626, 3626, 3626,    0, 3626,    0, 3626,
+     3627, 3627, 3627, 3627,    0,    0, 3627, 3627, 3628, 3628,
+     3628,    0,    0,    0, 3628, 3629, 3629, 3629, 3629,    0,
+        0, 3629, 3629, 3630, 3630, 3630, 3630,    0,    0, 3630,
+     3630, 3631, 3631, 3631,    0,    0,    0, 3631, 3632, 3632,
+     3632, 3632,    0,    0, 3632, 3632, 3633, 3633, 3633, 3633,
+
+        0, 3633,    0, 3633, 3634, 3634, 3634, 3634,    0,    0,
+     3634, 3634, 3635, 3635, 3635,    0,    0,    0, 3635, 3636,
+     3636, 3636, 3636,    0,    0, 3636, 3636, 3637, 3637, 3637,
+        0,    0,    0, 3637, 3638, 3638, 3638, 3638,    0,    0,
+     3638, 3638, 3639, 3639, 3639,    0,    0,    0, 3639, 3640,
+     3640, 3640, 3640,    0,    0, 3640, 3640, 3641, 3641, 3641,
+        0,    0,    0, 3641, 3642, 3642, 3642, 3642,    0,    0,
+     3642, 3642, 3643, 3643, 3643,    0,    0,    0, 3643, 3644,
      3644, 3644, 3644,    0,    0, 3644, 3644, 3645, 3645, 3645,
-        0,    0,    0, 3645, 3646, 3646, 3646, 3646,    0,    0,
-     3646, 3646, 3647, 3647, 3647,    0,    0,    0, 3647, 3648,
-     3648, 3648,    0,    0,    0, 3648, 3649, 3649, 3649, 3649,
-        0,    0, 3649, 3649, 3650, 3650, 3650,    0,    0,    0,
-     3650, 3651, 3651, 3651, 3651,    0,    0, 3651, 3651, 3652,
-     3652, 3652,    0,    0,    0, 3652, 3653, 3653, 3653, 3653,
-        0,    0, 3653, 3653, 3654, 3654, 3654, 3654,    0,    0,
-
-     3654, 3654, 3655, 3655, 3655, 3655,    0,    0, 3655, 3655,
-     3656, 3656, 3656,    0,    0,    0, 3656, 3657, 3657, 3657,
-     3657,    0,    0, 3657, 3657, 3658, 3658, 3658, 3658,    0,
-        0, 3658, 3658, 3659, 3659, 3659, 3659,    0,    0, 3659,
-     3659, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
-     3661, 3661, 3661, 3661, 3661, 3661, 3661, 3661, 3661, 3662,
-     3662, 3662, 3662,    0,    0, 3662, 3662, 3663, 3663, 3663,
-     3663,    0,    0, 3663, 3663, 3664, 3664, 3664,    0,    0,
-        0, 3664, 3665, 3665, 3665,    0,    0,    0, 3665, 3666,
-     3666, 3666, 3666,    0,    0, 3666, 3666, 3667, 3667, 3667,
-
-     3667,    0,    0, 3667, 3667, 3668, 3668, 3668, 3668,    0,
-        0, 3668, 3668, 3669, 3669, 3669, 3669,    0,    0, 3669,
-     3669, 3670, 3670, 3670, 3670,    0,    0, 3670, 3670, 3671,
-     3671, 3671,    0,    0,    0, 3671, 3672, 3672, 3672, 3672,
-        0,    0, 3672, 3672, 3673, 3673, 3673,    0,    0,    0,
-     3673, 3674, 3674, 3674, 3674,    0,    0, 3674, 3674, 3675,
-     3675, 3675, 3675,    0,    0, 3675, 3675, 3676, 3676, 3676,
-        0,    0,    0, 3676, 3677, 3677, 3677,    0,    0,    0,
-     3677, 3678, 3678, 3678, 3678,    0,    0, 3678, 3678, 3679,
-     3679, 3679,    0,    0,    0, 3679, 3680, 3680, 3680, 3680,
-
-        0,    0, 3680, 3680, 3681, 3681, 3681,    0,    0,    0,
-     3681, 3682, 3682, 3682,    0,    0,    0, 3682, 3683, 3683,
-     3683,    0,    0,    0, 3683, 3684, 3684, 3684, 3684,    0,
-        0, 3684, 3684, 3685, 3685, 3685,    0,    0,    0, 3685,
-     3686, 3686, 3686, 3686,    0,    0, 3686, 3686, 3687, 3687,
-     3687, 3687,    0,    0, 3687, 3687, 3688, 3688, 3688, 3688,
-        0,    0, 3688, 3688, 3689, 3689, 3689, 3689,    0, 3689,
-        0, 3689, 3690, 3690, 3690, 3690,    0,    0, 3690, 3690,
-     3691, 3691, 3691, 3691,    0,    0, 3691, 3691, 3692, 3692,
-     3692, 3692,    0,    0, 3692, 3692, 3693, 3693, 3693, 3693,
-
-     3693, 3693, 3693, 3693, 3693, 3694, 3694, 3694, 3694, 3694,
-     3694, 3694, 3694, 3694, 3695, 3695, 3695, 3695,    0,    0,
-     3695, 3695, 3696, 3696, 3696, 3696,    0,    0, 3696, 3696,
-     3697, 3697, 3697,    0,    0,    0, 3697, 3698, 3698, 3698,
-     3698,    0, 3698,    0, 3698, 3699, 3699, 3699, 3699,    0,
-        0, 3699, 3699, 3700, 3700, 3700, 3700,    0,    0, 3700,
-     3700, 3701, 3701, 3701, 3701,    0,    0, 3701, 3701, 3702,
-     3702, 3702, 3702,    0,    0, 3702, 3702, 3703, 3703, 3703,
-        0,    0,    0, 3703, 3704, 3704, 3704, 3704,    0,    0,
-     3704, 3704, 3705, 3705, 3705,    0,    0,    0, 3705, 3706,
-
-     3706, 3706, 3706,    0,    0, 3706, 3706, 3707, 3707, 3707,
-     3707,    0,    0, 3707, 3707, 3708, 3708, 3708,    0,    0,
-        0, 3708, 3709, 3709, 3709,    0,    0,    0, 3709, 3710,
-     3710, 3710, 3710,    0, 3710,    0, 3710, 3711, 3711, 3711,
-     3711,    0,    0, 3711, 3711, 3712, 3712, 3712, 3712,    0,
-     3712,    0, 3712, 3713, 3713, 3713,    0,    0,    0, 3713,
-     3714, 3714, 3714,    0,    0,    0, 3714, 3715, 3715, 3715,
-     3715,    0,    0, 3715, 3715, 3716, 3716, 3716, 3716,    0,
-     3716,    0, 3716, 3717, 3717, 3717, 3717,    0,    0, 3717,
-     3717, 3718, 3718, 3718, 3718,    0,    0, 3718, 3718, 3719,
-
-     3719, 3719, 3719,    0,    0, 3719, 3719, 3720, 3720, 3720,
-     3720,    0, 3720,    0, 3720, 3721, 3721, 3721, 3721,    0,
-        0, 3721, 3721, 3722, 3722, 3722, 3722,    0,    0, 3722,
-     3722, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723, 3723,
-     3724, 3724, 3724, 3724, 3724, 3724, 3724, 3724, 3724, 3725,
-     3725, 3725, 3725,    0,    0, 3725, 3725, 3726, 3726, 3726,
-        0,    0,    0, 3726, 3727, 3727, 3727,    0,    0,    0,
-     3727, 3728, 3728, 3728, 3728,    0,    0, 3728, 3728, 3729,
-     3729, 3729, 3729,    0,    0, 3729, 3729, 3730, 3730, 3730,
-     3730,    0,    0, 3730, 3730, 3731, 3731, 3731,    0,    0,
-
-        0, 3731, 3732, 3732, 3732, 3732,    0,    0, 3732, 3732,
-     3733, 3733, 3733,    0,    0,    0, 3733, 3734, 3734, 3734,
-     3734, 3734, 3734, 3734, 3734, 3734, 3735, 3735, 3735, 3735,
-     3735, 3735, 3735, 3735, 3735, 3736, 3736, 3736, 3736, 3736,
-     3736, 3736, 3736, 3736, 3737, 3737, 3737, 3737, 3737, 3737,
-     3737, 3737, 3737, 3738, 3738, 3738, 3738, 3738, 3738, 3738,
-     3738, 3738, 3739, 3739, 3739, 3739, 3739, 3739, 3739, 3739,
-     3739, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     3259, 3259, 3259, 3259, 3259, 3259
+     3645,    0, 3645,    0, 3645, 3646, 3646, 3646, 3646,    0,
+
+        0, 3646, 3646, 3647, 3647, 3647,    0,    0,    0, 3647,
+     3648, 3648, 3648, 3648,    0,    0, 3648, 3648, 3649, 3649,
+     3649, 3649,    0,    0, 3649, 3649, 3650, 3650, 3650, 3650,
+        0, 3650,    0, 3650, 3651, 3651, 3651, 3651,    0,    0,
+     3651, 3651, 3652, 3652, 3652,    0,    0,    0, 3652, 3653,
+     3653, 3653, 3653,    0,    0, 3653, 3653, 3654, 3654, 3654,
+     3654,    0,    0, 3654, 3654, 3655, 3655, 3655, 3655,    0,
+        0, 3655, 3655, 3656, 3656, 3656, 3656,    0,    0, 3656,
+     3656, 3657, 3657, 3657, 3657, 3657, 3657, 3657, 3657, 3657,
+     3658, 3658, 3658, 3658, 3658, 3658, 3658, 3658, 3658, 3659,
+
+     3659, 3659, 3659,    0, 3659,    0, 3659, 3660, 3660, 3660,
+     3660,    0,    0, 3660, 3660, 3661, 3661, 3661, 3661,    0,
+        0, 3661, 3661, 3662, 3662, 3662,    0,    0,    0, 3662,
+     3663, 3663, 3663, 3663,    0,    0, 3663, 3663, 3664, 3664,
+     3664,    0,    0,    0, 3664, 3665, 3665, 3665, 3665,    0,
+        0, 3665, 3665, 3666, 3666, 3666, 3666,    0, 3666,    0,
+     3666, 3667, 3667, 3667, 3667,    0,    0, 3667, 3667, 3668,
+     3668, 3668, 3668,    0, 3668,    0, 3668, 3669, 3669, 3669,
+     3669,    0, 3669,    0, 3669, 3670, 3670, 3670, 3670,    0,
+        0, 3670, 3670, 3671, 3671, 3671, 3671,    0, 3671,    0,
+
+     3671, 3672, 3672, 3672, 3672,    0,    0, 3672, 3672, 3673,
+     3673, 3673, 3673,    0,    0, 3673, 3673, 3674, 3674, 3674,
+     3674,    0,    0, 3674, 3674, 3675, 3675, 3675,    0,    0,
+        0, 3675, 3676, 3676, 3676, 3676,    0,    0, 3676, 3676,
+     3677, 3677, 3677,    0,    0,    0, 3677, 3678, 3678, 3678,
+     3678,    0,    0, 3678, 3678, 3679, 3679, 3679, 3679,    0,
+     3679,    0, 3679, 3680, 3680, 3680, 3680,    0,    0, 3680,
+     3680, 3681, 3681, 3681,    0,    0,    0, 3681, 3682, 3682,
+     3682,    0,    0,    0, 3682, 3683, 3683, 3683, 3683,    0,
+        0, 3683, 3683, 3684, 3684, 3684,    0,    0,    0, 3684,
+
+     3685, 3685, 3685, 3685,    0,    0, 3685, 3685, 3686, 3686,
+     3686,    0,    0,    0, 3686, 3687, 3687, 3687,    0,    0,
+        0, 3687, 3688, 3688, 3688, 3688,    0,    0, 3688, 3688,
+     3689, 3689, 3689,    0,    0,    0, 3689, 3690, 3690, 3690,
+     3690,    0,    0, 3690, 3690, 3691, 3691, 3691,    0,    0,
+        0, 3691, 3692, 3692, 3692, 3692,    0,    0, 3692, 3692,
+     3693, 3693, 3693, 3693,    0,    0, 3693, 3693, 3694, 3694,
+     3694, 3694,    0,    0, 3694, 3694, 3695, 3695, 3695,    0,
+        0,    0, 3695, 3696, 3696, 3696, 3696,    0,    0, 3696,
+     3696, 3697, 3697, 3697, 3697,    0,    0, 3697, 3697, 3698,
+
+     3698, 3698, 3698,    0,    0, 3698, 3698, 3699, 3699, 3699,
+     3699, 3699, 3699, 3699, 3699, 3699, 3700, 3700, 3700, 3700,
+     3700, 3700, 3700, 3700, 3700, 3701, 3701, 3701, 3701,    0,
+        0, 3701, 3701, 3702, 3702, 3702, 3702,    0,    0, 3702,
+     3702, 3703, 3703, 3703,    0,    0,    0, 3703, 3704, 3704,
+     3704,    0,    0,    0, 3704, 3705, 3705, 3705, 3705,    0,
+        0, 3705, 3705, 3706, 3706, 3706, 3706,    0,    0, 3706,
+     3706, 3707, 3707, 3707, 3707,    0,    0, 3707, 3707, 3708,
+     3708, 3708, 3708,    0,    0, 3708, 3708, 3709, 3709, 3709,
+     3709,    0,    0, 3709, 3709, 3710, 3710, 3710,    0,    0,
+
+        0, 3710, 3711, 3711, 3711, 3711,    0,    0, 3711, 3711,
+     3712, 3712, 3712,    0,    0,    0, 3712, 3713, 3713, 3713,
+     3713,    0,    0, 3713, 3713, 3714, 3714, 3714, 3714,    0,
+        0, 3714, 3714, 3715, 3715, 3715,    0,    0,    0, 3715,
+     3716, 3716, 3716,    0,    0,    0, 3716, 3717, 3717, 3717,
+     3717,    0,    0, 3717, 3717, 3718, 3718, 3718,    0,    0,
+        0, 3718, 3719, 3719, 3719, 3719,    0,    0, 3719, 3719,
+     3720, 3720, 3720,    0,    0,    0, 3720, 3721, 3721, 3721,
+        0,    0,    0, 3721, 3722, 3722, 3722,    0,    0,    0,
+     3722, 3723, 3723, 3723, 3723,    0,    0, 3723, 3723, 3724,
+
+     3724, 3724,    0,    0,    0, 3724, 3725, 3725, 3725, 3725,
+        0,    0, 3725, 3725, 3726, 3726, 3726, 3726,    0,    0,
+     3726, 3726, 3727, 3727, 3727, 3727,    0,    0, 3727, 3727,
+     3728, 3728, 3728, 3728,    0, 3728,    0, 3728, 3729, 3729,
+     3729, 3729,    0,    0, 3729, 3729, 3730, 3730, 3730, 3730,
+        0,    0, 3730, 3730, 3731, 3731, 3731, 3731,    0,    0,
+     3731, 3731, 3732, 3732, 3732, 3732, 3732, 3732, 3732, 3732,
+     3732, 3733, 3733, 3733, 3733, 3733, 3733, 3733, 3733, 3733,
+     3734, 3734, 3734, 3734,    0,    0, 3734, 3734, 3735, 3735,
+     3735, 3735,    0,    0, 3735, 3735, 3736, 3736, 3736,    0,
+
+        0,    0, 3736, 3737, 3737, 3737, 3737,    0, 3737,    0,
+     3737, 3738, 3738, 3738, 3738,    0,    0, 3738, 3738, 3739,
+     3739, 3739, 3739,    0,    0, 3739, 3739, 3740, 3740, 3740,
+     3740,    0,    0, 3740, 3740, 3741, 3741, 3741, 3741,    0,
+        0, 3741, 3741, 3742, 3742, 3742,    0,    0,    0, 3742,
+     3743, 3743, 3743, 3743,    0,    0, 3743, 3743, 3744, 3744,
+     3744,    0,    0,    0, 3744, 3745, 3745, 3745, 3745,    0,
+        0, 3745, 3745, 3746, 3746, 3746, 3746,    0,    0, 3746,
+     3746, 3747, 3747, 3747,    0,    0,    0, 3747, 3748, 3748,
+     3748,    0,    0,    0, 3748, 3749, 3749, 3749, 3749,    0,
+
+     3749,    0, 3749, 3750, 3750, 3750, 3750,    0,    0, 3750,
+     3750, 3751, 3751, 3751, 3751,    0, 3751,    0, 3751, 3752,
+     3752, 3752,    0,    0,    0, 3752, 3753, 3753, 3753,    0,
+        0,    0, 3753, 3754, 3754, 3754, 3754,    0,    0, 3754,
+     3754, 3755, 3755, 3755, 3755,    0, 3755,    0, 3755, 3756,
+     3756, 3756, 3756,    0,    0, 3756, 3756, 3757, 3757, 3757,
+     3757,    0,    0, 3757, 3757, 3758, 3758, 3758, 3758,    0,
+        0, 3758, 3758, 3759, 3759, 3759, 3759,    0, 3759,    0,
+     3759, 3760, 3760, 3760, 3760,    0,    0, 3760, 3760, 3761,
+     3761, 3761, 3761,    0,    0, 3761, 3761, 3762, 3762, 3762,
+
+     3762, 3762, 3762, 3762, 3762, 3762, 3763, 3763, 3763, 3763,
+     3763, 3763, 3763, 3763, 3763, 3764, 3764, 3764, 3764,    0,
+        0, 3764, 3764, 3765, 3765, 3765,    0,    0,    0, 3765,
+     3766, 3766, 3766,    0,    0,    0, 3766, 3767, 3767, 3767,
+     3767,    0,    0, 3767, 3767, 3768, 3768, 3768, 3768,    0,
+        0, 3768, 3768, 3769, 3769, 3769, 3769,    0,    0, 3769,
+     3769, 3770, 3770, 3770,    0,    0,    0, 3770, 3771, 3771,
+     3771, 3771,    0,    0, 3771, 3771, 3772, 3772, 3772,    0,
+        0,    0, 3772, 3773, 3773, 3773, 3773, 3773, 3773, 3773,
+     3773, 3773, 3774, 3774, 3774, 3774, 3774, 3774, 3774, 3774,
+
+     3774, 3775, 3775, 3775, 3775, 3775, 3775, 3775, 3775, 3775,
+     3776, 3776, 3776, 3776, 3776, 3776, 3776, 3776, 3776, 3777,
+     3777, 3777, 3777, 3777, 3777, 3777, 3777, 3777, 3778, 3778,
+     3778, 3778, 3778, 3778, 3778, 3778, 3778, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+
+     3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298, 3298,
+     3298, 3298
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[559] =
+static yyconst flex_int32_t yy_rule_can_match_eol[565] =
     {   0,
 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 
     0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 
@@ -4323,20 +4352,21 @@ static yyconst flex_int32_t yy_rule_can_match_eol[559] =
     1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
     0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 
+    1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
+    1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 
-    1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 
-    0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
-    1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
-    0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
-    1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 
-    0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,     };
+    1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+    1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 
+    1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 
+    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 
+    0, 0, 0, 1, 0,     };
 
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
@@ -4554,6 +4584,9 @@ short int surfxml_argument_value_isset;
 AT_surfxml_link_state AX_surfxml_link_state;
 #define A_surfxml_link_state AX_surfxml_link_state
 short int surfxml_link_state_isset;
+AT_surfxml_cluster_loopback___bw AX_surfxml_cluster_loopback___bw;
+#define A_surfxml_cluster_loopback___bw (surfxml_bufferstack + AX_surfxml_cluster_loopback___bw)
+short int surfxml_cluster_loopback___bw_isset;
 AT_surfxml_ASroute_gw___src AX_surfxml_ASroute_gw___src;
 #define A_surfxml_ASroute_gw___src (surfxml_bufferstack + AX_surfxml_ASroute_gw___src)
 short int surfxml_ASroute_gw___src_isset;
@@ -4686,6 +4719,9 @@ short int surfxml_peer_id_isset;
 AT_surfxml_cluster_router___id AX_surfxml_cluster_router___id;
 #define A_surfxml_cluster_router___id (surfxml_bufferstack + AX_surfxml_cluster_router___id)
 short int surfxml_cluster_router___id_isset;
+AT_surfxml_cluster_loopback___lat AX_surfxml_cluster_loopback___lat;
+#define A_surfxml_cluster_loopback___lat (surfxml_bufferstack + AX_surfxml_cluster_loopback___lat)
+short int surfxml_cluster_loopback___lat_isset;
 AT_surfxml_cabinet_radical AX_surfxml_cabinet_radical;
 #define A_surfxml_cabinet_radical (surfxml_bufferstack + AX_surfxml_cabinet_radical)
 short int surfxml_cabinet_radical_isset;
@@ -4749,6 +4785,9 @@ short int surfxml_random_std___deviation_isset;
 AT_surfxml_cluster_core AX_surfxml_cluster_core;
 #define A_surfxml_cluster_core (surfxml_bufferstack + AX_surfxml_cluster_core)
 short int surfxml_cluster_core_isset;
+AT_surfxml_cluster_limiter___link AX_surfxml_cluster_limiter___link;
+#define A_surfxml_cluster_limiter___link (surfxml_bufferstack + AX_surfxml_cluster_limiter___link)
+short int surfxml_cluster_limiter___link_isset;
 AT_surfxml_host_state___file AX_surfxml_host_state___file;
 #define A_surfxml_host_state___file (surfxml_bufferstack + AX_surfxml_host_state___file)
 short int surfxml_host_state___file_isset;
@@ -5441,13 +5480,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 3260 )
+                               if ( yy_current_state >= 3299 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 11972 );
+               while ( yy_base[yy_current_state] != 12038 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -7141,6 +7180,12 @@ YY_RULE_SETUP
   surfxml_cluster_state___file_isset = 0;
   AX_surfxml_cluster_router___id = 0;
   surfxml_cluster_router___id_isset = 0;
+  AX_surfxml_cluster_limiter___link = 0;
+  surfxml_cluster_limiter___link_isset = 0;
+  AX_surfxml_cluster_loopback___bw = 0;
+  surfxml_cluster_loopback___bw_isset = 0;
+  AX_surfxml_cluster_loopback___lat = 0;
+  surfxml_cluster_loopback___lat_isset = 0;
   ENTER(AL_surfxml_cluster); pushbuffer(0);
   }
        YY_BREAK
@@ -7311,6 +7356,36 @@ YY_RULE_SETUP
 if (surfxml_cluster_router___id_isset != 0) {FAIL("Multiple definition of attribute router_id in <surfxml_cluster>");}  surfxml_cluster_router___id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_router___id);
        YY_BREAK
 case 282:
+/* rule 282 can match eol */
+YY_RULE_SETUP
+if (surfxml_cluster_limiter___link_isset != 0) {FAIL("Multiple definition of attribute limiter_link in <surfxml_cluster>");} surfxml_cluster_limiter___link_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_limiter___link);
+       YY_BREAK
+case 283:
+/* rule 283 can match eol */
+YY_RULE_SETUP
+if (surfxml_cluster_limiter___link_isset != 0) {FAIL("Multiple definition of attribute limiter_link in <surfxml_cluster>");}  surfxml_cluster_limiter___link_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_limiter___link);
+       YY_BREAK
+case 284:
+/* rule 284 can match eol */
+YY_RULE_SETUP
+if (surfxml_cluster_loopback___bw_isset != 0) {FAIL("Multiple definition of attribute loopback_bw in <surfxml_cluster>");} surfxml_cluster_loopback___bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_loopback___bw);
+       YY_BREAK
+case 285:
+/* rule 285 can match eol */
+YY_RULE_SETUP
+if (surfxml_cluster_loopback___bw_isset != 0) {FAIL("Multiple definition of attribute loopback_bw in <surfxml_cluster>");}  surfxml_cluster_loopback___bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_loopback___bw);
+       YY_BREAK
+case 286:
+/* rule 286 can match eol */
+YY_RULE_SETUP
+if (surfxml_cluster_loopback___lat_isset != 0) {FAIL("Multiple definition of attribute loopback_lat in <surfxml_cluster>");} surfxml_cluster_loopback___lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cluster_loopback___lat);
+       YY_BREAK
+case 287:
+/* rule 287 can match eol */
+YY_RULE_SETUP
+if (surfxml_cluster_loopback___lat_isset != 0) {FAIL("Multiple definition of attribute loopback_lat in <surfxml_cluster>");}  surfxml_cluster_loopback___lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cluster_loopback___lat);
+       YY_BREAK
+case 288:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_cluster_id) FAIL("Required attribute `id' not set for `cluster' element.");
@@ -7323,7 +7398,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_cluster();surfxml_pcdata_ix = 0; ENTER(E_surfxml_cluster);
  }
        YY_BREAK
-case 283:
+case 289:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_cluster_id) FAIL("Required attribute `id' not set for `cluster' element.");
@@ -7341,11 +7416,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 284:
+case 290:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of cluster element.", surf_parse_text[0]);
        YY_BREAK
-case 285:
+case 291:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `cluster' element start tag.",surf_parse_text);
        YY_BREAK
@@ -7353,8 +7428,8 @@ case YY_STATE_EOF(AL_surfxml_cluster):
 FAIL("EOF in attribute list of `cluster' element.");
        YY_BREAK
 
-case 286:
-/* rule 286 can match eol */
+case 292:
+/* rule 292 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -7367,12 +7442,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 287:
-/* rule 287 can match eol */
+case 293:
+/* rule 293 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</cluster>' expected.",surf_parse_text);
        YY_BREAK
-case 288:
+case 294:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</cluster>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -7380,13 +7455,13 @@ case YY_STATE_EOF(E_surfxml_cluster):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</cluster>' expected.");
        YY_BREAK
 
-case 289:
-/* rule 289 can match eol */
+case 295:
+/* rule 295 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <cabinet> is not allowed here.");
        YY_BREAK
-case 290:
-/* rule 290 can match eol */
+case 296:
+/* rule 296 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_cabinet_id = 0;
@@ -7407,77 +7482,77 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 291:
-/* rule 291 can match eol */
+case 297:
+/* rule 297 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_cabinet>");} surfxml_cabinet_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_id);
        YY_BREAK
-case 292:
-/* rule 292 can match eol */
+case 298:
+/* rule 298 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_cabinet>");}  surfxml_cabinet_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_id);
        YY_BREAK
-case 293:
-/* rule 293 can match eol */
+case 299:
+/* rule 299 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in <surfxml_cabinet>");} surfxml_cabinet_prefix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_prefix);
        YY_BREAK
-case 294:
-/* rule 294 can match eol */
+case 300:
+/* rule 300 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_prefix_isset != 0) {FAIL("Multiple definition of attribute prefix in <surfxml_cabinet>");}  surfxml_cabinet_prefix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_prefix);
        YY_BREAK
-case 295:
-/* rule 295 can match eol */
+case 301:
+/* rule 301 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in <surfxml_cabinet>");} surfxml_cabinet_suffix_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_suffix);
        YY_BREAK
-case 296:
-/* rule 296 can match eol */
+case 302:
+/* rule 302 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_suffix_isset != 0) {FAIL("Multiple definition of attribute suffix in <surfxml_cabinet>");}  surfxml_cabinet_suffix_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_suffix);
        YY_BREAK
-case 297:
-/* rule 297 can match eol */
+case 303:
+/* rule 303 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_radical_isset != 0) {FAIL("Multiple definition of attribute radical in <surfxml_cabinet>");} surfxml_cabinet_radical_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_radical);
        YY_BREAK
-case 298:
-/* rule 298 can match eol */
+case 304:
+/* rule 304 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_radical_isset != 0) {FAIL("Multiple definition of attribute radical in <surfxml_cabinet>");}  surfxml_cabinet_radical_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_radical);
        YY_BREAK
-case 299:
-/* rule 299 can match eol */
+case 305:
+/* rule 305 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_power_isset != 0) {FAIL("Multiple definition of attribute power in <surfxml_cabinet>");} surfxml_cabinet_power_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_power);
        YY_BREAK
-case 300:
-/* rule 300 can match eol */
+case 306:
+/* rule 306 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_power_isset != 0) {FAIL("Multiple definition of attribute power in <surfxml_cabinet>");}  surfxml_cabinet_power_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_power);
        YY_BREAK
-case 301:
-/* rule 301 can match eol */
+case 307:
+/* rule 307 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_bw_isset != 0) {FAIL("Multiple definition of attribute bw in <surfxml_cabinet>");} surfxml_cabinet_bw_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_bw);
        YY_BREAK
-case 302:
-/* rule 302 can match eol */
+case 308:
+/* rule 308 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_bw_isset != 0) {FAIL("Multiple definition of attribute bw in <surfxml_cabinet>");}  surfxml_cabinet_bw_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_bw);
        YY_BREAK
-case 303:
-/* rule 303 can match eol */
+case 309:
+/* rule 309 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_lat_isset != 0) {FAIL("Multiple definition of attribute lat in <surfxml_cabinet>");} surfxml_cabinet_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_cabinet_lat);
        YY_BREAK
-case 304:
-/* rule 304 can match eol */
+case 310:
+/* rule 310 can match eol */
 YY_RULE_SETUP
 if (surfxml_cabinet_lat_isset != 0) {FAIL("Multiple definition of attribute lat in <surfxml_cabinet>");}  surfxml_cabinet_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_cabinet_lat);
        YY_BREAK
-case 305:
+case 311:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_cabinet_id) FAIL("Required attribute `id' not set for `cabinet' element.");
@@ -7490,7 +7565,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_cabinet();surfxml_pcdata_ix = 0; ENTER(E_surfxml_cabinet);
  }
        YY_BREAK
-case 306:
+case 312:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_cabinet_id) FAIL("Required attribute `id' not set for `cabinet' element.");
@@ -7509,11 +7584,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 307:
+case 313:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of cabinet element.", surf_parse_text[0]);
        YY_BREAK
-case 308:
+case 314:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `cabinet' element start tag.",surf_parse_text);
        YY_BREAK
@@ -7521,8 +7596,8 @@ case YY_STATE_EOF(AL_surfxml_cabinet):
 FAIL("EOF in attribute list of `cabinet' element.");
        YY_BREAK
 
-case 309:
-/* rule 309 can match eol */
+case 315:
+/* rule 315 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -7536,12 +7611,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 310:
-/* rule 310 can match eol */
+case 316:
+/* rule 316 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</cabinet>' expected.",surf_parse_text);
        YY_BREAK
-case 311:
+case 317:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</cabinet>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -7549,13 +7624,13 @@ case YY_STATE_EOF(E_surfxml_cabinet):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</cabinet>' expected.");
        YY_BREAK
 
-case 312:
-/* rule 312 can match eol */
+case 318:
+/* rule 318 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <peer> is not allowed here.");
        YY_BREAK
-case 313:
-/* rule 313 can match eol */
+case 319:
+/* rule 319 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_peer_id = 0;
@@ -7578,87 +7653,87 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 314:
-/* rule 314 can match eol */
+case 320:
+/* rule 320 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_peer>");} surfxml_peer_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_id);
        YY_BREAK
-case 315:
-/* rule 315 can match eol */
+case 321:
+/* rule 321 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_peer>");}  surfxml_peer_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_id);
        YY_BREAK
-case 316:
-/* rule 316 can match eol */
+case 322:
+/* rule 322 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_power_isset != 0) {FAIL("Multiple definition of attribute power in <surfxml_peer>");} surfxml_peer_power_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_power);
        YY_BREAK
-case 317:
-/* rule 317 can match eol */
+case 323:
+/* rule 323 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_power_isset != 0) {FAIL("Multiple definition of attribute power in <surfxml_peer>");}  surfxml_peer_power_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_power);
        YY_BREAK
-case 318:
-/* rule 318 can match eol */
+case 324:
+/* rule 324 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_bw___in_isset != 0) {FAIL("Multiple definition of attribute bw_in in <surfxml_peer>");} surfxml_peer_bw___in_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_bw___in);
        YY_BREAK
-case 319:
-/* rule 319 can match eol */
+case 325:
+/* rule 325 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_bw___in_isset != 0) {FAIL("Multiple definition of attribute bw_in in <surfxml_peer>");}  surfxml_peer_bw___in_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_bw___in);
        YY_BREAK
-case 320:
-/* rule 320 can match eol */
+case 326:
+/* rule 326 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_bw___out_isset != 0) {FAIL("Multiple definition of attribute bw_out in <surfxml_peer>");} surfxml_peer_bw___out_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_bw___out);
        YY_BREAK
-case 321:
-/* rule 321 can match eol */
+case 327:
+/* rule 327 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_bw___out_isset != 0) {FAIL("Multiple definition of attribute bw_out in <surfxml_peer>");}  surfxml_peer_bw___out_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_bw___out);
        YY_BREAK
-case 322:
-/* rule 322 can match eol */
+case 328:
+/* rule 328 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_lat_isset != 0) {FAIL("Multiple definition of attribute lat in <surfxml_peer>");} surfxml_peer_lat_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_lat);
        YY_BREAK
-case 323:
-/* rule 323 can match eol */
+case 329:
+/* rule 329 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_lat_isset != 0) {FAIL("Multiple definition of attribute lat in <surfxml_peer>");}  surfxml_peer_lat_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_lat);
        YY_BREAK
-case 324:
-/* rule 324 can match eol */
+case 330:
+/* rule 330 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in <surfxml_peer>");} surfxml_peer_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_coordinates);
        YY_BREAK
-case 325:
-/* rule 325 can match eol */
+case 331:
+/* rule 331 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in <surfxml_peer>");}  surfxml_peer_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_coordinates);
        YY_BREAK
-case 326:
-/* rule 326 can match eol */
+case 332:
+/* rule 332 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in <surfxml_peer>");} surfxml_peer_availability___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_availability___file);
        YY_BREAK
-case 327:
-/* rule 327 can match eol */
+case 333:
+/* rule 333 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_availability___file_isset != 0) {FAIL("Multiple definition of attribute availability_file in <surfxml_peer>");}  surfxml_peer_availability___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_availability___file);
        YY_BREAK
-case 328:
-/* rule 328 can match eol */
+case 334:
+/* rule 334 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in <surfxml_peer>");} surfxml_peer_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_peer_state___file);
        YY_BREAK
-case 329:
-/* rule 329 can match eol */
+case 335:
+/* rule 335 can match eol */
 YY_RULE_SETUP
 if (surfxml_peer_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in <surfxml_peer>");}  surfxml_peer_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_peer_state___file);
        YY_BREAK
-case 330:
+case 336:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_peer_id) FAIL("Required attribute `id' not set for `peer' element.");
@@ -7669,7 +7744,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_peer();surfxml_pcdata_ix = 0; ENTER(E_surfxml_peer);
  }
        YY_BREAK
-case 331:
+case 337:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_peer_id) FAIL("Required attribute `id' not set for `peer' element.");
@@ -7685,11 +7760,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 332:
+case 338:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of peer element.", surf_parse_text[0]);
        YY_BREAK
-case 333:
+case 339:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `peer' element start tag.",surf_parse_text);
        YY_BREAK
@@ -7697,8 +7772,8 @@ case YY_STATE_EOF(AL_surfxml_peer):
 FAIL("EOF in attribute list of `peer' element.");
        YY_BREAK
 
-case 334:
-/* rule 334 can match eol */
+case 340:
+/* rule 340 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -7711,12 +7786,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 335:
-/* rule 335 can match eol */
+case 341:
+/* rule 341 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</peer>' expected.",surf_parse_text);
        YY_BREAK
-case 336:
+case 342:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</peer>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -7724,13 +7799,13 @@ case YY_STATE_EOF(E_surfxml_peer):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</peer>' expected.");
        YY_BREAK
 
-case 337:
-/* rule 337 can match eol */
+case 343:
+/* rule 343 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <router> is not allowed here.");
        YY_BREAK
-case 338:
-/* rule 338 can match eol */
+case 344:
+/* rule 344 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_router_id = 0;
@@ -7741,34 +7816,34 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 339:
-/* rule 339 can match eol */
+case 345:
+/* rule 345 can match eol */
 YY_RULE_SETUP
 if (surfxml_router_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_router>");} surfxml_router_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_router_id);
        YY_BREAK
-case 340:
-/* rule 340 can match eol */
+case 346:
+/* rule 346 can match eol */
 YY_RULE_SETUP
 if (surfxml_router_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_router>");}  surfxml_router_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_router_id);
        YY_BREAK
-case 341:
-/* rule 341 can match eol */
+case 347:
+/* rule 347 can match eol */
 YY_RULE_SETUP
 if (surfxml_router_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in <surfxml_router>");} surfxml_router_coordinates_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_router_coordinates);
        YY_BREAK
-case 342:
-/* rule 342 can match eol */
+case 348:
+/* rule 348 can match eol */
 YY_RULE_SETUP
 if (surfxml_router_coordinates_isset != 0) {FAIL("Multiple definition of attribute coordinates in <surfxml_router>");}  surfxml_router_coordinates_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_router_coordinates);
        YY_BREAK
-case 343:
+case 349:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_router_id) FAIL("Required attribute `id' not set for `router' element.");
   LEAVE; STag_surfxml_router();surfxml_pcdata_ix = 0; ENTER(E_surfxml_router);
  }
        YY_BREAK
-case 344:
+case 350:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_router_id) FAIL("Required attribute `id' not set for `router' element.");
@@ -7778,11 +7853,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 345:
+case 351:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of router element.", surf_parse_text[0]);
        YY_BREAK
-case 346:
+case 352:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `router' element start tag.",surf_parse_text);
        YY_BREAK
@@ -7790,8 +7865,8 @@ case YY_STATE_EOF(AL_surfxml_router):
 FAIL("EOF in attribute list of `router' element.");
        YY_BREAK
 
-case 347:
-/* rule 347 can match eol */
+case 353:
+/* rule 353 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -7802,12 +7877,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 348:
-/* rule 348 can match eol */
+case 354:
+/* rule 354 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</router>' expected.",surf_parse_text);
        YY_BREAK
-case 349:
+case 355:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</router>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -7815,13 +7890,13 @@ case YY_STATE_EOF(E_surfxml_router):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</router>' expected.");
        YY_BREAK
 
-case 350:
-/* rule 350 can match eol */
+case 356:
+/* rule 356 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <backbone> is not allowed here.");
        YY_BREAK
-case 351:
-/* rule 351 can match eol */
+case 357:
+/* rule 357 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_backbone_id = 0;
@@ -7834,37 +7909,37 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 352:
-/* rule 352 can match eol */
+case 358:
+/* rule 358 can match eol */
 YY_RULE_SETUP
 if (surfxml_backbone_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_backbone>");} surfxml_backbone_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_backbone_id);
        YY_BREAK
-case 353:
-/* rule 353 can match eol */
+case 359:
+/* rule 359 can match eol */
 YY_RULE_SETUP
 if (surfxml_backbone_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_backbone>");}  surfxml_backbone_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_backbone_id);
        YY_BREAK
-case 354:
-/* rule 354 can match eol */
+case 360:
+/* rule 360 can match eol */
 YY_RULE_SETUP
 if (surfxml_backbone_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in <surfxml_backbone>");} surfxml_backbone_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_backbone_bandwidth);
        YY_BREAK
-case 355:
-/* rule 355 can match eol */
+case 361:
+/* rule 361 can match eol */
 YY_RULE_SETUP
 if (surfxml_backbone_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in <surfxml_backbone>");}  surfxml_backbone_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_backbone_bandwidth);
        YY_BREAK
-case 356:
-/* rule 356 can match eol */
+case 362:
+/* rule 362 can match eol */
 YY_RULE_SETUP
 if (surfxml_backbone_latency_isset != 0) {FAIL("Multiple definition of attribute latency in <surfxml_backbone>");} surfxml_backbone_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_backbone_latency);
        YY_BREAK
-case 357:
-/* rule 357 can match eol */
+case 363:
+/* rule 363 can match eol */
 YY_RULE_SETUP
 if (surfxml_backbone_latency_isset != 0) {FAIL("Multiple definition of attribute latency in <surfxml_backbone>");}  surfxml_backbone_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_backbone_latency);
        YY_BREAK
-case 358:
+case 364:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_backbone_id) FAIL("Required attribute `id' not set for `backbone' element.");
@@ -7873,7 +7948,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_backbone();surfxml_pcdata_ix = 0; ENTER(E_surfxml_backbone);
  }
        YY_BREAK
-case 359:
+case 365:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_backbone_id) FAIL("Required attribute `id' not set for `backbone' element.");
@@ -7886,11 +7961,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 360:
+case 366:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of backbone element.", surf_parse_text[0]);
        YY_BREAK
-case 361:
+case 367:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `backbone' element start tag.",surf_parse_text);
        YY_BREAK
@@ -7898,8 +7973,8 @@ case YY_STATE_EOF(AL_surfxml_backbone):
 FAIL("EOF in attribute list of `backbone' element.");
        YY_BREAK
 
-case 362:
-/* rule 362 can match eol */
+case 368:
+/* rule 368 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -7911,12 +7986,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 363:
-/* rule 363 can match eol */
+case 369:
+/* rule 369 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</backbone>' expected.",surf_parse_text);
        YY_BREAK
-case 364:
+case 370:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</backbone>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -7924,13 +7999,13 @@ case YY_STATE_EOF(E_surfxml_backbone):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</backbone>' expected.");
        YY_BREAK
 
-case 365:
-/* rule 365 can match eol */
+case 371:
+/* rule 371 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <link> is not allowed here.");
        YY_BREAK
-case 366:
-/* rule 366 can match eol */
+case 372:
+/* rule 372 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_link_id = 0;
@@ -7953,102 +8028,102 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 367:
-/* rule 367 can match eol */
-YY_RULE_SETUP
-if (surfxml_link_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_link>");} surfxml_link_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_id);
-       YY_BREAK
-case 368:
-/* rule 368 can match eol */
-YY_RULE_SETUP
-if (surfxml_link_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_link>");}  surfxml_link_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_id);
-       YY_BREAK
-case 369:
-/* rule 369 can match eol */
-YY_RULE_SETUP
-if (surfxml_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in <surfxml_link>");} surfxml_link_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_bandwidth);
-       YY_BREAK
-case 370:
-/* rule 370 can match eol */
-YY_RULE_SETUP
-if (surfxml_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in <surfxml_link>");}  surfxml_link_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_bandwidth);
-       YY_BREAK
-case 371:
-/* rule 371 can match eol */
-YY_RULE_SETUP
-if (surfxml_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in <surfxml_link>");} surfxml_link_bandwidth___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_bandwidth___file);
-       YY_BREAK
-case 372:
-/* rule 372 can match eol */
-YY_RULE_SETUP
-if (surfxml_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in <surfxml_link>");}  surfxml_link_bandwidth___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_bandwidth___file);
-       YY_BREAK
 case 373:
 /* rule 373 can match eol */
 YY_RULE_SETUP
-if (surfxml_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in <surfxml_link>");} surfxml_link_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_latency);
+if (surfxml_link_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_link>");} surfxml_link_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_id);
        YY_BREAK
 case 374:
 /* rule 374 can match eol */
 YY_RULE_SETUP
-if (surfxml_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in <surfxml_link>");}  surfxml_link_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_latency);
+if (surfxml_link_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_link>");}  surfxml_link_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_id);
        YY_BREAK
 case 375:
 /* rule 375 can match eol */
 YY_RULE_SETUP
-if (surfxml_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in <surfxml_link>");} surfxml_link_latency___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_latency___file);
+if (surfxml_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in <surfxml_link>");} surfxml_link_bandwidth_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_bandwidth);
        YY_BREAK
 case 376:
 /* rule 376 can match eol */
 YY_RULE_SETUP
-if (surfxml_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in <surfxml_link>");}  surfxml_link_latency___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_latency___file);
+if (surfxml_link_bandwidth_isset != 0) {FAIL("Multiple definition of attribute bandwidth in <surfxml_link>");}  surfxml_link_bandwidth_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_bandwidth);
        YY_BREAK
 case 377:
 /* rule 377 can match eol */
+YY_RULE_SETUP
+if (surfxml_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in <surfxml_link>");} surfxml_link_bandwidth___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_bandwidth___file);
+       YY_BREAK
 case 378:
 /* rule 378 can match eol */
 YY_RULE_SETUP
-A_surfxml_link_state = A_surfxml_link_state_ON;
+if (surfxml_link_bandwidth___file_isset != 0) {FAIL("Multiple definition of attribute bandwidth_file in <surfxml_link>");}  surfxml_link_bandwidth___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_bandwidth___file);
        YY_BREAK
 case 379:
 /* rule 379 can match eol */
+YY_RULE_SETUP
+if (surfxml_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in <surfxml_link>");} surfxml_link_latency_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_latency);
+       YY_BREAK
 case 380:
 /* rule 380 can match eol */
 YY_RULE_SETUP
-A_surfxml_link_state = A_surfxml_link_state_OFF;
+if (surfxml_link_latency_isset != 0) {FAIL("Multiple definition of attribute latency in <surfxml_link>");}  surfxml_link_latency_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_latency);
        YY_BREAK
 case 381:
 /* rule 381 can match eol */
 YY_RULE_SETUP
-if (surfxml_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in <surfxml_link>");} surfxml_link_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_state___file);
+if (surfxml_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in <surfxml_link>");} surfxml_link_latency___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_latency___file);
        YY_BREAK
 case 382:
 /* rule 382 can match eol */
 YY_RULE_SETUP
-if (surfxml_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in <surfxml_link>");}  surfxml_link_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_state___file);
+if (surfxml_link_latency___file_isset != 0) {FAIL("Multiple definition of attribute latency_file in <surfxml_link>");}  surfxml_link_latency___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_latency___file);
        YY_BREAK
 case 383:
 /* rule 383 can match eol */
 case 384:
 /* rule 384 can match eol */
 YY_RULE_SETUP
-A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_SHARED;
+A_surfxml_link_state = A_surfxml_link_state_ON;
        YY_BREAK
 case 385:
 /* rule 385 can match eol */
 case 386:
 /* rule 386 can match eol */
 YY_RULE_SETUP
-A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_FATPIPE;
+A_surfxml_link_state = A_surfxml_link_state_OFF;
        YY_BREAK
 case 387:
 /* rule 387 can match eol */
+YY_RULE_SETUP
+if (surfxml_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in <surfxml_link>");} surfxml_link_state___file_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link_state___file);
+       YY_BREAK
 case 388:
 /* rule 388 can match eol */
 YY_RULE_SETUP
-A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_FULLDUPLEX;
+if (surfxml_link_state___file_isset != 0) {FAIL("Multiple definition of attribute state_file in <surfxml_link>");}  surfxml_link_state___file_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link_state___file);
        YY_BREAK
 case 389:
+/* rule 389 can match eol */
+case 390:
+/* rule 390 can match eol */
+YY_RULE_SETUP
+A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_SHARED;
+       YY_BREAK
+case 391:
+/* rule 391 can match eol */
+case 392:
+/* rule 392 can match eol */
+YY_RULE_SETUP
+A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_FATPIPE;
+       YY_BREAK
+case 393:
+/* rule 393 can match eol */
+case 394:
+/* rule 394 can match eol */
+YY_RULE_SETUP
+A_surfxml_link_sharing___policy = A_surfxml_link_sharing___policy_FULLDUPLEX;
+       YY_BREAK
+case 395:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_link_id) FAIL("Required attribute `id' not set for `link' element.");
@@ -8056,7 +8131,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_link();surfxml_pcdata_ix = 0; ENTER(S_surfxml_link);
  }
        YY_BREAK
-case 390:
+case 396:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_link_id) FAIL("Required attribute `id' not set for `link' element.");
@@ -8068,11 +8143,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 391:
+case 397:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of link element.", surf_parse_text[0]);
        YY_BREAK
-case 392:
+case 398:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `link' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8080,8 +8155,8 @@ case YY_STATE_EOF(AL_surfxml_link):
 FAIL("EOF in attribute list of `link' element.");
        YY_BREAK
 
-case 393:
-/* rule 393 can match eol */
+case 399:
+/* rule 399 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8093,12 +8168,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 394:
-/* rule 394 can match eol */
+case 400:
+/* rule 400 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</link>' expected.",surf_parse_text);
        YY_BREAK
-case 395:
+case 401:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</link>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8108,13 +8183,13 @@ case YY_STATE_EOF(S_surfxml_link):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</link>' expected.");
        YY_BREAK
 
-case 396:
-/* rule 396 can match eol */
+case 402:
+/* rule 402 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <route> is not allowed here.");
        YY_BREAK
-case 397:
-/* rule 397 can match eol */
+case 403:
+/* rule 403 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_route_src = 0;
@@ -8127,41 +8202,41 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 398:
-/* rule 398 can match eol */
+case 404:
+/* rule 404 can match eol */
 YY_RULE_SETUP
 if (surfxml_route_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_route>");} surfxml_route_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_route_src);
        YY_BREAK
-case 399:
-/* rule 399 can match eol */
+case 405:
+/* rule 405 can match eol */
 YY_RULE_SETUP
 if (surfxml_route_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_route>");}  surfxml_route_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_route_src);
        YY_BREAK
-case 400:
-/* rule 400 can match eol */
+case 406:
+/* rule 406 can match eol */
 YY_RULE_SETUP
 if (surfxml_route_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_route>");} surfxml_route_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_route_dst);
        YY_BREAK
-case 401:
-/* rule 401 can match eol */
+case 407:
+/* rule 407 can match eol */
 YY_RULE_SETUP
 if (surfxml_route_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_route>");}  surfxml_route_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_route_dst);
        YY_BREAK
-case 402:
-/* rule 402 can match eol */
-case 403:
-/* rule 403 can match eol */
+case 408:
+/* rule 408 can match eol */
+case 409:
+/* rule 409 can match eol */
 YY_RULE_SETUP
 A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_YES;
        YY_BREAK
-case 404:
-/* rule 404 can match eol */
-case 405:
-/* rule 405 can match eol */
+case 410:
+/* rule 410 can match eol */
+case 411:
+/* rule 411 can match eol */
 YY_RULE_SETUP
 A_surfxml_route_symmetrical = A_surfxml_route_symmetrical_NO;
        YY_BREAK
-case 406:
+case 412:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_route_src) FAIL("Required attribute `src' not set for `route' element.");
@@ -8169,7 +8244,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_route();surfxml_pcdata_ix = 0; ENTER(S_surfxml_route);
  }
        YY_BREAK
-case 407:
+case 413:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_route_src) FAIL("Required attribute `src' not set for `route' element.");
@@ -8180,11 +8255,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 408:
+case 414:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of route element.", surf_parse_text[0]);
        YY_BREAK
-case 409:
+case 415:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `route' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8192,8 +8267,8 @@ case YY_STATE_EOF(AL_surfxml_route):
 FAIL("EOF in attribute list of `route' element.");
        YY_BREAK
 
-case 410:
-/* rule 410 can match eol */
+case 416:
+/* rule 416 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8204,12 +8279,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 411:
-/* rule 411 can match eol */
+case 417:
+/* rule 417 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</route>' expected.",surf_parse_text);
        YY_BREAK
-case 412:
+case 418:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</route>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8219,13 +8294,13 @@ case YY_STATE_EOF(E_surfxml_route):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</route>' expected.");
        YY_BREAK
 
-case 413:
-/* rule 413 can match eol */
+case 419:
+/* rule 419 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <ASroute> is not allowed here.");
        YY_BREAK
-case 414:
-/* rule 414 can match eol */
+case 420:
+/* rule 420 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_ASroute_src = 0;
@@ -8242,61 +8317,61 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 415:
-/* rule 415 can match eol */
+case 421:
+/* rule 421 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_ASroute>");} surfxml_ASroute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_src);
        YY_BREAK
-case 416:
-/* rule 416 can match eol */
+case 422:
+/* rule 422 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_ASroute>");}  surfxml_ASroute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_src);
        YY_BREAK
-case 417:
-/* rule 417 can match eol */
+case 423:
+/* rule 423 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_ASroute>");} surfxml_ASroute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_dst);
        YY_BREAK
-case 418:
-/* rule 418 can match eol */
+case 424:
+/* rule 424 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_ASroute>");}  surfxml_ASroute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_dst);
        YY_BREAK
-case 419:
-/* rule 419 can match eol */
+case 425:
+/* rule 425 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in <surfxml_ASroute>");} surfxml_ASroute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_gw___src);
        YY_BREAK
-case 420:
-/* rule 420 can match eol */
+case 426:
+/* rule 426 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in <surfxml_ASroute>");}  surfxml_ASroute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_gw___src);
        YY_BREAK
-case 421:
-/* rule 421 can match eol */
+case 427:
+/* rule 427 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in <surfxml_ASroute>");} surfxml_ASroute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_ASroute_gw___dst);
        YY_BREAK
-case 422:
-/* rule 422 can match eol */
+case 428:
+/* rule 428 can match eol */
 YY_RULE_SETUP
 if (surfxml_ASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in <surfxml_ASroute>");}  surfxml_ASroute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_ASroute_gw___dst);
        YY_BREAK
-case 423:
-/* rule 423 can match eol */
-case 424:
-/* rule 424 can match eol */
+case 429:
+/* rule 429 can match eol */
+case 430:
+/* rule 430 can match eol */
 YY_RULE_SETUP
 A_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_YES;
        YY_BREAK
-case 425:
-/* rule 425 can match eol */
-case 426:
-/* rule 426 can match eol */
+case 431:
+/* rule 431 can match eol */
+case 432:
+/* rule 432 can match eol */
 YY_RULE_SETUP
 A_surfxml_ASroute_symmetrical = A_surfxml_ASroute_symmetrical_NO;
        YY_BREAK
-case 427:
+case 433:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_ASroute_src) FAIL("Required attribute `src' not set for `ASroute' element.");
@@ -8306,7 +8381,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_ASroute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_ASroute);
  }
        YY_BREAK
-case 428:
+case 434:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_ASroute_src) FAIL("Required attribute `src' not set for `ASroute' element.");
@@ -8319,11 +8394,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 429:
+case 435:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of ASroute element.", surf_parse_text[0]);
        YY_BREAK
-case 430:
+case 436:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `ASroute' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8331,8 +8406,8 @@ case YY_STATE_EOF(AL_surfxml_ASroute):
 FAIL("EOF in attribute list of `ASroute' element.");
        YY_BREAK
 
-case 431:
-/* rule 431 can match eol */
+case 437:
+/* rule 437 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8343,12 +8418,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 432:
-/* rule 432 can match eol */
+case 438:
+/* rule 438 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</ASroute>' expected.",surf_parse_text);
        YY_BREAK
-case 433:
+case 439:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</ASroute>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8358,13 +8433,13 @@ case YY_STATE_EOF(S_surfxml_ASroute_2):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</ASroute>' expected.");
        YY_BREAK
 
-case 434:
-/* rule 434 can match eol */
+case 440:
+/* rule 440 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <link_ctn> is not allowed here.");
        YY_BREAK
-case 435:
-/* rule 435 can match eol */
+case 441:
+/* rule 441 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_link___ctn_id = 0;
@@ -8375,45 +8450,45 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 436:
-/* rule 436 can match eol */
+case 442:
+/* rule 442 can match eol */
 YY_RULE_SETUP
 if (surfxml_link___ctn_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_link___ctn>");} surfxml_link___ctn_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_link___ctn_id);
        YY_BREAK
-case 437:
-/* rule 437 can match eol */
+case 443:
+/* rule 443 can match eol */
 YY_RULE_SETUP
 if (surfxml_link___ctn_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_link___ctn>");}  surfxml_link___ctn_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_link___ctn_id);
        YY_BREAK
-case 438:
-/* rule 438 can match eol */
-case 439:
-/* rule 439 can match eol */
+case 444:
+/* rule 444 can match eol */
+case 445:
+/* rule 445 can match eol */
 YY_RULE_SETUP
 A_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_UP;
        YY_BREAK
-case 440:
-/* rule 440 can match eol */
-case 441:
-/* rule 441 can match eol */
+case 446:
+/* rule 446 can match eol */
+case 447:
+/* rule 447 can match eol */
 YY_RULE_SETUP
 A_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_DOWN;
        YY_BREAK
-case 442:
-/* rule 442 can match eol */
-case 443:
-/* rule 443 can match eol */
+case 448:
+/* rule 448 can match eol */
+case 449:
+/* rule 449 can match eol */
 YY_RULE_SETUP
 A_surfxml_link___ctn_direction = A_surfxml_link___ctn_direction_NONE;
        YY_BREAK
-case 444:
+case 450:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_link___ctn_id) FAIL("Required attribute `id' not set for `link_ctn' element.");
   LEAVE; STag_surfxml_link___ctn();surfxml_pcdata_ix = 0; ENTER(E_surfxml_link___ctn);
  }
        YY_BREAK
-case 445:
+case 451:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_link___ctn_id) FAIL("Required attribute `id' not set for `link_ctn' element.");
@@ -8426,11 +8501,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 446:
+case 452:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of link_ctn element.", surf_parse_text[0]);
        YY_BREAK
-case 447:
+case 453:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `link_ctn' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8438,8 +8513,8 @@ case YY_STATE_EOF(AL_surfxml_link___ctn):
 FAIL("EOF in attribute list of `link_ctn' element.");
        YY_BREAK
 
-case 448:
-/* rule 448 can match eol */
+case 454:
+/* rule 454 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8453,12 +8528,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 449:
-/* rule 449 can match eol */
+case 455:
+/* rule 455 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</link_ctn>' expected.",surf_parse_text);
        YY_BREAK
-case 450:
+case 456:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</link_ctn>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8466,13 +8541,13 @@ case YY_STATE_EOF(E_surfxml_link___ctn):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</link_ctn>' expected.");
        YY_BREAK
 
-case 451:
-/* rule 451 can match eol */
+case 457:
+/* rule 457 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <bypassRoute> is not allowed here.");
        YY_BREAK
-case 452:
-/* rule 452 can match eol */
+case 458:
+/* rule 458 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_bypassRoute_src = 0;
@@ -8483,27 +8558,27 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 453:
-/* rule 453 can match eol */
+case 459:
+/* rule 459 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_bypassRoute>");} surfxml_bypassRoute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassRoute_src);
        YY_BREAK
-case 454:
-/* rule 454 can match eol */
+case 460:
+/* rule 460 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassRoute_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_bypassRoute>");}  surfxml_bypassRoute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassRoute_src);
        YY_BREAK
-case 455:
-/* rule 455 can match eol */
+case 461:
+/* rule 461 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_bypassRoute>");} surfxml_bypassRoute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassRoute_dst);
        YY_BREAK
-case 456:
-/* rule 456 can match eol */
+case 462:
+/* rule 462 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassRoute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_bypassRoute>");}  surfxml_bypassRoute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassRoute_dst);
        YY_BREAK
-case 457:
+case 463:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_bypassRoute_src) FAIL("Required attribute `src' not set for `bypassRoute' element.");
@@ -8511,7 +8586,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_bypassRoute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_bypassRoute);
  }
        YY_BREAK
-case 458:
+case 464:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_bypassRoute_src) FAIL("Required attribute `src' not set for `bypassRoute' element.");
@@ -8522,11 +8597,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 459:
+case 465:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of bypassRoute element.", surf_parse_text[0]);
        YY_BREAK
-case 460:
+case 466:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `bypassRoute' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8534,8 +8609,8 @@ case YY_STATE_EOF(AL_surfxml_bypassRoute):
 FAIL("EOF in attribute list of `bypassRoute' element.");
        YY_BREAK
 
-case 461:
-/* rule 461 can match eol */
+case 467:
+/* rule 467 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8546,12 +8621,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 462:
-/* rule 462 can match eol */
+case 468:
+/* rule 468 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</bypassRoute>' expected.",surf_parse_text);
        YY_BREAK
-case 463:
+case 469:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</bypassRoute>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8561,13 +8636,13 @@ case YY_STATE_EOF(E_surfxml_bypassRoute):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</bypassRoute>' expected.");
        YY_BREAK
 
-case 464:
-/* rule 464 can match eol */
+case 470:
+/* rule 470 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <bypassASroute> is not allowed here.");
        YY_BREAK
-case 465:
-/* rule 465 can match eol */
+case 471:
+/* rule 471 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_bypassASroute_src = 0;
@@ -8582,47 +8657,47 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 466:
-/* rule 466 can match eol */
+case 472:
+/* rule 472 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_bypassASroute>");} surfxml_bypassASroute_src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_src);
        YY_BREAK
-case 467:
-/* rule 467 can match eol */
+case 473:
+/* rule 473 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_src_isset != 0) {FAIL("Multiple definition of attribute src in <surfxml_bypassASroute>");}  surfxml_bypassASroute_src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_src);
        YY_BREAK
-case 468:
-/* rule 468 can match eol */
+case 474:
+/* rule 474 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_bypassASroute>");} surfxml_bypassASroute_dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_dst);
        YY_BREAK
-case 469:
-/* rule 469 can match eol */
+case 475:
+/* rule 475 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_dst_isset != 0) {FAIL("Multiple definition of attribute dst in <surfxml_bypassASroute>");}  surfxml_bypassASroute_dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_dst);
        YY_BREAK
-case 470:
-/* rule 470 can match eol */
+case 476:
+/* rule 476 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in <surfxml_bypassASroute>");} surfxml_bypassASroute_gw___src_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_gw___src);
        YY_BREAK
-case 471:
-/* rule 471 can match eol */
+case 477:
+/* rule 477 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_gw___src_isset != 0) {FAIL("Multiple definition of attribute gw_src in <surfxml_bypassASroute>");}  surfxml_bypassASroute_gw___src_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_gw___src);
        YY_BREAK
-case 472:
-/* rule 472 can match eol */
+case 478:
+/* rule 478 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in <surfxml_bypassASroute>");} surfxml_bypassASroute_gw___dst_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_bypassASroute_gw___dst);
        YY_BREAK
-case 473:
-/* rule 473 can match eol */
+case 479:
+/* rule 479 can match eol */
 YY_RULE_SETUP
 if (surfxml_bypassASroute_gw___dst_isset != 0) {FAIL("Multiple definition of attribute gw_dst in <surfxml_bypassASroute>");}  surfxml_bypassASroute_gw___dst_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_bypassASroute_gw___dst);
        YY_BREAK
-case 474:
+case 480:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_bypassASroute_src) FAIL("Required attribute `src' not set for `bypassASroute' element.");
@@ -8632,7 +8707,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_bypassASroute();surfxml_pcdata_ix = 0; ENTER(S_surfxml_bypassASroute);
  }
        YY_BREAK
-case 475:
+case 481:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_bypassASroute_src) FAIL("Required attribute `src' not set for `bypassASroute' element.");
@@ -8645,11 +8720,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 476:
+case 482:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of bypassASroute element.", surf_parse_text[0]);
        YY_BREAK
-case 477:
+case 483:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `bypassASroute' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8657,8 +8732,8 @@ case YY_STATE_EOF(AL_surfxml_bypassASroute):
 FAIL("EOF in attribute list of `bypassASroute' element.");
        YY_BREAK
 
-case 478:
-/* rule 478 can match eol */
+case 484:
+/* rule 484 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8669,12 +8744,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 479:
-/* rule 479 can match eol */
+case 485:
+/* rule 485 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</bypassASroute>' expected.",surf_parse_text);
        YY_BREAK
-case 480:
+case 486:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</bypassASroute>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8684,13 +8759,13 @@ case YY_STATE_EOF(S_surfxml_bypassASroute):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</bypassASroute>' expected.");
        YY_BREAK
 
-case 481:
-/* rule 481 can match eol */
+case 487:
+/* rule 487 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <process> is not allowed here.");
        YY_BREAK
-case 482:
-/* rule 482 can match eol */
+case 488:
+/* rule 488 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_process_host = 0;
@@ -8707,61 +8782,61 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 483:
-/* rule 483 can match eol */
+case 489:
+/* rule 489 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_host_isset != 0) {FAIL("Multiple definition of attribute host in <surfxml_process>");} surfxml_process_host_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_host);
        YY_BREAK
-case 484:
-/* rule 484 can match eol */
+case 490:
+/* rule 490 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_host_isset != 0) {FAIL("Multiple definition of attribute host in <surfxml_process>");}  surfxml_process_host_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_host);
        YY_BREAK
-case 485:
-/* rule 485 can match eol */
+case 491:
+/* rule 491 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_function_isset != 0) {FAIL("Multiple definition of attribute function in <surfxml_process>");} surfxml_process_function_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_function);
        YY_BREAK
-case 486:
-/* rule 486 can match eol */
+case 492:
+/* rule 492 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_function_isset != 0) {FAIL("Multiple definition of attribute function in <surfxml_process>");}  surfxml_process_function_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_function);
        YY_BREAK
-case 487:
-/* rule 487 can match eol */
+case 493:
+/* rule 493 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in <surfxml_process>");} surfxml_process_start___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_start___time);
        YY_BREAK
-case 488:
-/* rule 488 can match eol */
+case 494:
+/* rule 494 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_start___time_isset != 0) {FAIL("Multiple definition of attribute start_time in <surfxml_process>");}  surfxml_process_start___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_start___time);
        YY_BREAK
-case 489:
-/* rule 489 can match eol */
+case 495:
+/* rule 495 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in <surfxml_process>");} surfxml_process_kill___time_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_process_kill___time);
        YY_BREAK
-case 490:
-/* rule 490 can match eol */
+case 496:
+/* rule 496 can match eol */
 YY_RULE_SETUP
 if (surfxml_process_kill___time_isset != 0) {FAIL("Multiple definition of attribute kill_time in <surfxml_process>");}  surfxml_process_kill___time_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_process_kill___time);
        YY_BREAK
-case 491:
-/* rule 491 can match eol */
-case 492:
-/* rule 492 can match eol */
+case 497:
+/* rule 497 can match eol */
+case 498:
+/* rule 498 can match eol */
 YY_RULE_SETUP
 A_surfxml_process_on___failure = A_surfxml_process_on___failure_DIE;
        YY_BREAK
-case 493:
-/* rule 493 can match eol */
-case 494:
-/* rule 494 can match eol */
+case 499:
+/* rule 499 can match eol */
+case 500:
+/* rule 500 can match eol */
 YY_RULE_SETUP
 A_surfxml_process_on___failure = A_surfxml_process_on___failure_RESTART;
        YY_BREAK
-case 495:
+case 501:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_process_host) FAIL("Required attribute `host' not set for `process' element.");
@@ -8769,7 +8844,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_process();surfxml_pcdata_ix = 0; ENTER(S_surfxml_process);
  }
        YY_BREAK
-case 496:
+case 502:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_process_host) FAIL("Required attribute `host' not set for `process' element.");
@@ -8780,11 +8855,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 497:
+case 503:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of process element.", surf_parse_text[0]);
        YY_BREAK
-case 498:
+case 504:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `process' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8792,8 +8867,8 @@ case YY_STATE_EOF(AL_surfxml_process):
 FAIL("EOF in attribute list of `process' element.");
        YY_BREAK
 
-case 499:
-/* rule 499 can match eol */
+case 505:
+/* rule 505 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8804,12 +8879,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 500:
-/* rule 500 can match eol */
+case 506:
+/* rule 506 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</process>' expected.",surf_parse_text);
        YY_BREAK
-case 501:
+case 507:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</process>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8819,13 +8894,13 @@ case YY_STATE_EOF(S_surfxml_process_2):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</process>' expected.");
        YY_BREAK
 
-case 502:
-/* rule 502 can match eol */
+case 508:
+/* rule 508 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <argument> is not allowed here.");
        YY_BREAK
-case 503:
-/* rule 503 can match eol */
+case 509:
+/* rule 509 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_argument_value = 0;
@@ -8834,24 +8909,24 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 504:
-/* rule 504 can match eol */
+case 510:
+/* rule 510 can match eol */
 YY_RULE_SETUP
 if (surfxml_argument_value_isset != 0) {FAIL("Multiple definition of attribute value in <surfxml_argument>");} surfxml_argument_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_argument_value);
        YY_BREAK
-case 505:
-/* rule 505 can match eol */
+case 511:
+/* rule 511 can match eol */
 YY_RULE_SETUP
 if (surfxml_argument_value_isset != 0) {FAIL("Multiple definition of attribute value in <surfxml_argument>");}  surfxml_argument_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_argument_value);
        YY_BREAK
-case 506:
+case 512:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_argument_value) FAIL("Required attribute `value' not set for `argument' element.");
   LEAVE; STag_surfxml_argument();surfxml_pcdata_ix = 0; ENTER(E_surfxml_argument);
  }
        YY_BREAK
-case 507:
+case 513:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_argument_value) FAIL("Required attribute `value' not set for `argument' element.");
@@ -8861,11 +8936,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 508:
+case 514:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of argument element.", surf_parse_text[0]);
        YY_BREAK
-case 509:
+case 515:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `argument' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8873,8 +8948,8 @@ case YY_STATE_EOF(AL_surfxml_argument):
 FAIL("EOF in attribute list of `argument' element.");
        YY_BREAK
 
-case 510:
-/* rule 510 can match eol */
+case 516:
+/* rule 516 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8885,12 +8960,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 511:
-/* rule 511 can match eol */
+case 517:
+/* rule 517 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</argument>' expected.",surf_parse_text);
        YY_BREAK
-case 512:
+case 518:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</argument>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8898,13 +8973,13 @@ case YY_STATE_EOF(E_surfxml_argument):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</argument>' expected.");
        YY_BREAK
 
-case 513:
-/* rule 513 can match eol */
+case 519:
+/* rule 519 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <config> is not allowed here.");
        YY_BREAK
-case 514:
-/* rule 514 can match eol */
+case 520:
+/* rule 520 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_config_id = 0;
@@ -8913,23 +8988,23 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 515:
-/* rule 515 can match eol */
+case 521:
+/* rule 521 can match eol */
 YY_RULE_SETUP
 if (surfxml_config_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_config>");} surfxml_config_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_config_id);
        YY_BREAK
-case 516:
-/* rule 516 can match eol */
+case 522:
+/* rule 522 can match eol */
 YY_RULE_SETUP
 if (surfxml_config_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_config>");}  surfxml_config_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_config_id);
        YY_BREAK
-case 517:
+case 523:
 YY_RULE_SETUP
 {
   LEAVE; STag_surfxml_config();surfxml_pcdata_ix = 0; ENTER(S_surfxml_config);
  }
        YY_BREAK
-case 518:
+case 524:
 YY_RULE_SETUP
 {
   LEAVE; STag_surfxml_config(); surfxml_pcdata_ix = 0; ETag_surfxml_config(); popbuffer(); /* attribute */
@@ -8938,11 +9013,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 519:
+case 525:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of config element.", surf_parse_text[0]);
        YY_BREAK
-case 520:
+case 526:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `config' element start tag.",surf_parse_text);
        YY_BREAK
@@ -8950,8 +9025,8 @@ case YY_STATE_EOF(AL_surfxml_config):
 FAIL("EOF in attribute list of `config' element.");
        YY_BREAK
 
-case 521:
-/* rule 521 can match eol */
+case 527:
+/* rule 527 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -8962,12 +9037,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 522:
-/* rule 522 can match eol */
+case 528:
+/* rule 528 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</config>' expected.",surf_parse_text);
        YY_BREAK
-case 523:
+case 529:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</config>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -8979,13 +9054,13 @@ if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</config>' expected.");
 
 /* <!-- <!ATTLIST prop key CDATA #REQUIRED> -->
   * <!-- <!ATTLIST prop key CDATA #REQUIRED> -->  */
-case 524:
-/* rule 524 can match eol */
+case 530:
+/* rule 530 can match eol */
 YY_RULE_SETUP
 FAIL("Starting tag <prop> is not allowed here.");
        YY_BREAK
-case 525:
-/* rule 525 can match eol */
+case 531:
+/* rule 531 can match eol */
 YY_RULE_SETUP
 {
   AX_surfxml_prop_id = 0;
@@ -8996,27 +9071,27 @@ YY_RULE_SETUP
   }
        YY_BREAK
 
-case 526:
-/* rule 526 can match eol */
+case 532:
+/* rule 532 can match eol */
 YY_RULE_SETUP
 if (surfxml_prop_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_prop>");} surfxml_prop_id_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_prop_id);
        YY_BREAK
-case 527:
-/* rule 527 can match eol */
+case 533:
+/* rule 533 can match eol */
 YY_RULE_SETUP
 if (surfxml_prop_id_isset != 0) {FAIL("Multiple definition of attribute id in <surfxml_prop>");}  surfxml_prop_id_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_prop_id);
        YY_BREAK
-case 528:
-/* rule 528 can match eol */
+case 534:
+/* rule 534 can match eol */
 YY_RULE_SETUP
 if (surfxml_prop_value_isset != 0) {FAIL("Multiple definition of attribute value in <surfxml_prop>");} surfxml_prop_value_isset = 1; ENTER(VALUE1); BUFFERSET(AX_surfxml_prop_value);
        YY_BREAK
-case 529:
-/* rule 529 can match eol */
+case 535:
+/* rule 535 can match eol */
 YY_RULE_SETUP
 if (surfxml_prop_value_isset != 0) {FAIL("Multiple definition of attribute value in <surfxml_prop>");}  surfxml_prop_value_isset = 1; ENTER(VALUE2); BUFFERSET(AX_surfxml_prop_value);
        YY_BREAK
-case 530:
+case 536:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_prop_id) FAIL("Required attribute `id' not set for `prop' element.");
@@ -9024,7 +9099,7 @@ YY_RULE_SETUP
   LEAVE; STag_surfxml_prop();surfxml_pcdata_ix = 0; ENTER(E_surfxml_prop);
  }
        YY_BREAK
-case 531:
+case 537:
 YY_RULE_SETUP
 {
   if (!AX_surfxml_prop_id) FAIL("Required attribute `id' not set for `prop' element.");
@@ -9041,11 +9116,11 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 532:
+case 538:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c' in attribute list of prop element.", surf_parse_text[0]);
        YY_BREAK
-case 533:
+case 539:
 YY_RULE_SETUP
 FAIL("Bad attribute `%s' in `prop' element start tag.",surf_parse_text);
        YY_BREAK
@@ -9053,8 +9128,8 @@ case YY_STATE_EOF(AL_surfxml_prop):
 FAIL("EOF in attribute list of `prop' element.");
        YY_BREAK
 
-case 534:
-/* rule 534 can match eol */
+case 540:
+/* rule 540 can match eol */
 YY_RULE_SETUP
 {
   LEAVE;
@@ -9071,12 +9146,12 @@ YY_RULE_SETUP
   }
  }
        YY_BREAK
-case 535:
-/* rule 535 can match eol */
+case 541:
+/* rule 541 can match eol */
 YY_RULE_SETUP
 FAIL("Unexpected end-tag `%s': `</prop>' expected.",surf_parse_text);
        YY_BREAK
-case 536:
+case 542:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</prop>' expected.",surf_parse_text[0]);
        YY_BREAK
@@ -9086,7 +9161,7 @@ if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</prop>' expected.");
 
 /* EPILOG: after the root element. */
 
-case 537:
+case 543:
 YY_RULE_SETUP
 {SET(PROLOG); yyless(0); CLEANUP; return -1;}
        YY_BREAK
@@ -9097,58 +9172,58 @@ SUCCEED;
 /* CHARACTER DATA. */
 
 /* Non-defined standard entities... */
-case 538:
+case 544:
 YY_RULE_SETUP
 BUFFERPUTC('&');
        YY_BREAK
-case 539:
+case 545:
 YY_RULE_SETUP
 BUFFERPUTC('<');
        YY_BREAK
-case 540:
+case 546:
 YY_RULE_SETUP
 BUFFERPUTC('>');
        YY_BREAK
-case 541:
+case 547:
 YY_RULE_SETUP
 BUFFERPUTC('\'');
        YY_BREAK
-case 542:
+case 548:
 YY_RULE_SETUP
 BUFFERPUTC('"');
        YY_BREAK
 /* Character entities. */
-case 543:
+case 549:
 YY_RULE_SETUP
 BUFFERPUTC((unsigned char)atoi(surf_parse_text+2));
        YY_BREAK
-case 544:
+case 550:
 YY_RULE_SETUP
 BUFFERPUTC((unsigned char)strtol(surf_parse_text+3,NULL,16));
        YY_BREAK
 
-case 545:
-/* rule 545 can match eol */
-case 546:
-/* rule 546 can match eol */
-case 547:
-/* rule 547 can match eol */
-case 548:
-/* rule 548 can match eol */
+case 551:
+/* rule 551 can match eol */
+case 552:
+/* rule 552 can match eol */
+case 553:
+/* rule 553 can match eol */
+case 554:
+/* rule 554 can match eol */
 YY_RULE_SETUP
 BUFFERPUTC('\n');
        YY_BREAK
 
-case 549:
+case 555:
 YY_RULE_SETUP
 ENTER(CDATA);
        YY_BREAK
-case 550:
+case 556:
 YY_RULE_SETUP
 FAIL("Unexpected `]""]>' in character data.");
        YY_BREAK
 
-case 551:
+case 557:
 YY_RULE_SETUP
 BUFFERDONE; LEAVE;
        YY_BREAK
@@ -9156,7 +9231,7 @@ case YY_STATE_EOF(VALUE1):
 FAIL("EOF in literal (\"'\" expected).");
        YY_BREAK
 
-case 552:
+case 558:
 YY_RULE_SETUP
 BUFFERDONE; LEAVE;
        YY_BREAK
@@ -9164,22 +9239,22 @@ case YY_STATE_EOF(VALUE2):
 FAIL("EOF in literal (`\"' expected).");
        YY_BREAK
 
-case 553:
-/* rule 553 can match eol */
+case 559:
+/* rule 559 can match eol */
 YY_RULE_SETUP
 BUFFERPUTC(surf_parse_text[0]);
        YY_BREAK
-case 554:
+case 560:
 YY_RULE_SETUP
 FAIL("Spurious `%c' in character data.",surf_parse_text[0]);
        YY_BREAK
 
-case 555:
+case 561:
 YY_RULE_SETUP
 LEAVE;
        YY_BREAK
 /* "]""]"              BUFFERPUTC(surf_parse_text[0]); BUFFERPUTC(surf_parse_text[1]); */
-case 556:
+case 562:
 YY_RULE_SETUP
 BUFFERPUTC(surf_parse_text[0]);
        YY_BREAK
@@ -9191,13 +9266,13 @@ FAIL("EOF in CDATA section.");
 /* Ideally, this should be replaced by code in flexml.pl that
     generates just the states not covered by other rules. */
 
-case 557:
-/* rule 557 can match eol */
+case 563:
+/* rule 563 can match eol */
 YY_RULE_SETUP
 FAIL("Syntax error on character `%c'.", surf_parse_text[0]);
        YY_BREAK
 
-case 558:
+case 564:
 YY_RULE_SETUP
 ECHO;
        YY_BREAK
@@ -9514,7 +9589,7 @@ static int yy_get_next_buffer (void)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 3260 )
+                       if ( yy_current_state >= 3299 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -9542,11 +9617,11 @@ static int yy_get_next_buffer (void)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 3260 )
+               if ( yy_current_state >= 3299 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 3259);
+       yy_is_jam = (yy_current_state == 3298);
 
        return yy_is_jam ? 0 : yy_current_state;
 }
index 8e25069..d95800f 100644 (file)
@@ -119,6 +119,8 @@ static void parse_S_host_link(sg_platf_host_link_cbarg_t host)
   s_surf_parsing_link_up_down_t link_up_down;
   link_up_down.link_up = xbt_lib_get_or_null(link_lib, host->link_up, SURF_LINK_LEVEL);
   link_up_down.link_down = xbt_lib_get_or_null(link_lib, host->link_down, SURF_LINK_LEVEL);
+  link_up_down.limiter_link = NULL;
+  link_up_down.loopback_link = NULL;
 
   xbt_assert(link_up_down.link_up, "Link '%s' not found!",host->link_up);
   xbt_assert(link_up_down.link_down, "Link '%s' not found!",host->link_down);
@@ -897,6 +899,47 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
         info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL);
         info.link_down = info.link_up;
       }
+      
+      if(cluster->limiter_link!=0){      
+        char *tmp_link = bprintf("%s_limiter", link_id);
+        XBT_DEBUG("<limiter\tid=\"%s\"\tbw=\"%f\"/>", tmp_link,
+                cluster->limiter_link);
+
+        
+        memset(&link, 0, sizeof(link));
+        link.id = tmp_link;
+        link.bandwidth = cluster->limiter_link;
+        link.latency = 0;
+        link.state = SURF_RESOURCE_ON;
+        link.policy = SURF_LINK_SHARED;
+        sg_platf_new_link(&link);
+         info.limiter_link =
+            xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL);
+        free(tmp_link);
+      }else{
+        info.limiter_link =NULL;
+      }
+      
+      if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){      
+        char *tmp_link = bprintf("%s_loopback", link_id);
+        XBT_DEBUG("<loopback\tid=\"%s\"\tbw=\"%f\"/>", tmp_link,
+                cluster->limiter_link);
+
+        
+        memset(&link, 0, sizeof(link));
+        link.id = tmp_link;
+        link.bandwidth = cluster->loopback_bw;
+        link.latency = cluster->loopback_lat;
+        link.state = SURF_RESOURCE_ON;
+        link.policy = SURF_LINK_FATPIPE;
+        sg_platf_new_link(&link);
+         info.loopback_link =
+            xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL);
+        free(tmp_link);
+      }else{
+        info.loopback_link =NULL;
+      }
+      
       xbt_dynar_push(current_routing->link_up_down_list,&info);
       xbt_free(link_id);
       xbt_free(host_id);
index f19670f..fbd7b42 100644 (file)
@@ -23,13 +23,27 @@ static void cluster_get_route_and_latency(AS_t as,
 {
 
   s_surf_parsing_link_up_down_t info;
-  XBT_DEBUG("cluster_get_route_and_latency from '%s'[%d] to '%s'[%d]",
+  XBT_VERB("cluster_get_route_and_latency from '%s'[%d] to '%s'[%d]",
             src->name, src->id, dst->name, dst->id);
 
   if (src->rc_type != SURF_NETWORK_ELEMENT_ROUTER) {    // No specific link for router
     info =
         xbt_dynar_get_as(as->link_up_down_list, src->id,
                          s_surf_parsing_link_up_down_t);
+                         
+    if((src->id == dst->id) && info.loopback_link  ){
+      xbt_dynar_push_as(route->link_list, void *, info.loopback_link);
+      if (lat)
+        *lat +=
+            surf_network_model->extension.network.get_link_latency(info.
+                                                                   loopback_link);
+      return;
+    }
+                         
+                         
+    if (info.limiter_link)          // limiter for sender
+      xbt_dynar_push_as(route->link_list, void *, info.limiter_link);
+    
     if (info.link_up) {         // link up
       xbt_dynar_push_as(route->link_list, void *, info.link_up);
       if (lat)
@@ -58,6 +72,10 @@ static void cluster_get_route_and_latency(AS_t as,
             surf_network_model->extension.network.get_link_latency(info.
                                                                    link_down);
     }
+    
+    if (info.limiter_link)          // limiter for receiver
+      xbt_dynar_push_as(route->link_list, void *, info.limiter_link);
+    
   }
 }
 
index c1369d0..b63fb23 100644 (file)
@@ -72,6 +72,7 @@ AS_t model_rulebased_create(void);      /* create structures for rulebased routi
 typedef struct {
   s_as_t generic_routing;
   void *backbone;
+  void *loopback;
   sg_routing_edge_t router;
 } s_as_cluster_t, *as_cluster_t;
 
index 18a6f49..fb6e217 100644 (file)
@@ -348,6 +348,12 @@ void STag_surfxml_cluster(void){
     cluster.bb_bw = surf_parse_get_double(A_surfxml_cluster_bb___bw);
   if(strcmp(A_surfxml_cluster_bb___lat,""))
     cluster.bb_lat = surf_parse_get_double(A_surfxml_cluster_bb___lat);
+  if(strcmp(A_surfxml_cluster_limiter___link,""))
+    cluster.limiter_link = surf_parse_get_double(A_surfxml_cluster_limiter___link);
+  if(strcmp(A_surfxml_cluster_loopback___bw,""))
+    cluster.loopback_bw = surf_parse_get_double(A_surfxml_cluster_loopback___bw);
+  if(strcmp(A_surfxml_cluster_loopback___lat,""))
+    cluster.loopback_lat = surf_parse_get_double(A_surfxml_cluster_loopback___lat);
   cluster.router_id = A_surfxml_cluster_router___id;
 
   switch (AX_surfxml_cluster_sharing___policy) {
index a089714..cfc8175 100644 (file)
@@ -582,6 +582,7 @@ static void xbt_log_connect_categories(void)
   XBT_LOG_CONNECT(instr_config);
   XBT_LOG_CONNECT(instr_msg);
   XBT_LOG_CONNECT(instr_msg_process);
+  XBT_LOG_CONNECT(instr_msg_vm);
   XBT_LOG_CONNECT(instr_paje_containers);
   XBT_LOG_CONNECT(instr_paje_header);
   XBT_LOG_CONNECT(instr_paje_trace);
@@ -589,6 +590,7 @@ static void xbt_log_connect_categories(void)
   XBT_LOG_CONNECT(instr_paje_values);
   XBT_LOG_CONNECT(instr_resource);
   XBT_LOG_CONNECT(instr_routing);
+  XBT_LOG_CONNECT(instr_sd);
   XBT_LOG_CONNECT(instr_surf);
 #endif
 
index a6735e0..ad5e05e 100644 (file)
@@ -55,7 +55,7 @@ void mfree(struct mdesc *mdp, void *ptr)
       mdp -> heapinfo[block].busy_block.size * BLOCKSIZE;
 
     if(MC_is_active()){
-      if(mdp->heapinfo[block].busy_block.ignore == 1)
+      if(mdp->heapinfo[block].busy_block.ignore > 0)
         MC_remove_ignore_heap(ptr, mdp -> heapinfo[block].busy_block.busy_size);
     }
 
@@ -162,7 +162,7 @@ void mfree(struct mdesc *mdp, void *ptr)
     }
 
     if(MC_is_active()){
-      if(mdp->heapinfo[block].busy_frag.ignore[frag_nb] == 1)
+      if(mdp->heapinfo[block].busy_frag.ignore[frag_nb] > 0)
         MC_remove_ignore_heap(ptr, mdp->heapinfo[block].busy_frag.frag_size[frag_nb]);
     }
 
index bede162..b80543e 100644 (file)
@@ -215,7 +215,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
         
           addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
         
-          res_compare = compare_area(addr_block1, addr_block2, previous);
+          res_compare = compare_area(addr_block1, addr_block2, NULL);
         
           if(res_compare == 0){
             for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
@@ -223,7 +223,6 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
             for(k=1; k < heapinfo1[current_block].busy_block.size; k++)
               heapinfo1[current_block+k].busy_block.equal_to = new_heap_area(i1, -1);
             equal = 1;
-            match_equals(previous);
             i1 = i1 + heapinfo1[current_block].busy_block.size;
           }
         
@@ -251,8 +250,8 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
           i2++;
           continue;
         }
-        
-        res_compare = compare_area(addr_block1, addr_block2, previous);
+          
+        res_compare = compare_area(addr_block1, addr_block2, NULL);
         
         if(res_compare == 0){
           for(k=1; k < heapinfo2[i2].busy_block.size; k++)
@@ -260,7 +259,6 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
           for(k=1; k < heapinfo1[i1].busy_block.size; k++)
             heapinfo1[i1+k].busy_block.equal_to = new_heap_area(i2, -1);
           equal = 1;
-          match_equals(previous);
           i1 = i1 + heapinfo1[i1].busy_block.size;
         }
 
@@ -301,16 +299,15 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
             addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
             addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << ((xbt_mheap_t)s_heap)->heapinfo[current_block].type));
 
-            res_compare = compare_area(addr_frag1, addr_frag2, previous);
+            res_compare = compare_area(addr_frag1, addr_frag2, NULL);
 
-            if(res_compare == 0){
+            if(res_compare == 0)
               equal = 1;
-              match_equals(previous);
-            }
         
             xbt_dynar_reset(previous);
 
-            }
+          }
+
         }
 
         while(i2 <= heaplimit && !equal){
@@ -323,7 +320,7 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
 
           for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
 
-            if(heapinfo2[i2].type == heapinfo1[i1].type && i2 == current_block && j2 == current_fragment)
+            if(i2 == current_block && j2 == current_fragment)
               continue;
 
             if(heapinfo2[i2].busy_frag.equal_to[j2] != NULL)                
@@ -332,11 +329,10 @@ int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
             addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)((xbt_mheap_t)s_heap)->heapbase));
             addr_frag2 = (void*) ((char *)addr_block2 + (j2 << ((xbt_mheap_t)s_heap)->heapinfo[i2].type));
 
-            res_compare = compare_area(addr_frag1, addr_frag2, previous);
+            res_compare = compare_area(addr_frag1, addr_frag2, NULL);
             
             if(res_compare == 0){
               equal = 1;
-              match_equals(previous);
               xbt_dynar_reset(previous);
               break;
             }
@@ -529,7 +525,7 @@ static size_t heap_comparison_ignore_size(xbt_dynar_t ignore_list, void *address
 }
 
 
-int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code : 0 = equal, 1 = same size but different bytes, 2 = different size used */
+int compare_area(void *area1, void* area2, xbt_dynar_t previous){
 
   size_t i = 0, pointer_align = 0, ignore1 = 0, ignore2 = 0;
   void *addr_pointed1, *addr_pointed2;
@@ -537,7 +533,6 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
   ssize_t block1, frag1, block2, frag2;
   ssize_t size;
   int check_ignore = 0;
-  int j;
 
   void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
   void *area1_to_compare, *area2_to_compare;
@@ -573,26 +568,22 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
   
   if(heapinfo1[block1].type == heapinfo2[block2].type){
     
-    if(heapinfo1[block1].type == -1){
+    if(heapinfo1[block1].type == -1){ /* Free block */
       if(match_pairs){
         match_equals(previous);
         xbt_dynar_free(&previous);
       }
       return 0;
-    }else if(heapinfo1[block1].type == 0){
 
-      if(heapinfo1[block1].busy_block.equal_to != NULL || heapinfo2[block2].busy_block.equal_to != NULL){
+    }else if(heapinfo1[block1].type == 0){ /* Complete block */
+
+      if(heapinfo1[block1].busy_block.equal_to != NULL && heapinfo2[block2].busy_block.equal_to != NULL){
         if(equal_blocks(block1, block2)){
           if(match_pairs){
             match_equals(previous);
             xbt_dynar_free(&previous);
           }
           return 0;
-        }else{
-          if(match_pairs){
-            xbt_dynar_free(&previous);
-          }
-          return 1;
         }
       }
 
@@ -607,7 +598,7 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
         if(match_pairs){
           xbt_dynar_free(&previous);
         }
-        return 2;
+        return 1;
       }
 
       if(!add_heap_area_pair(previous, block1, -1, block2, -1)){
@@ -634,8 +625,8 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
       area1_to_compare = addr_block1;
       area2_to_compare = addr_block2;
 
-      if(heapinfo1[block1].busy_block.ignore == 1 && heapinfo2[block2].busy_block.ignore == 1)
-        check_ignore = 1;
+      if((heapinfo1[block1].busy_block.ignore > 0) && (heapinfo2[block2].busy_block.ignore == heapinfo1[block1].busy_block.ignore))
+        check_ignore = heapinfo1[block1].busy_block.ignore;
       
     }else{
       frag1 = ((uintptr_t) (ADDR2UINT (area1) % (BLOCKSIZE))) >> heapinfo1[block1].type;
@@ -647,18 +638,13 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
       area1_to_compare = addr_frag1;
       area2_to_compare = addr_frag2;
 
-      if(heapinfo1[block1].busy_frag.equal_to[frag1] != NULL || heapinfo2[block2].busy_frag.equal_to[frag2] != NULL){
+      if(heapinfo1[block1].busy_frag.equal_to[frag1] != NULL && heapinfo2[block2].busy_frag.equal_to[frag2] != NULL){
         if(equal_fragments(block1, frag1, block2, frag2)){
           if(match_pairs){
             match_equals(previous);
             xbt_dynar_free(&previous);
           }
           return 0;
-        }else{
-          if(match_pairs){
-            xbt_dynar_free(&previous);
-          }
-          return 1;
         }
       }
 
@@ -666,7 +652,7 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
         if(match_pairs){
           xbt_dynar_free(&previous);
         }
-        return 2;  
+        return 1;  
       }
       
       if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
@@ -687,8 +673,8 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
         return 0;
       }
       
-      if(heapinfo1[block1].busy_frag.ignore[frag1] == 1 && heapinfo2[block2].busy_frag.ignore[frag2] == 1)
-        check_ignore = 1;
+      if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && ( heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
+        check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];
       
     }
 
@@ -704,11 +690,6 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
           xbt_dynar_free(&previous);
         }
         return 0;
-      }else{
-        if(match_pairs){
-          xbt_dynar_free(&previous);
-        }
-        return 1;
       }
     }
 
@@ -716,7 +697,7 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
       if(match_pairs){
         xbt_dynar_free(&previous);
       }
-      return 2;
+      return 1;
     }
     
     if(!add_heap_area_pair(previous, block1, frag1, block2, frag2)){
@@ -743,8 +724,8 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
       return 0;
     }
 
-    if(heapinfo1[block1].busy_frag.ignore[frag1] == 1 && heapinfo2[block2].busy_frag.ignore[frag2] == 1)
-      check_ignore = 1;   
+    if((heapinfo1[block1].busy_frag.ignore[frag1] > 0) && (heapinfo2[block2].busy_frag.ignore[frag2] == heapinfo1[block1].busy_frag.ignore[frag1]))
+      check_ignore = heapinfo1[block1].busy_frag.ignore[frag1];   
     
   }else{
     if(match_pairs){
@@ -755,43 +736,45 @@ int compare_area(void *area1, void* area2, xbt_dynar_t previous){ /* Return code
   
   while(i<size){
 
-    if(check_ignore){
+    if(check_ignore > 0){
       if((ignore1 = heap_comparison_ignore_size(to_ignore1, (char *)area1 + i)) > 0){
         if((ignore2 = heap_comparison_ignore_size(to_ignore2, (char *)area2 + i))  == ignore1){
           i = i + ignore2;
+          check_ignore--;
           continue;
         }
       }
     }
 
-    pointer_align = (i / sizeof(void*)) * sizeof(void*);
-    addr_pointed1 = *((void **)((char *)area1_to_compare + pointer_align));
-    addr_pointed2 = *((void **)((char *)area2_to_compare + pointer_align));
+    if(memcmp(((char *)area1_to_compare) + i, ((char *)area2_to_compare) + i, 1) != 0){
 
-    if(addr_pointed1 > maestro_stack_start && addr_pointed1 < maestro_stack_end && addr_pointed2 > maestro_stack_start && addr_pointed2 < maestro_stack_end){
-      i = pointer_align + sizeof(void *);
-      continue;
-    }else if((addr_pointed1 > s_heap) && ((char *)addr_pointed1 < (char *)s_heap + STD_HEAP_SIZE) 
+      pointer_align = (i / sizeof(void*)) * sizeof(void*);
+      addr_pointed1 = *((void **)((char *)area1_to_compare + pointer_align));
+      addr_pointed2 = *((void **)((char *)area2_to_compare + pointer_align));
+      
+      if(addr_pointed1 > maestro_stack_start && addr_pointed1 < maestro_stack_end && addr_pointed2 > maestro_stack_start && addr_pointed2 < maestro_stack_end){
+        i = pointer_align + sizeof(void *);
+        continue;
+      }else if((addr_pointed1 > s_heap) && ((char *)addr_pointed1 < (char *)s_heap + STD_HEAP_SIZE) 
            && (addr_pointed2 > s_heap) && ((char *)addr_pointed2 < (char *)s_heap + STD_HEAP_SIZE)){
-      res_compare = compare_area(addr_pointed1, addr_pointed2, previous);
-      if(res_compare != 0){
-        if(match_pairs)
-          xbt_dynar_free(&previous);
-        return res_compare;
-      }
-    }else{
-      j=0;
-      while(j<sizeof(void*) && (i + j) < size){
-        if(memcmp(((char *)area1_to_compare) + i + j, ((char *)area2_to_compare) + i + j , 1) != 0){
+        res_compare = compare_area(addr_pointed1, addr_pointed2, previous);
+        if(res_compare != 0){
           if(match_pairs)
             xbt_dynar_free(&previous);
-          return 1;
+          return res_compare;
         }
-        j++;
+        i = pointer_align + sizeof(void *);
+        continue;
+      }else{
+        if(match_pairs)
+          xbt_dynar_free(&previous);
+        return 1;
       }
+      
     }
+    
+    i++;
 
-    i = pointer_align + sizeof(void *);
   }
 
   if(match_pairs){
index 43e130a..0623bff 100644 (file)
@@ -156,7 +156,7 @@ typedef struct {
       size_t nfree;               /* Free fragments in a fragmented block.  */
       ssize_t frag_size[MAX_FRAGMENT_PER_BLOCK];
       //void *bt[MAX_FRAGMENT_PER_BLOCK][XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
-      short ignore[MAX_FRAGMENT_PER_BLOCK];
+      int ignore[MAX_FRAGMENT_PER_BLOCK];
       heap_area_t equal_to[MAX_FRAGMENT_PER_BLOCK];
     } busy_frag;
     struct {
@@ -164,7 +164,7 @@ typedef struct {
       size_t busy_size; /* Actually used space, in bytes */
       //void *bt[XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
       //int bt_size;
-      short ignore;
+      int ignore;
       heap_area_t equal_to;
     } busy_block;
     /* Heap information for a free block (that may be the first of a free cluster).  */
index 0f17fcc..9788f9f 100644 (file)
 #include <windows.h>
 #endif
 
+//Freebsd doesn't provide this clock_gettime flag yet, because it was added too recently (after 1993)
+#ifdef __FreeBSD__
+#define CLOCK_PROCESS_CPUTTIME_ID CLOCK_PROF
+#endif
+
 double xbt_os_time(void)
 {
 #ifdef HAVE_GETTIMEOFDAY
index a6a544b..e74b5a5 100644 (file)
@@ -11,17 +11,23 @@ if(enable_smpi)
   
   include_directories("${CMAKE_HOME_DIRECTORY}/include/smpi")
 
-  add_executable(alltoall2 alltoall2.c )
+  add_executable(allgather_coll allgather_coll.c)
+  add_executable(allgatherv_coll allgatherv_coll.c)
+  add_executable(alltoall2 alltoall2.c)
   add_executable(alltoall_basic alltoall_basic.c)
-  add_executable(alltoallv alltoallv.c)
+  add_executable(alltoall_coll alltoall_coll.c)
+  add_executable(alltoallv_coll alltoallv_coll.c)
   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(compute compute.c)
   add_executable(compute2 compute2.c)
   add_executable(compute3 compute3.c)
   add_executable(pingpong pingpong.c)
   add_executable(scatter scatter.c)
   add_executable(reduce reduce.c)
+  add_executable(reduce_coll reduce_coll.c)
   add_executable(split split.c)
   add_executable(smpi_sendrecv sendrecv.c)
   add_executable(ttest01 ttest01.c)
@@ -30,30 +36,36 @@ if(enable_smpi)
   add_executable(indexed_test indexed_test.c)
   add_executable(struct_test struct_test.c)
 
-  target_link_libraries(alltoall2 simgrid smpi )
-  target_link_libraries(alltoall_basic simgrid smpi )
-  target_link_libraries(alltoallv simgrid smpi )
-  target_link_libraries(allreduce simgrid smpi )
-  target_link_libraries(bcast simgrid smpi )
-  target_link_libraries(compute simgrid smpi )
-  target_link_libraries(compute2 simgrid smpi )
-  target_link_libraries(compute3 simgrid smpi )
-  target_link_libraries(pingpong simgrid smpi )
-  target_link_libraries(scatter simgrid smpi )
-  target_link_libraries(reduce simgrid smpi )
-  target_link_libraries(split simgrid smpi )
-  target_link_libraries(smpi_sendrecv simgrid smpi )
-  target_link_libraries(ttest01 simgrid smpi )
-  target_link_libraries(vector_test simgrid smpi )
-  target_link_libraries(hvector_test simgrid smpi )
-  target_link_libraries(indexed_test simgrid smpi )
-  target_link_libraries(struct_test simgrid smpi )
+  target_link_libraries(allgather_coll simgrid)
+  target_link_libraries(allgatherv_coll simgrid)
+  target_link_libraries(alltoall2 simgrid)
+  target_link_libraries(alltoall_basic simgrid)
+  target_link_libraries(alltoall_coll simgrid)
+  target_link_libraries(alltoallv_coll simgrid)
+  target_link_libraries(allreduce simgrid)
+  target_link_libraries(allreduce_coll simgrid)      
+  target_link_libraries(bcast simgrid)
+  target_link_libraries(bcast_coll simgrid)      
+  target_link_libraries(compute simgrid)
+  target_link_libraries(compute2 simgrid)
+  target_link_libraries(compute3 simgrid)
+  target_link_libraries(pingpong simgrid)
+  target_link_libraries(scatter simgrid)
+  target_link_libraries(reduce simgrid)
+  target_link_libraries(reduce_coll simgrid)      
+  target_link_libraries(split simgrid)
+  target_link_libraries(smpi_sendrecv simgrid)
+  target_link_libraries(ttest01 simgrid)
+  target_link_libraries(vector_test simgrid)
+  target_link_libraries(hvector_test simgrid)
+  target_link_libraries(indexed_test simgrid)
+  target_link_libraries(struct_test simgrid)
 
   set_target_properties(smpi_sendrecv PROPERTIES RENAME sendrecv)
 
   if(NOT WIN32)
     add_executable(dsend dsend.c)
-    target_link_libraries(dsend m simgrid smpi )
+    target_link_libraries(dsend m simgrid)
   endif()
 
 endif()
@@ -61,12 +73,19 @@ endif()
 
 set(tesh_files
   ${tesh_files}
+  ${CMAKE_CURRENT_SOURCE_DIR}/allgather_coll.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/allgatherv_coll.tesh  
+  ${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}/bcast.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/bcast_coll.tesh  
   ${CMAKE_CURRENT_SOURCE_DIR}/compute.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/hvector.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/indexed.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/pt2pt.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/reduce.tesh
+  ${CMAKE_CURRENT_SOURCE_DIR}/reduce_coll.tesh  
   ${CMAKE_CURRENT_SOURCE_DIR}/struct.tesh
   ${CMAKE_CURRENT_SOURCE_DIR}/vector.tesh  
   PARENT_SCOPE
@@ -77,7 +96,14 @@ set(xml_files
   )
 set(examples_src
   ${examples_src}
-  ${CMAKE_CURRENT_SOURCE_DIR}/alltoallv.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/allgather_coll.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/allgatherv_coll.c  
+  ${CMAKE_CURRENT_SOURCE_DIR}/allreduce_coll.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/alltoall_coll.c
+  ${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}/alltoallv_coll.c
   ${CMAKE_CURRENT_SOURCE_DIR}/get_processor_name.c
   ${CMAKE_CURRENT_SOURCE_DIR}/pingpong.c
   ${CMAKE_CURRENT_SOURCE_DIR}/bcast.c
diff --git a/teshsuite/smpi/allgather_coll.c b/teshsuite/smpi/allgather_coll.c
new file mode 100644 (file)
index 0000000..dfc7769
--- /dev/null
@@ -0,0 +1,62 @@
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "mpi.h"
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+int main(int argc, char *argv[])
+{
+  int rank, size;
+  int i;
+  int *sb;
+  int *rb;
+  int status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  int count = 2;
+  sb = (int *) xbt_malloc(count * sizeof(int));
+  rb = (int *) xbt_malloc(count * size * sizeof(int));
+  
+  for (i = 0; i < count; ++i)
+    sb[i] = rank * count + i;
+  for (i = 0; i < count * size; ++i)  
+    rb[i] = 0;
+
+  printf("[%d] sndbuf=[", rank);
+  for (i = 0; i < count; i++)
+    printf("%d ", sb[i]);
+  printf("]\n");
+
+  status = MPI_Allgather(sb, count, MPI_INT, rb, count, MPI_INT, MPI_COMM_WORLD);
+
+  printf("[%d] rcvbuf=[", rank);
+  for (i = 0; i < count * size; i++)
+    printf("%d ", rb[i]);
+  printf("]\n");
+
+
+  if (rank == 0) {
+    if (status != MPI_SUCCESS) {
+      printf("allgather returned %d\n", status);
+      fflush(stdout);
+    }
+  }
+  free(sb);
+  free(rb);
+  MPI_Finalize();
+  return (EXIT_SUCCESS);
+}
diff --git a/teshsuite/smpi/allgather_coll.tesh b/teshsuite/smpi/allgather_coll.tesh
new file mode 100644 (file)
index 0000000..2ff7d58
--- /dev/null
@@ -0,0 +1,57 @@
+# Smpi Alltoall collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test all to all
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./allgather_coll
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [1] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [2] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [3] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [4] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [5] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [6] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [7] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [8] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [9] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [10] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [11] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [12] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [13] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [14] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [15] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [0] sndbuf=[0 1 ]
+> [1] sndbuf=[2 3 ]
+> [2] sndbuf=[4 5 ]
+> [3] sndbuf=[6 7 ]
+> [4] sndbuf=[8 9 ]
+> [5] sndbuf=[10 11 ]
+> [6] sndbuf=[12 13 ]
+> [7] sndbuf=[14 15 ]
+> [8] sndbuf=[16 17 ]
+> [9] sndbuf=[18 19 ]
+> [10] sndbuf=[20 21 ]
+> [11] sndbuf=[22 23 ]
+> [12] sndbuf=[24 25 ]
+> [13] sndbuf=[26 27 ]
+> [14] sndbuf=[28 29 ]
+> [15] sndbuf=[30 31 ]
+
diff --git a/teshsuite/smpi/allgatherv_coll.c b/teshsuite/smpi/allgatherv_coll.c
new file mode 100644 (file)
index 0000000..2d8c87f
--- /dev/null
@@ -0,0 +1,74 @@
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "mpi.h"
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+int main(int argc, char *argv[])
+{
+  int rank, size;
+  int i;
+  int *sb;
+  int *rb;
+  int *recv_counts;
+  int *recv_disps;
+  int recv_sb_size;
+  int status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  recv_counts = (int *) xbt_malloc(size * sizeof(int));
+  recv_disps = (int *) xbt_malloc(size * sizeof(int));
+  
+  recv_sb_size = 0;
+  for (i = 0; i < size; i++) {
+    recv_counts[i] = i + 1;
+    recv_disps[i] = recv_sb_size;    
+    recv_sb_size += i + 1;
+  }
+
+  sb = (int *) xbt_malloc(recv_counts[rank] * sizeof(int));
+  rb = (int *) xbt_malloc(recv_sb_size * sizeof(int));
+
+  for (i = 0; i < recv_counts[rank]; ++i)
+    sb[i] = recv_disps[rank] + i;
+  for (i = 0; i < recv_sb_size; ++i)  
+    rb[i] = -1;
+
+  printf("[%d] sndbuf=[", rank);
+  for (i = 0; i < recv_counts[rank]; i++)
+    printf("%d ", sb[i]);
+  printf("]\n");
+
+  status = MPI_Allgatherv(sb, recv_counts[rank], MPI_INT, rb, recv_counts, recv_disps, MPI_INT, MPI_COMM_WORLD);
+
+  printf("[%d] rcvbuf=[", rank);
+  for (i = 0; i < recv_sb_size; i++)
+    printf("%d ", rb[i]);
+  printf("]\n");
+
+
+  if (rank == 0) {
+    if (status != MPI_SUCCESS) {
+      printf("allgatherv returned %d\n", status);
+      fflush(stdout);
+    }
+  }
+  free(sb);
+  free(rb);
+  MPI_Finalize();
+  return (EXIT_SUCCESS);
+}
diff --git a/teshsuite/smpi/allgatherv_coll.tesh b/teshsuite/smpi/allgatherv_coll.tesh
new file mode 100644 (file)
index 0000000..520004a
--- /dev/null
@@ -0,0 +1,56 @@
+# Smpi Allgatherv collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test allgatherv
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./allgatherv_coll
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] sndbuf=[0 ]
+> [1] sndbuf=[1 2 ]
+> [2] sndbuf=[3 4 5 ]
+> [3] sndbuf=[6 7 8 9 ]
+> [4] sndbuf=[10 11 12 13 14 ]
+> [5] sndbuf=[15 16 17 18 19 20 ]
+> [6] sndbuf=[21 22 23 24 25 26 27 ]
+> [7] sndbuf=[28 29 30 31 32 33 34 35 ]
+> [8] sndbuf=[36 37 38 39 40 41 42 43 44 ]
+> [9] sndbuf=[45 46 47 48 49 50 51 52 53 54 ]
+> [10] sndbuf=[55 56 57 58 59 60 61 62 63 64 65 ]
+> [11] sndbuf=[66 67 68 69 70 71 72 73 74 75 76 77 ]
+> [12] sndbuf=[78 79 80 81 82 83 84 85 86 87 88 89 90 ]
+> [13] sndbuf=[91 92 93 94 95 96 97 98 99 100 101 102 103 104 ]
+> [14] sndbuf=[105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ]
+> [15] sndbuf=[120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [0] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [1] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [2] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [3] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [4] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [5] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [6] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [7] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [8] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [9] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [10] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [11] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [12] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [13] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [14] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
+> [15] rcvbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 ]
diff --git a/teshsuite/smpi/allreduce_coll.c b/teshsuite/smpi/allreduce_coll.c
new file mode 100644 (file)
index 0000000..a2c9921
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "mpi.h"
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+int main(int argc, char *argv[])
+{
+  int rank, size;
+  int i;
+  int *sb;
+  int *rb;
+  int status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  sb = (int *) xbt_malloc(size * sizeof(int));
+  rb = (int *) xbt_malloc(size * sizeof(int));
+  
+  for (i = 0; i < size; ++i) {
+    sb[i] = rank*size + i;
+    rb[i] = 0;
+  }
+
+  printf("[%d] sndbuf=[", rank);
+  for (i = 0; i < size; i++)
+    printf("%d ", sb[i]);
+  printf("]\n");
+
+  status = MPI_Allreduce(sb, rb, size, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+
+  printf("[%d] rcvbuf=[", rank);
+  for (i = 0; i < size; i++)
+    printf("%d ", rb[i]);
+  printf("]\n");
+
+
+  if (rank == 0) {
+    if (status != MPI_SUCCESS) {
+      printf("all_to_all returned %d\n", status);
+      fflush(stdout);
+    }
+  }
+  free(sb);
+  free(rb);
+  MPI_Finalize();
+  return (EXIT_SUCCESS);
+}
diff --git a/teshsuite/smpi/allreduce_coll.tesh b/teshsuite/smpi/allreduce_coll.tesh
new file mode 100644 (file)
index 0000000..8cde55d
--- /dev/null
@@ -0,0 +1,57 @@
+# Smpi Allreduce collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test allreduce
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./allreduce_coll
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ]
+> [1] sndbuf=[16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [2] sndbuf=[32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ]
+> [3] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 ]
+> [4] sndbuf=[64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ]
+> [5] sndbuf=[80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 ]
+> [6] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ]
+> [7] sndbuf=[112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 ]
+> [8] sndbuf=[128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 ]
+> [9] sndbuf=[144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ]
+> [10] sndbuf=[160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 ]
+> [11] sndbuf=[176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 ]
+> [12] sndbuf=[192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ]
+> [13] sndbuf=[208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 ]
+> [14] sndbuf=[224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 ]
+> [15] sndbuf=[240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 ]
+> [0] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [1] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [2] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [3] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [4] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [5] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [6] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [7] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [8] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [9] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [10] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [11] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [12] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [13] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [14] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+> [15] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
+
index ad25e7a..869dd7c 100644 (file)
@@ -44,6 +44,7 @@ int main(int argc, char *argv[])
     sb[i] = rank + 1;
     rb[i] = 0;
   }
+
   status = MPI_Alltoall(sb, 1, MPI_INT, rb, 1, MPI_INT, MPI_COMM_WORLD);
 
   printf("[%d] rcvbuf=[", rank);
@@ -53,7 +54,7 @@ int main(int argc, char *argv[])
 
 
   if (rank == 0) {
-    if (status != 0) {
+    if (status != MPI_SUCCESS) {
       printf("all_to_all returned %d\n", status);
       fflush(stdout);
     }
diff --git a/teshsuite/smpi/alltoall_coll.c b/teshsuite/smpi/alltoall_coll.c
new file mode 100644 (file)
index 0000000..4c95ba3
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "mpi.h"
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+int main(int argc, char *argv[])
+{
+  int rank, size;
+  int i;
+  int *sb;
+  int *rb;
+  int status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  sb = (int *) xbt_malloc(size * sizeof(int) * 2);
+  rb = (int *) xbt_malloc(size * sizeof(int) * 2);
+  
+  for (i = 0; i < size; ++i) {
+    sb[i] = rank*size + i;
+    rb[i] = 0;
+  }
+
+  printf("[%d] sndbuf=[", rank);
+  for (i = 0; i < size; i++)
+    printf("%d ", sb[i]);
+  printf("]\n");
+
+  status = MPI_Alltoall(sb, 1, MPI_INT, rb, 1, MPI_INT, MPI_COMM_WORLD);
+
+  printf("[%d] rcvbuf=[", rank);
+  for (i = 0; i < size; i++)
+    printf("%d ", rb[i]);
+  printf("]\n");
+
+
+  if (rank == 0) {
+    if (status != MPI_SUCCESS) {
+      printf("all_to_all returned %d\n", status);
+      fflush(stdout);
+    }
+  }
+  free(sb);
+  free(rb);
+  MPI_Finalize();
+  return (EXIT_SUCCESS);
+}
diff --git a/teshsuite/smpi/alltoall_coll.tesh b/teshsuite/smpi/alltoall_coll.tesh
new file mode 100644 (file)
index 0000000..0cab7ea
--- /dev/null
@@ -0,0 +1,57 @@
+# Smpi Alltoall collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test all to all
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./alltoall_coll -q
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ]
+> [1] sndbuf=[16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [2] sndbuf=[32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ]
+> [3] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 ]
+> [4] sndbuf=[64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ]
+> [5] sndbuf=[80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 ]
+> [6] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ]
+> [7] sndbuf=[112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 ]
+> [8] sndbuf=[128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 ]
+> [9] sndbuf=[144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ]
+> [10] sndbuf=[160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 ]
+> [11] sndbuf=[176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 ]
+> [12] sndbuf=[192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ]
+> [13] sndbuf=[208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 ]
+> [14] sndbuf=[224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 ]
+> [15] sndbuf=[240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 ]
+> [0] rcvbuf=[0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 ]
+> [1] rcvbuf=[1 17 33 49 65 81 97 113 129 145 161 177 193 209 225 241 ]
+> [2] rcvbuf=[2 18 34 50 66 82 98 114 130 146 162 178 194 210 226 242 ]
+> [3] rcvbuf=[3 19 35 51 67 83 99 115 131 147 163 179 195 211 227 243 ]
+> [4] rcvbuf=[4 20 36 52 68 84 100 116 132 148 164 180 196 212 228 244 ]
+> [5] rcvbuf=[5 21 37 53 69 85 101 117 133 149 165 181 197 213 229 245 ]
+> [6] rcvbuf=[6 22 38 54 70 86 102 118 134 150 166 182 198 214 230 246 ]
+> [7] rcvbuf=[7 23 39 55 71 87 103 119 135 151 167 183 199 215 231 247 ]
+> [8] rcvbuf=[8 24 40 56 72 88 104 120 136 152 168 184 200 216 232 248 ]
+> [9] rcvbuf=[9 25 41 57 73 89 105 121 137 153 169 185 201 217 233 249 ]
+> [10] rcvbuf=[10 26 42 58 74 90 106 122 138 154 170 186 202 218 234 250 ]
+> [11] rcvbuf=[11 27 43 59 75 91 107 123 139 155 171 187 203 219 235 251 ]
+> [12] rcvbuf=[12 28 44 60 76 92 108 124 140 156 172 188 204 220 236 252 ]
+> [13] rcvbuf=[13 29 45 61 77 93 109 125 141 157 173 189 205 221 237 253 ]
+> [14] rcvbuf=[14 30 46 62 78 94 110 126 142 158 174 190 206 222 238 254 ]
+> [15] rcvbuf=[15 31 47 63 79 95 111 127 143 159 175 191 207 223 239 255 ]
+
similarity index 52%
rename from teshsuite/smpi/alltoallv.c
rename to teshsuite/smpi/alltoallv_coll.c
index f2717b9..0b4c71b 100644 (file)
    <2> rdisp: (#3):  [0][2][4]
 
    after MPI_Alltoallv :
-   <0> rbuf: (#9):   [0][-1][-2][-3][-4][-5][-6][-7][-8]
-   <1> rbuf: (#9):   [1][101][201][-3][-4][-5][-6][-7][-8]
-   <2> rbuf: (#9):   [3][4][103][104][203][204][-6][-7][-8]
+   <0> rbuf: (#9):   [-1][-1][-1][-1][-1][-1][-1][-1][-1]
+   <1> rbuf: (#9):   [1][101][201][-1][-1][-1][-1][-1][-1]
+   <2> rbuf: (#9):   [3][4][103][104][203][204][-1][-1][-1]
 */
 
 
 static void print_buffer_int(void *buf, int len, char *msg, int rank)
 {
   int tmp, *v;
-  printf("**<%d> %s (#%d): ", rank, msg, len);
+  printf("[%d] %s (#%d): ", rank, msg, len);
   for (tmp = 0; tmp < len; tmp++) {
     v = buf;
     printf("[%d]", v[tmp]);
@@ -67,96 +67,53 @@ int main(int argc, char **argv)
 {
 
   MPI_Comm comm;
-  int *sbuf, *rbuf, *erbuf;
+  int *sbuf, *rbuf;
   int rank, size;
   int *sendcounts, *recvcounts, *rdispls, *sdispls;
-  int i, j, *p, err;
+  int i;
 
   MPI_Init(&argc, &argv);
-  err = 0;
 
   comm = MPI_COMM_WORLD;
 
   /* Create the buffer */
   MPI_Comm_size(comm, &size);
   MPI_Comm_rank(comm, &rank);
-  sbuf = (int *) malloc(size * size * sizeof(int));
-  rbuf = (int *) malloc(size * size * sizeof(int));
-  erbuf = (int *) malloc(size * size * sizeof(int));    // expected
-  if (!sbuf || !rbuf) {
-    fprintf(stderr, "Could not allocated buffers!\n");
-    MPI_Abort(comm, 1);
-  }
+  sbuf = (int *) xbt_malloc(size * size * sizeof(int));
+  rbuf = (int *) xbt_malloc(size * size * sizeof(int));
 
   /* Load up the buffers */
   for (i = 0; i < size * size; i++) {
     sbuf[i] = i + 100 * rank;
-    rbuf[i] = -i;
-    erbuf[i] = -i;
+    rbuf[i] = -1;
   }
 
   /* Create and load the arguments to alltoallv */
-  sendcounts = (int *) malloc(size * sizeof(int));
-  recvcounts = (int *) malloc(size * sizeof(int));
-  rdispls = (int *) malloc(size * sizeof(int));
-  sdispls = (int *) malloc(size * sizeof(int));
-  if (!sendcounts || !recvcounts || !rdispls || !sdispls) {
-    fprintf(stderr, "Could not allocate arg items!\n");
-    MPI_Abort(comm, 1);
-  }
+  sendcounts = (int *) xbt_malloc(size * sizeof(int));
+  recvcounts = (int *) xbt_malloc(size * sizeof(int));
+  rdispls = (int *) xbt_malloc(size * sizeof(int));
+  sdispls = (int *) xbt_malloc(size * sizeof(int));
   for (i = 0; i < size; i++) {
     sendcounts[i] = i;
     recvcounts[i] = rank;
     rdispls[i] = i * rank;
     sdispls[i] = (i * (i + 1)) / 2;
   }
-
-  /* debug */
-  /* 
-     print_buffer_int( sbuf, size*size, strdup("sbuf:"),rank);
-     print_buffer_int( sendcounts, size, strdup("scount:"),rank);
-     print_buffer_int( recvcounts, size, strdup("rcount:"),rank);
-     print_buffer_int( sdispls, size, strdup("sdisp:"),rank);
-     print_buffer_int( rdispls, size, strdup("rdisp:"),rank);
-   */
-
-
-  /* debug : erbuf */
-  /* debug
-     for (i=0; i<size; i++) {
-     for (j=0; j<rank; j++) {
-     *(erbuf+j+ rdispls[i]) = i * 100 + (rank*(rank+1))/2 + j; 
-     }
-     }
-   */
-
-
-  //print_buffer_int( erbuf, size*size, strdup("erbuf:"),rank);
-
+  print_buffer_int( sbuf, size*size, strdup("sbuf:"),rank);
+  print_buffer_int( sendcounts, size, strdup("scount:"),rank);
+  print_buffer_int( recvcounts, size, strdup("rcount:"),rank);
+  print_buffer_int( sdispls, size, strdup("sdisp:"),rank);
+  print_buffer_int( rdispls, size, strdup("rdisp:"),rank);
+   
   MPI_Alltoallv(sbuf, sendcounts, sdispls, MPI_INT,
                 rbuf, recvcounts, rdispls, MPI_INT, comm);
 
-  // debug: print_buffer_int( rbuf, size*size, strdup("rbuf:"),rank);
-
-
-  /* Check rbuf */
-  for (i = 0; i < size; i++) {
-    p = rbuf + rdispls[i];
-    for (j = 0; j < rank; j++) {
-      if (p[j] != i * 100 + (rank * (rank + 1)) / 2 + j) {
-        fprintf(stderr, "** Error: <%d> got %d expected %d for %dth\n",
-                rank, p[j], (i * (i + 1)) / 2 + j, j);
-        err++;
-      }
-    }
-  }
+  print_buffer_int( rbuf, size*size, strdup("rbuf:"),rank);
 
-  /* Summary */
-  if (err > 0) {
-    printf("<%d> Alltoallv test: failure (%d errors).\n", rank, err);
-  }
+  MPI_Barrier(MPI_COMM_WORLD);  
   if (0 == rank) {
-    printf("Alltoallv TEST COMPLETE.\n");
+    printf("Alltoallv TEST COMPLETE.\n");
   }
   free(sdispls);
   free(rdispls);
@@ -165,7 +122,6 @@ int main(int argc, char **argv)
   free(rbuf);
   free(sbuf);
 
-  MPI_Barrier(MPI_COMM_WORLD);
   MPI_Finalize();
   return 0;
 }
diff --git a/teshsuite/smpi/alltoallv_coll.tesh b/teshsuite/smpi/alltoallv_coll.tesh
new file mode 100644 (file)
index 0000000..9b432f1
--- /dev/null
@@ -0,0 +1,123 @@
+# Smpi Alltoall collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test all to all
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./alltoallv_coll
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] rbuf: (#256): [-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [0] rcount: (#16): [0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
+> [0] rdisp: (#16): [0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
+> [0] sbuf: (#256): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31][32][33][34][35][36][37][38][39][40][41][42][43][44][45][46][47][48][49][50][51][52][53][54][55][56][57][58][59][60][61][62][63][64][65][66][67][68][69][70][71][72][73][74][75][76][77][78][79][80][81][82][83][84][85][86][87][88][89][90][91][92][93][94][95][96][97][98][99][100][101][102][103][104][105][106][107][108][109][110][111][112][113][114][115][116][117][118][119][120][121][122][123][124][125][126][127][128][129][130][131][132][133][134][135][136][137][138][139][140][141][142][143][144][145][146][147][148][149][150][151][152][153][154][155][156][157][158][159][160][161][162][163][164][165][166][167][168][169][170][171][172][173][174][175][176][177][178][179][180][181][182][183][184][185][186][187][188][189][190][191][192][193][194][195][196][197][198][199][200][201][202][203][204][205][206][207][208][209][210][211][212][213][214][215][216][217][218][219][220][221][222][223][224][225][226][227][228][229][230][231][232][233][234][235][236][237][238][239][240][241][242][243][244][245][246][247][248][249][250][251][252][253][254][255]
+> [0] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [0] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [1] rbuf: (#256): [1][101][201][301][401][501][601][701][801][901][1001][1101][1201][1301][1401][1501][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [1] rcount: (#16): [1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]
+> [1] rdisp: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [1] sbuf: (#256): [100][101][102][103][104][105][106][107][108][109][110][111][112][113][114][115][116][117][118][119][120][121][122][123][124][125][126][127][128][129][130][131][132][133][134][135][136][137][138][139][140][141][142][143][144][145][146][147][148][149][150][151][152][153][154][155][156][157][158][159][160][161][162][163][164][165][166][167][168][169][170][171][172][173][174][175][176][177][178][179][180][181][182][183][184][185][186][187][188][189][190][191][192][193][194][195][196][197][198][199][200][201][202][203][204][205][206][207][208][209][210][211][212][213][214][215][216][217][218][219][220][221][222][223][224][225][226][227][228][229][230][231][232][233][234][235][236][237][238][239][240][241][242][243][244][245][246][247][248][249][250][251][252][253][254][255][256][257][258][259][260][261][262][263][264][265][266][267][268][269][270][271][272][273][274][275][276][277][278][279][280][281][282][283][284][285][286][287][288][289][290][291][292][293][294][295][296][297][298][299][300][301][302][303][304][305][306][307][308][309][310][311][312][313][314][315][316][317][318][319][320][321][322][323][324][325][326][327][328][329][330][331][332][333][334][335][336][337][338][339][340][341][342][343][344][345][346][347][348][349][350][351][352][353][354][355]
+> [1] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [1] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [2] rbuf: (#256): [3][4][103][104][203][204][303][304][403][404][503][504][603][604][703][704][803][804][903][904][1003][1004][1103][1104][1203][1204][1303][1304][1403][1404][1503][1504][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [2] rcount: (#16): [2][2][2][2][2][2][2][2][2][2][2][2][2][2][2][2]
+> [2] rdisp: (#16): [0][2][4][6][8][10][12][14][16][18][20][22][24][26][28][30]
+> [2] sbuf: (#256): [200][201][202][203][204][205][206][207][208][209][210][211][212][213][214][215][216][217][218][219][220][221][222][223][224][225][226][227][228][229][230][231][232][233][234][235][236][237][238][239][240][241][242][243][244][245][246][247][248][249][250][251][252][253][254][255][256][257][258][259][260][261][262][263][264][265][266][267][268][269][270][271][272][273][274][275][276][277][278][279][280][281][282][283][284][285][286][287][288][289][290][291][292][293][294][295][296][297][298][299][300][301][302][303][304][305][306][307][308][309][310][311][312][313][314][315][316][317][318][319][320][321][322][323][324][325][326][327][328][329][330][331][332][333][334][335][336][337][338][339][340][341][342][343][344][345][346][347][348][349][350][351][352][353][354][355][356][357][358][359][360][361][362][363][364][365][366][367][368][369][370][371][372][373][374][375][376][377][378][379][380][381][382][383][384][385][386][387][388][389][390][391][392][393][394][395][396][397][398][399][400][401][402][403][404][405][406][407][408][409][410][411][412][413][414][415][416][417][418][419][420][421][422][423][424][425][426][427][428][429][430][431][432][433][434][435][436][437][438][439][440][441][442][443][444][445][446][447][448][449][450][451][452][453][454][455]
+> [2] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [2] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [3] rbuf: (#256): [6][7][8][106][107][108][206][207][208][306][307][308][406][407][408][506][507][508][606][607][608][706][707][708][806][807][808][906][907][908][1006][1007][1008][1106][1107][1108][1206][1207][1208][1306][1307][1308][1406][1407][1408][1506][1507][1508][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [3] rcount: (#16): [3][3][3][3][3][3][3][3][3][3][3][3][3][3][3][3]
+> [3] rdisp: (#16): [0][3][6][9][12][15][18][21][24][27][30][33][36][39][42][45]
+> [3] sbuf: (#256): [300][301][302][303][304][305][306][307][308][309][310][311][312][313][314][315][316][317][318][319][320][321][322][323][324][325][326][327][328][329][330][331][332][333][334][335][336][337][338][339][340][341][342][343][344][345][346][347][348][349][350][351][352][353][354][355][356][357][358][359][360][361][362][363][364][365][366][367][368][369][370][371][372][373][374][375][376][377][378][379][380][381][382][383][384][385][386][387][388][389][390][391][392][393][394][395][396][397][398][399][400][401][402][403][404][405][406][407][408][409][410][411][412][413][414][415][416][417][418][419][420][421][422][423][424][425][426][427][428][429][430][431][432][433][434][435][436][437][438][439][440][441][442][443][444][445][446][447][448][449][450][451][452][453][454][455][456][457][458][459][460][461][462][463][464][465][466][467][468][469][470][471][472][473][474][475][476][477][478][479][480][481][482][483][484][485][486][487][488][489][490][491][492][493][494][495][496][497][498][499][500][501][502][503][504][505][506][507][508][509][510][511][512][513][514][515][516][517][518][519][520][521][522][523][524][525][526][527][528][529][530][531][532][533][534][535][536][537][538][539][540][541][542][543][544][545][546][547][548][549][550][551][552][553][554][555]
+> [3] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [3] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [4] rbuf: (#256): [10][11][12][13][110][111][112][113][210][211][212][213][310][311][312][313][410][411][412][413][510][511][512][513][610][611][612][613][710][711][712][713][810][811][812][813][910][911][912][913][1010][1011][1012][1013][1110][1111][1112][1113][1210][1211][1212][1213][1310][1311][1312][1313][1410][1411][1412][1413][1510][1511][1512][1513][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [4] rcount: (#16): [4][4][4][4][4][4][4][4][4][4][4][4][4][4][4][4]
+> [4] rdisp: (#16): [0][4][8][12][16][20][24][28][32][36][40][44][48][52][56][60]
+> [4] sbuf: (#256): [400][401][402][403][404][405][406][407][408][409][410][411][412][413][414][415][416][417][418][419][420][421][422][423][424][425][426][427][428][429][430][431][432][433][434][435][436][437][438][439][440][441][442][443][444][445][446][447][448][449][450][451][452][453][454][455][456][457][458][459][460][461][462][463][464][465][466][467][468][469][470][471][472][473][474][475][476][477][478][479][480][481][482][483][484][485][486][487][488][489][490][491][492][493][494][495][496][497][498][499][500][501][502][503][504][505][506][507][508][509][510][511][512][513][514][515][516][517][518][519][520][521][522][523][524][525][526][527][528][529][530][531][532][533][534][535][536][537][538][539][540][541][542][543][544][545][546][547][548][549][550][551][552][553][554][555][556][557][558][559][560][561][562][563][564][565][566][567][568][569][570][571][572][573][574][575][576][577][578][579][580][581][582][583][584][585][586][587][588][589][590][591][592][593][594][595][596][597][598][599][600][601][602][603][604][605][606][607][608][609][610][611][612][613][614][615][616][617][618][619][620][621][622][623][624][625][626][627][628][629][630][631][632][633][634][635][636][637][638][639][640][641][642][643][644][645][646][647][648][649][650][651][652][653][654][655]
+> [4] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [4] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [5] rbuf: (#256): [15][16][17][18][19][115][116][117][118][119][215][216][217][218][219][315][316][317][318][319][415][416][417][418][419][515][516][517][518][519][615][616][617][618][619][715][716][717][718][719][815][816][817][818][819][915][916][917][918][919][1015][1016][1017][1018][1019][1115][1116][1117][1118][1119][1215][1216][1217][1218][1219][1315][1316][1317][1318][1319][1415][1416][1417][1418][1419][1515][1516][1517][1518][1519][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [5] rcount: (#16): [5][5][5][5][5][5][5][5][5][5][5][5][5][5][5][5]
+> [5] rdisp: (#16): [0][5][10][15][20][25][30][35][40][45][50][55][60][65][70][75]
+> [5] sbuf: (#256): [500][501][502][503][504][505][506][507][508][509][510][511][512][513][514][515][516][517][518][519][520][521][522][523][524][525][526][527][528][529][530][531][532][533][534][535][536][537][538][539][540][541][542][543][544][545][546][547][548][549][550][551][552][553][554][555][556][557][558][559][560][561][562][563][564][565][566][567][568][569][570][571][572][573][574][575][576][577][578][579][580][581][582][583][584][585][586][587][588][589][590][591][592][593][594][595][596][597][598][599][600][601][602][603][604][605][606][607][608][609][610][611][612][613][614][615][616][617][618][619][620][621][622][623][624][625][626][627][628][629][630][631][632][633][634][635][636][637][638][639][640][641][642][643][644][645][646][647][648][649][650][651][652][653][654][655][656][657][658][659][660][661][662][663][664][665][666][667][668][669][670][671][672][673][674][675][676][677][678][679][680][681][682][683][684][685][686][687][688][689][690][691][692][693][694][695][696][697][698][699][700][701][702][703][704][705][706][707][708][709][710][711][712][713][714][715][716][717][718][719][720][721][722][723][724][725][726][727][728][729][730][731][732][733][734][735][736][737][738][739][740][741][742][743][744][745][746][747][748][749][750][751][752][753][754][755]
+> [5] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [5] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [6] rbuf: (#256): [21][22][23][24][25][26][121][122][123][124][125][126][221][222][223][224][225][226][321][322][323][324][325][326][421][422][423][424][425][426][521][522][523][524][525][526][621][622][623][624][625][626][721][722][723][724][725][726][821][822][823][824][825][826][921][922][923][924][925][926][1021][1022][1023][1024][1025][1026][1121][1122][1123][1124][1125][1126][1221][1222][1223][1224][1225][1226][1321][1322][1323][1324][1325][1326][1421][1422][1423][1424][1425][1426][1521][1522][1523][1524][1525][1526][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [6] rcount: (#16): [6][6][6][6][6][6][6][6][6][6][6][6][6][6][6][6]
+> [6] rdisp: (#16): [0][6][12][18][24][30][36][42][48][54][60][66][72][78][84][90]
+> [6] sbuf: (#256): [600][601][602][603][604][605][606][607][608][609][610][611][612][613][614][615][616][617][618][619][620][621][622][623][624][625][626][627][628][629][630][631][632][633][634][635][636][637][638][639][640][641][642][643][644][645][646][647][648][649][650][651][652][653][654][655][656][657][658][659][660][661][662][663][664][665][666][667][668][669][670][671][672][673][674][675][676][677][678][679][680][681][682][683][684][685][686][687][688][689][690][691][692][693][694][695][696][697][698][699][700][701][702][703][704][705][706][707][708][709][710][711][712][713][714][715][716][717][718][719][720][721][722][723][724][725][726][727][728][729][730][731][732][733][734][735][736][737][738][739][740][741][742][743][744][745][746][747][748][749][750][751][752][753][754][755][756][757][758][759][760][761][762][763][764][765][766][767][768][769][770][771][772][773][774][775][776][777][778][779][780][781][782][783][784][785][786][787][788][789][790][791][792][793][794][795][796][797][798][799][800][801][802][803][804][805][806][807][808][809][810][811][812][813][814][815][816][817][818][819][820][821][822][823][824][825][826][827][828][829][830][831][832][833][834][835][836][837][838][839][840][841][842][843][844][845][846][847][848][849][850][851][852][853][854][855]
+> [6] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [6] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [7] rbuf: (#256): [28][29][30][31][32][33][34][128][129][130][131][132][133][134][228][229][230][231][232][233][234][328][329][330][331][332][333][334][428][429][430][431][432][433][434][528][529][530][531][532][533][534][628][629][630][631][632][633][634][728][729][730][731][732][733][734][828][829][830][831][832][833][834][928][929][930][931][932][933][934][1028][1029][1030][1031][1032][1033][1034][1128][1129][1130][1131][1132][1133][1134][1228][1229][1230][1231][1232][1233][1234][1328][1329][1330][1331][1332][1333][1334][1428][1429][1430][1431][1432][1433][1434][1528][1529][1530][1531][1532][1533][1534][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [7] rcount: (#16): [7][7][7][7][7][7][7][7][7][7][7][7][7][7][7][7]
+> [7] rdisp: (#16): [0][7][14][21][28][35][42][49][56][63][70][77][84][91][98][105]
+> [7] sbuf: (#256): [700][701][702][703][704][705][706][707][708][709][710][711][712][713][714][715][716][717][718][719][720][721][722][723][724][725][726][727][728][729][730][731][732][733][734][735][736][737][738][739][740][741][742][743][744][745][746][747][748][749][750][751][752][753][754][755][756][757][758][759][760][761][762][763][764][765][766][767][768][769][770][771][772][773][774][775][776][777][778][779][780][781][782][783][784][785][786][787][788][789][790][791][792][793][794][795][796][797][798][799][800][801][802][803][804][805][806][807][808][809][810][811][812][813][814][815][816][817][818][819][820][821][822][823][824][825][826][827][828][829][830][831][832][833][834][835][836][837][838][839][840][841][842][843][844][845][846][847][848][849][850][851][852][853][854][855][856][857][858][859][860][861][862][863][864][865][866][867][868][869][870][871][872][873][874][875][876][877][878][879][880][881][882][883][884][885][886][887][888][889][890][891][892][893][894][895][896][897][898][899][900][901][902][903][904][905][906][907][908][909][910][911][912][913][914][915][916][917][918][919][920][921][922][923][924][925][926][927][928][929][930][931][932][933][934][935][936][937][938][939][940][941][942][943][944][945][946][947][948][949][950][951][952][953][954][955]
+> [7] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [7] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [8] rbuf: (#256): [36][37][38][39][40][41][42][43][136][137][138][139][140][141][142][143][236][237][238][239][240][241][242][243][336][337][338][339][340][341][342][343][436][437][438][439][440][441][442][443][536][537][538][539][540][541][542][543][636][637][638][639][640][641][642][643][736][737][738][739][740][741][742][743][836][837][838][839][840][841][842][843][936][937][938][939][940][941][942][943][1036][1037][1038][1039][1040][1041][1042][1043][1136][1137][1138][1139][1140][1141][1142][1143][1236][1237][1238][1239][1240][1241][1242][1243][1336][1337][1338][1339][1340][1341][1342][1343][1436][1437][1438][1439][1440][1441][1442][1443][1536][1537][1538][1539][1540][1541][1542][1543][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [8] rcount: (#16): [8][8][8][8][8][8][8][8][8][8][8][8][8][8][8][8]
+> [8] rdisp: (#16): [0][8][16][24][32][40][48][56][64][72][80][88][96][104][112][120]
+> [8] sbuf: (#256): [800][801][802][803][804][805][806][807][808][809][810][811][812][813][814][815][816][817][818][819][820][821][822][823][824][825][826][827][828][829][830][831][832][833][834][835][836][837][838][839][840][841][842][843][844][845][846][847][848][849][850][851][852][853][854][855][856][857][858][859][860][861][862][863][864][865][866][867][868][869][870][871][872][873][874][875][876][877][878][879][880][881][882][883][884][885][886][887][888][889][890][891][892][893][894][895][896][897][898][899][900][901][902][903][904][905][906][907][908][909][910][911][912][913][914][915][916][917][918][919][920][921][922][923][924][925][926][927][928][929][930][931][932][933][934][935][936][937][938][939][940][941][942][943][944][945][946][947][948][949][950][951][952][953][954][955][956][957][958][959][960][961][962][963][964][965][966][967][968][969][970][971][972][973][974][975][976][977][978][979][980][981][982][983][984][985][986][987][988][989][990][991][992][993][994][995][996][997][998][999][1000][1001][1002][1003][1004][1005][1006][1007][1008][1009][1010][1011][1012][1013][1014][1015][1016][1017][1018][1019][1020][1021][1022][1023][1024][1025][1026][1027][1028][1029][1030][1031][1032][1033][1034][1035][1036][1037][1038][1039][1040][1041][1042][1043][1044][1045][1046][1047][1048][1049][1050][1051][1052][1053][1054][1055]
+> [8] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [8] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [9] rbuf: (#256): [45][46][47][48][49][50][51][52][53][145][146][147][148][149][150][151][152][153][245][246][247][248][249][250][251][252][253][345][346][347][348][349][350][351][352][353][445][446][447][448][449][450][451][452][453][545][546][547][548][549][550][551][552][553][645][646][647][648][649][650][651][652][653][745][746][747][748][749][750][751][752][753][845][846][847][848][849][850][851][852][853][945][946][947][948][949][950][951][952][953][1045][1046][1047][1048][1049][1050][1051][1052][1053][1145][1146][1147][1148][1149][1150][1151][1152][1153][1245][1246][1247][1248][1249][1250][1251][1252][1253][1345][1346][1347][1348][1349][1350][1351][1352][1353][1445][1446][1447][1448][1449][1450][1451][1452][1453][1545][1546][1547][1548][1549][1550][1551][1552][1553][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [9] rcount: (#16): [9][9][9][9][9][9][9][9][9][9][9][9][9][9][9][9]
+> [9] rdisp: (#16): [0][9][18][27][36][45][54][63][72][81][90][99][108][117][126][135]
+> [9] sbuf: (#256): [900][901][902][903][904][905][906][907][908][909][910][911][912][913][914][915][916][917][918][919][920][921][922][923][924][925][926][927][928][929][930][931][932][933][934][935][936][937][938][939][940][941][942][943][944][945][946][947][948][949][950][951][952][953][954][955][956][957][958][959][960][961][962][963][964][965][966][967][968][969][970][971][972][973][974][975][976][977][978][979][980][981][982][983][984][985][986][987][988][989][990][991][992][993][994][995][996][997][998][999][1000][1001][1002][1003][1004][1005][1006][1007][1008][1009][1010][1011][1012][1013][1014][1015][1016][1017][1018][1019][1020][1021][1022][1023][1024][1025][1026][1027][1028][1029][1030][1031][1032][1033][1034][1035][1036][1037][1038][1039][1040][1041][1042][1043][1044][1045][1046][1047][1048][1049][1050][1051][1052][1053][1054][1055][1056][1057][1058][1059][1060][1061][1062][1063][1064][1065][1066][1067][1068][1069][1070][1071][1072][1073][1074][1075][1076][1077][1078][1079][1080][1081][1082][1083][1084][1085][1086][1087][1088][1089][1090][1091][1092][1093][1094][1095][1096][1097][1098][1099][1100][1101][1102][1103][1104][1105][1106][1107][1108][1109][1110][1111][1112][1113][1114][1115][1116][1117][1118][1119][1120][1121][1122][1123][1124][1125][1126][1127][1128][1129][1130][1131][1132][1133][1134][1135][1136][1137][1138][1139][1140][1141][1142][1143][1144][1145][1146][1147][1148][1149][1150][1151][1152][1153][1154][1155]
+> [9] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [9] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [10] rbuf: (#256): [55][56][57][58][59][60][61][62][63][64][155][156][157][158][159][160][161][162][163][164][255][256][257][258][259][260][261][262][263][264][355][356][357][358][359][360][361][362][363][364][455][456][457][458][459][460][461][462][463][464][555][556][557][558][559][560][561][562][563][564][655][656][657][658][659][660][661][662][663][664][755][756][757][758][759][760][761][762][763][764][855][856][857][858][859][860][861][862][863][864][955][956][957][958][959][960][961][962][963][964][1055][1056][1057][1058][1059][1060][1061][1062][1063][1064][1155][1156][1157][1158][1159][1160][1161][1162][1163][1164][1255][1256][1257][1258][1259][1260][1261][1262][1263][1264][1355][1356][1357][1358][1359][1360][1361][1362][1363][1364][1455][1456][1457][1458][1459][1460][1461][1462][1463][1464][1555][1556][1557][1558][1559][1560][1561][1562][1563][1564][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [10] rcount: (#16): [10][10][10][10][10][10][10][10][10][10][10][10][10][10][10][10]
+> [10] rdisp: (#16): [0][10][20][30][40][50][60][70][80][90][100][110][120][130][140][150]
+> [10] sbuf: (#256): [1000][1001][1002][1003][1004][1005][1006][1007][1008][1009][1010][1011][1012][1013][1014][1015][1016][1017][1018][1019][1020][1021][1022][1023][1024][1025][1026][1027][1028][1029][1030][1031][1032][1033][1034][1035][1036][1037][1038][1039][1040][1041][1042][1043][1044][1045][1046][1047][1048][1049][1050][1051][1052][1053][1054][1055][1056][1057][1058][1059][1060][1061][1062][1063][1064][1065][1066][1067][1068][1069][1070][1071][1072][1073][1074][1075][1076][1077][1078][1079][1080][1081][1082][1083][1084][1085][1086][1087][1088][1089][1090][1091][1092][1093][1094][1095][1096][1097][1098][1099][1100][1101][1102][1103][1104][1105][1106][1107][1108][1109][1110][1111][1112][1113][1114][1115][1116][1117][1118][1119][1120][1121][1122][1123][1124][1125][1126][1127][1128][1129][1130][1131][1132][1133][1134][1135][1136][1137][1138][1139][1140][1141][1142][1143][1144][1145][1146][1147][1148][1149][1150][1151][1152][1153][1154][1155][1156][1157][1158][1159][1160][1161][1162][1163][1164][1165][1166][1167][1168][1169][1170][1171][1172][1173][1174][1175][1176][1177][1178][1179][1180][1181][1182][1183][1184][1185][1186][1187][1188][1189][1190][1191][1192][1193][1194][1195][1196][1197][1198][1199][1200][1201][1202][1203][1204][1205][1206][1207][1208][1209][1210][1211][1212][1213][1214][1215][1216][1217][1218][1219][1220][1221][1222][1223][1224][1225][1226][1227][1228][1229][1230][1231][1232][1233][1234][1235][1236][1237][1238][1239][1240][1241][1242][1243][1244][1245][1246][1247][1248][1249][1250][1251][1252][1253][1254][1255]
+> [10] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [10] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [11] rbuf: (#256): [66][67][68][69][70][71][72][73][74][75][76][166][167][168][169][170][171][172][173][174][175][176][266][267][268][269][270][271][272][273][274][275][276][366][367][368][369][370][371][372][373][374][375][376][466][467][468][469][470][471][472][473][474][475][476][566][567][568][569][570][571][572][573][574][575][576][666][667][668][669][670][671][672][673][674][675][676][766][767][768][769][770][771][772][773][774][775][776][866][867][868][869][870][871][872][873][874][875][876][966][967][968][969][970][971][972][973][974][975][976][1066][1067][1068][1069][1070][1071][1072][1073][1074][1075][1076][1166][1167][1168][1169][1170][1171][1172][1173][1174][1175][1176][1266][1267][1268][1269][1270][1271][1272][1273][1274][1275][1276][1366][1367][1368][1369][1370][1371][1372][1373][1374][1375][1376][1466][1467][1468][1469][1470][1471][1472][1473][1474][1475][1476][1566][1567][1568][1569][1570][1571][1572][1573][1574][1575][1576][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [11] rcount: (#16): [11][11][11][11][11][11][11][11][11][11][11][11][11][11][11][11]
+> [11] rdisp: (#16): [0][11][22][33][44][55][66][77][88][99][110][121][132][143][154][165]
+> [11] sbuf: (#256): [1100][1101][1102][1103][1104][1105][1106][1107][1108][1109][1110][1111][1112][1113][1114][1115][1116][1117][1118][1119][1120][1121][1122][1123][1124][1125][1126][1127][1128][1129][1130][1131][1132][1133][1134][1135][1136][1137][1138][1139][1140][1141][1142][1143][1144][1145][1146][1147][1148][1149][1150][1151][1152][1153][1154][1155][1156][1157][1158][1159][1160][1161][1162][1163][1164][1165][1166][1167][1168][1169][1170][1171][1172][1173][1174][1175][1176][1177][1178][1179][1180][1181][1182][1183][1184][1185][1186][1187][1188][1189][1190][1191][1192][1193][1194][1195][1196][1197][1198][1199][1200][1201][1202][1203][1204][1205][1206][1207][1208][1209][1210][1211][1212][1213][1214][1215][1216][1217][1218][1219][1220][1221][1222][1223][1224][1225][1226][1227][1228][1229][1230][1231][1232][1233][1234][1235][1236][1237][1238][1239][1240][1241][1242][1243][1244][1245][1246][1247][1248][1249][1250][1251][1252][1253][1254][1255][1256][1257][1258][1259][1260][1261][1262][1263][1264][1265][1266][1267][1268][1269][1270][1271][1272][1273][1274][1275][1276][1277][1278][1279][1280][1281][1282][1283][1284][1285][1286][1287][1288][1289][1290][1291][1292][1293][1294][1295][1296][1297][1298][1299][1300][1301][1302][1303][1304][1305][1306][1307][1308][1309][1310][1311][1312][1313][1314][1315][1316][1317][1318][1319][1320][1321][1322][1323][1324][1325][1326][1327][1328][1329][1330][1331][1332][1333][1334][1335][1336][1337][1338][1339][1340][1341][1342][1343][1344][1345][1346][1347][1348][1349][1350][1351][1352][1353][1354][1355]
+> [11] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [11] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [12] rbuf: (#256): [78][79][80][81][82][83][84][85][86][87][88][89][178][179][180][181][182][183][184][185][186][187][188][189][278][279][280][281][282][283][284][285][286][287][288][289][378][379][380][381][382][383][384][385][386][387][388][389][478][479][480][481][482][483][484][485][486][487][488][489][578][579][580][581][582][583][584][585][586][587][588][589][678][679][680][681][682][683][684][685][686][687][688][689][778][779][780][781][782][783][784][785][786][787][788][789][878][879][880][881][882][883][884][885][886][887][888][889][978][979][980][981][982][983][984][985][986][987][988][989][1078][1079][1080][1081][1082][1083][1084][1085][1086][1087][1088][1089][1178][1179][1180][1181][1182][1183][1184][1185][1186][1187][1188][1189][1278][1279][1280][1281][1282][1283][1284][1285][1286][1287][1288][1289][1378][1379][1380][1381][1382][1383][1384][1385][1386][1387][1388][1389][1478][1479][1480][1481][1482][1483][1484][1485][1486][1487][1488][1489][1578][1579][1580][1581][1582][1583][1584][1585][1586][1587][1588][1589][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [12] rcount: (#16): [12][12][12][12][12][12][12][12][12][12][12][12][12][12][12][12]
+> [12] rdisp: (#16): [0][12][24][36][48][60][72][84][96][108][120][132][144][156][168][180]
+> [12] sbuf: (#256): [1200][1201][1202][1203][1204][1205][1206][1207][1208][1209][1210][1211][1212][1213][1214][1215][1216][1217][1218][1219][1220][1221][1222][1223][1224][1225][1226][1227][1228][1229][1230][1231][1232][1233][1234][1235][1236][1237][1238][1239][1240][1241][1242][1243][1244][1245][1246][1247][1248][1249][1250][1251][1252][1253][1254][1255][1256][1257][1258][1259][1260][1261][1262][1263][1264][1265][1266][1267][1268][1269][1270][1271][1272][1273][1274][1275][1276][1277][1278][1279][1280][1281][1282][1283][1284][1285][1286][1287][1288][1289][1290][1291][1292][1293][1294][1295][1296][1297][1298][1299][1300][1301][1302][1303][1304][1305][1306][1307][1308][1309][1310][1311][1312][1313][1314][1315][1316][1317][1318][1319][1320][1321][1322][1323][1324][1325][1326][1327][1328][1329][1330][1331][1332][1333][1334][1335][1336][1337][1338][1339][1340][1341][1342][1343][1344][1345][1346][1347][1348][1349][1350][1351][1352][1353][1354][1355][1356][1357][1358][1359][1360][1361][1362][1363][1364][1365][1366][1367][1368][1369][1370][1371][1372][1373][1374][1375][1376][1377][1378][1379][1380][1381][1382][1383][1384][1385][1386][1387][1388][1389][1390][1391][1392][1393][1394][1395][1396][1397][1398][1399][1400][1401][1402][1403][1404][1405][1406][1407][1408][1409][1410][1411][1412][1413][1414][1415][1416][1417][1418][1419][1420][1421][1422][1423][1424][1425][1426][1427][1428][1429][1430][1431][1432][1433][1434][1435][1436][1437][1438][1439][1440][1441][1442][1443][1444][1445][1446][1447][1448][1449][1450][1451][1452][1453][1454][1455]
+> [12] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [12] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [13] rbuf: (#256): [91][92][93][94][95][96][97][98][99][100][101][102][103][191][192][193][194][195][196][197][198][199][200][201][202][203][291][292][293][294][295][296][297][298][299][300][301][302][303][391][392][393][394][395][396][397][398][399][400][401][402][403][491][492][493][494][495][496][497][498][499][500][501][502][503][591][592][593][594][595][596][597][598][599][600][601][602][603][691][692][693][694][695][696][697][698][699][700][701][702][703][791][792][793][794][795][796][797][798][799][800][801][802][803][891][892][893][894][895][896][897][898][899][900][901][902][903][991][992][993][994][995][996][997][998][999][1000][1001][1002][1003][1091][1092][1093][1094][1095][1096][1097][1098][1099][1100][1101][1102][1103][1191][1192][1193][1194][1195][1196][1197][1198][1199][1200][1201][1202][1203][1291][1292][1293][1294][1295][1296][1297][1298][1299][1300][1301][1302][1303][1391][1392][1393][1394][1395][1396][1397][1398][1399][1400][1401][1402][1403][1491][1492][1493][1494][1495][1496][1497][1498][1499][1500][1501][1502][1503][1591][1592][1593][1594][1595][1596][1597][1598][1599][1600][1601][1602][1603][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [13] rcount: (#16): [13][13][13][13][13][13][13][13][13][13][13][13][13][13][13][13]
+> [13] rdisp: (#16): [0][13][26][39][52][65][78][91][104][117][130][143][156][169][182][195]
+> [13] sbuf: (#256): [1300][1301][1302][1303][1304][1305][1306][1307][1308][1309][1310][1311][1312][1313][1314][1315][1316][1317][1318][1319][1320][1321][1322][1323][1324][1325][1326][1327][1328][1329][1330][1331][1332][1333][1334][1335][1336][1337][1338][1339][1340][1341][1342][1343][1344][1345][1346][1347][1348][1349][1350][1351][1352][1353][1354][1355][1356][1357][1358][1359][1360][1361][1362][1363][1364][1365][1366][1367][1368][1369][1370][1371][1372][1373][1374][1375][1376][1377][1378][1379][1380][1381][1382][1383][1384][1385][1386][1387][1388][1389][1390][1391][1392][1393][1394][1395][1396][1397][1398][1399][1400][1401][1402][1403][1404][1405][1406][1407][1408][1409][1410][1411][1412][1413][1414][1415][1416][1417][1418][1419][1420][1421][1422][1423][1424][1425][1426][1427][1428][1429][1430][1431][1432][1433][1434][1435][1436][1437][1438][1439][1440][1441][1442][1443][1444][1445][1446][1447][1448][1449][1450][1451][1452][1453][1454][1455][1456][1457][1458][1459][1460][1461][1462][1463][1464][1465][1466][1467][1468][1469][1470][1471][1472][1473][1474][1475][1476][1477][1478][1479][1480][1481][1482][1483][1484][1485][1486][1487][1488][1489][1490][1491][1492][1493][1494][1495][1496][1497][1498][1499][1500][1501][1502][1503][1504][1505][1506][1507][1508][1509][1510][1511][1512][1513][1514][1515][1516][1517][1518][1519][1520][1521][1522][1523][1524][1525][1526][1527][1528][1529][1530][1531][1532][1533][1534][1535][1536][1537][1538][1539][1540][1541][1542][1543][1544][1545][1546][1547][1548][1549][1550][1551][1552][1553][1554][1555]
+> [13] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [13] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [14] rbuf: (#256): [105][106][107][108][109][110][111][112][113][114][115][116][117][118][205][206][207][208][209][210][211][212][213][214][215][216][217][218][305][306][307][308][309][310][311][312][313][314][315][316][317][318][405][406][407][408][409][410][411][412][413][414][415][416][417][418][505][506][507][508][509][510][511][512][513][514][515][516][517][518][605][606][607][608][609][610][611][612][613][614][615][616][617][618][705][706][707][708][709][710][711][712][713][714][715][716][717][718][805][806][807][808][809][810][811][812][813][814][815][816][817][818][905][906][907][908][909][910][911][912][913][914][915][916][917][918][1005][1006][1007][1008][1009][1010][1011][1012][1013][1014][1015][1016][1017][1018][1105][1106][1107][1108][1109][1110][1111][1112][1113][1114][1115][1116][1117][1118][1205][1206][1207][1208][1209][1210][1211][1212][1213][1214][1215][1216][1217][1218][1305][1306][1307][1308][1309][1310][1311][1312][1313][1314][1315][1316][1317][1318][1405][1406][1407][1408][1409][1410][1411][1412][1413][1414][1415][1416][1417][1418][1505][1506][1507][1508][1509][1510][1511][1512][1513][1514][1515][1516][1517][1518][1605][1606][1607][1608][1609][1610][1611][1612][1613][1614][1615][1616][1617][1618][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [14] rcount: (#16): [14][14][14][14][14][14][14][14][14][14][14][14][14][14][14][14]
+> [14] rdisp: (#16): [0][14][28][42][56][70][84][98][112][126][140][154][168][182][196][210]
+> [14] sbuf: (#256): [1400][1401][1402][1403][1404][1405][1406][1407][1408][1409][1410][1411][1412][1413][1414][1415][1416][1417][1418][1419][1420][1421][1422][1423][1424][1425][1426][1427][1428][1429][1430][1431][1432][1433][1434][1435][1436][1437][1438][1439][1440][1441][1442][1443][1444][1445][1446][1447][1448][1449][1450][1451][1452][1453][1454][1455][1456][1457][1458][1459][1460][1461][1462][1463][1464][1465][1466][1467][1468][1469][1470][1471][1472][1473][1474][1475][1476][1477][1478][1479][1480][1481][1482][1483][1484][1485][1486][1487][1488][1489][1490][1491][1492][1493][1494][1495][1496][1497][1498][1499][1500][1501][1502][1503][1504][1505][1506][1507][1508][1509][1510][1511][1512][1513][1514][1515][1516][1517][1518][1519][1520][1521][1522][1523][1524][1525][1526][1527][1528][1529][1530][1531][1532][1533][1534][1535][1536][1537][1538][1539][1540][1541][1542][1543][1544][1545][1546][1547][1548][1549][1550][1551][1552][1553][1554][1555][1556][1557][1558][1559][1560][1561][1562][1563][1564][1565][1566][1567][1568][1569][1570][1571][1572][1573][1574][1575][1576][1577][1578][1579][1580][1581][1582][1583][1584][1585][1586][1587][1588][1589][1590][1591][1592][1593][1594][1595][1596][1597][1598][1599][1600][1601][1602][1603][1604][1605][1606][1607][1608][1609][1610][1611][1612][1613][1614][1615][1616][1617][1618][1619][1620][1621][1622][1623][1624][1625][1626][1627][1628][1629][1630][1631][1632][1633][1634][1635][1636][1637][1638][1639][1640][1641][1642][1643][1644][1645][1646][1647][1648][1649][1650][1651][1652][1653][1654][1655]
+> [14] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [14] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> [15] rbuf: (#256): [120][121][122][123][124][125][126][127][128][129][130][131][132][133][134][220][221][222][223][224][225][226][227][228][229][230][231][232][233][234][320][321][322][323][324][325][326][327][328][329][330][331][332][333][334][420][421][422][423][424][425][426][427][428][429][430][431][432][433][434][520][521][522][523][524][525][526][527][528][529][530][531][532][533][534][620][621][622][623][624][625][626][627][628][629][630][631][632][633][634][720][721][722][723][724][725][726][727][728][729][730][731][732][733][734][820][821][822][823][824][825][826][827][828][829][830][831][832][833][834][920][921][922][923][924][925][926][927][928][929][930][931][932][933][934][1020][1021][1022][1023][1024][1025][1026][1027][1028][1029][1030][1031][1032][1033][1034][1120][1121][1122][1123][1124][1125][1126][1127][1128][1129][1130][1131][1132][1133][1134][1220][1221][1222][1223][1224][1225][1226][1227][1228][1229][1230][1231][1232][1233][1234][1320][1321][1322][1323][1324][1325][1326][1327][1328][1329][1330][1331][1332][1333][1334][1420][1421][1422][1423][1424][1425][1426][1427][1428][1429][1430][1431][1432][1433][1434][1520][1521][1522][1523][1524][1525][1526][1527][1528][1529][1530][1531][1532][1533][1534][1620][1621][1622][1623][1624][1625][1626][1627][1628][1629][1630][1631][1632][1633][1634][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1][-1]
+> [15] rcount: (#16): [15][15][15][15][15][15][15][15][15][15][15][15][15][15][15][15]
+> [15] rdisp: (#16): [0][15][30][45][60][75][90][105][120][135][150][165][180][195][210][225]
+> [15] sbuf: (#256): [1500][1501][1502][1503][1504][1505][1506][1507][1508][1509][1510][1511][1512][1513][1514][1515][1516][1517][1518][1519][1520][1521][1522][1523][1524][1525][1526][1527][1528][1529][1530][1531][1532][1533][1534][1535][1536][1537][1538][1539][1540][1541][1542][1543][1544][1545][1546][1547][1548][1549][1550][1551][1552][1553][1554][1555][1556][1557][1558][1559][1560][1561][1562][1563][1564][1565][1566][1567][1568][1569][1570][1571][1572][1573][1574][1575][1576][1577][1578][1579][1580][1581][1582][1583][1584][1585][1586][1587][1588][1589][1590][1591][1592][1593][1594][1595][1596][1597][1598][1599][1600][1601][1602][1603][1604][1605][1606][1607][1608][1609][1610][1611][1612][1613][1614][1615][1616][1617][1618][1619][1620][1621][1622][1623][1624][1625][1626][1627][1628][1629][1630][1631][1632][1633][1634][1635][1636][1637][1638][1639][1640][1641][1642][1643][1644][1645][1646][1647][1648][1649][1650][1651][1652][1653][1654][1655][1656][1657][1658][1659][1660][1661][1662][1663][1664][1665][1666][1667][1668][1669][1670][1671][1672][1673][1674][1675][1676][1677][1678][1679][1680][1681][1682][1683][1684][1685][1686][1687][1688][1689][1690][1691][1692][1693][1694][1695][1696][1697][1698][1699][1700][1701][1702][1703][1704][1705][1706][1707][1708][1709][1710][1711][1712][1713][1714][1715][1716][1717][1718][1719][1720][1721][1722][1723][1724][1725][1726][1727][1728][1729][1730][1731][1732][1733][1734][1735][1736][1737][1738][1739][1740][1741][1742][1743][1744][1745][1746][1747][1748][1749][1750][1751][1752][1753][1754][1755]
+> [15] scount: (#16): [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]
+> [15] sdisp: (#16): [0][1][3][6][10][15][21][28][36][45][55][66][78][91][105][120]
+> 
+> Alltoallv TEST COMPLETE.
+
diff --git a/teshsuite/smpi/bcast_coll.c b/teshsuite/smpi/bcast_coll.c
new file mode 100644 (file)
index 0000000..9bb6a04
--- /dev/null
@@ -0,0 +1,44 @@
+/* Copyright (c) 2009. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdio.h>
+#include <mpi.h>
+
+int main(int argc, char **argv)
+{
+  int i, size, rank;
+  int count = 2048;
+  int *values;
+  int status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  
+  values = (int *) xbt_malloc(count * sizeof(int));  
+
+  for (i = 0; i < count; i++)
+    values[i] = (0 == rank) ? 17 : 3;
+
+  status = MPI_Bcast(values, count, MPI_INT, 0, MPI_COMM_WORLD);
+
+  int good = 0;
+  for (i = 0; i < count; i++)
+    if (values[i]==17) good++;
+  printf("[%d] number of values equals to 17: %d\n", rank, good);
+
+  MPI_Barrier(MPI_COMM_WORLD);
+
+  if (rank == 0) {
+    if (status != MPI_SUCCESS) {
+      printf("bcast returned %d\n", status);
+      fflush(stdout);
+    }
+  }
+
+  MPI_Finalize();
+  return 0;
+}
diff --git a/teshsuite/smpi/bcast_coll.tesh b/teshsuite/smpi/bcast_coll.tesh
new file mode 100644 (file)
index 0000000..7dc08a5
--- /dev/null
@@ -0,0 +1,39 @@
+p Test Broadcast with more processes than hosts
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./bcast_coll
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] number of values equals to 17: 2048
+> [1] number of values equals to 17: 2048
+> [2] number of values equals to 17: 2048
+> [3] number of values equals to 17: 2048
+> [4] number of values equals to 17: 2048
+> [5] number of values equals to 17: 2048
+> [6] number of values equals to 17: 2048
+> [7] number of values equals to 17: 2048
+> [8] number of values equals to 17: 2048
+> [9] number of values equals to 17: 2048
+> [10] number of values equals to 17: 2048
+> [11] number of values equals to 17: 2048
+> [12] number of values equals to 17: 2048
+> [13] number of values equals to 17: 2048
+> [14] number of values equals to 17: 2048
+> [15] number of values equals to 17: 2048
index 7cb0c94..3fa64ff 100644 (file)
@@ -51,40 +51,40 @@ if(enable_smpi)
     add_executable(bcastlog bcastlog.f)
   endif()
 
-  target_link_libraries(coll1  simgrid smpi )
-  target_link_libraries(coll2 simgrid smpi )
-  target_link_libraries(coll3 simgrid smpi )
-  target_link_libraries(coll4 simgrid smpi )
-  target_link_libraries(coll5 simgrid smpi )
-  target_link_libraries(coll6 simgrid smpi )
-  target_link_libraries(coll7 simgrid smpi )
-  target_link_libraries(coll8 simgrid smpi )
-  target_link_libraries(coll9 simgrid smpi )
-  target_link_libraries(coll10 simgrid smpi )
-  target_link_libraries(coll11 simgrid smpi )
-  target_link_libraries(coll12  simgrid smpi )
-  target_link_libraries(coll13 simgrid smpi )
-  target_link_libraries(allredmany simgrid smpi )
-  target_link_libraries(bcastbug simgrid smpi )
-  target_link_libraries(bcastbug2 simgrid smpi )
-  target_link_libraries(bcastvec simgrid smpi )
-  target_link_libraries(grouptest simgrid smpi )
-  target_link_libraries(redtst simgrid smpi )
-  target_link_libraries(barrier simgrid smpi )
-  target_link_libraries(bcast_mpich simgrid smpi )
-  target_link_libraries(allred simgrid smpi )
-  target_link_libraries(allred2 simgrid smpi )
-  target_link_libraries(scatterv simgrid smpi )
-  target_link_libraries(scattern simgrid smpi )
-  target_link_libraries(redscat simgrid smpi )
-  target_link_libraries(longuser simgrid smpi )
-  target_link_libraries(alltoallv_mpich simgrid smpi )
-  target_link_libraries(scantst simgrid smpi )
+  target_link_libraries(coll1  simgrid)
+  target_link_libraries(coll2 simgrid)
+  target_link_libraries(coll3 simgrid)
+  target_link_libraries(coll4 simgrid)
+  target_link_libraries(coll5 simgrid)
+  target_link_libraries(coll6 simgrid)
+  target_link_libraries(coll7 simgrid)
+  target_link_libraries(coll8 simgrid)
+  target_link_libraries(coll9 simgrid)
+  target_link_libraries(coll10 simgrid)
+  target_link_libraries(coll11 simgrid)
+  target_link_libraries(coll12  simgrid)
+  target_link_libraries(coll13 simgrid)
+  target_link_libraries(allredmany simgrid)
+  target_link_libraries(bcastbug simgrid)
+  target_link_libraries(bcastbug2 simgrid)
+  target_link_libraries(bcastvec simgrid)
+  target_link_libraries(grouptest simgrid)
+  target_link_libraries(redtst simgrid)
+  target_link_libraries(barrier simgrid)
+  target_link_libraries(bcast_mpich simgrid)
+  target_link_libraries(allred simgrid)
+  target_link_libraries(allred2 simgrid)
+  target_link_libraries(scatterv simgrid)
+  target_link_libraries(scattern simgrid)
+  target_link_libraries(redscat simgrid)
+  target_link_libraries(longuser simgrid)
+  target_link_libraries(alltoallv_mpich simgrid)
+  target_link_libraries(scantst simgrid)
   if(SMPI_F2C)
-    target_link_libraries(allredf simgrid smpi )
-    target_link_libraries(assocf simgrid smpi )
-    target_link_libraries(allgatherf simgrid smpi )
-    target_link_libraries(bcastlog simgrid smpi )
+    target_link_libraries(allredf simgrid)
+    target_link_libraries(assocf simgrid)
+    target_link_libraries(allgatherf simgrid)
+    target_link_libraries(bcastlog simgrid)
   endif()
 
   set_target_properties(coll1 PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
index 4defd0f..fe255e0 100644 (file)
@@ -30,19 +30,19 @@ if(enable_smpi)
   #add_executable(commnames_f commnamesf.f)
   endif()
 
-  target_link_libraries(attrerr simgrid smpi )
- # target_link_libraries(attrt simgrid smpi )
- # target_link_libraries(commnames simgrid smpi )
-  target_link_libraries(groupcreate simgrid smpi )
-  target_link_libraries(grouptest_mpich simgrid smpi )
-  target_link_libraries(icdup simgrid smpi )
-  target_link_libraries(ictest simgrid smpi )
-  target_link_libraries(ictest2 simgrid smpi )
-  target_link_libraries(ictest3 simgrid smpi )
+  target_link_libraries(attrerr simgrid)
+ # target_link_libraries(attrt simgrid)
+ # target_link_libraries(commnames simgrid)
+  target_link_libraries(groupcreate simgrid)
+  target_link_libraries(grouptest_mpich simgrid)
+  target_link_libraries(icdup simgrid)
+  target_link_libraries(ictest simgrid)
+  target_link_libraries(ictest2 simgrid)
+  target_link_libraries(ictest3 simgrid)
 
   if(SMPI_F2C)
-  #target_link_libraries(attrtest_f simgrid smpi f2c)
-  #target_link_libraries(commnames_f simgrid smpi f2c)
+  #target_link_libraries(attrtest_f simgrid f2c)
+  #target_link_libraries(commnames_f simgrid f2c)
   endif()
   
   set_target_properties(attrerr PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
index a81ab47..65f9eba 100644 (file)
@@ -31,23 +31,23 @@ if(enable_smpi)
 #    add_executable(errstringsf errstringsf.f)
     add_executable(getprocf getprocf.f)
   endif()
-  target_link_libraries(init simgrid smpi )
-  target_link_libraries(timers simgrid smpi )
-  target_link_libraries(timertest simgrid smpi )
-  target_link_libraries(baseattr simgrid smpi )
-  target_link_libraries(gtime simgrid smpi )
-  target_link_libraries(errhand simgrid smpi )
+  target_link_libraries(init simgrid)
+  target_link_libraries(timers simgrid)
+  target_link_libraries(timertest simgrid)
+  target_link_libraries(baseattr simgrid)
+  target_link_libraries(gtime simgrid)
+  target_link_libraries(errhand simgrid)
   if(NOT WIN32)
-    target_link_libraries(sigchk simgrid smpi )
+    target_link_libraries(sigchk simgrid)
   endif()
-       target_link_libraries(aborttest simgrid smpi )
-  target_link_libraries(testerr simgrid smpi )
-  target_link_libraries(getproc simgrid smpi )
+       target_link_libraries(aborttest simgrid)
+  target_link_libraries(testerr simgrid)
+  target_link_libraries(getproc simgrid)
   if(SMPI_F2C)
-#    target_link_libraries(baseattrf simgrid smpi )
-#    target_link_libraries(errhandf simgrid smpi )
-#    target_link_libraries(errstringsf simgrid smpi )
-    target_link_libraries(getprocf simgrid smpi )
+#    target_link_libraries(baseattrf simgrid)
+#    target_link_libraries(errhandf simgrid)
+#    target_link_libraries(errstringsf simgrid)
+    target_link_libraries(getprocf simgrid)
   endif()
 
   set_target_properties(timers PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
index e755aef..4e3d33f 100644 (file)
@@ -80,7 +80,7 @@ int main( int argc, char **argv )
 {
     int    err = 0;
     void *v;
-    int  flag;
+    int  flag=0;
     int  vval;
     int  rank;
     double t1;
index 024ee2b..7fae884 100644 (file)
@@ -15,8 +15,8 @@ if(enable_smpi)
   add_executable(ptest ptest.c )
   add_executable(colluses colluses.c )
 
-  target_link_libraries(ptest simgrid smpi )
-  target_link_libraries(colluses simgrid smpi )
+  target_link_libraries(ptest simgrid)
+  target_link_libraries(colluses simgrid)
 
   set_target_properties(ptest PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
   set_target_properties(colluses PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
index 5482e0c..0503262 100644 (file)
@@ -105,97 +105,97 @@ if(enable_smpi)
     add_executable(typebasef typebasef.f)
   endif()
 
-  target_link_libraries(overtake simgrid smpi )
-  target_link_libraries(bsendtest simgrid smpi )
-  target_link_libraries(relrank simgrid smpi )
-  target_link_libraries(sendrecv_mpich simgrid smpi )
-  target_link_libraries(persistent simgrid smpi )
-  target_link_libraries(flood simgrid smpi )
-  target_link_libraries(flood2 simgrid smpi )
-  target_link_libraries(persist simgrid smpi )
-  target_link_libraries(persist2 simgrid smpi )
-  target_link_libraries(sendrecv2 simgrid smpi )
-  target_link_libraries(sendrecv3 simgrid smpi )
-  target_link_libraries(sendrecv4 simgrid smpi )
-  target_link_libraries(irsend simgrid smpi )
-  target_link_libraries(irsendinit simgrid smpi )
-  target_link_libraries(longmsgs simgrid smpi )
-  target_link_libraries(testsome simgrid smpi )
-  target_link_libraries(testall_mpich simgrid smpi )
-  target_link_libraries(sndrcv simgrid smpi )
-  target_link_libraries(sndrcvrep simgrid smpi )
-  target_link_libraries(sndrcvrpl2 simgrid smpi )
-  target_link_libraries(getelm simgrid smpi )
-  target_link_libraries(self simgrid smpi )
-  target_link_libraries(typelb simgrid smpi )
-  target_link_libraries(structlb simgrid smpi )
-  target_link_libraries(typeub simgrid smpi )
-  target_link_libraries(typeub2 simgrid smpi )
-  target_link_libraries(typeub3 simgrid smpi )
-  target_link_libraries(typecreate simgrid smpi )
-  target_link_libraries(reqcreate simgrid smpi )
-  target_link_libraries(reqfree simgrid smpi )
-  target_link_libraries(isndrcv simgrid smpi )
-  target_link_libraries(nullproc simgrid smpi )
-  target_link_libraries(nullproc2 simgrid smpi )
-  target_link_libraries(trunc simgrid smpi )
-  target_link_libraries(truncmult simgrid smpi )
-  target_link_libraries(typetest simgrid smpi )
-  target_link_libraries(typebase simgrid smpi )
-  target_link_libraries(ssendtest simgrid smpi )
-  target_link_libraries(ssendtest2 simgrid smpi )
-  target_link_libraries(issendtest simgrid smpi )
-  target_link_libraries(issend2 simgrid smpi )
-  target_link_libraries(issendinit simgrid smpi )
-  target_link_libraries(testtypes simgrid smpi )
-  target_link_libraries(dataalign simgrid smpi )
-  target_link_libraries(dtyperecv simgrid smpi )
-  target_link_libraries(dtypelife simgrid smpi )
-  target_link_libraries(htmsg simgrid smpi )
-  target_link_libraries(isendtest simgrid smpi )
-  target_link_libraries(third simgrid smpi )
-  target_link_libraries(fourth simgrid smpi )
-  target_link_libraries(fifth simgrid smpi )
-  target_link_libraries(sixth simgrid smpi )
-  target_link_libraries(probe simgrid smpi )
-  target_link_libraries(nblock simgrid smpi )
-  target_link_libraries(sendmany simgrid smpi )
-  target_link_libraries(order simgrid smpi )
-  target_link_libraries(pack simgrid smpi )
-  target_link_libraries(probe1 simgrid smpi )
-  target_link_libraries(testtest1  simgrid smpi )
-  target_link_libraries(hvectest simgrid smpi )
-  target_link_libraries(hvectest2 simgrid smpi )
-  target_link_libraries(hvec simgrid smpi )
-  target_link_libraries(hindexed simgrid smpi )
-  target_link_libraries(irecvtest simgrid smpi )
-  target_link_libraries(nbtest simgrid smpi )
-  target_link_libraries(waitany simgrid smpi )
-  target_link_libraries(waitall simgrid smpi )
-  target_link_libraries(waitall2 simgrid smpi )
-  target_link_libraries(waitall3 simgrid smpi )
-  target_link_libraries(waitall4 simgrid smpi )
-  target_link_libraries(commit simgrid smpi )
-  target_link_libraries(cancel simgrid smpi )
-  target_link_libraries(cancel2 simgrid smpi )
-  target_link_libraries(cancel3 simgrid smpi )
-  target_link_libraries(cancelmessages simgrid smpi )
-  target_link_libraries(cancelibm simgrid smpi )
-  target_link_libraries(cancelissend simgrid smpi )
-  target_link_libraries(sendorder simgrid smpi )
-  target_link_libraries(exittest simgrid smpi )
-  target_link_libraries(selfvsworld simgrid smpi )
+  target_link_libraries(overtake simgrid)
+  target_link_libraries(bsendtest simgrid)
+  target_link_libraries(relrank simgrid)
+  target_link_libraries(sendrecv_mpich simgrid)
+  target_link_libraries(persistent simgrid)
+  target_link_libraries(flood simgrid)
+  target_link_libraries(flood2 simgrid)
+  target_link_libraries(persist simgrid)
+  target_link_libraries(persist2 simgrid)
+  target_link_libraries(sendrecv2 simgrid)
+  target_link_libraries(sendrecv3 simgrid)
+  target_link_libraries(sendrecv4 simgrid)
+  target_link_libraries(irsend simgrid)
+  target_link_libraries(irsendinit simgrid)
+  target_link_libraries(longmsgs simgrid)
+  target_link_libraries(testsome simgrid)
+  target_link_libraries(testall_mpich simgrid)
+  target_link_libraries(sndrcv simgrid)
+  target_link_libraries(sndrcvrep simgrid)
+  target_link_libraries(sndrcvrpl2 simgrid)
+  target_link_libraries(getelm simgrid)
+  target_link_libraries(self simgrid)
+  target_link_libraries(typelb simgrid)
+  target_link_libraries(structlb simgrid)
+  target_link_libraries(typeub simgrid)
+  target_link_libraries(typeub2 simgrid)
+  target_link_libraries(typeub3 simgrid)
+  target_link_libraries(typecreate simgrid)
+  target_link_libraries(reqcreate simgrid)
+  target_link_libraries(reqfree simgrid)
+  target_link_libraries(isndrcv simgrid)
+  target_link_libraries(nullproc simgrid)
+  target_link_libraries(nullproc2 simgrid)
+  target_link_libraries(trunc simgrid)
+  target_link_libraries(truncmult simgrid)
+  target_link_libraries(typetest simgrid)
+  target_link_libraries(typebase simgrid)
+  target_link_libraries(ssendtest simgrid)
+  target_link_libraries(ssendtest2 simgrid)
+  target_link_libraries(issendtest simgrid)
+  target_link_libraries(issend2 simgrid)
+  target_link_libraries(issendinit simgrid)
+  target_link_libraries(testtypes simgrid)
+  target_link_libraries(dataalign simgrid)
+  target_link_libraries(dtyperecv simgrid)
+  target_link_libraries(dtypelife simgrid)
+  target_link_libraries(htmsg simgrid)
+  target_link_libraries(isendtest simgrid)
+  target_link_libraries(third simgrid)
+  target_link_libraries(fourth simgrid)
+  target_link_libraries(fifth simgrid)
+  target_link_libraries(sixth simgrid)
+  target_link_libraries(probe simgrid)
+  target_link_libraries(nblock simgrid)
+  target_link_libraries(sendmany simgrid)
+  target_link_libraries(order simgrid)
+  target_link_libraries(pack simgrid)
+  target_link_libraries(probe1 simgrid)
+  target_link_libraries(testtest1  simgrid)
+  target_link_libraries(hvectest simgrid)
+  target_link_libraries(hvectest2 simgrid)
+  target_link_libraries(hvec simgrid)
+  target_link_libraries(hindexed simgrid)
+  target_link_libraries(irecvtest simgrid)
+  target_link_libraries(nbtest simgrid)
+  target_link_libraries(waitany simgrid)
+  target_link_libraries(waitall simgrid)
+  target_link_libraries(waitall2 simgrid)
+  target_link_libraries(waitall3 simgrid)
+  target_link_libraries(waitall4 simgrid)
+  target_link_libraries(commit simgrid)
+  target_link_libraries(cancel simgrid)
+  target_link_libraries(cancel2 simgrid)
+  target_link_libraries(cancel3 simgrid)
+  target_link_libraries(cancelmessages simgrid)
+  target_link_libraries(cancelibm simgrid)
+  target_link_libraries(cancelissend simgrid)
+  target_link_libraries(sendorder simgrid)
+  target_link_libraries(exittest simgrid)
+  target_link_libraries(selfvsworld simgrid)
   if(SMPI_F2C)
-    target_link_libraries(secondf simgrid smpi f2c)
-#    target_link_libraries(allpair2 simgrid smpi f2c)
-#    target_link_libraries(allpair simgrid smpi f2c)
-    target_link_libraries(isendf simgrid smpi f2c)
-    target_link_libraries(pingpong_f simgrid smpi f2c)
-    target_link_libraries(send1 simgrid smpi f2c)
-    target_link_libraries(sendcplx simgrid smpi f2c)
-    target_link_libraries(sendfort simgrid smpi f2c)
-#    target_link_libraries(structf simgrid smpi f2c)
-    target_link_libraries(typebasef simgrid smpi f2c)
+    target_link_libraries(secondf simgrid f2c)
+#    target_link_libraries(allpair2 simgrid f2c)
+#    target_link_libraries(allpair simgrid f2c)
+    target_link_libraries(isendf simgrid f2c)
+    target_link_libraries(pingpong_f simgrid f2c)
+    target_link_libraries(send1 simgrid f2c)
+    target_link_libraries(sendcplx simgrid f2c)
+    target_link_libraries(sendfort simgrid f2c)
+#    target_link_libraries(structf simgrid f2c)
+    target_link_libraries(typebasef simgrid f2c)
   endif()
 
   set_target_properties(overtake PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
diff --git a/teshsuite/smpi/reduce_coll.c b/teshsuite/smpi/reduce_coll.c
new file mode 100644 (file)
index 0000000..df40dc2
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (c) 2009, 2010. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "mpi.h"
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#endif
+
+int main(int argc, char *argv[])
+{
+  int rank, size;
+  int i;
+  int *sb;
+  int *rb;
+  int status;
+
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  sb = (int *) xbt_malloc(size * sizeof(int));
+  rb = (int *) xbt_malloc(size * sizeof(int));
+  
+  for (i = 0; i < size; ++i) {
+    sb[i] = rank*size + i;
+    rb[i] = 0;
+  }
+
+  printf("[%d] sndbuf=[", rank);
+  for (i = 0; i < size; i++)
+    printf("%d ", sb[i]);
+  printf("]\n");
+
+  status = MPI_Reduce(sb, rb, size, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
+  MPI_Barrier(MPI_COMM_WORLD);
+
+  if (rank == 0) {
+    printf("[%d] rcvbuf=[", rank);
+    for (i = 0; i < size; i++)
+      printf("%d ", rb[i]);
+    printf("]\n");
+    if (status != MPI_SUCCESS) {
+      printf("all_to_all returned %d\n", status);
+      fflush(stdout);
+    }
+  }
+  free(sb);
+  free(rb);
+  MPI_Finalize();
+  return (EXIT_SUCCESS);
+}
diff --git a/teshsuite/smpi/reduce_coll.tesh b/teshsuite/smpi/reduce_coll.tesh
new file mode 100644 (file)
index 0000000..ae94a6c
--- /dev/null
@@ -0,0 +1,41 @@
+# Smpi Allreduce collectives tests
+! setenv LD_LIBRARY_PATH=../../lib
+! output sort
+
+p Test allreduce
+$ ../../bin/smpirun -map -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../../examples/msg/small_platform.xml -np 16 --log=xbt_cfg.thres:critical ./reduce_coll
+> You requested to use 16 processes, but there is only 5 processes in your hostfile...
+> [rank 0] -> 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
+> [rank 10] -> Tremblay
+> [rank 11] -> Jupiter
+> [rank 12] -> Fafard
+> [rank 13] -> Ginette
+> [rank 14] -> Bourassa
+> [rank 15] -> Tremblay
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [0] sndbuf=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ]
+> [1] sndbuf=[16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ]
+> [2] sndbuf=[32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ]
+> [3] sndbuf=[48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 ]
+> [4] sndbuf=[64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ]
+> [5] sndbuf=[80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 ]
+> [6] sndbuf=[96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 ]
+> [7] sndbuf=[112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 ]
+> [8] sndbuf=[128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 ]
+> [9] sndbuf=[144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 ]
+> [10] sndbuf=[160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 ]
+> [11] sndbuf=[176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 ]
+> [12] sndbuf=[192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ]
+> [13] sndbuf=[208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 ]
+> [14] sndbuf=[224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 ]
+> [15] sndbuf=[240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 ]
+> [0] rcvbuf=[1920 1936 1952 1968 1984 2000 2016 2032 2048 2064 2080 2096 2112 2128 2144 2160 ]
index b016125..6da3d56 100644 (file)
 $ ./xbt/mmalloc_test --log=root.fmt:%m%n
 > Allocating a new heap
 > HeapA allocated
-> 100 bytes allocated with offset 55000
-> 200 bytes allocated with offset 56000
-> 300 bytes allocated with offset 57000
-> 400 bytes allocated with offset 57200
-> 500 bytes allocated with offset 57400
-> 600 bytes allocated with offset 58000
-> 700 bytes allocated with offset 58400
-> 800 bytes allocated with offset 58800
-> 900 bytes allocated with offset 58c00
-> 1000 bytes allocated with offset 59000
-> 1100 bytes allocated with offset 5a000
-> 1200 bytes allocated with offset 5a800
-> 1300 bytes allocated with offset 5b000
-> 1400 bytes allocated with offset 5b800
-> 1500 bytes allocated with offset 5c000
-> 1600 bytes allocated with offset 5c800
-> 1700 bytes allocated with offset 5d000
-> 1800 bytes allocated with offset 5d800
-> 1900 bytes allocated with offset 5e000
-> 2000 bytes allocated with offset 5e800
-> 2100 bytes allocated with offset 5f000
-> 2200 bytes allocated with offset 60000
-> 2300 bytes allocated with offset 61000
-> 2400 bytes allocated with offset 62000
-> 2500 bytes allocated with offset 63000
-> 2600 bytes allocated with offset 64000
-> 2700 bytes allocated with offset 65000
-> 2800 bytes allocated with offset 66000
-> 2900 bytes allocated with offset 67000
-> 3000 bytes allocated with offset 68000
-> 3100 bytes allocated with offset 69000
-> 3200 bytes allocated with offset 6a000
-> 3300 bytes allocated with offset 6b000
-> 3400 bytes allocated with offset 6c000
-> 3500 bytes allocated with offset 6d000
-> 3600 bytes allocated with offset 6e000
-> 3700 bytes allocated with offset 6f000
-> 3800 bytes allocated with offset 70000
-> 3900 bytes allocated with offset 71000
-> 4000 bytes allocated with offset 72000
-> 4100 bytes allocated with offset 73000
-> 4200 bytes allocated with offset 75000
-> 4300 bytes allocated with offset 77000
-> 4400 bytes allocated with offset 79000
-> 4500 bytes allocated with offset 7b000
-> 4600 bytes allocated with offset 7d000
-> 4700 bytes allocated with offset 7f000
-> 4800 bytes allocated with offset 81000
-> 4900 bytes allocated with offset 83000
-> 5000 bytes allocated with offset 85000
-> 100 bytes allocated with offset 55080
-> 200 bytes allocated with offset 56100
-> 300 bytes allocated with offset 57600
-> 400 bytes allocated with offset 57800
-> 500 bytes allocated with offset 57a00
-> 600 bytes allocated with offset 59400
-> 700 bytes allocated with offset 59800
-> 800 bytes allocated with offset 59c00
-> 900 bytes allocated with offset 87000
-> 1000 bytes allocated with offset 87400
-> 1100 bytes allocated with offset 88000
-> 1200 bytes allocated with offset 88800
-> 1300 bytes allocated with offset 89000
-> 1400 bytes allocated with offset 89800
-> 1500 bytes allocated with offset 8a000
-> 1600 bytes allocated with offset 8a800
-> 1700 bytes allocated with offset 8b000
-> 1800 bytes allocated with offset 8b800
-> 1900 bytes allocated with offset 8c000
-> 2000 bytes allocated with offset 8c800
-> 2100 bytes allocated with offset 8d000
-> 2200 bytes allocated with offset 8e000
-> 2300 bytes allocated with offset 8f000
-> 2400 bytes allocated with offset 90000
-> 2500 bytes allocated with offset 91000
-> 2600 bytes allocated with offset 92000
-> 2700 bytes allocated with offset 93000
-> 2800 bytes allocated with offset 94000
-> 2900 bytes allocated with offset 95000
-> 3000 bytes allocated with offset 96000
-> 3100 bytes allocated with offset 97000
-> 3200 bytes allocated with offset 98000
-> 3300 bytes allocated with offset 99000
-> 3400 bytes allocated with offset 9a000
-> 3500 bytes allocated with offset 9b000
-> 3600 bytes allocated with offset 9c000
-> 3700 bytes allocated with offset 9d000
-> 3800 bytes allocated with offset 9e000
-> 3900 bytes allocated with offset 9f000
-> 4000 bytes allocated with offset a0000
-> 4100 bytes allocated with offset a1000
-> 4200 bytes allocated with offset a3000
-> 4300 bytes allocated with offset a5000
-> 4400 bytes allocated with offset a7000
-> 4500 bytes allocated with offset a9000
-> 4600 bytes allocated with offset ab000
-> 4700 bytes allocated with offset ad000
-> 4800 bytes allocated with offset af000
-> 4900 bytes allocated with offset b1000
-> 5000 bytes allocated with offset b3000
+> 100 bytes allocated with offset 65000
+> 200 bytes allocated with offset 66000
+> 300 bytes allocated with offset 67000
+> 400 bytes allocated with offset 67200
+> 500 bytes allocated with offset 67400
+> 600 bytes allocated with offset 68000
+> 700 bytes allocated with offset 68400
+> 800 bytes allocated with offset 68800
+> 900 bytes allocated with offset 68c00
+> 1000 bytes allocated with offset 69000
+> 1100 bytes allocated with offset 6a000
+> 1200 bytes allocated with offset 6a800
+> 1300 bytes allocated with offset 6b000
+> 1400 bytes allocated with offset 6b800
+> 1500 bytes allocated with offset 6c000
+> 1600 bytes allocated with offset 6c800
+> 1700 bytes allocated with offset 6d000
+> 1800 bytes allocated with offset 6d800
+> 1900 bytes allocated with offset 6e000
+> 2000 bytes allocated with offset 6e800
+> 2100 bytes allocated with offset 6f000
+> 2200 bytes allocated with offset 70000
+> 2300 bytes allocated with offset 71000
+> 2400 bytes allocated with offset 72000
+> 2500 bytes allocated with offset 73000
+> 2600 bytes allocated with offset 74000
+> 2700 bytes allocated with offset 75000
+> 2800 bytes allocated with offset 76000
+> 2900 bytes allocated with offset 77000
+> 3000 bytes allocated with offset 78000
+> 3100 bytes allocated with offset 79000
+> 3200 bytes allocated with offset 7a000
+> 3300 bytes allocated with offset 7b000
+> 3400 bytes allocated with offset 7c000
+> 3500 bytes allocated with offset 7d000
+> 3600 bytes allocated with offset 7e000
+> 3700 bytes allocated with offset 7f000
+> 3800 bytes allocated with offset 80000
+> 3900 bytes allocated with offset 81000
+> 4000 bytes allocated with offset 82000
+> 4100 bytes allocated with offset 83000
+> 4200 bytes allocated with offset 85000
+> 4300 bytes allocated with offset 87000
+> 4400 bytes allocated with offset 89000
+> 4500 bytes allocated with offset 8b000
+> 4600 bytes allocated with offset 8d000
+> 4700 bytes allocated with offset 8f000
+> 4800 bytes allocated with offset 91000
+> 4900 bytes allocated with offset 93000
+> 5000 bytes allocated with offset 95000
+> 100 bytes allocated with offset 65080
+> 200 bytes allocated with offset 66100
+> 300 bytes allocated with offset 67600
+> 400 bytes allocated with offset 67800
+> 500 bytes allocated with offset 67a00
+> 600 bytes allocated with offset 69400
+> 700 bytes allocated with offset 69800
+> 800 bytes allocated with offset 69c00
+> 900 bytes allocated with offset 97000
+> 1000 bytes allocated with offset 97400
+> 1100 bytes allocated with offset 98000
+> 1200 bytes allocated with offset 98800
+> 1300 bytes allocated with offset 99000
+> 1400 bytes allocated with offset 99800
+> 1500 bytes allocated with offset 9a000
+> 1600 bytes allocated with offset 9a800
+> 1700 bytes allocated with offset 9b000
+> 1800 bytes allocated with offset 9b800
+> 1900 bytes allocated with offset 9c000
+> 2000 bytes allocated with offset 9c800
+> 2100 bytes allocated with offset 9d000
+> 2200 bytes allocated with offset 9e000
+> 2300 bytes allocated with offset 9f000
+> 2400 bytes allocated with offset a0000
+> 2500 bytes allocated with offset a1000
+> 2600 bytes allocated with offset a2000
+> 2700 bytes allocated with offset a3000
+> 2800 bytes allocated with offset a4000
+> 2900 bytes allocated with offset a5000
+> 3000 bytes allocated with offset a6000
+> 3100 bytes allocated with offset a7000
+> 3200 bytes allocated with offset a8000
+> 3300 bytes allocated with offset a9000
+> 3400 bytes allocated with offset aa000
+> 3500 bytes allocated with offset ab000
+> 3600 bytes allocated with offset ac000
+> 3700 bytes allocated with offset ad000
+> 3800 bytes allocated with offset ae000
+> 3900 bytes allocated with offset af000
+> 4000 bytes allocated with offset b0000
+> 4100 bytes allocated with offset b1000
+> 4200 bytes allocated with offset b3000
+> 4300 bytes allocated with offset b5000
+> 4400 bytes allocated with offset b7000
+> 4500 bytes allocated with offset b9000
+> 4600 bytes allocated with offset bb000
+> 4700 bytes allocated with offset bd000
+> 4800 bytes allocated with offset bf000
+> 4900 bytes allocated with offset c1000
+> 5000 bytes allocated with offset c3000
 > All blocks were correctly allocated. Free every second block
 > Memset every second block to zero (yeah, they are not currently allocated :)
 > Re-allocate every second block
index 95dcd53..77be118 100644 (file)
 $ ./xbt/mmalloc_test --log=root.fmt:%m%n
 > Allocating a new heap
 > HeapA allocated
-> 100 bytes allocated with offset 51000
-> 200 bytes allocated with offset 51100
-> 300 bytes allocated with offset 52000
-> 400 bytes allocated with offset 52200
-> 500 bytes allocated with offset 52400
-> 600 bytes allocated with offset 53000
-> 700 bytes allocated with offset 53400
-> 800 bytes allocated with offset 53800
-> 900 bytes allocated with offset 53c00
-> 1000 bytes allocated with offset 54000
-> 1100 bytes allocated with offset 55000
-> 1200 bytes allocated with offset 55800
-> 1300 bytes allocated with offset 56000
-> 1400 bytes allocated with offset 56800
-> 1500 bytes allocated with offset 57000
-> 1600 bytes allocated with offset 57800
-> 1700 bytes allocated with offset 58000
-> 1800 bytes allocated with offset 58800
-> 1900 bytes allocated with offset 59000
-> 2000 bytes allocated with offset 59800
-> 2100 bytes allocated with offset 5a000
-> 2200 bytes allocated with offset 5b000
-> 2300 bytes allocated with offset 5c000
-> 2400 bytes allocated with offset 5d000
-> 2500 bytes allocated with offset 5e000
-> 2600 bytes allocated with offset 5f000
-> 2700 bytes allocated with offset 60000
-> 2800 bytes allocated with offset 61000
-> 2900 bytes allocated with offset 62000
-> 3000 bytes allocated with offset 63000
-> 3100 bytes allocated with offset 64000
-> 3200 bytes allocated with offset 65000
-> 3300 bytes allocated with offset 66000
-> 3400 bytes allocated with offset 67000
-> 3500 bytes allocated with offset 68000
-> 3600 bytes allocated with offset 69000
-> 3700 bytes allocated with offset 6a000
-> 3800 bytes allocated with offset 6b000
-> 3900 bytes allocated with offset 6c000
-> 4000 bytes allocated with offset 6d000
-> 4100 bytes allocated with offset 6e000
-> 4200 bytes allocated with offset 70000
-> 4300 bytes allocated with offset 72000
-> 4400 bytes allocated with offset 74000
-> 4500 bytes allocated with offset 76000
-> 4600 bytes allocated with offset 78000
-> 4700 bytes allocated with offset 7a000
-> 4800 bytes allocated with offset 7c000
-> 4900 bytes allocated with offset 7e000
-> 5000 bytes allocated with offset 80000
-> 100 bytes allocated with offset 51200
-> 200 bytes allocated with offset 51300
-> 300 bytes allocated with offset 52600
-> 400 bytes allocated with offset 52800
-> 500 bytes allocated with offset 52a00
-> 600 bytes allocated with offset 54400
-> 700 bytes allocated with offset 54800
-> 800 bytes allocated with offset 54c00
-> 900 bytes allocated with offset 82000
-> 1000 bytes allocated with offset 82400
-> 1100 bytes allocated with offset 83000
-> 1200 bytes allocated with offset 83800
-> 1300 bytes allocated with offset 84000
-> 1400 bytes allocated with offset 84800
-> 1500 bytes allocated with offset 85000
-> 1600 bytes allocated with offset 85800
-> 1700 bytes allocated with offset 86000
-> 1800 bytes allocated with offset 86800
-> 1900 bytes allocated with offset 87000
-> 2000 bytes allocated with offset 87800
-> 2100 bytes allocated with offset 88000
-> 2200 bytes allocated with offset 89000
-> 2300 bytes allocated with offset 8a000
-> 2400 bytes allocated with offset 8b000
-> 2500 bytes allocated with offset 8c000
-> 2600 bytes allocated with offset 8d000
-> 2700 bytes allocated with offset 8e000
-> 2800 bytes allocated with offset 8f000
-> 2900 bytes allocated with offset 90000
-> 3000 bytes allocated with offset 91000
-> 3100 bytes allocated with offset 92000
-> 3200 bytes allocated with offset 93000
-> 3300 bytes allocated with offset 94000
-> 3400 bytes allocated with offset 95000
-> 3500 bytes allocated with offset 96000
-> 3600 bytes allocated with offset 97000
-> 3700 bytes allocated with offset 98000
-> 3800 bytes allocated with offset 99000
-> 3900 bytes allocated with offset 9a000
-> 4000 bytes allocated with offset 9b000
-> 4100 bytes allocated with offset 9c000
-> 4200 bytes allocated with offset 9e000
-> 4300 bytes allocated with offset a0000
-> 4400 bytes allocated with offset a2000
-> 4500 bytes allocated with offset a4000
-> 4600 bytes allocated with offset a6000
-> 4700 bytes allocated with offset a8000
-> 4800 bytes allocated with offset aa000
-> 4900 bytes allocated with offset ac000
-> 5000 bytes allocated with offset ae000
+> 100 bytes allocated with offset 59000
+> 200 bytes allocated with offset 59100
+> 300 bytes allocated with offset 5a000
+> 400 bytes allocated with offset 5a200
+> 500 bytes allocated with offset 5a400
+> 600 bytes allocated with offset 5b000
+> 700 bytes allocated with offset 5b400
+> 800 bytes allocated with offset 5b800
+> 900 bytes allocated with offset 5bc00
+> 1000 bytes allocated with offset 5c000
+> 1100 bytes allocated with offset 5d000
+> 1200 bytes allocated with offset 5d800
+> 1300 bytes allocated with offset 5e000
+> 1400 bytes allocated with offset 5e800
+> 1500 bytes allocated with offset 5f000
+> 1600 bytes allocated with offset 5f800
+> 1700 bytes allocated with offset 60000
+> 1800 bytes allocated with offset 60800
+> 1900 bytes allocated with offset 61000
+> 2000 bytes allocated with offset 61800
+> 2100 bytes allocated with offset 62000
+> 2200 bytes allocated with offset 63000
+> 2300 bytes allocated with offset 64000
+> 2400 bytes allocated with offset 65000
+> 2500 bytes allocated with offset 66000
+> 2600 bytes allocated with offset 67000
+> 2700 bytes allocated with offset 68000
+> 2800 bytes allocated with offset 69000
+> 2900 bytes allocated with offset 6a000
+> 3000 bytes allocated with offset 6b000
+> 3100 bytes allocated with offset 6c000
+> 3200 bytes allocated with offset 6d000
+> 3300 bytes allocated with offset 6e000
+> 3400 bytes allocated with offset 6f000
+> 3500 bytes allocated with offset 70000
+> 3600 bytes allocated with offset 71000
+> 3700 bytes allocated with offset 72000
+> 3800 bytes allocated with offset 73000
+> 3900 bytes allocated with offset 74000
+> 4000 bytes allocated with offset 75000
+> 4100 bytes allocated with offset 76000
+> 4200 bytes allocated with offset 78000
+> 4300 bytes allocated with offset 7a000
+> 4400 bytes allocated with offset 7c000
+> 4500 bytes allocated with offset 7e000
+> 4600 bytes allocated with offset 80000
+> 4700 bytes allocated with offset 82000
+> 4800 bytes allocated with offset 84000
+> 4900 bytes allocated with offset 86000
+> 5000 bytes allocated with offset 88000
+> 100 bytes allocated with offset 59200
+> 200 bytes allocated with offset 59300
+> 300 bytes allocated with offset 5a600
+> 400 bytes allocated with offset 5a800
+> 500 bytes allocated with offset 5aa00
+> 600 bytes allocated with offset 5c400
+> 700 bytes allocated with offset 5c800
+> 800 bytes allocated with offset 5cc00
+> 900 bytes allocated with offset 8a000
+> 1000 bytes allocated with offset 8a400
+> 1100 bytes allocated with offset 8b000
+> 1200 bytes allocated with offset 8b800
+> 1300 bytes allocated with offset 8c000
+> 1400 bytes allocated with offset 8c800
+> 1500 bytes allocated with offset 8d000
+> 1600 bytes allocated with offset 8d800
+> 1700 bytes allocated with offset 8e000
+> 1800 bytes allocated with offset 8e800
+> 1900 bytes allocated with offset 8f000
+> 2000 bytes allocated with offset 8f800
+> 2100 bytes allocated with offset 90000
+> 2200 bytes allocated with offset 91000
+> 2300 bytes allocated with offset 92000
+> 2400 bytes allocated with offset 93000
+> 2500 bytes allocated with offset 94000
+> 2600 bytes allocated with offset 95000
+> 2700 bytes allocated with offset 96000
+> 2800 bytes allocated with offset 97000
+> 2900 bytes allocated with offset 98000
+> 3000 bytes allocated with offset 99000
+> 3100 bytes allocated with offset 9a000
+> 3200 bytes allocated with offset 9b000
+> 3300 bytes allocated with offset 9c000
+> 3400 bytes allocated with offset 9d000
+> 3500 bytes allocated with offset 9e000
+> 3600 bytes allocated with offset 9f000
+> 3700 bytes allocated with offset a0000
+> 3800 bytes allocated with offset a1000
+> 3900 bytes allocated with offset a2000
+> 4000 bytes allocated with offset a3000
+> 4100 bytes allocated with offset a4000
+> 4200 bytes allocated with offset a6000
+> 4300 bytes allocated with offset a8000
+> 4400 bytes allocated with offset aa000
+> 4500 bytes allocated with offset ac000
+> 4600 bytes allocated with offset ae000
+> 4700 bytes allocated with offset b0000
+> 4800 bytes allocated with offset b2000
+> 4900 bytes allocated with offset b4000
+> 5000 bytes allocated with offset b6000
 > All blocks were correctly allocated. Free every second block
 > Memset every second block to zero (yeah, they are not currently allocated :)
 > Re-allocate every second block
index 8339ce8..70ec40a 100644 (file)
 + src/simix/simix_network\.tla
 
 + src/smpi/BUGS
++ src/smpi/colls/allgather-2dmesh\.c
++ src/smpi/colls/allgather-3dmesh\.c
++ src/smpi/colls/allgather-bruck\.c
++ src/smpi/colls/allreduce-rab-rdb\.c
++ src/smpi/colls/allreduce-rab-reduce-scatter\.c
++ src/smpi/colls/allreduce-smp-binomial-pipeline\.c
++ src/smpi/colls/alltoall-bruck\.c
 + src/smpi/fixsrc\.pl
 + src/smpi/myprintloc\.cocci
 + src/smpi/patch_source\.sh
index f58c80e..c611336 100644 (file)
@@ -742,7 +742,7 @@ void *rctx_wait(void *r)
      return NULL;
      xbt_os_mutex_acquire(rctx->interruption); */
 
-  {
+  { // Sorting output got
     xbt_dynar_t a = xbt_str_split(rctx->output_got->data, "\n");
     xbt_dynar_t b = xbt_dynar_new(sizeof(char *), NULL);
     unsigned cpt;
@@ -777,6 +777,22 @@ void *rctx_wait(void *r)
     xbt_dynar_free(&a);
   }
 
+  if (rctx->output_sort) { // Sorting output wanted
+    char *newbuf;
+    xbt_dynar_t a = xbt_str_split(rctx->output_wanted->data, "\n");
+
+    stable_sort(a);
+    /* If empty lines moved in first position, remove them */
+    while (!xbt_dynar_is_empty(a) && *xbt_dynar_getfirst_as(a, char*) == '\0')
+        xbt_dynar_shift(a, NULL);
+
+    newbuf = xbt_str_join(a, "\n");
+    strcpy(rctx->output_wanted->data, newbuf);
+    rctx->output_wanted->used = strlen(newbuf);
+    xbt_free(newbuf);
+
+    xbt_dynar_free(&a);
+  }
   xbt_strbuff_chomp(rctx->output_got);
   xbt_strbuff_chomp(rctx->output_wanted);
   xbt_strbuff_trim(rctx->output_got);