Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge conflicts in instr_routing.c
authorJonathan Rouzaud-Cornabas <jonathan.rouzaud-cornabas@ens-lyon.fr>
Thu, 27 Sep 2012 06:07:29 +0000 (08:07 +0200)
committerJonathan Rouzaud-Cornabas <jonathan.rouzaud-cornabas@ens-lyon.fr>
Thu, 27 Sep 2012 06:07:29 +0000 (08:07 +0200)
144 files changed:
.gitignore
ChangeLog
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/memcheck_tests.cmake
doc/user_guide/doxygen/options.doc
doc/user_guide/doxygen/platform.doc
doc/user_guide/doxygen/tracing.doc
examples/msg/bittorrent/CMakeLists.txt
examples/msg/bittorrent/bittorrent_platfgen.c [new file with mode: 0644]
examples/msg/io/CMakeLists.txt
examples/msg/io/file.c
examples/msg/io/file_unlink.c [new file with mode: 0644]
examples/msg/io/io.tesh
examples/msg/masterslave/CMakeLists.txt
examples/msg/masterslave/masterslave_failure_platfgen.c [new file with mode: 0644]
examples/msg/masterslave/masterslave_platfgen.c [new file with mode: 0644]
examples/msg/token_ring/CMakeLists.txt
examples/msg/token_ring/token_bypass.c [new file with mode: 0644]
examples/msg/tracing/trace_platform.tesh
examples/platforms/conf/gridpp_grid_2004.xml
examples/platforms/prop.xml
examples/simdag/faulty_host.trace
examples/simdag/sd_fail.c
examples/simdag/sd_test.c
examples/simdag/test_simdag_fail.tesh [new file with mode: 0644]
examples/simdag/test_simdag_tracing.tesh
examples/smpi/CMakeLists.txt
examples/smpi/actions.txt [deleted file]
examples/smpi/compute3.c
examples/smpi/replay/actions0.txt [new file with mode: 0644]
examples/smpi/replay/actions1.txt [new file with mode: 0644]
examples/smpi/replay/actions_bcast.txt [new file with mode: 0644]
examples/smpi/replay/one_trace [new file with mode: 0644]
examples/smpi/replay/replay.c [moved from examples/smpi/replay.c with 86% similarity]
examples/smpi/replay/replay_platform.xml [new file with mode: 0644]
examples/smpi/replay/smpi_replay.tesh [new file with mode: 0644]
examples/smpi/replay/split_traces [new file with mode: 0644]
examples/smpi/tracing/smpi_traced.tesh
include/instr/instr.h
include/msg/msg.h
include/simdag/datatypes.h
include/simdag/simdag.h
include/simgrid/modelchecker.h
include/simgrid/platf.h
include/simgrid/platf_generator.h [new file with mode: 0644]
include/simgrid/simix.h
include/smpi/smpi.h
include/surf/surf_routing.h
include/surf/surfxml_parse.h
include/xbt/mmalloc.h
include/xbt/str.h
src/bindings/lua/lua_platf.c
src/include/mc/datatypes.h
src/include/mc/mc.h
src/include/simgrid/platf_interface.h
src/include/surf/surf.h
src/include/xbt/xbt_os_time.h
src/instr/instr_config.c
src/instr/instr_interface.c
src/instr/instr_msg_process.c
src/instr/instr_paje_header.c [new file with mode: 0644]
src/instr/instr_paje_trace.c
src/instr/instr_private.h
src/instr/instr_routing.c
src/instr/instr_smpi.c
src/instr/instr_surf.c
src/mc/mc_checkpoint.c
src/mc/mc_global.c
src/mc/mc_liveness.c
src/mc/mc_private.h
src/mc/memory_map.c
src/mc/test/compare_snapshot.c
src/msg/msg_environment.c
src/msg/msg_global.c
src/msg/msg_gos.c
src/msg/msg_host.c
src/msg/msg_io.c
src/msg/msg_mailbox.c
src/msg/msg_mailbox.h
src/msg/msg_private.h
src/msg/msg_process.c
src/simdag/sd_task.c
src/simdag/sd_workstation.c
src/simix/smx_context_raw.c
src/simix/smx_deployment.c
src/simix/smx_environment.c
src/simix/smx_global.c
src/simix/smx_io.c
src/simix/smx_io_private.h
src/simix/smx_network.c
src/simix/smx_network_private.h
src/simix/smx_private.h
src/simix/smx_smurf.c
src/simix/smx_smurf_private.h
src/simix/smx_user.c
src/smpi/private.h
src/smpi/smpi_base.c
src/smpi/smpi_bench.c
src/smpi/smpi_global.c
src/smpi/smpi_mpi.c
src/smpi/smpi_mpi_dt.c
src/smpi/smpi_pmpi.c
src/smpi/smpi_replay.c
src/smpi/smpirun.in
src/surf/maxmin.c
src/surf/network.c
src/surf/network_ns3.c
src/surf/platf_generator.c [new file with mode: 0644]
src/surf/platf_generator_private.h [new file with mode: 0644]
src/surf/sg_platf.c
src/surf/simgrid.dtd
src/surf/simgrid_dtd.c
src/surf/storage.c
src/surf/storage_private.h
src/surf/surf.c
src/surf/surf_config.c
src/surf/surf_private.h
src/surf/surf_routing.c
src/surf/surf_routing_cluster.c
src/surf/surf_routing_dijkstra.c
src/surf/surf_routing_floyd.c
src/surf/surf_routing_full.c
src/surf/surf_routing_generic.c
src/surf/surf_routing_none.c
src/surf/surf_routing_private.h
src/surf/surf_routing_rulebased.c
src/surf/surf_routing_vivaldi.c
src/surf/surfxml_parse.c
src/surf/surfxml_parseplatf.c
src/surf/trace_mgr.c
src/surf/workstation.c
src/xbt/mmalloc/mfree.c
src/xbt/mmalloc/mm_diff.c
src/xbt/mmalloc/mmalloc.c
src/xbt/mmalloc/mmprivate.h
src/xbt/xbt_log_appender_file.c
src/xbt/xbt_main.c
src/xbt/xbt_os_time.c
src/xbt/xbt_str.c
teshsuite/simdag/platforms/basic_parsing_test.c
teshsuite/simdag/platforms/random.xml
tools/gras/stub_generator.c
tools/simgrid2vite.sed [new file with mode: 0644]

index 4eb661d..e67d83f 100644 (file)
@@ -149,6 +149,7 @@ examples/msg/masterslave/toto.txt
 examples/msg/simulation.trace
 examples/msg/toto.txt
 examples/msg/z_gtnets.trace
+examples/msg/gpu/test_MSG_gpu_task_create
 examples/msg/cloud/masterslave_virtual_machines
 examples/msg/tracing/link_srcdst_user_variables
 examples/msg/tracing/link_user_variables
@@ -158,6 +159,8 @@ examples/msg/tracing/user_variables
 examples/msg/tracing/procmig
 examples/msg/tracing/tasks
 examples/msg/tracing/volume
+examples/msg/io/file
+examples/msg/io/file_unlink
 examples/msg/mc/bugged3
 examples/msg/mc/random_test
 examples/msg/chord/chord
@@ -165,8 +168,6 @@ examples/msg/chord/chord_stateful
 examples/msg/chord/deployments
 examples/msg/chord/exp_*
 examples/msg/token_ring/token_ring
-examples/simdag/ex_sd_seq_access
-examples/simdag/sd_seq_access
 examples/msg/icomms/peer
 examples/msg/icomms/peer2
 examples/gras/console/ping_client_console
@@ -176,15 +177,27 @@ examples/msg/icomms/.kdbgrc.peer3
 examples/msg/icomms/peer3
 examples/msg/icomms/toto.txt
 examples/msg/masterslave/masterslave_console
+examples/msg/irc_isend/peer
+examples/msg/irc_isend/toto.txt
+examples/simdag/ex_sd_seq_access
+examples/simdag/sd_seq_access
+examples/simdag/sd_comm_throttling
+examples/simdag/sd_fail
+examples/simdag/sd_typed_tasks_test
 examples/simdag/ex_sd_test_console
 examples/simdag/sd_test_console
 examples/simdag/scheduling/Montage_25.jed
-examples/msg/irc_isend/peer
-examples/msg/irc_isend/toto.txt
 examples/simdag/dot/dot_test
 examples/simdag/dot/dot_test2
-examples/smpi/toto.txt
-examples/java/*/classnoinst.stamp
+examples/simdag/ex_sd_test
+examples/simdag/ex_sd_test2
+examples/simdag/metaxml/sd_meta
+examples/simdag/properties/sd_prop
+examples/simdag/sd_test
+examples/simdag/sd_test2
+examples/simdag/dax/dax_test
+examples/simdag/goal/goal_test
+examples/simdag/scheduling/minmin_test
 examples/amok/bandwidth/bandwidth_maestro
 examples/amok/bandwidth/bandwidth_sensor
 examples/amok/saturate/saturate_maestro
@@ -215,6 +228,8 @@ examples/gras/replay/replay_simulator
 examples/gras/replay/replay_master
 examples/gras/replay/replay_worker
 examples/msg/actions/actions
+examples/msg/bittorrent/bittorrent
+examples/msg/kademlia/kademlia
 examples/msg/gtnets/gtnets
 examples/msg/masterslave/masterslave_bypass
 examples/msg/masterslave/masterslave_failure
@@ -236,15 +251,8 @@ examples/msg/mc/bugged1
 examples/msg/parallel_contexts/pcontexts
 examples/msg/parallel_contexts/pcontexts2
 examples/msg/pmm/msg_pmm
-examples/simdag/ex_sd_test
-examples/simdag/ex_sd_test2
-examples/simdag/metaxml/sd_meta
-examples/simdag/properties/sd_prop
-examples/simdag/sd_test
-examples/simdag/sd_test2
-examples/simdag/dax/dax_test
-examples/simdag/goal/goal_test
-examples/simdag/scheduling/minmin_test
+examples/smpi/toto.txt
+examples/smpi/replay
 examples/smpi/reduce
 examples/smpi/bcast
 examples/smpi/bcbench
@@ -295,6 +303,7 @@ teshsuite/simdag/basic3
 teshsuite/simdag/basic4
 teshsuite/simdag/basic5
 teshsuite/simdag/basic6
+teshsuite/simdag/incomplete
 teshsuite/simdag/network/mxn/test_intra_all2all
 teshsuite/simdag/network/mxn/test_intra_independent_comm
 teshsuite/simdag/network/mxn/test_intra_scatter
@@ -306,6 +315,7 @@ teshsuite/simdag/network/test_reinit_costs
 teshsuite/simdag/platforms/basic_parsing_test
 teshsuite/simdag/platforms/flatifier
 teshsuite/simdag/platforms/basic_tracing
+teshsuite/simdag/platforms/basic_link_test
 teshsuite/simdag/platforms/evaluate_get_route_time
 teshsuite/simdag/platforms/evaluate_parse_time
 teshsuite/simdag/partask/test_comp_only_par
index 579b0d8..fa21ecf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -55,11 +55,21 @@ SimGrid (3.8) NOT RELEASED; urgency=low
    bandwidth on the route onto which the task is  scheduled and the amount of 
    data to transfer.
    To divide the nominal bandwidth by 2, the rate then has to be :
-                     rate = bandwidth/(2*amount) 
-                     
+                     rate = bandwidth/(2*amount)
+ * Compute tasks that have failed can now be rescheduled and executed again
+   (from their beginning)
+ * Increasing source code coverage (src/simdag is now covered at 91.5%
+   on average)
+   
+ SMPI:
+ * Re-implement time-independent trace replay using SMPI (at the
+   smpi_smp_* level) instead of MSG. This should replace
+   examples/msg/actions/actions.c
+   
  XBT:
  * Functions xbt_dict_hash() and xbt_dict_hash_ext() are made public,
    and renamed to xbt_str_hash() and xbt_str_hash_ext().
+ * New function: xbt_os_timer_resume() to restart a timer w/o resetting it.
 
  -- $date Da SimGrid team <simgrid-devel@lists.gforge.inria.fr>
 
index 40c0cf2..7ee2360 100644 (file)
@@ -370,6 +370,7 @@ if(NOT enable_memcheck)
   ADD_TEST(simdag-test-simdag2                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag --cd ${CMAKE_BINARY_DIR}/examples/simdag ${CMAKE_HOME_DIRECTORY}/examples/simdag/test_simdag2.tesh)
   ADD_TEST(simdag-test-seq-access               ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag --cd ${CMAKE_BINARY_DIR}/examples/simdag ${CMAKE_HOME_DIRECTORY}/examples/simdag/test_simdag_seq_access.tesh)
   ADD_TEST(simdag-test-typed-tasks              ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag --cd ${CMAKE_BINARY_DIR}/examples/simdag ${CMAKE_HOME_DIRECTORY}/examples/simdag/test_simdag_typed_tasks.tesh)
+  ADD_TEST(simdag-test-fail                    ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag --cd ${CMAKE_BINARY_DIR}/examples/simdag ${CMAKE_HOME_DIRECTORY}/examples/simdag/test_simdag_fail.tesh)
   ADD_TEST(simdag-test-comm-throttling          ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag --cd ${CMAKE_BINARY_DIR}/examples/simdag ${CMAKE_HOME_DIRECTORY}/examples/simdag/test_simdag_comm_throttling.tesh)
   ADD_TEST(simdag-test-dax-cycle                ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag/dax --cd ${CMAKE_BINARY_DIR}/examples/simdag/dax ${CMAKE_HOME_DIRECTORY}/examples/simdag/dax/simple_dax_with_cycle.tesh)
   ADD_TEST(simdag-test-prop                     ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/simdag --cd ${CMAKE_BINARY_DIR}/examples/simdag ${CMAKE_HOME_DIRECTORY}/examples/simdag/properties/test_prop.tesh)
@@ -460,6 +461,7 @@ if(NOT enable_memcheck)
     # smpi examples
     ADD_TEST(smpi-bcast-thread                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:thread --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/bcast.tesh)
     ADD_TEST(smpi-reduce-thread                 ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:thread --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/reduce.tesh)
+
     if(HAVE_RAWCTX)
       ADD_TEST(smpi-bcast-raw                   ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:raw --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/bcast.tesh)
       ADD_TEST(smpi-reduce-raw                  ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg contexts/factory:raw --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/reduce.tesh)
@@ -470,6 +472,7 @@ if(NOT enable_memcheck)
     endif(CONTEXT_UCONTEXT)
     if(HAVE_TRACING)
       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} --cd ${CMAKE_BINARY_DIR}/examples/smpi ${CMAKE_HOME_DIRECTORY}/examples/smpi/replay/smpi_replay.tesh)
     endif(HAVE_TRACING)
   endif(enable_smpi)
 
index f1d9159..3d8e05e 100644 (file)
@@ -272,6 +272,12 @@ set(MSG_SRC
   src/msg/msg_vm.c
   )
 
+set(PLATFGEN_SRC
+  include/simgrid/platf_generator.h
+  src/surf/platf_generator.c
+  src/surf/platf_generator_private.h
+  )
+
 set(SIMDAG_SRC
   src/simdag/sd_daxloader.c
   src/simdag/sd_global.c
@@ -351,6 +357,7 @@ set(TRACING_SRC
   src/instr/instr_msg_task.c
   src/instr/instr_paje_containers.c
   src/instr/instr_paje_trace.c
+  src/instr/instr_paje_header.c
   src/instr/instr_paje_types.c
   src/instr/instr_paje_values.c
   src/instr/instr_private.h
@@ -402,6 +409,7 @@ set(headers_to_install
   include/simdag/simdag.h
   include/simgrid/modelchecker.h
   include/simgrid/platf.h
+  include/simgrid/platf_generator.h
   include/simgrid/simix.h
   include/smpi/mpi.h
   include/smpi/mpif.h
@@ -510,6 +518,7 @@ set(simgrid_sources
   ${SIMDAG_SRC}
   ${SIMIX_SRC}
   ${SURF_SRC}
+  ${PLATFGEN_SRC}
   ${TRACING_SRC}
   ${XBT_SRC}
   )
index 7d8da06..406d3d2 100644 (file)
@@ -134,6 +134,7 @@ ADD_TEST(memcheck-tesh-simdag-par-2-1 ${CMAKE_BINARY_DIR}/teshsuite/simdag/parta
 
 # MSG examples
 ADD_TEST(memcheck-msg-file-0 ${CMAKE_BINARY_DIR}/examples/msg//io/file ${CMAKE_HOME_DIRECTORY}//examples/platforms/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cd ${CMAKE_HOME_DIRECTORY}/examples//)
+ADD_TEST(memcheck-msg-file-1 ${CMAKE_BINARY_DIR}/examples/msg//io/file_unlink ${CMAKE_HOME_DIRECTORY}//examples/platforms/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cd ${CMAKE_HOME_DIRECTORY}/examples//)
 ADD_TEST(memcheck-msg-start-kill-time-0 ${CMAKE_BINARY_DIR}/examples/msg//start_kill_time/sk_time ${CMAKE_HOME_DIRECTORY}//examples/platforms/cluster.xml ${CMAKE_HOME_DIRECTORY}//examples/msg/start_kill_time/deployment.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cd ${CMAKE_HOME_DIRECTORY}/examples//)
 ADD_TEST(memcheck-msg-start-kill-time-1 ${CMAKE_BINARY_DIR}/examples/msg//start_kill_time/sk_time ${CMAKE_HOME_DIRECTORY}//examples/platforms/cluster.xml ${CMAKE_HOME_DIRECTORY}//examples/msg/start_kill_time/deployment_start.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cd ${CMAKE_HOME_DIRECTORY}/examples//)
 ADD_TEST(memcheck-msg-start-kill-time-2 ${CMAKE_BINARY_DIR}/examples/msg//start_kill_time/sk_time ${CMAKE_HOME_DIRECTORY}//examples/platforms/cluster.xml ${CMAKE_HOME_DIRECTORY}//examples/msg/start_kill_time/deployment_kill.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cd ${CMAKE_HOME_DIRECTORY}/examples//)
@@ -210,17 +211,20 @@ if(HAVE_RAWCTX)
 endif(HAVE_RAWCTX)
 
 ADD_TEST(memcheck-msg-masterslave-vivaldi-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/masterslave/masterslave_mailbox  ${CMAKE_HOME_DIRECTORY}/examples/msg/../platforms/vivaldi.xml ${CMAKE_HOME_DIRECTORY}/examples/msg/masterslave/deployment_masterslave_vivaldi.xml --cfg=network/latency_factor:1.0 --cfg=network/bandwidth_factor:1.0 --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/)
-ADD_TEST(memcheck-msg-token-ring-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/msg/token_ring/two_clusters.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
-ADD_TEST(memcheck-msg-token-ring-thread-1 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/msg/token_ring/two_peers.xml --cfg=network/coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+ADD_TEST(memcheck-msg-token-ring-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/routing_cluster.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+ADD_TEST(memcheck-msg-token-ring-thread-1 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/two_peers.xml --cfg=network/coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+ADD_TEST(memcheck-msg-token-ring-thread-2 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/meta_cluster.xml --log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
 if(HAVE_RAWCTX)
   ADD_TEST(memcheck-msg-masterslave-vivaldi-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/masterslave/masterslave_mailbox  ${CMAKE_HOME_DIRECTORY}/examples/msg/../platforms/vivaldi.xml ${CMAKE_HOME_DIRECTORY}/examples/msg/masterslave/deployment_masterslave_vivaldi.xml --cfg=network/latency_factor:1.0 --cfg=network/bandwidth_factor:1.0 --cfg=contexts/factory:raw  --cd ${CMAKE_BINARY_DIR}/examples/msg/)
-  ADD_TEST(memcheck-msg-token-ring-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/msg/token_ring/two_clusters.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
-  ADD_TEST(memcheck-msg-token-ring-raw-1 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/msg/token_ring/two_peers.xml --cfg=network/coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+  ADD_TEST(memcheck-msg-token-ring-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/routing_cluster.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+  ADD_TEST(memcheck-msg-token-ring-raw-1 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/two_peers.xml --cfg=network/coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+  ADD_TEST(memcheck-msg-token-ring-raw-2 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/meta_cluster.xml --log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n --cfg=contexts/factory:raw  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
 endif(HAVE_RAWCTX)
 if(CONTEXT_UCONTEXT)
   ADD_TEST(memcheck-msg-masterslave-vivaldi-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/masterslave/masterslave_mailbox  ${CMAKE_HOME_DIRECTORY}/examples/msg/../platforms/vivaldi.xml ${CMAKE_HOME_DIRECTORY}/examples/msg/masterslave/deployment_masterslave_vivaldi.xml --cfg=network/latency_factor:1.0 --cfg=network/bandwidth_factor:1.0 --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/)
-  ADD_TEST(memcheck-msg-token-ring-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/msg/token_ring/two_clusters.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
-  ADD_TEST(memcheck-msg-token-ring-ucontext-1 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/msg/token_ring/two_peers.xml --cfg=network/coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+  ADD_TEST(memcheck-msg-token-ring-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/routing_cluster.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+  ADD_TEST(memcheck-msg-token-ring-ucontext-1 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/two_peers.xml --cfg=network/coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
+  ADD_TEST(memcheck-msg-token-ring-ucontext-2 ${CMAKE_BINARY_DIR}/examples/msg/token_ring/token_ring ${CMAKE_HOME_DIRECTORY}/examples/platforms/meta_cluster.xml --log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/token_ring/)
 endif(CONTEXT_UCONTEXT)
 
 ADD_TEST(memcheck-msg-migration-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/migration/migration ${CMAKE_HOME_DIRECTORY}/examples/msg/msg_platform.xml ${CMAKE_HOME_DIRECTORY}/examples/msg/migration/migration.deploy  "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_BINARY_DIR}/examples/msg/)
@@ -258,10 +262,10 @@ ADD_TEST(memcheck-msg-chord-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/chord/chor
 ADD_TEST(memcheck-msg-chord-thread-1 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord ./../../platforms/cluster.xml ./chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
 ADD_TEST(memcheck-msg-chord-thread-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord -nb_bits=6 ./../msg_platform.xml ./chord.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/nthreads:4 --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
 ADD_TEST(memcheck-msg-chord-thread-parallel-1 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord ./../../platforms/cluster.xml ./chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant --cfg=contexts/nthreads:4 --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
-ADD_TEST(memcheck-msg-bittorrent-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
-ADD_TEST(memcheck-msg-bittorrent-thread-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
-ADD_TEST(memcheck-msg-kademlia-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
-ADD_TEST(memcheck-msg-kademlia-thread-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
+ADD_TEST(memcheck-msg-bittorrent-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
+ADD_TEST(memcheck-msg-bittorrent-thread-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:thread --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
+ADD_TEST(memcheck-msg-kademlia-thread-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%02i:%P@%h)%e%m%n" --cfg=contexts/factory:thread  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
+ADD_TEST(memcheck-msg-kademlia-thread-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%02i:%P@%h)%e%m%n" --cfg=contexts/factory:thread --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
 
 if(CONTEXT_UCONTEXT)
   ADD_TEST(memcheck-msg-migration-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/migration/migration ${CMAKE_HOME_DIRECTORY}/examples/msg/msg_platform.xml ${CMAKE_HOME_DIRECTORY}/examples/msg/migration/migration.deploy  "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_BINARY_DIR}/examples/msg/)
@@ -299,10 +303,10 @@ if(CONTEXT_UCONTEXT)
   ADD_TEST(memcheck-msg-chord-ucontext-1 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord ./../../platforms/cluster.xml ./chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
   ADD_TEST(memcheck-msg-chord-ucontext-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord -nb_bits=6 ./../msg_platform.xml ./chord.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/nthreads:4 --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
   ADD_TEST(memcheck-msg-chord-ucontext-parallel-1 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord ./../../platforms/cluster.xml ./chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant --cfg=contexts/nthreads:4 --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
-  ADD_TEST(memcheck-msg-bittorrent-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
-  ADD_TEST(memcheck-msg-bittorrent-ucontext-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
-  ADD_TEST(memcheck-msg-kademlia-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
-  ADD_TEST(memcheck-msg-kademlia-ucontext-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
+  ADD_TEST(memcheck-msg-bittorrent-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
+  ADD_TEST(memcheck-msg-bittorrent-ucontext-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
+  ADD_TEST(memcheck-msg-kademlia-ucontext-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%02i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
+  ADD_TEST(memcheck-msg-kademlia-ucontext-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%02i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
 
 endif(CONTEXT_UCONTEXT)
 if(HAVE_RAWCTX)
@@ -341,10 +345,10 @@ if(HAVE_RAWCTX)
   ADD_TEST(memcheck-msg-chord-raw-1 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord ./../../platforms/cluster.xml ./chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
   ADD_TEST(memcheck-msg-chord-raw-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord -nb_bits=6 ./../msg_platform.xml ./chord.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/nthreads:4 --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
   ADD_TEST(memcheck-msg-chord-raw-parallel-1 ${CMAKE_BINARY_DIR}/examples/msg/chord/chord ./../../platforms/cluster.xml ./chord10.xml --log=msg_chord.thres:verbose "--log=root.fmt:[%11.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:Constant --cfg=contexts/nthreads:4 --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/chord/)
-  ADD_TEST(memcheck-msg-bittorrent-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
-  ADD_TEST(memcheck-msg-bittorrent-raw-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
-  ADD_TEST(memcheck-msg-kademlia-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
-  ADD_TEST(memcheck-msg-kademlia-raw-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
+  ADD_TEST(memcheck-msg-bittorrent-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
+  ADD_TEST(memcheck-msg-bittorrent-raw-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/bittorrent/bittorrent ./../msg_platform.xml ./bittorrent.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:raw --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent/)
+  ADD_TEST(memcheck-msg-kademlia-raw-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%02i:%P@%h)%e%m%n" --cfg=contexts/factory:raw  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
+  ADD_TEST(memcheck-msg-kademlia-raw-parallel-0 ${CMAKE_BINARY_DIR}/examples/msg/kademlia/kademlia ./../msg_platform.xml ./kademlia.xml "--log=root.fmt:[%10.6r]%e(%02i:%P@%h)%e%m%n" --cfg=contexts/factory:raw --cfg=contexts/nthreads:4  --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia/)
 endif(HAVE_RAWCTX)
 
 IF(${ARCH_32_BITS})
@@ -469,7 +473,8 @@ ADD_TEST(memcheck-simdag-test-simdag-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_te
 ADD_TEST(memcheck-simdag-test-simdag2-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_test2 ${CMAKE_HOME_DIRECTORY}/examples/simdag/2clusters.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
 ADD_TEST(memcheck-simdag-test-seq-access-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_seq_access ${CMAKE_HOME_DIRECTORY}/examples/simdag/2clusters.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
 ADD_TEST(memcheck-simdag-test-typed-tasks-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_typed_tasks_test --cfg=network/TCP_gamma:4194304 ${CMAKE_HOME_DIRECTORY}/examples/simdag/2clusters.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
-ADD_TEST(memcheck-simdag-test-comm-throttling-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_comm_throttling ${CMAKE_HOME_DIRECTORY}/examples/simdag/2clusters.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
+ADD_TEST(memcheck-simdag-test-fail-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_fail --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
+ADD_TEST(memcheck-simdag-test-comm-throttling-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_comm_throttling --cfg=network/TCP_gamma:4194304 ${CMAKE_HOME_DIRECTORY}/examples/simdag/2clusters.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
 ADD_TEST(memcheck-simdag-test-dax-cycle-0 ${CMAKE_BINARY_DIR}/examples/simdag/dax/dax_test --log=no_loc ${CMAKE_HOME_DIRECTORY}/examples/simdag/dax/../2clusters.xml ${CMAKE_HOME_DIRECTORY}/examples/simdag/dax/simple_dax_with_cycle.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/dax/)
 ADD_TEST(memcheck-simdag-test-prop-0 ${CMAKE_BINARY_DIR}/examples/simdag/properties/sd_prop ${CMAKE_HOME_DIRECTORY}/examples/simdag/../platforms/prop.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/)
 ADD_TEST(memcheck-simdag-test-minmin-scheduling-0 ${CMAKE_BINARY_DIR}/examples/simdag/scheduling/minmin_test --log=sd_daxparse.thresh:critical ./simulacrum_7_hosts.xml ./Montage_25.xml --cd ${CMAKE_HOME_DIRECTORY}/examples/simdag/scheduling/)
index dd5500a..4fb36d4 100644 (file)
@@ -157,7 +157,7 @@ complicated pattern aiming at following the actual dependencies.
 
 The analytical models handle a lot of floating point values. It is
 possible to change the epsilon used to update and compare them through
-the \b maxmin/precision item (default value: 1e-9). Changing it
+the \b maxmin/precision item (default value: 0.00001). Changing it
 may speedup the simulation by discarding very small actions, at the
 price of a reduced numerical precision.
 
@@ -448,6 +448,25 @@ smpirun -trace ...
 simulation with --cfg=tracing:1 and --cfg=tracing/smpi:1. Check the
 smpirun's <i>-help</i> parameter for additional tracing options.
 
+Sometimes you might want to put additional information on the trace to
+correctly identify them later, or to provide data that can be used to
+reproduce an experiment. You have two ways to do that:
+
+- Add a string on top of the trace file as comment:
+\verbatim
+--cfg=tracing/comment:my_simulation_identifier
+\endverbatim
+
+- Add the contents of a textual file on top of the trace file as comment:
+\verbatim
+--cfg=tracing/comment_file:my_file_with_additional_information.txt
+\endverbatim
+
+Please, use these two parameters (for comments) to make reproducible
+simulations. For additional details about this and all tracing
+options, check See the \ref tracing_tracing_options "Tracing
+Configuration Options subsection".
+
 \section options_smpi Configuring SMPI
 
 The SMPI interface provides several specific configuration items.
@@ -506,6 +525,12 @@ code, but it can reveal troublesome in some cases (such as when the
 amount of processes becomes really big). This behavior is disabled
 when \b verbose-exit is set to 0 (it is to 1 by default).
 
+
+\section options_log Logging Configuration
+
+It can be done by using XBT. Go to \ref XBT_log for more details.
+
+
 \section options_index Index of all existing configuration items
 
 - \c contexts/factory: \ref options_virt_factory
index 72d45f1..e33d8d9 100644 (file)
@@ -247,13 +247,13 @@ The principle is the same, except we don't have the backbone. The way to obtain
 \li <b>bw (mandatory)</b>: bandwidth for the links between nodes and backbone (if any). See <b>link</b> section for syntax/details.
 \li <b>lat (mandatory)</b>: latency for the links between nodes and backbone (if any). See <b>link</b> section for syntax/details.
 \li <b>sharing_policy</b>: sharing policy for the links between nodes and backbone (if any). See <b>link</b> section for syntax/details.
-\li <b>bb_bw </b>: bandwidth for backbone (if any). See <b>link</b> section for syntax/details. If both bb_* attributes are ommited, no backbone is create (alternative cluster architecture described before).
-\li <b>bb_lat </b>: latency for backbone (if any). See <b>link</b> section for syntax/details. If both bb_* attributes are ommited, no backbone is create (alternative cluster architecture described before).
+\li <b>bb_bw </b>: bandwidth for backbone (if any). See <b>link</b> section for syntax/details. If both bb_* attributes are ommited, no backbone is created (alternative cluster architecture described before).
+\li <b>bb_lat </b>: latency for backbone (if any). See <b>link</b> section for syntax/details. If both bb_* attributes are ommited, no backbone is created (alternative cluster architecture described before).
 \li <b>bb_sharing_policy</b>: sharing policy for the backbone (if any). See <b>link</b> section for syntax/details.
 \li <b>availability_file</b>: Allow you to use a file as input for availability. Similar to <b>hosts</b> attribute.
 \li <b>state_file</b>: Allow you to use a file as input for states. Similar to <b>hosts</b> attribute.
 
-the router name is defined as the resulting String in the following java line of code: router_name = prefix + "router_ + suffix ;
+the router name is defined as the resulting String in the following java line of code: router_name = prefix + clusterId + router_ + suffix ;
 
 
 <b>cluster example</b>
@@ -264,6 +264,14 @@ the router name is defined as the resulting String in the following java line of
                radical="0-99"  power="1000000000"    bw="125000000"     lat="5E-5"
         bb_bw="2250000000" bb_lat="5E-4"/>
 \endverbatim
+The second examples creates 100 machines, which names are the following:
+\verbatim
+c-0.my_cluster_1.me
+c-1.my_cluster_1.me
+c-2.my_cluster_1.me
+...
+c-99.my_cluster_1.me
+\endverbatim
 
 \subsubsection pf_peer peer
 A <b>peer</b> represents a peer, as in Peer-to-Peer (P2P). Basically, as cluster, <b>A PEER IS INTERNALLY INTERPRETED AS AN \<AS\></b>. It's just a kind of shortcut that does the following :
index 7f0c4d3..a21a049 100644 (file)
@@ -215,6 +215,33 @@ can be used with simulators that have a different notion of time
 --cfg=tracing/disable_destroy:1
 \endverbatim
 
+\li <b>\c
+tracing/basic
+</b>:
+Some visualization tools are not able to parse correctly the Paje file format.
+Use this option if you are using one of these tools to visualize the simulation
+trace. Keep in mind that the trace might be incomplete, without all the
+information that would be registered otherwise.
+\verbatim
+--cfg=tracing/basic:1
+\endverbatim
+
+\li <b>\c
+tracing/comment
+</b>:
+Use this to add a comment line to the top of the trace file.
+\verbatim
+--cfg=tracing/comment:my_string
+\endverbatim
+
+\li <b>\c
+tracing/comment_file
+</b>:
+Use this to add the contents of a file to the top of the trace file as comment.
+\verbatim
+--cfg=tracing/comment_file:textual_file.txt
+\endverbatim
+
 \li <b>\c
 triva/categorized
 </b>:
index 2fdb8e0..cada54a 100644 (file)
@@ -4,9 +4,12 @@ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
 
 add_executable(bittorrent
   "bittorrent.c" "messages.c" "peer.c" "tracker.c" "connection.c")
+add_executable(bittorrent_platfgen
+  "bittorrent_platfgen.c" "messages.c" "peer.c" "tracker.c" "connection.c")
 
 ### Add definitions for compile
 target_link_libraries(bittorrent simgrid )
+target_link_libraries(bittorrent_platfgen simgrid )
 
 set(tesh_files
   ${tesh_files}
@@ -21,6 +24,7 @@ set(xml_files
 set(examples_src
   ${examples_src}
   ${CMAKE_CURRENT_SOURCE_DIR}/bittorrent.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/bittorrent_platfgen.c
   ${CMAKE_CURRENT_SOURCE_DIR}/bittorrent.h
   ${CMAKE_CURRENT_SOURCE_DIR}/connection.c
   ${CMAKE_CURRENT_SOURCE_DIR}/connection.h
diff --git a/examples/msg/bittorrent/bittorrent_platfgen.c b/examples/msg/bittorrent/bittorrent_platfgen.c
new file mode 100644 (file)
index 0000000..ff18530
--- /dev/null
@@ -0,0 +1,144 @@
+/* Copyright (c) 2012. 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 "bittorrent.h"
+#include "peer.h"
+#include "tracker.h"
+#include <msg/msg.h>
+#include <simgrid/platf_generator.h>
+/**
+ * Bittorrent example launcher, using a generated platform
+ */
+
+static RngStream rng_stream;
+
+void promoter(context_node_t node);
+void labeler(context_edge_t edge);
+void create_environment(int node_count);
+void dispatch_jobs(double tracker_deadline, double peer_deadline, double seed_percentage);
+
+void promoter(context_node_t node) {
+  s_sg_platf_host_cbarg_t host_parameters;
+
+  if(node->degree == 1) {
+    //We promote only the leaf; as we use a star topology, all the nodes
+    //will be promoted except the first one, which will be a router with
+    //every hosts connected on.
+    host_parameters.id = NULL;
+
+    //Power from 3,000,000 to 10,000,000
+    host_parameters.power_peak = 7000000 * RngStream_RandU01(rng_stream) + 3000000;
+    host_parameters.core_amount = 1;
+    host_parameters.power_scale = 1;
+    host_parameters.power_trace = NULL;
+    host_parameters.initial_state = SURF_RESOURCE_ON;
+    host_parameters.state_trace = NULL;
+    host_parameters.coord = NULL;
+    host_parameters.properties = NULL;
+
+    platf_graph_promote_to_host(node, &host_parameters);
+  }
+}
+
+void labeler(context_edge_t edge) {
+
+  s_sg_platf_link_cbarg_t link_parameters;
+  link_parameters.id = NULL;
+
+  //bandwidth from 3,000,000 to 10,000,000
+  link_parameters.bandwidth = 7000000 * RngStream_RandU01(rng_stream) + 3000000;
+  link_parameters.bandwidth_trace = NULL;
+
+  //Latency from 0ms to 100ms
+  link_parameters.latency = RngStream_RandU01(rng_stream) / 10.0;
+  link_parameters.latency_trace = NULL;
+  link_parameters.state = SURF_RESOURCE_ON;
+  link_parameters.state_trace = NULL;
+  link_parameters.policy = SURF_LINK_SHARED;
+  link_parameters.properties = NULL;
+
+  platf_graph_link_label(edge, &link_parameters);
+}
+
+void create_environment(int node_count) {
+
+  platf_graph_uniform(node_count);
+
+  //every nodes are connected to the first one
+  platf_graph_interconnect_star();
+  //No need to check if the graph is connected, the star topology implies it.
+
+  //register promoter and labeler
+  platf_graph_promoter(promoter);
+  platf_graph_labeler(labeler);
+
+  //promoting and labeling
+  platf_do_promote();
+  platf_do_label();
+
+  //Put the platform into the simulator
+  platf_generate();
+}
+
+void dispatch_jobs(double tracker_deadline, double peer_deadline, double seed_percentage) {
+
+  xbt_dynar_t available_nodes = MSG_hosts_as_dynar();
+  msg_host_t host;
+  unsigned int i;
+
+  char** arguments_tracker;
+  char** arguments_peer;
+
+  unsigned int seed_count = (seed_percentage/100.0) * xbt_dynar_length(available_nodes);
+
+  xbt_dynar_foreach(available_nodes, i, host) {
+    if(i==0) {
+      //The fisrt node is the tracker
+      arguments_tracker = xbt_malloc0(sizeof(char*) * 2);
+      arguments_tracker[0] = bprintf("tracker");
+      arguments_tracker[1] = bprintf("%f", tracker_deadline);
+      MSG_process_create_with_arguments("tracker", tracker, NULL, host, 2, arguments_tracker);
+    } else {
+      //Other nodes are peers
+      int argument_size;
+      arguments_peer = xbt_malloc0(sizeof(char*) * 4);
+      arguments_peer[0] = bprintf("peer");
+      arguments_peer[1] = bprintf("%d", i);
+      arguments_peer[2] = bprintf("%f", peer_deadline);
+
+      //The first peers will be seeders
+      if(seed_count > 0) {
+        seed_count--;
+        arguments_peer[3] = bprintf("1");
+        argument_size = 4;
+      } else {
+        //Other ars leechers
+        arguments_peer[3] = NULL;
+        argument_size = 3;
+      }
+      MSG_process_create_with_arguments("peer", peer, NULL, host, argument_size, arguments_peer);
+    }
+  }
+}
+
+int main(int argc, char *argv[])
+{
+  MSG_init(&argc, argv);
+
+  rng_stream = RngStream_CreateStream(NULL);
+
+  //Maybe these parameters should be set from the command line...
+  //create_environment(<node_count>)
+  create_environment(20);
+
+  //dispatch_jobs(<tracker_deadline>, <peer_deadline>, <seed_percentage>)
+  dispatch_jobs(2000, 2000, 10);
+
+  MSG_main();
+
+  MSG_clean();
+
+  return 0;
+}
index fbee5bb..7036f56 100644 (file)
@@ -3,12 +3,15 @@ cmake_minimum_required(VERSION 2.6)
 set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
 
 add_executable(file file.c)
+add_executable(file_unlink file_unlink.c)
 
 ### Add definitions for compile
 if(NOT WIN32)
   target_link_libraries(file simgrid m pthread)
+  target_link_libraries(file_unlink simgrid m pthread)
 else(NOT WIN32)
   target_link_libraries(file simgrid)
+  target_link_libraries(file_unlink simgrid)
 endif(NOT WIN32)
 
 set(tesh_files
@@ -23,6 +26,7 @@ set(xml_files
 set(examples_src
   ${examples_src}
   ${CMAKE_CURRENT_SOURCE_DIR}/file.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/file_unlink.c
   PARENT_SCOPE
   )
 set(bin_files
index cdcf901..6769661 100644 (file)
@@ -61,6 +61,7 @@ int host(int argc, char *argv[])
 
   MSG_file_stat(file,&stat);
   XBT_INFO("\tFile stat %s Size %.1f",file->name,stat.size);
+  MSG_file_free_stat(&stat);
 
   XBT_INFO("\tClose file '%s'",file->name);
   MSG_file_close(file);
diff --git a/examples/msg/io/file_unlink.c b/examples/msg/io/file_unlink.c
new file mode 100644 (file)
index 0000000..8a36a78
--- /dev/null
@@ -0,0 +1,130 @@
+/* Copyright (c) 2008, 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. */
+
+/** @addtogroup MSG_examples
+ * 
+ * @subsection MSG_ex_resources Other resource kinds
+ * 
+ * This section contains some sparse examples of how to use the other
+ * kind of resources, such as disk or GPU. These resources are quite
+ * experimental for now, but here we go anyway.
+ * 
+ * - <b>io/file.c</b> Example with the disk resource
+ */
+
+#define FILENAME1 "./doc/simgrid/examples/platforms/g5k.xml"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "msg/msg.h"
+#include "surf/surf_private.h"
+
+int host(int argc, char *argv[]);
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(io_file,
+                             "Messages specific for this io example");
+
+int host(int argc, char *argv[])
+{
+  msg_file_t file = NULL;
+  s_msg_stat_t stat;
+  void *ptr = NULL;
+  char* mount = bprintf("/home");
+  double write;
+
+  // First open
+  XBT_INFO("\tOpen file '%s'",FILENAME1);
+  file = MSG_file_open(mount,FILENAME1,"rw");
+
+  // Print stat
+  MSG_file_stat(file,&stat);
+  XBT_INFO("\tFile stat %s Size %.1f",file->name,stat.size);
+  MSG_file_free_stat(&stat);
+
+  // Unlink the file
+  XBT_INFO("\tUnlink file '%s'",file->name);
+  MSG_file_unlink(file);
+
+  // Re Open the file wich is in fact created
+  XBT_INFO("\tOpen file '%s'",FILENAME1);
+  file = MSG_file_open(mount,FILENAME1,"rw");
+
+  // Print stat
+  MSG_file_stat(file,&stat);
+  XBT_INFO("\tFile stat %s Size %.1f",file->name,stat.size);
+  MSG_file_free_stat(&stat);
+
+  // Write into the new file
+  write = MSG_file_write(ptr,100000,sizeof(char*),file);  // Write for 100Ko
+  XBT_INFO("\tHaving write %.1f \ton %s",write,file->name);
+
+  // Print the stat
+  MSG_file_stat(file,&stat);
+  XBT_INFO("\tFile stat %s Size %.1f",file->name,stat.size);
+  MSG_file_free_stat(&stat);
+
+  // Close the file
+  XBT_INFO("\tClose file '%s'",file->name);
+  MSG_file_close(file);
+
+  xbt_dict_t dict_ls;
+  char* key;
+  surf_stat_t data = NULL;
+  xbt_dict_cursor_t cursor = NULL;
+
+  dict_ls = MSG_file_ls(mount,"./");
+  XBT_INFO(" ");XBT_INFO("ls ./");
+  xbt_dict_foreach(dict_ls,cursor,key,data){
+    if(data) XBT_INFO("FILE : %s",key);
+    else     XBT_INFO("DIR  : %s",key);
+  }
+  xbt_dict_free(&dict_ls);
+
+  dict_ls = MSG_file_ls(mount,"./doc/simgrid/examples/platforms/");
+  XBT_INFO(" ");XBT_INFO("ls ./doc/simgrid/examples/platforms/");
+  xbt_dict_foreach(dict_ls,cursor,key,data){
+    if(data) XBT_INFO("FILE : %s",key);
+    else     XBT_INFO("DIR  : %s",key);
+  }
+  xbt_dict_free(&dict_ls);
+
+  dict_ls = MSG_file_ls(mount,"./doc/simgrid/examples/msg/");
+  XBT_INFO(" ");XBT_INFO("ls ./doc/simgrid/examples/msg/");
+  xbt_dict_foreach(dict_ls,cursor,key,data){
+    if(data) XBT_INFO("FILE : %s",key);
+    else     XBT_INFO("DIR  : %s",key);
+  }
+  xbt_dict_free(&dict_ls);
+
+  free(mount);
+
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  int res;
+  MSG_init(&argc, argv);
+  MSG_create_environment(argv[1]);
+  xbt_dynar_t hosts =  MSG_hosts_as_dynar();
+  MSG_function_register("host", host);
+  unsigned long nb_hosts = xbt_dynar_length(hosts);
+  XBT_INFO("Number of host '%lu'",nb_hosts);
+  char* name_host = bprintf("0");
+  MSG_process_create( name_host, host, NULL, xbt_dynar_get_as(hosts,0,msg_host_t) );
+  free(name_host);
+
+  xbt_dynar_free(&hosts);
+
+  res = MSG_main();
+  XBT_INFO("Simulation time %g", MSG_get_clock());
+  MSG_clean();
+  if (res == MSG_OK)
+    return 0;
+  else
+    return 1;
+
+}
index 8f1131f..4dbe954 100644 (file)
@@ -28,3 +28,64 @@ $ ${bindir:=.}/io/file ${srcdir:=.}/examples/platforms/storage.xml "--log=root.f
 > [  0.004786] (3:2@carl)      File stat ./doc/simgrid/examples/platforms/g5k_cabinets.xml Size 122645.0
 > [  0.004786] (3:2@carl)      Close file './doc/simgrid/examples/platforms/g5k_cabinets.xml'
 > [  0.004786] (0:@) Simulation time 0.00478623
+
+$ ${bindir:=.}/io/file_unlink ${srcdir:=.}/examples/platforms/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (0:@) Configuration change: Set 'path' to '../examples/platforms/'
+> [  0.000000] (0:@) Number of host '4'
+> [  0.000000] (1:0@denise)    Open file './doc/simgrid/examples/platforms/g5k.xml'
+> [  0.000000] (1:0@denise)    File stat ./doc/simgrid/examples/platforms/g5k.xml Size 17028.0
+> [  0.000000] (1:0@denise)    Unlink file './doc/simgrid/examples/platforms/g5k.xml'
+> [  0.000000] (1:0@denise)    Open file './doc/simgrid/examples/platforms/g5k.xml'
+> [  0.000000] (1:0@denise)    File stat ./doc/simgrid/examples/platforms/g5k.xml Size 0.0
+> [  0.003333] (1:0@denise)    Having write 100000.0   on ./doc/simgrid/examples/platforms/g5k.xml
+> [  0.003333] (1:0@denise)    File stat ./doc/simgrid/examples/platforms/g5k.xml Size 100000.0
+> [  0.003333] (1:0@denise)    Close file './doc/simgrid/examples/platforms/g5k.xml'
+> [  0.003333] (1:0@denise)  
+> [  0.003333] (1:0@denise) ls ./
+> [  0.003333] (1:0@denise) DIR  : include
+> [  0.003333] (1:0@denise) DIR  : lib
+> [  0.003333] (1:0@denise) DIR  : bin
+> [  0.003333] (1:0@denise) DIR  : doc
+> [  0.003333] (1:0@denise)  
+> [  0.003333] (1:0@denise) ls ./doc/simgrid/examples/platforms/
+> [  0.003333] (1:0@denise) FILE : lcg_sept2004_grid.xml
+> [  0.003333] (1:0@denise) FILE : prop.xml
+> [  0.003333] (1:0@denise) FILE : multicore_machine.xml
+> [  0.003333] (1:0@denise) FILE : g5k.xml
+> [  0.003333] (1:0@denise) FILE : vivaldi.xml
+> [  0.003333] (1:0@denise) FILE : gdx.xml
+> [  0.003333] (1:0@denise) FILE : griffon.xml
+> [  0.003333] (1:0@denise) FILE : Two_clusters.xml
+> [  0.003333] (1:0@denise) FILE : One_cluster_no_backbone.xml
+> [  0.003333] (1:0@denise) FILE : median_harvard.xml
+> [  0.003333] (1:0@denise) FILE : nancy.xml
+> [  0.003333] (1:0@denise) FILE : One_cluster.xml
+> [  0.003333] (1:0@denise) FILE : g5k_cabinets.xml
+> [  0.003333] (1:0@denise) FILE : gridpp_grid_2004.xml
+> [  0.003333] (1:0@denise)  
+> [  0.003333] (1:0@denise) ls ./doc/simgrid/examples/msg/
+> [  0.003333] (1:0@denise) DIR  : parallel_contexts
+> [  0.003333] (1:0@denise) DIR  : alias
+> [  0.003333] (1:0@denise) DIR  : trace
+> [  0.003333] (1:0@denise) FILE : small_platform.xml
+> [  0.003333] (1:0@denise) DIR  : priority
+> [  0.003333] (1:0@denise) DIR  : tracing
+> [  0.003333] (1:0@denise) DIR  : properties
+> [  0.003333] (1:0@denise) FILE : README
+> [  0.003333] (1:0@denise) DIR  : chord
+> [  0.003333] (1:0@denise) DIR  : mc
+> [  0.003333] (1:0@denise) DIR  : gtnets
+> [  0.003333] (1:0@denise) DIR  : suspend
+> [  0.003333] (1:0@denise) FILE : small_platform_with_routers.xml
+> [  0.003333] (1:0@denise) DIR  : pmm
+> [  0.003333] (1:0@denise) FILE : msg_platform.xml
+> [  0.003333] (1:0@denise) DIR  : token_ring
+> [  0.003333] (1:0@denise) DIR  : actions
+> [  0.003333] (1:0@denise) FILE : small_platform_with_failures.xml
+> [  0.003333] (1:0@denise) DIR  : ns3
+> [  0.003333] (1:0@denise) DIR  : sendrecv
+> [  0.003333] (1:0@denise) DIR  : parallel_task
+> [  0.003333] (1:0@denise) DIR  : masterslave
+> [  0.003333] (1:0@denise) DIR  : icomms
+> [  0.003333] (1:0@denise) DIR  : migration
+> [  0.003333] (0:@) Simulation time 0.00333333
\ No newline at end of file
index c2fdc98..e68e0da 100644 (file)
@@ -10,6 +10,8 @@ add_executable(masterslave_console "masterslave_console.c")
 add_executable(masterslave_cluster "masterslave_cluster.c")
 add_executable(masterslave_kill "masterslave_kill.c")
 add_executable(masterslave_arg "masterslave_arg.c")
+add_executable(masterslave_platfgen "masterslave_platfgen.c")
+add_executable(masterslave_failure_platfgen "masterslave_failure_platfgen.c")
 
 ### Add definitions for compile
 if(WIN32)
@@ -20,6 +22,8 @@ if(WIN32)
   target_link_libraries(masterslave_console simgrid )
   target_link_libraries(masterslave_kill simgrid )
   target_link_libraries(masterslave_arg simgrid )
+  target_link_libraries(masterslave_platfgen simgrid )
+  target_link_libraries(masterslave_failure_platfgen simgrid )
 else(WIN32)
   target_link_libraries(masterslave_forwarder simgrid m )
   target_link_libraries(masterslave_failure simgrid m )
@@ -28,6 +32,8 @@ else(WIN32)
   target_link_libraries(masterslave_console simgrid m )
   target_link_libraries(masterslave_kill simgrid m )
   target_link_libraries(masterslave_arg simgrid m )
+  target_link_libraries(masterslave_platfgen simgrid m )
+  target_link_libraries(masterslave_failure_platfgen simgrid m )
 endif(WIN32)
 target_link_libraries(masterslave_cluster simgrid)
 
@@ -73,6 +79,8 @@ set(examples_src
   ${CMAKE_CURRENT_SOURCE_DIR}/masterslave_forwarder.c
   ${CMAKE_CURRENT_SOURCE_DIR}/masterslave_kill.c
   ${CMAKE_CURRENT_SOURCE_DIR}/masterslave_mailbox.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/masterslave_platfgen.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/masterslave_failure_platfgen.c
   PARENT_SCOPE
   )
 set(bin_files
diff --git a/examples/msg/masterslave/masterslave_failure_platfgen.c b/examples/msg/masterslave/masterslave_failure_platfgen.c
new file mode 100644 (file)
index 0000000..8194e32
--- /dev/null
@@ -0,0 +1,348 @@
+/* Copyright (c) 2007, 2008, 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 <stdio.h>
+#include "msg/msg.h"            /* Yeah! If you want to use msg, you need to include msg/msg.h */
+#include "xbt/sysdep.h"         /* calloc, printf */
+
+/* Create a log channel to have nice outputs. */
+#include "xbt/log.h"
+#include "xbt/asserts.h"
+
+/* we are going to use a generated platform */
+#include "simgrid/platf_generator.h"
+#include "simgrid/platf_interface.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
+                             "Messages specific for this msg example");
+
+int master(int argc, char *argv[]);
+int slave(int argc, char *argv[]);
+void promoter_1(context_node_t node);
+void labeler_1(context_edge_t edge);
+
+#define FINALIZE ((void*)221297)        /* a magic number to tell people to stop working */
+
+#define TASK_COUNT_PER_HOST 5           /* Number of tasks each slave has to do */
+#define TASK_COMP_SIZE 15000000         /* computation cost of each task */
+#define TASK_COMM_SIZE 1200000          /* communication time of task */
+
+/** Promoter function
+ * Just promote each node into a host, with fixed power
+ * Set one node as master
+ * Add a state trace on other nodes
+ */
+void promoter_1(context_node_t node) {
+
+  s_sg_platf_host_cbarg_t host_parameters;
+  static int master_choosen = FALSE;
+
+  host_parameters.id = NULL;
+  host_parameters.power_peak = 1000000;
+
+  host_parameters.core_amount = 1;
+  host_parameters.power_scale = 1;
+  host_parameters.power_trace = NULL;
+  host_parameters.initial_state = SURF_RESOURCE_ON;
+  host_parameters.state_trace = NULL;
+  host_parameters.coord = NULL;
+  host_parameters.properties = NULL;
+
+  if(!master_choosen) {
+    master_choosen = TRUE;
+    host_parameters.id = "host_master";
+  } else {
+    /*
+     * The bug #14699 cannot allow us to set up an event trace which
+     * begin by SURF_RESOURCE_OFF, otherwise, the host will be down at startup
+     * and the associate process will fail to start. So, here, we generate a
+     * first useless event.
+     */
+    //Set a availability trace for the node
+    char* generator_id = bprintf("state_host_%ld", node->id);
+    probabilist_event_generator_t date_generator =
+                            tmgr_event_generator_new_weibull(generator_id, 80, 1.5);
+    host_parameters.state_trace = tmgr_trace_generator_state(generator_id,
+                                                            date_generator,
+                                                            SURF_RESOURCE_ON);
+
+    //Set a power trace
+    char* pw_date_generator_id = bprintf("pw_date_host_%ld", node->id);
+    char* pw_value_generator_id = bprintf("pw_value_host_%ld", node->id);
+    probabilist_event_generator_t pw_date_generator =
+                          tmgr_event_generator_new_uniform(pw_date_generator_id, 5, 10);
+    probabilist_event_generator_t pw_value_generator =
+                          tmgr_event_generator_new_uniform(pw_value_generator_id, 0.6, 1.0);
+    host_parameters.power_trace =
+              tmgr_trace_generator_value(bprintf("pw_host_%ld", node->id),
+                                                pw_date_generator,
+                                                pw_value_generator);
+  }
+
+  platf_graph_promote_to_host(node, &host_parameters);
+
+}
+
+/** Labeler function
+ * Set all links with the same bandwidth and latency
+ * Add a state trace to each link
+ */
+void labeler_1(context_edge_t edge) {
+  s_sg_platf_link_cbarg_t link_parameters;
+  link_parameters.id = NULL;
+  link_parameters.bandwidth = 100000000;
+  link_parameters.bandwidth_trace = NULL;
+  link_parameters.latency = 0.01;
+  link_parameters.latency_trace = NULL;
+  link_parameters.state = SURF_RESOURCE_ON;
+  link_parameters.state_trace = NULL;
+  link_parameters.policy = SURF_LINK_SHARED;
+  link_parameters.properties = NULL;
+
+  char* avail_generator_id = bprintf("avail_link_%ld", edge->id);
+  char* unavail_generator_id = bprintf("unavail_link_%ld", edge->id);
+
+  probabilist_event_generator_t avail_generator =
+                          tmgr_event_generator_new_exponential(avail_generator_id, 0.0001);
+  probabilist_event_generator_t unavail_generator =
+                          tmgr_event_generator_new_uniform(unavail_generator_id, 10, 20);
+
+  link_parameters.state_trace =
+              tmgr_trace_generator_avail_unavail(bprintf("state_link_%ld", edge->id),
+                                                avail_generator,
+                                                unavail_generator,
+                                                SURF_RESOURCE_ON);
+
+
+  platf_graph_link_label(edge, &link_parameters);
+
+}
+
+/** Emitter function  */
+int master(int argc, char *argv[])
+{
+  int slaves_count = 0;
+  msg_host_t *slaves = NULL;
+  int number_of_tasks = 0;
+  double task_comp_size = 0;
+  double task_comm_size = 0;
+  int i;
+  _XBT_GNUC_UNUSED int read;
+
+  number_of_tasks = TASK_COUNT_PER_HOST*argc;
+  task_comp_size = TASK_COMP_SIZE;
+  task_comm_size = TASK_COMM_SIZE;
+
+  {                             /* Process organisation */
+    slaves_count = argc;
+    slaves = xbt_new0(msg_host_t, slaves_count);
+
+    for (i = 0; i < argc; i++) {
+      slaves[i] = MSG_get_host_by_name(argv[i]);
+      if (slaves[i] == NULL) {
+        XBT_INFO("Unknown host %s. Stopping Now! ", argv[i]);
+        abort();
+      }
+    }
+  }
+
+  XBT_INFO("Got %d slave(s) :", slaves_count);
+  for (i = 0; i < slaves_count; i++)
+    XBT_INFO("%s", MSG_host_get_name(slaves[i]));
+
+  XBT_INFO("Got %d task to process :", number_of_tasks);
+
+  for (i = 0; i < number_of_tasks; i++) {
+    msg_task_t task = MSG_task_create("Task", task_comp_size, task_comm_size,
+                                    xbt_new0(double, 1));
+    int a;
+    *((double *) task->data) = MSG_get_clock();
+
+    a = MSG_task_send_with_timeout(task,MSG_host_get_name(slaves[i % slaves_count]),10.0);
+
+    if (a == MSG_OK) {
+      XBT_INFO("Send completed");
+    } else if (a == MSG_HOST_FAILURE) {
+      XBT_INFO
+          ("Gloups. The cpu on which I'm running just turned off!. See you!");
+      free(task->data);
+      MSG_task_destroy(task);
+      free(slaves);
+      return 0;
+    } else if (a == MSG_TRANSFER_FAILURE) {
+      XBT_INFO
+          ("Mmh. Something went wrong with '%s'. Nevermind. Let's keep going!",
+              MSG_host_get_name(slaves[i % slaves_count]));
+      free(task->data);
+      MSG_task_destroy(task);
+    } else if (a == MSG_TIMEOUT) {
+      XBT_INFO
+          ("Mmh. Got timeouted while speaking to '%s'. Nevermind. Let's keep going!",
+              MSG_host_get_name(slaves[i % slaves_count]));
+      free(task->data);
+      MSG_task_destroy(task);
+    } else {
+      XBT_INFO("Hey ?! What's up ? ");
+      xbt_die( "Unexpected behavior");
+    }
+  }
+
+  XBT_INFO
+      ("All tasks have been dispatched. Let's tell everybody the computation is over.");
+  for (i = 0; i < slaves_count; i++) {
+    msg_task_t task = MSG_task_create("finalize", 0, 0, FINALIZE);
+    int a = MSG_task_send_with_timeout(task,MSG_host_get_name(slaves[i]),1.0);
+    if (a == MSG_OK)
+      continue;
+    if (a == MSG_HOST_FAILURE) {
+      XBT_INFO
+          ("Gloups. The cpu on which I'm running just turned off!. See you!");
+      MSG_task_destroy(task);
+      free(slaves);
+      return 0;
+    } else if (a == MSG_TRANSFER_FAILURE) {
+      XBT_INFO("Mmh. Can't reach '%s'! Nevermind. Let's keep going!",
+          MSG_host_get_name(slaves[i]));
+      MSG_task_destroy(task);
+    } else if (a == MSG_TIMEOUT) {
+      XBT_INFO
+          ("Mmh. Got timeouted while speaking to '%s'. Nevermind. Let's keep going!",
+              MSG_host_get_name(slaves[i % slaves_count]));
+      MSG_task_destroy(task);
+    } else {
+      XBT_INFO("Hey ?! What's up ? ");
+      xbt_die("Unexpected behavior with '%s': %d", MSG_host_get_name(slaves[i]), a);
+    }
+  }
+
+  XBT_INFO("Goodbye now!");
+  free(slaves);
+  return 0;
+}                               /* end_of_master */
+
+/** Receiver function  */
+int slave(int argc, char *argv[])
+{
+  while (1) {
+    msg_task_t task = NULL;
+    int a;
+    double time1, time2;
+
+    time1 = MSG_get_clock();
+    a = MSG_task_receive( &(task), MSG_host_get_name(MSG_host_self()) );
+    time2 = MSG_get_clock();
+    if (a == MSG_OK) {
+      XBT_INFO("Received \"%s\"", MSG_task_get_name(task));
+      if (MSG_task_get_data(task) == FINALIZE) {
+        MSG_task_destroy(task);
+        break;
+      }
+      if (time1 < *((double *) task->data))
+        time1 = *((double *) task->data);
+      XBT_INFO("Communication time : \"%f\"", time2 - time1);
+      XBT_INFO("Processing \"%s\"", MSG_task_get_name(task));
+      a = MSG_task_execute(task);
+      if (a == MSG_OK) {
+        XBT_INFO("\"%s\" done", MSG_task_get_name(task));
+        free(task->data);
+        MSG_task_destroy(task);
+      } else if (a == MSG_HOST_FAILURE) {
+        XBT_INFO
+            ("Gloups. The cpu on which I'm running just turned off!. See you!");
+        return 0;
+      } else {
+        XBT_INFO("Hey ?! What's up ? ");
+        xbt_die("Unexpected behavior");
+      }
+    } else if (a == MSG_HOST_FAILURE) {
+      XBT_INFO
+          ("Gloups. The cpu on which I'm running just turned off!. See you!");
+      return 0;
+    } else if (a == MSG_TRANSFER_FAILURE) {
+      XBT_INFO("Mmh. Something went wrong. Nevermind. Let's keep going!");
+    } else if (a == MSG_TIMEOUT) {
+      XBT_INFO("Mmh. Got a timeout. Nevermind. Let's keep going!");
+    } else {
+      XBT_INFO("Hey ?! What's up ? ");
+      xbt_die("Unexpected behavior");
+    }
+  }
+  XBT_INFO("I'm done. See you!");
+  return 0;
+}                               /* end_of_slave */
+
+/** Main function */
+int main(int argc, char *argv[])
+{
+  msg_error_t res = MSG_OK;
+  unsigned long seed_platf_gen[] = {134, 233445, 865, 2634, 424242, 876543};
+  unsigned long seed_trace_gen[] = {8865244, 356772, 42, 77465, 2098754, 8725442};
+  int connected;
+  int max_tries = 10;
+
+  //MSG initialisation
+  MSG_init(&argc, argv);
+
+  //Set up the seed for the platform generation
+  platf_random_seed(seed_platf_gen);
+
+  //Set up the RngStream for trace generation
+  sg_platf_rng_stream_init(seed_trace_gen);
+
+  XBT_INFO("creating nodes...");
+  platf_graph_uniform(10);
+
+  do {
+    max_tries--;
+    XBT_INFO("creating links...");
+    platf_graph_clear_links();
+    platf_graph_interconnect_waxman(0.9, 0.4);
+    XBT_INFO("done. Check connectedness...");
+    connected = platf_graph_is_connected();
+    XBT_INFO("Is it connected : %s", connected ? "yes" : (max_tries ? "no, retrying" : "no"));
+  } while(!connected && max_tries);
+
+  if(!connected && !max_tries) {
+    xbt_die("Impossible to connect the graph, aborting.");
+  }
+
+  XBT_INFO("registering callbacks...");
+  platf_graph_promoter(promoter_1);
+  platf_graph_labeler(labeler_1);
+
+  XBT_INFO("protmoting...");
+  platf_do_promote();
+
+  XBT_INFO("labeling...");
+  platf_do_label();
+
+  XBT_INFO("Putting it in surf...");
+  platf_generate();
+
+  XBT_INFO("Let's get the available hosts and dispatch work:");
+
+  unsigned int i;
+  msg_host_t host = NULL;
+  msg_host_t host_master = NULL;
+  msg_process_t process = NULL;
+  xbt_dynar_t host_dynar = MSG_hosts_as_dynar();
+  char** hostname_list = malloc(sizeof(char*) * xbt_dynar_length(host_dynar));
+
+  xbt_dynar_foreach(host_dynar, i, host) {
+    process = MSG_process_create("slave", slave, NULL, host);
+    MSG_process_auto_restart_set(process, TRUE);
+    hostname_list[i] = (char*) MSG_host_get_name(host);
+  }
+  host_master = MSG_get_host_by_name("host_master");
+  MSG_process_create_with_arguments("master", master, NULL, host_master, xbt_dynar_length(host_dynar), hostname_list);
+
+  res = MSG_main();
+
+  if (res == MSG_OK)
+    return 0;
+  else
+    return 1;
+}                               /* end_of_main */
diff --git a/examples/msg/masterslave/masterslave_platfgen.c b/examples/msg/masterslave/masterslave_platfgen.c
new file mode 100644 (file)
index 0000000..e26fb1d
--- /dev/null
@@ -0,0 +1,232 @@
+
+#include "simgrid/platf_generator.h"
+#include "xbt.h"
+#include "msg/msg.h"
+
+#include "xbt/log.h"
+XBT_LOG_NEW_DEFAULT_CATEGORY(test_generation,
+                             "Messages specific for this msg example");
+
+
+#define FINALIZE ((void*)221297)        /* a magic number to tell people to stop working */
+
+void promoter_1(context_node_t node);
+void labeler_1(context_edge_t edge);
+int master(int argc, char *argv[]);
+int slave(int argc, char *argv[]);
+
+
+/** Promoter function
+ * Just promote each node into a host, with fixed power
+ */
+void promoter_1(context_node_t node) {
+
+  s_sg_platf_host_cbarg_t host_parameters;
+
+  host_parameters.id = NULL;
+  host_parameters.power_peak = 1000000;
+
+  host_parameters.core_amount = 1;
+  host_parameters.power_scale = 1;
+  host_parameters.power_trace = NULL;
+  host_parameters.initial_state = SURF_RESOURCE_ON;
+  host_parameters.state_trace = NULL;
+  host_parameters.coord = NULL;
+  host_parameters.properties = NULL;
+
+  platf_graph_promote_to_host(node, &host_parameters);
+
+}
+
+/** Labeler function
+ * Set all links with the same bandwidth and latency
+ */
+void labeler_1(context_edge_t edge) {
+  s_sg_platf_link_cbarg_t link_parameters;
+  link_parameters.id = NULL;
+  link_parameters.bandwidth = 1000000;
+  link_parameters.bandwidth_trace = NULL;
+  link_parameters.latency = 0.01;
+  link_parameters.latency_trace = NULL;
+  link_parameters.state = SURF_RESOURCE_ON;
+  link_parameters.state_trace = NULL;
+  link_parameters.policy = SURF_LINK_SHARED;
+  link_parameters.properties = NULL;
+
+  platf_graph_link_label(edge, &link_parameters);
+}
+
+/** Emitter function  */
+int master(int argc, char *argv[])
+{
+  int slaves_count = 0;
+  msg_host_t *slaves = NULL;
+  int number_of_tasks = 0;
+  double task_comp_size = 0;
+  double task_comm_size = 0;
+  int i;
+
+  number_of_tasks = 3*argc;
+  task_comp_size = 2400000*argc;
+  task_comm_size = 1000000;
+
+  {                             /* Process organisation */
+    slaves_count = argc;
+    slaves = xbt_new0(msg_host_t, slaves_count);
+
+    for (i = 0; i < argc; i++) {
+      slaves[i] = MSG_get_host_by_name(argv[i]);
+      if (slaves[i] == NULL) {
+        XBT_INFO("Unknown host %s. Stopping Now! ", argv[i]);
+        abort();
+      }
+    }
+  }
+
+  XBT_INFO("Got %d slave(s) :", slaves_count);
+  for (i = 0; i < slaves_count; i++)
+    XBT_INFO("%s", MSG_host_get_name(slaves[i]));
+
+  XBT_INFO("Got %d task to process :", number_of_tasks);
+
+  for (i = 0; i < number_of_tasks; i++) {
+    msg_task_t task = MSG_task_create("Task", task_comp_size, task_comm_size,
+                                    xbt_new0(double, 1));
+    int a;
+    *((double *) task->data) = MSG_get_clock();
+
+    a = MSG_task_send(task,MSG_host_get_name(slaves[i % slaves_count]));
+
+    if (a == MSG_OK) {
+      XBT_INFO("Send completed");
+    } else {
+      XBT_INFO("Hey ?! What's up ? ");
+      xbt_die( "Unexpected behavior");
+    }
+  }
+
+  XBT_INFO
+      ("All tasks have been dispatched. Let's tell everybody the computation is over.");
+  for (i = 0; i < slaves_count; i++) {
+    msg_task_t task = MSG_task_create("finalize", 0, 0, FINALIZE);
+    int a = MSG_task_send(task,MSG_host_get_name(slaves[i]));
+    if (a != MSG_OK) {
+      XBT_INFO("Hey ?! What's up ? ");
+      xbt_die("Unexpected behavior with '%s': %d", MSG_host_get_name(slaves[i]), a);
+    }
+  }
+
+  XBT_INFO("Goodbye now!");
+  free(slaves);
+  return 0;
+}                               /* end_of_master */
+
+/** Receiver function  */
+int slave(int argc, char *argv[])
+{
+  while (1) {
+    msg_task_t task = NULL;
+    int a;
+    double time1, time2;
+
+    time1 = MSG_get_clock();
+    a = MSG_task_receive( &(task), MSG_host_get_name(MSG_host_self()) );
+    time2 = MSG_get_clock();
+    if (a == MSG_OK) {
+      XBT_INFO("Received \"%s\"", MSG_task_get_name(task));
+      if (MSG_task_get_data(task) == FINALIZE) {
+        MSG_task_destroy(task);
+        break;
+      }
+      if (time1 < *((double *) task->data))
+        time1 = *((double *) task->data);
+      XBT_INFO("Communication time : \"%f\"", time2 - time1);
+      XBT_INFO("Processing \"%s\"", MSG_task_get_name(task));
+      a = MSG_task_execute(task);
+      if (a == MSG_OK) {
+        XBT_INFO("\"%s\" done", MSG_task_get_name(task));
+        free(task->data);
+        MSG_task_destroy(task);
+      } else {
+        XBT_INFO("Hey ?! What's up ? ");
+        xbt_die("Unexpected behavior");
+      }
+    } else {
+      XBT_INFO("Hey ?! What's up ? error %d", a);
+      xbt_die("Unexpected behavior");
+    }
+  }
+  XBT_INFO("I'm done. See you!");
+  return 0;
+}
+
+/**
+ * Main function
+ * Create the platform, list the available hosts and give them some work
+ */
+int main(int argc, char **argv) {
+
+  unsigned long seed[] = {134, 233445, 865, 2634, 424242, 876543};
+  int connected;
+  int max_tries = 10;
+
+  //MSG initialisation
+  MSG_init(&argc, argv);
+
+  //Set up the seed for the platform generation
+  platf_random_seed(seed);
+
+  XBT_INFO("creating nodes...");
+  platf_graph_uniform(50);
+  do {
+    max_tries--;
+    XBT_INFO("creating links...");
+    platf_graph_clear_links();
+    platf_graph_interconnect_uniform(0.07); //Unrealistic, but simple
+    XBT_INFO("done. Check connectedness...");
+    connected = platf_graph_is_connected();
+    XBT_INFO("Is it connected : %s", connected ? "yes" : (max_tries ? "no, retrying" : "no"));
+  } while(!connected && max_tries);
+
+  if(!connected && !max_tries) {
+    xbt_die("Impossible to connect the graph, aborting.");
+  }
+
+  XBT_INFO("registering callbacks...");
+  platf_graph_promoter(promoter_1);
+  platf_graph_labeler(labeler_1);
+
+  XBT_INFO("protmoting...");
+  platf_do_promote();
+
+  XBT_INFO("labeling...");
+  platf_do_label();
+
+  XBT_INFO("Putting it in surf...");
+  platf_generate();
+
+  XBT_INFO("Let's get the available hosts and dispatch work:");
+
+  unsigned int i;
+  msg_host_t host = NULL;
+  msg_host_t host_master = NULL;
+  xbt_dynar_t host_dynar = MSG_hosts_as_dynar();
+  char** hostname_list = malloc(sizeof(char*) * xbt_dynar_length(host_dynar));
+
+  xbt_dynar_foreach(host_dynar, i, host) {
+    MSG_process_create("slave", slave, NULL, host);
+    if(i==0) {
+      //The first node will also be the master
+      XBT_INFO("%s will be the master", MSG_host_get_name(host));
+      host_master = host;
+    }
+    hostname_list[i] = (char*) MSG_host_get_name(host);
+  }
+
+  MSG_process_create_with_arguments("master", master, NULL, host_master, xbt_dynar_length(host_dynar), hostname_list);
+
+  XBT_INFO("Let's rock!");
+  MSG_main();
+  XBT_INFO("Simulation time %g", MSG_get_clock());
+  return 0;
+}
index eb4186b..c87894e 100644 (file)
@@ -3,12 +3,15 @@ cmake_minimum_required(VERSION 2.6)
 set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
 
 add_executable(token_ring ring_call.c)
+add_executable(token_bypass token_bypass.c)
 
 ### Add definitions for compile
 if(NOT WIN32)
   target_link_libraries(token_ring simgrid m pthread )
+  target_link_libraries(token_bypass simgrid m pthread )
 else(NOT WIN32)
   target_link_libraries(token_ring simgrid)
+  target_link_libraries(token_bypass simgrid)
 endif(NOT WIN32)
 
 set(tesh_files
@@ -23,6 +26,7 @@ set(xml_files
 set(examples_src
   ${examples_src}
   ${CMAKE_CURRENT_SOURCE_DIR}/ring_call.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/token_bypass.c
   PARENT_SCOPE
   )
 set(bin_files
diff --git a/examples/msg/token_ring/token_bypass.c b/examples/msg/token_ring/token_bypass.c
new file mode 100644 (file)
index 0000000..3902008
--- /dev/null
@@ -0,0 +1,130 @@
+/* Copyright (c) 2008, 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 <stdio.h>
+#include <stdlib.h>
+#include "msg/msg.h"
+#include "surf/surf_private.h"
+
+int host(int argc, char *argv[]);
+unsigned int task_comp_size = 50000000;
+unsigned int task_comm_size = 1000000;
+
+int nb_hosts; /* All declared hosts */
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(ring,
+                             "Messages specific for this msg example");
+
+/** @addtogroup MSG_examples
+ * 
+ *  @section MSG_ex_apps Examples of full applications
+ * 
+ * - <b>token_ring/token_bypass.c</b>: Classical token ring with a bypass deployment.
+ *   A token is exchanged along a ring to reach every participant.
+ * 
+ */
+
+int host(int argc, char *argv[])
+{
+  int host_number = atoi(MSG_process_get_name(MSG_process_self()));
+  char mailbox[256];
+  msg_task_t task = NULL;
+  _XBT_GNUC_UNUSED int res;
+  if (host_number == 0){ //master  send then receive
+    sprintf(mailbox, "%d", host_number+1);
+    task = MSG_task_create("Token", task_comp_size, task_comm_size, NULL);
+    XBT_INFO("Host \"%d\" send '%s' to Host \"%s\"",host_number,task->name,mailbox);
+    MSG_task_send(task, mailbox);
+    task = NULL;
+    res = MSG_task_receive(&(task), MSG_process_get_name(MSG_process_self()));
+    xbt_assert(res == MSG_OK, "MSG_task_get failed");
+    XBT_INFO("Host \"%d\" received \"%s\"",host_number, MSG_task_get_name(task));
+    MSG_task_destroy(task);
+  }
+  else{ //slave receive then send
+    res = MSG_task_receive(&(task), MSG_process_get_name(MSG_process_self()));
+    xbt_assert(res == MSG_OK, "MSG_task_get failed");
+    XBT_INFO("Host \"%d\" received \"%s\"",host_number, MSG_task_get_name(task));
+
+    if(host_number+1 == nb_hosts)
+      sprintf(mailbox, "0");
+    else
+      sprintf(mailbox, "%d", host_number+1);
+    XBT_INFO("Host \"%d\" send '%s' to Host \"%s\"",host_number,task->name,mailbox);
+    MSG_task_send(task, mailbox);
+  }
+  return 0;
+}
+
+static int surf_parse_bypass_platform(void)
+{
+  sg_platf_begin();
+  s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+  AS.id = "AS0";
+  AS.routing = A_surfxml_AS_routing_Full;
+  sg_platf_new_AS_begin(&AS);
+
+  s_sg_platf_host_cbarg_t bob = SG_PLATF_HOST_INITIALIZER;
+  bob.id = "bob";
+  bob.power_peak = 98095000;
+  sg_platf_new_host(&bob);
+
+  s_sg_platf_host_cbarg_t alice = SG_PLATF_HOST_INITIALIZER;
+  alice.id = "alice";
+  alice.power_peak = 98095000;
+  sg_platf_new_host(&alice);
+
+  s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
+  link.id = "link1";
+  link.latency = 0.000278066;
+  link.bandwidth = 27946250;
+  sg_platf_new_link(&link);
+
+  s_sg_platf_route_cbarg_t route= SG_PLATF_ROUTE_INITIALIZER;
+  route.src = "bob";
+  route.dst = "alice";
+  sg_platf_route_begin(&route);
+  sg_platf_route_add_link("link1", &route);
+  sg_platf_route_end(&route);
+
+  sg_platf_new_AS_end();
+  sg_platf_end();
+  sg_platf_exit();
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  int i;
+  msg_error_t res = MSG_OK;
+
+  MSG_init(&argc, argv);
+  surf_parse = surf_parse_bypass_platform;
+  MSG_create_environment(NULL);
+
+  MSG_function_register("host", host);
+
+  xbt_dynar_t hosts = MSG_hosts_as_dynar();
+  nb_hosts =  xbt_dynar_length(hosts);
+
+  XBT_INFO("Number of host '%d'",nb_hosts);
+  for(i = 0 ; i<nb_hosts; i++)
+  {
+    char* name_host = bprintf("%d",i);
+    MSG_process_create( name_host, host, NULL, xbt_dynar_get_as(hosts,i,msg_host_t) );
+    free(name_host);
+  }
+  xbt_dynar_free(&hosts);
+
+  res = MSG_main();
+  XBT_INFO("Simulation time %g", MSG_get_clock());
+  MSG_clean();
+  if (res == MSG_OK)
+    return 0;
+  else
+    return 1;
+
+}
index dd577e5..c9dfc19 100644 (file)
@@ -6,113 +6,114 @@ $ $SG_TEST_EXENV ${bindir:=.}/tracing/trace_platform$EXEEXT --cfg=tracing:1 --cf
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to '1'
 
 $ cat simgrid.trace
-> %EventDef PajeDefineContainerType 0 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineVariableType 1 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %       Color color 
-> %EndEventDef 
-> %EventDef PajeDefineStateType 2 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineEventType 3 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineLinkType 4 
-> %       Alias string 
-> %       Type string 
-> %       StartContainerType string 
-> %       EndContainerType string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineEntityValue 5 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %       Color color 
-> %EndEventDef 
-> %EventDef PajeCreateContainer 6 
-> %       Time date 
-> %       Alias string 
-> %       Type string 
-> %       Container string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDestroyContainer 7 
-> %       Time date 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeSetVariable 8 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> #This file was generated using SimGrid-3.8.0
+> %EventDef PajeDefineContainerType 0
+> %       Alias string
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeAddVariable 9 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> %EventDef PajeDefineVariableType 1
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
 > %EndEventDef
-> %EventDef PajeSubVariable 10 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> %EventDef PajeDefineStateType 2
+> %       Alias string
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeSetState 11 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeDefineEventType 3
+> %       Alias string
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajePushState 12 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeDefineLinkType 4
+> %       Alias string
+> %       Type string
+> %       StartContainerType string
+> %       EndContainerType string
+> %       Name string
 > %EndEventDef
-> %EventDef PajePopState 13 
-> %       Time date 
-> %       Type string 
-> %       Container string 
+> %EventDef PajeDefineEntityValue 5
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
 > %EndEventDef
-> %EventDef PajeResetState 14 
-> %       Time date 
-> %       Type string 
-> %       Container string 
+> %EventDef PajeCreateContainer 6
+> %       Time date
+> %       Alias string
+> %       Type string
+> %       Container string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeStartLink 15 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
-> %       StartContainer string 
-> %       Key string 
+> %EventDef PajeDestroyContainer 7
+> %       Time date
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeEndLink 16 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
-> %       EndContainer string 
-> %       Key string 
+> %EventDef PajeSetVariable 8
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
 > %EndEventDef
-> %EventDef PajeNewEvent 17 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeAddVariable 9
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeSubVariable 10
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeSetState 11
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> %EventDef PajePushState 12
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> %EventDef PajePopState 13
+> %       Time date
+> %       Type string
+> %       Container string
+> %EndEventDef
+> %EventDef PajeResetState 14
+> %       Time date
+> %       Type string
+> %       Container string
+> %EndEventDef
+> %EventDef PajeStartLink 15
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       StartContainer string
+> %       Key string
+> %EndEventDef
+> %EventDef PajeEndLink 16
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       EndContainer string
+> %       Key string
+> %EndEventDef
+> %EventDef PajeNewEvent 17
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
 > %EndEventDef
 > 0 1 0 HOST
 > 6 0 1 1 0 "Tremblay"
@@ -217,113 +218,114 @@ $ $SG_TEST_EXENV ${bindir:=.}/tracing/trace_platform$EXEEXT --cfg=tracing:1 --cf
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to '1'
 
 $ cat simgrid.trace
-> %EventDef PajeDefineContainerType 0 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineVariableType 1 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %       Color color 
-> %EndEventDef 
-> %EventDef PajeDefineStateType 2 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineEventType 3 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineLinkType 4 
-> %       Alias string 
-> %       Type string 
-> %       StartContainerType string 
-> %       EndContainerType string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineEntityValue 5 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %       Color color 
-> %EndEventDef 
-> %EventDef PajeCreateContainer 6 
-> %       Time date 
-> %       Alias string 
-> %       Type string 
-> %       Container string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDestroyContainer 7 
-> %       Time date 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeSetVariable 8 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> #This file was generated using SimGrid-3.8.0
+> %EventDef PajeDefineContainerType 0
+> %       Alias string
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineVariableType 1
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
+> %EndEventDef
+> %EventDef PajeDefineStateType 2
+> %       Alias string
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineEventType 3
+> %       Alias string
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineLinkType 4
+> %       Alias string
+> %       Type string
+> %       StartContainerType string
+> %       EndContainerType string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineEntityValue 5
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
+> %EndEventDef
+> %EventDef PajeCreateContainer 6
+> %       Time date
+> %       Alias string
+> %       Type string
+> %       Container string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDestroyContainer 7
+> %       Time date
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeSetVariable 8
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
 > %EndEventDef
-> %EventDef PajeAddVariable 9 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> %EventDef PajeAddVariable 9
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
 > %EndEventDef
-> %EventDef PajeSubVariable 10 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> %EventDef PajeSubVariable 10
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
 > %EndEventDef
-> %EventDef PajeSetState 11 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeSetState 11
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
 > %EndEventDef
-> %EventDef PajePushState 12 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajePushState 12
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
 > %EndEventDef
-> %EventDef PajePopState 13 
-> %       Time date 
-> %       Type string 
-> %       Container string 
+> %EventDef PajePopState 13
+> %       Time date
+> %       Type string
+> %       Container string
 > %EndEventDef
-> %EventDef PajeResetState 14 
-> %       Time date 
-> %       Type string 
-> %       Container string 
+> %EventDef PajeResetState 14
+> %       Time date
+> %       Type string
+> %       Container string
 > %EndEventDef
-> %EventDef PajeStartLink 15 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
-> %       StartContainer string 
-> %       Key string 
+> %EventDef PajeStartLink 15
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       StartContainer string
+> %       Key string
 > %EndEventDef
-> %EventDef PajeEndLink 16 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
-> %       EndContainer string 
-> %       Key string 
+> %EventDef PajeEndLink 16
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       EndContainer string
+> %       Key string
 > %EndEventDef
-> %EventDef PajeNewEvent 17 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeNewEvent 17
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
 > %EndEventDef
 > 0 1 0 L1
 > 6 0 1 1 0 "AS_interne"
index d8beea2..d7a7917 100644 (file)
@@ -1,3 +1,14 @@
+<!-- This platform was automatically converted from the OptorSim platform.
+
+  As such, it only contains information of the cluster interconnexion,
+  not on the caracteristics of each cluster. In a sense, it describes
+  the network of a National Research and Education Network (NREN), but
+  not of a computational platform.
+  
+  We hope that you find it useful anyway. I you know how to complete
+  this information with data on the cluster configurations, please
+  drop us a mail so that we can add this information. -->
+
 <?xml version='1.0'?>
 <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
 <platform version="3">
index 7c7d356..b41fe4d 100644 (file)
  
  <platform version="3">
  <AS  id="AS0"  routing="Full">
-   <host id="host1" power="1000000000">
-     <prop id="SG_TEST_Hdd" value="180"/>
-     <prop id="SG_TEST_mem" value="4"/>
-   </host>
-   <host id="host2" power="1000000000">
-     <prop id="SG_TEST_Hdd" value="120"/>
-   </host>
-   <link id="l1" bandwidth="125000000" latency="0.000100">
-     <prop id="type" value="Ethernet"/>
-   </link>
-   <link id="l2" bandwidth="125000000" latency="0.000100">
-     <prop id="type" value="ethernet"/>
-   </link>
-   <route src="host1" dst="host2"><link_ctn id="l1"/><link_ctn id="l2"/></route>
+   <prop id="filename" value="prop.xml"/>
+   <prop id="date" value="31-08-12"/>
+   <prop id="author" value="pnavarro"/>
+   
+   <AS  id="AS3"  routing="Full">
+          <AS id="AS1" routing="None">
+              <prop id="name" value="AS1"/>
+          </AS>
+          
+          <AS id="AS2" routing="None">
+              <prop id="name" value="AS2"/>
+          </AS>
+   </AS>
+   
+   <AS  id="AS4"  routing="Full">
+          <host id="host1" power="1000000000">
+            <prop id="SG_TEST_Hdd" value="180"/>
+            <prop id="SG_TEST_mem" value="4"/>
+          </host>
+          
+          <host id="host2" power="1000000000">
+            <prop id="SG_TEST_Hdd" value="120"/>
+          </host>
+          
+          <link id="l1" bandwidth="125000000" latency="0.000100">
+            <prop id="type" value="Ethernet"/>
+          </link>
+          
+          <link id="l2" bandwidth="125000000" latency="0.000100">
+            <prop id="type" value="ethernet"/>
+          </link>
+          <route src="host1" dst="host2"><link_ctn id="l1"/><link_ctn id="l2"/></route>
+   </AS>
  </AS>
  </platform>
index 0e93b54..18ffe77 100644 (file)
@@ -1,4 +1,6 @@
 0 1
 10 0
 11 1
-50 0
\ No newline at end of file
+60 0
+61 1
+111 0
\ No newline at end of file
index 39ffe5d..e383395 100644 (file)
@@ -16,7 +16,9 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(sd_fail,
 int main(int argc, char **argv)
 {
   SD_task_t task;
-
+  double computation_amount[1];
+  double communication_amount[2] = { 0 };
+  SD_workstation_t workstation_list[1];
   /* initialization of SD */
   SD_init(&argc, argv);
 
@@ -25,8 +27,10 @@ int main(int argc, char **argv)
  
   /* creation of a single task that will poorly fail when the workstation
    * will stop */
-
+  XBT_INFO("First test: COMP_SEQ task");
   task = SD_task_create_comp_seq("Poor task", NULL, 2e10);
+  SD_task_watch(task, SD_FAILED);
+  SD_task_watch(task, SD_DONE);
 
   XBT_INFO("Schedule task '%s' on workstation 'Faulty Host'",
            SD_task_get_name(task));
@@ -37,11 +41,11 @@ int main(int argc, char **argv)
 
   SD_task_dump(task);
 
-  XBT_INFO("Task %s has failed. %.f flops remain to be done",
+  XBT_INFO("Task '%s' has failed. %.f flops remain to be done",
            SD_task_get_name(task),
            SD_task_get_remaining_amount(task));
 
-  XBT_INFO("let's unschedule taks %s and reschedule it on the 'Safe Host'",
+  XBT_INFO("let's unschedule task '%s' and reschedule it on the 'Safe Host'",
            SD_task_get_name(task));
   SD_task_unschedule(task);
   SD_task_schedulel(task, 1, SD_workstation_get_by_name("Safe Host"));
@@ -56,7 +60,50 @@ int main(int argc, char **argv)
       SD_task_get_finish_time(task));
 
   SD_task_destroy(task);
+  task=NULL;
+
+  XBT_INFO("Second test: NON TYPED task");
+
+  task = SD_task_create("Poor parallel task", NULL, 2e10);
+  SD_task_watch(task, SD_FAILED);
+  SD_task_watch(task, SD_DONE);
+
+  computation_amount[0] = 2e10;
+
+  XBT_INFO("Schedule task '%s' on workstation 'Faulty Host'",
+             SD_task_get_name(task));
+
+  workstation_list[0] = SD_workstation_get_by_name("Faulty Host");
+  SD_task_schedule(task, 1, workstation_list,
+          computation_amount, communication_amount,-1);
+
+  SD_simulate(-1.0);
+
+  SD_task_dump(task);
+
+  XBT_INFO("Task '%s' has failed. %.f flops remain to be done",
+            SD_task_get_name(task),
+            SD_task_get_remaining_amount(task));
 
+  XBT_INFO("let's unschedule task '%s' and reschedule it on the 'Safe Host'",
+           SD_task_get_name(task));
+  SD_task_unschedule(task);
+
+  workstation_list[0] = SD_workstation_get_by_name("Safe Host");
+
+  SD_task_schedule(task, 1, workstation_list,
+                   computation_amount, communication_amount,-1);
+
+  XBT_INFO("Run the simulation again");
+  SD_simulate(-1.0);
+
+  SD_task_dump(task);
+  XBT_INFO("Task '%s' start time: %f, finish time: %f",
+           SD_task_get_name(task),
+           SD_task_get_start_time(task),
+           SD_task_get_finish_time(task));
+
+  SD_task_destroy(task);
   SD_exit();
   return 0;
 }
index d288790..becdeef 100644 (file)
@@ -95,6 +95,10 @@ int main(int argc, char **argv)
   taskC = SD_task_create("Task C", NULL, 30.0);
   taskD = SD_task_create("Task D", NULL, 60.0);
 
+  /* try to attach and retrieve user data to a task */
+  SD_task_set_data(taskA, (void*) &computation_amount1);
+  if (computation_amount1 != (*((double*) SD_task_get_data(taskA))))
+      XBT_ERROR("User data was corrupted by a simple set/get");
 
   SD_task_dependency_add(NULL, NULL, taskB, taskA);
   SD_task_dependency_add(NULL, NULL, taskC, taskA);
diff --git a/examples/simdag/test_simdag_fail.tesh b/examples/simdag/test_simdag_fail.tesh
new file mode 100644 (file)
index 0000000..108ddfd
--- /dev/null
@@ -0,0 +1,36 @@
+#! ./tesh
+
+p Test of the management of failed tasks simdag
+
+$ $SG_TEST_EXENV ./sd_fail
+> [0.000000] [surf_workstation/INFO] surf_workstation_model_init_ptask_L07
+> [0.000000] [sd_fail/INFO] First test: COMP_SEQ task
+> [0.000000] [sd_fail/INFO] Schedule task 'Poor task' on workstation 'Faulty Host'
+> [10.000000] [sd_task/INFO] Displaying task Poor task
+> [10.000000] [sd_task/INFO]   - state:    not runnable    failed
+> [10.000000] [sd_task/INFO]   - kind: sequential computation
+> [10.000000] [sd_task/INFO]   - amount: 20000000000
+> [10.000000] [sd_task/INFO]   - Dependencies to satisfy: 0
+> [10.000000] [sd_fail/INFO] Task 'Poor task' has failed. 20000000000 flops remain to be done
+> [10.000000] [sd_fail/INFO] let's unschedule task 'Poor task' and reschedule it on the 'Safe Host'
+> [10.000000] [sd_fail/INFO] Run the simulation again
+> [50.000000] [sd_task/INFO] Displaying task Poor task
+> [50.000000] [sd_task/INFO]   - state:    not runnable   done 
+> [50.000000] [sd_task/INFO]   - kind: sequential computation
+> [50.000000] [sd_task/INFO]   - amount: 20000000000
+> [50.000000] [sd_task/INFO]   - Dependencies to satisfy: 0
+> [50.000000] [sd_fail/INFO] Task 'Poor task' start time: 10.000000, finish time: 50.000000
+> [50.000000] [sd_fail/INFO] Second test: NON TYPED task
+> [50.000000] [sd_fail/INFO] Schedule task 'Poor parallel task' on workstation 'Faulty Host'
+> [60.000000] [sd_task/INFO] Displaying task Poor parallel task
+> [60.000000] [sd_task/INFO]   - state:    not runnable    failed
+> [60.000000] [sd_task/INFO]   - amount: 20000000000
+> [60.000000] [sd_task/INFO]   - Dependencies to satisfy: 0
+> [60.000000] [sd_fail/INFO] Task 'Poor parallel task' has failed. 20000000000 flops remain to be done
+> [60.000000] [sd_fail/INFO] let's unschedule task 'Poor parallel task' and reschedule it on the 'Safe Host'
+> [60.000000] [sd_fail/INFO] Run the simulation again
+> [100.000000] [sd_task/INFO] Displaying task Poor parallel task
+> [100.000000] [sd_task/INFO]   - state:    not runnable   done 
+> [100.000000] [sd_task/INFO]   - amount: 20000000000
+> [100.000000] [sd_task/INFO]   - Dependencies to satisfy: 0
+> [100.000000] [sd_fail/INFO] Task 'Poor parallel task' start time: 60.000000, finish time: 100.000000
index 1004299..92cfdc2 100644 (file)
@@ -18,113 +18,114 @@ $ $SG_TEST_EXENV ./simdag_tracing --cfg=tracing:1 --cfg=tracing/categorized:1 ${
 > [30.800300] [sd_seq_access/INFO] There is no task running on C2-06
 
 $ cat ./simgrid.trace
-> %EventDef PajeDefineContainerType 0 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineVariableType 1 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %       Color color 
-> %EndEventDef 
-> %EventDef PajeDefineStateType 2 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineEventType 3 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineLinkType 4 
-> %       Alias string 
-> %       Type string 
-> %       StartContainerType string 
-> %       EndContainerType string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDefineEntityValue 5 
-> %       Alias string 
-> %       Type string 
-> %       Name string 
-> %       Color color 
-> %EndEventDef 
-> %EventDef PajeCreateContainer 6 
-> %       Time date 
-> %       Alias string 
-> %       Type string 
-> %       Container string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeDestroyContainer 7 
-> %       Time date 
-> %       Type string 
-> %       Name string 
-> %EndEventDef 
-> %EventDef PajeSetVariable 8 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> #This file was generated using SimGrid-3.8.0
+> %EventDef PajeDefineContainerType 0
+> %       Alias string
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeAddVariable 9 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> %EventDef PajeDefineVariableType 1
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
 > %EndEventDef
-> %EventDef PajeSubVariable 10 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value double 
+> %EventDef PajeDefineStateType 2
+> %       Alias string
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeSetState 11 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeDefineEventType 3
+> %       Alias string
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajePushState 12 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeDefineLinkType 4
+> %       Alias string
+> %       Type string
+> %       StartContainerType string
+> %       EndContainerType string
+> %       Name string
 > %EndEventDef
-> %EventDef PajePopState 13 
-> %       Time date 
-> %       Type string 
-> %       Container string 
+> %EventDef PajeDefineEntityValue 5
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
 > %EndEventDef
-> %EventDef PajeResetState 14 
-> %       Time date 
-> %       Type string 
-> %       Container string 
+> %EventDef PajeCreateContainer 6
+> %       Time date
+> %       Alias string
+> %       Type string
+> %       Container string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeStartLink 15 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
-> %       StartContainer string 
-> %       Key string 
+> %EventDef PajeDestroyContainer 7
+> %       Time date
+> %       Type string
+> %       Name string
 > %EndEventDef
-> %EventDef PajeEndLink 16 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
-> %       EndContainer string 
-> %       Key string 
+> %EventDef PajeSetVariable 8
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
 > %EndEventDef
-> %EventDef PajeNewEvent 17 
-> %       Time date 
-> %       Type string 
-> %       Container string 
-> %       Value string 
+> %EventDef PajeAddVariable 9
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeSubVariable 10
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeSetState 11
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> %EventDef PajePushState 12
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> %EventDef PajePopState 13
+> %       Time date
+> %       Type string
+> %       Container string
+> %EndEventDef
+> %EventDef PajeResetState 14
+> %       Time date
+> %       Type string
+> %       Container string
+> %EndEventDef
+> %EventDef PajeStartLink 15
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       StartContainer string
+> %       Key string
+> %EndEventDef
+> %EventDef PajeEndLink 16
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       EndContainer string
+> %       Key string
+> %EndEventDef
+> %EventDef PajeNewEvent 17
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
 > %EndEventDef
 > 0 1 0 HOST
 > 6 0 1 1 0 "C2-06"
index b98c20f..ac183b8 100644 (file)
@@ -28,7 +28,7 @@ if(enable_smpi)
   add_executable(ttest01 ttest01.c)
   add_executable(mc_bugged1 mc_bugged1.c)
   add_executable(mc_bugged2 mc_bugged2.c)
-  add_executable(replay replay.c)
+  add_executable(smpi_replay replay/replay.c)
 
   target_link_libraries(alltoall2 m simgrid smpi )
   target_link_libraries(alltoall_basic m simgrid smpi )
@@ -51,7 +51,7 @@ if(enable_smpi)
   target_link_libraries(ttest01 m simgrid smpi )
   target_link_libraries(mc_bugged1 m simgrid smpi )
   target_link_libraries(mc_bugged2 m simgrid smpi )
-  target_link_libraries(replay m simgrid smpi )
+  target_link_libraries(smpi_replay m simgrid smpi )
 
   set_target_properties(smpi_sendrecv PROPERTIES RENAME sendrecv)
 endif(enable_smpi)
@@ -78,7 +78,6 @@ set(examples_src
   ${CMAKE_CURRENT_SOURCE_DIR}/alltoall_basic.c
   ${CMAKE_CURRENT_SOURCE_DIR}/sendrecv.c
   ${CMAKE_CURRENT_SOURCE_DIR}/mc_bugged1.c
-  ${CMAKE_CURRENT_SOURCE_DIR}/replay.c
   ${CMAKE_CURRENT_SOURCE_DIR}/reduce.c
   ${CMAKE_CURRENT_SOURCE_DIR}/mvmul.c
   ${CMAKE_CURRENT_SOURCE_DIR}/compute2.c
@@ -92,6 +91,7 @@ set(examples_src
   ${CMAKE_CURRENT_SOURCE_DIR}/sendtest.c
   ${CMAKE_CURRENT_SOURCE_DIR}/barrier.c
   ${CMAKE_CURRENT_SOURCE_DIR}/bcbench.c
+  ${CMAKE_CURRENT_SOURCE_DIR}/replay/replay.c
   ${CMAKE_CURRENT_SOURCE_DIR}/tracing/smpi_traced.c
   ${CMAKE_CURRENT_SOURCE_DIR}/tracing/smpi_traced_simple.c
   PARENT_SCOPE
diff --git a/examples/smpi/actions.txt b/examples/smpi/actions.txt
deleted file mode 100644 (file)
index 5456907..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-0 send 1 1e6
-1 recv 0
-1 compute 1e9
-1 Isend 0 1e6
-0 recv 1
index ad823a2..23452c4 100644 (file)
@@ -1,5 +1,7 @@
-/* Copyright (c) 2009, 2010. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2009-2012. The SimGrid Team. All rights reserved.          */
+
+/* This example should be instructive to learn about SMPI_SAMPLE_LOCAL and 
+   SMPI_SAMPLE_GLOBAL macros for execution sampling */
 
 /* 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. */
 
 int main(int argc, char *argv[])
 {
-  int i;
+  int i,j;
   double d;
   MPI_Init(&argc, &argv);
   d = 2.0;
-/*  SMPI_DO_ONCE */  {
-    for (i = 0; i < atoi(argv[1]); i++) {
-      if (d < 10000) {
-        d = d * d;
-      } else {
-        d = 2;
-      }
-    }
-    printf("%d %f\n", i, d);
+  for (i=0;i<5;i++) {  
+     SMPI_SAMPLE_GLOBAL(3,-1)  { // I want no more than 3 benchs (thres<0)
+       fprintf(stderr,"[rank:%d] Run the first computation. It's globally benched, and I want no more than 3 benchmarks (thres<0)\n", smpi_process_index());
+    
+       for (j=0;j<100*1000*1000;j++) { // 100 kflop
+          if (d < 100000) {
+             d = d * d;
+          } else {
+             d = 2;
+          }
+       }     
+     }
   }
-/*  SMPI_DO_ONCE */  {
-    for (i = 0; i < 2 * atoi(argv[1]); i++) {
-      if (d < 10000) {
-        d = d * d;
-      } else {
-        d = 2;
-      }
-    }
-    printf("%d %f\n", i, d);
+
+  for (i=0;i<5;i++) {  
+     SMPI_SAMPLE_LOCAL(0, 0.1) { // I want the standard error to go below 0.1 second. Two tests at least will be run (count is not >0)
+       fprintf(stderr,"[rank:%d] Run the first (locally benched) computation. It's locally benched, and I want the standard error to go below 0.1 second (count is not >0)\n", smpi_process_index());
+       for (j=0;j<100*1000*1000;j++) { // 100 kflop
+          if (d < 100000) {
+             d = d * d;
+          } else {
+             d = 2;
+          }
+       }
+     }
   }
+   
+  fprintf(stderr,"[%d] The result of the computation is: %f\n", smpi_process_index(), d);
+
   MPI_Finalize();
   return 0;
 }
diff --git a/examples/smpi/replay/actions0.txt b/examples/smpi/replay/actions0.txt
new file mode 100644 (file)
index 0000000..3e499e2
--- /dev/null
@@ -0,0 +1,5 @@
+0 init
+0 send 1 1e6
+0 recv 1 1e6
+0 send 1 1e6
+0 finalize
diff --git a/examples/smpi/replay/actions1.txt b/examples/smpi/replay/actions1.txt
new file mode 100644 (file)
index 0000000..572645f
--- /dev/null
@@ -0,0 +1,7 @@
+1 init
+1 recv 0 1e6
+1 compute 1e9
+1 Isend 0 1e6
+1 Irecv 0 1e6
+1 wait
+1 finalize
diff --git a/examples/smpi/replay/actions_bcast.txt b/examples/smpi/replay/actions_bcast.txt
new file mode 100644 (file)
index 0000000..5ee22c0
--- /dev/null
@@ -0,0 +1,28 @@
+0 init
+1 init
+2 init
+
+0 comm_size 3
+0 bcast 5e8
+1 bcast 5e8
+2 bcast 5e8
+
+0 compute 5e8
+1 compute 2e8
+2 compute 5e8
+
+0 bcast 5e8
+1 bcast 5e8
+2 bcast 5e8
+
+0 compute 5e8
+1 compute 2e8
+2 compute 5e8
+
+0 reduce 5e8 5e8
+1 reduce 5e8 5e8
+2 reduce 5e8 5e8
+
+0 finalize
+1 finalize
+2 finalize
diff --git a/examples/smpi/replay/one_trace b/examples/smpi/replay/one_trace
new file mode 100644 (file)
index 0000000..c46e677
--- /dev/null
@@ -0,0 +1 @@
+replay/actions_bcast.txt
similarity index 86%
rename from examples/smpi/replay.c
rename to examples/smpi/replay/replay.c
index e82d6bf..3aad3c2 100644 (file)
@@ -11,8 +11,8 @@ int main(int argc, char *argv[])
   smpi_replay_init(&argc, &argv);
 
   /* Actually do the simulation using smpi_action_trace_run */
-  smpi_action_trace_run(argv[1]);  // it's ok to pass a NULL argument here
-
+  smpi_action_trace_run(NULL);
   smpi_replay_finalize();
+
   return 0;
 }
diff --git a/examples/smpi/replay/replay_platform.xml b/examples/smpi/replay/replay_platform.xml
new file mode 100644 (file)
index 0000000..9823e34
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version='1.0'?>
+ <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+ <platform version="3">
+ <AS  id="AS0"  routing="Full">
+   <!-- ljlkj -->
+   <host id="Tremblay" power="98095000"/>
+   <host id="Jupiter" power="76296000"/>
+   <host id="Fafard" power="76296000"/>
+   <host id="Ginette" power="48492000"/>
+   <host id="Bourassa" power="48492000"/>
+   <link id="6" bandwidth="41279125" latency="5.9904e-05"/>
+   <link id="11" bandwidth="252750" latency="0.00570455"/>
+   <link id="3" bandwidth="34285625" latency="0.000514433"/>
+   <link id="7" bandwidth="11618875" latency="0.00018998"/>
+   <link id="9" bandwidth="7209750" latency="0.001461517"/>
+   <link id="12" bandwidth="1792625" latency="0.007877863"/>
+   <link id="2" bandwidth="118682500" latency="0.000136931"/>
+   <link id="8" bandwidth="8158000" latency="0.000270544"/>
+   <link id="1" bandwidth="34285625" latency="0.000514433"/>
+   <link id="4" bandwidth="10099625" latency="0.00047978"/>
+   <link id="0" bandwidth="41279125" latency="5.9904e-05"/>
+   <link id="10" bandwidth="4679750" latency="0.000848712"/>
+   <link id="5" bandwidth="27946250" latency="0.000278066"/>
+   <link id="loopback" bandwidth="498000000" latency="0.000015" sharing_policy="FATPIPE"/>
+   <route src="Tremblay" dst="Tremblay"><link_ctn id="loopback"/></route>
+   <route src="Jupiter" dst="Jupiter"><link_ctn id="loopback"/></route>
+   <route src="Fafard" dst="Fafard"><link_ctn id="loopback"/></route>
+   <route src="Ginette" dst="Ginette"><link_ctn id="loopback"/></route>
+   <route src="Bourassa" dst="Bourassa"><link_ctn id="loopback"/></route>
+   <route src="Tremblay" dst="Jupiter">
+     <link_ctn id="9"/>
+   </route>
+   <route src="Tremblay" dst="Fafard">
+     <link_ctn id="4"/><link_ctn id="3"/><link_ctn id="2"/><link_ctn id="0"/><link_ctn id="1"/><link_ctn id="8"/>
+   </route>
+   <route src="Tremblay" dst="Ginette">
+     <link_ctn id="4"/><link_ctn id="3"/><link_ctn id="5"/>
+   </route>
+   <route src="Tremblay" dst="Bourassa">
+     <link_ctn id="4"/><link_ctn id="3"/><link_ctn id="2"/><link_ctn id="0"/><link_ctn id="1"/><link_ctn id="6"/><link_ctn id="7"/>
+   </route>
+   <route src="Jupiter" dst="Fafard">
+     <link_ctn id="9"/><link_ctn id="4"/><link_ctn id="3"/><link_ctn id="2"/><link_ctn id="0"/><link_ctn id="1"/><link_ctn id="8"/>
+   </route>
+   <route src="Jupiter" dst="Ginette">
+     <link_ctn id="9"/><link_ctn id="4"/><link_ctn id="3"/><link_ctn id="5"/>
+   </route>
+   <route src="Jupiter" dst="Bourassa">
+     <link_ctn id="9"/><link_ctn id="4"/><link_ctn id="3"/><link_ctn id="2"/><link_ctn id="0"/><link_ctn id="1"/><link_ctn id="6"/><link_ctn id="7"/>
+   </route>
+   <route src="Fafard" dst="Ginette">
+     <link_ctn id="8"/><link_ctn id="1"/><link_ctn id="0"/><link_ctn id="2"/><link_ctn id="5"/>
+   </route>
+   <route src="Fafard" dst="Bourassa">
+     <link_ctn id="8"/><link_ctn id="6"/><link_ctn id="7"/>
+   </route>
+   <route src="Ginette" dst="Bourassa">
+     <link_ctn id="5"/><link_ctn id="2"/><link_ctn id="0"/><link_ctn id="1"/><link_ctn id="6"/><link_ctn id="7"/>
+   </route>
+ </AS>
+ </platform>
diff --git a/examples/smpi/replay/smpi_replay.tesh b/examples/smpi/replay/smpi_replay.tesh
new file mode 100644 (file)
index 0000000..4120087
--- /dev/null
@@ -0,0 +1,220 @@
+# use the tested library, not the installed one
+# (since we want to pass it to the child, it has to be redefined before each command)
+# Go for the first test
+p Test of trace replay with SMPI (one trace for all processes)
+$ ../../bin/smpirun --log=replay.thresh:critical --log=smpi_replay.thresh:verbose --log=no_loc -np 3 -platform ${srcdir:=.}/replay/replay_platform.xml -hostfile ${srcdir:=.}/hostfile ./smpi_replay ${srcdir:=.}/replay/one_trace
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-9'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [Tremblay:0:(0) 0.000000] [smpi_replay/VERBOSE] 0 comm_size 3 0.000000
+> [Fafard:2:(0) 75.475893] [smpi_replay/VERBOSE] 2 bcast 5e8 75.475893
+> [Fafard:2:(0) 82.029316] [smpi_replay/VERBOSE] 2 compute 5e8 6.553424
+> [Jupiter:1:(0) 85.401170] [smpi_replay/VERBOSE] 1 bcast 5e8 85.401170
+> [Tremblay:0:(0) 85.401170] [smpi_replay/VERBOSE] 0 bcast 5e8 85.401170
+> [Jupiter:1:(0) 88.022539] [smpi_replay/VERBOSE] 1 compute 2e8 2.621369
+> [Tremblay:0:(0) 90.498269] [smpi_replay/VERBOSE] 0 compute 5e8 5.097100
+> [Fafard:2:(0) 165.974172] [smpi_replay/VERBOSE] 2 bcast 5e8 83.944856
+> [Fafard:2:(0) 172.527595] [smpi_replay/VERBOSE] 2 compute 5e8 6.553424
+> [Jupiter:1:(0) 175.899449] [smpi_replay/VERBOSE] 1 bcast 5e8 87.876910
+> [Tremblay:0:(0) 175.899449] [smpi_replay/VERBOSE] 0 bcast 5e8 85.401180
+> [Jupiter:1:(0) 178.520818] [smpi_replay/VERBOSE] 1 compute 2e8 2.621369
+> [Tremblay:0:(0) 180.996549] [smpi_replay/VERBOSE] 0 compute 5e8 5.097100
+> [Fafard:2:(0) 256.472441] [smpi_replay/VERBOSE] 2 reduce 5e8 5e8 83.944846
+> [Jupiter:1:(0) 266.397728] [smpi_replay/VERBOSE] 1 reduce 5e8 5e8 87.876910
+> [Tremblay:0:(0) 266.397728] [smpi_replay/VERBOSE] 0 reduce 5e8 5e8 85.401180
+> [Tremblay:0:(0) 266.397728] [smpi_replay/INFO] Simulation time 266.398
+
+p The same with tracing activated
+$ ../../bin/smpirun --log=replay.thresh:critical --log=no_loc  --cfg=tracing:1 --cfg=tracing/smpi:1 --cfg=tracing/smpi/computing:1 -np 3 -platform ${srcdir:=.}/replay/replay_platform.xml -hostfile ${srcdir:=.}/hostfile ./smpi_replay ${srcdir:=.}/replay/one_trace
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-9'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/smpi' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/smpi/computing' to '1'
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [Tremblay:0:(0) 266.397728] [smpi_replay/INFO] Simulation time 266.398
+
+$ cat ./simgrid.trace
+> #This file was generated using SimGrid-3.8.0
+> %EventDef PajeDefineContainerType 0
+> %       Alias string
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineVariableType 1
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
+> %EndEventDef
+> %EventDef PajeDefineStateType 2
+> %       Alias string
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineEventType 3
+> %       Alias string
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineLinkType 4
+> %       Alias string
+> %       Type string
+> %       StartContainerType string
+> %       EndContainerType string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDefineEntityValue 5
+> %       Alias string
+> %       Type string
+> %       Name string
+> %       Color color
+> %EndEventDef
+> %EventDef PajeCreateContainer 6
+> %       Time date
+> %       Alias string
+> %       Type string
+> %       Container string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeDestroyContainer 7
+> %       Time date
+> %       Type string
+> %       Name string
+> %EndEventDef
+> %EventDef PajeSetVariable 8
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeAddVariable 9
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeSubVariable 10
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value double
+> %EndEventDef
+> %EventDef PajeSetState 11
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> %EventDef PajePushState 12
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> %EventDef PajePopState 13
+> %       Time date
+> %       Type string
+> %       Container string
+> %EndEventDef
+> %EventDef PajeResetState 14
+> %       Time date
+> %       Type string
+> %       Container string
+> %EndEventDef
+> %EventDef PajeStartLink 15
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       StartContainer string
+> %       Key string
+> %EndEventDef
+> %EventDef PajeEndLink 16
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %       EndContainer string
+> %       Key string
+> %EndEventDef
+> %EventDef PajeNewEvent 17
+> %       Time date
+> %       Type string
+> %       Container string
+> %       Value string
+> %EndEventDef
+> 0 1 0 MPI
+> 2 2 1 MPI_STATE
+> 4 3 0 1 1 MPI_LINK
+> 6 0 1 1 0 "rank-0"
+> 5 4 2 computing "0 1 1"
+> 5 5 2 action_bcast "0 0.78 0.39"
+> 6 0 2 1 0 "rank-1"
+> 6 0 3 1 0 "rank-2"
+> 12 0 2 1 4
+> 13 0 2 1
+> 12 0 2 1 5
+> 12 0 2 2 4
+> 13 0 2 2
+> 12 0 2 2 5
+> 12 0 2 3 4
+> 13 0 2 3
+> 12 0 2 3 5
+> 13 75.475893 2 3
+> 12 75.475893 2 3 4
+> 13 82.029316 2 3
+> 12 82.029316 2 3 5
+> 13 85.401170 2 2
+> 12 85.401170 2 2 4
+> 13 85.401170 2 1
+> 12 85.401170 2 1 4
+> 5 6 2 action_reduce "0 1 0"
+> 13 88.022539 2 2
+> 12 88.022539 2 2 5
+> 13 90.498269 2 1
+> 12 90.498269 2 1 5
+> 13 165.974172 2 3
+> 12 165.974172 2 3 4
+> 13 172.527595 2 3
+> 12 172.527595 2 3 6
+> 13 175.899449 2 2
+> 12 175.899449 2 2 4
+> 13 175.899449 2 1
+> 12 175.899449 2 1 4
+> 13 178.520818 2 2
+> 12 178.520818 2 2 6
+> 13 180.996549 2 1
+> 12 180.996549 2 1 6
+> 13 256.472441 2 3
+> 12 256.472441 2 3 4
+> 13 256.472442 2 3
+> 7 256.472442 1 3
+> 13 266.397728 2 2
+> 12 266.397728 2 2 4
+> 13 266.397728 2 1
+> 12 266.397728 2 1 4
+> 13 266.397729 2 1
+> 7 266.397729 1 1
+> 13 266.397729 2 2
+> 7 266.397729 1 2
+
+$ rm -f ./simgrid.trace
+
+p Another test of trace replay with SMPI (one trace per process)
+$ ../../bin/smpirun --log=replay.thresh:critical --log=smpi_replay.thresh:verbose --log=no_loc -np 2 -platform ${srcdir:=.}/replay/replay_platform.xml -hostfile ${srcdir:=.}/hostfile ./smpi_replay ${srcdir:=.}/replay/split_traces
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-9'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
+> [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [Tremblay:0:(0) 0.173741] [smpi_replay/VERBOSE] 0 send 1 1e6 0.173741
+> [Jupiter:1:(0) 0.173741] [smpi_replay/VERBOSE] 1 recv 0 1e6 0.173741
+> [Jupiter:1:(0) 13.280588] [smpi_replay/VERBOSE] 1 compute 1e9 13.106847
+> [Jupiter:1:(0) 13.280588] [smpi_replay/VERBOSE] 1 Isend 0 1e6 0.000000
+> [Jupiter:1:(0) 13.280588] [smpi_replay/VERBOSE] 1 Irecv 0 1e6 0.000000
+> [Tremblay:0:(0) 13.593030] [smpi_replay/VERBOSE] 0 recv 1 1e6 13.419289
+> [Jupiter:1:(0) 13.905472] [smpi_replay/VERBOSE] 1 wait 0.624884
+> [Tremblay:0:(0) 13.905472] [smpi_replay/VERBOSE] 0 send 1 1e6 0.312442
+> [Tremblay:0:(0) 13.905472] [smpi_replay/INFO] Simulation time 13.9055
diff --git a/examples/smpi/replay/split_traces b/examples/smpi/replay/split_traces
new file mode 100644 (file)
index 0000000..d7ae089
--- /dev/null
@@ -0,0 +1,2 @@
+replay/actions0.txt
+replay/actions1.txt
index 5a22819..ac93a45 100644 (file)
@@ -56,7 +56,7 @@ $ ../../bin/smpirun -trace -trace-resource -trace-triva -trace-file smpi_traced.
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'triva/categorized' to 'smpi_cat.plist'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'triva/uncategorized' to 'smpi_uncat.plist'
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
-> [1.003981] [instr_config/INFO] No categories declared, ignoring generation of triva graph configuration
+> [0.013981] [instr_config/INFO] No categories declared, ignoring generation of triva graph configuration
 
 p Testing with parameters but without activating them with the safe switch (-trace)
 $ ../../bin/smpirun -trace-resource -trace-triva -trace-file smpi_traced.trace -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../msg/tracing/platform.xml -np 3 ./smpi_traced_simple
index 84a4343..4ed246e 100644 (file)
@@ -93,6 +93,9 @@ XBT_PUBLIC(void) TRACE_host_reset_state (const char *host, const char *state);
 /* for creating graph configuration files for Triva by hand */
 XBT_PUBLIC(xbt_dynar_t) TRACE_get_node_types (void);
 XBT_PUBLIC(xbt_dynar_t) TRACE_get_edge_types (void);
+XBT_PUBLIC(void) TRACE_pause (void);
+XBT_PUBLIC(void) TRACE_resume (void);
+
 
 #else                           /* HAVE_TRACING */
 
index 195f90b..8cc633d 100644 (file)
@@ -77,7 +77,15 @@ XBT_PUBLIC(size_t) MSG_file_write(const void* ptr, size_t size, size_t nmemb, ms
 XBT_PUBLIC(msg_file_t) MSG_file_open(const char* mount, const char* path, const char* mode);
 XBT_PUBLIC(int) MSG_file_close(msg_file_t fp);
 XBT_PUBLIC(int) MSG_file_stat(msg_file_t fd, s_msg_stat_t *buf);
+XBT_PUBLIC(void) MSG_file_free_stat(s_msg_stat_t *stat);
 
+XBT_PUBLIC(int) MSG_file_unlink(msg_file_t fd);
+XBT_PUBLIC(xbt_dict_t) MSG_file_ls(const char *mount, const char *path);
+
+/************************** AS Router handling ************************************/
+XBT_PUBLIC(const char *) MSG_as_router_get_property_value(const char* asr, const char *name);
+XBT_PUBLIC(xbt_dict_t) MSG_as_router_get_properties(const char* asr);
+XBT_PUBLIC(void) MSG_as_router_set_property_value(const char* asr, const char *name, char *value,void_f_pvoid_t free_ctn);
 
 /************************** Host handling ***********************************/
 XBT_PUBLIC(msg_error_t) MSG_host_set_data(msg_host_t host, void *data);
@@ -104,6 +112,7 @@ XBT_PUBLIC(void) MSG_load_platform_script(const char *script_file);
 
 XBT_PUBLIC(msg_host_t) MSG_get_host_by_name(const char *name);
 XBT_PUBLIC(xbt_dynar_t) MSG_hosts_as_dynar(void);
+XBT_PUBLIC(int) MSG_get_host_number(void);
 
 /************************** Process handling *********************************/
 XBT_PUBLIC(msg_process_t) MSG_process_create(const char *name,
@@ -261,6 +270,9 @@ 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);
+
+
 /************************** Action handling **********************************/
 msg_error_t MSG_action_trace_run(char *path);
 
@@ -272,7 +284,6 @@ typedef msg_error_t MSG_error_t;
 #define MSG_global_init_args(argc, argv) MSG_init(argc,argv)
 
 /* these are the functions which are deprecated. Do not use them, they may get removed in future releases */
-XBT_PUBLIC(int) MSG_get_host_number(void);
 XBT_PUBLIC(msg_host_t *) MSG_get_host_table(void);
 
 #define MSG_TIMEOUT_FAILURE MSG_TIMEOUT
index 0ce3b00..53a9f1a 100644 (file)
@@ -65,7 +65,7 @@ typedef struct SD_task *SD_task_t;
     @see SD_task_management */
 typedef enum {
   SD_NOT_SCHEDULED = 0,      /**< @brief Initial state (not valid for SD_watch and SD_unwatch). */
-  SD_SCHEDULABLE = 0x0001,               /**< @brief A task becomes SD_READY as soon as its dependencies are satisfied */
+  SD_SCHEDULABLE = 0x0001,               /**< @brief A task becomes SD_SCHEDULABLE as soon as its dependencies are satisfied */
   SD_SCHEDULED = 0x0002,     /**< @brief A task becomes SD_SCHEDULED when you call function
                                   SD_task_schedule. SD_simulate will execute it when it becomes SD_RUNNABLE. */
   SD_RUNNABLE = 0x0004,      /**< @brief A scheduled task becomes runnable is SD_simulate as soon as its dependencies are satisfied. */
index 48a5dd5..6469356 100644 (file)
 
 SG_BEGIN_DECL()
 
+/************************** AS handling *************************************/
+XBT_PUBLIC(xbt_dict_t) SD_as_router_get_properties(const char *as);
+XBT_PUBLIC(const char*) SD_as_router_get_property_value(const char * as,
+                                                  const char *name);
+
 /************************** Link handling ***********************************/
 /** @defgroup SD_link_management Links
  *  @brief Functions for managing the network links
index bd966e6..3d846c2 100644 (file)
@@ -19,10 +19,8 @@ extern int _surf_do_model_check;
 
 XBT_PUBLIC(void) MC_assert(int);
 XBT_PUBLIC(int) MC_random(int min, int max);
-XBT_PUBLIC(void) MC_diff(void);
 XBT_PUBLIC(void) MC_automaton_new_propositional_symbol(const char* id, void* fct);
 
-
 #else
 
 #define MC_IS_ENABLED 0
index e517a94..574b0f9 100644 (file)
@@ -15,6 +15,30 @@ typedef struct s_routing_edge *sg_routing_edge_t;
 
 XBT_PUBLIC(sg_routing_edge_t) sg_routing_edge_by_name_or_null(const char *name);
 
+/** Defines whether a given resource is working or not */
+typedef enum {
+  SURF_RESOURCE_ON = 1,                   /**< Up & ready        */
+  SURF_RESOURCE_OFF = 0                   /**< Down & broken     */
+} e_surf_resource_state_t;
+
+typedef enum {
+  SURF_LINK_FULLDUPLEX = 2,
+  SURF_LINK_SHARED = 1,
+  SURF_LINK_FATPIPE = 0
+} e_surf_link_sharing_policy_t;
+
+typedef enum {
+  SURF_TRACE_CONNECT_KIND_HOST_AVAIL = 4,
+  SURF_TRACE_CONNECT_KIND_POWER = 3,
+  SURF_TRACE_CONNECT_KIND_LINK_AVAIL = 2,
+  SURF_TRACE_CONNECT_KIND_BANDWIDTH = 1,
+  SURF_TRACE_CONNECT_KIND_LATENCY = 0
+} e_surf_trace_connect_kin_t;
+
+typedef enum {
+  SURF_PROCESS_ON_FAILURE_DIE = 1,
+  SURF_PROCESS_ON_FAILURE_RESTART = 0
+} e_surf_process_on_failure_t;
 
 
 typedef struct tmgr_trace *tmgr_trace_t; /**< Opaque structure defining an availability trace */
@@ -26,10 +50,17 @@ XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_file(const char *filename);
 XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_string(const char *id,
                                                     const char *input,
                                                     double periodicity);
-XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_generator(const char *id,
-                                                  probabilist_event_generator_t generator1,
-                                                  probabilist_event_generator_t generator2,
-                                                  int is_state_trace);
+
+XBT_PUBLIC(tmgr_trace_t) tmgr_trace_generator_value(const char *id,
+                                              probabilist_event_generator_t date_generator,
+                                              probabilist_event_generator_t value_generator);
+XBT_PUBLIC(tmgr_trace_t) tmgr_trace_generator_state(const char *id,
+                                              probabilist_event_generator_t date_generator,
+                                              e_surf_resource_state_t first_event_value);
+XBT_PUBLIC(tmgr_trace_t) tmgr_trace_generator_avail_unavail(const char *id,
+                                              probabilist_event_generator_t avail_duration_generator,
+                                              probabilist_event_generator_t unavail_duration_generator,
+                                              e_surf_resource_state_t first_event_value);
 
 XBT_PUBLIC(probabilist_event_generator_t) tmgr_event_generator_new_uniform(const char* id,
                                                                            double min,
@@ -40,18 +71,6 @@ XBT_PUBLIC(probabilist_event_generator_t) tmgr_event_generator_new_weibull(const
                                                                            double scale,
                                                                            double shape);
 
-/** Defines whether a given resource is working or not */
-typedef enum {
-  SURF_RESOURCE_ON = 1,                   /**< Up & ready        */
-  SURF_RESOURCE_OFF = 0                   /**< Down & broken     */
-} e_surf_resource_state_t;
-
-typedef enum {
-  SURF_LINK_FULLDUPLEX = 2,
-  SURF_LINK_SHARED = 1,
-  SURF_LINK_FATPIPE = 0
-} e_surf_link_sharing_policy_t;
-
 /*
  * Platform creation functions. Instead of passing 123 arguments to the creation functions
  * (one for each possible XML attribute), we pass structures containing them all. It removes the
@@ -74,18 +93,33 @@ typedef struct {
   xbt_dict_t properties;
 } s_sg_platf_host_cbarg_t, *sg_platf_host_cbarg_t;
 
+#define SG_PLATF_HOST_INITIALIZER { \
+    .id = NULL,\
+    .power_peak = 0,\
+    .core_amount = 1.,\
+    .power_scale = 1,\
+    .initial_state = SURF_RESOURCE_ON,\
+    .power_trace = NULL,\
+    .state_trace = NULL,\
+    .coord = NULL,\
+    .properties = NULL\
+    }
+
 typedef struct {
   const char* id;
   const char* link_up;
   const char* link_down;
 } s_sg_platf_host_link_cbarg_t, *sg_platf_host_link_cbarg_t;
 
+#define SG_PLATF_HOST_LINK_INITIALIZER {NULL,NULL,NULL}
 
 typedef struct {
   const char* id;
   const char* coord;
 } s_sg_platf_router_cbarg_t, *sg_platf_router_cbarg_t;
 
+#define SG_PLATF_ROUTER_INITIALIZER {NULL,NULL}
+
 typedef struct {
   const char* id;
   double bandwidth;
@@ -98,6 +132,18 @@ typedef struct {
   xbt_dict_t properties;
 } s_sg_platf_link_cbarg_t, *sg_platf_link_cbarg_t;
 
+#define SG_PLATF_LINK_INITIALIZER {\
+  .id = NULL,\
+  .bandwidth = 0.,\
+  .bandwidth_trace = NULL,\
+  .latency = 0.,\
+  .latency_trace = NULL,\
+  .state = SURF_RESOURCE_ON,\
+  .state_trace = NULL,\
+  .policy = SURF_LINK_SHARED,\
+  .properties = NULL\
+}
+
 typedef struct s_sg_platf_peer_cbarg *sg_platf_peer_cbarg_t;
 typedef struct s_sg_platf_peer_cbarg {
   const char* id;
@@ -110,11 +156,19 @@ typedef struct s_sg_platf_peer_cbarg {
   tmgr_trace_t state_trace;
 } s_sg_platf_peer_cbarg_t;
 
-typedef struct s_sg_platf_linkctn_cbarg *sg_platf_linkctn_cbarg_t;
-typedef struct s_sg_platf_linkctn_cbarg {
-  const char *id;
-  const char *direction;
-} s_sg_platf_linkctn_cbarg_t;
+#define SG_PLATF_PEER_INITIALIZER {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+
+typedef struct s_sg_platf_route_cbarg *sg_platf_route_cbarg_t;
+typedef struct s_sg_platf_route_cbarg {
+  int symmetrical;
+  const char *src;
+  const char *dst;
+  sg_routing_edge_t gw_src;
+  sg_routing_edge_t gw_dst;
+  xbt_dynar_t link_list;
+} s_sg_platf_route_cbarg_t;
+
+#define SG_PLATF_ROUTE_INITIALIZER {TRUE,NULL,NULL,NULL,NULL,NULL}
 
 typedef struct s_sg_platf_cluster_cbarg *sg_platf_cluster_cbarg_t;
 typedef struct s_sg_platf_cluster_cbarg {
@@ -135,6 +189,9 @@ typedef struct s_sg_platf_cluster_cbarg {
   const char* state_trace;
 } s_sg_platf_cluster_cbarg_t;
 
+#define SG_PLATF_CLUSTER_INITIALIZER {NULL,NULL,NULL,NULL,NULL,NULL \
+  ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+
 typedef struct s_sg_platf_cabinet_cbarg *sg_platf_cabinet_cbarg_t;
 typedef struct s_sg_platf_cabinet_cbarg {
   const char* id;
@@ -146,12 +203,17 @@ typedef struct s_sg_platf_cabinet_cbarg {
   double lat;
 } s_sg_platf_cabinet_cbarg_t;
 
+#define SG_PLATF_CABINET_INITIALIZER {NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+
 typedef struct {
   const char* id;
   const char* type_id;
   const char* content;
+  xbt_dict_t properties;
 } s_sg_platf_storage_cbarg_t, *sg_platf_storage_cbarg_t;
 
+#define SG_PLATF_STORAGE_INITIALIZER {NULL,NULL,NULL,NULL}
+
 typedef struct {
   const char* id;
   const char* model;
@@ -160,21 +222,75 @@ typedef struct {
   unsigned long size; /* size in Gbytes */
 } s_sg_platf_storage_type_cbarg_t, *sg_platf_storage_type_cbarg_t;
 
+#define SG_PLATF_STORAGE_TYPE_INITIALIZER {NULL,NULL,NULL,NULL,NULL}
+
 typedef struct {
   const char* type_id;
   const char* name;
 } s_sg_platf_mstorage_cbarg_t, *sg_platf_mstorage_cbarg_t;
 
+#define SG_PLATF_MSTORAGE_INITIALIZER {NULL,NULL}
+
 typedef struct {
   const char* id;
   const char* name;
 } s_sg_platf_mount_cbarg_t, *sg_platf_mount_cbarg_t;
 
+#define SG_PLATF_MOUNT_INITIALIZER {NULL,NULL}
+
+typedef struct s_sg_platf_prop_cbarg *sg_platf_prop_cbarg_t;
+typedef struct s_sg_platf_prop_cbarg {
+  const char *id;
+  const char *value;
+} s_sg_platf_prop_cbarg_t;
+
+#define SG_PLATF_PROP_INITIALIZER {NULL,NULL}
+
+typedef struct s_sg_platf_trace_cbarg *sg_platf_trace_cbarg_t;
+typedef struct s_sg_platf_trace_cbarg {
+  const char *id;
+  const char *file;
+  double periodicity;
+  const char *pc_data;
+} s_sg_platf_trace_cbarg_t;
+
+#define SG_PLATF_TRACE_INITIALIZER {NULL,NULL,NULL,NULL}
+
+typedef struct s_sg_platf_trace_connect_cbarg *sg_platf_trace_connect_cbarg_t;
+typedef struct s_sg_platf_trace_connect_cbarg {
+  e_surf_trace_connect_kin_t kind;
+  const char *trace;
+  const char *element;
+} s_sg_platf_trace_connect_cbarg_t;
+
+#define SG_PLATF_TRACE_CONNECT_INITIALIZER {NULL,NULL,NULL}
+
+typedef struct s_sg_platf_process_cbarg *sg_platf_process_cbarg_t;
+typedef struct s_sg_platf_process_cbarg {
+  const char **argv;
+  int argc;
+  xbt_dict_t properties;
+  const char *host;
+  const char *function;
+  double start_time;
+  double kill_time;
+  e_surf_process_on_failure_t on_failure;
+} s_sg_platf_process_cbarg_t;
+
+#define SG_PLATF_PROCESS_INITIALIZER {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+
+typedef struct s_sg_platf_AS_cbarg *sg_platf_AS_cbarg_t;
+typedef struct s_sg_platf_AS_cbarg {
+  const char *id;
+  int routing;
+} s_sg_platf_AS_cbarg_t;
+
+#define SG_PLATF_AS_INITIALIZER {NULL,0}
 
 XBT_PUBLIC(void) sg_platf_begin(void);  // Start a new platform
 XBT_PUBLIC(void) sg_platf_end(void); // Finish the creation of the platform
 
-XBT_PUBLIC(void) sg_platf_new_AS_begin(const char *id, int mode); // Begin description of new AS
+XBT_PUBLIC(void) sg_platf_new_AS_begin(sg_platf_AS_cbarg_t AS); // Begin description of new AS
 XBT_PUBLIC(void) sg_platf_new_AS_end(void);                            // That AS is fully described
 
 XBT_PUBLIC(void) sg_platf_new_host   (sg_platf_host_cbarg_t   host);   // Add an host   to the currently described AS
@@ -184,10 +300,36 @@ XBT_PUBLIC(void) sg_platf_new_link   (sg_platf_link_cbarg_t link);     // Add a
 XBT_PUBLIC(void) sg_platf_new_peer   (sg_platf_peer_cbarg_t peer);     // Add a peer    to the currently described AS
 XBT_PUBLIC(void) sg_platf_new_cluster(sg_platf_cluster_cbarg_t clust); // Add a cluster to the currently described AS
 XBT_PUBLIC(void) sg_platf_new_cabinet(sg_platf_cabinet_cbarg_t cabinet); // Add a cabinet to the currently described AS
+
+XBT_PUBLIC(void) sg_platf_new_route (sg_platf_route_cbarg_t route); // Add a route
+XBT_PUBLIC(void) sg_platf_new_ASroute (sg_platf_route_cbarg_t ASroute); // Add an ASroute
+XBT_PUBLIC(void) sg_platf_new_bypassRoute (sg_platf_route_cbarg_t bypassroute); // Add a bypassRoute
+XBT_PUBLIC(void) sg_platf_new_bypassASroute (sg_platf_route_cbarg_t bypassASroute); // Add an bypassASroute
+XBT_PUBLIC(void) sg_platf_new_prop (sg_platf_prop_cbarg_t prop); // Add a prop
+
+XBT_PUBLIC(void) sg_platf_new_trace(sg_platf_trace_cbarg_t trace);
+XBT_PUBLIC(void) sg_platf_new_trace_connect(sg_platf_trace_connect_cbarg_t trace_connect);
+
 XBT_PUBLIC(void) sg_platf_new_storage(sg_platf_storage_cbarg_t storage); // Add a storage to the currently described AS
 XBT_PUBLIC(void) sg_platf_new_storage(sg_platf_storage_cbarg_t storage); // Add a storage to the currently described AS
 XBT_PUBLIC(void) sg_platf_new_mstorage(sg_platf_mstorage_cbarg_t mstorage);
 XBT_PUBLIC(void) sg_platf_new_storage_type(sg_platf_storage_type_cbarg_t storage_type);
 XBT_PUBLIC(void) sg_platf_new_mount(sg_platf_mount_cbarg_t mount);
 
+XBT_PUBLIC(void) sg_platf_new_process(sg_platf_process_cbarg_t process);
+
+// Add route and Asroute without xml file with those functions
+XBT_PUBLIC(void) sg_platf_route_begin (sg_platf_route_cbarg_t route); // Initialize route
+XBT_PUBLIC(void) sg_platf_route_end (sg_platf_route_cbarg_t route); // Finalize and add a route
+
+XBT_PUBLIC(void) sg_platf_ASroute_begin (sg_platf_route_cbarg_t ASroute); // Initialize ASroute
+XBT_PUBLIC(void) sg_platf_ASroute_end (sg_platf_route_cbarg_t ASroute); // Finalize and add a ASroute
+
+XBT_PUBLIC(void) sg_platf_route_add_link (const char* link_id, sg_platf_route_cbarg_t route); // Add a link to link list
+XBT_PUBLIC(void) sg_platf_ASroute_add_link (const char* link_id, sg_platf_route_cbarg_t ASroute); // Add a link to link list
+
+typedef void (*sg_platf_process_cb_t)(sg_platf_process_cbarg_t);
+XBT_PUBLIC(void) sg_platf_process_add_cb(sg_platf_process_cb_t fct);
+
+
 #endif                          /* SG_PLATF_H */
diff --git a/include/simgrid/platf_generator.h b/include/simgrid/platf_generator.h
new file mode 100644 (file)
index 0000000..767fe6e
--- /dev/null
@@ -0,0 +1,82 @@
+
+/* platf_generator.h - Public interface to the SimGrid platforms generator  */
+
+/* Copyright (c) 2004-2012. 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. */
+
+#ifndef SG_PLATF_GEN_H
+#define SG_PLATF_GEN_H
+
+#include "xbt.h"
+#include "xbt/graph.h" //Only for platf_graph_get()
+#include "platf.h"
+
+typedef enum {
+  ROUTER,
+  HOST,
+  CLUSTER
+} e_platf_node_kind;
+
+typedef struct s_context_node_t {
+  unsigned long id;
+  double x, y;
+  int degree;
+  e_platf_node_kind kind;
+  int connect_checked;
+  union {
+    s_sg_platf_host_cbarg_t host_parameters;
+    s_sg_platf_cluster_cbarg_t cluster_parameters;
+    char* router_id;
+  };
+} s_context_node_t, *context_node_t;
+
+typedef struct s_context_edge_t {
+  unsigned long id;
+  double length;
+  int labeled;
+  s_sg_platf_link_cbarg_t link_parameters;
+} s_context_edge_t, *context_edge_t;
+
+typedef void (*platf_promoter_cb_t) (context_node_t);
+typedef void (*platf_labeler_cb_t) (context_edge_t);
+
+XBT_PUBLIC(void) platf_random_seed(unsigned long seed[6]);
+
+XBT_PUBLIC(void) platf_graph_uniform(unsigned long node_count);
+XBT_PUBLIC(void) platf_graph_heavytailed(unsigned long node_count);
+
+XBT_PUBLIC(void) platf_graph_interconnect_star(void);
+XBT_PUBLIC(void) platf_graph_interconnect_line(void);
+XBT_PUBLIC(void) platf_graph_interconnect_ring(void);
+XBT_PUBLIC(void) platf_graph_interconnect_clique(void);
+XBT_PUBLIC(void) platf_graph_interconnect_uniform(double alpha);
+XBT_PUBLIC(void) platf_graph_interconnect_exponential(double alpha);
+XBT_PUBLIC(void) platf_graph_interconnect_zegura(double alpha, double beta, double r);
+XBT_PUBLIC(void) platf_graph_interconnect_waxman(double alpha, double beta);
+XBT_PUBLIC(void) platf_graph_interconnect_barabasi(void);
+
+XBT_PUBLIC(int) platf_graph_is_connected(void);
+
+XBT_PUBLIC(void) platf_graph_clear_links(void);
+
+XBT_PUBLIC(void) platf_graph_promote_to_host(context_node_t node, sg_platf_host_cbarg_t parameters);
+XBT_PUBLIC(void) platf_graph_promote_to_cluster(context_node_t node, sg_platf_cluster_cbarg_t parameters);
+
+XBT_PUBLIC(void) platf_graph_link_label(context_edge_t edge, sg_platf_link_cbarg_t parameters);
+
+XBT_PUBLIC(void) platf_graph_promoter(platf_promoter_cb_t promoter_callback);
+XBT_PUBLIC(void) platf_graph_labeler(platf_labeler_cb_t labeler_callback);
+
+XBT_PUBLIC(void) platf_do_promote(void);
+XBT_PUBLIC(void) platf_do_label(void);
+
+XBT_PUBLIC(void) platf_generate(void);
+
+// WARNING : Only for debbugging ; should be removed when platform
+// generation works correctly
+XBT_PUBLIC(xbt_graph_t) platf_graph_get(void);
+
+#endif              /* SG_PLATF_GEN_H */
+
index e27cbaa..5fe3313 100644 (file)
@@ -365,6 +365,8 @@ XBT_PUBLIC(void) simcall_rdv_destroy(smx_rdv_t rvp);
 XBT_PUBLIC(smx_rdv_t) simcall_rdv_get_by_name(const char *name);
 XBT_PUBLIC(int) simcall_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host);
 XBT_PUBLIC(smx_action_t) simcall_rdv_get_head(smx_rdv_t rdv);
+XBT_PUBLIC(smx_process_t) simcall_rdv_get_receiver(smx_rdv_t rdv);
+XBT_PUBLIC(void) simcall_rdv_set_receiver(smx_rdv_t rdv , smx_process_t process);
 
 XBT_PUBLIC(xbt_dict_t) SIMIX_get_rdv_points(void);
 
@@ -394,7 +396,8 @@ XBT_PUBLIC(smx_action_t) simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff,
                                               void *data);
 
 XBT_PUBLIC(void) simcall_comm_destroy(smx_action_t comm);
-
+XBT_PUBLIC(smx_action_t) simcall_comm_iprobe(smx_rdv_t rdv, int src, int tag,
+                                int (*match_fun)(void *, void *, smx_action_t), void *data);
 XBT_PUBLIC(void) simcall_comm_cancel(smx_action_t comm);
 
 /* FIXME: waitany is going to be a vararg function, and should take a timeout */
@@ -454,6 +457,13 @@ XBT_PUBLIC(size_t) simcall_file_write(const void* ptr, size_t size, size_t nmemb
 XBT_PUBLIC(smx_file_t) simcall_file_open(const char* storage, const char* path, const char* mode);
 XBT_PUBLIC(int) simcall_file_close(smx_file_t fp);
 XBT_PUBLIC(int) simcall_file_stat(smx_file_t fd, s_file_stat_t *buf);
+XBT_PUBLIC(int) simcall_file_unlink(smx_file_t fd);
+XBT_PUBLIC(xbt_dict_t) simcall_file_ls(const char* mount, const char* path);
+
+/************************** AS router   **********************************/
+XBT_PUBLIC(xbt_dict_t) SIMIX_asr_get_properties(const char *name);
+/************************** AS router simcalls ***************************/
+XBT_PUBLIC(xbt_dict_t) simcall_asr_get_properties(const char *name);
 
 SG_END_DECL()
 #endif                          /* _SIMIX_SIMIX_H */
index 9d08843..822c1a0 100644 (file)
@@ -35,6 +35,7 @@ SG_BEGIN_DECL()
 #define MPI_MAX_PORT_NAME      100
 #define SMPI_RAND_SEED 5
 #define MPI_ANY_SOURCE -1
+#define MPI_BOTTOM (void *)0
 #define MPI_PROC_NULL -2
 #define MPI_ANY_TAG -1
 #define MPI_UNDEFINED -1
@@ -162,7 +163,7 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Query_thread, (int *provided));
 MPI_CALL(XBT_PUBLIC(int), MPI_Is_thread_main, (int *flag));
 MPI_CALL(XBT_PUBLIC(int), MPI_Abort, (MPI_Comm comm, int errorcode));
 MPI_CALL(XBT_PUBLIC(double), MPI_Wtime, (void));
-
+MPI_CALL(XBT_PUBLIC(double), MPI_Wtick,(void));
 MPI_CALL(XBT_PUBLIC(int), MPI_Address, (void *location, MPI_Aint * address));
 
 MPI_CALL(XBT_PUBLIC(int), MPI_Type_free, (MPI_Datatype * datatype));
@@ -173,7 +174,28 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Type_get_extent,
 MPI_CALL(XBT_PUBLIC(int), MPI_Type_extent, (MPI_Datatype datatype, MPI_Aint * extent));
 MPI_CALL(XBT_PUBLIC(int), MPI_Type_lb, (MPI_Datatype datatype, MPI_Aint * disp));
 MPI_CALL(XBT_PUBLIC(int), MPI_Type_ub, (MPI_Datatype datatype, MPI_Aint * disp));
-
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_commit, (MPI_Datatype* datatype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_hindexed,
+                            (int count, int* blocklens, MPI_Aint* indices,
+                            MPI_Datatype old_type, MPI_Datatype* newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_hvector,
+                            (int count, int blocklen, MPI_Aint stride,
+                             MPI_Datatype old_type, MPI_Datatype* newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_indexed,
+                            (int count, int* blocklens, int* indices,
+                             MPI_Datatype old_type, MPI_Datatype* newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_struct,
+                            (int count, int* blocklens, MPI_Aint* indices,
+                             MPI_Datatype* old_types, MPI_Datatype* newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_vector,
+                            (int count, int blocklen, int stride,
+                             MPI_Datatype old_type, MPI_Datatype* newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_contiguous,
+                            (int count, MPI_Datatype old_type,
+                             MPI_Datatype* newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Testall,
+                            (int count, MPI_Request* requests, int* flag,
+                             MPI_Status* statuses));
 MPI_CALL(XBT_PUBLIC(int), MPI_Op_create,
                             (MPI_User_function * function, int commute,
                              MPI_Op * op));
@@ -345,6 +367,13 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Alltoallv,
                              void *recvbuf, int *recvcounts,
                              int *recvdisps, MPI_Datatype recvtype,
                              MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC(int), MPI_Iprobe,
+                            (int source, int tag, MPI_Comm comm,
+                             int* flag, MPI_Status* status));
+MPI_CALL(XBT_PUBLIC(int), MPI_Probe,
+                            (int source, int tag, MPI_Comm comm,
+                             MPI_Status* status));
+
 
 //FIXME: these are not yet implemented
 typedef void MPI_Handler_function(MPI_Comm*, int*, ...);
@@ -375,19 +404,12 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Errhandler_free, (MPI_Errhandler* errhandler));
 MPI_CALL(XBT_PUBLIC(int), MPI_Errhandler_get, (MPI_Comm comm, MPI_Errhandler* errhandler));
 MPI_CALL(XBT_PUBLIC(int), MPI_Error_string, (int errorcode, char* string, int* resultlen));
 MPI_CALL(XBT_PUBLIC(int), MPI_Errhandler_set, (MPI_Comm comm, MPI_Errhandler errhandler));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_contiguous, (int count, MPI_Datatype old_type, MPI_Datatype* newtype));
 MPI_CALL(XBT_PUBLIC(int), MPI_Cancel, (MPI_Request* request));
 MPI_CALL(XBT_PUBLIC(int), MPI_Buffer_attach, (void* buffer, int size));
 MPI_CALL(XBT_PUBLIC(int), MPI_Buffer_detach, (void* buffer, int* size));
 MPI_CALL(XBT_PUBLIC(int), MPI_Testsome, (int incount, MPI_Request* requests, int* outcount, int* indices, MPI_Status* statuses));
 MPI_CALL(XBT_PUBLIC(int), MPI_Comm_test_inter, (MPI_Comm comm, int* flag));
 MPI_CALL(XBT_PUBLIC(int), MPI_Unpack, (void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_commit, (MPI_Datatype* datatype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_hindexed, (int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* newtype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_hvector, (int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* newtype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_indexed, (int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* newtype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_struct, (int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* newtype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_vector, (int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* newtype));
 MPI_CALL(XBT_PUBLIC(int), MPI_Ssend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
 MPI_CALL(XBT_PUBLIC(int), MPI_Ssend_init, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
 MPI_CALL(XBT_PUBLIC(int), MPI_Intercomm_create, (MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out));
@@ -398,7 +420,6 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Ibsend, (void* buf, int count, MPI_Datatype dataty
 MPI_CALL(XBT_PUBLIC(int), MPI_Comm_remote_group, (MPI_Comm comm, MPI_Group* group));
 MPI_CALL(XBT_PUBLIC(int), MPI_Comm_remote_size, (MPI_Comm comm, int* size));
 MPI_CALL(XBT_PUBLIC(int), MPI_Issend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
-MPI_CALL(XBT_PUBLIC(int), MPI_Probe, (int source, int tag, MPI_Comm comm, MPI_Status* status));
 MPI_CALL(XBT_PUBLIC(int), MPI_Attr_delete, (MPI_Comm comm, int keyval));
 MPI_CALL(XBT_PUBLIC(int), MPI_Attr_get, (MPI_Comm comm, int keyval, void* attr_value, int* flag));
 MPI_CALL(XBT_PUBLIC(int), MPI_Attr_put, (MPI_Comm comm, int keyval, void* attr_value));
@@ -409,10 +430,8 @@ MPI_CALL(XBT_PUBLIC(int), MPI_Keyval_create, (MPI_Copy_function* copy_fn, MPI_De
 MPI_CALL(XBT_PUBLIC(int), MPI_Keyval_free, (int* keyval));
 MPI_CALL(XBT_PUBLIC(int), MPI_Test_cancelled, (MPI_Status* status, int* flag));
 MPI_CALL(XBT_PUBLIC(int), MPI_Pack, (void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Testall, (int count, MPI_Request* requests, int* flag, MPI_Status* statuses));
 MPI_CALL(XBT_PUBLIC(int), MPI_Get_elements, (MPI_Status* status, MPI_Datatype datatype, int* elements));
 MPI_CALL(XBT_PUBLIC(int), MPI_Dims_create, (int nnodes, int ndims, int* dims));
-MPI_CALL(XBT_PUBLIC(int), MPI_Iprobe, (int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status));
 MPI_CALL(XBT_PUBLIC(int), MPI_Initialized, (int* flag));
 //FIXME: End of all the not yet implemented stuff
 
@@ -427,11 +446,10 @@ XBT_PUBLIC(unsigned int) smpi_sleep(unsigned int secs);
 XBT_PUBLIC(int) smpi_gettimeofday(struct timeval *tv, struct timezone *tz);
 XBT_PUBLIC(unsigned long long) smpi_rastro_resolution (void);
 XBT_PUBLIC(unsigned long long) smpi_rastro_timestamp (void);
-XBT_PUBLIC(int) smpi_sample_1(int global, const char *file, int line,
+XBT_PUBLIC(void) smpi_sample_1(int global, const char *file, int line,
                               int iters, double threshold);
 XBT_PUBLIC(int) smpi_sample_2(int global, const char *file, int line);
 XBT_PUBLIC(void) smpi_sample_3(int global, const char *file, int line);
-XBT_PUBLIC(void) smpi_sample_flops(double flops);
 
 #define SMPI_SAMPLE_LOCAL(iters,thres) for(smpi_sample_1(0, __FILE__, __LINE__, iters, thres); \
                                            smpi_sample_2(0, __FILE__, __LINE__);      \
@@ -441,7 +459,8 @@ XBT_PUBLIC(void) smpi_sample_flops(double flops);
                                             smpi_sample_2(1, __FILE__, __LINE__);      \
                                             smpi_sample_3(1, __FILE__, __LINE__))
 
-#define SMPI_SAMPLE_DELAY(flops) for(smpi_sample_flops(flops); 0; )
+#define SMPI_SAMPLE_DELAY(duration) for(smpi_execute(duration); 0; )
+#define SMPI_SAMPLE_FLOPS(flops) for(smpi_execute_flops(flops); 0; )
 
 XBT_PUBLIC(void *) smpi_shared_malloc(size_t size, const char *file,
                                       int line);
index e42c4da..2d0e95e 100644 (file)
@@ -8,6 +8,7 @@
 #define _SURF_SURF_ROUTING_H
 
 #include "xbt/lib.h"
+#include "simgrid/platf_interface.h"
 
 extern xbt_lib_t host_lib;
 extern int ROUTING_HOST_LEVEL; //Routing level
@@ -28,6 +29,7 @@ extern xbt_lib_t as_router_lib;
 extern int ROUTING_ASR_LEVEL;  //Routing level
 extern int COORD_ASR_LEVEL;  //Coordinates level
 extern int NS3_ASR_LEVEL;    //host node for ns3
+extern int ROUTING_PROP_ASR_LEVEL; //Properties for AS and router
 
 extern xbt_lib_t storage_lib;
 extern int ROUTING_STORAGE_LEVEL;        //Routing storage level
@@ -38,8 +40,8 @@ extern xbt_lib_t storage_type_lib;
 extern int ROUTING_STORAGE_TYPE_LEVEL;   //Routing storage_type level
 
 /* The callbacks to register for the routing to work */
-void routing_AS_begin(const char *AS_id, int wanted_routing_type);
-void routing_AS_end(void);
+void routing_AS_begin(sg_platf_AS_cbarg_t AS);
+void routing_AS_end(sg_platf_AS_cbarg_t AS);
 
 void routing_cluster_add_backbone(void* bb);
 
index 98c47d2..3564ab7 100644 (file)
 
 SG_BEGIN_DECL()
 
-/* Hook for the different tags. All the functions which pointer to are push into here are run when the tag is encountered */
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_route_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_route_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_link_ctn_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_link_ctn_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_process_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_process_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_argument_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_argument_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_prop_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_prop_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_trace_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_trace_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_trace_connect_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_trace_connect_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_random_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_random_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_ASroute_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_ASroute_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_bypassRoute_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_bypassRoute_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_bypassASroute_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_bypassASroute_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_peer_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_peer_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_include_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_include_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) STag_surfxml_storage_cb_list;
-XBT_PUBLIC_DATA(xbt_dynar_t) ETag_surfxml_storage_cb_list;
-
 XBT_PUBLIC(void) surf_parse_open(const char *file);
 XBT_PUBLIC(void) surf_parse_close(void);
 XBT_PUBLIC(void) surf_parse_init_callbacks(void);
@@ -98,10 +68,5 @@ extern unsigned int surfxml_buffer_stack_stack[1024];
     ETag_surfxml_##tag();                                               \
   } while(0)
 
-XBT_PUBLIC(void) surfxml_add_callback(xbt_dynar_t cb_list,
-                                      void_f_void_t function);
-XBT_PUBLIC(void) surfxml_del_callback(xbt_dynar_t cb_list,
-                                      void_f_void_t function);
-
 SG_END_DECL()
 #endif
index 3b71d77..95fbc2c 100644 (file)
@@ -56,11 +56,10 @@ extern xbt_mheap_t mmalloc_get_default_md(void);
 void mmalloc_set_current_heap(xbt_mheap_t new_heap);
 xbt_mheap_t mmalloc_get_current_heap(void);
 
-int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2);
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2);
 
-void mmalloc_backtrace_block_display(void *heapinfo, size_t block);
-
-void mmalloc_backtrace_fragment_display(void *heapinfo, size_t block, size_t frag);
+void mmalloc_backtrace_block_display(void* heapinfo, int block);
+void mmalloc_backtrace_fragment_display(void* heapinfo, int block, int frag);
 
 
 
index 865ea28..39ecbd6 100644 (file)
@@ -49,6 +49,8 @@ XBT_PUBLIC(char *) xbt_str_diff(const char *a, const char *b);
 
 XBT_PUBLIC(char *) xbt_str_from_file(FILE * file);
 
+XBT_PUBLIC(int) xbt_str_start_with(const char* str, const char* start);
+
 #define DJB2_HASH_FUNCTION
 //#define FNV_HASH_FUNCTION
 
index a2ebe11..74d63ea 100644 (file)
@@ -336,7 +336,10 @@ int console_AS_open(lua_State *L) {
  else if(!strcmp(mode,"none")) mode_int = A_surfxml_AS_routing_None;
  else xbt_die("Don't have the model name '%s'",mode);
 
- sg_platf_new_AS_begin(id,mode_int);
+ s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+ AS.id = id;
+ AS.routing = mode_int;
+ sg_platf_new_AS_begin(&AS);
 
  return 0;
 }
index 0b64046..da5a3ca 100644 (file)
@@ -14,5 +14,12 @@ SG_BEGIN_DECL()
 /******************************* Transitions **********************************/
 typedef struct s_mc_transition *mc_transition_t;
 
+typedef struct s_mc_ignore_region{
+  int block;
+  int fragment;
+  void *address;
+  size_t size;
+}s_mc_ignore_region_t, *mc_ignore_region_t;
+
 SG_END_DECL()
 #endif                          /* _MC_MC_H */
index 1febbe0..cbc7ce3 100644 (file)
@@ -14,6 +14,7 @@
 #include "simgrid/simix.h"
 #include "simgrid/modelchecker.h" /* our public interface (and definition of HAVE_MC) */
 #include "xbt/automaton.h"
+#include "xbt/dynar.h"
 
 #define STD_HEAP_SIZE   20480000        /* Maximum size of the system's heap */
 
@@ -21,6 +22,8 @@ SG_BEGIN_DECL()
 
 extern char*_surf_mc_property_file; /* fixme: better location? */
 
+extern xbt_dynar_t mmalloc_ignore;
+
 /********************************* Global *************************************/
 void _mc_cfg_cb_reduce(const char *name, int pos);
 void _mc_cfg_cb_checkpoint(const char *name, int pos);
@@ -37,6 +40,9 @@ XBT_PUBLIC(void) MC_process_clock_add(smx_process_t, double);
 XBT_PUBLIC(double) MC_process_clock_get(smx_process_t);
 void MC_automaton_load(const char *file);
 
+void MC_ignore_init(void);
+XBT_PUBLIC(void) MC_ignore(void *address, size_t size);
+
 /********************************* Memory *************************************/
 XBT_PUBLIC(void) MC_memory_init(void);  /* Initialize the memory subsystem */
 XBT_PUBLIC(void) MC_memory_exit(void);
index 683ca3e..a92b8ef 100644 (file)
@@ -25,7 +25,13 @@ typedef void (*sg_platf_link_cb_t)(sg_platf_link_cbarg_t);
 typedef void (*sg_platf_peer_cb_t)(sg_platf_peer_cbarg_t);
 typedef void (*sg_platf_cluster_cb_t)(sg_platf_cluster_cbarg_t);
 typedef void (*sg_platf_cabinet_cb_t)(sg_platf_cabinet_cbarg_t);
-typedef void (*sg_platf_AS_begin_cb_t)(const char*id, int routing);
+typedef void (*sg_platf_AS_cb_t)(sg_platf_AS_cbarg_t);
+typedef void (*sg_platf_prop_cb_t)(sg_platf_prop_cbarg_t);
+
+typedef void (*sg_platf_route_cb_t)(sg_platf_route_cbarg_t);
+
+typedef void (*sg_platf_trace_cb_t)(sg_platf_trace_cbarg_t);
+typedef void (*sg_platf_trace_connect_cb_t)(sg_platf_trace_connect_cbarg_t);
 
 typedef void (*sg_platf_storage_cb_t)(sg_platf_storage_cbarg_t);
 typedef void (*sg_platf_storage_type_cb_t)(sg_platf_storage_type_cbarg_t);
@@ -40,8 +46,17 @@ void sg_platf_peer_add_cb(sg_platf_peer_cb_t fct);
 void sg_platf_cluster_add_cb(sg_platf_cluster_cb_t fct);
 void sg_platf_cabinet_add_cb(sg_platf_cabinet_cb_t fct);
 void sg_platf_postparse_add_cb(void_f_void_t fct);
-void sg_platf_AS_begin_add_cb(sg_platf_AS_begin_cb_t fct);
-void sg_platf_AS_end_add_cb(void_f_void_t fct);
+void sg_platf_AS_begin_add_cb(sg_platf_AS_cb_t fct);
+void sg_platf_AS_end_add_cb(sg_platf_AS_cb_t fct);
+void sg_platf_prop_add_cb(sg_platf_prop_cb_t fct);
+
+void sg_platf_route_add_cb(sg_platf_route_cb_t);
+void sg_platf_ASroute_add_cb(sg_platf_route_cb_t);
+void sg_platf_bypassRoute_add_cb(sg_platf_route_cb_t);
+void sg_platf_bypassASroute_add_cb(sg_platf_route_cb_t);
+
+void sg_platf_trace_add_cb(sg_platf_trace_cb_t);
+void sg_platf_trace_connect_add_cb(sg_platf_trace_connect_cb_t);
 
 void sg_platf_storage_add_cb(sg_platf_storage_cb_t fct);
 void sg_platf_mstorage_add_cb(sg_platf_mstorage_cb_t fct);
index 7842c9e..475f9da 100644 (file)
@@ -97,6 +97,7 @@ typedef struct surf_action {
 #endif
   surf_file_t file;        /**< surf_file_t for storage model */
   s_file_stat_t stat;        /**< surf_file_t for storage model */
+  xbt_dict_t ls_dict;
 } s_surf_action_t;
 
 typedef struct surf_action_lmm {
@@ -223,6 +224,8 @@ typedef struct surf_storage_model_extension_public {
   surf_action_t(*read) (void *storage, void* ptr, double size, size_t nmemb, surf_file_t stream);
   surf_action_t(*write) (void *storage, const void* ptr, size_t size, size_t nmemb, surf_file_t stream);
   surf_action_t(*stat) (void *storage, surf_file_t stream);
+  surf_action_t(*unlink) (void *storage, surf_file_t stream);
+  surf_action_t(*ls) (void *storage, const char *path);
   void* (*create_resource) (const char* id, const char* model, const char* type_id, const char *content);
 } s_surf_model_extension_storage_t;
 
@@ -256,6 +259,9 @@ typedef struct surf_workstation_model_extension_public {
   surf_action_t(*read) (void *workstation, void* ptr, size_t size, size_t nmemb, surf_file_t stream);
   surf_action_t(*write) (void *workstation, const void* ptr, size_t size, size_t nmemb, surf_file_t stream);
   surf_action_t(*stat) (void *workstation, surf_file_t stream);
+  surf_action_t(*unlink) (void *workstation, surf_file_t stream);
+  surf_action_t(*ls) (void *workstation, const char* mount, const char *path);
+
   int (*link_shared) (const void *link);
    xbt_dict_t(*get_properties) (const void *resource);
   void* (*link_create_resource) (const char *name,
@@ -567,11 +573,6 @@ XBT_PUBLIC(void) surf_network_model_init_Vegas(void);
 XBT_PUBLIC_DATA(s_surf_model_description_t)
     surf_network_model_description[];
 
-
-
-
-
-
 /** \ingroup SURF_models
  *  \brief The storage model
  */
@@ -583,12 +584,6 @@ XBT_PUBLIC(void) surf_storage_model_init_default(void);
  */
 XBT_PUBLIC_DATA(s_surf_model_description_t) surf_storage_model_description[];
 
-
-
-
-
-
-
 /** \ingroup SURF_models
  *  \brief The workstation model
  *
@@ -729,6 +724,8 @@ XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_latency;
 
 XBT_PUBLIC(double) get_cpu_power(const char *power);
 
+XBT_PUBLIC(xbt_dict_t) get_as_router_properties(const char* name);
+
 int surf_get_nthreads(void);
 void surf_set_nthreads(int nthreads);
 
index ab5d51f..3498cec 100644 (file)
@@ -24,6 +24,7 @@ typedef struct s_xbt_os_timer *xbt_os_timer_t;
 XBT_PUBLIC(xbt_os_timer_t) xbt_os_timer_new(void);
 XBT_PUBLIC(void) xbt_os_timer_free(xbt_os_timer_t timer);
 XBT_PUBLIC(void) xbt_os_timer_start(xbt_os_timer_t timer);
+XBT_PUBLIC(void) xbt_os_timer_resume(xbt_os_timer_t timer);
 XBT_PUBLIC(void) xbt_os_timer_stop(xbt_os_timer_t timer);
 XBT_PUBLIC(double) xbt_os_timer_elapsed(xbt_os_timer_t timer);
 
index 3e783a1..510dd55 100644 (file)
@@ -16,6 +16,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration");
 #define OPT_TRACING_PLATFORM      "tracing/platform"
 #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_CATEGORIZED   "tracing/categorized"
 #define OPT_TRACING_UNCATEGORIZED "tracing/uncategorized"
 #define OPT_TRACING_MSG_PROCESS   "tracing/msg/process"
@@ -24,6 +25,9 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_config, instr, "Configuration");
 #define OPT_TRACING_BUFFER        "tracing/buffer"
 #define OPT_TRACING_ONELINK_ONLY  "tracing/onelink_only"
 #define OPT_TRACING_DISABLE_DESTROY "tracing/disable_destroy"
+#define OPT_TRACING_BASIC         "tracing/basic"
+#define OPT_TRACING_COMMENT       "tracing/comment"
+#define OPT_TRACING_COMMENT_FILE  "tracing/comment_file"
 #define OPT_TRIVA_UNCAT_CONF      "triva/uncategorized"
 #define OPT_TRIVA_CAT_CONF        "triva/categorized"
 #define OPT_VIVA_UNCAT_CONF      "viva/uncategorized"
@@ -33,6 +37,7 @@ static int trace_enabled;
 static int trace_platform;
 static int trace_smpi_enabled;
 static int trace_smpi_grouped;
+static int trace_smpi_computing;
 static int trace_categorized;
 static int trace_uncategorized;
 static int trace_msg_process_enabled;
@@ -40,6 +45,7 @@ static int trace_msg_vm_enabled;
 static int trace_buffer;
 static int trace_onelink_only;
 static int trace_disable_destroy;
+static int trace_basic;
 
 static int trace_configured = 0;
 static int trace_active = 0;
@@ -50,6 +56,7 @@ static void TRACE_getopts(void)
   trace_platform = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_PLATFORM);
   trace_smpi_enabled = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_SMPI);
   trace_smpi_grouped = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_SMPI_GROUP);
+  trace_smpi_computing = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_SMPI_COMPUTING);
   trace_categorized = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_CATEGORIZED);
   trace_uncategorized = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_UNCATEGORIZED);
   trace_msg_process_enabled = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_MSG_PROCESS);
@@ -57,6 +64,7 @@ static void TRACE_getopts(void)
   trace_buffer = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_BUFFER);
   trace_onelink_only = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_ONELINK_ONLY);
   trace_disable_destroy = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_DISABLE_DESTROY);
+  trace_basic = xbt_cfg_get_int(_surf_cfg_set, OPT_TRACING_BASIC);
 }
 
 int TRACE_start()
@@ -167,6 +175,12 @@ int TRACE_smpi_is_grouped(void)
   return trace_smpi_grouped;
 }
 
+int TRACE_smpi_is_computing(void)
+{
+  return trace_smpi_computing;
+}
+
+
 int TRACE_categorized (void)
 {
   return trace_categorized;
@@ -203,6 +217,21 @@ int TRACE_disable_destroy (void)
   return trace_disable_destroy && TRACE_is_enabled();
 }
 
+int TRACE_basic (void)
+{
+  return trace_basic && TRACE_is_enabled();
+}
+
+char *TRACE_get_comment (void)
+{
+  return xbt_cfg_get_string(_surf_cfg_set, OPT_TRACING_COMMENT);
+}
+
+char *TRACE_get_comment_file (void)
+{
+  return xbt_cfg_get_string(_surf_cfg_set, OPT_TRACING_COMMENT_FILE);
+}
+
 char *TRACE_get_filename(void)
 {
   return xbt_cfg_get_string(_surf_cfg_set, OPT_TRACING_FILENAME);
@@ -265,6 +294,12 @@ void TRACE_global_init(int *argc, char **argv)
                    xbt_cfgelm_int, &default_tracing_smpi_grouped, 0, 1,
                    NULL, NULL);
 
+  /* smpi computing */
+  int default_tracing_smpi_computing = 0;
+  xbt_cfg_register(&_surf_cfg_set, OPT_TRACING_SMPI_COMPUTING,
+                   "Generate states for timing out of SMPI parts of the application",
+                   xbt_cfgelm_int, &default_tracing_smpi_computing, 0, 1,
+                   NULL, NULL);
 
   /* tracing categorized resource utilization traces */
   int default_tracing_categorized = 0;
@@ -315,6 +350,27 @@ void TRACE_global_init(int *argc, char **argv)
                    xbt_cfgelm_int, &default_disable_destroy, 0, 1,
                    NULL, NULL);
 
+  /* basic -- Avoid extended events (impoverished trace file) */
+  int default_basic = 0;
+  xbt_cfg_register(&_surf_cfg_set, OPT_TRACING_BASIC,
+                   "Avoid extended events (impoverished trace file).",
+                   xbt_cfgelm_int, &default_basic, 0, 1,
+                   NULL, NULL);
+
+  /* comment */
+  char *default_tracing_comment = xbt_strdup ("");
+  xbt_cfg_register(&_surf_cfg_set, OPT_TRACING_COMMENT,
+                   "Comment to be added on the top of the trace file.",
+                   xbt_cfgelm_string, &default_tracing_comment, 1, 1,
+                   NULL, NULL);
+
+  /* comment_file */
+  char *default_tracing_comment_file = xbt_strdup ("");
+  xbt_cfg_register(&_surf_cfg_set, OPT_TRACING_COMMENT_FILE,
+                   "The contents of the file are added to the top of the trace file as comment.",
+                   xbt_cfgelm_string, &default_tracing_comment_file, 1, 1,
+                   NULL, NULL);
+
   /* Triva graph configuration for uncategorized tracing */
   char *default_triva_uncat_conf_file = xbt_strdup ("");
   xbt_cfg_register(&_surf_cfg_set, OPT_TRIVA_UNCAT_CONF,
@@ -393,6 +449,10 @@ void TRACE_help (int detailed)
       "  This option only has effect if this simulator is SMPI-based. The processes\n"
       "  are grouped by the hosts where they were executed.",
       detailed);
+  print_line (OPT_TRACING_SMPI_COMPUTING, "Generates a \" Computing \" State",
+      "  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_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"
@@ -417,6 +477,18 @@ void TRACE_help (int detailed)
       "  used with simulators that have a different notion of time (different from\n"
       "  the simulated time).",
       detailed);
+  print_line (OPT_TRACING_BASIC, "Avoid extended events (impoverished trace file).",
+      "  Some visualization tools are not able to parse correctly the Paje file format.\n"
+      "  Use this option if you are using one of these tools to visualize the simulation\n"
+      "  trace. Keep in mind that the trace might be incomplete, without all the\n"
+      "  information that would be registered otherwise.",
+      detailed);
+  print_line (OPT_TRACING_COMMENT, "Comment to be added on the top of the trace file.",
+      "  Use this to add a comment line to the top of the trace file.",
+      detailed);
+  print_line (OPT_TRACING_COMMENT_FILE, "File contents added to trace file as comment.",
+      "  Use this to add the contents of a file to the top of the trace file as comment.",
+      detailed);
   print_line (OPT_TRIVA_UNCAT_CONF, "Generate graph configuration for Triva",
       "  This option can be used in all types of simulators build with SimGrid\n"
       "  to generate a uncategorized resource utilization graph to be used as\n"
@@ -582,6 +654,37 @@ void TRACE_generate_viva_cat_conf (void)
   generate_cat_configuration (TRACE_get_viva_cat_conf(), "viva", 0);
 }
 
+static int previous_trace_state = -1;
+
+void instr_pause_tracing (void)
+{
+  previous_trace_state = trace_enabled;
+  if (!TRACE_is_enabled()){
+    XBT_DEBUG ("Tracing is already paused, therefore do nothing.");
+  }else{
+    XBT_DEBUG ("Tracing is being paused.");
+  }
+  trace_enabled = 0;
+  XBT_DEBUG ("Tracing is paused.");
+}
+
+void instr_resume_tracing (void)
+{
+  if (TRACE_is_enabled()){
+    XBT_DEBUG ("Tracing is already running while trying to resume, therefore do nothing.");
+  }else{
+    XBT_DEBUG ("Tracing is being resumed.");
+  }
+
+  if (previous_trace_state != -1){
+    trace_enabled = previous_trace_state;
+  }else{
+    trace_enabled = 1;
+  }
+  XBT_DEBUG ("Tracing is resumed.");
+  previous_trace_state = -1;
+}
+
 #undef OPT_TRACING
 #undef OPT_TRACING_PLATFORM
 #undef OPT_TRACING_SMPI
@@ -593,6 +696,9 @@ void TRACE_generate_viva_cat_conf (void)
 #undef OPT_TRACING_BUFFER
 #undef OPT_TRACING_ONELINK_ONLY
 #undef OPT_TRACING_DISABLE_DESTROY
+#undef OPT_TRACING_BASIC
+#undef OPT_TRACING_COMMENT
+#undef OPT_TRACING_COMMENT_FILE
 #undef OPT_TRIVA_UNCAT_CONF
 #undef OPT_TRIVA_CAT_CONF
 #undef OPT_VIVA_UNCAT_CONF
index 7855291..3c06b95 100644 (file)
@@ -1146,4 +1146,22 @@ xbt_dynar_t TRACE_get_edge_types (void)
   return instr_dict_to_dynar (trivaEdgeTypes);
 }
 
+/** \ingroup TRACE_API
+ *  \brief Pauses all tracing activities.
+ *  \see TRACE_resume
+ */
+void TRACE_pause (void)
+{
+  instr_pause_tracing();
+}
+
+/** \ingroup TRACE_API
+ *  \brief Resumes all tracing activities.
+ *  \see TRACE_pause
+ */
+void TRACE_resume (void)
+{
+  instr_resume_tracing();
+}
+
 #endif /* HAVE_TRACING */
index 94e1970..a2d8901 100644 (file)
@@ -40,12 +40,10 @@ void TRACE_msg_process_change_host(msg_process_t process, msg_host_t old_host, m
     new_pajeStartLink (MSG_get_clock(), PJ_container_get_root(), type, msg, "M", key);
 
     //destroy existing container of this process
-    container_t existing_container = PJ_container_get(instr_process_id(process, str, len));
-    PJ_container_remove_from_parent (existing_container);
-    PJ_container_free(existing_container);
+    TRACE_msg_process_destroy (MSG_process_get_name (process), MSG_process_get_PID (process), old_host);
 
     //create new container on the new_host location
-    msg = PJ_container_new(instr_process_id(process, str, len), INSTR_MSG_PROCESS, PJ_container_get(SIMIX_host_get_name(new_host->smx_host)));
+    TRACE_msg_process_create (MSG_process_get_name (process), MSG_process_get_PID (process), new_host);
 
     //end link
     msg = PJ_container_get(instr_process_id(process, str, len));
@@ -65,14 +63,21 @@ void TRACE_msg_process_create (const char *process_name, int process_pid, msg_ho
   }
 }
 
+void TRACE_msg_process_destroy (const char *process_name, int process_pid, msg_host_t host)
+{
+  int len = INSTR_DEFAULT_STR_SIZE;
+  char str[INSTR_DEFAULT_STR_SIZE];
+
+  container_t process = PJ_container_get (instr_process_id_2 (process_name, process_pid, str, len));
+  PJ_container_remove_from_parent (process);
+  PJ_container_free (process);
+}
+
 void TRACE_msg_process_kill(msg_process_t process)
 {
   if (TRACE_msg_process_is_enabled()){
-    int len = INSTR_DEFAULT_STR_SIZE;
-    char str[INSTR_DEFAULT_STR_SIZE];
-
     //kill means that this process no longer exists, let's destroy it
-    PJ_container_free (PJ_container_get (instr_process_id(process, str, len)));
+    TRACE_msg_process_destroy (MSG_process_get_name (process), MSG_process_get_PID (process), MSG_process_get_host (process));
   }
 }
 
diff --git a/src/instr/instr_paje_header.c b/src/instr/instr_paje_header.c
new file mode 100644 (file)
index 0000000..fc7a5d0
--- /dev/null
@@ -0,0 +1,257 @@
+/* Copyright (c) 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 "instr/instr_private.h"
+
+#ifdef HAVE_TRACING
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_header, instr, "Paje tracing event system (header)");
+
+extern FILE *tracing_file;
+
+static void TRACE_header_PajeDefineContainerType (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDefineContainerType %d\n", PAJE_DefineContainerType);
+  fprintf(tracing_file, "%%       Alias string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       ContainerType string\n");
+  }else{
+    fprintf(tracing_file, "%%       Type string\n");
+  }
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeDefineVariableType (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDefineVariableType %d\n", PAJE_DefineVariableType);
+  fprintf(tracing_file, "%%       Alias string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       ContainerType string\n");
+  }else{
+    fprintf(tracing_file, "%%       Type string\n");
+  }
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%       Color color\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeDefineStateType (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDefineStateType %d\n", PAJE_DefineStateType);
+  fprintf(tracing_file, "%%       Alias string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       ContainerType string\n");
+  }else{
+    fprintf(tracing_file, "%%       Type string\n");
+  }
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeDefineEventType (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDefineEventType %d\n", PAJE_DefineEventType);
+  fprintf(tracing_file, "%%       Alias string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       ContainerType string\n");
+  }else{
+    fprintf(tracing_file, "%%       Type string\n");
+  }
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeDefineLinkType (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDefineLinkType %d\n", PAJE_DefineLinkType);
+  fprintf(tracing_file, "%%       Alias string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       ContainerType string\n");
+    fprintf(tracing_file, "%%       SourceContainerType string\n");
+    fprintf(tracing_file, "%%       DestContainerType string\n");
+  }else{
+    fprintf(tracing_file, "%%       Type string\n");
+    fprintf(tracing_file, "%%       StartContainerType string\n");
+    fprintf(tracing_file, "%%       EndContainerType string\n");
+  }
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeDefineEntityValue (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDefineEntityValue %d\n", PAJE_DefineEntityValue);
+  fprintf(tracing_file, "%%       Alias string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       EntityType string\n");
+  }else{
+    fprintf(tracing_file, "%%       Type string\n");
+  }
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%       Color color\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeCreateContainer (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeCreateContainer %d\n", PAJE_CreateContainer);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Alias string\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeDestroyContainer (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeDestroyContainer %d\n", PAJE_DestroyContainer);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Name string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeSetVariable (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeSetVariable %d\n", PAJE_SetVariable);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value double\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeAddVariable (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeAddVariable %d\n", PAJE_AddVariable);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value double\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeSubVariable (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeSubVariable %d\n", PAJE_SubVariable);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value double\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+
+static void TRACE_header_PajeSetState (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeSetState %d\n", PAJE_SetState);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajePushState (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajePushState %d\n", PAJE_PushState);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajePopState (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajePopState %d\n", PAJE_PopState);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeResetState (int basic)
+{
+  if (basic) return;
+
+  fprintf(tracing_file, "%%EventDef PajeResetState %d\n", PAJE_ResetState);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeStartLink (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeStartLink %d\n", PAJE_StartLink);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       SourceContainer string\n");
+  }else{
+    fprintf(tracing_file, "%%       StartContainer string\n");
+  }
+  fprintf(tracing_file, "%%       Key string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeEndLink (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeEndLink %d\n", PAJE_EndLink);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value string\n");
+  if (basic){
+    fprintf(tracing_file, "%%       DestContainer string\n");
+  }else{
+    fprintf(tracing_file, "%%       EndContainer string\n");
+  }
+  fprintf(tracing_file, "%%       Key string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+static void TRACE_header_PajeNewEvent (int basic)
+{
+  fprintf(tracing_file, "%%EventDef PajeNewEvent %d\n", PAJE_NewEvent);
+  fprintf(tracing_file, "%%       Time date\n");
+  fprintf(tracing_file, "%%       Type string\n");
+  fprintf(tracing_file, "%%       Container string\n");
+  fprintf(tracing_file, "%%       Value string\n");
+  fprintf(tracing_file, "%%EndEventDef\n");
+}
+
+void TRACE_header(int basic)
+{
+  XBT_DEBUG ("Define paje header");
+  TRACE_header_PajeDefineContainerType (basic);
+  TRACE_header_PajeDefineVariableType (basic);
+  TRACE_header_PajeDefineStateType (basic);
+  TRACE_header_PajeDefineEventType (basic);
+  TRACE_header_PajeDefineLinkType (basic);
+  TRACE_header_PajeDefineEntityValue (basic);
+  TRACE_header_PajeCreateContainer (basic);
+  TRACE_header_PajeDestroyContainer (basic);
+  TRACE_header_PajeSetVariable (basic);
+  TRACE_header_PajeAddVariable (basic);
+  TRACE_header_PajeSubVariable (basic);
+  TRACE_header_PajeSetState (basic);
+  TRACE_header_PajePushState (basic);
+  TRACE_header_PajePopState (basic);
+  TRACE_header_PajeResetState (basic);
+  TRACE_header_PajeStartLink (basic);
+  TRACE_header_PajeEndLink (basic);
+  TRACE_header_PajeNewEvent (basic);
+}
+
+#endif
+
+
index 0e0af37..7b5568d 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_trace, instr, "Paje tracing event system");
 
-typedef enum {
-  PAJE_DefineContainerType,
-  PAJE_DefineVariableType,
-  PAJE_DefineStateType,
-  PAJE_DefineEventType,
-  PAJE_DefineLinkType,
-  PAJE_DefineEntityValue,
-  PAJE_CreateContainer,
-  PAJE_DestroyContainer,
-  PAJE_SetVariable,
-  PAJE_AddVariable,
-  PAJE_SubVariable,
-  PAJE_SetState,
-  PAJE_PushState,
-  PAJE_PopState,
-  PAJE_ResetState,
-  PAJE_StartLink,
-  PAJE_EndLink,
-  PAJE_NewEvent
-} e_event_type;
-
 typedef struct paje_event *paje_event_t;
 typedef struct paje_event {
   double timestamp;
@@ -154,10 +133,39 @@ typedef struct s_newEvent {
   val_t value;
 }s_newEvent_t;
 
-static FILE *tracing_file = NULL;
+FILE *tracing_file = NULL;
 
 static xbt_dynar_t buffer = NULL;
 
+static void dump_comment (const char *comment)
+{
+  if (!strlen(comment)) return;
+  fprintf (tracing_file, "# %s\n", comment);
+}
+
+static void dump_comment_file (const char *filename)
+{
+  if (!strlen(filename)) return;
+  FILE *file = fopen (filename, "r");
+  if (!file){
+    THROWF (system_error, 1, "Comment file %s could not be opened for reading.", filename);
+  }
+  while (!feof(file)){
+    char c;
+    c = fgetc(file);
+    if (feof(file)) break;
+    fprintf (tracing_file, "# ");
+    while (c != '\n'){
+      fprintf (tracing_file, "%c", c);
+      c = fgetc(file);
+      if (feof(file)) break;
+    }
+    fprintf (tracing_file, "\n");
+  }
+  fclose(file);
+}
+
+
 void TRACE_paje_start(void)
 {
   char *filename = TRACE_get_filename();
@@ -168,8 +176,17 @@ void TRACE_paje_start(void)
 
   XBT_DEBUG("Filename %s is open for writing", filename);
 
+  /* output generator version */
+  fprintf (tracing_file, "#This file was generated using SimGrid-%d.%d.%d\n", SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR, SIMGRID_VERSION_PATCH);
+
+  /* output one line comment */
+  dump_comment (TRACE_get_comment());
+
+  /* output comment file */
+  dump_comment_file (TRACE_get_comment_file());
+
   /* output header */
-  TRACE_paje_create_header();
+  TRACE_header(TRACE_basic());
 
   buffer = xbt_dynar_new (sizeof(paje_event_t), NULL);
 }
@@ -212,138 +229,6 @@ void TRACE_paje_dump_buffer (int force)
   XBT_DEBUG("%s: ends", __FUNCTION__);
 }
 
-void TRACE_paje_create_header(void)
-{
-  XBT_DEBUG ("Define paje header");
-  fprintf(tracing_file, "\
-%%EventDef PajeDefineContainerType %d \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       Name string \n\
-%%EndEventDef \n\
-%%EventDef PajeDefineVariableType %d \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       Name string \n\
-%%       Color color \n\
-%%EndEventDef \n\
-%%EventDef PajeDefineStateType %d \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       Name string \n\
-%%EndEventDef \n\
-%%EventDef PajeDefineEventType %d \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       Name string \n\
-%%EndEventDef \n\
-%%EventDef PajeDefineLinkType %d \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       StartContainerType string \n\
-%%       EndContainerType string \n\
-%%       Name string \n\
-%%EndEventDef \n\
-%%EventDef PajeDefineEntityValue %d \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       Name string \n\
-%%       Color color \n\
-%%EndEventDef \n\
-%%EventDef PajeCreateContainer %d \n\
-%%       Time date \n\
-%%       Alias string \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Name string \n\
-%%EndEventDef \n\
-%%EventDef PajeDestroyContainer %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Name string \n\
-%%EndEventDef \n\
-%%EventDef PajeSetVariable %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value double \n\
-%%EndEventDef\n\
-%%EventDef PajeAddVariable %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value double \n\
-%%EndEventDef\n\
-%%EventDef PajeSubVariable %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value double \n\
-%%EndEventDef\n\
-%%EventDef PajeSetState %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value string \n\
-%%EndEventDef\n\
-%%EventDef PajePushState %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value string \n\
-%%EndEventDef\n\
-%%EventDef PajePopState %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%EndEventDef\n\
-%%EventDef PajeResetState %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%EndEventDef\n\
-%%EventDef PajeStartLink %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value string \n\
-%%       StartContainer string \n\
-%%       Key string \n\
-%%EndEventDef\n\
-%%EventDef PajeEndLink %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value string \n\
-%%       EndContainer string \n\
-%%       Key string \n\
-%%EndEventDef\n\
-%%EventDef PajeNewEvent %d \n\
-%%       Time date \n\
-%%       Type string \n\
-%%       Container string \n\
-%%       Value string \n\
-%%EndEventDef\n",
-  PAJE_DefineContainerType,
-  PAJE_DefineVariableType,
-  PAJE_DefineStateType,
-  PAJE_DefineEventType,
-  PAJE_DefineLinkType,
-  PAJE_DefineEntityValue,
-  PAJE_CreateContainer,
-  PAJE_DestroyContainer,
-  PAJE_SetVariable,
-  PAJE_AddVariable,
-  PAJE_SubVariable,
-  PAJE_SetState,
-  PAJE_PushState,
-  PAJE_PopState,
-  PAJE_ResetState,
-  PAJE_StartLink,
-  PAJE_EndLink,
-  PAJE_NewEvent);
-}
-
 /* internal do the instrumentation module */
 static void insert_into_buffer (paje_event_t tbi)
 {
index fe73bf0..fa969a3 100644 (file)
 #include "simix/smx_private.h"
 #include "xbt/graph_private.h"
 
+typedef enum {
+  PAJE_DefineContainerType,
+  PAJE_DefineVariableType,
+  PAJE_DefineStateType,
+  PAJE_DefineEventType,
+  PAJE_DefineLinkType,
+  PAJE_DefineEntityValue,
+  PAJE_CreateContainer,
+  PAJE_DestroyContainer,
+  PAJE_SetVariable,
+  PAJE_AddVariable,
+  PAJE_SubVariable,
+  PAJE_SetState,
+  PAJE_PushState,
+  PAJE_PopState,
+  PAJE_ResetState,
+  PAJE_StartLink,
+  PAJE_EndLink,
+  PAJE_NewEvent
+} e_event_type;
+
 typedef enum {
   TYPE_VARIABLE,
   TYPE_LINK,
@@ -81,8 +102,10 @@ extern xbt_dict_t user_vm_variables;
 extern xbt_dict_t user_link_variables;
 extern double TRACE_last_timestamp_to_dump;
 
+/* instr_paje_header.c */
+void TRACE_header(int basic);
+
 /* from paje.c */
-void TRACE_paje_create_header(void);
 void TRACE_paje_start(void);
 void TRACE_paje_end(void);
 void TRACE_paje_dump_buffer (int force);
@@ -122,6 +145,7 @@ char *instr_process_id_2 (const char *process_name, int process_pid, char *str,
 void TRACE_msg_process_change_host(msg_process_t process, msg_host_t old_host,
                                    msg_host_t new_host);
 void TRACE_msg_process_create (const char *process_name, int process_pid, msg_host_t host);
+void TRACE_msg_process_destroy (const char *process_name, int process_pid, msg_host_t host);
 void TRACE_msg_process_kill(msg_process_t process);
 void TRACE_msg_process_suspend(msg_process_t process);
 void TRACE_msg_process_resume(msg_process_t process);
@@ -162,6 +186,9 @@ void TRACE_smpi_init(int rank);
 void TRACE_smpi_finalize(int rank);
 void TRACE_smpi_collective_in(int rank, int root, const char *operation);
 void TRACE_smpi_collective_out(int rank, int root, const char *operation);
+void TRACE_smpi_computing_init(int rank);
+void TRACE_smpi_computing_out(int rank);
+void TRACE_smpi_computing_in(int rank);
 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation);
 void TRACE_smpi_ptp_out(int rank, int src, int dst, const char *operation);
 void TRACE_smpi_send(int rank, int src, int dst);
@@ -176,12 +203,16 @@ int TRACE_platform(void);
 int TRACE_is_configured(void);
 int TRACE_smpi_is_enabled(void);
 int TRACE_smpi_is_grouped(void);
+int TRACE_smpi_is_computing(void);
 int TRACE_categorized (void);
 int TRACE_uncategorized (void);
 int TRACE_msg_process_is_enabled(void);
 int TRACE_buffer (void);
 int TRACE_onelink_only (void);
 int TRACE_disable_destroy (void);
+int TRACE_basic (void);
+char *TRACE_get_comment (void);
+char *TRACE_get_comment_file (void);
 char *TRACE_get_filename(void);
 char *TRACE_get_triva_uncat_conf (void);
 char *TRACE_get_triva_cat_conf (void);
@@ -193,6 +224,8 @@ void TRACE_generate_triva_uncat_conf (void);
 void TRACE_generate_triva_cat_conf (void);
 void TRACE_generate_viva_uncat_conf (void);
 void TRACE_generate_viva_cat_conf (void);
+void instr_pause_tracing (void);
+void instr_resume_tracing (void);
 
 /* from resource_utilization.c */
 void TRACE_surf_host_set_utilization(const char *resource,
index d8649af..23a6553 100644 (file)
@@ -71,8 +71,10 @@ static container_t lowestCommonAncestor (container_t a1, container_t a2)
 static void linkContainers (container_t src, container_t dst, xbt_dict_t filter)
 {
   //ignore loopback
-  if (strcmp (src->name, "__loopback__") == 0 || strcmp (dst->name, "__loopback__") == 0)
+  if (strcmp (src->name, "__loopback__") == 0 || strcmp (dst->name, "__loopback__") == 0){
+    XBT_DEBUG ("  linkContainers: ignoring loopback link");
     return;
+  }
 
   //find common father
   container_t father = lowestCommonAncestor (src, dst);
@@ -85,8 +87,14 @@ static void linkContainers (container_t src, container_t dst, xbt_dict_t filter)
     char aux1[INSTR_DEFAULT_STR_SIZE], aux2[INSTR_DEFAULT_STR_SIZE];
     snprintf (aux1, INSTR_DEFAULT_STR_SIZE, "%s%s", src->name, dst->name);
     snprintf (aux2, INSTR_DEFAULT_STR_SIZE, "%s%s", dst->name, src->name);
-    if (xbt_dict_get_or_null (filter, aux1)) return;
-    if (xbt_dict_get_or_null (filter, aux2)) return;
+    if (xbt_dict_get_or_null (filter, aux1)){
+      XBT_DEBUG ("  linkContainers: already registered %s <-> %s (1)", src->name, dst->name);
+      return;
+    }
+    if (xbt_dict_get_or_null (filter, aux2)){
+      XBT_DEBUG ("  linkContainers: already registered %s <-> %s (2)", dst->name, src->name);
+      return;
+    }
 
     //ok, not found, register it
     xbt_dict_set (filter, aux1, xbt_strdup ("1"), NULL);
@@ -113,10 +121,25 @@ static void linkContainers (container_t src, container_t dst, xbt_dict_t filter)
   snprintf (key, INSTR_DEFAULT_STR_SIZE, "%lld", counter++);
   new_pajeStartLink(SIMIX_get_clock(), father, link_type, src, "G", key);
   new_pajeEndLink(SIMIX_get_clock(), father, link_type, dst, "G", key);
+
+  XBT_DEBUG ("  linkContainers %s <-> %s", src->name, dst->name);
+}
+
+static int graph_extraction_filter_out (container_t c1, container_t c2)
+{
+  if (c1->kind == INSTR_LINK ||
+      c1->kind == INSTR_SMPI ||
+      c1->kind == INSTR_MSG_PROCESS ||
+      c1->kind == INSTR_MSG_TASK ||
+      (c2 && strcmp (c1->name, c2->name) == 0))
+    return 1;
+  else
+    return 0;
 }
 
 static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t filter)
 {
+  XBT_DEBUG ("Graph extraction for routing_component = %s", rc->name);
   if (!xbt_dict_is_empty(rc->routing_sons)){
     xbt_dict_cursor_t cursor = NULL;
     AS_t rc_son;
@@ -143,8 +166,13 @@ static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t
       //if child1 is not child2
       if (strcmp (child1_name, child2_name) == 0) continue;
 
+      if (graph_extraction_filter_out (child1, NULL)) continue;
+    xbt_dict_foreach(container->children, cursor2, child2_name, child2) {
+      if (graph_extraction_filter_out (child2, child1)) continue;
+      XBT_DEBUG ("get_route from %s to %s", child1_name, child2_name);
+
       //get the route
-      route_t route = xbt_new0(s_route_t,1);
+      sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1);
       route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
       rc->get_route_and_latency(rc, child1->net_elm, child2->net_elm,
                                 route, NULL);
@@ -160,20 +188,21 @@ static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t
       unsigned int cpt;
       void *link;
       container_t current, previous;
-      if (route->src_gateway){
-        previous = PJ_container_get(route->src_gateway->name);
+      if (route->gw_src){
+        previous = PJ_container_get(route->gw_src->name);
       }else{
         previous = child1;
       }
 
       xbt_dynar_foreach (route->link_list, cpt, link) {
+        //FIXME (TODO): Should have a cleaner way to get the link name
         char *link_name = ((link_CM02_t)link)->lmm_resource.generic_resource.name;
         current = PJ_container_get(link_name);
         linkContainers(previous, current, filter);
         previous = current;
       }
-      if (route->dst_gateway){
-        current = PJ_container_get(route->dst_gateway->name);
+      if (route->gw_dst){
+        current = PJ_container_get(route->gw_dst->name);
       }else{
         current = child2;
       }
@@ -186,8 +215,10 @@ static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t
 /*
  * Callbacks
  */
-static void instr_routing_parse_start_AS (const char*id,int routing)
+static void instr_routing_parse_start_AS (sg_platf_AS_cbarg_t AS)
 {
+  const char*id = AS->id;
+
   if (PJ_container_get_root() == NULL){
     PJ_container_alloc ();
     PJ_type_alloc();
@@ -345,7 +376,9 @@ static void instr_routing_parse_end_platform ()
   xbt_dynar_free(&currentContainer);
   currentContainer = NULL;
   xbt_dict_t filter = xbt_dict_new_homogeneous(xbt_free);
+  XBT_DEBUG ("Starting graph extraction.");
   recursiveGraphExtraction (routing_platf->root, PJ_container_get_root(), filter);
+  XBT_DEBUG ("Graph extraction finished.");
   xbt_dict_free(&filter);
   platform_created = 1;
   TRACE_paje_dump_buffer(1);
@@ -526,7 +559,7 @@ static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xb
       if (strcmp (child1_name, child2_name) == 0) continue;
 
       //get the route
-      route_t route = xbt_new0(s_route_t,1);
+      sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1);
       route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
       rc->get_route_and_latency(rc, child1->net_elm, child2->net_elm,
                                 route, NULL);
@@ -539,8 +572,8 @@ static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xb
       unsigned int cpt;
       void *link;
       xbt_node_t current, previous;
-      if (route->src_gateway){
-        previous = new_xbt_graph_node(graph, route->src_gateway->name, nodes);
+      if (route->gw_src){
+        previous = new_xbt_graph_node(graph, route->gw_src->name, nodes);
       }else{
         previous = new_xbt_graph_node(graph, child1_name, nodes);
       }
@@ -552,8 +585,8 @@ static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xb
         //previous -> current
         previous = current;
       }
-      if (route->dst_gateway){
-        current = new_xbt_graph_node(graph, route->dst_gateway->name, nodes);
+      if (route->gw_dst){
+        current = new_xbt_graph_node(graph, route->gw_dst->name, nodes);
       }else{
         current = new_xbt_graph_node(graph, child2_name, nodes);
       }
index 060f0a9..65086bd 100644 (file)
@@ -16,29 +16,30 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI");
 static xbt_dict_t keys;
 
 static const char *smpi_colors[] ={
-    "recv",     "255 000 000",
-    "irecv",    "255 135 135",
-    "send",     "000 000 255",
-    "isend",    "135 135 255",
-    "sendrecv", "000 255 255",
-    "wait",     "255 255 000",
-    "waitall",  "200 200 000",
-    "waitany",  "200 200 150",
-
-    "allgather",     "255 000 000",
-    "allgatherv",    "255 135 135",
-    "allreduce",     "255 000 255",
-    "alltoall",      "135 000 255",
-    "alltoallv",     "200 135 255",
-    "barrier",       "000 200 200",
-    "bcast",         "000 200 100",
-    "gather",        "255 255 000",
-    "gatherv",       "255 255 135",
-    "reduce",        "000 255 000",
-    "reducescatter", "135 255 135",
-    "scan",          "255 150 060",
-    "scatterv",      "135 000 135",
-    "scatter",       "255 190 140",
+    "recv",     "1 0 0",
+    "irecv",    "1 0.52 0.52",
+    "send",     "0 0 1",
+    "isend",    "0.52 0.52 1",
+    "sendrecv", "0 1 1",
+    "wait",     "1 1 0",
+    "waitall",  "0.78 0.78 0",
+    "waitany",  "0.78 0.78 0.58",
+
+    "allgather",     "1 0 0",
+    "allgatherv",    "1 0.52 0.52",
+    "allreduce",     "1 0 1",
+    "alltoall",      "0.52 0 1",
+    "alltoallv",     "0.78 0.52 1",
+    "barrier",       "0 0.78 0.78",
+    "bcast",         "0 0.78 0.39",
+    "gather",        "1 1 0",
+    "gatherv",       "1 1 0.52",
+    "reduce",        "0 1 0",
+    "reducescatter", "0.52 1 0.52",
+    "scan",          "1 0.58 0.23",
+    "scatterv",      "0.52 0 0.52",
+    "scatter",       "1 0.74 0.54",
+    "computing",     "0 1 1",
 
     NULL, NULL,
 };
@@ -86,7 +87,7 @@ static char *TRACE_smpi_put_key(int src, int dst, char *key, int n)
   }
   //generate the key
   static unsigned long long counter = 0;
-  snprintf(key, n, "%d%d%llu", src, dst, counter++);
+  snprintf(key, n, "%d_%d_%llu", src, dst, counter++);
 
   //push it
   char *a = (char*)xbt_strdup(key);
@@ -200,6 +201,45 @@ void TRACE_smpi_collective_out(int rank, int root, const char *operation)
   new_pajePopState (SIMIX_get_clock(), container, type);
 }
 
+void TRACE_smpi_computing_init(int rank)
+{
+ //first use, initialize the color in the trace
+ //TODO : check with lucas and Pierre how to generalize this approach
+  //to avoid unnecessary access to the color array
+  if (!TRACE_smpi_is_enabled() || !TRACE_smpi_is_computing()) return;
+
+  char str[INSTR_DEFAULT_STR_SIZE];
+  smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
+  container_t container = PJ_container_get (str);
+  type_t type = PJ_type_get ("MPI_STATE", container->type);
+  const char *color = instr_find_color ("computing");
+  val_t value = PJ_value_get_or_new ("computing", color, type);
+  new_pajePushState (SIMIX_get_clock(), container, type, value);
+}
+
+void TRACE_smpi_computing_in(int rank)
+{
+  //do not forget to set the color first, otherwise this will explode
+  if (!TRACE_smpi_is_enabled()|| !TRACE_smpi_is_computing()) return;
+
+  char str[INSTR_DEFAULT_STR_SIZE];
+  smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
+  container_t container = PJ_container_get (str);
+  type_t type = PJ_type_get ("MPI_STATE", container->type);
+  val_t value = PJ_value_get_or_new ("computing", NULL, type);
+  new_pajePushState (SIMIX_get_clock(), container, type, value);
+}
+
+void TRACE_smpi_computing_out(int rank)
+{
+  if (!TRACE_smpi_is_enabled()|| !TRACE_smpi_is_computing()) return;
+  char str[INSTR_DEFAULT_STR_SIZE];
+  smpi_container(rank, str, INSTR_DEFAULT_STR_SIZE);
+  container_t container = PJ_container_get (str);
+  type_t type = PJ_type_get ("MPI_STATE", container->type);
+  new_pajePopState (SIMIX_get_clock(), container, type);
+}
+
 void TRACE_smpi_ptp_in(int rank, int src, int dst, const char *operation)
 {
   if (!TRACE_smpi_is_enabled()) return;
@@ -231,6 +271,7 @@ void TRACE_smpi_send(int rank, int src, int dst)
   if (!TRACE_smpi_is_enabled()) return;
 
   char key[INSTR_DEFAULT_STR_SIZE];
+  bzero (key, INSTR_DEFAULT_STR_SIZE);
   TRACE_smpi_put_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
 
   char str[INSTR_DEFAULT_STR_SIZE];
@@ -246,6 +287,7 @@ void TRACE_smpi_recv(int rank, int src, int dst)
   if (!TRACE_smpi_is_enabled()) return;
 
   char key[INSTR_DEFAULT_STR_SIZE];
+  bzero (key, INSTR_DEFAULT_STR_SIZE);
   TRACE_smpi_get_key(src, dst, key, INSTR_DEFAULT_STR_SIZE);
 
   char str[INSTR_DEFAULT_STR_SIZE];
index 1de381c..9faf3a8 100644 (file)
@@ -24,33 +24,20 @@ void TRACE_surf_release(void)
 
 void TRACE_surf_host_set_power(double date, const char *resource, double power)
 {
-  if (!TRACE_is_enabled())
-    return;
-
-  container_t container = PJ_container_get(resource);
-  type_t type = PJ_type_get ("power", container->type);
-  new_pajeSetVariable(date, container, type, power);
+  if (TRACE_categorized() || TRACE_uncategorized() || TRACE_platform()) {
+    container_t container = PJ_container_get(resource);
+    type_t type = PJ_type_get ("power", container->type);
+    new_pajeSetVariable(date, container, type, power);
+  }
 }
 
 void TRACE_surf_link_set_bandwidth(double date, const char *resource, double bandwidth)
 {
-  if (!TRACE_is_enabled())
-    return;
-
-  container_t container = PJ_container_get(resource);
-  type_t type = PJ_type_get ("bandwidth", container->type);
-  new_pajeSetVariable(date, container, type, bandwidth);
-}
-
-//FIXME: this function is not used (latency availability traces support exists in surf network models?)
-void TRACE_surf_link_set_latency(double date, const char *resource, double latency)
-{
-  if (!TRACE_is_enabled())
-    return;
-
-  container_t container = PJ_container_get(resource);
-  type_t type = PJ_type_get ("latency", container->type);
-  new_pajeSetVariable(date, container, type, latency);
+  if (TRACE_categorized() || TRACE_uncategorized() || TRACE_platform()) {
+    container_t container = PJ_container_get(resource);
+    type_t type = PJ_type_get ("bandwidth", container->type);
+    new_pajeSetVariable(date, container, type, bandwidth);
+  }
 }
 
 /* to trace gtnets */
index 60f74e5..16c924d 100644 (file)
@@ -7,16 +7,22 @@
 #include "mc_private.h"
 #include "xbt/module.h"
 
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkpoint, mc,
                                 "Logging specific to mc_checkpoint");
 
+void *start_text_libsimgrid;
+void *start_plt, *end_plt;
+char *libsimgrid_path;
+
 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size);
 static void MC_region_restore(mc_mem_region_t reg);
 static void MC_region_destroy(mc_mem_region_t reg);
 
 static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size);
 
+static int data_program_region_compare(void *d1, void *d2, size_t size);
+static int data_libsimgrid_region_compare(void *d1, void *d2, size_t size);
+
 static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
 {
   mc_mem_region_t new_reg = xbt_new0(s_mc_mem_region_t, 1);
@@ -24,8 +30,9 @@ static mc_mem_region_t MC_region_new(int type, void *start_addr, size_t size)
   new_reg->start_addr = start_addr;
   new_reg->size = size;
   new_reg->data = xbt_malloc0(size);
-  XBT_DEBUG("New reg data %p, start_addr %p, size %zu", new_reg->data, start_addr, size);
   memcpy(new_reg->data, start_addr, size);
+
+  XBT_DEBUG("New region : type : %d, data : %p, size : %zu", type, new_reg->data, size);
   
   return new_reg;
 }
@@ -35,7 +42,6 @@ static void MC_region_restore(mc_mem_region_t reg)
   /*FIXME: check if start_addr is still mapped, if it is not, then map it
     before copying the data */
  
-  XBT_DEBUG("Memcpy : dest %p, src %p, size %zu", reg->start_addr, reg->data, reg->size);
   memcpy(reg->start_addr, reg->data, reg->size);
  
   return;
@@ -49,17 +55,6 @@ static void MC_region_destroy(mc_mem_region_t reg)
 
 static void MC_snapshot_add_region(mc_snapshot_t snapshot, int type, void *start_addr, size_t size)
 {
-  switch(type){
-  case 0 : 
-    XBT_DEBUG("New region heap (%zu)", size);
-    break;
-  case 1 : 
-    XBT_DEBUG("New region libsimgrid (%zu)", size);
-    break;
-  case 2 : 
-    XBT_DEBUG("New region program data (%zu)", size);
-    break;
-  }
   mc_mem_region_t new_reg = MC_region_new(type, start_addr, size);
   snapshot->regions = xbt_realloc(snapshot->regions, (snapshot->num_reg + 1) * sizeof(mc_mem_region_t));
   snapshot->regions[snapshot->num_reg] = new_reg;
@@ -90,7 +85,7 @@ void MC_take_snapshot(mc_snapshot_t snapshot)
     i++;
   }
 
-  /* FIXME: free the memory map */
+  free_memory_map(maps);
 }
 
 void MC_take_snapshot_liveness(mc_snapshot_t snapshot)
@@ -98,29 +93,41 @@ void MC_take_snapshot_liveness(mc_snapshot_t snapshot)
   unsigned int i = 0;
   s_map_region_t reg;
   memory_map_t maps = get_memory_map();
+  int nb_reg = 0;
 
   /* Save the std heap and the writable mapped pages of libsimgrid */
-  while (i < maps->mapsize) {
+  while (i < maps->mapsize && nb_reg < 3) {
     reg = maps->regions[i];
     if ((reg.prot & PROT_WRITE)){
       if (maps->regions[i].pathname == NULL){
         if (reg.start_addr == std_heap){ // only save the std heap (and not the raw one)
           MC_snapshot_add_region(snapshot, 0, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
+          nb_reg++;
         }
       } else {
         if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
           MC_snapshot_add_region(snapshot, 1, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
+          nb_reg++;
         } else {
           if (!memcmp(basename(maps->regions[i].pathname), basename(xbt_binary_name), strlen(basename(xbt_binary_name)))){
             MC_snapshot_add_region(snapshot, 2, reg.start_addr, (char*)reg.end_addr - (char*)reg.start_addr);
-          } 
+            nb_reg++;
+          }
+        }
+      }
+    }else if ((reg.prot & PROT_READ)){
+      if (maps->regions[i].pathname != NULL){
+        if (!memcmp(basename(maps->regions[i].pathname), "libsimgrid", 10)){
+          start_text_libsimgrid = reg.start_addr;
+          libsimgrid_path = strdup(maps->regions[i].pathname);
         }
       }
     }
     i++;
   }
+  
+  free_memory_map(maps);
 
-  /* FIXME: free the memory map */
 }
 
 void MC_restore_snapshot(mc_snapshot_t snapshot)
@@ -128,18 +135,6 @@ void MC_restore_snapshot(mc_snapshot_t snapshot)
   unsigned int i;
   for(i=0; i < snapshot->num_reg; i++){
     MC_region_restore(snapshot->regions[i]);
-    switch(snapshot->regions[i]->type){
-    case 0 : 
-      XBT_DEBUG("heap restored");
-      break;
-    case 1:
-      XBT_DEBUG("libsimgrid (data) restored");
-      break;
-    case 2:
-      XBT_DEBUG("data program restored");
-      break;
-    }
-
   }
 
 }
@@ -153,108 +148,178 @@ void MC_free_snapshot(mc_snapshot_t snapshot)
   xbt_free(snapshot);
 }
 
-static int data_program_region_compare(void *d1, void *d2, size_t size);
-static int data_libsimgrid_region_compare(void *d1, void *d2, size_t size);
-
 static int data_program_region_compare(void *d1, void *d2, size_t size){
   int distance = 0;
-  int i;
+  size_t i = 0;
   
   for(i=0; i<size; i++){
     if(memcmp(((char *)d1) + i, ((char *)d2) + i, 1) != 0){
-      fprintf(stderr,"Different byte (offset=%d) (%p - %p) in data program region\n", i, (char *)d1 + i, (char *)d2 + i);
+      XBT_DEBUG("Different byte (offset=%zu) (%p - %p) in data program region", i, (char *)d1 + i, (char *)d2 + i);
       distance++;
     }
   }
   
-  fprintf(stderr, "Hamming distance between data program regions : %d\n", distance);
+  XBT_DEBUG("Hamming distance between data program regions : %d", distance);
 
   return distance;
 }
 
-int data_libsimgrid_region_compare(void *d1, void *d2, size_t size){
+static int data_libsimgrid_region_compare(void *d1, void *d2, size_t size){
   int distance = 0;
-  int i;
-  
+  size_t i = 0;
+  int pointer_align;
+  void *addr_pointed1 = NULL, *addr_pointed2 = NULL;
+
   for(i=0; i<size; i++){
     if(memcmp(((char *)d1) + i, ((char *)d2) + i, 1) != 0){
-      fprintf(stderr, "Different byte (offset=%d) (%p - %p) in data libsimgrid region\n", i, (char *)d1 + i, (char *)d2 + i);
-      distance++;
+      pointer_align = (i / sizeof(void*)) * sizeof(void*);
+      addr_pointed1 = *((void **)((char *)d1 + pointer_align));
+      addr_pointed2 = *((void **)((char *)d2 + pointer_align));
+      if((addr_pointed1 > start_plt && addr_pointed1 < end_plt) || (addr_pointed2 > start_plt && addr_pointed2 < end_plt)){
+        continue;
+      }else{
+        XBT_DEBUG("Different byte (offset=%zu) (%p - %p) in data libsimgrid region", i, (char *)d1 + i, (char *)d2 + i);
+        XBT_DEBUG("Addresses pointed : %p - %p\n", addr_pointed1, addr_pointed2);
+        distance++;
+      }
     }
   }
   
-  fprintf(stderr, "Hamming distance between data libsimgrid regions : %d\n", distance);
+  XBT_DEBUG("Hamming distance between data libsimgrid regions : %d", distance); fflush(NULL);
   
   return distance;
 }
 
 int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2){
 
+  int errors = 0, i;
   
   if(s1->num_reg != s2->num_reg){
-    XBT_INFO("Different num_reg (s1 = %u, s2 = %u)", s1->num_reg, s2->num_reg);
+    XBT_DEBUG("Different num_reg (s1 = %u, s2 = %u)", s1->num_reg, s2->num_reg);
     return 1;
   }
 
-  int i;
-  int errors = 0;
-
   for(i=0 ; i< s1->num_reg ; i++){
-
+    
     if(s1->regions[i]->type != s2->regions[i]->type){
       XBT_INFO("Different type of region");
       errors++;
     }
-
+    
     switch(s1->regions[i]->type){
-    case 0:
+    case 0 :
+      /* Compare heapregion */
       if(s1->regions[i]->size != s2->regions[i]->size){
-        XBT_INFO("Different size of heap (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
+        XBT_DEBUG("Different size of heap (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
         errors++;
       }
       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
-        XBT_INFO("Different start addr of heap (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
+        XBT_DEBUG("Different start addr of heap (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
         errors++;
       }
-      if(mmalloc_compare_heap(s1->regions[i]->data, s2->regions[i]->data)){
-        XBT_INFO("Different heap (mmalloc_compare)");
+      if(mmalloc_compare_heap((xbt_mheap_t)s1->regions[i]->data, (xbt_mheap_t)s2->regions[i]->data)){
+        XBT_DEBUG("Different heap (mmalloc_compare)");
         errors++; 
       }
       break;
     case 1 :
+      /* Compare data libsimgrid region */
       if(s1->regions[i]->size != s2->regions[i]->size){
-        XBT_INFO("Different size of libsimgrid (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
+        XBT_DEBUG("Different size of libsimgrid (data) (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
         errors++;
       }
       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
-        XBT_INFO("Different start addr of libsimgrid (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
+        XBT_DEBUG("Different start addr of libsimgrid (data) (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
         errors++;
       }
       if(data_libsimgrid_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
-        XBT_INFO("Different memcmp for data in libsimgrid");
+        XBT_DEBUG("Different memcmp for data in libsimgrid");
         errors++;
       }
       break;
+
     case 2 :
+       /* Compare data program region */
       if(s1->regions[i]->size != s2->regions[i]->size){
-        XBT_INFO("Different size of data program (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
-        errors++;
+        XBT_DEBUG("Different size of data program (s1 = %zu, s2 = %zu)", s1->regions[i]->size, s2->regions[i]->size);
+        //errors++;
+        return 1;
       }
       if(s1->regions[i]->start_addr != s2->regions[i]->start_addr){
-        XBT_INFO("Different start addr of data program (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
-        errors++;
+        XBT_DEBUG("Different start addr of data program (s1 = %p, s2 = %p)", s1->regions[i]->start_addr, s2->regions[i]->start_addr);
+        //errors++;
+        return 1;
       }
       if(data_program_region_compare(s1->regions[i]->data, s2->regions[i]->data, s1->regions[i]->size) != 0){
-        XBT_INFO("Different memcmp for data in program");
-        errors++;
+        XBT_DEBUG("Different memcmp for data in program");
+        //errors++;
+        return 1;
       }
       break;
-    default:
-      break;
     }
+
   }
 
-  return (errors > 0);
+
+  return errors > 0;
   
 }
 
+void get_plt_section(){
+
+  FILE *fp;
+  char *line = NULL;            /* Temporal storage for each line that is readed */
+  ssize_t read;                 /* Number of bytes readed */
+  size_t n = 0;                 /* Amount of bytes to read by getline */
+
+  char *lfields[7];
+  int i, plt_not_found = 1;
+  unsigned long int size, offset;
+
+  char *command = bprintf( "objdump --section-headers %s", libsimgrid_path);
+
+  fp = popen(command, "r");
+
+  if(fp == NULL)
+    perror("popen failed");
+
+  while ((read = getline(&line, &n, fp)) != -1 && plt_not_found == 1) {
+
+    if(n == 0)
+      continue;
+
+     /* Wipeout the new line character */
+    line[read - 1] = '\0';
+
+    lfields[0] = strtok(line, " ");
+
+    if(lfields[0] == NULL)
+      continue;
+
+    if(strcmp(lfields[0], "Sections:") == 0 || strcmp(lfields[0], "Idx") == 0 || strcmp(lfields[0], "libsimgrid.so:") == 0)
+      continue;
+
+    for (i = 1; i < 7 && lfields[i - 1] != NULL; i++) {
+      lfields[i] = strtok(NULL, " ");
+    }
+
+    if(i>=5){
+      if(strcmp(lfields[1], ".plt") == 0){
+        size = strtoul(lfields[2], NULL, 16);
+        offset = strtoul(lfields[4], NULL, 16);
+        start_plt = (char *)start_text_libsimgrid + offset;
+        end_plt = (char *)start_plt + size;
+        plt_not_found = 0;
+      }
+    }
+    
+    
+  }
+
+  free(command);
+  free(line);
+  pclose(fp);
+
+}
+
index 461f6c0..fa16d65 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "../surf/surf_private.h"
 #include "../simix/smx_private.h"
+#include "../xbt/mmalloc/mmprivate.h"
 #include "xbt/fifo.h"
 #include "mc_private.h"
 #include "xbt/automaton.h"
@@ -72,6 +73,9 @@ mc_stats_pair_t mc_stats_pair = NULL;
 xbt_fifo_t mc_stack_liveness = NULL;
 mc_snapshot_t initial_snapshot_liveness = NULL;
 int compare;
+xbt_dynar_t mc_binary_local_variables = NULL;
+
+extern xbt_dynar_t mmalloc_ignore;
 
 xbt_automaton_t _mc_property_automaton = NULL;
 
@@ -161,6 +165,11 @@ void MC_modelcheck_liveness(){
   
   mc_time = xbt_new0(double, simix_process_maxpid);
 
+  /* mc_time refers to clock for each process -> ignore it for heap comparison */
+  int i;
+  for(i = 0; i<simix_process_maxpid; i++)
+    MC_ignore(&(mc_time[i]), sizeof(double));
+  
   compare = 0;
 
   /* Initialize the data structures that must be persistent across every
@@ -168,6 +177,8 @@ void MC_modelcheck_liveness(){
 
   MC_SET_RAW_MEM;
 
+  mc_binary_local_variables = xbt_dynar_new(sizeof(dw_frame_t), NULL);
+
   /* Initialize statistics */
   mc_stats_pair = xbt_new0(s_mc_stats_pair_t, 1);
 
@@ -178,6 +189,8 @@ void MC_modelcheck_liveness(){
 
   MC_UNSET_RAW_MEM;
 
+  /* Get local variables in binary for state equality detection */
+  MC_get_binary_local_variables();
 
   MC_ddfs_init();
 
@@ -593,37 +606,6 @@ double MC_process_clock_get(smx_process_t process)
     return 0;
 }
 
-void MC_diff(void){
-
-  mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
-  MC_take_snapshot_liveness(sn);
-
-  int i;
-
-  XBT_INFO("Number of regions : %u", sn->num_reg);
-
-  for(i=0; i<sn->num_reg; i++){
-    
-    switch(sn->regions[i]->type){
-    case 0: /* heap */
-      XBT_INFO("Size of heap : %zu", sn->regions[i]->size);
-      break;
-    case 1 : /* libsimgrid */
-      XBT_INFO("Size of libsimgrid : %zu", sn->regions[i]->size);
-      break;
-    case 2 : /* data program */
-      XBT_INFO("Size of data program : %zu", sn->regions[i]->size);
-      break;
-    case 3 : /* stack */
-      XBT_INFO("Size of stack : %zu", sn->regions[i]->size);
-      XBT_INFO("Start addr of stack : %p", sn->regions[i]->start_addr);
-      break;
-    }
-
-  }
-
-}
-
 void MC_automaton_load(const char *file){
 
   raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
@@ -663,3 +645,573 @@ void MC_automaton_new_propositional_symbol(const char* id, void* fct) {
     MC_UNSET_RAW_MEM;
   
 }
+
+/************ MC_ignore ***********/ 
+
+void MC_ignore_init(){
+  MC_SET_RAW_MEM;
+  mmalloc_ignore = xbt_dynar_new(sizeof(mc_ignore_region_t), NULL);
+  MC_UNSET_RAW_MEM;
+}
+
+void MC_ignore(void *address, size_t size){
+
+  MC_SET_RAW_MEM;
+
+  mc_ignore_region_t region = NULL;
+  region = xbt_new0(s_mc_ignore_region_t, 1);
+  region->address = address;
+  region->size = size;
+  region->block = ((char*)address - (char*)((xbt_mheap_t)std_heap)->heapbase) / BLOCKSIZE + 1;
+
+  if(((xbt_mheap_t)std_heap)->heapinfo[region->block].type == 0){
+    region->fragment = -1;
+  }else{
+    region->fragment = ((uintptr_t) (ADDR2UINT (address) % (BLOCKSIZE))) >> ((xbt_mheap_t)std_heap)->heapinfo[region->block].type;
+  }
+
+  unsigned int cursor = 0;
+  mc_ignore_region_t current_region;
+  xbt_dynar_foreach(mmalloc_ignore, cursor, current_region){
+    if(current_region->address > address)
+      break;
+  }
+
+  xbt_dynar_insert_at(mmalloc_ignore, cursor, &region);
+
+  MC_UNSET_RAW_MEM;
+}
+
+/************ DWARF ***********/
+
+static e_dw_location_type get_location(char *expr, dw_location_t entry);
+
+void MC_get_binary_local_variables(){
+
+  char *command = bprintf("dwarfdump -i %s", xbt_binary_name); 
+  
+  FILE* fp = popen(command, "r");
+
+  if(fp == NULL)
+    perror("popen failed");
+
+  char *line = NULL, *tmp_line = NULL, *tmp_location = NULL, *frame_name = NULL;
+  ssize_t read;
+  size_t n = 0;
+  int valid_variable = 1, valid_frame = 1;
+  char *node_type = NULL, *location_type = NULL, *variable_name = NULL, *lowpc = NULL, *highpc = NULL;
+  xbt_dynar_t split = NULL;
+
+  read = getline(&line, &n, fp);
+
+  while (read != -1) {
+
+    if(n == 0)
+      continue;
+
+    /* Wipeout the new line character */
+    line[read - 1] = '\0';
+    
+    if(line[0] == '<'){
+
+      /* Get node type */
+      strtok(line, " ");
+      strtok(NULL, " ");
+      node_type = strtok(NULL, " ");
+
+      if(strcmp(node_type, "DW_TAG_subprogram") == 0){ /* New frame */
+
+        read = getline(&line, &n, fp);
+
+        while(read != -1 && line[0] != '<'){
+
+          if(n == 0)
+            continue;
+
+          node_type = strtok(line, " ");
+
+          if(node_type != NULL && strcmp(node_type, "DW_AT_name") == 0){
+
+            frame_name = strdup(strtok(NULL, " "));
+            read = getline(&line, &n, fp);
+
+          }else if(node_type != NULL && strcmp(node_type, "DW_AT_frame_base") == 0){
+
+            if(valid_frame == 1){
+
+              dw_frame_t frame = xbt_new0(s_dw_frame_t, 1);
+              frame->name = strdup(frame_name);
+              frame->variables = xbt_dynar_new(sizeof(dw_local_variable_t), NULL);
+              frame->location = xbt_new0(s_dw_location_t, 1);
+            
+              location_type = strtok(NULL, " ");
+
+              if(strcmp(location_type, "<loclist") == 0){
+
+                frame->location->type = e_dw_loclist;
+                frame->location->location.loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL);
+             
+                read = getline(&line, &n, fp);
+                xbt_str_ltrim(line, NULL);
+                
+                while(read != -1 && line[0] == '['){
+
+                  strtok(line, "<");
+                  lowpc = strdup(strtok(NULL, "<"));
+                  highpc = strdup(strtok(NULL, ">"));
+                  tmp_location = strdup(strtok(NULL, ">"));
+                  lowpc[strlen(lowpc) - 1] = '\0'; /* Remove last character '>' */
+             
+                  dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1);
+                
+                  strtok(lowpc, "=");
+                  new_entry->lowpc = (void *) strtoul(strtok(NULL, "="), NULL, 16);
+                  strtok(highpc, "=");
+                  new_entry->highpc = (void *) strtoul(strtok(NULL, "="), NULL, 16);
+
+                  new_entry->location = xbt_new0(s_dw_location_t, 1);
+                
+                  get_location(tmp_location, new_entry->location);
+                
+                  xbt_dynar_push(frame->location->location.loclist, &new_entry);
+
+                  read = getline(&line, &n, fp);
+                  xbt_str_ltrim(line, NULL);
+                }
+
+              }else{
+                read = getline(&line, &n, fp);
+                frame->location->type = get_location(location_type, frame->location);
+
+              }
+
+              xbt_dynar_push(mc_binary_local_variables, &frame);
+
+            }else{
+
+               read = getline(&line, &n, fp);
+
+            }
+          }else if(node_type != NULL && (strcmp(node_type, "DW_AT_declaration") == 0 || strcmp(node_type, "DW_AT_abstract_origin") == 0 || strcmp(node_type, "DW_AT_artificial") == 0)){
+
+            read = getline(&line, &n, fp);
+            valid_frame = 0;
+          
+          }else{
+
+            read = getline(&line, &n, fp);
+
+          }         
+
+        }
+        
+        valid_frame = 1;
+
+      }else if(strcmp(node_type, "DW_TAG_variable") == 0){ /* New variable */
+        
+        variable_name = NULL;
+        location_type = NULL;
+        
+        read = getline(&line, &n, fp);
+
+        while(read != -1 && line[0] != '<'){
+
+          if(n == 0)
+            continue;
+
+          tmp_line = strdup(line);
+          
+          node_type = strtok(line, " ");
+
+          if(node_type != NULL && strcmp(node_type, "DW_AT_name") == 0){
+
+            variable_name = strdup(strtok(NULL, " "));
+            read = getline(&line, &n, fp);
+            
+          }else if(node_type != NULL && strcmp(node_type, "DW_AT_location") == 0){
+
+            if(valid_variable == 1){
+
+              location_type = strdup(strtok(NULL, " "));
+
+              dw_local_variable_t variable = xbt_new0(s_dw_local_variable_t, 1);
+              variable->name = strdup(variable_name);
+              variable->location = xbt_new0(s_dw_location_t, 1);
+            
+              if(strcmp(location_type, "<loclist") == 0){
+
+                variable->location->type = e_dw_loclist;
+                variable->location->location.loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL);
+
+                read = getline(&line, &n, fp);
+                xbt_str_ltrim(line, NULL);
+                
+                while(read != -1 && line[0] == '['){
+
+                  strtok(line, "<");
+                  lowpc = strdup(strtok(NULL, "<"));
+                  highpc = strdup(strtok(NULL, ">"));
+                  tmp_location = strdup(strtok(NULL, ">"));
+                  lowpc[strlen(lowpc) - 1] = '\0'; /* Remove last character '>' */
+
+                  dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1);
+
+                  strtok(lowpc, "=");
+                  new_entry->lowpc = (void *) strtoul(strtok(NULL, "="), NULL, 16);
+                  strtok(highpc, "=");
+                  new_entry->highpc = (void *) strtoul(strtok(NULL, "="), NULL, 16);
+
+                  new_entry->location = xbt_new0(s_dw_location_t, 1);
+                
+                  get_location(tmp_location, new_entry->location);
+                  
+                  xbt_dynar_push(variable->location->location.loclist, &new_entry);
+
+                  read = getline(&line, &n, fp);
+                  xbt_str_ltrim(line, NULL);
+                }
+              
+              }else{
+                
+                xbt_str_strip_spaces(tmp_line);
+                split = xbt_str_split(tmp_line, " ");
+                xbt_dynar_remove_at(split, 0, NULL);
+                location_type = xbt_str_join(split, " ");
+                
+                variable->location->type = get_location(location_type, variable->location);
+                read = getline(&line, &n, fp);
+
+              }
+
+              xbt_dynar_push(((dw_frame_t)xbt_dynar_get_as(mc_binary_local_variables, xbt_dynar_length(mc_binary_local_variables) - 1, dw_frame_t))->variables, &variable);
+
+            }else{
+
+              read = getline(&line, &n, fp);
+
+            }
+           
+          }else if(node_type != NULL && (strcmp(node_type, "DW_AT_artificial") == 0 || strcmp(node_type, "DW_AT_external") == 0)){
+
+            valid_variable = 0;
+            read = getline(&line, &n, fp);
+
+          }else{
+
+            read = getline(&line, &n, fp);
+
+          }
+      
+        }
+
+        valid_variable = 1;
+
+      }else{
+
+        read = getline(&line, &n, fp);
+
+      }
+    }else{
+
+      read = getline(&line, &n, fp);
+
+    }
+
+  }
+
+  print_local_variables(mc_binary_local_variables);
+
+  free(line); free(tmp_line); free(tmp_location); free(frame_name);
+  free(node_type); free(location_type); free(variable_name); free(lowpc); free(highpc);
+  free(command);
+  pclose(fp);
+}
+
+void print_local_variables(xbt_dynar_t list){
+  
+  dw_frame_t frame;
+  dw_local_variable_t variable;
+  dw_location_entry_t entry;
+  dw_location_t location_entry;
+  unsigned int cursor = 0, cursor2 = 0, cursor3 = 0, cursor4 = 0;
+
+  xbt_dynar_foreach(list, cursor, frame){
+    fprintf(stderr, "Frame name : %s", frame->name);
+    fprintf(stderr, "Location type : %d\n", frame->location->type); 
+    fprintf(stderr, "Variables : (%lu)\n", xbt_dynar_length(frame->variables));
+    xbt_dynar_foreach(frame->variables, cursor2, variable){
+      fprintf(stderr, "Name : %s", variable->name);
+      fprintf(stderr, "Location type : %d\n", variable->location->type);
+      switch(variable->location->type){
+      case e_dw_loclist :
+        xbt_dynar_foreach(variable->location->location.loclist, cursor3, entry){
+          fprintf(stderr, "Lowpc : %p, Highpc : %p,", entry->lowpc, entry->highpc);
+          switch(entry->location->type){
+          case e_dw_register :
+            fprintf(stderr, " Location : in register %d\n", entry->location->location.reg);
+            break;
+          case e_dw_bregister_op:
+            fprintf(stderr, " Location : Add %d to the value in register %d\n", entry->location->location.breg_op.offset, entry->location->location.breg_op.reg);
+            break;
+          case e_dw_lit:
+            fprintf(stderr, "Value already kwnown : %d\n", entry->location->location.lit);
+            break;
+          case e_dw_fbregister_op:
+            fprintf(stderr, " Location : %d bytes from logical frame pointer\n", entry->location->location.fbreg_op);
+            break;
+          case e_dw_compose:
+            fprintf(stderr, " Location :\n");
+            xbt_dynar_foreach(entry->location->location.compose, cursor4, location_entry){
+              switch(location_entry->type){
+              case e_dw_register :
+                fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg);
+                break;
+              case e_dw_bregister_op:
+                fprintf(stderr, " %d) add %d to the value in register %d\n", cursor4 + 1, location_entry->location.breg_op.offset, location_entry->location.breg_op.reg);
+                break;
+              case e_dw_lit:
+                fprintf(stderr, "%d) Value already kwnown : %d\n", cursor4 + 1, location_entry->location.lit);
+                break;
+              case e_dw_fbregister_op:
+                fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op);
+                break;
+              case e_dw_deref:
+                fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size);      
+                break;
+              case e_dw_arithmetic : 
+                fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic);
+                break;
+              case e_dw_piece:
+                fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece);
+                break;
+              case e_dw_constant :
+                fprintf(stderr, "%d) Constant %d\n", cursor4 + 1, location_entry->location.constant.value);
+                break;
+              default : 
+                fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1);
+                break;
+              }
+            }
+            break;
+          default:
+            fprintf(stderr, "Location type not supported\n");
+            break;
+          }
+        }
+        break;
+      case e_dw_compose:
+        cursor4 = 0;
+        fprintf(stderr, "Location :\n");
+        xbt_dynar_foreach(variable->location->location.compose, cursor4, location_entry){
+          switch(location_entry->type){
+          case e_dw_register :
+             fprintf(stderr, " %d) in register %d\n", cursor4 + 1, location_entry->location.reg);
+            break;
+          case e_dw_bregister_op:
+            fprintf(stderr, " %d) add %d to the value in register %d\n", cursor4 + 1, location_entry->location.breg_op.offset, location_entry->location.breg_op.reg);
+            break;
+          case e_dw_lit:
+            fprintf(stderr, "%d) Value already kwnown : %d\n", cursor4 + 1, location_entry->location.lit);
+            break;
+          case e_dw_fbregister_op:
+            fprintf(stderr, " %d) %d bytes from logical frame pointer\n", cursor4 + 1, location_entry->location.fbreg_op);
+            break;
+          case e_dw_deref:
+            fprintf(stderr, " %d) Pop the stack entry and treats it as an address (size of data %d)\n", cursor4 + 1, location_entry->location.deref_size);      
+            break;
+          case e_dw_arithmetic : 
+            fprintf(stderr, "%d) arithmetic operation : %s\n", cursor4 + 1, location_entry->location.arithmetic);
+            break;
+          case e_dw_piece:
+            fprintf(stderr, "%d) The %d byte(s) previous value\n", cursor4 + 1, location_entry->location.piece);
+            break;
+          case e_dw_constant :
+            fprintf(stderr, "%d) Constant %d\n", cursor4 + 1, location_entry->location.constant.value);
+            break;
+          default : 
+            fprintf(stderr, "%d) Location type not supported\n", cursor4 + 1);
+            break;
+          }
+        }
+        break;
+      default :
+        fprintf(stderr, "Location type not supported\n");
+        break;
+      }
+    }
+  }
+
+}
+
+static e_dw_location_type get_location(char *expr, dw_location_t entry){
+
+  int cursor = 0;
+  char *tok = NULL, *tmp_tok = NULL; 
+
+  xbt_dynar_t tokens = xbt_str_split(expr, NULL);
+  xbt_dynar_remove_at(tokens, xbt_dynar_length(tokens) - 1, NULL);
+
+  if(xbt_dynar_length(tokens) > 1){
+
+    entry->type = e_dw_compose;
+    entry->location.compose = xbt_dynar_new(sizeof(dw_location_t), NULL);
+
+    while(cursor < xbt_dynar_length(tokens)){
+
+      tok = xbt_dynar_get_as(tokens, cursor, char*);
+      
+      if(strncmp(tok, "DW_OP_reg", 9) == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_register;
+        if(tok[9] == 'x'){
+          new_element->location.reg = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+        }else{
+          new_element->location.reg = atoi(strtok(tok, "DW_OP_reg"));
+        }
+        xbt_dynar_push(entry->location.compose, &new_element);     
+      }else if(strcmp(tok, "DW_OP_fbreg") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_fbregister_op;
+        new_element->location.fbreg_op = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strncmp(tok, "DW_OP_breg", 10) == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_bregister_op;
+        if(tok[10] == 'x'){
+          new_element->location.breg_op.reg = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+          new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+        }else{
+          if(strchr(tok,'+') != NULL){
+            tmp_tok = strtok(tok,"DW_OP_breg"); 
+            new_element->location.breg_op.reg = atoi(strtok(tmp_tok,"+"));
+            new_element->location.breg_op.offset = atoi(strtok(NULL,"+"));
+          }else{
+            new_element->location.breg_op.reg = atoi(strtok(tok, "DW_OP_breg"));
+            new_element->location.breg_op.offset = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+          }
+        }
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strncmp(tok, "DW_OP_lit", 9) == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_lit;
+        new_element->location.lit = atoi(strtok(tok, "DW_OP_lit"));
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_piece") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_piece;
+        if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
+          new_element->location.piece = atoi(xbt_dynar_get_as(tokens, cursor, char*));
+        else
+          new_element->location.piece = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';
+        xbt_dynar_push(entry->location.compose, &new_element);
+
+      }else if(strcmp(tok, "DW_OP_abs") == 0 || 
+               strcmp(tok, "DW_OP_and") == 0 ||
+               strcmp(tok, "DW_OP_div") == 0 ||
+               strcmp(tok, "DW_OP_minus") == 0 ||
+               strcmp(tok, "DW_OP_mod") == 0 ||
+               strcmp(tok, "DW_OP_mul") == 0 ||
+               strcmp(tok, "DW_OP_neg") == 0 ||
+               strcmp(tok, "DW_OP_not") == 0 ||
+               strcmp(tok, "DW_OP_or") == 0 ||
+               strcmp(tok, "DW_OP_plus") == 0 ||
+               strcmp(tok, "DW_OP_plus_uconst") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_arithmetic;
+        new_element->location.arithmetic = strdup(strtok(tok, "DW_OP_"));
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_stack_value") == 0){
+        cursor++;
+      }else if(strcmp(tok, "DW_OP_deref_size") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_deref;
+        if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
+          new_element->location.deref_size = atoi(xbt_dynar_get_as(tokens, cursor, char*));
+        else
+          new_element->location.deref_size = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_deref") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_deref;
+        new_element->location.deref_size = sizeof(void *);
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_constu") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_constant;
+        new_element->location.constant.is_signed = 0;
+        new_element->location.constant.bytes = 1;
+        if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
+          new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*));
+        else
+          new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_consts") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_constant;
+        new_element->location.constant.is_signed = 1;
+        new_element->location.constant.bytes = 1;
+        new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_const1u") == 0 ||
+               strcmp(tok, "DW_OP_const2u") == 0 ||
+               strcmp(tok, "DW_OP_const4u") == 0 ||
+               strcmp(tok, "DW_OP_const8u") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_constant;
+        new_element->location.constant.is_signed = 0;
+        new_element->location.constant.bytes = tok[11] - '0';
+        if(strlen(xbt_dynar_get_as(tokens, ++cursor, char*)) > 1)
+          new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, cursor, char*));
+        else
+          new_element->location.constant.value = xbt_dynar_get_as(tokens, cursor, char*)[0] - '0';
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else if(strcmp(tok, "DW_OP_const1s") == 0 ||
+               strcmp(tok, "DW_OP_const2s") == 0 ||
+               strcmp(tok, "DW_OP_const4s") == 0 ||
+               strcmp(tok, "DW_OP_const8s") == 0){
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_constant;
+        new_element->location.constant.is_signed = 1;
+        new_element->location.constant.bytes = tok[11] - '0';
+        new_element->location.constant.value = atoi(xbt_dynar_get_as(tokens, ++cursor, char*));
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }else{
+        dw_location_t new_element = xbt_new0(s_dw_location_t, 1);
+        new_element->type = e_dw_unsupported;
+        xbt_dynar_push(entry->location.compose, &new_element);
+      }
+
+      cursor++;
+      
+    }
+
+    free(tok);
+    free(tmp_tok);
+    /*xbt_dynar_free(&tokens);*/
+
+    return e_dw_compose;
+
+  }else{
+
+    if(strncmp(expr, "DW_OP_reg", 9) == 0){
+      entry->type = e_dw_register;
+      entry->location.reg = atoi(strtok(expr,"DW_OP_reg"));
+    }else if(strncmp(expr, "DW_OP_breg", 10) == 0){
+      entry->type = e_dw_bregister_op;
+      tok = strtok(expr, "+");
+      entry->location.breg_op.offset = atoi(strtok(NULL, "+"));
+      entry->location.breg_op.reg = atoi(strtok(tok, "DW_OP_breg"));
+    }else{
+      entry->type = e_dw_unsupported;
+    }
+
+    free(tok);
+    free(tmp_tok);
+
+    return entry->type;
+
+  }
+
+}
index 3689a69..eadd149 100644 (file)
@@ -11,29 +11,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc,
                                 "Logging specific to algorithms for liveness properties verification");
 
 xbt_dynar_t reached_pairs;
-xbt_dynar_t reached_pairs_hash;
-xbt_dynar_t visited_pairs;
-xbt_dynar_t visited_pairs_hash;
 xbt_dynar_t successors;
 
-xbt_dynar_t hosts_table;
-
-
-/* fast implementation of djb2 algorithm */
-unsigned int hash_region(char *str, int str_len){
-
-  int c;
-  register unsigned int hash = 5381;
-
-  while (str_len--) {
-    c = *str++;
-    hash = ((hash << 5) + hash) + c;    /* hash * 33 + c */
-  }
-
-  return hash;
-
-}
-
 int create_dump(int pair)
 {
    // Try to enable core dumps
@@ -104,8 +83,7 @@ int reached(xbt_state_t st){
     /* New pair reached */
     xbt_dynar_push(reached_pairs, &new_pair); 
     MC_UNSET_RAW_MEM;
-    
-    
     return 0;
 
   }else{
@@ -136,8 +114,6 @@ int reached(xbt_state_t st){
       }
     }
 
-    //create_dump(xbt_dynar_length(reached_pairs));
-
     /* New pair reached */
     xbt_dynar_push(reached_pairs, &new_pair); 
     
@@ -193,403 +169,6 @@ void set_pair_reached(xbt_state_t st){
     
 }
 
-
-int reached_hash(xbt_state_t st){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  if(xbt_dynar_is_empty(reached_pairs_hash)){
-
-    return 0;
-
-  }else{
-
-    MC_SET_RAW_MEM;
-
-    mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
-    MC_take_snapshot_liveness(sn);
-
-    int j;
-    unsigned int hash_regions[sn->num_reg];
-    for(j=0; j<sn->num_reg; j++){
-      hash_regions[j] = hash_region(sn->regions[j]->data, sn->regions[j]->size);
-    }
-
-
-    /* Get values of propositional symbols */
-    xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
-    unsigned int cursor = 0;
-    xbt_propositional_symbol_t ps = NULL;
-    int res;
-    int_f_void_t f;
-
-    xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-      f = (int_f_void_t)ps->function;
-      res = (*f)();
-      xbt_dynar_push_as(prop_ato, int, res);
-    }
-
-    mc_pair_reached_hash_t pair_test = NULL;
-
-    int region_diff = 0;
-
-    cursor = 0;
-
-    xbt_dynar_foreach(reached_pairs_hash, cursor, pair_test){
-
-      if(automaton_state_compare(pair_test->automaton_state, st) == 0){
-        if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
-          for(j=0 ; j< sn->num_reg ; j++){
-            if(hash_regions[j] != pair_test->hash_regions[j]){
-              region_diff++;
-            }
-          }
-          if(region_diff == 0){
-            MC_free_snapshot(sn);
-            xbt_dynar_reset(prop_ato);
-            xbt_free(prop_ato);
-            MC_UNSET_RAW_MEM;
-
-            if(raw_mem_set)
-              MC_SET_RAW_MEM;
-            else
-              MC_UNSET_RAW_MEM;
-            
-            return 1;
-          }else{
-            XBT_INFO("Different snapshot");
-          }
-        }else{
-          XBT_INFO("Different values of propositional symbols");
-        }
-      }else{
-        XBT_INFO("Different automaton state");
-      }
-
-      region_diff = 0;
-    }
-    
-    MC_free_snapshot(sn);
-    xbt_dynar_reset(prop_ato);
-    xbt_free(prop_ato);
-    MC_UNSET_RAW_MEM;
-
-    if(raw_mem_set)
-      MC_SET_RAW_MEM;
-    else
-      MC_UNSET_RAW_MEM;
-    
-    return 0;
-    
-  }
-}
-
-void set_pair_reached_hash(xbt_state_t st){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-  MC_SET_RAW_MEM;
-
-  mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
-  MC_take_snapshot_liveness(sn);
-  mc_pair_reached_hash_t pair = NULL;
-  pair = xbt_new0(s_mc_pair_reached_hash_t, 1);
-  pair->automaton_state = st;
-  pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
-  pair->hash_regions = malloc(sizeof(unsigned int) * sn->num_reg);
-  
-  int i;
-
-  for(i=0 ; i< sn->num_reg ; i++){
-    pair->hash_regions[i] = hash_region(sn->regions[i]->data, sn->regions[i]->size);
-  }
-  
-  /* Get values of propositional symbols */
-  unsigned int cursor = 0;
-  xbt_propositional_symbol_t ps = NULL;
-  int res;
-  int_f_void_t f;
-
-  xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-    f = (int_f_void_t)ps->function;
-    res = (*f)();
-    xbt_dynar_push_as(pair->prop_ato, int, res);
-  }
-  
-  xbt_dynar_push(reached_pairs_hash, &pair);
-
-  MC_free_snapshot(sn);
-  
-  MC_UNSET_RAW_MEM;
-
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
-  else
-    MC_UNSET_RAW_MEM;
-      
-}
-
-
-int visited(xbt_state_t st, int sc){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  if(xbt_dynar_is_empty(visited_pairs)){
-
-    return 0;
-
-  }else{
-
-    MC_SET_RAW_MEM;
-
-    mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
-    MC_take_snapshot_liveness(sn);
-
-    xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
-
-    /* Get values of propositional symbols */
-    unsigned int cursor = 0;
-    xbt_propositional_symbol_t ps = NULL;
-    int res;
-    int_f_void_t f;
-
-    xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-      f = (int_f_void_t)ps->function;
-      res = (*f)();
-      xbt_dynar_push_as(prop_ato, int, res);
-    }
-
-    cursor = 0;
-    mc_pair_visited_t pair_test = NULL;
-
-    xbt_dynar_foreach(visited_pairs, cursor, pair_test){
-      if(pair_test->search_cycle == sc) {
-        if(automaton_state_compare(pair_test->automaton_state, st) == 0){
-          if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
-            if(snapshot_compare(pair_test->system_state, sn) == 0){
-      
-              MC_free_snapshot(sn);
-              xbt_dynar_reset(prop_ato);
-              xbt_free(prop_ato);
-              MC_UNSET_RAW_MEM;
-    
-              if(raw_mem_set)
-                MC_SET_RAW_MEM;
-              else
-                MC_UNSET_RAW_MEM;
-              
-              return 1;
-  
-            }else{
-              XBT_INFO("Different snapshot");
-            }
-          }else{
-            XBT_INFO("Different values of propositional symbols"); 
-          }
-        }else{
-          XBT_INFO("Different automaton state");
-        }
-      }else{
-        XBT_INFO("Different value of search_cycle");
-      }
-    }
-
-
-    MC_free_snapshot(sn);
-    xbt_dynar_reset(prop_ato);
-    xbt_free(prop_ato);
-    MC_UNSET_RAW_MEM;
-
-    if(raw_mem_set)
-      MC_SET_RAW_MEM;
-    else
-      MC_UNSET_RAW_MEM;
-    
-    return 0;
-    
-  }
-}
-
-
-int visited_hash(xbt_state_t st, int sc){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-
-  if(xbt_dynar_is_empty(visited_pairs_hash)){
-
-    return 0;
-
-  }else{
-
-    MC_SET_RAW_MEM;
-
-    mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
-    MC_take_snapshot_liveness(sn);
-
-    int j;
-    unsigned int hash_regions[sn->num_reg];
-    for(j=0; j<sn->num_reg; j++){
-      hash_regions[j] = hash_region(sn->regions[j]->data, sn->regions[j]->size);
-    }
-
-    
-    /* Get values of propositional symbols */
-    xbt_dynar_t prop_ato = xbt_dynar_new(sizeof(int), NULL);
-    unsigned int cursor = 0;
-    xbt_propositional_symbol_t ps = NULL;
-    int res;
-    int_f_void_t f;
-
-    xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-      f = (int_f_void_t)ps->function;
-      res = (*f)();
-      xbt_dynar_push_as(prop_ato, int, res);
-    }
-
-    mc_pair_visited_hash_t pair_test = NULL;
-
-    int region_diff = 0;
-    cursor = 0;
-
-    xbt_dynar_foreach(visited_pairs_hash, cursor, pair_test){
-  
-      if(pair_test->search_cycle == sc) {
-        if(automaton_state_compare(pair_test->automaton_state, st) == 0){
-          if(propositional_symbols_compare_value(pair_test->prop_ato, prop_ato) == 0){
-            for(j=0 ; j< sn->num_reg ; j++){
-              if(hash_regions[j] != pair_test->hash_regions[j]){
-                region_diff++;
-              }
-            }
-            if(region_diff == 0){
-              MC_free_snapshot(sn);
-              xbt_dynar_reset(prop_ato);
-              xbt_free(prop_ato);
-              MC_UNSET_RAW_MEM;
-              
-              if(raw_mem_set)
-                MC_SET_RAW_MEM;
-              else
-                MC_UNSET_RAW_MEM;
-  
-              return 1;
-            }else{
-              //XBT_INFO("Different snapshot");
-            }
-          }else{
-            //XBT_INFO("Different values of propositional symbols"); 
-          }
-        }else{
-          //XBT_INFO("Different automaton state");
-        }
-      }else{
-        //XBT_INFO("Different value of search_cycle");
-      }
-      
-      region_diff = 0;
-    }
-    
-    MC_free_snapshot(sn);
-    xbt_dynar_reset(prop_ato);
-    xbt_free(prop_ato);
-    MC_UNSET_RAW_MEM;
-  
-    if(raw_mem_set)
-      MC_SET_RAW_MEM;
-    else
-      MC_UNSET_RAW_MEM;
-  
-    return 0;
-    
-  }
-}
-
-void set_pair_visited_hash(xbt_state_t st, int sc){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-  MC_SET_RAW_MEM;
-
-  mc_snapshot_t sn = xbt_new0(s_mc_snapshot_t, 1);
-  MC_take_snapshot_liveness(sn);
-  mc_pair_visited_hash_t pair = NULL;
-  pair = xbt_new0(s_mc_pair_visited_hash_t, 1);
-  pair->automaton_state = st;
-  pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
-  pair->search_cycle = sc;
-  pair->hash_regions = malloc(sizeof(unsigned int) * sn->num_reg);
-  
-  int i;
-
-  for(i=0 ; i< sn->num_reg ; i++){
-    pair->hash_regions[i] = hash_region(sn->regions[i]->data, sn->regions[i]->size);
-  }
-  
-  /* Get values of propositional symbols */
-  unsigned int cursor = 0;
-  xbt_propositional_symbol_t ps = NULL;
-  int res;
-  int_f_void_t f;
-
-  xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-    f = (int_f_void_t)ps->function;
-    res = (*f)();
-    xbt_dynar_push_as(pair->prop_ato, int, res);
-  }
-  
-  xbt_dynar_push(visited_pairs_hash, &pair);
-
-  MC_free_snapshot(sn);
-  
-  MC_UNSET_RAW_MEM;
-    
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
-  else
-    MC_UNSET_RAW_MEM;
-  
-}
-
-void set_pair_visited(xbt_state_t st, int sc){
-
-  raw_mem_set = (mmalloc_get_current_heap() == raw_heap);
-  MC_SET_RAW_MEM;
-  mc_pair_visited_t pair = NULL;
-  pair = xbt_new0(s_mc_pair_visited_t, 1);
-  pair->automaton_state = st;
-  pair->prop_ato = xbt_dynar_new(sizeof(int), NULL);
-  pair->search_cycle = sc;
-  pair->system_state = xbt_new0(s_mc_snapshot_t, 1);
-  MC_take_snapshot_liveness(pair->system_state);
-
-
-  /* Get values of propositional symbols */
-  unsigned int cursor = 0;
-  xbt_propositional_symbol_t ps = NULL;
-  int res;
-  int_f_void_t f;
-
-  xbt_dynar_foreach(_mc_property_automaton->propositional_symbols, cursor, ps){
-    f = (int_f_void_t)ps->function;
-    res = (*f)();
-    xbt_dynar_push_as(pair->prop_ato, int, res);
-  }
-  
-  xbt_dynar_push(visited_pairs, &pair);
-  
-  MC_UNSET_RAW_MEM;
-  
-  if(raw_mem_set)
-    MC_SET_RAW_MEM;
-  else
-    MC_UNSET_RAW_MEM;
-  
-}
-
 void MC_pair_delete(mc_pair_t pair){
   xbt_free(pair->graph_state->proc_status);
   xbt_free(pair->graph_state);
@@ -679,9 +258,6 @@ void MC_ddfs_init(void){
   }
 
   reached_pairs = xbt_dynar_new(sizeof(mc_pair_reached_t), NULL);
-  //reached_pairs_hash = xbt_dynar_new(sizeof(mc_pair_reached_hash_t), NULL);
-  //visited_pairs = xbt_dynar_new(sizeof(mc_pair_visited_t), NULL);
-  //visited_pairs_hash = xbt_dynar_new(sizeof(mc_pair_visited_hash_t), NULL);
   successors = xbt_dynar_new(sizeof(mc_pair_stateless_t), NULL);
 
   /* Save the initial state */
@@ -690,6 +266,9 @@ void MC_ddfs_init(void){
 
   MC_UNSET_RAW_MEM; 
 
+  /* Get .plt section (start and end addresses) for data libsimgrid comparison */
+  get_plt_section();
+
   unsigned int cursor = 0;
   xbt_state_t state;
 
@@ -717,7 +296,6 @@ void MC_ddfs_init(void){
         MC_UNSET_RAW_MEM;
 
         set_pair_reached(state);
-        //set_pair_reached_hash(state);
 
         if(cursor != 0){
           MC_restore_snapshot(initial_snapshot_liveness);
@@ -777,12 +355,6 @@ void MC_ddfs(int search_cycle){
   
   if(xbt_fifo_size(mc_stack_liveness) < MAX_DEPTH_LIVENESS){
 
-    //set_pair_visited(current_pair->automaton_state, search_cycle);
-    //set_pair_visited_hash(current_pair->automaton_state, search_cycle);
-
-    //XBT_INFO("Visited pairs : %lu", xbt_dynar_length(visited_pairs));
-    //XBT_INFO("Visited pairs : %lu", xbt_dynar_length(visited_pairs_hash));
-
     if(current_pair->requests > 0){
 
       while((req = MC_state_get_request(current_pair->graph_state, &value)) != NULL){
@@ -801,7 +373,6 @@ void MC_ddfs(int search_cycle){
         /* Wait for requests (schedules processes) */
         MC_wait_for_requests();
 
-
         MC_SET_RAW_MEM;
 
         /* Create the new expanded graph_state */
@@ -857,7 +428,6 @@ void MC_ddfs(int search_cycle){
             if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){ 
           
               if(reached(pair_succ->automaton_state)){
-                //if(reached_hash(pair_succ->automaton_state)){
         
                 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));
 
@@ -875,7 +445,6 @@ void MC_ddfs(int search_cycle){
                 XBT_INFO("Next pair (depth =%d) -> Acceptance pair : graph=%p, automaton=%p(%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
 
                 XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
-                //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
 
                 MC_SET_RAW_MEM;
                 xbt_fifo_unshift(mc_stack_liveness, pair_succ);
@@ -887,21 +456,12 @@ void MC_ddfs(int search_cycle){
 
             }else{
 
-              //if(!visited_hash(pair_succ->automaton_state, search_cycle)){
-                //if(!visited(pair_succ->automaton_state, search_cycle)){
-    
-                MC_SET_RAW_MEM;
-                xbt_fifo_unshift(mc_stack_liveness, pair_succ);
-                MC_UNSET_RAW_MEM;
-    
-                MC_ddfs(search_cycle);
-    
-                /*}else{
-
-                XBT_INFO("Next pair already visited ! ");
-
-                }*/
-        
+              MC_SET_RAW_MEM;
+              xbt_fifo_unshift(mc_stack_liveness, pair_succ);
+              MC_UNSET_RAW_MEM;
+              
+              MC_ddfs(search_cycle);
+               
             }
 
           }else{
@@ -911,30 +471,19 @@ void MC_ddfs(int search_cycle){
               XBT_INFO("Next pair (depth =%d) -> Acceptance pair : graph=%p, automaton=%p(%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
       
               set_pair_reached(pair_succ->automaton_state); 
-              //set_pair_reached_hash(pair_succ->automaton_state);
 
               search_cycle = 1;
 
               XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
-              //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
 
             }
 
-            //if(!visited_hash(pair_succ->automaton_state, search_cycle)){
-              //if(!visited(pair_succ->automaton_state, search_cycle)){
-        
-              MC_SET_RAW_MEM;
-              xbt_fifo_unshift(mc_stack_liveness, pair_succ);
-              MC_UNSET_RAW_MEM;
-        
-              MC_ddfs(search_cycle);
-        
-              /*}else{
-
-              XBT_INFO("Next pair already visited ! ");
-
-              }*/
-
+            MC_SET_RAW_MEM;
+            xbt_fifo_unshift(mc_stack_liveness, pair_succ);
+            MC_UNSET_RAW_MEM;
+            
+            MC_ddfs(search_cycle);
+           
           }
 
    
@@ -1002,8 +551,7 @@ void MC_ddfs(int search_cycle){
           if((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2)){ 
 
             if(reached(pair_succ->automaton_state)){
-              //if(reached_hash(pair_succ->automaton_state)){
-
+           
               XBT_INFO("Next pair (depth = %d) already reached !", xbt_fifo_size(mc_stack_liveness) + 1);
         
               XBT_INFO("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*");
@@ -1020,7 +568,6 @@ void MC_ddfs(int search_cycle){
               XBT_INFO("Next pair (depth = %d) -> Acceptance pair : graph=%p, automaton=%p(%s)", xbt_fifo_size(mc_stack_liveness) + 1, pair_succ->graph_state, pair_succ->automaton_state, pair_succ->automaton_state->id);
         
               XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
-              //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
 
               MC_SET_RAW_MEM;
               xbt_fifo_unshift(mc_stack_liveness, pair_succ);
@@ -1032,20 +579,12 @@ void MC_ddfs(int search_cycle){
 
           }else{
 
-            //if(!visited_hash(pair_succ->automaton_state, search_cycle)){
-              //if(!visited(pair_succ->automaton_state, search_cycle)){
-
-              MC_SET_RAW_MEM;
-              xbt_fifo_unshift(mc_stack_liveness, pair_succ);
-              MC_UNSET_RAW_MEM;
-        
-              MC_ddfs(search_cycle);
-        
-              /*}else{
-
-              XBT_INFO("Next pair already visited ! ");
-
-              }*/
+            MC_SET_RAW_MEM;
+            xbt_fifo_unshift(mc_stack_liveness, pair_succ);
+            MC_UNSET_RAW_MEM;
+            
+            MC_ddfs(search_cycle);
+            
           }
       
 
@@ -1054,30 +593,19 @@ void MC_ddfs(int search_cycle){
           if(((pair_succ->automaton_state->type == 1) || (pair_succ->automaton_state->type == 2))){
 
             set_pair_reached(pair_succ->automaton_state);
-            //set_pair_reached_hash(pair_succ->automaton_state);
-            
+         
             search_cycle = 1;
 
             XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs));
-            //XBT_INFO("Reached pairs : %lu", xbt_dynar_length(reached_pairs_hash));
 
           }
 
-          //if(!visited_hash(pair_succ->automaton_state, search_cycle)){
-            //if(!visited(pair_succ->automaton_state, search_cycle)){
-
-            MC_SET_RAW_MEM;
-            xbt_fifo_unshift(mc_stack_liveness, pair_succ);
-            MC_UNSET_RAW_MEM;
-      
-            MC_ddfs(search_cycle);
-      
-            /*}else{
-
-            XBT_INFO("Next pair already visited ! ");
-
-            }*/
-
+          MC_SET_RAW_MEM;
+          xbt_fifo_unshift(mc_stack_liveness, pair_succ);
+          MC_UNSET_RAW_MEM;
+          
+          MC_ddfs(search_cycle);
+          
         }
 
         /* Restore system before checking others successors */
@@ -1106,7 +634,6 @@ void MC_ddfs(int search_cycle){
   xbt_fifo_shift(mc_stack_liveness);
   if((current_pair->automaton_state->type == 1) || (current_pair->automaton_state->type == 2)){
     xbt_dynar_pop(reached_pairs, NULL);
-    //xbt_dynar_pop(reached_pairs_hash, NULL);
   }
   MC_UNSET_RAW_MEM;
 
index 0de5a9e..5c64d95 100644 (file)
@@ -35,8 +35,6 @@ typedef struct s_mc_snapshot{
   mc_mem_region_t *regions;
 } s_mc_snapshot_t, *mc_snapshot_t;
 
-extern char *prog_name;
-
 void MC_take_snapshot(mc_snapshot_t);
 void MC_take_snapshot_liveness(mc_snapshot_t s);
 void MC_restore_snapshot(mc_snapshot_t);
@@ -143,13 +141,13 @@ extern void *raw_heap;
 /* an API to query about the status of a heap, we simply call mmstats and */
 /* because I now how does structure looks like, then I redefine it here */
 
-struct mstats {
-  size_t bytes_total;           /* Total size of the heap. */
-  size_t chunks_used;           /* Chunks allocated by the user. */
-  size_t bytes_used;            /* Byte total of user-allocated chunks. */
-  size_t chunks_free;           /* Chunks in the free list. */
-  size_t bytes_free;            /* Byte total of chunks in the free list. */
-};
+/* struct mstats { */
+/*   size_t bytes_total;           /\* Total size of the heap. *\/ */
+/*   size_t chunks_used;           /\* Chunks allocated by the user. *\/ */
+/*   size_t bytes_used;            /\* Byte total of user-allocated chunks. *\/ */
+/*   size_t chunks_free;           /\* Chunks in the free list. *\/ */
+/*   size_t bytes_free;            /\* Byte total of chunks in the free list. *\/ */
+/* }; */
 
 #define MC_SET_RAW_MEM    mmalloc_set_current_heap(raw_heap)
 #define MC_UNSET_RAW_MEM  mmalloc_set_current_heap(std_heap)
@@ -183,6 +181,8 @@ typedef struct s_memory_map {
 } s_memory_map_t, *memory_map_t;
 
 memory_map_t get_memory_map(void);
+void free_memory_map(memory_map_t map);
+void get_plt_section(void);
 
 
 /********************************** DPOR for safety  **************************************/
@@ -191,6 +191,7 @@ typedef enum {
   e_mc_reduce_none,
   e_mc_reduce_dpor
 } e_mc_reduce_t;
+
 extern e_mc_reduce_t mc_reduce_kind;
 
 void MC_dpor_init(void);
@@ -201,6 +202,7 @@ void MC_init_safety(void);
 
 /********************************** Double-DFS for liveness property**************************************/
 
+extern xbt_fifo_t mc_stack_liveness;
 extern mc_snapshot_t initial_snapshot_liveness;
 extern xbt_automaton_t _mc_property_automaton;
 extern int compare;
@@ -216,47 +218,17 @@ typedef struct s_mc_pair_reached{
   xbt_state_t automaton_state;
   xbt_dynar_t prop_ato;
   mc_snapshot_t system_state;
-  //xbt_dict_t rdv_points;
 }s_mc_pair_reached_t, *mc_pair_reached_t;
 
-typedef struct s_mc_pair_visited{
-  xbt_state_t automaton_state;
-  xbt_dynar_t prop_ato;
-  mc_snapshot_t system_state;
-  int search_cycle;
-}s_mc_pair_visited_t, *mc_pair_visited_t;
-
-typedef struct s_mc_pair_visited_hash{
-  xbt_state_t automaton_state;
-  xbt_dynar_t prop_ato;
-  unsigned int *hash_regions;
-  int search_cycle;
-}s_mc_pair_visited_hash_t, *mc_pair_visited_hash_t;
-
-typedef struct s_mc_pair_reached_hash{
-  xbt_state_t automaton_state;
-  xbt_dynar_t prop_ato;
-  unsigned int *hash_regions;
-}s_mc_pair_reached_hash_t, *mc_pair_reached_hash_t;
-
-
-
 int MC_automaton_evaluate_label(xbt_exp_label_t l);
 mc_pair_t new_pair(mc_snapshot_t sn, mc_state_t sg, xbt_state_t st);
 
 int reached(xbt_state_t st);
 void set_pair_reached(xbt_state_t st);
-int reached_hash(xbt_state_t st);
-void set_pair_reached_hash(xbt_state_t st);
 int snapshot_compare(mc_snapshot_t s1, mc_snapshot_t s2);
 void MC_pair_delete(mc_pair_t pair);
 void MC_exit_liveness(void);
 mc_state_t MC_state_pair_new(void);
-int visited(xbt_state_t st, int search_cycle);
-void set_pair_visited(xbt_state_t st, int search_cycle);
-int visited_hash(xbt_state_t st, int search_cycle);
-void set_pair_visited_hash(xbt_state_t st, int search_cycle);
-unsigned int hash_region(char *str, int str_len);
 
 /* **** Double-DFS stateless **** */
 
@@ -266,8 +238,6 @@ typedef struct s_mc_pair_stateless{
   int requests;
 }s_mc_pair_stateless_t, *mc_pair_stateless_t;
 
-extern xbt_fifo_t mc_stack_liveness;
-
 mc_pair_stateless_t new_pair_stateless(mc_state_t sg, xbt_state_t st, int r);
 void MC_ddfs_init(void);
 void MC_ddfs(int search_cycle);
@@ -285,5 +255,78 @@ extern char* _surf_mc_property_file;
 
 int create_dump(int pair);
 
+/****** Local variables with DWARF ******/
+
+typedef enum {
+  e_dw_loclist,
+  e_dw_register,
+  e_dw_bregister_op,
+  e_dw_lit,
+  e_dw_fbregister_op,
+  e_dw_piece,
+  e_dw_arithmetic,
+  e_dw_compose,
+  e_dw_deref,
+  e_dw_constant,
+  e_dw_unsupported
+} e_dw_location_type;
+
+typedef struct s_dw_location{
+  e_dw_location_type type;
+  union{
+    
+    xbt_dynar_t loclist;
+    
+    int reg;
+    
+    struct{
+      int reg;
+      int offset;
+    }breg_op;
+
+    unsigned lit;
+
+    int fbreg_op;
+
+    int piece;
+
+    int deref_size;
+
+    xbt_dynar_t compose;
+
+    char *arithmetic;
+
+    struct{
+      int is_signed;
+      int bytes;
+      int value;
+    }constant;
+
+  }location;
+}s_dw_location_t, *dw_location_t;
+
+typedef struct s_dw_location_entry{
+  void *lowpc;
+  void *highpc;
+  dw_location_t location;
+}s_dw_location_entry_t, *dw_location_entry_t;
+
+typedef struct s_dw_local_variable{
+  char *name;
+  dw_location_t location;
+}s_dw_local_variable_t, *dw_local_variable_t;
+
+typedef struct s_dw_frame{
+  char *name;
+  dw_location_t location;
+  xbt_dynar_t variables;
+}s_dw_frame_t, *dw_frame_t;
+
+/* FIXME : implement free functions for each strcuture */
+
+extern xbt_dynar_t mc_binary_local_variables;
+
+void MC_get_binary_local_variables(void);
+void print_local_variables(xbt_dynar_t list);
 
 #endif
index 97f8bb8..25a49ca 100644 (file)
@@ -152,3 +152,12 @@ memory_map_t get_memory_map(void)
 
   return ret;
 }
+
+void free_memory_map(memory_map_t map){
+
+  int i;
+  for(i=0; i< map->mapsize; i++){
+    xbt_free(map->regions[i].pathname);
+  }
+  xbt_free(map);
+}
index 59d2e64..b97a629 100644 (file)
@@ -21,11 +21,11 @@ static void test1()
   mc_snapshot_t snapshot2 = xbt_new0(s_mc_snapshot_t, 1);
   MC_take_snapshot_liveness(snapshot2);
 
-  MC_UNSET_RAW_MEM;
-
   int res = snapshot_compare(snapshot1, snapshot2);
   xbt_assert(res == 0);
 
+  MC_UNSET_RAW_MEM;
+
   fprintf(stderr, "\n**************** END TEST 1 ****************\n");
 
   MC_SET_RAW_MEM;
@@ -49,7 +49,7 @@ static void test2()
 
   MC_UNSET_RAW_MEM;
 
-  char* t = strdup("toto");
+  char* t = malloc(5);
 
   MC_SET_RAW_MEM;
 
@@ -87,7 +87,7 @@ static void test3()
 
   MC_UNSET_RAW_MEM;
 
-  char *t = strdup("toto");;
+  char *t = malloc(5);
   free(t);
 
   MC_SET_RAW_MEM;
@@ -116,7 +116,7 @@ static void test4()
 
   fprintf(stderr, "\n**************** TEST 4 ****************\n\n");
 
-  char *t = strdup("toto");
+  char *t = malloc(5);
 
   MC_SET_RAW_MEM;
 
@@ -238,6 +238,9 @@ void MC_test_snapshot_comparison(){
   MC_UNSET_RAW_MEM;
 
   test1();
+
+  MC_restore_snapshot(initial);
+  MC_UNSET_RAW_MEM;
   
   test2();
   
@@ -260,4 +263,7 @@ void MC_test_snapshot_comparison(){
   MC_UNSET_RAW_MEM;
   
   test6();
+
+  MC_restore_snapshot(initial);
+  MC_UNSET_RAW_MEM;
 }
index 5814f78..eb889cb 100644 (file)
  */
 void MSG_create_environment(const char *file)
 {
+  SIMIX_create_environment(file);
+}
+
+void MSG_post_create_environment(void) {
   xbt_lib_cursor_t cursor;
   void **data;
   char *name;
 
-  SIMIX_create_environment(file);
-
   /* Initialize MSG hosts */
   xbt_lib_foreach(host_lib, cursor, name, data) {
     if(data[SIMIX_HOST_LEVEL])
index 5383a20..5aef61a 100644 (file)
@@ -38,6 +38,9 @@ void MSG_init_nocheck(int *argc, char **argv) {
 
     SIMIX_global_init(argc, argv);
 
+    if(MC_IS_ENABLED && mmalloc_ignore == NULL)
+      MC_ignore_init();
+    
     msg_global = xbt_new0(s_MSG_Global_t, 1);
 
 #ifdef MSG_USE_DEPRECATED
@@ -54,7 +57,15 @@ void MSG_init_nocheck(int *argc, char **argv) {
 
     SIMIX_function_register_process_create(MSG_process_create_from_SIMIX);
     SIMIX_function_register_process_cleanup(MSG_process_cleanup_from_SIMIX);
+
+    sg_platf_postparse_add_cb(MSG_post_create_environment);
+  }
+  
+  if(MC_IS_ENABLED){
+    /* Ignore total amount of messages sent during the simulation for heap comparison */
+    MC_ignore(&(msg_global->sent_msg), sizeof(msg_global->sent_msg));
   }
+
 #ifdef HAVE_TRACING
   TRACE_start();
 #endif
@@ -108,7 +119,7 @@ msg_error_t MSG_main(void)
   fflush(stdout);
   fflush(stderr);
 
-  if (MC_IS_ENABLED) {
+  if (MC_IS_ENABLED) { 
     MC_do_the_modelcheck_for_real();
   } else {
     SIMIX_run();
index 473ec7a..e63d05f 100644 (file)
@@ -294,7 +294,9 @@ XBT_INLINE msg_comm_t MSG_task_isend_with_matching(msg_task_t task, const char *
   msg_process_t process = MSG_process_self();
   msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
 
-  /* FIXME: these functions are not traceable */
+#ifdef HAVE_TRACING
+  int call_end = TRACE_msg_task_put_start(task);
+#endif
 
   /* Prepare the task to send */
   t_simdata = task->simdata;
@@ -317,6 +319,16 @@ XBT_INLINE msg_comm_t MSG_task_isend_with_matching(msg_task_t task, const char *
     simcall_comm_isend(mailbox, t_simdata->message_size,
                          t_simdata->rate, task, sizeof(void *), match_fun, NULL, match_data, 0);
   t_simdata->comm = comm->s_comm; /* FIXME: is the field t_simdata->comm still useful? */
+#ifdef HAVE_TRACING
+    if (TRACE_is_enabled()) {
+      simcall_set_category(comm->s_comm, task->category);
+    }
+#endif
+
+#ifdef HAVE_TRACING
+  if (call_end)
+    TRACE_msg_task_put_end();
+#endif
 
   return comm;
 }
@@ -344,8 +356,6 @@ void MSG_task_dsend(msg_task_t task, const char *alias, void_f_pvoid_t cleanup)
   msg_process_t process = MSG_process_self();
   msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
 
-  /* FIXME: these functions are not traceable */
-
   /* Prepare the task to send */
   t_simdata = task->simdata;
   t_simdata->sender = process;
@@ -358,10 +368,24 @@ void MSG_task_dsend(msg_task_t task, const char *alias, void_f_pvoid_t cleanup)
   t_simdata->comm = NULL;
   msg_global->sent_msg++;
 
+#ifdef HAVE_TRACING
+  int call_end = TRACE_msg_task_put_start(task);
+#endif
+
   /* Send it by calling SIMIX network layer */
   smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size,
                        t_simdata->rate, task, sizeof(void *), NULL, cleanup, NULL, 1);
   t_simdata->comm = comm;
+#ifdef HAVE_TRACING
+    if (TRACE_is_enabled()) {
+      simcall_set_category(comm, task->category);
+    }
+#endif
+
+#ifdef HAVE_TRACING
+  if (call_end)
+    TRACE_msg_task_put_end();
+#endif
 }
 
 /** \ingroup msg_task_usage
@@ -813,6 +837,42 @@ const char *MSG_task_get_category (msg_task_t task)
 #endif
 }
 
+/**
+ * \brief Returns the value of a given AS or router property
+ *
+ * \param asr the name of a router or AS
+ * \param name a property name
+ * \return value of a property (or NULL if property not set)
+ */
+const char *MSG_as_router_get_property_value(const char* asr, const char *name)
+{
+  return xbt_dict_get_or_null(MSG_as_router_get_properties(asr), name);
+}
+
+/**
+ * \brief Returns a xbt_dict_t consisting of the list of properties assigned to
+ * a the AS or router
+ *
+ * \param asr the name of a router or AS
+ * \return a dict containing the properties
+ */
+xbt_dict_t MSG_as_router_get_properties(const char* asr)
+{
+  return (simcall_asr_get_properties(asr));
+}
+
+/**
+ * \brief Change the value of a given AS or router
+ *
+ * \param asr the name of a router or AS
+ * \param name a property name
+ * \param value what to change the property to
+ * \param free_ctn the freeing function to use to kill the value on need
+ */
+void MSG_as_router_set_property_value(const char* asr, const char *name, char *value,void_f_pvoid_t free_ctn) {
+  xbt_dict_set(MSG_as_router_get_properties(asr), name, value,free_ctn);
+}
+
 #ifdef MSG_USE_DEPRECATED
 /** \ingroup msg_deprecated_functions
  *
index 53e1ac5..73eb35a 100644 (file)
@@ -131,12 +131,12 @@ void __MSG_host_destroy(msg_host_t host) {
   free(host);
 }
 
-#ifdef MSG_USE_DEPRECATED
 int MSG_get_host_number(void)
 {
   return xbt_lib_length(host_lib);
 }
 
+#ifdef MSG_USE_DEPRECATED
 msg_host_t *MSG_get_host_table(void)
 {
       void **array;
@@ -211,7 +211,7 @@ const char *MSG_host_get_property_value(msg_host_t host, const char *name)
 }
 
 /** \ingroup m_host_management
- * \brief Returns a xbt_dynar_t consisting of the list of properties assigned to this host
+ * \brief Returns a xbt_dict_t consisting of the list of properties assigned to this host
  *
  * \param host a host
  * \return a dict containing the properties
index 3774f1e..1932908 100644 (file)
@@ -81,7 +81,11 @@ msg_file_t MSG_file_open(const char* mount, const char* path, const char* mode)
  */
 int MSG_file_close(msg_file_t fp)
 {
-  return simcall_file_close(fp->simdata->smx_file);
+  int res = simcall_file_close(fp->simdata->smx_file);
+  free(fp->name);
+  xbt_free(fp->simdata);
+  xbt_free(fp);
+  return res;
 }
 
 /** \ingroup msg_file_management
@@ -97,3 +101,56 @@ int MSG_file_stat(msg_file_t fd, s_msg_stat_t *buf)
   res = simcall_file_stat(fd->simdata->smx_file, buf);
   return res;
 }
+
+/** \ingroup msg_file_management
+ * \brief Free the stat structure
+ *
+ * \param stat the #s_msg_stat_t to free
+ */
+void MSG_file_free_stat(s_msg_stat_t *stat)
+{
+  free(stat->date);
+  free(stat->group);
+  free(stat->time);
+  free(stat->user);
+  free(stat->user_rights);
+}
+
+/** \ingroup msg_file_management
+ * \brief Unlink the file pointed by fd
+ *
+ * \param fd is the file descriptor (#msg_file_t)
+ * \return 0 on success or 1 on error
+ */
+int MSG_file_unlink(msg_file_t fd)
+{
+  int res = simcall_file_unlink(fd->simdata->smx_file);
+  free(fd->name);
+  xbt_free(fd->simdata);
+  xbt_free(fd);
+  return res;
+}
+
+/** \ingroup msg_file_management
+ * \brief Search for file
+ *
+ * \param mount is the mount point where find the file is located
+ * \param path the file regex to find
+ * \return a xbt_dict_t of file where key is the name of file and the
+ * value the msg_stat_t corresponding to the key
+ */
+xbt_dict_t MSG_file_ls(const char *mount, const char *path)
+{
+  xbt_assert(path,"You must set path");
+  int size = strlen(path);
+  if(size && path[size-1] != '/')
+  {
+    char *new_path = bprintf("%s/",path);
+    XBT_DEBUG("Change '%s' for '%s'",path,new_path);
+    xbt_dict_t dict = simcall_file_ls(mount, new_path);
+    xbt_free(new_path);
+    return dict;
+  }
+
+  return simcall_file_ls(mount, path);
+}
index 8d1e7c9..984df9d 100644 (file)
@@ -56,6 +56,14 @@ msg_mailbox_t MSG_mailbox_get_by_alias(const char *alias)
   return mailbox;
 }
 
+void MSG_mailbox_set_async(const char *alias){
+  msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
+
+  simcall_rdv_set_receiver(mailbox, SIMIX_process_self());
+  XBT_VERB("%s mailbox set to receive eagerly for process %p\n",alias, SIMIX_process_self());
+
+}
+
 msg_error_t
 MSG_mailbox_get_task_ext(msg_mailbox_t mailbox, msg_task_t * task,
                          msg_host_t host, double timeout)
index ded6199..9f3f379 100644 (file)
@@ -66,6 +66,19 @@ XBT_PUBLIC(msg_mailbox_t)
  */
 XBT_PUBLIC(int) MSG_mailbox_is_empty(msg_mailbox_t mailbox);
 
+/* \brief MSG_mailbox_set_async - set a mailbox as eager
+ *
+ * The function MSG_mailbox_set_async sets the mailbox to a permanent receiver mode
+ * Messages sent to this mailbox will then be sent just after the send is issued,
+ * without waiting for the corresponding receive.
+ *
+ * This call should be done before issuing any receive, and on the receiver's side only
+ *
+ * \param alias    The alias of the mailbox to modify.
+ *
+ */
+void MSG_mailbox_set_async(const char *alias);
+
 /*! \brief MSG_mailbox_get_head - get the task at the head of a mailbox.
  *
  * The MSG_mailbox_get_head returns the task at the head of the mailbox.
index d5a93f6..165371c 100644 (file)
@@ -16,7 +16,6 @@
 #include "xbt/dict.h"
 #include "xbt/config.h"
 #include "instr/instr_private.h"
-
 SG_BEGIN_DECL()
 
 /**************** datatypes **********************************/
@@ -154,5 +153,7 @@ void MSG_comm_copy_data_from_SIMIX(smx_action_t comm, void* buff, size_t buff_si
 void _MSG_action_init(void);
 void _MSG_action_exit(void);
 
+void MSG_post_create_environment(void);
+
 SG_END_DECL()
 #endif
index 9b8a842..8c318c5 100644 (file)
@@ -179,7 +179,7 @@ msg_process_t MSG_process_create_with_environment(const char *name,
 
 #ifdef HAVE_TRACING
   TRACE_msg_process_create(name, simdata->PID, simdata->m_host);
-  #endif
+#endif
   /* Let's create the process: SIMIX may decide to start it right now,
    * even before returning the flow control to us */
   simcall_process_create(&process, name, code, simdata, SIMIX_host_get_name(host->smx_host), -1,
index c51d5f2..c4dc318 100644 (file)
@@ -1440,6 +1440,11 @@ void SD_task_schedulev(SD_task_t task, int count,
     xbt_assert(task->workstation_nb == count,"Got %d locations, but were expecting %d locations",count,task->workstation_nb);
     for (i = 0; i < count; i++)
       task->workstation_list[i] = list[i];
+    if (SD_task_get_kind(task)== SD_TASK_COMP_SEQ && !task->computation_amount){
+      /*This task has failed and is rescheduled. Reset the computation amount*/
+      task->computation_amount = xbt_new0(double, 1);
+      task->computation_amount[0] = task->remains;
+    }
     SD_task_do_schedule(task);
     break;
   default:
index 7a163ef..1be8d28 100644 (file)
@@ -7,6 +7,7 @@
 #include "private.h"
 #include "simdag/simdag.h"
 #include "xbt/dict.h"
+#include "xbt/lib.h"
 #include "xbt/sysdep.h"
 #include "surf/surf.h"
 #include "surf/surf_resource.h"
@@ -157,6 +158,7 @@ xbt_dict_t SD_workstation_get_properties(SD_workstation_t workstation)
 
 }
 
+
 /** @brief Displays debugging informations about a workstation */
 void SD_workstation_dump(SD_workstation_t ws)
 {
@@ -512,3 +514,29 @@ SD_task_t SD_workstation_get_current_task(SD_workstation_t workstation)
 
   return (workstation->current_task);
 }
+
+/**
+ * \brief Returns a #xbt_dict_t consisting of the list of properties assigned to the AS
+ * or router
+ *
+ * \param AS, router name
+ * \return the xbt_dict_t properties of the AS
+ */
+xbt_dict_t SD_as_router_get_properties(const char *asr)
+{
+  return get_as_router_properties(asr);
+}
+/**
+ * \brief Returns a #xbt_dict_t consisting of the list of properties assigned to the AS
+ * or router
+ *
+ * \param AS, router name
+ * \param The name of a properties
+ * \return value of the properties
+ */
+const char* SD_as_router_get_property_value(const char *asr, const char *name)
+{
+  xbt_dict_t dict = get_as_router_properties(asr);
+  if(!dict) return NULL;
+  return xbt_dict_get_or_null(dict,name);
+}
index fa653a7..2b94104 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "smx_private.h"
 #include "xbt/parmap.h"
+#include "mc/mc.h"
 
 #ifdef HAVE_VALGRIND_VALGRIND_H
 #  include <valgrind/valgrind.h>
@@ -23,7 +24,7 @@ typedef struct s_smx_ctx_raw {
 #ifdef HAVE_VALGRIND_VALGRIND_H
   unsigned int valgrind_stack_id; /* the valgrind stack id */
 #endif
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   unsigned int thread;            /* Just for measuring purposes */
 #endif
 } s_smx_ctx_raw_t, *smx_ctx_raw_t;
@@ -192,7 +193,7 @@ void raw_swapcontext(raw_stack_t* old, raw_stack_t new) {
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
 
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
 #include "xbt/xbt_os_time.h"
 #define NUM_THREADS 4
 static xbt_os_timer_t timer;
@@ -226,6 +227,12 @@ static void smx_ctx_raw_runall(void);
  */
 void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
 {
+
+  if(MC_IS_ENABLED && mmalloc_ignore == NULL){
+    /* Create list of elements to ignore for heap comparison algorithm */
+    MC_ignore_init();
+  }
+
   XBT_VERB("Using raw contexts. Because the glibc is just not good enough for us.");
   smx_ctx_base_factory_init(factory);
 
@@ -259,7 +266,7 @@ void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
     (*factory)->runall = smx_ctx_raw_runall_serial;
     (*factory)->suspend = smx_ctx_raw_suspend_serial;
   }
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   timer = xbt_os_timer_new();
 #endif
 }
@@ -270,7 +277,7 @@ void SIMIX_ctx_raw_factory_init(smx_context_factory_t *factory)
  */
 static int smx_ctx_raw_factory_finalize(smx_context_factory_t *factory)
 {
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   XBT_CRITICAL("Total wasted time in %u SR: %lf", sr_count, time_wasted_sr);
   XBT_CRITICAL("Total wasted time in %u SSR: %lf", ssr_count, time_wasted_ssr);
 #endif
@@ -324,6 +331,10 @@ smx_ctx_raw_create_context(xbt_main_func_t code, int argc, char **argv,
 
      } else {
        raw_maestro_context = context;
+
+       if(MC_IS_ENABLED)
+         MC_ignore(&(raw_maestro_context->stack_top), sizeof(raw_maestro_context->stack_top));
+
      }
 
      return (smx_context_t) context;
@@ -410,7 +421,7 @@ static void smx_ctx_raw_resume_serial(smx_process_t first_process)
       ((smx_ctx_raw_t) context)->stack_top);
 }
 
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
 static void smx_ctx_raw_runall_serial(xbt_dynar_t processes)
 {
   smx_process_t process;
index a25155a..5cb246b 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_deployment, simix,
                                 "Logging specific to SIMIX (deployment)");
-static int parse_argc = -1;
-static char **parse_argv = NULL;
+
 static xbt_main_func_t parse_code = NULL;
-static char *parse_host = NULL;
 static double start_time = 0.0;
 static double kill_time = -1.0;
 
@@ -23,42 +21,29 @@ static int auto_restart = 0;
 
 extern int surf_parse_lineno;
 
-static void parse_process_init(void)
+static void parse_process(sg_platf_process_cbarg_t process)
 {
-  smx_host_t host = SIMIX_host_get_by_name(A_surfxml_process_host);
+  smx_host_t host = SIMIX_host_get_by_name(process->host);
   if (!host)
-    THROWF(arg_error, 0, "Host '%s' unknown", A_surfxml_process_host);
-  parse_host = host->name;
-  parse_code = SIMIX_get_registered_function(A_surfxml_process_function);
-  xbt_assert(parse_code, "Function '%s' unknown",
-              A_surfxml_process_function);
-  parse_argv = xbt_new(char *, 2);
-  parse_argv[0] = xbt_strdup(A_surfxml_process_function);
-  parse_argc = 1;
-  start_time = surf_parse_get_double(A_surfxml_process_start_time);
-  kill_time  = surf_parse_get_double(A_surfxml_process_kill_time);
-  auto_restart = A_surfxml_process_on_failure == A_surfxml_process_on_failure_DIE ? 0 : 1;
-}
-static void parse_argument(void)
-{
-  parse_argv = xbt_realloc(parse_argv, (parse_argc + 2) * sizeof(char *));
-  parse_argv[parse_argc++] = xbt_strdup(A_surfxml_argument_value);
-}
+    THROWF(arg_error, 0, "Host '%s' unknown", process->host);
+  parse_code = SIMIX_get_registered_function(process->function);
+  xbt_assert(parse_code, "Function '%s' unknown", process->function);
+
+  start_time = process->start_time;
+  kill_time  = process->kill_time;
+  auto_restart = process->on_failure == SURF_PROCESS_ON_FAILURE_DIE ? 0 : 1;
 
-static void parse_process_finalize(void)
-{
   smx_process_arg_t arg = NULL;
-  smx_process_t process = NULL;
-  parse_argv[parse_argc] = NULL;
+  smx_process_t process_created = NULL;
 
   if (start_time > SIMIX_get_clock()) {
     arg = xbt_new0(s_smx_process_arg_t, 1);
-    arg->name = parse_argv[0];
+    arg->name = (char*)(process->argv)[0];
     arg->code = parse_code;
     arg->data = NULL;
-    arg->hostname = parse_host;
-    arg->argc = parse_argc;
-    arg->argv = parse_argv;
+    arg->hostname = host->name;
+    arg->argc = process->argc;
+    arg->argv = (char**)(process->argv);
     arg->kill_time = kill_time;
     arg->properties = current_property_set;
 
@@ -66,25 +51,25 @@ static void parse_process_finalize(void)
            arg->hostname, start_time);
     SIMIX_timer_set(start_time, &SIMIX_process_create_from_wrapper, arg);
   } else {                      // start_time <= SIMIX_get_clock()
-    XBT_DEBUG("Starting Process %s(%s) right now", parse_argv[0], parse_host);
+    XBT_DEBUG("Starting Process %s(%s) right now", process->argv[0], host->name);
 
     if (simix_global->create_process_function)
-      simix_global->create_process_function(&process,
-                                            parse_argv[0],
+      simix_global->create_process_function(&process_created,
+                                            (char*)(process->argv)[0],
                                             parse_code,
                                             NULL,
-                                            parse_host,
+                                            host->name,
                                             kill_time,
-                                            parse_argc,
-                                            parse_argv,
+                                            process->argc,
+                                            (char**)(process->argv),
                                             current_property_set,
                                             auto_restart);
     else
-      simcall_process_create(&process, parse_argv[0], parse_code, NULL, parse_host, kill_time, parse_argc, parse_argv,
-                               current_property_set,auto_restart);
+      simcall_process_create(&process_created, (char*)(process->argv)[0], parse_code, NULL, host->name, kill_time, process->argc,
+          (char**)process->argv, current_property_set,auto_restart);
 
     /* verify if process has been created (won't be the case if the host is currently dead, but that's fine) */
-    if (!process) {
+    if (!process_created) {
       return;
     }
   }
@@ -115,11 +100,7 @@ void SIMIX_launch_application(const char *file)
 
   surf_parse_reset_callbacks();
 
-  surfxml_add_callback(STag_surfxml_process_cb_list, parse_process_init);
-  surfxml_add_callback(ETag_surfxml_argument_cb_list, parse_argument);
-  surfxml_add_callback(STag_surfxml_prop_cb_list, parse_properties);
-  surfxml_add_callback(ETag_surfxml_process_cb_list,
-                       parse_process_finalize);
+  sg_platf_process_add_cb(parse_process);
 
   surf_parse_open(file);
   TRY {
@@ -127,8 +108,9 @@ void SIMIX_launch_application(const char *file)
     surf_parse_close();
     xbt_assert(!parse_status, "Parse error at %s:%d", file,surf_parse_lineno);
   } CATCH(e) {
-    xbt_die("Unrecoverable error at %s:%d: %s",
-                  file, surf_parse_lineno, e.msg);
+    XBT_ERROR("Unrecoverable error at %s:%d. The full exception stack follows, in case it helps you to diagnose the problem.",
+        file, surf_parse_lineno);
+    RETHROW;
   }
 }
 
@@ -193,30 +175,34 @@ void SIMIX_process_set_function(const char *process_host,
                                 double process_start_time,
                                 double process_kill_time)
 {
-  unsigned int i;
-  char *arg;
+  s_sg_platf_process_cbarg_t process;
+  memset(&process,0,sizeof(process));
 
-  /* init process */
   smx_host_t host = SIMIX_host_get_by_name(process_host);
   if (!host)
     THROWF(arg_error, 0, "Host '%s' unknown", process_host);
-  parse_host = host->name;
-  parse_code = SIMIX_get_registered_function(process_function);
-  xbt_assert(parse_code, "Function '%s' unknown", process_function);
-
-  parse_argc = 1 + xbt_dynar_length(arguments);
-  parse_argv = xbt_new(char *, parse_argc + 1);
-  parse_argv[0] = xbt_strdup(process_function);
+  process.host = host->name;
 
+  process.argc = 1 + xbt_dynar_length(arguments);
+  process.argv = (const char**)xbt_new(char *, process.argc + 1);
+  process.argv[0] = xbt_strdup(process_function);
   /* add arguments */
+  unsigned int i;
+  char *arg;
   xbt_dynar_foreach(arguments, i, arg) {
-    parse_argv[i + 1] = xbt_strdup(arg);
+    process.argv[i + 1] = xbt_strdup(arg);
   }
-  parse_argv[parse_argc] = NULL;
+  process.argv[process.argc] = NULL;
+
+  parse_code = SIMIX_get_registered_function(process_function);
+  xbt_assert(parse_code, "Function '%s' unknown", process_function);
+  process.function = process_function;
 
-  start_time = process_start_time;
-  kill_time = process_kill_time;
+  process.host = process_host;
+  process.kill_time = process_kill_time;
+  process.start_time = process_start_time;
+  process.on_failure = SURF_PROCESS_ON_FAILURE_DIE;
+  process.properties = NULL;
 
-  /* finalize */
-  parse_process_finalize();
+  sg_platf_new_process(&process);
 }
index 76c1e32..dd4709a 100644 (file)
@@ -33,10 +33,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_environment, simix,
  */
 void SIMIX_create_environment(const char *file)
 {
-  xbt_lib_cursor_t cursor = NULL;
-  char *name = NULL;
-  void **workstation = NULL;
-
   double start, end;
 
   start = xbt_os_time();
@@ -44,6 +40,14 @@ void SIMIX_create_environment(const char *file)
   end = xbt_os_time();
   XBT_DEBUG("PARSE TIME: %lg", (end - start));
 
+}
+
+void SIMIX_post_create_environment(void) {
+
+  void **workstation = NULL;
+  xbt_lib_cursor_t cursor = NULL;
+  char *name = NULL;
+
   xbt_lib_foreach(host_lib, cursor, name, workstation) {
     if(workstation[SURF_WKS_LEVEL])
       SIMIX_host_create(name, workstation[SURF_WKS_LEVEL], NULL);
index 52c0aca..6133fcf 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2007-2012. 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. */
@@ -23,8 +22,6 @@ static void* SIMIX_action_mallocator_new_f(void);
 static void SIMIX_action_mallocator_free_f(void* action);
 static void SIMIX_action_mallocator_reset_f(void* action);
 
-extern void smx_ctx_raw_new_sr(void);
-
 /* FIXME: Yeah, I'll do it in a portable maner one day [Mt] */
 #include <signal.h>
 
@@ -62,6 +59,11 @@ void SIMIX_global_init(int *argc, char **argv)
   if (!simix_global) {
     simix_global = xbt_new0(s_smx_global_t, 1);
 
+#ifdef TIME_BENCH_AMDAHL
+    simix_global->timer_seq = xbt_os_timer_new();
+    simix_global->timer_par = xbt_os_timer_new();
+    xbt_os_timer_start(simix_global->timer_seq);
+#endif
     simix_global->process_to_run = xbt_dynar_new(sizeof(smx_process_t), NULL);
     simix_global->process_that_ran = xbt_dynar_new(sizeof(smx_process_t), NULL);
     simix_global->process_list =
@@ -93,6 +95,11 @@ void SIMIX_global_init(int *argc, char **argv)
 
     /* Prepare to display some more info when dying on Ctrl-C pressing */
     signal(SIGINT, inthandler);
+
+    /* register a function to be called by SURF after the environment creation */
+    sg_platf_init();
+    sg_platf_postparse_add_cb(SIMIX_post_create_environment);
+
   }
   if (!simix_timers) {
     simix_timers = xbt_heap_new(8, &free);
@@ -110,7 +117,7 @@ void SIMIX_global_init(int *argc, char **argv)
  */
 void SIMIX_clean(void)
 {
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
   smx_ctx_raw_new_sr();
 #endif
 
@@ -146,6 +153,15 @@ void SIMIX_clean(void)
 
   surf_exit();
 
+#ifdef TIME_BENCH_AMDAHL
+  xbt_os_timer_stop(simix_global->timer_seq);
+  XBT_INFO("Amdhal timing informations. Sequential time: %lf; Parallel time: %lf",
+           xbt_os_timer_elapsed(simix_global->timer_seq),
+           xbt_os_timer_elapsed(simix_global->timer_par));
+  xbt_os_timer_free(simix_global->timer_seq);
+  xbt_os_timer_free(simix_global->timer_par);
+#endif
+
   xbt_mallocator_free(simix_global->action_mallocator);
   xbt_free(simix_global);
   simix_global = NULL;
@@ -199,7 +215,7 @@ void SIMIX_run(void)
   do {
     XBT_DEBUG("New Schedule Round; size(queue)=%lu",
         xbt_dynar_length(simix_global->process_to_run));
-#ifdef TIME_BENCH
+#ifdef TIME_BENCH_PER_SR
     smx_ctx_raw_new_sr();
 #endif
     while (!xbt_dynar_is_empty(simix_global->process_to_run)) {
@@ -207,7 +223,15 @@ void SIMIX_run(void)
               xbt_dynar_length(simix_global->process_to_run));
 
       /* Run all processes that are ready to run, possibly in parallel */
+#ifdef TIME_BENCH_AMDAHL
+      xbt_os_timer_stop(simix_global->timer_seq);
+      xbt_os_timer_resume(simix_global->timer_par);
+#endif
       SIMIX_process_runall();
+#ifdef TIME_BENCH_AMDAHL
+      xbt_os_timer_stop(simix_global->timer_par);
+      xbt_os_timer_resume(simix_global->timer_seq);
+#endif
 
       /* Move all killing processes to the end of the list, because killing a process that have an ongoing simcall is a bad idea */
       xbt_dynar_three_way_partition(simix_global->process_that_ran, process_syscall_color);
@@ -453,3 +477,9 @@ static void SIMIX_action_mallocator_reset_f(void* action) {
   memset(action, 0, sizeof(s_smx_action_t));
   ((smx_action_t) action)->simcalls = fifo;
 }
+
+xbt_dict_t SIMIX_asr_get_properties(const char *name)
+{
+  return xbt_lib_get_or_null(as_router_lib, name, ROUTING_PROP_ASR_LEVEL);
+}
+
index 33424c6..23aa928 100644 (file)
@@ -207,10 +207,94 @@ smx_action_t SIMIX_file_stat(smx_process_t process, smx_file_t fd, s_file_stat_t
   return action;
 }
 
+//SIMIX FILE UNLINK
+void SIMIX_pre_file_unlink(smx_simcall_t simcall)
+{
+  smx_action_t action = SIMIX_file_unlink(simcall->issuer,
+      simcall->file_unlink.fd);
+  xbt_fifo_push(action->simcalls, simcall);
+  simcall->issuer->waiting_action = action;
+}
+
+smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
+{
+  smx_action_t action;
+  smx_host_t host = process->smx_host;
+  /* check if the host is active */
+  if (surf_workstation_model->extension.
+      workstation.get_state(host->host) != SURF_RESOURCE_ON) {
+    THROWF(host_error, 0, "Host %s failed, you cannot call this function",
+           host->name);
+  }
+
+  action = xbt_mallocator_get(simix_global->action_mallocator);
+  action->type = SIMIX_ACTION_IO;
+  action->name = NULL;
+#ifdef HAVE_TRACING
+  action->category = NULL;
+#endif
+
+  action->io.host = host;
+  action->io.surf_io = surf_workstation_model->extension.workstation.unlink(host->host, fd->surf_file);
+
+  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  XBT_DEBUG("Create io action %p", action);
+
+  return action;
+}
+
+//SIMIX FILE LS
+void SIMIX_pre_file_ls(smx_simcall_t simcall)
+{
+  smx_action_t action = SIMIX_file_ls(simcall->issuer,
+      simcall->file_ls.mount, simcall->file_ls.path);
+  xbt_fifo_push(action->simcalls, simcall);
+  simcall->issuer->waiting_action = action;
+}
+smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char *path)
+{
+  smx_action_t action;
+  smx_host_t host = process->smx_host;
+  /* check if the host is active */
+  if (surf_workstation_model->extension.workstation.get_state(host->host) != SURF_RESOURCE_ON) {
+    THROWF(host_error, 0, "Host %s failed, you cannot call this function",
+           host->name);
+  }
+
+  action = xbt_mallocator_get(simix_global->action_mallocator);
+  action->type = SIMIX_ACTION_IO;
+  action->name = NULL;
+#ifdef HAVE_TRACING
+  action->category = NULL;
+#endif
+
+  action->io.host = host;
+  action->io.surf_io = surf_workstation_model->extension.workstation.ls(host->host,mount,path);
+
+  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  XBT_DEBUG("Create io action %p", action);
+  return action;
+}
+
+static void free_file_stat(void *p)
+{
+  file_stat_t fs = p;
+  xbt_free(fs->date);
+  xbt_free(fs->group);
+  xbt_free(fs->time);
+  xbt_free(fs->user);
+  xbt_free(fs->user_rights);
+  xbt_free(fs);
+}
+
 void SIMIX_post_io(smx_action_t action)
 {
   xbt_fifo_item_t i;
   smx_simcall_t simcall;
+  char* key;
+  xbt_dict_cursor_t cursor = NULL;
+  s_file_stat_t *dst = NULL;
+  s_file_stat_t *src = NULL;
 
   xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) {
     switch (simcall->call) {
@@ -218,21 +302,44 @@ void SIMIX_post_io(smx_action_t action)
       simcall->file_open.result = xbt_new(s_smx_file_t,1);
       simcall->file_open.result->surf_file = (action->io.surf_io)->file;
       break;
+
     case SIMCALL_FILE_CLOSE:
-      simcall->file_read.result = 0;
+      xbt_free(simcall->file_close.fp);
+      simcall->file_close.result = 0;
       break;
+
     case SIMCALL_FILE_WRITE:
       simcall->file_write.result = (action->io.surf_io)->cost;
       break;
+
     case SIMCALL_FILE_READ:
       simcall->file_read.result = (action->io.surf_io)->cost;
       break;
+
     case SIMCALL_FILE_STAT:
       simcall->file_stat.result = 0;
-      s_file_stat_t *dst = &(simcall->file_stat.buf);
-      s_file_stat_t *src = &((action->io.surf_io)->stat);
+      dst = &(simcall->file_stat.buf);
+      src = &((action->io.surf_io)->stat);
       file_stat_copy(src,dst);
       break;
+
+    case SIMCALL_FILE_UNLINK:
+      xbt_free(simcall->file_unlink.fd);
+      simcall->file_unlink.result = 0;
+      break;
+
+    case SIMCALL_FILE_LS:
+      xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
+        // if there is a stat we have to duplicate it
+        if(src){
+          dst = xbt_new0(s_file_stat_t,1);
+          file_stat_copy(src, dst);
+          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,free_file_stat);
+        }
+      }
+      simcall->file_ls.result = (action->io.surf_io)->ls_dict;
+      break;
+
     default:
       break;
     }
index c457a02..b7df26c 100644 (file)
@@ -15,12 +15,16 @@ void SIMIX_pre_file_write(smx_simcall_t simcall);
 void SIMIX_pre_file_open(smx_simcall_t simcall);
 void SIMIX_pre_file_close(smx_simcall_t simcall);
 void SIMIX_pre_file_stat(smx_simcall_t simcall);
+void SIMIX_pre_file_unlink(smx_simcall_t simcall);
+void SIMIX_pre_file_ls(smx_simcall_t simcall);
 
 smx_action_t SIMIX_file_read(smx_process_t process, void* ptr, size_t size, size_t nmemb, smx_file_t stream);
 smx_action_t SIMIX_file_write(smx_process_t process, const void* ptr, size_t size, size_t nmemb, smx_file_t stream);
 smx_action_t SIMIX_file_open(smx_process_t process, const char* storage, const char* path, const char* mode);
 smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fp);
 smx_action_t SIMIX_file_stat(smx_process_t process, smx_file_t fd, s_file_stat_t buf);
+smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd);
+smx_action_t SIMIX_file_ls(smx_process_t process, const char *mount, const char *path);
 
 void SIMIX_post_io(smx_action_t action);
 void SIMIX_io_destroy(smx_action_t action);
index c72e0af..93921fb 100644 (file)
@@ -19,9 +19,12 @@ static void SIMIX_waitany_remove_simcall_from_actions(smx_simcall_t simcall);
 static void SIMIX_comm_copy_data(smx_action_t comm);
 static smx_action_t SIMIX_comm_new(e_smx_comm_type_t type);
 static XBT_INLINE void SIMIX_rdv_push(smx_rdv_t rdv, smx_action_t comm);
-static smx_action_t SIMIX_rdv_get_comm(smx_rdv_t rdv, e_smx_comm_type_t type,
-            int (*match_fun)(void *, void *,smx_action_t),
-            void *user_data, smx_action_t my_action);
+static smx_action_t SIMIX_fifo_probe_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
+                                        int (*match_fun)(void *, void *,smx_action_t),
+                                        void *user_data, smx_action_t my_action);
+static smx_action_t SIMIX_fifo_get_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
+                                        int (*match_fun)(void *, void *,smx_action_t),
+                                        void *user_data, smx_action_t my_action);
 static void SIMIX_rdv_free(void *data);
 
 void SIMIX_network_init(void)
@@ -47,6 +50,10 @@ smx_rdv_t SIMIX_rdv_create(const char *name)
     rdv = xbt_new0(s_smx_rvpoint_t, 1);
     rdv->name = name ? xbt_strdup(name) : NULL;
     rdv->comm_fifo = xbt_fifo_new();
+    rdv->done_comm_fifo = xbt_fifo_new();
+    rdv->permanent_receiver=NULL;
+
+    XBT_DEBUG("Creating a mailbox at %p with name %s\n", rdv, name);
 
     if (rdv->name)
       xbt_dict_set(rdv_points, rdv->name, rdv, NULL);
@@ -62,9 +69,12 @@ void SIMIX_rdv_destroy(smx_rdv_t rdv)
 
 void SIMIX_rdv_free(void *data)
 {
+  XBT_DEBUG("rdv free %p", data);
   smx_rdv_t rdv = (smx_rdv_t) data;
   xbt_free(rdv->name);
   xbt_fifo_free(rdv->comm_fifo);
+  xbt_fifo_free(rdv->done_comm_fifo);
+
   xbt_free(rdv);  
 }
 
@@ -97,6 +107,26 @@ smx_action_t SIMIX_rdv_get_head(smx_rdv_t rdv)
   return xbt_fifo_get_item_content(xbt_fifo_get_first_item(rdv->comm_fifo));
 }
 
+/**
+ *  \brief get the receiver (process associated to the mailbox)
+ *  \param rdv The rendez-vous point
+ *  \return process The receiving process (NULL if not set)
+ */
+smx_process_t SIMIX_rdv_get_receiver(smx_rdv_t rdv)
+{
+  return rdv->permanent_receiver;
+}
+
+/**
+ *  \brief set the receiver of the rendez vous point to allow eager sends
+ *  \param rdv The rendez-vous point
+ *  \param process The receiving process
+ */
+void SIMIX_rdv_set_receiver(smx_rdv_t rdv , smx_process_t process)
+{
+  rdv->permanent_receiver=process;
+}
+
 /**
  *  \brief Pushes a communication action into a rendez-vous point
  *  \param rdv The rendez-vous point
@@ -120,19 +150,19 @@ XBT_INLINE void SIMIX_rdv_remove(smx_rdv_t rdv, smx_action_t comm)
 }
 
 /**
- *  \brief Checks if there is a communication action queued in a rendez-vous matching our needs
+ *  \brief Checks if there is a communication action queued in a fifo matching our needs
  *  \param type The type of communication we are looking for (comm_send, comm_recv)
  *  \return The communication action if found, NULL otherwise
  */
-smx_action_t SIMIX_rdv_get_comm(smx_rdv_t rdv, e_smx_comm_type_t type,
-                                   int (*match_fun)(void *, void *,smx_action_t),
-                                   void *this_user_data, smx_action_t my_action)
+smx_action_t SIMIX_fifo_get_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
+                                 int (*match_fun)(void *, void *,smx_action_t),
+                                 void *this_user_data, smx_action_t my_action)
 {
   smx_action_t action;
   xbt_fifo_item_t item;
   void* other_user_data = NULL;
 
-  xbt_fifo_foreach(rdv->comm_fifo, item, action, smx_action_t) {
+  xbt_fifo_foreach(fifo, item, action, smx_action_t) {
     if (action->comm.type == SIMIX_COMM_SEND) {
       other_user_data = action->comm.src_data;
     } else if (action->comm.type == SIMIX_COMM_RECEIVE) {
@@ -142,21 +172,55 @@ smx_action_t SIMIX_rdv_get_comm(smx_rdv_t rdv, e_smx_comm_type_t type,
         (!match_fun              ||              match_fun(this_user_data,  other_user_data, action)) &&
         (!action->comm.match_fun || action->comm.match_fun(other_user_data, this_user_data,  my_action))) {
       XBT_DEBUG("Found a matching communication action %p", action);
-      xbt_fifo_remove_item(rdv->comm_fifo, item);
+      xbt_fifo_remove_item(fifo, item);
       xbt_fifo_free_item(item);
       action->comm.refcount++;
       action->comm.rdv = NULL;
       return action;
     }
     XBT_DEBUG("Sorry, communication action %p does not match our needs:"
-           " its type is %d but we are looking for a comm of type %d (or maybe the filtering didn't match)",
-           action, (int)action->comm.type, (int)type);
+              " its type is %d but we are looking for a comm of type %d (or maybe the filtering didn't match)",
+              action, (int)action->comm.type, (int)type);
   }
   XBT_DEBUG("No matching communication action found");
   return NULL;
 }
 
 
+/**
+ *  \brief Checks if there is a communication action queued in a fifo matching our needs, but leave it there
+ *  \param type The type of communication we are looking for (comm_send, comm_recv)
+ *  \return The communication action if found, NULL otherwise
+ */
+smx_action_t SIMIX_fifo_probe_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
+                                 int (*match_fun)(void *, void *,smx_action_t),
+                                 void *this_user_data, smx_action_t my_action)
+{
+  smx_action_t action;
+  xbt_fifo_item_t item;
+  void* other_user_data = NULL;
+
+  xbt_fifo_foreach(fifo, item, action, smx_action_t) {
+    if (action->comm.type == SIMIX_COMM_SEND) {
+      other_user_data = action->comm.src_data;
+    } else if (action->comm.type == SIMIX_COMM_RECEIVE) {
+      other_user_data = action->comm.dst_data;
+    }
+    if (action->comm.type == type &&
+        (!match_fun              ||              match_fun(this_user_data,  other_user_data, action)) &&
+        (!action->comm.match_fun || action->comm.match_fun(other_user_data, this_user_data,  my_action))) {
+      XBT_DEBUG("Found a matching communication action %p", action);
+      action->comm.refcount++;
+
+      return action;
+    }
+    XBT_DEBUG("Sorry, communication action %p does not match our needs:"
+              " its type is %d but we are looking for a comm of type %d (or maybe the filtering didn't match)",
+              action, (int)action->comm.type, (int)type);
+  }
+  XBT_DEBUG("No matching communication action found");
+  return NULL;
+}
 /******************************************************************************/
 /*                            Communication Actions                            */
 /******************************************************************************/
@@ -213,10 +277,10 @@ void SIMIX_comm_destroy(smx_action_t action)
   if (action->comm.refcount > 0)
     return;
   XBT_DEBUG("Really free communication %p; refcount is now %d", action,
-        action->comm.refcount);
+            action->comm.refcount);
 
 #ifdef HAVE_LATENCY_BOUND_TRACKING
-    action->latency_limited = SIMIX_comm_is_latency_bounded( action ) ;
+  action->latency_limited = SIMIX_comm_is_latency_bounded( action ) ;
 #endif
 
   xbt_free(action->name);
@@ -263,6 +327,8 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
                               void *data,
                               int detached)
 {
+  XBT_DEBUG("send from %p\n", rdv);
+
   /* Prepare an action describing us, so that it gets passed to the user-provided filter of other side */
   smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_SEND);
 
@@ -270,17 +336,33 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
    * ourself so that the other side also gets a chance of choosing if it wants to match with us.
    *
    * If it is not found then push our communication into the rendez-vous point */
-  smx_action_t other_action = SIMIX_rdv_get_comm(rdv, SIMIX_COMM_RECEIVE, match_fun, data, this_action);
+  smx_action_t other_action = SIMIX_fifo_get_comm(rdv->comm_fifo, SIMIX_COMM_RECEIVE, match_fun, data, this_action);
 
   if (!other_action) {
     other_action = this_action;
-    SIMIX_rdv_push(rdv, this_action);
+
+    if (rdv->permanent_receiver!=NULL){
+      //this mailbox is for small messages, which have to be sent right now
+      other_action->state = SIMIX_READY;
+      other_action->comm.dst_proc=rdv->permanent_receiver;
+      other_action->comm.refcount++;
+      other_action->comm.rdv = rdv;
+      xbt_fifo_push(rdv->done_comm_fifo,other_action);
+      other_action->comm.rdv=rdv;
+      XBT_DEBUG("pushing a message into the permanent receive fifo %p, comm %p \n", rdv, &(other_action->comm));
+
+    }else{
+      SIMIX_rdv_push(rdv, this_action);
+    }
   } else {
+    XBT_DEBUG("Receive already pushed\n");
+
     SIMIX_comm_destroy(this_action);
     --smx_total_comms; // this creation was a pure waste
 
     other_action->state = SIMIX_READY;
     other_action->comm.type = SIMIX_COMM_READY;
+
   }
   xbt_fifo_push(src_proc->comms, other_action);
 
@@ -314,29 +396,66 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
 }
 
 smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
-                      void *dst_buff, size_t *dst_buff_size,
-                      int (*match_fun)(void *, void *, smx_action_t), void *data)
+                              void *dst_buff, size_t *dst_buff_size,
+                              int (*match_fun)(void *, void *, smx_action_t), void *data)
 {
-  /* Prepare an action describing us, so that it gets passed to the user-provided filter of other side */
+  XBT_DEBUG("recv from %p %p\n", rdv, rdv->comm_fifo);
   smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_RECEIVE);
 
-  /* Look for communication action matching our needs. We also provide a description of
-   * ourself so that the other side also gets a chance of choosing if it wants to match with us.
-   *
-   * If it is not found then push our communication into the rendez-vous point */
-  smx_action_t other_action = SIMIX_rdv_get_comm(rdv, SIMIX_COMM_SEND, match_fun, data, this_action);
-
-  if (!other_action) {
-    other_action = this_action;
-    SIMIX_rdv_push(rdv, this_action);
-  } else {
-    SIMIX_comm_destroy(this_action);
-    --smx_total_comms; // this creation was a pure waste
-
-    other_action->state = SIMIX_READY;
-    other_action->comm.type = SIMIX_COMM_READY;
+  smx_action_t other_action;
+  //communication already done, get it inside the fifo of completed comms
+  //permanent receive v1
+  //int already_received=0;
+  if(rdv->permanent_receiver && xbt_fifo_size(rdv->done_comm_fifo)!=0){
+
+    XBT_DEBUG("We have a comm that has probably already been received, trying to match it, to skip the communication\n");
+    //find a match in the already received fifo
+    other_action = SIMIX_fifo_get_comm(rdv->done_comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
+    //if not found, assume the receiver came first, register it to the mailbox in the classical way
+    if (!other_action)  {
+      XBT_DEBUG("We have messages in the permanent receive list, but not the one we are looking for, pushing request into fifo\n");
+      other_action = this_action;
+      SIMIX_rdv_push(rdv, this_action);
+    }else{
+      if(other_action->comm.surf_comm &&       SIMIX_comm_get_remains(other_action)==0.0)
+      {
+        XBT_DEBUG("comm %p has been already sent, and is finished, destroy it\n",&(other_action->comm));
+        other_action->state = SIMIX_DONE;
+        other_action->comm.type = SIMIX_COMM_DONE;
+        other_action->comm.rdv = NULL;
+        //SIMIX_comm_destroy(this_action);
+        //--smx_total_comms; // this creation was a pure waste
+        //already_received=1;
+        //other_action->comm.refcount--;
+      }/*else{
+         XBT_DEBUG("Not yet finished, we have to wait %d\n", xbt_fifo_size(rdv->comm_fifo));
+         }*/
+     // other_action->comm.refcount--;
+      SIMIX_comm_destroy(this_action);
+      --smx_total_comms; // this creation was a pure waste
+    }
+  }else{
+    /* Prepare an action describing us, so that it gets passed to the user-provided filter of other side */
+
+    /* Look for communication action matching our needs. We also provide a description of
+     * ourself so that the other side also gets a chance of choosing if it wants to match with us.
+     *
+     * If it is not found then push our communication into the rendez-vous point */
+    other_action = SIMIX_fifo_get_comm(rdv->comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
+
+    if (!other_action) {
+      XBT_DEBUG("Receive pushed first %d\n", xbt_fifo_size(rdv->comm_fifo));
+      other_action = this_action;
+      SIMIX_rdv_push(rdv, this_action);
+    } else {
+      SIMIX_comm_destroy(this_action);
+      --smx_total_comms; // this creation was a pure waste
+      other_action->state = SIMIX_READY;
+      other_action->comm.type = SIMIX_COMM_READY;
+   //   other_action->comm.refcount--;
+    }
+    xbt_fifo_push(dst_proc->comms, other_action);
   }
-  xbt_fifo_push(dst_proc->comms, other_action);
 
   /* Setup communication action */
   other_action->comm.dst_proc = dst_proc;
@@ -346,12 +465,39 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
 
   other_action->comm.match_fun = match_fun;
 
+
+  /*if(already_received)//do the actual copy, because the first one after the comm didn't have all the info
+    SIMIX_comm_copy_data(other_action);*/
+
+
   if (MC_IS_ENABLED) {
     other_action->state = SIMIX_RUNNING;
     return other_action;
   }
 
   SIMIX_comm_start(other_action);
+  // }
+  return other_action;
+}
+
+
+smx_action_t SIMIX_comm_iprobe(smx_process_t dst_proc, smx_rdv_t rdv, int src,
+                              int tag, int (*match_fun)(void *, void *, smx_action_t), void *data)
+{
+  XBT_DEBUG("iprobe from %p %p\n", rdv, rdv->comm_fifo);
+  smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_RECEIVE);
+
+  smx_action_t other_action;
+  if(rdv->permanent_receiver && xbt_fifo_size(rdv->done_comm_fifo)!=0){
+    //find a match in the already received fifo
+    other_action = SIMIX_fifo_probe_comm(rdv->done_comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
+  }else{
+    other_action = SIMIX_fifo_probe_comm(rdv->comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
+  }
+  if(other_action)other_action->comm.refcount--;
+
+  SIMIX_comm_destroy(this_action);
+  --smx_total_comms;
   return other_action;
 }
 
@@ -362,6 +508,8 @@ void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double time
   surf_action_t sleep;
 
   /* Associate this simcall to the wait action */
+  XBT_DEBUG("SIMIX_pre_comm_wait, %p", action);
+
   xbt_fifo_push(action->simcalls, simcall);
   simcall->issuer->waiting_action = action;
 
@@ -506,10 +654,10 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
     smx_host_t receiver = action->comm.dst_proc->smx_host;
 
     XBT_DEBUG("Starting communication %p from '%s' to '%s'", action,
-           SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
+              SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
 
     action->comm.surf_comm = surf_workstation_model->extension.workstation.
-        communicate(sender->host, receiver->host, action->comm.task_size, action->comm.rate);
+      communicate(sender->host, receiver->host, action->comm.task_size, action->comm.rate);
 
     surf_workstation_model->action_data_set(action->comm.surf_comm, action);
 
@@ -518,7 +666,7 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
     /* If a link is failed, detect it immediately */
     if (surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
       XBT_DEBUG("Communication from '%s' to '%s' failed to start because of a link failure",
-    SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
+                SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
       action->state = SIMIX_LINK_FAILURE;
       SIMIX_comm_destroy_internal_actions(action);
     }
@@ -531,10 +679,10 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
 
       if (SIMIX_process_is_suspended(action->comm.src_proc))
         XBT_DEBUG("The communication is suspended on startup because src (%s:%s) were suspended since it initiated the communication",
-            SIMIX_host_get_name(action->comm.src_proc->smx_host), action->comm.src_proc->name);
+                  SIMIX_host_get_name(action->comm.src_proc->smx_host), action->comm.src_proc->name);
       else
         XBT_DEBUG("The communication is suspended on startup because dst (%s:%s) were suspended since it initiated the communication",
-            SIMIX_host_get_name(action->comm.dst_proc->smx_host), action->comm.dst_proc->name);
+                  SIMIX_host_get_name(action->comm.dst_proc->smx_host), action->comm.dst_proc->name);
 
       surf_workstation_model->suspend(action->comm.surf_comm);
 
@@ -572,64 +720,64 @@ void SIMIX_comm_finish(smx_action_t action)
     /* Check out for errors */
     switch (action->state) {
 
-      case SIMIX_DONE:
-        XBT_DEBUG("Communication %p complete!", action);
-        SIMIX_comm_copy_data(action);
-        break;
+    case SIMIX_DONE:
+      XBT_DEBUG("Communication %p complete!", action);
+      SIMIX_comm_copy_data(action);
+      break;
 
-      case SIMIX_SRC_TIMEOUT:
-        SMX_EXCEPTION(simcall->issuer, timeout_error, 0,
-                  "Communication timeouted because of sender");
-        break;
+    case SIMIX_SRC_TIMEOUT:
+      SMX_EXCEPTION(simcall->issuer, timeout_error, 0,
+                    "Communication timeouted because of sender");
+      break;
 
-      case SIMIX_DST_TIMEOUT:
-        SMX_EXCEPTION(simcall->issuer, timeout_error, 0,
-                  "Communication timeouted because of receiver");
-        break;
+    case SIMIX_DST_TIMEOUT:
+      SMX_EXCEPTION(simcall->issuer, timeout_error, 0,
+                    "Communication timeouted because of receiver");
+      break;
 
-      case SIMIX_SRC_HOST_FAILURE:
-        if (simcall->issuer == action->comm.src_proc)
-          simcall->issuer->context->iwannadie = 1;
+    case SIMIX_SRC_HOST_FAILURE:
+      if (simcall->issuer == action->comm.src_proc)
+        simcall->issuer->context->iwannadie = 1;
 //          SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
-        else
-          SMX_EXCEPTION(simcall->issuer, network_error, 0, "Remote peer failed");
-        break;
+      else
+        SMX_EXCEPTION(simcall->issuer, network_error, 0, "Remote peer failed");
+      break;
 
-      case SIMIX_DST_HOST_FAILURE:
-        if (simcall->issuer == action->comm.dst_proc)
-          simcall->issuer->context->iwannadie = 1;
+    case SIMIX_DST_HOST_FAILURE:
+      if (simcall->issuer == action->comm.dst_proc)
+        simcall->issuer->context->iwannadie = 1;
 //          SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
-        else
-          SMX_EXCEPTION(simcall->issuer, network_error, 0, "Remote peer failed");
-        break;
-
-      case SIMIX_LINK_FAILURE:
-        XBT_DEBUG("Link failure in action %p between '%s' and '%s': posting an exception to the issuer: %s (%p) detached:%d",
-            action,
-            action->comm.src_proc ? action->comm.src_proc->smx_host->name : NULL,
-            action->comm.dst_proc ? action->comm.dst_proc->smx_host->name : NULL,
-            simcall->issuer->name, simcall->issuer, action->comm.detached);
-        if (action->comm.src_proc == simcall->issuer) {
-          XBT_DEBUG("I'm source");
-        } else if (action->comm.dst_proc == simcall->issuer) {
-          XBT_DEBUG("I'm dest");
-        } else {
-          XBT_DEBUG("I'm neither source nor dest");
-        }
-        SMX_EXCEPTION(simcall->issuer, network_error, 0, "Link failure");
-        break;
-
-      case SIMIX_CANCELED:
-        if (simcall->issuer == action->comm.dst_proc)
-          SMX_EXCEPTION(simcall->issuer, cancel_error, 0,
-                    "Communication canceled by the sender");
-        else
-          SMX_EXCEPTION(simcall->issuer, cancel_error, 0,
-                    "Communication canceled by the receiver");
-        break;
-
-      default:
-        xbt_die("Unexpected action state in SIMIX_comm_finish: %d", (int)action->state);
+      else
+        SMX_EXCEPTION(simcall->issuer, network_error, 0, "Remote peer failed");
+      break;
+
+    case SIMIX_LINK_FAILURE:
+      XBT_DEBUG("Link failure in action %p between '%s' and '%s': posting an exception to the issuer: %s (%p) detached:%d",
+                action,
+                action->comm.src_proc ? action->comm.src_proc->smx_host->name : NULL,
+                action->comm.dst_proc ? action->comm.dst_proc->smx_host->name : NULL,
+                simcall->issuer->name, simcall->issuer, action->comm.detached);
+      if (action->comm.src_proc == simcall->issuer) {
+        XBT_DEBUG("I'm source");
+      } else if (action->comm.dst_proc == simcall->issuer) {
+        XBT_DEBUG("I'm dest");
+      } else {
+        XBT_DEBUG("I'm neither source nor dest");
+      }
+      SMX_EXCEPTION(simcall->issuer, network_error, 0, "Link failure");
+      break;
+
+    case SIMIX_CANCELED:
+      if (simcall->issuer == action->comm.dst_proc)
+        SMX_EXCEPTION(simcall->issuer, cancel_error, 0,
+                      "Communication canceled by the sender");
+      else
+        SMX_EXCEPTION(simcall->issuer, cancel_error, 0,
+                      "Communication canceled by the receiver");
+      break;
+
+    default:
+      xbt_die("Unexpected action state in SIMIX_comm_finish: %d", (int)action->state);
     }
 
     /* if there is an exception during a waitany or a testany, indicate the position of the failed communication */
@@ -665,26 +813,26 @@ void SIMIX_post_comm(smx_action_t action)
 {
   /* Update action state */
   if (action->comm.src_timeout &&
-     surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_DONE)
-     action->state = SIMIX_SRC_TIMEOUT;
+      surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_DONE)
+    action->state = SIMIX_SRC_TIMEOUT;
   else if (action->comm.dst_timeout &&
-          surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_DONE)
-     action->state = SIMIX_DST_TIMEOUT;
+           surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_DONE)
+    action->state = SIMIX_DST_TIMEOUT;
   else if (action->comm.src_timeout &&
-          surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_FAILED)
-     action->state = SIMIX_SRC_HOST_FAILURE;
+           surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_FAILED)
+    action->state = SIMIX_SRC_HOST_FAILURE;
   else if (action->comm.dst_timeout &&
-          surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_FAILED)
-     action->state = SIMIX_DST_HOST_FAILURE;
+           surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_FAILED)
+    action->state = SIMIX_DST_HOST_FAILURE;
   else if (action->comm.surf_comm &&
-          surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+           surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
     XBT_DEBUG("Puta madre. Surf says that the link broke");
-     action->state = SIMIX_LINK_FAILURE;
+    action->state = SIMIX_LINK_FAILURE;
   } else
     action->state = SIMIX_DONE;
 
   XBT_DEBUG("SIMIX_post_comm: comm %p, state %d, src_proc %p, dst_proc %p, detached: %d",
-      action, (int)action->state, action->comm.src_proc, action->comm.dst_proc, action->comm.detached);
+            action, (int)action->state, action->comm.src_proc, action->comm.dst_proc, action->comm.detached);
 
   /* destroy the surf actions associated with the Simix communication */
   SIMIX_comm_destroy_internal_actions(action);
@@ -713,7 +861,7 @@ void SIMIX_comm_cancel(smx_action_t action)
     action->state = SIMIX_CANCELED;
   }
   else if (!MC_IS_ENABLED /* when running the MC there are no surf actions */
-      && (action->state == SIMIX_READY || action->state == SIMIX_RUNNING)) {
+           && (action->state == SIMIX_READY || action->state == SIMIX_RUNNING)) {
 
     surf_workstation_model->action_cancel(action->comm.surf_comm);
   }
@@ -747,23 +895,23 @@ double SIMIX_comm_get_remains(smx_action_t action)
   double remains;
 
   if(!action){
-      return 0;
+    return 0;
   }
 
   switch (action->state) {
 
-    case SIMIX_RUNNING:
-      remains = surf_workstation_model->get_remains(action->comm.surf_comm);
-      break;
+  case SIMIX_RUNNING:
+    remains = surf_workstation_model->get_remains(action->comm.surf_comm);
+    break;
 
-    case SIMIX_WAITING:
-    case SIMIX_READY:
-      remains = 0; /*FIXME: check what should be returned */
-      break;
+  case SIMIX_WAITING:
+  case SIMIX_READY:
+    remains = 0; /*FIXME: check what should be returned */
+    break;
 
-    default:
-      remains = 0; /*FIXME: is this correct? */
-      break;
+  default:
+    remains = 0; /*FIXME: is this correct? */
+    break;
   }
   return remains;
 }
@@ -811,12 +959,12 @@ smx_process_t SIMIX_comm_get_dst_proc(smx_action_t action)
 XBT_INLINE int SIMIX_comm_is_latency_bounded(smx_action_t action)
 {
   if(!action){
-      return 0;
+    return 0;
   }
   if (action->comm.surf_comm){
-      XBT_DEBUG("Getting latency limited for surf_action (%p)", action->comm.surf_comm);
-      action->latency_limited = surf_workstation_model->get_latency_limited(action->comm.surf_comm);
-      XBT_DEBUG("Action limited is %d", action->latency_limited);
+    XBT_DEBUG("Getting latency limited for surf_action (%p)", action->comm.surf_comm);
+    action->latency_limited = surf_workstation_model->get_latency_limited(action->comm.surf_comm);
+    XBT_DEBUG("Action limited is %d", action->latency_limited);
   }
   return action->latency_limited;
 }
@@ -826,7 +974,7 @@ XBT_INLINE int SIMIX_comm_is_latency_bounded(smx_action_t action)
 /*                    SIMIX_comm_copy_data callbacks                       */
 /******************************************************************************/
 static void (*SIMIX_comm_copy_data_callback) (smx_action_t, void*, size_t) =
-    &SIMIX_comm_copy_pointer_callback;
+  &SIMIX_comm_copy_pointer_callback;
 
 void
 SIMIX_comm_set_copy_data_callback(void (*callback) (smx_action_t, void*, size_t))
@@ -837,17 +985,11 @@ SIMIX_comm_set_copy_data_callback(void (*callback) (smx_action_t, void*, size_t)
 void SIMIX_comm_copy_pointer_callback(smx_action_t comm, void* buff, size_t buff_size)
 {
   xbt_assert((buff_size == sizeof(void *)),
-              "Cannot copy %zu bytes: must be sizeof(void*)", buff_size);
+             "Cannot copy %zu bytes: must be sizeof(void*)", buff_size);
   *(void **) (comm->comm.dst_buff) = buff;
 }
 
 void SIMIX_comm_copy_buffer_callback(smx_action_t comm, void* buff, size_t buff_size)
-{
-  XBT_DEBUG("Copy the data over");
-  memcpy(comm->comm.dst_buff, buff, buff_size);
-}
-
-void smpi_comm_copy_data_callback(smx_action_t comm, void* buff, size_t buff_size)
 {
   XBT_DEBUG("Copy the data over");
   memcpy(comm->comm.dst_buff, buff, buff_size);
@@ -857,6 +999,7 @@ void smpi_comm_copy_data_callback(smx_action_t comm, void* buff, size_t buff_siz
   }
 }
 
+
 /**
  *  \brief Copy the communication data from the sender's buffer to the receiver's one
  *  \param comm The communication
@@ -869,11 +1012,11 @@ void SIMIX_comm_copy_data(smx_action_t comm)
     return;
 
   XBT_DEBUG("Copying comm %p data from %s (%p) -> %s (%p) (%zu bytes)",
-         comm,
-         comm->comm.src_proc ? comm->comm.src_proc->smx_host->name : "a finished process",
-         comm->comm.src_buff,
-         comm->comm.dst_proc ? comm->comm.dst_proc->smx_host->name : "a finished process",
-         comm->comm.dst_buff, buff_size);
+            comm,
+            comm->comm.src_proc ? comm->comm.src_proc->smx_host->name : "a finished process",
+            comm->comm.src_buff,
+            comm->comm.dst_proc ? comm->comm.dst_proc->smx_host->name : "a finished process",
+            comm->comm.dst_buff, buff_size);
 
   /* Copy at most dst_buff_size bytes of the message to receiver's buffer */
   if (comm->comm.dst_buff_size)
index d14ec57..ee5d53b 100644 (file)
@@ -15,6 +15,8 @@ typedef struct s_smx_rvpoint {
   char *name;
   xbt_fifo_t comm_fifo;
   void *data;
+  smx_process_t permanent_receiver; //process which the mailbox is attached to
+  xbt_fifo_t done_comm_fifo;//messages already received in the permanent receive mode
 } s_smx_rvpoint_t;
 
 void SIMIX_network_init(void);
@@ -30,6 +32,8 @@ smx_rdv_t SIMIX_rdv_get_by_name(const char *name);
 void SIMIX_rdv_remove(smx_rdv_t rdv, smx_action_t comm);
 int SIMIX_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host);
 smx_action_t SIMIX_rdv_get_head(smx_rdv_t rdv);
+void SIMIX_rdv_set_receiver(smx_rdv_t rdv, smx_process_t proc);
+smx_process_t SIMIX_rdv_get_receiver(smx_rdv_t rdv);
 void SIMIX_comm_start(smx_action_t action);
 void SIMIX_comm_send(smx_process_t src_proc, smx_rdv_t rdv,
                      double task_size, double rate,
@@ -53,6 +57,8 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
 void SIMIX_comm_destroy(smx_action_t action);
 void SIMIX_comm_destroy_internal_actions(smx_action_t action);
 void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double timeout, int idx);
+smx_action_t SIMIX_comm_iprobe(smx_process_t dst_proc, smx_rdv_t rdv, int src,
+                              int tag, int (*match_fun)(void *, void *, smx_action_t), void *data);
 void SIMIX_pre_comm_waitany(smx_simcall_t simcall, int idx);
 void SIMIX_post_comm(smx_action_t action);
 void SIMIX_pre_comm_test(smx_simcall_t simcall);
index 472d523..88bd7b7 100644 (file)
@@ -14,6 +14,7 @@
 #include "xbt/dict.h"
 #include "xbt/mallocator.h"
 #include "xbt/config.h"
+#include "xbt/xbt_os_time.h"
 #include "xbt/function_types.h"
 #include "xbt/ex_interface.h"
 #include "instr/instr_private.h"
@@ -25,7 +26,8 @@
 #include "smx_synchro_private.h"
 
 /* Define only for SimGrid benchmarking purposes */
-#undef TIME_BENCH
+//#define TIME_BENCH_PER_SR /* this aims at measuring the time spent in each scheduling round per each thread. The code is thus run in sequential to bench separately each SSR */
+//#define TIME_BENCH_AMDAHL /* this aims at measuring the porting of time that could be parallelized at maximum (to get the optimal speedup by applying the amdahl law). */
 
 /********************************** Simix Global ******************************/
 typedef struct s_smx_global {
@@ -41,6 +43,11 @@ typedef struct s_smx_global {
   void_pfn_smxprocess_t cleanup_process_function;
   xbt_mallocator_t action_mallocator;
   void_pfn_smxhost_t autorestart;
+
+#ifdef TIME_BENCH_AMDAHL
+  xbt_os_timer_t timer_seq; /* used to bench the sequential and parallel parts of the simulation, if requested to */
+  xbt_os_timer_t timer_par;
+#endif
 } s_smx_global_t, *smx_global_t;
 
 extern smx_global_t simix_global;
@@ -302,4 +309,7 @@ static XBT_INLINE void* SIMIX_context_get_data(smx_context_t context)
 }
 
 XBT_PUBLIC(int) SIMIX_process_get_maxpid(void);
+
+void SIMIX_post_create_environment(void);
+
 #endif
index dfb1268..0a8fbca 100644 (file)
@@ -123,6 +123,17 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value)
       SIMIX_simcall_answer(simcall);
       break;
 
+    case SIMCALL_COMM_IPROBE:
+      simcall->comm_iprobe.result = SIMIX_comm_iprobe(
+          simcall->issuer,
+          simcall->comm_iprobe.rdv,
+          simcall->comm_iprobe.src,
+          simcall->comm_iprobe.tag,
+          simcall->comm_iprobe.match_fun,
+          simcall->comm_iprobe.data);
+      SIMIX_simcall_answer(simcall);
+      break;
+
     case SIMCALL_COMM_DESTROY:
       SIMIX_comm_destroy(simcall->comm_destroy.comm);
       SIMIX_simcall_answer(simcall);
@@ -203,6 +214,16 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value)
       SIMIX_simcall_answer(simcall);
       break;
 
+    case SIMCALL_RDV_SET_RECV:
+      SIMIX_rdv_set_receiver(simcall->rdv_set_rcv_proc.rdv, simcall->rdv_set_rcv_proc.receiver);
+      SIMIX_simcall_answer(simcall);
+      break;
+
+    case SIMCALL_RDV_GET_RECV:
+      simcall->rdv_get_rcv_proc.result = SIMIX_rdv_get_receiver(simcall->rdv_set_rcv_proc.rdv);
+      SIMIX_simcall_answer(simcall);
+      break;
+
     case SIMCALL_HOST_GET_BY_NAME:
       simcall->host_get_by_name.result =
         SIMIX_host_get_by_name(simcall->host_get_by_name.name);
@@ -522,6 +543,20 @@ void SIMIX_simcall_pre(smx_simcall_t simcall, int value)
       SIMIX_pre_file_stat(simcall);
       break;
 
+    case SIMCALL_FILE_UNLINK:
+      SIMIX_pre_file_unlink(simcall);
+      break;
+
+    case SIMCALL_FILE_LS:
+      SIMIX_pre_file_ls(simcall);
+      break;
+
+    case SIMCALL_ASR_GET_PROPERTIES:
+      simcall->asr_get_properties.result =
+        SIMIX_asr_get_properties(simcall->asr_get_properties.name);
+      SIMIX_simcall_answer(simcall);
+      break;
+
     case SIMCALL_NONE:
       THROWF(arg_error,0,"Asked to do the noop syscall on %s@%s",
           SIMIX_process_get_name(simcall->issuer),
index 6e83587..d111650 100644 (file)
@@ -53,6 +53,8 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_DESTROY),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GEY_BY_NAME),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_COMM_COUNT_BY_HOST),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GET_HEAD),\
+SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_SET_RECV),\
+SIMCALL_ENUM_ELEMENT(SIMCALL_RDV_GET_RECV),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_SEND),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_ISEND),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_RECV),\
@@ -63,6 +65,7 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_WAITANY),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_WAIT),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_TEST),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_TESTANY),\
+SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_IPROBE),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_GET_REMAINS),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_GET_STATE),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_COMM_GET_SRC_DATA),\
@@ -91,7 +94,10 @@ SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_READ),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_WRITE),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_OPEN),\
 SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_CLOSE),\
-SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_STAT)
+SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_STAT), \
+SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_UNLINK),\
+SIMCALL_ENUM_ELEMENT(SIMCALL_FILE_LS),\
+SIMCALL_ENUM_ELEMENT(SIMCALL_ASR_GET_PROPERTIES)
 
 
 /* SIMCALL_COMM_IS_LATENCY_BOUNDED and SIMCALL_SET_CATEGORY make things complicated
@@ -334,6 +340,16 @@ typedef struct s_smx_simcall {
       smx_action_t result;
     } rdv_get_head;
 
+    struct {
+      smx_rdv_t rdv;
+      smx_process_t receiver;
+    } rdv_set_rcv_proc;
+
+    struct {
+      smx_rdv_t rdv;
+      smx_process_t result;
+    } rdv_get_rcv_proc;
+
     struct {
       smx_rdv_t rdv;
       double task_size;
@@ -376,6 +392,15 @@ typedef struct s_smx_simcall {
       smx_action_t result;
     } comm_irecv;
 
+    struct {
+      smx_rdv_t rdv;
+      int src;
+      int tag;
+      int (*match_fun)(void *, void *, smx_action_t);
+      void *data;
+      smx_action_t result;
+    } comm_iprobe;
+
     struct {
       smx_action_t comm;
     } comm_destroy;
@@ -562,6 +587,22 @@ typedef struct s_smx_simcall {
       int result;
     } file_stat;
 
+    struct {
+      smx_file_t fd;
+      int result;
+    } file_unlink;
+
+    struct {
+      const char *mount;
+      const char *path;
+      xbt_dict_t result;
+    } file_ls;
+
+    struct {
+      const char* name;
+      xbt_dict_t result;
+    } asr_get_properties;
+
   };
 } s_smx_simcall_t, *smx_simcall_t;
 
index b09d08e..54edf9d 100644 (file)
@@ -41,6 +41,8 @@ smx_host_t simcall_host_get_by_name(const char *name)
 
   simcall->call = SIMCALL_HOST_GET_BY_NAME;
   simcall->host_get_by_name.name = name;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->host_get_by_name.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_by_name.result;
 }
@@ -58,6 +60,8 @@ const char* simcall_host_get_name(smx_host_t host)
 
   simcall->call = SIMCALL_HOST_GET_NAME;
   simcall->host_get_name.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->host_get_name.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_name.result;
 }
@@ -75,10 +79,32 @@ xbt_dict_t simcall_host_get_properties(smx_host_t host)
 
   simcall->call = SIMCALL_HOST_GET_PROPERTIES;
   simcall->host_get_properties.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->host_get_properties.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_properties.result;
 }
 
+/**
+ * \ingroup simix_host_management
+ * \brief Returns a dict of the properties assigned to a router or AS.
+ *
+ * \param asr name of the router or AS
+ * \return The properties
+ */
+xbt_dict_t simcall_asr_get_properties(const char *name)
+{
+  smx_simcall_t simcall = SIMIX_simcall_mine();
+
+  simcall->call = SIMCALL_ASR_GET_PROPERTIES;
+  simcall->asr_get_properties.name = name;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->asr_get_properties.result = NULL;
+  SIMIX_simcall_push(simcall->issuer);
+  return simcall->asr_get_properties.result;
+}
+
+
 /**
  * \ingroup simix_host_management
  * \brief Returns the speed of the processor.
@@ -93,6 +119,8 @@ double simcall_host_get_speed(smx_host_t host)
 
   simcall->call = SIMCALL_HOST_GET_SPEED;
   simcall->host_get_speed.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->host_get_speed.result = 0.0;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_speed.result;
 }
@@ -109,6 +137,8 @@ double simcall_host_get_available_speed(smx_host_t host)
 
   simcall->call = SIMCALL_HOST_GET_AVAILABLE_SPEED;
   simcall->host_get_available_speed.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->host_get_available_speed.result = 0.0;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_available_speed.result;
 }
@@ -127,6 +157,8 @@ int simcall_host_get_state(smx_host_t host)
 
   simcall->call = SIMCALL_HOST_GET_STATE;
   simcall->host_get_state.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->host_get_state.result = -1;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_state.result;
 }
@@ -144,6 +176,8 @@ void* simcall_host_get_data(smx_host_t host)
 
   simcall->call = SIMCALL_HOST_GET_DATA;
   simcall->host_get_data.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->host_get_data.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_get_data.result;
 }
@@ -194,6 +228,8 @@ smx_action_t simcall_host_execute(const char *name, smx_host_t host,
   simcall->host_execute.host = host;
   simcall->host_execute.computation_amount = computation_amount;
   simcall->host_execute.priority = priority;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->host_execute.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_execute.result;
 }
@@ -244,6 +280,8 @@ smx_action_t simcall_host_parallel_execute(const char *name,
   simcall->host_parallel_execute.communication_amount = communication_amount;
   simcall->host_parallel_execute.amount = amount;
   simcall->host_parallel_execute.rate = rate;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->host_parallel_execute.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_parallel_execute.result;
 }
@@ -293,6 +331,8 @@ double simcall_host_execution_get_remains(smx_action_t execution)
 
   simcall->call = SIMCALL_HOST_EXECUTION_GET_REMAINS;
   simcall->host_execution_get_remains.execution = execution;
+  if(MC_IS_ENABLED) /* Initializeialize result to a default value for snapshot comparison done during simcall */
+    simcall->host_execution_get_remains.result = 0.0;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_execution_get_remains.result;
 }
@@ -310,6 +350,7 @@ e_smx_state_t simcall_host_execution_get_state(smx_action_t execution)
 
   simcall->call = SIMCALL_HOST_EXECUTION_GET_STATE;
   simcall->host_execution_get_state.execution = execution;
+  simcall->host_execution_get_state.result = -1;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_execution_get_state.result;
 }
@@ -347,6 +388,8 @@ e_smx_state_t simcall_host_execution_wait(smx_action_t execution)
 
   simcall->call = SIMCALL_HOST_EXECUTION_WAIT;
   simcall->host_execution_wait.execution = execution;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->host_execution_wait.result = -1;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->host_execution_wait.result;
 }
@@ -505,6 +548,8 @@ int simcall_process_count(void)
   smx_simcall_t simcall = SIMIX_simcall_mine();
 
   simcall->call = SIMCALL_PROCESS_COUNT;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->process_count.result = -1;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_count.result;
 }
@@ -526,6 +571,8 @@ void* simcall_process_get_data(smx_process_t process)
 
   simcall->call = SIMCALL_PROCESS_GET_DATA;
   simcall->process_get_data.process = process;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->process_get_data.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_get_data.result;
 }
@@ -588,6 +635,8 @@ smx_host_t simcall_process_get_host(smx_process_t process)
 
   simcall->call = SIMCALL_PROCESS_GET_HOST;
   simcall->process_get_host.process = process;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->process_get_host.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_get_host.result;
 }
@@ -611,6 +660,8 @@ const char* simcall_process_get_name(smx_process_t process)
 
   simcall->call = SIMCALL_PROCESS_GET_NAME;
   simcall->process_get_name.process = process;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->process_get_name.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_get_name.result;
 }
@@ -629,6 +680,8 @@ int simcall_process_is_suspended(smx_process_t process)
 
   simcall->call = SIMCALL_PROCESS_IS_SUSPENDED;
   simcall->process_is_suspended.process = process;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->process_is_suspended.result = -1;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_is_suspended.result;
 }
@@ -645,6 +698,8 @@ xbt_dict_t simcall_process_get_properties(smx_process_t process)
 
   simcall->call = SIMCALL_PROCESS_GET_PROPERTIES;
   simcall->process_get_properties.process = process;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->process_get_properties.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_get_properties.result;
 }
@@ -690,6 +745,8 @@ XBT_PUBLIC(smx_process_t) simcall_process_restart(smx_process_t process)
 
   simcall->call = SIMCALL_PROCESS_RESTART;
   simcall->process_restart.process = process;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->process_restart.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
 
@@ -715,6 +772,8 @@ e_smx_state_t simcall_process_sleep(double duration)
 
   simcall->call = SIMCALL_PROCESS_SLEEP;
   simcall->process_sleep.duration = duration;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->process_sleep.result = -1;
   SIMIX_simcall_push(simcall->issuer);
   return simcall->process_sleep.result;
 }
@@ -731,6 +790,8 @@ smx_rdv_t simcall_rdv_create(const char *name)
 
   simcall->call = SIMCALL_RDV_CREATE;
   simcall->rdv_create.name = name;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->rdv_create.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->rdv_create.result;
@@ -788,6 +849,8 @@ int simcall_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
   simcall->call = SIMCALL_RDV_COMM_COUNT_BY_HOST;
   simcall->rdv_comm_count_by_host.rdv = rdv;
   simcall->rdv_comm_count_by_host.host = host;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->rdv_comm_count_by_host.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->rdv_comm_count_by_host.result;
@@ -805,10 +868,37 @@ smx_action_t simcall_rdv_get_head(smx_rdv_t rdv)
 
   simcall->call = SIMCALL_RDV_GET_HEAD;
   simcall->rdv_get_head.rdv = rdv;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->rdv_get_head.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->rdv_get_head.result;
 }
+
+void simcall_rdv_set_receiver(smx_rdv_t rdv , smx_process_t process)
+{
+  smx_simcall_t simcall = SIMIX_simcall_mine();
+
+  simcall->call = SIMCALL_RDV_SET_RECV;
+  simcall->rdv_set_rcv_proc.rdv = rdv;
+  simcall->rdv_set_rcv_proc.receiver = process;
+
+  SIMIX_simcall_push(simcall->issuer);
+}
+
+smx_process_t simcall_rdv_get_receiver(smx_rdv_t rdv)
+{
+  smx_simcall_t simcall = SIMIX_simcall_mine();
+
+  simcall->call = SIMCALL_RDV_GET_RECV;
+  simcall->rdv_get_rcv_proc.rdv = rdv;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->rdv_get_rcv_proc.result = NULL;
+
+  SIMIX_simcall_push(simcall->issuer);
+  return simcall->rdv_get_rcv_proc.result;
+}
+
 /**
  * \ingroup simix_comm_management
  */
@@ -874,6 +964,8 @@ smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
   simcall->comm_isend.clean_fun = clean_fun;
   simcall->comm_isend.data = data;
   simcall->comm_isend.detached = detached;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_isend.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_isend.result;
@@ -923,10 +1015,36 @@ smx_action_t simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff
   simcall->comm_irecv.dst_buff_size = dst_buff_size;
   simcall->comm_irecv.match_fun = match_fun;
   simcall->comm_irecv.data = data;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_irecv.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_irecv.result;
 }
+
+
+/**
+ * \ingroup simix_comm_management
+ */
+smx_action_t simcall_comm_iprobe(smx_rdv_t rdv, int src, int tag,
+                                int (*match_fun)(void *, void *, smx_action_t), void *data)
+{
+  xbt_assert(rdv, "No rendez-vous point defined for iprobe");
+
+  smx_simcall_t simcall = SIMIX_simcall_mine();
+
+  simcall->call = SIMCALL_COMM_IPROBE;
+  simcall->comm_iprobe.rdv = rdv;
+  simcall->comm_iprobe.src = src;
+  simcall->comm_iprobe.match_fun = match_fun;
+  simcall->comm_iprobe.data = data;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_iprobe.result = NULL;
+  SIMIX_simcall_push(simcall->issuer);
+  return simcall->comm_iprobe.result;
+}
+
+
 void simcall_comm_destroy(smx_action_t comm)
 {
   xbt_assert(comm, "Invalid parameter");
@@ -963,6 +1081,8 @@ unsigned int simcall_comm_waitany(xbt_dynar_t comms)
 
   simcall->call = SIMCALL_COMM_WAITANY;
   simcall->comm_waitany.comms = comms;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->comm_waitany.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_waitany.result;
@@ -978,6 +1098,8 @@ int simcall_comm_testany(xbt_dynar_t comms)
 
   simcall->call = SIMCALL_COMM_TESTANY;
   simcall->comm_testany.comms = comms;
+    if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+      simcall->comm_testany.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_testany.result;
@@ -1031,6 +1153,8 @@ int simcall_comm_test(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_TEST;
   simcall->comm_test.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->comm_test.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_test.result;
@@ -1045,6 +1169,8 @@ double simcall_comm_get_remains(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_GET_REMAINS;
   simcall->comm_get_remains.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->comm_get_remains.result = 0.0;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_get_remains.result;
@@ -1059,6 +1185,8 @@ e_smx_state_t simcall_comm_get_state(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_GET_STATE;
   simcall->comm_get_state.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->comm_get_state.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_get_state.result;
@@ -1073,6 +1201,8 @@ void *simcall_comm_get_src_data(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_GET_SRC_DATA;
   simcall->comm_get_src_data.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_get_src_data.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_get_src_data.result;
@@ -1087,6 +1217,8 @@ void *simcall_comm_get_dst_data(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_GET_DST_DATA;
   simcall->comm_get_dst_data.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_get_dst_data.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_get_dst_data.result;
@@ -1101,6 +1233,8 @@ smx_process_t simcall_comm_get_src_proc(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_GET_SRC_PROC;
   simcall->comm_get_src_proc.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_get_src_proc.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_get_src_proc.result;
@@ -1115,6 +1249,8 @@ smx_process_t simcall_comm_get_dst_proc(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_GET_DST_PROC;
   simcall->comm_get_dst_proc.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->comm_get_dst_proc.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_get_dst_proc.result;
@@ -1127,6 +1263,8 @@ int simcall_comm_is_latency_bounded(smx_action_t comm)
 
   simcall->call = SIMCALL_COMM_IS_LATENCY_BOUNDED;
   simcall->comm_is_latency_bounded.comm = comm;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->comm_is_latency_bounded.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->comm_is_latency_bounded.result;
@@ -1145,6 +1283,8 @@ smx_mutex_t simcall_mutex_init(void)
   smx_simcall_t simcall = SIMIX_simcall_mine();
 
   simcall->call = SIMCALL_MUTEX_INIT;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->mutex_init.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->mutex_init.result;
@@ -1185,6 +1325,8 @@ int simcall_mutex_trylock(smx_mutex_t mutex)
 
   simcall->call = SIMCALL_MUTEX_TRYLOCK;
   simcall->mutex_trylock.mutex = mutex;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->mutex_trylock.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->mutex_trylock.result;
@@ -1211,6 +1353,8 @@ smx_cond_t simcall_cond_init(void)
   smx_simcall_t simcall = SIMIX_simcall_mine();
 
   simcall->call = SIMCALL_COND_INIT;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->cond_init.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->cond_init.result;
@@ -1297,6 +1441,8 @@ smx_sem_t simcall_sem_init(int capacity)
 
   simcall->call = SIMCALL_SEM_INIT;
   simcall->sem_init.capacity = capacity;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->sem_init.result = NULL;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->sem_init.result;
@@ -1337,6 +1483,8 @@ int simcall_sem_would_block(smx_sem_t sem)
 
   simcall->call = SIMCALL_SEM_WOULD_BLOCK;
   simcall->sem_would_block.sem = sem;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->sem_would_block.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->sem_would_block.result;
@@ -1380,6 +1528,8 @@ int simcall_sem_get_capacity(smx_sem_t sem)
 
   simcall->call = SIMCALL_SEM_GET_CAPACITY;
   simcall->sem_get_capacity.sem = sem;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->sem_get_capacity.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
   return simcall->sem_get_capacity.result;
@@ -1397,6 +1547,8 @@ double simcall_file_read(void* ptr, size_t size, size_t nmemb, smx_file_t stream
   simcall->file_read.size = size;
   simcall->file_read.nmemb = nmemb;
   simcall->file_read.stream = stream;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->file_read.result = 0.0;
   SIMIX_simcall_push(simcall->issuer);
 
   return simcall->file_read.result;
@@ -1414,6 +1566,8 @@ size_t simcall_file_write(const void* ptr, size_t size, size_t nmemb, smx_file_t
   simcall->file_write.size = size;
   simcall->file_write.nmemb = nmemb;
   simcall->file_write.stream = stream;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->file_write.result = 0;
   SIMIX_simcall_push(simcall->issuer);
 
   return simcall->file_write.result;
@@ -1430,6 +1584,8 @@ smx_file_t simcall_file_open(const char* mount, const char* path, const char* mo
   simcall->file_open.mount = mount;
   simcall->file_open.path = path;
   simcall->file_open.mode = mode;
+  if(MC_IS_ENABLED) /* Initialize result to NULL for snapshot comparison done during simcall */
+    simcall->file_open.result = NULL;
   SIMIX_simcall_push(simcall->issuer);
 
   return simcall->file_open.result;
@@ -1444,6 +1600,8 @@ int simcall_file_close(smx_file_t fp)
 
   simcall->call = SIMCALL_FILE_CLOSE;
   simcall->file_close.fp = fp;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->file_close.result = -1;
   SIMIX_simcall_push(simcall->issuer);
 
   return simcall->file_close.result;
@@ -1457,6 +1615,8 @@ int simcall_file_stat(smx_file_t fd, s_file_stat_t *buf)
   smx_simcall_t simcall = SIMIX_simcall_mine();
   simcall->call = SIMCALL_FILE_STAT;
   simcall->file_stat.fd = fd;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->file_stat.result = -1;
 
   SIMIX_simcall_push(simcall->issuer);
 
@@ -1465,6 +1625,41 @@ int simcall_file_stat(smx_file_t fd, s_file_stat_t *buf)
   return simcall->file_stat.result;
 }
 
+/**
+ * \ingroup simix_file_management
+ *
+ */
+int simcall_file_unlink(smx_file_t fd)
+{
+  smx_simcall_t simcall = SIMIX_simcall_mine();
+  simcall->call = SIMCALL_FILE_UNLINK;
+  simcall->file_unlink.fd = fd;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->file_unlink.result = -1;
+
+  SIMIX_simcall_push(simcall->issuer);
+
+  return simcall->file_unlink.result;
+}
+
+/**
+ * \ingroup simix_file_management
+ *
+ */
+xbt_dict_t simcall_file_ls(const char* mount, const char* path)
+{
+  smx_simcall_t simcall = SIMIX_simcall_mine();
+  simcall->call = SIMCALL_FILE_LS;
+  simcall->file_ls.mount = mount;
+  simcall->file_ls.path = path;
+  if(MC_IS_ENABLED) /* Initialize result to a default value for snapshot comparison done during simcall */
+    simcall->file_ls.result = NULL;
+
+  SIMIX_simcall_push(simcall->issuer);
+
+  return simcall->file_ls.result;
+}
+
 /* ************************************************************************** */
 
 /** @brief returns a printable string representing a simcall */
index a01ffef..c657011 100644 (file)
@@ -44,9 +44,13 @@ void smpi_process_finalize(void);
 
 smpi_process_data_t smpi_process_data(void);
 smpi_process_data_t smpi_process_remote_data(int index);
+void smpi_process_set_user_data(void *);
+void* smpi_process_get_user_data(void);
 int smpi_process_count(void);
 smx_rdv_t smpi_process_mailbox(void);
 smx_rdv_t smpi_process_remote_mailbox(int index);
+smx_rdv_t smpi_process_mailbox_small(void);
+smx_rdv_t smpi_process_remote_mailbox_small(int index);
 xbt_os_timer_t smpi_process_timer(void);
 void smpi_process_simulated_start(void);
 double smpi_process_simulated_elapsed(void);
@@ -64,6 +68,24 @@ int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb,
 int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                        void *recvbuf, int recvcount,
                        MPI_Datatype recvtype);
+int smpi_datatype_contiguous(int count, MPI_Datatype old_type,
+                       MPI_Datatype* new_type);
+int smpi_datatype_vector(int count, int blocklen, int stride,
+                      MPI_Datatype old_type, MPI_Datatype* new_type);
+
+int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride,
+                      MPI_Datatype old_type, MPI_Datatype* new_type);
+int smpi_datatype_indexed(int count, int* blocklens, int* indices,
+                     MPI_Datatype old_type, MPI_Datatype* new_type);
+int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices,
+                     MPI_Datatype old_type, MPI_Datatype* new_type);
+int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices,
+                    MPI_Datatype* old_types, MPI_Datatype* new_type);
+void smpi_datatype_create(MPI_Datatype* new_type, int size, int flags);
+void smpi_datatype_free(MPI_Datatype* type);
+void smpi_datatype_commit(MPI_Datatype* datatype);
+
+
 
 MPI_Op smpi_op_new(MPI_User_function * function, int commute);
 void smpi_op_destroy(MPI_Op op);
@@ -114,6 +136,11 @@ void smpi_mpi_sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 int smpi_mpi_test(MPI_Request * request, MPI_Status * status);
 int smpi_mpi_testany(int count, MPI_Request requests[], int *index,
                      MPI_Status * status);
+int smpi_mpi_testall(int count, MPI_Request requests[],
+                     MPI_Status status[]);
+void smpi_mpi_probe(int source, int tag, MPI_Comm comm, MPI_Status* status);
+MPI_Request smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag,
+                    MPI_Status* status);
 int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype);
 void smpi_mpi_wait(MPI_Request * request, MPI_Status * status);
 int smpi_mpi_waitany(int count, MPI_Request requests[],
@@ -180,6 +207,7 @@ int smpi_coll_basic_alltoallv(void *sendbuf, int *sendcounts,
 void smpi_bench_destroy(void);
 void smpi_bench_begin(void);
 void smpi_bench_end(void);
+void smpi_execute_flops(double flops);
 
 // f77 wrappers
 void mpi_init__(int*);
index 62429c8..458eb84 100644 (file)
@@ -8,6 +8,8 @@
 #include "xbt/time.h"
 #include "mc/mc.h"
 #include "xbt/replay.h"
+#include <errno.h>
+#include "surf/surf.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_base, smpi,
                                 "Logging specific to SMPI (base)");
@@ -120,39 +122,50 @@ void smpi_mpi_start(MPI_Request request)
               "Cannot (re)start a non-finished communication");
   if(request->flags & RECV) {
     print_request("New recv", request);
+    if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres"))
+    mailbox = smpi_process_mailbox_small();
+    else
     mailbox = smpi_process_mailbox();
+
     // FIXME: SIMIX does not yet support non-contiguous datatypes
     request->action = simcall_comm_irecv(mailbox, request->buf, &request->size, &match_recv, request);
   } else {
     print_request("New send", request);
-    mailbox = smpi_process_remote_mailbox(
-        smpi_group_index(smpi_comm_group(request->comm), request->dst));
-    // FIXME: SIMIX does not yet support non-contiguous datatypes
 
-    if (request->size < 64*1024 ) { // eager mode => detached send (FIXME: this limit should be configurable)
+    if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")) { // eager mode => detached send (FIXME: this limit should be configurable)
+      mailbox = smpi_process_remote_mailbox_small(
+            smpi_group_index(smpi_comm_group(request->comm), request->dst));
+    }else{
+      XBT_DEBUG("Send request %p is not in the permanent receive mailbox (buf: %p)",request,request->buf);
+      mailbox = smpi_process_remote_mailbox(
+                  smpi_group_index(smpi_comm_group(request->comm), request->dst));
+    }
+    if (request->size < 64*1024 ) { //(FIXME: this limit should be configurable)
       void *oldbuf = request->buf;
       detached = 1;
       request->buf = malloc(request->size);
-      memcpy(request->buf,oldbuf,request->size);
+      if (oldbuf)
+        memcpy(request->buf,oldbuf,request->size);
       XBT_DEBUG("Send request %p is detached; buf %p copied into %p",request,oldbuf,request->buf);
-    } else {
-      XBT_DEBUG("Send request %p is not detached (buf: %p)",request,request->buf);
     }
-    request->action = 
-    simcall_comm_isend(mailbox, request->size, -1.0,
-            request->buf, request->size,
-            &match_send,
-            &smpi_mpi_request_free_voidp, // how to free the userdata if a detached send fails
-            request,
-            // detach if msg size < eager/rdv switch limit
-            detached);
 
-#ifdef HAVE_TRACING
-    /* FIXME: detached sends are not traceable (request->action == NULL) */
-    if (request->action)
-      simcall_set_category(request->action, TRACE_internal_smpi_get_category());
-#endif
-  }
+      request->action =
+      simcall_comm_isend(mailbox, request->size, -1.0,
+              request->buf, request->size,
+              &match_send,
+              &smpi_mpi_request_free_voidp, // how to free the userdata if a detached send fails
+              request,
+              // detach if msg size < eager/rdv switch limit
+              detached);
+
+  #ifdef HAVE_TRACING
+      /* FIXME: detached sends are not traceable (request->action == NULL) */
+      if (request->action)
+        simcall_set_category(request->action, TRACE_internal_smpi_get_category());
+  #endif
+
+    }
+
 }
 
 void smpi_mpi_startall(int count, MPI_Request * requests)
@@ -219,13 +232,15 @@ void smpi_mpi_recv(void *buf, int count, MPI_Datatype datatype, int src,
   smpi_mpi_wait(&request, status);
 }
 
+
+
 void smpi_mpi_send(void *buf, int count, MPI_Datatype datatype, int dst,
                    int tag, MPI_Comm comm)
 {
-  MPI_Request request;
+         MPI_Request request;
 
-  request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
-  smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
+         request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
+         smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
 }
 
 void smpi_mpi_sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
@@ -256,6 +271,10 @@ int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype)
 static void finish_wait(MPI_Request * request, MPI_Status * status)
 {
   MPI_Request req = *request;
+  // if we have a sender, we should use its data, and not the data from the receive
+  if((req->action)&&
+      (req->src==MPI_ANY_SOURCE || req->tag== MPI_ANY_TAG))
+    req = (MPI_Request)SIMIX_comm_get_src_data((*request)->action);
 
   if(status != MPI_STATUS_IGNORE) {
     status->MPI_SOURCE = req->src;
@@ -265,6 +284,8 @@ static void finish_wait(MPI_Request * request, MPI_Status * status)
     // right?
     status->count = req->size;
   }
+  req = *request;
+
   print_request("Finishing", req);
   if(req->flags & NON_PERSISTENT) {
     smpi_mpi_request_free(request);
@@ -281,7 +302,7 @@ int flag;
    else 
     flag = simcall_comm_test((*request)->action);
    if(flag) {
-        smpi_mpi_wait(request, status);
+       finish_wait(request, status);
     }
     return flag;
 }
@@ -321,6 +342,67 @@ int smpi_mpi_testany(int count, MPI_Request requests[], int *index,
   return flag;
 }
 
+
+int smpi_mpi_testall(int count, MPI_Request requests[],
+                     MPI_Status status[])
+{
+  int flag=1;
+  int i;
+  for(i=0; i<count; i++)
+   if (smpi_mpi_test(&requests[i], &status[i])!=1)
+       flag=0;
+
+  return flag;
+}
+
+void smpi_mpi_probe(int source, int tag, MPI_Comm comm, MPI_Status* status){
+  int flag=0;
+  //FIXME find another wait to avoid busy waiting ?
+  // the issue here is that we have to wait on a nonexistent comm
+  MPI_Request request;
+  while(flag==0){
+        request = smpi_mpi_iprobe(source, tag, comm, &flag, status);
+        XBT_DEBUG("Busy Waiting on probing : %d", flag);
+        if(!flag) {
+            smpi_mpi_request_free(&request);
+            simcall_process_sleep(0.0001);
+        }
+  }
+}
+
+MPI_Request smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status){
+  MPI_Request request =build_request(NULL, 0, MPI_CHAR, source, smpi_comm_rank(comm), tag,
+            comm, NON_PERSISTENT | RECV);
+  // behave like a receive, but don't do it
+  smx_rdv_t mailbox;
+
+  print_request("New iprobe", request);
+  // We have to test both mailboxes as we don't know if we will receive one one or another
+    if (xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")>0){
+        mailbox = smpi_process_mailbox_small();
+        request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
+
+    }
+    if (request->action==NULL){
+       mailbox = smpi_process_mailbox();
+        request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
+    }
+
+  if(request->action){
+    MPI_Request req = (MPI_Request)SIMIX_comm_get_src_data(request->action);
+    *flag=true;
+    if(status != MPI_STATUS_IGNORE) {
+      status->MPI_SOURCE = req->src;
+      status->MPI_TAG = req->tag;
+      status->MPI_ERROR = MPI_SUCCESS;
+      status->count = req->size;
+    }
+  }
+  else *flag=false;
+
+  return request;
+}
+
 void smpi_mpi_wait(MPI_Request * request, MPI_Status * status)
 {
   print_request("Waiting", *request);
@@ -347,7 +429,7 @@ int smpi_mpi_waitany(int count, MPI_Request requests[],
     XBT_DEBUG("Wait for one of");
     for(i = 0; i < count; i++) {
       if((requests[i] != MPI_REQUEST_NULL) && (requests[i]->action != NULL)) {
-        print_request("   ", requests[i]);
+        print_request("Waiting any ", requests[i]);
         xbt_dynar_push(comms, &requests[i]->action);
         map[size] = i;
         size++;
@@ -355,10 +437,12 @@ int smpi_mpi_waitany(int count, MPI_Request requests[],
     }
     if(size > 0) {
       i = simcall_comm_waitany(comms);
+
       // FIXME: MPI_UNDEFINED or does SIMIX have a return code?
       if (i != MPI_UNDEFINED) {
         index = map[i];
         finish_wait(&requests[index], status);
+
       }
     }
     xbt_free(map);
@@ -670,7 +754,8 @@ void smpi_mpi_reduce(void *sendbuf, void *recvbuf, int count,
     // FIXME: check for errors
     smpi_datatype_extent(datatype, &lb, &dataext);
     // Local copy from root
-    smpi_datatype_copy(sendbuf, count, datatype, recvbuf, count, datatype);
+    if (sendbuf && recvbuf)
+      smpi_datatype_copy(sendbuf, count, datatype, recvbuf, count, datatype);
     // Receive buffers from senders
     //TODO: make a MPI_barrier here ?
     requests = xbt_new(MPI_Request, size - 1);
@@ -691,10 +776,12 @@ void smpi_mpi_reduce(void *sendbuf, void *recvbuf, int count,
     smpi_mpi_startall(size - 1, requests);
     for(src = 0; src < size - 1; src++) {
       index = smpi_mpi_waitany(size - 1, requests, MPI_STATUS_IGNORE);
+      XBT_VERB("finished waiting any request with index %d", index);
       if(index == MPI_UNDEFINED) {
         break;
       }
-      smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype);
+      if(op) /* op can be MPI_OP_NULL that does nothing */
+        smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype);
     }
     for(index = 0; index < size - 1; index++) {
       xbt_free(tmpbufs[index]);
index 7fb8181..c3628c8 100644 (file)
@@ -108,17 +108,6 @@ static void* shm_map(int fd, size_t size, shared_data_t* data) {
   return mem;
 }
 
-typedef struct {
-  int count;
-  double sum;
-  double sum_pow2;
-  double mean;
-  double relstderr;
-  int iters;
-  double threshold;
-  int started;
-} local_data_t;
-
 void smpi_bench_destroy(void)
 {
   xbt_dict_free(&allocs);
@@ -126,8 +115,7 @@ void smpi_bench_destroy(void)
   xbt_dict_free(&calls);
 }
 
-static void smpi_execute_flops(double flops)
-{
+void smpi_execute_flops(double flops) {
   smx_action_t action;
   smx_host_t host;
   host = SIMIX_host_self();
@@ -149,7 +137,7 @@ static void smpi_execute(double duration)
                        xbt_cfg_get_double(_surf_cfg_set,
                                           "smpi/running_power"));
   } else {
-    XBT_DEBUG("Real computation took %f while threshold is set to %f; ignore it",
+    XBT_DEBUG("Real computation took %f while option smpi/cpu_threshold is set to %f => ignore it",
         duration, xbt_cfg_get_double(_surf_cfg_set, "smpi/cpu_threshold"));
   }
 }
@@ -209,38 +197,74 @@ unsigned long long smpi_rastro_timestamp (void)
   return (unsigned long long)sec * smpi_rastro_resolution() + pre;
 }
 
-static char *sample_location(int global, const char *file, int line)
-{
+/* ****************************** Functions related to the SMPI_SAMPLE_ macros ************************************/
+typedef struct {
+  int iters;        /* amount of requested iterations */
+  int count;        /* amount of iterations done so far */
+  double threshold; /* maximal stderr requested (if positive) */
+  double relstderr; /* observed stderr so far */
+  double mean;      /* mean of benched times, to be used if the block is disabled */
+  double sum;       /* sum of benched times (to compute the mean and stderr) */
+  double sum_pow2;  /* sum of the square of the benched times (to compute the stderr) */
+  int benching;     /* 1: we are benchmarking; 0: we have enough data, no bench anymore */
+} local_data_t;
+
+static char *sample_location(int global, const char *file, int line) {
   if (global) {
     return bprintf("%s:%d", file, line);
   } else {
     return bprintf("%s:%d:%d", file, line, smpi_process_index());
   }
 }
+static int sample_enough_benchs(local_data_t *data) {
+  int res = data->count >= data->iters;
+  if (data->threshold>0.0) {
+    if (data->count <2)
+      res = 0; // not enough data
+    if (data->relstderr > data->threshold)
+      res = 0; // stderr too high yet
+  }
+  XBT_DEBUG("%s (count:%d iter:%d stderr:%f thres:%f mean:%fs)",
+      (res?"enough benchs":"need more data"),
+      data->count, data->iters, data->relstderr, data->threshold, data->mean);
+  return res;
+}
 
-int smpi_sample_1(int global, const char *file, int line, int iters, double threshold)
+void smpi_sample_1(int global, const char *file, int line, int iters, double threshold)
 {
   char *loc = sample_location(global, file, line);
   local_data_t *data;
 
-  smpi_bench_end();     /* Take time from previous MPI call into account */
-  if (!samples) {
+  smpi_bench_end();     /* Take time from previous, unrelated computation into account */
+  if (!samples)
     samples = xbt_dict_new_homogeneous(free);
-  }
+
   data = xbt_dict_get_or_null(samples, loc);
   if (!data) {
+    xbt_assert(threshold>0 || iters>0,
+        "You should provide either a positive amount of iterations to bench, or a positive maximal stderr (or both)");
     data = (local_data_t *) xbt_new(local_data_t, 1);
     data->count = 0;
     data->sum = 0.0;
     data->sum_pow2 = 0.0;
     data->iters = iters;
     data->threshold = threshold;
-    data->started = 0;
+    data->benching = 1; // If we have no data, we need at least one
+    data->mean = 0;
     xbt_dict_set(samples, loc, data, NULL);
-    return 0;
+    XBT_DEBUG("XXXXX First time ever on benched nest %s.",loc);
+  } else {
+    if (data->iters != iters || data->threshold != threshold) {
+      XBT_ERROR("Asked to bench block %s with different settings %d, %f is not %d, %f. How did you manage to give two numbers at the same line??",
+          loc, data->iters, data->threshold, iters,threshold);
+      THROW_IMPOSSIBLE;
+    }
+
+    // if we already have some data, check whether sample_2 should get one more bench or whether it should emulate the computation instead
+    data->benching = !sample_enough_benchs(data);
+    XBT_DEBUG("XXXX Re-entering the benched nest %s. %s",loc, (data->benching?"more benching needed":"we have enough data, skip computes"));
   }
   free(loc);
-  return 1;
 }
 
 int smpi_sample_2(int global, const char *file, int line)
@@ -248,54 +272,63 @@ int smpi_sample_2(int global, const char *file, int line)
   char *loc = sample_location(global, file, line);
   local_data_t *data;
 
-  xbt_assert(samples, "You did something very inconsistent, didn't you?");
-  data = xbt_dict_get_or_null(samples, loc);
-  if (!data) {
-    xbt_assert(data, "Please, do thing in order");
-  }
-  if (!data->started) {
-    if ((data->iters > 0 && data->count >= data->iters)
-        || (data->count > 1 && data->threshold > 0.0 && data->relstderr <= data->threshold)) {
-      XBT_DEBUG("Perform some wait of %f", data->mean);
-      smpi_execute(data->mean);
-    } else {
-      data->started = 1;
-      data->count++;
-    }
+  xbt_assert(samples, "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
+  data = xbt_dict_get(samples, loc);
+  XBT_DEBUG("sample2 %s",loc);
+  free(loc);
+
+  if (data->benching==1) {
+    // we need to run a new bench
+    XBT_DEBUG("benchmarking: count:%d iter:%d stderr:%f thres:%f; mean:%f",
+        data->count, data->iters, data->relstderr, data->threshold, data->mean);
+    smpi_bench_begin();
+    return 1;
   } else {
-    data->started = 0;
+    // Enough data, no more bench (either we got enough data from previous visits to this benched nest, or we just ran one bench and need to bail out now that our job is done).
+    // Just sleep instead
+    XBT_DEBUG("No benchmark (either no need, or just ran one): count >= iter (%d >= %d) or stderr<thres (%f<=%f). apply the %fs delay instead",
+        data->count, data->iters, data->relstderr, data->threshold, data->mean);
+    smpi_execute(data->mean);
+
+    smpi_bench_begin(); // prepare to capture future, unrelated computations
+    return 0;
   }
-  free(loc);
-  smpi_bench_begin();
-  smpi_process_simulated_start();
-  return data->started;
 }
 
+
 void smpi_sample_3(int global, const char *file, int line)
 {
   char *loc = sample_location(global, file, line);
   local_data_t *data;
-  double sample, n;
 
-  xbt_assert(samples, "You did something very inconsistent, didn't you?");
-  data = xbt_dict_get_or_null(samples, loc);
-  smpi_bench_end();
-  if(data && data->started && data->count < data->iters) {
-    sample = smpi_process_simulated_elapsed();
-    data->sum += sample;
-    data->sum_pow2 += sample * sample;
-    n = (double)data->count;
-    data->mean = data->sum / n;
-    data->relstderr = sqrt((data->sum_pow2 / n - data->mean * data->mean) / n) / data->mean;
-    XBT_DEBUG("Average mean after %d steps is %f, relative standard error is %f (sample was %f)", data->count,
-           data->mean, data->relstderr, sample);
+  xbt_assert(samples, "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
+  data = xbt_dict_get(samples, loc);
+  XBT_DEBUG("sample3 %s",loc);
+
+  if (data->benching==0) {
+    THROW_IMPOSSIBLE;
   }
-  free(loc);
-}
 
-void smpi_sample_flops(double flops)
-{
-  smpi_execute_flops(flops);
+  // ok, benchmarking this loop is over
+  xbt_os_timer_stop(smpi_process_timer());
+
+  // update the stats
+  double sample, n;
+  data->count++;
+  sample = xbt_os_timer_elapsed(smpi_process_timer());
+  data->sum += sample;
+  data->sum_pow2 += sample * sample;
+  n = (double)data->count;
+  data->mean = data->sum / n;
+  data->relstderr = sqrt((data->sum_pow2 / n - data->mean * data->mean) / n) / data->mean;
+  if (!sample_enough_benchs(data)) {
+    data->mean = sample; // Still in benching process; We want sample_2 to simulate the exact time of this loop occurrence before leaving, not the mean over the history
+  }
+  XBT_DEBUG("Average mean after %d steps is %f, relative standard error is %f (sample was %f)", data->count,
+      data->mean, data->relstderr, sample);
+
+  // That's enough for now, prevent sample_2 to run the same code over and over
+  data->benching = 0;
 }
 
 void *smpi_shared_malloc(size_t size, const char *file, int line)
index f157012..c0706b2 100644 (file)
@@ -12,8 +12,8 @@
 #include "smpi_mpi_dt_private.h"
 #include "mc/mc.h"
 #include "surf/surf.h"
+#include "simix/smx_private.h"
 
-XBT_LOG_NEW_CATEGORY(smpi, "All SMPI categories");
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi,
                                 "Logging specific to SMPI (kernel)");
@@ -23,9 +23,11 @@ typedef struct s_smpi_process_data {
   int* argc;
   char*** argv;
   smx_rdv_t mailbox;
+  smx_rdv_t mailbox_small;
   xbt_os_timer_t timer;
   double simulated;
   MPI_Comm comm_self;
+  void *data; /* user data */
 } s_smpi_process_data_t;
 
 static smpi_process_data_t *process_data = NULL;
@@ -40,6 +42,11 @@ static char* get_mailbox_name(char* str, int index) {
   return str;
 }
 
+static char* get_mailbox_name_small(char* str, int index) {
+  snprintf(str, MAILBOX_NAME_MAXLEN, "small%0*x", (int)(sizeof(int) * 2), index);
+  return str;
+}
+
 void smpi_process_init(int *argc, char ***argv)
 {
   int index;
@@ -59,6 +66,7 @@ void smpi_process_init(int *argc, char ***argv)
     (*argc)--;
     data->argc = argc;
     data->argv = argv;
+    simcall_rdv_set_receiver(data->mailbox_small, proc);// set the process attached to the mailbox
     XBT_DEBUG("<%d> New process in the game: %p", index, proc);
   }
 }
@@ -77,7 +85,7 @@ void smpi_process_finalize(void)
 {
   // wait for all pending asynchronous comms to finish
   while (SIMIX_process_has_pending_comms(SIMIX_process_self())) {
-    simcall_process_sleep(1);
+    simcall_process_sleep(0.01);
   }
 }
 
@@ -126,6 +134,17 @@ smpi_process_data_t smpi_process_remote_data(int index)
   return process_data[index];
 }
 
+void smpi_process_set_user_data(void *data)
+{
+  smpi_process_data_t process_data = smpi_process_data();
+  process_data->data = data;
+}
+
+void* smpi_process_get_user_data(){
+  smpi_process_data_t process_data = smpi_process_data();
+  return process_data->data;
+}
+
 int smpi_process_count(void)
 {
   return process_count;
@@ -144,12 +163,25 @@ smx_rdv_t smpi_process_mailbox(void) {
   return data->mailbox;
 }
 
+smx_rdv_t smpi_process_mailbox_small(void) {
+  smpi_process_data_t data = smpi_process_data();
+
+  return data->mailbox_small;
+}
+
 smx_rdv_t smpi_process_remote_mailbox(int index) {
   smpi_process_data_t data = smpi_process_remote_data(index);
 
   return data->mailbox;
 }
 
+
+smx_rdv_t smpi_process_remote_mailbox_small(int index) {
+  smpi_process_data_t data = smpi_process_remote_data(index);
+
+  return data->mailbox_small;
+}
+
 xbt_os_timer_t smpi_process_timer(void)
 {
   smpi_process_data_t data = smpi_process_data();
@@ -157,29 +189,25 @@ xbt_os_timer_t smpi_process_timer(void)
   return data->timer;
 }
 
-void smpi_process_simulated_start(void)
-{
+void smpi_process_simulated_start(void) {
   smpi_process_data_t data = smpi_process_data();
 
   data->simulated = SIMIX_get_clock();
 }
 
-double smpi_process_simulated_elapsed(void)
-{
+double smpi_process_simulated_elapsed(void) {
   smpi_process_data_t data = smpi_process_data();
 
   return SIMIX_get_clock() - data->simulated;
 }
 
-MPI_Comm smpi_process_comm_self(void)
-{
+MPI_Comm smpi_process_comm_self(void) {
   smpi_process_data_t data = smpi_process_data();
 
   return data->comm_self;
 }
 
-void print_request(const char *message, MPI_Request request)
-{
+void print_request(const char *message, MPI_Request request) {
   XBT_DEBUG("%s  request %p  [buf = %p, size = %zu, src = %d, dst = %d, tag = %d, flags = %x]",
          message, request, request->buf, request->size,
          request->src, request->dst, request->tag, request->flags);
@@ -191,7 +219,7 @@ void smpi_global_init(void)
   MPI_Group group;
   char name[MAILBOX_NAME_MAXLEN];
 
-  SIMIX_comm_set_copy_data_callback(&smpi_comm_copy_data_callback);
+  SIMIX_comm_set_copy_data_callback(&SIMIX_comm_copy_buffer_callback);
   process_count = SIMIX_process_count();
   process_data = xbt_new(smpi_process_data_t, process_count);
   for (i = 0; i < process_count; i++) {
@@ -200,6 +228,7 @@ void smpi_global_init(void)
     process_data[i]->argc = NULL;
     process_data[i]->argv = NULL;
     process_data[i]->mailbox = simcall_rdv_create(get_mailbox_name(name, i));
+    process_data[i]->mailbox_small = simcall_rdv_create(get_mailbox_name_small(name, i));
     process_data[i]->timer = xbt_os_timer_new();
     group = smpi_group_new(1);
     process_data[i]->comm_self = smpi_comm_new(group);
@@ -224,6 +253,7 @@ void smpi_global_destroy(void)
     smpi_comm_destroy(process_data[i]->comm_self);
     xbt_os_timer_free(process_data[i]->timer);
     simcall_rdv_destroy(process_data[i]->mailbox);
+    simcall_rdv_destroy(process_data[i]->mailbox_small);
     xbt_free(process_data[i]);
   }
   xbt_free(process_data);
@@ -254,7 +284,8 @@ int MAIN__(void)
   }
 
   /* Connect log categories.  See xbt/log.c */
-  XBT_LOG_CONNECT(smpi);
+  XBT_LOG_CONNECT(smpi);  /* Keep this line as soon as possible in this function: xbt_log_appender_file.c depends on it
+                             DO NOT connect this in XBT or so, or it will be useless to xbt_log_appender_file.c */
   XBT_LOG_CONNECT(smpi_base);
   XBT_LOG_CONNECT(smpi_bench);
   XBT_LOG_CONNECT(smpi_coll);
index d86fcd8..483bbf5 100644 (file)
@@ -46,6 +46,11 @@ double MPI_Wtime(void)
   return PMPI_Wtime();
 }
 
+double MPI_Wtick(void)
+{
+  return PMPI_Wtick();
+}
+
 int MPI_Address(void *location, MPI_Aint * address)
 {
   return PMPI_Address(location, address);
index 700870d..ca60a35 100644 (file)
@@ -151,6 +151,110 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   return retval;
 }
 
+void smpi_datatype_create(MPI_Datatype* new_type, int size, int flags){
+  MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1);
+  new_t->size=size;
+  new_t->lb=0;
+  new_t->ub=size;
+  new_t->flags=flags;
+  *new_type = new_t;
+}
+
+void smpi_datatype_free(MPI_Datatype* type){
+  xbt_free(*type);
+}
+
+int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type)
+{
+  int retval;
+  if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
+     retval = MPI_ERR_TYPE;
+  } else {
+    smpi_datatype_create(new_type, count * smpi_datatype_size(old_type), DT_FLAG_CONTIGUOUS);
+    retval=MPI_SUCCESS;
+  }
+  return retval;
+}
+
+int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type)
+{
+  int retval;
+  if (blocklen<=0)return MPI_ERR_ARG;
+  if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
+     retval = MPI_ERR_TYPE;
+  } else {
+    smpi_datatype_create(new_type, count * (blocklen+stride) * smpi_datatype_size(old_type), DT_FLAG_VECTOR);
+    retval=MPI_SUCCESS;
+  }
+  return retval;
+}
+
+int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type)
+{
+  int retval;
+  if (blocklen<=0)return MPI_ERR_ARG;
+  if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
+     retval = MPI_ERR_TYPE;
+  } else {
+    smpi_datatype_create(new_type, count * ((blocklen * smpi_datatype_size(old_type))+stride), DT_FLAG_VECTOR);
+    retval=MPI_SUCCESS;
+  }
+  return retval;
+}
+
+
+int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
+{
+  int i;
+  int retval;
+  for(i=0; i< count; i++){
+    if   (blocklens[i]<=0)
+      return MPI_ERR_ARG;
+  }
+  if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
+     retval = MPI_ERR_TYPE;
+  } else {
+    smpi_datatype_create(new_type,  (blocklens[count-1] + indices[count-1]) * smpi_datatype_size(old_type), DT_FLAG_DATA);
+    retval=MPI_SUCCESS;
+  }
+  return retval;
+}
+
+int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type)
+{
+  int i;
+  int retval;
+  for(i=0; i< count; i++){
+    if   (blocklens[i]<=0)
+      return MPI_ERR_ARG;
+  }
+  if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) {
+     retval = MPI_ERR_TYPE;
+  } else {
+    smpi_datatype_create(new_type,indices[count-1] + (blocklens[count-1]  * smpi_datatype_size(old_type)), DT_FLAG_DATA);
+    retval=MPI_SUCCESS;
+  }
+  return retval;
+}
+
+int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type)
+{
+  int i;
+  for(i=0; i< count; i++){
+    if (blocklens[i]<=0)
+      return MPI_ERR_ARG;
+    if ((old_types[i]->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED)
+      return MPI_ERR_TYPE;
+  }
+  smpi_datatype_create(new_type,indices[count-1] + (blocklens[count-1]  * smpi_datatype_size(old_types[count-1])), DT_FLAG_DATA);
+  return MPI_SUCCESS;
+}
+
+void smpi_datatype_commit(MPI_Datatype* datatype)
+{
+  (*datatype)->flags= ( (*datatype)->flags | DT_FLAG_COMMITED);
+}
+
 typedef struct s_smpi_mpi_op {
   MPI_User_function *func;
 } s_smpi_mpi_op_t;
index db8815d..d730222 100644 (file)
@@ -28,7 +28,10 @@ int PMPI_Init(int *argc, char ***argv)
 {
   smpi_process_init(argc, argv);
 #ifdef HAVE_TRACING
-  TRACE_smpi_init(smpi_process_index());
+  int rank = smpi_process_index();
+  TRACE_smpi_init(rank);
+
+  TRACE_smpi_computing_init(rank);
 #endif
   smpi_bench_begin();
   return MPI_SUCCESS;
@@ -39,6 +42,8 @@ int PMPI_Finalize(void)
   smpi_process_finalize();
   smpi_bench_end();
 #ifdef HAVE_TRACING
+  int rank = smpi_process_index();
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_finalize(smpi_process_index());
 #endif
   smpi_process_destroy();
@@ -87,6 +92,10 @@ int PMPI_Abort(MPI_Comm comm, int errorcode)
 {
   smpi_bench_end();
   smpi_process_destroy();
+#ifdef HAVE_TRACING
+  int rank = smpi_process_index();
+  TRACE_smpi_computing_out(rank);
+#endif
   // FIXME: should kill all processes in comm instead
   simcall_process_kill(SIMIX_process_self());
   return MPI_SUCCESS;
@@ -101,6 +110,11 @@ double PMPI_Wtime(void)
   smpi_bench_begin();
   return time;
 }
+extern double sg_maxmin_precision;
+double PMPI_Wtick(void)
+{
+  return sg_maxmin_precision;
+}
 
 int PMPI_Address(void *location, MPI_Aint * address)
 {
@@ -111,6 +125,7 @@ int PMPI_Address(void *location, MPI_Aint * address)
     retval = MPI_ERR_ARG;
   } else {
     *address = (MPI_Aint) location;
+    retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
   return retval;
@@ -124,8 +139,8 @@ int PMPI_Type_free(MPI_Datatype * datatype)
   if (!datatype) {
     retval = MPI_ERR_ARG;
   } else {
-    // FIXME: always fail for now
-    retval = MPI_ERR_TYPE;
+    smpi_datatype_free(datatype);
+    retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
   return retval;
@@ -908,6 +923,7 @@ int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src,
   return retval;
 }
 
+
 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst,
               int tag, MPI_Comm comm, MPI_Request * request)
 {
@@ -916,6 +932,7 @@ int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int dst_traced = smpi_group_rank(smpi_comm_group(comm), dst);
   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
   TRACE_smpi_send(rank, rank, dst_traced);
@@ -931,11 +948,14 @@ int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst,
 #ifdef HAVE_TRACING
   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
   (*request)->send = 1;
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
 }
 
+
+
 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag,
              MPI_Comm comm, MPI_Status * status)
 {
@@ -945,6 +965,8 @@ int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag,
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
   int src_traced = smpi_group_rank(smpi_comm_group(comm), src);
+  TRACE_smpi_computing_out(rank);
+
   TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -954,8 +976,11 @@ int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag,
     retval = MPI_SUCCESS;
   }
 #ifdef HAVE_TRACING
+  //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
+  if(status!=MPI_STATUS_IGNORE)src_traced = smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE);
   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
   TRACE_smpi_recv(rank, src_traced, rank);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -969,6 +994,7 @@ int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int dst_traced = smpi_group_rank(smpi_comm_group(comm), dst);
   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
   TRACE_smpi_send(rank, rank, dst_traced);
@@ -981,6 +1007,7 @@ int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -996,6 +1023,7 @@ int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int dst_traced = smpi_group_rank(smpi_comm_group(comm), dst);
   int src_traced = smpi_group_rank(smpi_comm_group(comm), src);
   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__);
@@ -1016,6 +1044,8 @@ int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
   TRACE_smpi_recv(rank, rank, dst_traced);
   TRACE_smpi_recv(rank, src_traced, rank);
+  TRACE_smpi_computing_in(rank);
+
 #endif
   smpi_bench_begin();
   return retval;
@@ -1072,6 +1102,56 @@ int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag,
   return retval;
 }
 
+int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
+{
+  int retval;
+
+  smpi_bench_end();
+  if (flag == NULL) {
+    retval = MPI_ERR_ARG;
+  } else {
+    *flag = smpi_mpi_testall(count, requests, statuses);
+    retval = MPI_SUCCESS;
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
+  int retval;
+  smpi_bench_end();
+
+  if (status == NULL) {
+     retval = MPI_ERR_ARG;
+  }else if (comm == MPI_COMM_NULL) {
+       retval = MPI_ERR_COMM;
+  } else {
+       smpi_mpi_probe(source, tag, comm, status);
+       retval = MPI_SUCCESS;
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+
+int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
+  int retval;
+  smpi_bench_end();
+
+  if (flag == NULL) {
+       retval = MPI_ERR_ARG;
+    }else if (status == NULL) {
+     retval = MPI_ERR_ARG;
+  }else if (comm == MPI_COMM_NULL) {
+       retval = MPI_ERR_COMM;
+  } else {
+       smpi_mpi_iprobe(source, tag, comm, flag, status);
+       retval = MPI_SUCCESS;
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
 {
   int retval;
@@ -1081,6 +1161,8 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status)
   int rank = request && (*request)->comm != MPI_COMM_NULL
       ? smpi_comm_rank((*request)->comm)
       : -1;
+  TRACE_smpi_computing_out(rank);
+
   MPI_Group group = smpi_comm_group((*request)->comm);
   int src_traced = smpi_group_rank(group, (*request)->src);
   int dst_traced = smpi_group_rank(group, (*request)->dst);
@@ -1100,6 +1182,8 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status)
   if (is_wait_for_receive) {
     TRACE_smpi_recv(rank, src_traced, dst_traced);
   }
+  TRACE_smpi_computing_in(rank);
+
 #endif
   smpi_bench_begin();
   return retval;
@@ -1140,7 +1224,10 @@ int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * sta
     }
   }
   int rank_traced = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank_traced);
+
   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__);
+
 #endif
   if (index == NULL) {
     retval = MPI_ERR_ARG;
@@ -1161,6 +1248,8 @@ int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * sta
   xbt_dynar_free(&srcs);
   xbt_dynar_free(&dsts);
   xbt_dynar_free(&recvs);
+  TRACE_smpi_computing_in(rank_traced);
+
 #endif
   smpi_bench_begin();
   return retval;
@@ -1192,6 +1281,8 @@ int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
     xbt_free(arecv);
   }
   int rank_traced = smpi_comm_rank (MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank_traced);
+
   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__);
 #endif
   smpi_mpi_waitall(count, requests, status);
@@ -1210,6 +1301,7 @@ int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
   xbt_dynar_free(&srcs);
   xbt_dynar_free(&dsts);
   xbt_dynar_free(&recvs);
+  TRACE_smpi_computing_in(rank_traced);
 #endif
   smpi_bench_begin();
   return MPI_SUCCESS;
@@ -1238,6 +1330,7 @@ int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm c
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
@@ -1249,6 +1342,7 @@ int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm c
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1261,6 +1355,7 @@ int PMPI_Barrier(MPI_Comm comm)
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1271,6 +1366,7 @@ int PMPI_Barrier(MPI_Comm comm)
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1285,6 +1381,7 @@ int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
@@ -1300,6 +1397,7 @@ int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1314,6 +1412,7 @@ int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
@@ -1331,6 +1430,7 @@ int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1345,6 +1445,7 @@ int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1373,6 +1474,7 @@ int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1389,6 +1491,7 @@ int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1403,6 +1506,7 @@ int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
@@ -1418,6 +1522,7 @@ int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1432,6 +1537,7 @@ int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
@@ -1449,6 +1555,7 @@ int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1462,6 +1569,7 @@ int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   int root_traced = smpi_group_rank(smpi_comm_group(comm), root);
   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
 #endif
@@ -1475,6 +1583,7 @@ int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1488,6 +1597,7 @@ int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1502,6 +1612,7 @@ int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1515,6 +1626,7 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1529,6 +1641,7 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1543,6 +1656,7 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
 
   smpi_bench_end();
 #ifdef HAVE_TRACING
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1571,6 +1685,7 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1585,6 +1700,7 @@ int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1614,6 +1730,7 @@ int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1628,6 +1745,7 @@ int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
   smpi_bench_end();
 #ifdef HAVE_TRACING
   int rank = comm != MPI_COMM_NULL ? smpi_comm_rank(comm) : -1;
+  TRACE_smpi_computing_out(rank);
   TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
 #endif
   if (comm == MPI_COMM_NULL) {
@@ -1646,6 +1764,7 @@ int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
   }
 #ifdef HAVE_TRACING
   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
 #endif
   smpi_bench_begin();
   return retval;
@@ -1691,12 +1810,117 @@ int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
   return retval;
 }
 
+int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
+  int retval;
+
+  smpi_bench_end();
+  if (old_type == MPI_DATATYPE_NULL) {
+    retval = MPI_ERR_TYPE;
+  } else if (count<=0){
+    retval = MPI_ERR_COUNT;
+  } else {
+    retval = smpi_datatype_contiguous(count, old_type, new_type);
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+int PMPI_Type_commit(MPI_Datatype* datatype) {
+  int retval;
+
+  smpi_bench_end();
+  if (datatype == MPI_DATATYPE_NULL) {
+    retval = MPI_ERR_TYPE;
+  } else {
+    smpi_datatype_commit(datatype);
+    retval = MPI_SUCCESS;
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+
+int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
+  int retval;
+
+  smpi_bench_end();
+  if (old_type == MPI_DATATYPE_NULL) {
+    retval = MPI_ERR_TYPE;
+  } else if (count<=0 || blocklen<=0){
+    retval = MPI_ERR_COUNT;
+  } else {
+    retval = smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
+  int retval;
+
+  smpi_bench_end();
+  if (old_type == MPI_DATATYPE_NULL) {
+    retval = MPI_ERR_TYPE;
+  } else if (count<=0 || blocklen<=0){
+    retval = MPI_ERR_COUNT;
+  } else {
+    retval = smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+
+int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
+  int retval;
+
+  smpi_bench_end();
+  if (old_type == MPI_DATATYPE_NULL) {
+    retval = MPI_ERR_TYPE;
+  } else if (count<=0){
+    retval = MPI_ERR_COUNT;
+  } else {
+    retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
+  int retval;
+
+  smpi_bench_end();
+  if (old_type == MPI_DATATYPE_NULL) {
+    retval = MPI_ERR_TYPE;
+  } else if (count<=0){
+    retval = MPI_ERR_COUNT;
+  } else {
+    retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
+  }
+  smpi_bench_begin();
+  return retval;
+}
+
+
+int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
+  int retval;
+
+  smpi_bench_end();
+  if (count<=0){
+    retval = MPI_ERR_COUNT;
+  } else {
+    retval = smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
+  }
+  smpi_bench_begin();
+  return retval;}
+
+
 /* The following calls are not yet implemented and will fail at runtime. */
 /* Once implemented, please move them above this notice. */
 
 static int not_yet_implemented(void) {
-   xbt_die("Not yet implemented");
-   return MPI_ERR_OTHER;
+         XBT_WARN("Not yet implemented");
+   return MPI_SUCCESS;
 }
 
 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
@@ -1787,9 +2011,6 @@ int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler) {
    return not_yet_implemented();
 }
 
-int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* newtype) {
-   return not_yet_implemented();
-}
 
 int PMPI_Cancel(MPI_Request* request) {
    return not_yet_implemented();
@@ -1815,30 +2036,6 @@ int PMPI_Unpack(void* inbuf, int insize, int* position, void* outbuf, int outcou
    return not_yet_implemented();
 }
 
-int PMPI_Type_commit(MPI_Datatype* datatype) {
-   return not_yet_implemented();
-}
-
-int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* newtype) {
-   return not_yet_implemented();
-}
-
-int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* newtype) {
-   return not_yet_implemented();
-}
-
-int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* newtype) {
-   return not_yet_implemented();
-}
-
-int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* newtype) {
-   return not_yet_implemented();
-}
-
-int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* newtype) {
-   return not_yet_implemented();
-}
-
 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
    return not_yet_implemented();
 }
@@ -1879,9 +2076,6 @@ int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dest, int tag,
    return not_yet_implemented();
 }
 
-int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
-   return not_yet_implemented();
-}
 
 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
    return not_yet_implemented();
@@ -1923,10 +2117,6 @@ int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int out
    return not_yet_implemented();
 }
 
-int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses) {
-   return not_yet_implemented();
-}
-
 int PMPI_Get_elements(MPI_Status* status, MPI_Datatype datatype, int* elements) {
    return not_yet_implemented();
 }
@@ -1935,10 +2125,6 @@ int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
    return not_yet_implemented();
 }
 
-int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
-   return not_yet_implemented();
-}
-
 int PMPI_Initialized(int* flag) {
    return not_yet_implemented();
 }
index 657b3a4..dc35a68 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_replay,smpi,"Trace Replay with SMPI");
 
+int communicator_size = 0;
+
+typedef struct {
+  xbt_dynar_t isends; /* of MPI_Request */
+  xbt_dynar_t irecvs; /* of MPI_Request */
+} s_smpi_replay_globals_t, *smpi_replay_globals_t;
+
 /* Helper function */
 static double parse_double(const char *string)
 {
@@ -23,86 +30,295 @@ static double parse_double(const char *string)
   return value;
 }
 
+static void action_init(const char *const *action)
+{
+  XBT_DEBUG("Initialize the counters");
+  smpi_replay_globals_t globals =  xbt_new(s_smpi_replay_globals_t, 1);
+  globals->isends = xbt_dynar_new(sizeof(MPI_Request),NULL);
+  globals->irecvs = xbt_dynar_new(sizeof(MPI_Request),NULL);
+
+  smpi_process_set_user_data((void*) globals);
+
+  /* start a simulated timer */
+  smpi_process_simulated_start();
+}
+
+static void action_finalize(const char *const *action)
+{
+  double sim_time= 1.;
+  smpi_replay_globals_t globals =
+      (smpi_replay_globals_t) smpi_process_get_user_data();
+
+  if (globals){
+    XBT_DEBUG("There are %lu isends and %lu irecvs in the dynars",
+         xbt_dynar_length(globals->isends),xbt_dynar_length(globals->irecvs));
+    xbt_dynar_free_container(&(globals->isends));
+    xbt_dynar_free_container(&(globals->irecvs));
+  }
+  free(globals);
+  /* end the simulated timer */
+  sim_time = smpi_process_simulated_elapsed();
+  if (!smpi_process_index())
+    XBT_INFO("Simulation time %g", sim_time);
+  smpi_process_finalize();
+  smpi_process_destroy();
+}
+
+static void action_comm_size(const char *const *action)
+{
+  double clock = smpi_process_simulated_elapsed();
+
+  communicator_size = parse_double(action[2]);
+
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
+}
+
+
 static void action_compute(const char *const *action)
 {
-  XBT_DEBUG("Start to compute %.0f flops", parse_double(action[2]));
-  smpi_sample_flops(parse_double(action[2]));
+  double clock = smpi_process_simulated_elapsed();
+  smpi_execute_flops(parse_double(action[2]));
+
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
 }
 
 static void action_send(const char *const *action)
 {
   int to = atoi(action[2]);
   double size=parse_double(action[3]);
-
-  XBT_DEBUG("send %.0f bytes to rank%d (%s)",size, to, action[2]);
+  double clock = smpi_process_simulated_elapsed();
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank);
+  int dst_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), to);
+  TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
+  TRACE_smpi_send(rank, rank, dst_traced);
+#endif
 
   smpi_mpi_send(NULL, size, MPI_BYTE, to , 0, MPI_COMM_WORLD);
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
+#ifdef HAVE_TRACING
+  TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
+#endif
+
 }
 
 static void action_Isend(const char *const *action)
 {
   int to = atoi(action[2]);
   double size=parse_double(action[3]);
+  double clock = smpi_process_simulated_elapsed();
+  smpi_replay_globals_t globals =
+     (smpi_replay_globals_t) smpi_process_get_user_data();
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank);
+  int dst_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), to);
+  TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
+  TRACE_smpi_send(rank, rank, dst_traced);
+#endif
 
   MPI_Request request = smpi_mpi_isend(NULL, size, MPI_BYTE, to, 0,
                                        MPI_COMM_WORLD);
+#ifdef HAVE_TRACING
+  TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
+  request->send = 1;
+  TRACE_smpi_computing_in(rank);
+#endif
+
+  xbt_dynar_push(globals->isends,&request);
 
-  //TODO do something with request
-  request = NULL;
+  //TODO do the asynchronous cleanup
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
 }
 
 static void action_recv(const char *const *action) {
   int from = atoi(action[2]);
-  XBT_DEBUG("receive from rank%d (%s)",from, action[2]);
-
+  double size=parse_double(action[3]);
+  double clock = smpi_process_simulated_elapsed();
   MPI_Status status;
-  //TODO find a way to get the message size
-  smpi_mpi_recv(NULL, 1e9, MPI_BYTE, from, 0, MPI_COMM_WORLD, &status);
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from);
+  TRACE_smpi_computing_out(rank);
+
+  TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
+#endif
+
+  smpi_mpi_recv(NULL, size, MPI_BYTE, from, 0, MPI_COMM_WORLD, &status);
+
+#ifdef HAVE_TRACING
+  TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
+  TRACE_smpi_recv(rank, src_traced, rank);
+  TRACE_smpi_computing_in(rank);
+#endif
 
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
 }
 
 static void action_Irecv(const char *const *action)
 {
   int from = atoi(action[2]);
+  double size=parse_double(action[3]);
+  double clock = smpi_process_simulated_elapsed();
   MPI_Request request;
+  smpi_replay_globals_t globals =
+     (smpi_replay_globals_t) smpi_process_get_user_data();
 
-  XBT_DEBUG("Asynchronous receive from rank%d (%s)",from, action[2]);
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from);
+  TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
+#endif
 
-  //TODO find a way to get the message size
-  request = smpi_mpi_irecv(NULL, 1e9, MPI_BYTE, from, 0, MPI_COMM_WORLD);
+  request = smpi_mpi_irecv(NULL, size, MPI_BYTE, from, 0, MPI_COMM_WORLD);
+#ifdef HAVE_TRACING
+  TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
+  request->recv = 1;
+#endif
+  xbt_dynar_push(globals->irecvs,&request);
 
-  //TODO do something with request
-  request = NULL;
+  //TODO do the asynchronous cleanup
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
 }
 
 static void action_wait(const char *const *action){
+  double clock = smpi_process_simulated_elapsed();
   MPI_Request request;
   MPI_Status status;
+  smpi_replay_globals_t globals =
+      (smpi_replay_globals_t) smpi_process_get_user_data();
+
+  xbt_assert(xbt_dynar_length(globals->irecvs),
+      "action wait not preceded by any irecv: %s",
+      xbt_str_join_array(action," "));
+  request = xbt_dynar_pop_as(globals->irecvs,MPI_Request);
+#ifdef HAVE_TRACING
+  int rank = request && request->comm != MPI_COMM_NULL
+      ? smpi_comm_rank(request->comm)
+      : -1;
+  TRACE_smpi_computing_out(rank);
 
+  MPI_Group group = smpi_comm_group(request->comm);
+  int src_traced = smpi_group_rank(group, request->src);
+  int dst_traced = smpi_group_rank(group, request->dst);
+  int is_wait_for_receive = request->recv;
+  TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__);
+#endif
   smpi_mpi_wait(&request, &status);
+#ifdef HAVE_TRACING
+  TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
+  if (is_wait_for_receive) {
+    TRACE_smpi_recv(rank, src_traced, dst_traced);
+  }
+  TRACE_smpi_computing_in(rank);
+#endif
+
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
 }
 
 static void action_barrier(const char *const *action){
+  double clock = smpi_process_simulated_elapsed();
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank);
+  TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
+#endif
   smpi_mpi_barrier(MPI_COMM_WORLD);
+#ifdef HAVE_TRACING
+  TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
+#endif
+
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
+}
+
+static void action_bcast(const char *const *action)
+{
+  double size = parse_double(action[2]);
+  double clock = smpi_process_simulated_elapsed();
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank);
+  int root_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), 0);
+  TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
+#endif
+
+  smpi_mpi_bcast(NULL, size, MPI_BYTE, 0, MPI_COMM_WORLD);
+#ifdef HAVE_TRACING
+  TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
+#endif
+
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
+}
+
+static void action_reduce(const char *const *action)
+{
+  double size = parse_double(action[2]);
+  double clock = smpi_process_simulated_elapsed();
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank);
+  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, size, MPI_BYTE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
+#ifdef HAVE_TRACING
+  TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
+#endif
+
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
+}
+
+static void action_allReduce(const char *const *action) {
+  double comm_size = parse_double(action[2]);
+  double comp_size = parse_double(action[3]);
+  double clock = smpi_process_simulated_elapsed();
+#ifdef HAVE_TRACING
+  int rank = smpi_comm_rank(MPI_COMM_WORLD);
+  TRACE_smpi_computing_out(rank);
+  TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
+#endif
+  smpi_mpi_reduce(NULL, NULL, comm_size, MPI_BYTE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
+  smpi_execute_flops(comp_size);
+  smpi_mpi_bcast(NULL, comm_size, MPI_BYTE, 0, MPI_COMM_WORLD);
+#ifdef HAVE_TRACING
+  TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+  TRACE_smpi_computing_in(rank);
+#endif
+  XBT_VERB("%s %f", xbt_str_join_array(action, " "),
+           smpi_process_simulated_elapsed()-clock);
 }
 
 void smpi_replay_init(int *argc, char***argv){
   PMPI_Init(argc, argv);
   _xbt_replay_action_init();
 
-//  xbt_replay_action_register("init",     action_init);
-//  xbt_replay_action_register("finalize", action_finalize);
-//  xbt_replay_action_register("comm_size",action_comm_size);
+  xbt_replay_action_register("init",     action_init);
+  xbt_replay_action_register("finalize", action_finalize);
+  xbt_replay_action_register("comm_size",action_comm_size);
   xbt_replay_action_register("send",     action_send);
   xbt_replay_action_register("Isend",    action_Isend);
   xbt_replay_action_register("recv",     action_recv);
   xbt_replay_action_register("Irecv",    action_Irecv);
   xbt_replay_action_register("wait",     action_wait);
   xbt_replay_action_register("barrier",  action_barrier);
-//  xbt_replay_action_register("bcast",    action_bcast);
-//  xbt_replay_action_register("reduce",   action_reduce);
-//  xbt_replay_action_register("allReduce",action_allReduce);
-//  xbt_replay_action_register("sleep",    action_sleep);
+  xbt_replay_action_register("bcast",    action_bcast);
+  xbt_replay_action_register("reduce",   action_reduce);
+  xbt_replay_action_register("allReduce",action_allReduce);
   xbt_replay_action_register("compute",  action_compute);
 
   xbt_replay_action_runner(*argc, *argv);
index aa962e2..2ef2757 100755 (executable)
@@ -27,6 +27,8 @@ function usage () {
     echo "      [-np <numprocs>]          # use that amount of processes from the hostfile."
     echo "                                # By default, all processes of the hostfile are used."
     echo "      [-trace]                  # activate tracing"
+    echo "      [-trace-comment <comment>]# put a comment on the top of the trace file"
+    echo "      [-trace-comment-file <file>]   # put file contents on the top of the trace file as comment"
     echo "      [-trace-grouped]          # group MPI processes by location"
     echo "      [-trace-resource]         # trace resource utilization"
     echo "      [-trace-triva]            # generate configuration for Triva's GraphView"
@@ -80,8 +82,18 @@ while true; do
    ;;
 
    "-trace")
-       TRACE_ACTIVE="true"
-         shift 1
+      TRACE_ACTIVE="true"
+      shift 1
+   ;;
+
+   "-trace-comment")
+      TRACE_COMMENT="$2"
+      shift 2
+   ;;
+
+   "-trace-comment-file")
+      TRACE_COMMENT_FILE="$2"
+      shift 2
    ;;
 
    "-trace-file")
@@ -212,6 +224,14 @@ if [ -n "${HOSTFILE}" ] && [ -f ${HOSTFILE} ]; then
       NUMHOSTS=`cat ${HOSTFILE} | wc -l`
 fi
 
+if [ ${EXEC} = "./smpi_replay" ]; then 
+  APP_TRACES=$1;
+  if [ -n "${APP_TRACES}" ] && [ -f ${APP_TRACES} ]; then
+     hosttraces=(`cat ${APP_TRACES} | tr \\\n " "`)
+     NUMTRACES=`cat ${APP_TRACES} | wc -l`
+  fi
+fi
+
 ##----------------------------------------------------------
 ##  generate application.xml with hostnames from hostfile:
 ##  the name of host_i (1<=i<=p, where -np p) is the line i
@@ -250,9 +270,17 @@ do
   fi
   echo "  <process host=\"${host}\" function=\"$i\"> <!-- function name used only for logging -->" >> ${APPLICATIONTMP}
   echo "    <argument value=\"$i\"/> <!-- rank -->" >> ${APPLICATIONTMP}
-  for ARG in $*; do
-    echo "    <argument value=\"${ARG}\"/>" >> ${APPLICATIONTMP}
-  done
+  if [ ${EXEC} = "./smpi_replay" ]; then
+    if  [ ${NUMTRACES} -gt 1 ]; then
+      echo "    <argument value=\"${hosttraces[$j]}\"/>" >> ${APPLICATIONTMP}
+    else
+      echo "    <argument value=\"${hosttraces[0]}\"/>" >> ${APPLICATIONTMP}
+    fi
+  else 
+    for ARG in $*; do
+       echo "    <argument value=\"${ARG}\"/>" >> ${APPLICATIONTMP}
+    done
+  fi
   echo "  </process>" >> ${APPLICATIONTMP}
 done
 
@@ -269,6 +297,14 @@ if [ -n "${TRACE_ACTIVE}" ]; then
   fi
   TRACEOPTIONS="--cfg=tracing:1 --cfg=tracing/filename:${TRACE_FILENAME} --cfg=tracing/smpi:1"
 
+  if [ -n "${TRACE_COMMENT}" ]; then
+    TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/comment:${TRACE_COMMENT}"
+  fi
+
+  if [ -n "${TRACE_COMMENT_FILE}" ]; then
+    TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/comment_file:${TRACE_COMMENT_FILE}"
+  fi
+
   if [ -n "${TRACE_GROUPED}" ]; then
     TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/smpi/group:1"
   fi
index a441d1e..929c106 100644 (file)
@@ -659,7 +659,6 @@ void lmm_solve(lmm_system_t sys)
           make_elem_inactive(elem);
           elem_list = &(cnst->element_set);
           xbt_swag_foreach(elem, elem_list) {
-              make_elem_active(elem);
             if (elem->variable->weight <= 0 || elem->variable->value > 0)
               break;
             if (elem->value > 0)
index 99d03be..ed1db7b 100644 (file)
@@ -77,6 +77,13 @@ static double constant_bandwidth_constraint(double rate, double bound,
 /**********************/
 /*   SMPI callbacks   */
 /**********************/
+
+static int factor_cmp(const void *pa, const void *pb)
+{
+  return (((s_smpi_factor_t*)pa)->factor > ((s_smpi_factor_t*)pb)->factor);
+}
+
+
 static xbt_dynar_t parse_factor(const char *smpi_coef_string)
 {
   char *value = NULL;
@@ -98,6 +105,12 @@ static xbt_dynar_t parse_factor(const char *smpi_coef_string)
     xbt_dynar_free(&radical_elements2);
   }
   xbt_dynar_free(&radical_elements);
+  iter=0;
+  xbt_dynar_sort(smpi_factor, &factor_cmp);
+  xbt_dynar_foreach(smpi_factor, iter, fact) {
+    XBT_DEBUG("ordered smpi_factor:\t%ld : %f", fact.factor, fact.value);
+
+  }
   return smpi_factor;
 }
 
@@ -672,8 +685,7 @@ static void smpi_gap_append(double size, const link_CM02_t link,
           xbt_fifo_get_item_content(xbt_fifo_get_last_item(fifo));
       bw = net_get_link_bandwidth(link);
       action->sender.gap =
-          last_action->sender.gap + max(sg_sender_gap,
-                                        last_action->sender.size / bw);
+          max(sg_sender_gap,last_action->sender.size / bw);
       action->latency += action->sender.gap;
     }
     /* Append action as last send */
index bb5a356..25175c7 100644 (file)
@@ -109,13 +109,13 @@ static void parse_ns3_add_router(sg_platf_router_cbarg_t router)
     );
 }
 
-static void parse_ns3_add_AS(const char*id, int routing)
+static void parse_ns3_add_AS(sg_platf_AS_cbarg_t AS)
 {
-  XBT_DEBUG("NS3_ADD_AS '%s'",id);
+  XBT_DEBUG("NS3_ADD_AS '%s'",AS->id);
   xbt_lib_set(as_router_lib,
-              id,
+              AS->id,
               NS3_ASR_LEVEL,
-              ns3_add_AS(id)
+              ns3_add_AS(AS->id)
     );
 }
 
diff --git a/src/surf/platf_generator.c b/src/surf/platf_generator.c
new file mode 100644 (file)
index 0000000..63e816e
--- /dev/null
@@ -0,0 +1,737 @@
+
+
+#include "simgrid/platf_generator.h"
+#include "platf_generator_private.h"
+#include "xbt.h"
+#include "xbt/RngStream.h"
+#include "surf/simgrid_dtd.h"
+#include "surf_private.h"
+#include <math.h>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(platf_generator, surf, "Platform Generator");
+
+static xbt_graph_t platform_graph = NULL;
+static xbt_dynar_t promoter_dynar = NULL;
+static xbt_dynar_t labeler_dynar = NULL;
+
+static RngStream rng_stream = NULL;
+
+static unsigned long last_link_id = 0;
+
+xbt_graph_t platf_graph_get(void) {
+  // We need some debug, so let's add this function
+  // WARNING : should be removed when it becomes useless
+  return platform_graph;
+}
+
+/**
+ * \brief Set the seed of the platform generator RngStream
+ *
+ * This RngStream is used to generate all the random values needed to
+ * generate the platform
+ *
+ * \param seed A array of six integer; if NULL, the default seed will be used.
+ */
+void platf_random_seed(unsigned long seed[6]) {
+
+  if(rng_stream == NULL) {
+    //stream not created yet, we do it now
+    rng_stream = RngStream_CreateStream(NULL);
+  }
+  if(seed != NULL) {
+    RngStream_SetSeed(rng_stream, seed);
+  }
+}
+
+/**
+ * \brief Initialize the platform generator
+ *
+ * This function create the graph and add node_count nodes to it
+ * \param node_count The number of nodes of the platform
+ */
+void platf_graph_init(unsigned long node_count) {
+  unsigned long i;
+  platform_graph = xbt_graph_new_graph(FALSE, NULL);
+  if(rng_stream == NULL) {
+    rng_stream = RngStream_CreateStream(NULL);
+  }
+
+  for(i=0 ; i<node_count ; i++) {
+    context_node_t node_data = NULL;
+    node_data = xbt_new0(s_context_node_t, 1);
+    node_data->id = i+1;
+    node_data->x = 0;
+    node_data->y = 0;
+    node_data->degree = 0;
+    node_data->kind = ROUTER;
+    node_data->connect_checked = FALSE;
+    xbt_graph_new_node(platform_graph, (void*) node_data);
+  }
+
+  last_link_id = 0;
+
+}
+
+/**
+ * \brief Connect two nodes
+ * \param node1 The first node to connect
+ * \param node2 The second node to connect
+ */
+void platf_node_connect(xbt_node_t node1, xbt_node_t node2) {
+  context_node_t node1_data;
+  context_node_t node2_data;
+  node1_data = (context_node_t) xbt_graph_node_get_data(node1);
+  node2_data = (context_node_t) xbt_graph_node_get_data(node2);
+  node1_data->degree++;
+  node2_data->degree++;
+
+  context_edge_t edge_data = NULL;
+  edge_data = xbt_new0(s_context_edge_t, 1);
+  edge_data->id = ++last_link_id;
+  edge_data->length = platf_node_distance(node1, node2);
+  edge_data->labeled = FALSE;
+  xbt_graph_new_edge(platform_graph, node1, node2, (void*)edge_data);
+}
+
+/**
+ * \brief Compute the distance between two nodes
+ * \param node1 The first node
+ * \param node2 The second node
+ * \return The distance between node1 and node2
+ */
+double platf_node_distance(xbt_node_t node1, xbt_node_t node2) {
+  context_node_t node1_data;
+  context_node_t node2_data;
+  double delta_x;
+  double delta_y;
+  double distance;
+  node1_data = (context_node_t) xbt_graph_node_get_data(node1);
+  node2_data = (context_node_t) xbt_graph_node_get_data(node2);
+  delta_x = node1_data->x - node2_data->x;
+  delta_y = node1_data->y - node2_data->y;
+  distance = sqrt(delta_x*delta_x + delta_y*delta_y);
+  return distance;
+}
+
+/**
+ * \brief Initialize the platform, placing nodes uniformly on the unit square
+ * \param node_count The number of node
+ */
+void platf_graph_uniform(unsigned long node_count) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t graph_node = NULL;
+  context_node_t node_data = NULL;
+  unsigned int i;
+  platf_graph_init(node_count);
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    node_data = (context_node_t) xbt_graph_node_get_data(graph_node);
+    node_data->x = RngStream_RandU01(rng_stream);
+    node_data->y = RngStream_RandU01(rng_stream);
+  }
+}
+
+/**
+ * \brief Initialize the platform, placing nodes in little clusters on the unit square
+ * \param node_count The number of node
+ */
+void platf_graph_heavytailed(unsigned long node_count) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t graph_node = NULL;
+  context_node_t node_data = NULL;
+  unsigned int i;
+  platf_graph_init(node_count);
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    node_data = (context_node_t) xbt_graph_node_get_data(graph_node);
+    node_data->x = random_pareto(0, 1, 1.0/*K*/, 10e9/*P*/, 1.0/*alpha*/);
+    node_data->y = random_pareto(0, 1, 1.0/*K*/, 10e9/*P*/, 1.0/*alpha*/);
+  }
+}
+
+/**
+ * \brief Creates a simple topology where all nodes are connected to the first one in a star fashion
+ */
+void platf_graph_interconnect_star(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t graph_node = NULL;
+  xbt_node_t first_node = NULL;
+  unsigned int i;
+
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    if(i==0) {
+      //Ok, we get the first node, let's keep it somewhere...
+      first_node = graph_node;
+    } else {
+      //All the other nodes are connected to the first one
+      platf_node_connect(graph_node, first_node);
+    }
+  }
+}
+
+/**
+ * \brief Creates a simple topology where all nodes are connected in line
+ */
+void platf_graph_interconnect_line(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t graph_node = NULL;
+  xbt_node_t old_node = NULL;
+  unsigned int i;
+
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    if(old_node != NULL) {
+      platf_node_connect(graph_node, old_node);
+    }
+    old_node = graph_node;
+  }
+}
+
+/**
+ * \brief Create a simple topology where all nodes are connected along a ring
+ */
+void platf_graph_interconnect_ring(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t graph_node = NULL;
+  xbt_node_t old_node = NULL;
+  xbt_node_t first_node = NULL;
+  unsigned int i;
+
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    if(i == 0) {
+      // this is the first node, let's keep it somewhere
+      first_node = graph_node;
+    } else {
+      //connect each node to the previous one
+      platf_node_connect(graph_node, old_node);
+    }
+    old_node = graph_node;
+  }
+  //we still have to connect the first and the last node together
+  platf_node_connect(first_node, graph_node);
+}
+
+/**
+ * \brief Create a simple topology where all nodes are connected to each other, in a clique manner
+ */
+void platf_graph_interconnect_clique(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t first_node = NULL;
+  xbt_node_t second_node = NULL;
+  unsigned int i,j;
+
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, first_node) {
+    xbt_dynar_foreach(dynar_nodes, j, second_node) {
+      if(j>=i)
+        break;
+      platf_node_connect(first_node, second_node);
+    }
+  }
+}
+
+/**
+ * \brief Creates a topology where the probability to connect two nodes is uniform (unrealistic, but simple)
+ * \param alpha Probability for two nodes to get connected
+ */
+void platf_graph_interconnect_uniform(double alpha) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t first_node = NULL;
+  xbt_node_t second_node = NULL;
+  unsigned int i,j;
+
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, first_node) {
+    xbt_dynar_foreach(dynar_nodes, j, second_node) {
+      if(j>=i)
+        break;
+      if(RngStream_RandU01(rng_stream) < alpha) {
+        platf_node_connect(first_node, second_node);
+      }
+    }
+  }
+}
+
+/**
+ * \brief Create a topology where the probability follows an exponential law
+ * \param alpha Number of edges increases with alpha
+ */
+void platf_graph_interconnect_exponential(double alpha) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t first_node = NULL;
+  xbt_node_t second_node = NULL;
+  unsigned int i,j;
+  double L = sqrt(2.0); /*  L = c*sqrt(2); c=side of placement square */
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, first_node) {
+    xbt_dynar_foreach(dynar_nodes, j, second_node) {
+      if(j>=i)
+        break;
+      double d = platf_node_distance(first_node, second_node);
+      if(RngStream_RandU01(rng_stream) < alpha*exp(-d/(L-d))) {
+        platf_node_connect(first_node, second_node);
+      }
+    }
+  }
+}
+
+/**
+ * \brief Create a topology where the probability follows the model of Waxman
+ *
+ * see Waxman, Routing of Multipoint Connections, IEEE J. on Selected Areas in Comm., 1988
+ *
+ * \param alpha Number of edges increases with alpha
+ * \param beta Edge length heterogeneity increases with beta
+ */
+void platf_graph_interconnect_waxman(double alpha, double beta) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t first_node = NULL;
+  xbt_node_t second_node = NULL;
+  unsigned int i,j;
+  double L = sqrt(2.0); /*  L = c*sqrt(2); c=side of placement square */
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, first_node) {
+    xbt_dynar_foreach(dynar_nodes, j, second_node) {
+      if(j>=i)
+        break;
+      double d = platf_node_distance(first_node, second_node);
+      if(RngStream_RandU01(rng_stream) < alpha*exp(-d/(L*beta))) {
+        platf_node_connect(first_node, second_node);
+      }
+    }
+  }
+}
+
+/**
+ * \brief Create a topology where the probability follows the model of Zegura
+ * see Zegura, Calvert, Donahoo, A quantitative comparison of graph-based models
+ * for Internet topology, IEEE/ACM Transactions on Networking, 1997.
+ *
+ * \param alpha Probability of connexion for short edges
+ * \param beta Probability of connexion for long edges
+ * \param r Limit between long and short edges (between 0 and sqrt(2) since nodes are placed on the unit square)
+ */
+void platf_graph_interconnect_zegura(double alpha, double beta, double r) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t first_node = NULL;
+  xbt_node_t second_node = NULL;
+  unsigned int i,j;
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, first_node) {
+    xbt_dynar_foreach(dynar_nodes, j, second_node) {
+      if(j>=i)
+        break;
+      double d = platf_node_distance(first_node, second_node);
+      double proba = d < r ? alpha : beta;
+      if(RngStream_RandU01(rng_stream) < proba) {
+        platf_node_connect(first_node, second_node);
+      }
+    }
+  }
+}
+
+/**
+ * \brief Create a topology constructed according to the Barabasi-Albert algorithm (follows power laws)
+ * see Barabasi and Albert, Emergence of scaling in random networks, Science 1999, num 59, p509­-512.
+ */
+void platf_graph_interconnect_barabasi(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_node_t first_node = NULL;
+  xbt_node_t second_node = NULL;
+  context_node_t node_data = NULL;
+  unsigned int i,j;
+  unsigned long sum = 0;
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, first_node) {
+    xbt_dynar_foreach(dynar_nodes, j, second_node) {
+      if(j>=i)
+        break;
+      node_data = xbt_graph_node_get_data(second_node);
+      if(sum==0 || RngStream_RandU01(rng_stream) < ((double)(node_data->degree)/ (double)sum)) {
+        platf_node_connect(first_node, second_node);
+        sum += 2;
+      }
+    }
+  }
+}
+
+/**
+ * \brief Check if the produced graph is connected
+ *
+ * You should check if the produced graph is connected before doing anything
+ * on it. You probably don't want any isolated node or group of nodes...
+ *
+ * \return TRUE if the graph is connected, FALSE otherwise
+ */
+int platf_graph_is_connected(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_dynar_t connected_nodes = NULL;
+  xbt_dynar_t outgoing_edges = NULL;
+  xbt_node_t graph_node = NULL;
+  context_node_t node_data = NULL;
+  xbt_edge_t outedge = NULL;
+  unsigned long iterator;
+  unsigned int i;
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  connected_nodes = xbt_dynar_new(sizeof(xbt_node_t), NULL);
+
+  //Let's just check if every nodes are connected to something
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    node_data = xbt_graph_node_get_data(graph_node);
+    if(node_data->degree==0) {
+      return FALSE;
+    }
+  }
+
+  //We still need a real check
+  //Initialize the connected node array with the first node
+  xbt_dynar_get_cpy(dynar_nodes, 0, &graph_node);
+  node_data = xbt_graph_node_get_data(graph_node);
+  node_data->connect_checked = TRUE;
+  xbt_dynar_push(connected_nodes, &graph_node);
+  iterator = 0;
+  do {
+    //Get the next node
+    xbt_dynar_get_cpy(connected_nodes, iterator, &graph_node);
+    node_data = xbt_graph_node_get_data(graph_node);
+
+    //add all the linked nodes to the connected node array
+    outgoing_edges = xbt_graph_node_get_outedges(graph_node);
+    xbt_dynar_foreach(outgoing_edges, i, outedge) {
+      xbt_node_t src = xbt_graph_edge_get_source(outedge);
+      xbt_node_t dst = xbt_graph_edge_get_target(outedge);
+      node_data = xbt_graph_node_get_data(src);
+      if(!node_data->connect_checked) {
+        xbt_dynar_push(connected_nodes, &src);
+        node_data->connect_checked = TRUE;
+      }
+      node_data = xbt_graph_node_get_data(dst);
+      if(!node_data->connect_checked) {
+        xbt_dynar_push(connected_nodes, &dst);
+        node_data->connect_checked = TRUE;
+      }
+    }
+  } while(++iterator < xbt_dynar_length(connected_nodes));
+
+  // The graph is connected if the connected node array has the same length
+  // as the graph node array
+  return xbt_dynar_length(connected_nodes) == xbt_dynar_length(dynar_nodes);
+}
+
+
+/**
+ * \brief Remove the links in the created topology
+ *
+ * This is useful when the created topology is not connected, and you want
+ * to generate a new one.
+ */
+void platf_graph_clear_links(void) {
+  xbt_dynar_t dynar_nodes = NULL;
+  xbt_dynar_t dynar_edges = NULL;
+  xbt_dynar_t dynar_edges_cpy = NULL;
+  xbt_node_t graph_node = NULL;
+  xbt_edge_t graph_edge = NULL;
+  context_node_t node_data = NULL;
+  unsigned int i;
+
+  //The graph edge dynar will be modified directly, so we work on a copy of it
+  dynar_edges = xbt_graph_get_edges(platform_graph);
+  dynar_edges_cpy = xbt_dynar_new(sizeof(xbt_edge_t), NULL);
+  xbt_dynar_foreach(dynar_edges, i, graph_edge) {
+    xbt_dynar_push_as(dynar_edges_cpy, xbt_edge_t, graph_edge);
+  }
+  //Delete edges from the graph
+  xbt_dynar_foreach(dynar_edges_cpy, i, graph_edge) {
+    xbt_graph_free_edge(platform_graph, graph_edge, xbt_free);
+  }
+  //remove the dynar copy
+  xbt_dynar_free(&dynar_edges_cpy);
+
+  //All the nodes will be of degree 0, unchecked from connectedness
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    node_data = xbt_graph_node_get_data(graph_node);
+    node_data->degree = 0;
+    node_data->connect_checked = FALSE;
+  }
+}
+
+/**
+ * \brief Promote a node to a host
+ *
+ * This function should be called in callbacks registered with the
+ * platf_graph_promoter function.
+ *
+ * \param node The node to promote
+ * \param parameters The parameters needed to build the host
+ */
+void platf_graph_promote_to_host(context_node_t node, sg_platf_host_cbarg_t parameters) {
+  node->kind = HOST;
+  memcpy(&(node->host_parameters), parameters, sizeof(s_sg_platf_host_cbarg_t));
+}
+
+/**
+ * \brief Promote a node to a cluster
+ *
+ * This function should be called in callbacks registered with the
+ * platf_graph_promoter function.
+ *
+ * \param node The node to promote
+ * \param parameters The parameters needed to build the cluster
+ */
+void platf_graph_promote_to_cluster(context_node_t node, sg_platf_cluster_cbarg_t parameters) {
+  node->kind = CLUSTER;
+  memcpy(&(node->cluster_parameters), parameters, sizeof(s_sg_platf_cluster_cbarg_t));
+}
+
+/**
+ * \brief Set the parameters of a network link.
+ *
+ * This function should be called in callbacks registered with the
+ * platf_graph_labeler function.
+ *
+ * \param edge The edge to modify
+ * \param parameters The parameters of the network link
+ */
+void platf_graph_link_label(context_edge_t edge, sg_platf_link_cbarg_t parameters) {
+  memcpy(&(edge->link_parameters), parameters, sizeof(s_sg_platf_link_cbarg_t));
+  edge->labeled = TRUE;
+}
+
+/**
+ * \brief Register a callback to promote nodes
+ *
+ * The best way to promote nodes into host or cluster is to write a function
+ * which takes one parameter, a #context_node_t, make every needed test on
+ * it, and call platf_graph_promote_to_host or platf_graph_promote_to_cluster
+ * if needed. Then, register the function with this one.
+ * You can register several callbacks: the first registered function will be
+ * called first. If the node have not been promoted yet, the second function
+ * will be called, and so on...
+ *
+ * \param promoter_callback The callback function
+ */
+void platf_graph_promoter(platf_promoter_cb_t promoter_callback) {
+  if(promoter_dynar == NULL) {
+    promoter_dynar = xbt_dynar_new(sizeof(platf_promoter_cb_t), NULL);
+  }
+  xbt_dynar_push(promoter_dynar, &promoter_callback);
+}
+
+/**
+ * \brief Register a callback to label links
+ *
+ * Like the node promotion, it is better, to set links, to write a function
+ * which take one parameter, a #context_edge_t, make every needed test on
+ * it, and call platf_graph_link_label if needed.
+ * You can register several callbacks: the first registered function will be
+ * called first. If the link have not been labeled yet, the second function
+ * will be called, and so on... All the links must have been labeled after
+ * all the calls.
+ *
+ * \param labeler_callback The callback function
+ */
+void platf_graph_labeler(platf_labeler_cb_t labeler_callback) {
+  if(labeler_dynar == NULL) {
+    labeler_dynar = xbt_dynar_new(sizeof(void*), NULL);
+  }
+  xbt_dynar_push(labeler_dynar, &labeler_callback);
+}
+
+/**
+ * \brief Call the registered promoters on all nodes
+ *
+ * The promoters are called on all nodes, in the order of their registration
+ * If some nodes are not promoted, they will be routers
+ */
+void platf_do_promote(void) {
+  platf_promoter_cb_t promoter_callback;
+  xbt_node_t graph_node = NULL;
+  xbt_dynar_t dynar_nodes = NULL;
+  context_node_t node = NULL;
+  unsigned int i, j;
+  dynar_nodes = xbt_graph_get_nodes(platform_graph);
+  xbt_dynar_foreach(dynar_nodes, i, graph_node) {
+    node = (context_node_t) xbt_graph_node_get_data(graph_node);
+    xbt_dynar_foreach(promoter_dynar, j, promoter_callback) {
+      if(node->kind != ROUTER)
+        break;
+      promoter_callback(node);
+    }
+  }
+}
+
+/**
+ * \brief Call the registered labelers on all links
+ */
+void platf_do_label(void) {
+  platf_labeler_cb_t labeler_callback;
+  xbt_edge_t graph_edge = NULL;
+  xbt_dynar_t dynar_edges = NULL;
+  context_edge_t edge = NULL;
+  unsigned int i, j;
+  dynar_edges = xbt_graph_get_edges(platform_graph);
+  xbt_dynar_foreach(dynar_edges, i, graph_edge) {
+    edge = (context_edge_t) xbt_graph_edge_get_data(graph_edge);
+    xbt_dynar_foreach(labeler_dynar, j, labeler_callback) {
+      if(edge->labeled)
+        break;
+      labeler_callback(edge);
+    }
+    if(!edge->labeled) {
+      XBT_ERROR("All links of the generated platform are not labeled.");
+      xbt_die("Please check your generation parameters.");
+    }
+  }
+}
+
+/**
+ * \brief putting into SURF the generated platform
+ *
+ * This function should be called when the generation is over and the platform
+ * is ready to be put in place in SURF. All the init function, like MSG_init,
+ * must have been called before, or this function will not do anything.
+ * After that function, it should be possible to list all the available hosts
+ * with the provided functions.
+ */
+void platf_generate(void) {
+
+  xbt_dynar_t nodes = NULL;
+  xbt_node_t graph_node = NULL;
+  context_node_t node_data = NULL;
+  xbt_dynar_t edges = NULL;
+  xbt_edge_t graph_edge = NULL;
+  context_edge_t edge_data = NULL;
+  unsigned int i;
+
+  unsigned int last_host = 0;
+  unsigned int last_router = 0;
+  unsigned int last_cluster = 0;
+
+  sg_platf_host_cbarg_t host_parameters;
+  sg_platf_cluster_cbarg_t cluster_parameters;
+  sg_platf_link_cbarg_t link_parameters;
+  s_sg_platf_router_cbarg_t router_parameters; /* This one is not a pointer! */
+  s_sg_platf_route_cbarg_t route_parameters; /* neither this one! */
+
+  router_parameters.coord = NULL;
+  route_parameters.symmetrical = FALSE;
+  route_parameters.src = NULL;
+  route_parameters.dst = NULL;
+  route_parameters.gw_dst = NULL;
+  route_parameters.gw_src = NULL;
+  route_parameters.link_list = NULL;
+
+  nodes = xbt_graph_get_nodes(platform_graph);
+  edges = xbt_graph_get_edges(platform_graph);
+
+  sg_platf_begin();
+  surf_parse_init_callbacks();
+  routing_register_callbacks();
+
+  s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+  AS.id = "random platform";
+  AS.routing = A_surfxml_AS_routing_Floyd;
+  sg_platf_new_AS_begin(&AS);
+
+  //Generate hosts, clusters and routers
+  xbt_dynar_foreach(nodes, i, graph_node) {
+    node_data = xbt_graph_node_get_data(graph_node);
+    switch(node_data->kind) {
+      case HOST:
+        host_parameters = &node_data->host_parameters;
+        last_host++;
+        if(host_parameters->id == NULL) {
+          host_parameters->id = bprintf("host-%d", last_host);
+        }
+        sg_platf_new_host(host_parameters);
+        break;
+      case CLUSTER:
+        cluster_parameters = &node_data->cluster_parameters;
+        last_cluster++;
+        if(cluster_parameters->prefix == NULL) {
+          cluster_parameters->prefix = "host-";
+        }
+        if(cluster_parameters->suffix == NULL) {
+          cluster_parameters->suffix = bprintf(".cluster-%d", last_cluster);
+        }
+        if(cluster_parameters->id == NULL) {
+          cluster_parameters->id = bprintf("cluster-%d", last_cluster);
+        }
+        sg_platf_new_cluster(cluster_parameters);
+        break;
+      case ROUTER:
+        node_data->router_id = bprintf("router-%d", ++last_router);
+        router_parameters.id = node_data->router_id;
+        sg_platf_new_router(&router_parameters);
+    }
+  }
+
+  //Generate links and routes
+  xbt_dynar_foreach(edges, i, graph_edge) {
+    xbt_node_t src = xbt_graph_edge_get_source(graph_edge);
+    xbt_node_t dst = xbt_graph_edge_get_target(graph_edge);
+    context_node_t src_data = xbt_graph_node_get_data(src);
+    context_node_t dst_data = xbt_graph_node_get_data(dst);
+    edge_data = xbt_graph_edge_get_data(graph_edge);
+    const char* temp = NULL;
+
+    //Add a link to the platform
+    link_parameters = &edge_data->link_parameters;
+    if(link_parameters->id == NULL) {
+      link_parameters->id = bprintf("link-%ld", edge_data->id);
+    }
+    sg_platf_new_link(link_parameters);
+
+    //Add a route matching this link
+    switch(src_data->kind) {
+      case ROUTER:
+        route_parameters.src = src_data->router_id;
+        break;
+      case CLUSTER:
+        route_parameters.src = src_data->cluster_parameters.id;
+        break;
+      case HOST:
+        route_parameters.src = src_data->host_parameters.id;
+    }
+    switch(dst_data->kind) {
+      case ROUTER:
+        route_parameters.dst = dst_data->router_id;
+        break;
+      case CLUSTER:
+        route_parameters.dst = dst_data->cluster_parameters.id;
+        break;
+      case HOST:
+        route_parameters.dst = dst_data->host_parameters.id;
+    }
+    sg_platf_route_begin(&route_parameters);
+    sg_platf_route_add_link(link_parameters->id, &route_parameters);
+    sg_platf_route_end(&route_parameters);
+
+    //Create the symmertical route
+    temp = route_parameters.dst;
+    route_parameters.dst = route_parameters.src;
+    route_parameters.src = temp;
+    sg_platf_route_begin(&route_parameters);
+    sg_platf_route_add_link(link_parameters->id, &route_parameters);
+    sg_platf_route_end(&route_parameters);
+  }
+
+  sg_platf_new_AS_end();
+  sg_platf_end();
+}
+
+/* Functions used to generate interesting random values */
+
+double random_pareto(double min, double max, double K, double P, double ALPHA) {
+  double x = RngStream_RandU01(rng_stream);
+  double den = pow(1.0 - x + x*pow(K/P, ALPHA), 1.0/ALPHA);
+  double res = (1/den);
+  res += min - 1; // pareto is on [1, infinity) by default
+  if (res>max) {
+    return max;
+  }
+  return res;
+}
diff --git a/src/surf/platf_generator_private.h b/src/surf/platf_generator_private.h
new file mode 100644 (file)
index 0000000..12cfdd0
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef SG_PLATF_GEN_PRIVATE_H
+#define SG_PLATF_GEN_PRIVATE_H
+
+#include "xbt/graph.h"
+#include "simgrid/platf.h"
+
+void platf_graph_init(unsigned long node_count);
+
+void platf_node_connect(xbt_node_t node1, xbt_node_t node2);
+
+double platf_node_distance(xbt_node_t node1, xbt_node_t node2);
+
+double random_pareto(double min, double max, double K, double P, double ALPHA);
+
+#endif      /* SG_PLATF_GEN_PRIVATE_H */
index 874a000..f5ddb1b 100644 (file)
@@ -22,12 +22,23 @@ xbt_dynar_t sg_platf_cabinet_cb_list = NULL; // of sg_platf_cluster_cb_t
 xbt_dynar_t sg_platf_AS_begin_cb_list = NULL; //of sg_platf_AS_begin_cb_t
 xbt_dynar_t sg_platf_AS_end_cb_list = NULL; //of void_f_void_t
 xbt_dynar_t sg_platf_postparse_cb_list = NULL; // of void_f_void_t
+xbt_dynar_t sg_platf_prop_cb_list = NULL; // of sg_platf_prop_cb_t
+
+xbt_dynar_t sg_platf_route_cb_list = NULL; // of sg_platf_route_cb_t
+xbt_dynar_t sg_platf_ASroute_cb_list = NULL; // of sg_platf_ASroute_cb_t
+xbt_dynar_t sg_platf_bypassRoute_cb_list = NULL; // of sg_platf_bypassRoute_cb_t
+xbt_dynar_t sg_platf_bypassASroute_cb_list = NULL; // of sg_platf_bypassASroute_cb_t
+
+xbt_dynar_t sg_platf_trace_cb_list = NULL;
+xbt_dynar_t sg_platf_trace_connect_cb_list = NULL;
 
 xbt_dynar_t sg_platf_storage_cb_list = NULL; // of sg_platf_storage_cb_t
 xbt_dynar_t sg_platf_storage_type_cb_list = NULL; // of sg_platf_storage_cb_t
 xbt_dynar_t sg_platf_mstorage_cb_list = NULL; // of sg_platf_storage_cb_t
 xbt_dynar_t sg_platf_mount_cb_list = NULL; // of sg_platf_storage_cb_t
 
+xbt_dynar_t sg_platf_process_cb_list = NULL;
+
 static int surf_parse_models_setup_already_called;
 
 /* one RngStream for the platform, to respect some statistic rules */
@@ -35,21 +46,37 @@ static RngStream sg_platf_rng_stream = NULL;
 
 /** Module management function: creates all internal data structures */
 void sg_platf_init(void) {
+
+  //FIXME : Ugly, but useful...
+  if(sg_platf_host_cb_list)
+    return; //Already initialized, so do nothing...
+
   sg_platf_host_cb_list = xbt_dynar_new(sizeof(sg_platf_host_cb_t), NULL);
   sg_platf_host_link_cb_list = xbt_dynar_new(sizeof(sg_platf_host_link_cb_t), NULL);
-  sg_platf_router_cb_list = xbt_dynar_new(sizeof(sg_platf_host_cb_t), NULL);
-  sg_platf_link_cb_list = xbt_dynar_new(sizeof(sg_platf_host_cb_t), NULL);
+  sg_platf_router_cb_list = xbt_dynar_new(sizeof(sg_platf_router_cb_t), NULL);
+  sg_platf_link_cb_list = xbt_dynar_new(sizeof(sg_platf_link_cb_t), NULL);
   sg_platf_peer_cb_list = xbt_dynar_new(sizeof(sg_platf_peer_cb_t), NULL);
   sg_platf_cluster_cb_list = xbt_dynar_new(sizeof(sg_platf_cluster_cb_t), NULL);
   sg_platf_cabinet_cb_list = xbt_dynar_new(sizeof(sg_platf_cabinet_cb_t), NULL);
   sg_platf_postparse_cb_list = xbt_dynar_new(sizeof(sg_platf_link_cb_t),NULL);
-  sg_platf_AS_begin_cb_list = xbt_dynar_new(sizeof(sg_platf_AS_begin_cb_t),NULL);
-  sg_platf_AS_end_cb_list = xbt_dynar_new(sizeof(void_f_void_t),NULL);
+  sg_platf_AS_begin_cb_list = xbt_dynar_new(sizeof(sg_platf_AS_cb_t),NULL);
+  sg_platf_AS_end_cb_list = xbt_dynar_new(sizeof(sg_platf_AS_cb_t),NULL);
+  sg_platf_prop_cb_list = xbt_dynar_new(sizeof(sg_platf_prop_cb_t),NULL);
+
+  sg_platf_route_cb_list = xbt_dynar_new(sizeof(sg_platf_route_cb_t), NULL);
+  sg_platf_ASroute_cb_list = xbt_dynar_new(sizeof(sg_platf_route_cb_t), NULL);
+  sg_platf_bypassRoute_cb_list = xbt_dynar_new(sizeof(sg_platf_route_cb_t), NULL);
+  sg_platf_bypassASroute_cb_list = xbt_dynar_new(sizeof(sg_platf_route_cb_t), NULL);
+
+  sg_platf_trace_cb_list = xbt_dynar_new(sizeof(sg_platf_trace_cb_t), NULL);
+  sg_platf_trace_connect_cb_list = xbt_dynar_new(sizeof(sg_platf_trace_connect_cb_t), NULL);
 
   sg_platf_storage_cb_list = xbt_dynar_new(sizeof(sg_platf_storage_cb_t), NULL);
   sg_platf_storage_type_cb_list = xbt_dynar_new(sizeof(sg_platf_storage_cb_t), NULL);
   sg_platf_mstorage_cb_list = xbt_dynar_new(sizeof(sg_platf_storage_cb_t), NULL);
   sg_platf_mount_cb_list = xbt_dynar_new(sizeof(sg_platf_storage_cb_t), NULL);
+
+  sg_platf_process_cb_list = xbt_dynar_new(sizeof(sg_platf_process_cb_t), NULL);
 }
 /** Module management function: frees all internal data structures */
 void sg_platf_exit(void) {
@@ -63,12 +90,23 @@ void sg_platf_exit(void) {
   xbt_dynar_free(&sg_platf_cabinet_cb_list);
   xbt_dynar_free(&sg_platf_AS_begin_cb_list);
   xbt_dynar_free(&sg_platf_AS_end_cb_list);
+  xbt_dynar_free(&sg_platf_prop_cb_list);
+
+  xbt_dynar_free(&sg_platf_trace_cb_list);
+  xbt_dynar_free(&sg_platf_trace_connect_cb_list);
+
+  xbt_dynar_free(&sg_platf_route_cb_list);
+  xbt_dynar_free(&sg_platf_ASroute_cb_list);
+  xbt_dynar_free(&sg_platf_bypassRoute_cb_list);
+  xbt_dynar_free(&sg_platf_bypassASroute_cb_list);
 
   xbt_dynar_free(&sg_platf_storage_cb_list);
   xbt_dynar_free(&sg_platf_storage_type_cb_list);
   xbt_dynar_free(&sg_platf_mstorage_cb_list);
   xbt_dynar_free(&sg_platf_mount_cb_list);
 
+  xbt_dynar_free(&sg_platf_process_cb_list);
+
   /* make sure that we will reinit the models while loading the platf once reinited */
   surf_parse_models_setup_already_called = 0;
 }
@@ -101,6 +139,7 @@ void sg_platf_new_link(sg_platf_link_cbarg_t link){
     fun(link);
   }
 }
+
 void sg_platf_new_peer(sg_platf_peer_cbarg_t peer){
   unsigned int iterator;
   sg_platf_peer_cb_t fun;
@@ -150,6 +189,83 @@ void sg_platf_new_mount(sg_platf_mount_cbarg_t mount){
     fun(mount);
   }
 }
+void sg_platf_new_route(sg_platf_route_cbarg_t route) {
+  unsigned int iterator;
+  sg_platf_route_cb_t fun;
+  xbt_dynar_foreach(sg_platf_route_cb_list, iterator, fun) {
+    fun(route);
+  }
+}void sg_platf_new_ASroute(sg_platf_route_cbarg_t ASroute) {
+  unsigned int iterator;
+  sg_platf_route_cb_t fun;
+  xbt_dynar_foreach(sg_platf_ASroute_cb_list, iterator, fun) {
+    fun(ASroute);
+  }
+}
+void sg_platf_new_bypassRoute(sg_platf_route_cbarg_t bypassRoute) {
+  unsigned int iterator;
+  sg_platf_route_cb_t fun;
+  xbt_dynar_foreach(sg_platf_bypassRoute_cb_list, iterator, fun) {
+    fun(bypassRoute);
+  }
+}void sg_platf_new_bypassASroute(sg_platf_route_cbarg_t bypassASroute) {
+  unsigned int iterator;
+  sg_platf_route_cb_t fun;
+  xbt_dynar_foreach(sg_platf_bypassASroute_cb_list, iterator, fun) {
+    fun(bypassASroute);
+  }
+}
+void sg_platf_new_prop(sg_platf_prop_cbarg_t prop) {
+  unsigned int iterator;
+  sg_platf_prop_cb_t fun;
+  xbt_dynar_foreach(sg_platf_prop_cb_list, iterator, fun) {
+    fun(prop);
+  }
+}
+void sg_platf_new_trace(sg_platf_trace_cbarg_t trace) {
+  unsigned int iterator;
+  sg_platf_trace_cb_t fun;
+  xbt_dynar_foreach(sg_platf_trace_cb_list, iterator, fun) {
+    fun(trace);
+  }
+}
+void sg_platf_new_trace_connect(sg_platf_trace_connect_cbarg_t trace_connect) {
+  unsigned int iterator;
+  sg_platf_trace_connect_cb_t fun;
+  xbt_dynar_foreach(sg_platf_trace_connect_cb_list, iterator, fun) {
+    fun(trace_connect);
+  }
+}
+void sg_platf_new_process(sg_platf_process_cbarg_t process){
+  unsigned int iterator;
+  sg_platf_process_cb_t fun;
+  xbt_dynar_foreach(sg_platf_process_cb_list, iterator, fun) {
+    fun(process);
+  }
+}
+
+void sg_platf_route_begin (sg_platf_route_cbarg_t route){
+  route->link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
+}
+void sg_platf_ASroute_begin (sg_platf_route_cbarg_t ASroute){
+  ASroute->link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
+}
+
+void sg_platf_route_end (sg_platf_route_cbarg_t route){
+  sg_platf_new_route(route);
+}
+void sg_platf_ASroute_end (sg_platf_route_cbarg_t ASroute){
+  sg_platf_new_ASroute(ASroute);
+}
+
+void sg_platf_route_add_link (const char* link_id, sg_platf_route_cbarg_t route){
+  char *link_name = xbt_strdup(link_id);
+  xbt_dynar_push(route->link_list, &link_name);
+}
+void sg_platf_ASroute_add_link (const char* link_id, sg_platf_route_cbarg_t ASroute){
+  char *link_name = xbt_strdup(link_id);
+  xbt_dynar_push(ASroute->link_list, &link_name);
+}
 
 void sg_platf_begin() { /* Do nothing: just for symmetry of user code */ }
 
@@ -163,9 +279,9 @@ void sg_platf_end() {
 
 static int surf_parse_models_setup_already_called = 0;
 
-void sg_platf_new_AS_begin(const char *id, int routing) {
+void sg_platf_new_AS_begin(sg_platf_AS_cbarg_t AS) {
   unsigned int iterator;
-  sg_platf_AS_begin_cb_t fun;
+  sg_platf_AS_cb_t fun;
 
   if (!surf_parse_models_setup_already_called && !xbt_dynar_is_empty(sg_platf_AS_begin_cb_list)) {
     /* Initialize the surf models. That must be done after we got all config, and before we need the models.
@@ -185,7 +301,7 @@ void sg_platf_new_AS_begin(const char *id, int routing) {
   }
 
   xbt_dynar_foreach(sg_platf_AS_begin_cb_list, iterator, fun) {
-    fun(id, routing);
+    fun(AS);
   }
 }
 
@@ -222,10 +338,10 @@ void sg_platf_cabinet_add_cb(sg_platf_cabinet_cb_t fct) {
 void sg_platf_postparse_add_cb(void_f_void_t fct) {
   xbt_dynar_push(sg_platf_postparse_cb_list, &fct);
 }
-void sg_platf_AS_begin_add_cb(sg_platf_AS_begin_cb_t fct) {
+void sg_platf_AS_begin_add_cb(sg_platf_AS_cb_t fct) {
   xbt_dynar_push(sg_platf_AS_begin_cb_list, &fct);
 }
-void sg_platf_AS_end_add_cb(void_f_void_t fct) {
+void sg_platf_AS_end_add_cb(sg_platf_AS_cb_t fct) {
   xbt_dynar_push(sg_platf_AS_end_cb_list, &fct);
 }
 void sg_platf_storage_add_cb(sg_platf_storage_cb_t fct) {
@@ -240,12 +356,34 @@ void sg_platf_mstorage_add_cb(sg_platf_mstorage_cb_t fct) {
 void sg_platf_mount_add_cb(sg_platf_mount_cb_t fct) {
   xbt_dynar_push(sg_platf_mount_cb_list, &fct);
 }
-
-
+void sg_platf_route_add_cb(sg_platf_route_cb_t fct) {
+  xbt_dynar_push(sg_platf_route_cb_list, &fct);
+}
+void sg_platf_ASroute_add_cb(sg_platf_route_cb_t fct) {
+  xbt_dynar_push(sg_platf_ASroute_cb_list, &fct);
+}
+void sg_platf_bypassRoute_add_cb(sg_platf_route_cb_t fct) {
+  xbt_dynar_push(sg_platf_bypassRoute_cb_list, &fct);
+}
+void sg_platf_bypassASroute_add_cb(sg_platf_route_cb_t fct) {
+  xbt_dynar_push(sg_platf_bypassASroute_cb_list, &fct);
+}
+void sg_platf_prop_add_cb(sg_platf_prop_cb_t fct) {
+  xbt_dynar_push(sg_platf_prop_cb_list, &fct);
+}
+void sg_platf_trace_add_cb(sg_platf_trace_cb_t fct) {
+  xbt_dynar_push(sg_platf_trace_cb_list, &fct);
+}
+void sg_platf_trace_connect_add_cb(sg_platf_trace_connect_cb_t fct) {
+  xbt_dynar_push(sg_platf_trace_connect_cb_list, &fct);
+}
 void sg_platf_rng_stream_init(unsigned long seed[6]) {
   RngStream_SetPackageSeed(seed);
   sg_platf_rng_stream = RngStream_CreateStream(NULL);
 }
+void sg_platf_process_add_cb(sg_platf_process_cb_t fct) {
+  xbt_dynar_push(sg_platf_process_cb_list, &fct);
+}
 
 RngStream sg_platf_rng_stream_get(const char* id) {
   RngStream stream = NULL;
index 29c4231..3df796e 100644 (file)
@@ -10,7 +10,7 @@
 <!ATTLIST trace file CDATA "">
 <!ATTLIST trace periodicity CDATA #REQUIRED>
 
-<!ELEMENT random (prop*)>
+<!ELEMENT random EMPTY>
 <!ATTLIST random id CDATA #REQUIRED>
 <!ATTLIST random min CDATA #REQUIRED>
 <!ATTLIST random max CDATA #REQUIRED>
@@ -25,8 +25,7 @@
 <!ATTLIST trace_connect trace CDATA #REQUIRED>
 <!ATTLIST trace_connect element CDATA #REQUIRED>
 
-<!ELEMENT AS (((AS|include|storage_type|storage|link|backbone|cabinet|cluster|peer|trace|trace_connect)*,(ASroute|trace|trace_connect|bypassASroute)*,(trace|trace_connect)*)|((include|storage_type|storage|host|cabinet|router|link|backbone|trace|trace_connect|host_link)*,(route|trace|trace_connect|bypassRoute)*))>
-
+<!ELEMENT AS ((prop*),(((AS|include|storage_type|storage|link|backbone|cabinet|cluster|peer|trace|trace_connect)*,(ASroute|trace|trace_connect|bypassASroute)*,(trace|trace_connect)*)|((include|storage_type|storage|host|cabinet|router|link|backbone|trace|trace_connect|host_link)*,(route|trace|trace_connect|bypassRoute)*)))>
 <!ATTLIST AS id CDATA #REQUIRED>
 <!ATTLIST AS routing (Full|Floyd|Dijkstra|DijkstraCache|None|RuleBased|Vivaldi|Cluster) "None">
 
index 7de3c25..587e163 100644 (file)
@@ -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[3217] =
+static yyconst flex_int16_t yy_accept[3218] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -449,10 +449,10 @@ static yyconst flex_int16_t yy_accept[3217] =
 
        10,   37,   37,   48,   10,   48,   48,   48,   46,   48,
        48,   48,  543,  542,   78,   10,   78,   78,   78,   76,
-       78,   78,   78,   78,   78,   82,   10,   82,  546,   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,  546,  132,  132,  546,  546,  132,
+       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,  546,  132,  546,  132,  132,  546,  546,  132,
       546,  132,  546,  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,
@@ -491,273 +491,273 @@ static yyconst flex_int16_t yy_accept[3217] =
        34,    0,   47,   49,   49,   49,   49,    0,    0,    0,
        77,   79,   79,   79,   79,   79,   79,   79,   79,   79,
 
-        0,    0,  100,  102,  102,  102,  102,    0,  127,  129,
-      129,  129,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,  144,  146,
-      146,  146,  146,  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,
-      227,  229,  229,  229,  229,    0,  272,  274,  274,  274,
+        0,  100,  102,  102,  102,  102,    0,  127,  129,  129,
+      129,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  144,
+      146,  146,  146,  146,  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,  227,  229,  229,  229,  229,    0,  272,  274,  274,
       274,  274,  274,  274,  274,  274,  274,  274,  274,  274,
-      274,    0,  295,  297,  297,  297,  297,  297,  297,  297,
-      297,    0,  320,  322,  322,  322,  322,  322,  322,  322,
-
-      322,    0,  333,  335,  335,  335,    0,  348,  350,  350,
-      350,  350,    0,  379,  381,  381,  381,  381,  381,  381,
-        0,  396,  398,  398,  398,  398,    0,    0,  417,  419,
-      419,  419,  419,  419,    0,  434,  436,  436,  436,    0,
-      447,  449,  449,  449,    0,  464,  466,  466,  466,  466,
-        0,  485,  487,  487,  487,  487,  487,  487,    0,    0,
-      496,  498,  498,    0,  507,  509,  509,    0,  520,  522,
-      522,  522,    0,    0,    0,    0,    0,    3,    0,    0,
-        0,    0,    0,    0,    0,  544,    0,   23,    0,    0,
-      107,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      274,  274,    0,  295,  297,  297,  297,  297,  297,  297,
+      297,  297,    0,  320,  322,  322,  322,  322,  322,  322,
+
+      322,  322,    0,  333,  335,  335,  335,    0,  348,  350,
+      350,  350,  350,    0,  379,  381,  381,  381,  381,  381,
+      381,    0,  396,  398,  398,  398,  398,    0,    0,  417,
+      419,  419,  419,  419,  419,    0,  434,  436,  436,  436,
+        0,  447,  449,  449,  449,    0,  464,  466,  466,  466,
+      466,    0,  485,  487,  487,  487,  487,  487,  487,    0,
+        0,  496,  498,  498,    0,  507,  509,  509,    0,  520,
+      522,  522,  522,    0,    0,    0,    0,    0,    3,    0,
+        0,    0,    0,    0,    0,    0,  544,    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,  539,   79,
-        0,    0,   79,   79,   79,   79,   79,   79,    0,    0,
+        0,    0,  106,    0,    0,    0,    0,    0,    0,   34,
+        0,    0,   49,    0,    0,   49,    0,    0,    0,  539,
+       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,  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,  229,    0,    0,    0,
-
-        0,    0,    0,  274,  274,    0,    0,  274,    0,    0,
-      274,  274,  274,  274,  274,  274,  274,  274,    0,    0,
-        0,    0,    0,    0,  297,  297,  297,  297,  297,    0,
-        0,  322,  322,  322,    0,    0,  322,  322,  322,    0,
-        0,  335,    0,    0,    0,    0,  350,    0,    0,  350,
-        0,    0,  381,    0,    0,  381,  381,  381,    0,    0,
-      398,  398,  398,    0,    0,    0,  419,  419,  419,  419,
-        0,    0,  436,    0,    0,    0,    0,  449,  449,    0,
-        0,  466,  466,  466,    0,    0,  487,  487,  487,  487,
-      487,    0,    0,    0,  498,    0,    0,    0,    0,    0,
-
-        0,    0,    0,  522,    0,    0,    0,   14,    1,    0,
-        0,  532,    0,    0,    0,  529,  528,    0,    0,   23,
-        0,    0,   25,    0,  107,    0,    0,    0,    0,    0,
+        0,  107,    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,  229,    0,    0,
+
+        0,    0,    0,    0,  274,  274,    0,    0,  274,    0,
+        0,  274,  274,  274,  274,  274,  274,  274,  274,    0,
+        0,    0,    0,    0,    0,  297,  297,  297,  297,  297,
+        0,    0,  322,  322,  322,    0,    0,  322,  322,  322,
+        0,    0,  335,    0,    0,    0,    0,  350,    0,    0,
+      350,    0,    0,  381,    0,    0,  381,  381,  381,    0,
+        0,  398,  398,  398,    0,    0,    0,  419,  419,  419,
+      419,    0,    0,  436,    0,    0,    0,    0,  449,  449,
+        0,    0,  466,  466,  466,    0,    0,  487,  487,  487,
+      487,  487,    0,    0,    0,  498,    0,    0,    0,    0,
+
+        0,    0,    0,    0,  522,    0,    0,    0,   14,    1,
+        0,    0,  532,    0,    0,    0,  529,  528,    0,    0,
+       23,    0,    0,   25,    0,  107,    0,    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,   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,    0,  102,  102,  102,    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,    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,  229,    0,
-      221,  220,    0,  223,  222,    0,    0,  231,    0,  274,
-      274,  274,  274,    0,  248,  247,  274,    0,  236,  235,
-        0,    0,  274,  274,  274,  274,  274,  274,  274,    0,
-        0,  276,    0,    0,  291,  290,    0,  281,  280,    0,
-
-        0,  297,  297,  297,  297,    0,    0,  299,    0,  322,
-      322,  322,  322,    0,  304,  303,    0,    0,  322,  322,
-        0,    0,  324,    0,  335,    0,  329,  328,    0,    0,
-      337,    0,  350,    0,  342,  341,  350,    0,    0,  352,
-        0,  381,    0,  357,  356,  381,  381,  381,    0,    0,
-      383,    0,    0,    0,    0,    0,  398,    0,    0,  400,
-        0,    0,    0,    0,  419,  419,    0,    0,  419,    0,
-        0,  421,    0,  436,    0,  426,  425,    0,    0,  438,
-        0,    0,    0,    0,    0,    0,    0,  451,    0,    0,
-        0,  466,  466,    0,    0,    0,    0,  468,    0,  487,
-
-      487,  487,  487,  487,    0,    0,  489,    0,    0,  498,
-        0,    0,  500,    0,    0,  505,  504,    0,    0,  511,
-        0,    0,  516,  515,  522,    0,    0,  524,    0,    0,
-        0,  533,  527,    0,    0,    0,   23,    0,    0,    0,
-        0,    0,    0,    0,    0,  191,    0,  354,    0,    0,
-      302,    0,    0,  513,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  301,    0,    0,    0,    0,    0,    0,
-        0,   49,    0,    0,   79,    0,   59,   58,    0,    0,
-        0,   57,   56,   79,    0,    0,   79,    0,  514,  102,
+        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,  229,
+        0,  221,  220,    0,  223,  222,    0,    0,  231,    0,
+      274,  274,  274,  274,    0,  248,  247,  274,    0,  236,
+      235,    0,    0,  274,  274,  274,  274,  274,  274,  274,
+        0,    0,  276,    0,    0,  291,  290,    0,  281,  280,
+
+        0,    0,  297,  297,  297,  297,    0,    0,  299,    0,
+      322,  322,  322,  322,    0,  304,  303,    0,    0,  322,
+      322,    0,    0,  324,    0,  335,    0,  329,  328,    0,
+        0,  337,    0,  350,    0,  342,  341,  350,    0,    0,
+      352,    0,  381,    0,  357,  356,  381,  381,  381,    0,
+        0,  383,    0,    0,    0,    0,    0,  398,    0,    0,
+      400,    0,    0,    0,    0,  419,  419,    0,    0,  419,
+        0,    0,  421,    0,  436,    0,  426,  425,    0,    0,
+      438,    0,    0,    0,    0,    0,    0,    0,  451,    0,
+        0,    0,  466,  466,    0,    0,    0,    0,  468,    0,
+
+      487,  487,  487,  487,  487,    0,    0,  489,    0,    0,
+      498,    0,    0,  500,    0,    0,  505,  504,    0,    0,
+      511,    0,    0,  516,  515,  522,    0,    0,  524,    0,
+        0,    0,  533,  527,    0,    0,    0,   23,    0,    0,
+        0,    0,    0,    0,    0,    0,  191,    0,  354,    0,
+        0,  302,    0,    0,  513,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  301,    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,
 
-      192,  355,    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,  274,  274,  274,  274,    0,
-        0,    0,  250,  249,  274,  274,  274,  274,  274,  274,
-      274,    0,    0,  293,  292,  297,  297,  297,  297,    0,
-      322,  322,  322,  322,    0,  312,  311,  322,  322,    0,
-      335,    0,  350,  350,    0,  381,  381,  381,  381,    0,
-        0,  390,  389,    0,  388,  387,  398,    0,  354,    0,
-      407,  406,  419,  419,    0,  405,  404,  419,    0,  436,
-
-        0,    0,  445,  444,    0,  443,  442,    0,    0,  458,
-      457,  466,  466,    0,  456,  455,    0,  487,    0,    0,
-      487,  487,  487,    0,    0,  498,    0,    0,  522,    0,
-        0,    0,    0,   12,    0,  530,  531,    0,   23,    0,
-        0,    0,    0,    0,    0,    0,    0,  191,    0,    0,
-      354,    0,  165,    0,  302,    0,    0,  513,    0,  385,
-        0,   39,    0,    0,    0,    0,    0,  301,    0,   38,
-        0,   30,   29,    0,    0,   43,   42,   49,    0,    0,
-       79,    0,   61,   60,   79,    0,   65,   64,   79,    0,
-      514,  102,    0,    0,    0,    0,    0,    0,  129,    0,
-
-        0,    0,  192,    0,  355,  386,    0,    0,    0,  386,
-      385,  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,  225,  224,    0,  274,    0,    0,
-      274,  274,    0,  246,  245,    0,    0,  274,  274,  274,
-      274,  274,  274,    0,    0,    0,  297,  297,  297,    0,
-      322,    0,    0,  322,  322,    0,    0,  322,    0,  335,
-        0,  350,  350,    0,  381,  381,  381,    0,    0,  381,
-        0,  398,    0,    0,  419,  419,  419,    0,  436,    0,
-
-        0,  466,  466,    0,  487,    0,  473,  472,  487,  487,
-      487,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,   11,    0,   23,    0,    0,    0,    0,
-        0,    0,    0,  503,    0,    0,    0,  165,    0,    0,
-        0,   53,  385,  326,    0,   39,    0,  502,   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,  386,  327,    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,  274,    0,  258,  257,    0,    0,  274,
-        0,  244,  243,    0,    0,  274,  274,  274,  274,    0,
-        0,    0,    0,  289,  288,    0,    0,  297,    0,    0,
-        0,  322,    0,  308,  307,    0,    0,  322,    0,  306,
-      305,  322,    0,  323,  335,    0,  350,  350,    0,  381,
-      381,  381,    0,    0,    0,  381,    0,  382,  398,    0,
-        0,    0,    0,    0,    0,  419,    0,  436,    0,    0,
-        0,    0,    0,    0,    0,  487,  487,  487,  487,    0,
-        0,    0,  494,  493,    0,    0,    0,  518,  517,    0,
-
-      523,    0,    0,    0,    0,    0,    0,    0,  402,    0,
-        0,    0,    0,  279,  234,  503,    0,   28,    0,    0,
-        0,  471,   53,  326,  150,    0,  502,   52,  278,  233,
-       27,  470,    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,    0,  403,    0,
-        0,    0,    0,  327,  151,    0,    0,    0,    0,    0,
-        0,  155,  154,    0,    0,  175,    0,  181,  180,    0,
-      214,  214,    0,    0,  214,    0,    0,  274,    0,  260,
-      259,  274,    0,  238,  237,    0,    0,  274,  274,  274,
-
-        0,  240,  239,    0,    0,  283,  282,    0,    0,    0,
-      285,  284,    0,  322,    0,  310,  309,  322,  322,  335,
-        0,  350,    0,    0,    0,  381,    0,    0,  381,  381,
-        0,    0,  381,  398,    0,  399,    0,    0,  411,  410,
-        0,  409,  408,  419,    0,  436,    0,    0,    0,  462,
-      461,    0,  460,  459,    0,  487,  487,  487,  487,    0,
-        0,    0,    0,    0,    0,    0,   17,    0,   19,   18,
-        0,  402,  491,  339,    0,    0,  279,  234,    0,   28,
-      423,  178,   16,  471,  150,    0,    0,  278,  233,   27,
-      470,    0,    0,   49,  538,   79,    0,   67,   66,   79,
-
-        0,   80,    0,   98,   97,    0,    0,    0,    0,    0,
+      192,  355,  514,    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,  274,  274,  274,  274,
+        0,    0,    0,  250,  249,  274,  274,  274,  274,  274,
+      274,  274,    0,    0,  293,  292,  297,  297,  297,  297,
+        0,  322,  322,  322,  322,    0,  312,  311,  322,  322,
+        0,  335,    0,  350,  350,    0,  381,  381,  381,  381,
+        0,    0,  390,  389,    0,  388,  387,  398,    0,  354,
+        0,  407,  406,  419,  419,    0,  405,  404,  419,    0,
+
+      436,    0,    0,  445,  444,    0,  443,  442,    0,    0,
+      458,  457,  466,  466,    0,  456,  455,    0,  487,    0,
+        0,  487,  487,  487,    0,    0,  498,    0,    0,  522,
+        0,    0,    0,    0,   12,    0,  530,  531,    0,   23,
+        0,    0,    0,    0,    0,    0,    0,    0,  191,    0,
+        0,  354,    0,  165,    0,  302,    0,    0,  513,    0,
+      385,    0,   39,    0,    0,    0,    0,    0,  301,    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,  355,  514,  386,    0,    0,    0,
+      386,  385,  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,  225,  224,    0,  274,    0,
+        0,  274,  274,    0,  246,  245,    0,    0,  274,  274,
+      274,  274,  274,  274,    0,    0,    0,  297,  297,  297,
+        0,  322,    0,    0,  322,  322,    0,    0,  322,    0,
+      335,    0,  350,  350,    0,  381,  381,  381,    0,    0,
+      381,    0,  398,    0,    0,  419,  419,  419,    0,  436,
+
+        0,    0,  466,  466,    0,  487,    0,  473,  472,  487,
+      487,  487,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,   11,    0,   23,    0,    0,    0,
+        0,    0,    0,    0,  503,    0,    0,    0,  165,    0,
+        0,    0,   53,  385,  326,    0,   39,    0,  502,   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,  386,  327,    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,  274,    0,  258,  257,    0,    0,
+      274,    0,  244,  243,    0,    0,  274,  274,  274,  274,
+        0,    0,    0,    0,  289,  288,    0,    0,  297,    0,
+        0,    0,  322,    0,  308,  307,    0,    0,  322,    0,
+      306,  305,  322,    0,  323,  335,    0,  350,  350,    0,
+      381,  381,  381,    0,    0,    0,  381,    0,  382,  398,
+        0,    0,    0,    0,    0,    0,  419,    0,  436,    0,
+        0,    0,    0,    0,    0,    0,  487,  487,  487,  487,
+        0,    0,    0,  494,  493,    0,    0,    0,  518,  517,
+
+        0,  523,    0,    0,    0,    0,    0,    0,    0,  402,
+        0,    0,    0,    0,  279,  234,  503,    0,   28,    0,
+        0,    0,  471,   53,  326,  150,    0,  502,   52,  278,
+      233,   27,  470,    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,    0,  403,
-      340,    0,    0,    0,  151,    0,    0,  142,  141,    0,
-        0,  157,  156,    0,    0,  214,  214,    0,    0,    0,
-        0,  214,  179,    0,  274,  274,    0,  242,  241,  274,
-      274,  274,    0,    0,  287,  286,    0,  322,  322,  322,
-      335,    0,  336,  350,    0,  346,  345,    0,  381,    0,
-      363,  362,  381,  381,    0,    0,    0,    0,  381,  398,
-      424,  419,    0,  436,    0,    0,    0,    0,    0,  487,
-      487,  487,    0,  492,    0,    0,  510,    0,    0,    0,
-
-       17,    0,  491,  339,    0,    0,  218,  423,  178,   16,
-        0,    0,    0,    0,   35,   49,    0,    0,   79,    0,
+        0,    0,    0,    0,  327,  151,    0,    0,    0,    0,
+        0,    0,  155,  154,    0,    0,  175,    0,  181,  180,
+        0,  214,  214,    0,    0,  214,    0,    0,  274,    0,
+      260,  259,  274,    0,  238,  237,    0,    0,  274,  274,
+
+      274,    0,  240,  239,    0,    0,  283,  282,    0,    0,
+        0,  285,  284,    0,  322,    0,  310,  309,  322,  322,
+      335,    0,  350,    0,    0,    0,  381,    0,    0,  381,
+      381,    0,    0,  381,  398,    0,  399,    0,    0,  411,
+      410,    0,  409,  408,  419,    0,  436,    0,    0,    0,
+      462,  461,    0,  460,  459,    0,  487,  487,  487,  487,
+        0,    0,    0,    0,    0,    0,    0,   17,    0,   19,
+       18,    0,  402,  491,  339,    0,    0,  279,  234,    0,
+       28,  423,  178,   16,  471,  150,    0,    0,  278,  233,
+       27,  470,    0,    0,   49,  538,   79,    0,   67,   66,
+
+       79,    0,   80,    0,   98,   97,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      403,  340,    0,    0,    0,  151,    0,    0,  142,  141,
+        0,    0,  157,  156,    0,    0,  214,  214,    0,    0,
+        0,    0,  214,  179,    0,  274,  274,    0,  242,  241,
+      274,  274,  274,    0,    0,  287,  286,    0,  322,  322,
+      322,  335,    0,  336,  350,    0,  346,  345,    0,  381,
+        0,  363,  362,  381,  381,    0,    0,    0,    0,  381,
+      398,  424,  419,    0,  436,    0,    0,    0,    0,    0,
+      487,  487,  487,    0,  492,    0,    0,  510,    0,    0,
+
+        0,   17,    0,  491,  339,    0,    0,  218,  423,  178,
+       16,    0,    0,    0,    0,   35,   49,    0,    0,   79,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  340,    0,    0,  219,    0,    0,    0,  162,
-        0,  214,  214,    0,  204,    0,  203,  214,  179,    0,
-      274,  274,    0,    0,  274,  274,    0,  275,    0,  298,
-      322,  322,  322,  335,    0,    0,    0,    0,    0,  381,
-      381,  381,    0,  367,    0,  366,  381,  398,  424,  419,
-        0,  420,    0,    0,    0,    0,    0,    0,  475,  474,
-
-        0,    0,  487,  487,    0,  488,  492,    0,    0,    0,
-        0,    0,   24,    0,    0,  218,    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,  340,    0,    0,  219,    0,    0,    0,
+      162,    0,  214,  214,    0,  204,    0,  203,  214,  179,
+        0,  274,  274,    0,    0,  274,  274,    0,  275,    0,
+      298,  322,  322,  322,  335,    0,    0,    0,    0,    0,
+      381,  381,  381,    0,  367,    0,  366,  381,  398,  424,
+      419,    0,  420,    0,    0,    0,    0,    0,    0,  475,
+
+      474,    0,    0,  487,  487,    0,  488,  492,    0,    0,
+        0,    0,    0,   24,    0,    0,  218,    0,    0,    0,
+       49,    0,    0,    0,   79,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,  219,    0,    0,    0,  188,  214,  214,  206,  205,
-        0,    0,    0,  274,  274,    0,  270,  269,  274,    0,
-        0,  322,  322,    0,    0,  335,    0,  344,  343,    0,
-      351,    0,  359,  358,  381,  381,  381,  369,  368,    0,
-        0,  398,  419,    0,    0,    0,    0,  437,    0,    0,
-
-        0,  479,  478,    0,    0,    0,    0,    0,  499,    0,
-        0,    0,    0,  440,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    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,  441,    0,    0,  214,    0,    0,    0,  208,
-      207,    0,  230,  274,  274,  274,    0,  268,  267,  322,
-        0,    0,    0,  318,  317,    0,    0,  381,  381,  381,
-        0,  371,  370,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,  477,
-
-      476,    0,    0,    0,    0,  440,  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,  219,    0,    0,    0,  188,  214,  214,  206,
+      205,    0,    0,    0,  274,  274,    0,  270,  269,  274,
+        0,    0,  322,  322,    0,    0,  335,    0,  344,  343,
+        0,  351,    0,  359,  358,  381,  381,  381,  369,  368,
+        0,    0,  398,  419,    0,    0,    0,    0,  437,    0,
+
+        0,    0,  479,  478,    0,    0,    0,    0,    0,  499,
+        0,    0,    0,    0,  440,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    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,    0,    0,  441,  134,    0,    0,    0,
-      214,    0,  210,  209,  274,  274,  274,  322,    0,  314,
-      313,    0,  331,  330,  381,    0,    0,  381,    0,    0,
+        0,    0,    0,  441,    0,    0,  214,    0,    0,    0,
+      208,  207,    0,  230,  274,  274,  274,    0,  268,  267,
+      322,    0,    0,    0,  318,  317,    0,    0,  381,  381,
+      381,    0,  371,  370,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+
+      477,  476,    0,    0,    0,    0,  440,  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,    0,    0,    0,
-      453,  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,  454,  134,    0,
-        0,  200,  199,  214,  274,  274,  274,  322,  381,    0,
-      365,  364,  381,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  428,    0,    0,  427,    0,  450,    0,
+        0,    0,    0,    0,    0,    0,  441,  134,    0,    0,
+        0,  214,    0,  210,  209,  274,  274,  274,  322,    0,
+      314,  313,    0,  331,  330,  381,    0,    0,  381,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-      453,   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,  454,    0,  147,  214,  274,  274,    0,    0,  322,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,  453,  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,  454,  134,
+        0,    0,  200,  199,  214,  274,  274,  274,  322,  381,
+        0,  365,  364,  381,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  428,    0,    0,  427,    0,  450,
         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,  274,  274,    0,    0,    0,  322,    0,  361,
-      360,    0,    0,    0,  394,    0,  393,    0,  415,    0,
-      414,    0,  430,  432,  429,  431,    0,  467,  481,    0,
-      480,    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,  274,  274,    0,    0,
-        0,    0,  322,    0,    0,    0,    0,  392,  391,  413,
-      412,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,  115,    0,    0,  114,    0,    0,    0,    0,
+        0,  453,   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,  454,    0,  147,  214,  274,  274,    0,    0,
+      322,    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,   75,
+       71,    0,    0,   74,   70,    0,   92,    0,    0,   91,
+        0,    0,    0,  103,    0,    0,    0,    0,    0,    0,
+        0,    0,  214,  274,  274,    0,    0,    0,  322,    0,
+      361,  360,    0,    0,    0,  394,    0,  393,    0,  415,
+        0,  414,    0,  430,  432,  429,  431,    0,  467,  481,
+        0,  480,    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,  274,  274,    0,
+        0,    0,    0,  322,    0,    0,    0,    0,  392,  391,
+      413,  412,    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,   69,    0,   68,    0,    0,  121,    0,  120,
-        0,  202,  201,    0,  266,  265,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  316,  315,    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,  266,  265,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  316,  315,    0,
 
-        0,    0,    0,    0,    0,    0,    0,   11,    0,    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,  483,  482,
-        0,   73,   72,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  483,
+      482,    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,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,  117,  116,    0,    0,    0,    0,    0,    0,  252,
-        0,    0,  251,    0,    0,  373,    0,    0,  372,    0,
-        0,    0,    0,    0,  256,    0,  255,    0,  375,    0,
+        0,    0,  117,  116,    0,    0,    0,    0,    0,    0,
+      252,    0,    0,  251,    0,    0,  373,    0,    0,  372,
+        0,    0,    0,    0,    0,  256,    0,  255,    0,  375,
 
-      374,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  262,    0,  261,    0,    0,    0,    0,
-        0,    0,  264,  263,  254,  253,  377,  376,    0,    0,
+        0,  374,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  262,    0,  261,    0,    0,    0,
+        0,    0,    0,  264,  263,  254,  253,  377,  376,    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,
@@ -767,7 +767,7 @@ static yyconst flex_int16_t yy_accept[3217] =
         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,   13,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -814,7 +814,7 @@ static yyconst flex_int32_t yy_meta[75] =
         5,    5,    5,    5
     } ;
 
-static yyconst flex_int16_t yy_base[3687] =
+static yyconst flex_int16_t yy_base[3688] =
     {   0,
         0,    0,    0,    3,    6,    9,   12,   29,   16,   19,
        14,   17,   33,   36,   49,   55,   45,   61,   66,   72,
@@ -822,8 +822,8 @@ static yyconst flex_int16_t yy_base[3687] =
       158,  198,  201,  204,  208,  211,  228,  231,  234,  237,
       240,  257,  275,  329,  295,  298,  301,  305,  308,  349,
       352,  355,  383,  447,  360,  416,  511,  578,  407,  410,
-      413,  467,  470,  473,  477,  480,  645,  713,  531,  534,
-      781,  847,  537,  541,  544,  598,  601,  604,  608,  611,
+      645,  713,  413,  467,  781,  847,  470,  473,  477,  480,
+      531,  534,  537,  541,  544,  598,  601,  604,  608,  611,
       665,  668,  671,  675,  678,  733,  736,  739,  743,  746,
       801,  804,  807,  811,  814,  867,  870,  873,  877,  880,
 
@@ -842,988 +842,988 @@ static yyconst flex_int16_t yy_base[3687] =
      2091, 2095, 2142, 2145, 2148, 2152, 2199, 2202, 3083, 3150,
      2205, 2209, 2212, 2259, 2262, 2265, 2269, 2272, 3217, 3287,
      2319, 2322, 3357, 3414, 2325, 2329, 2332, 2386, 2389, 2392,
-     2396, 2399, 3471, 3541, 2453, 2456,    0,    0, 8755,11735,
-    11735,   95,  100,   29,   41,11735,  103,   51,11735,11735,
-     8740,11735,11735, 8729,11735, 8744, 8740,  202,11735,11735,
-    11735,11735, 8738, 8738, 8689,  153,11735,  161, 8715,    0,
-      145,11735, 8681,11735,  165, 3607,   73, 2465,  315,  357,
-     8717, 8664,11735,  168, 8707,    0,  152,11735, 8665,11735,
-
-      261, 8709,   31,11735,  266, 8700,    0,  245,11735, 8658,
-     8662, 8660,  421, 8661,11735,  269, 8687,    0,  340,11735,
-     8653, 8649,  271, 8651,  238,11735,  441,  163,  313,  368,
-    11735,  503, 8679,    0,  401,11735, 8634, 8636, 8626,11735,
-      506,  548,11735,  561, 8667,    0,  481,11735, 8634, 8622,
-    11735,  571, 2474, 2399,  567,  206,   38, 8668,  477, 2473,
-      572,  907, 8667,   79,11735,  628, 8658,    0,  482,11735,
-     8079, 8089, 8076, 8081,11735,  638,  426,  597,11735,  697,
-     8117,    0,  546,11735, 8073, 8083, 8061,11735,  703,  631,
-      691,11735,  706, 8113,    0,  549,11735, 8079, 8081,11735,
-
-      765,  753,11735,  773, 8108,    0,  616,11735, 8071, 8046,
-    11735,  776,  818,11735,  831, 8097,    0,  815,11735, 8039,
-     8045, 8054, 8037, 8030,11735,  838,  825, 8081,   87,11735,
-      841, 8072,    0,  882,11735, 8027, 8033, 8020,11735,  906,
-      958,11735,  914, 8057,    0,  891,11735, 8005,  203, 8011,
-     8020, 8010,  157,  311,  908,11735,  981, 1019,11735, 1039,
-     8038,    0,  953,11735, 7985, 7996, 7998,  251, 7996, 7975,
-    11735, 1044, 1032,11735, 1048, 8022,    0,  966,11735, 7967,
-     7965, 7967, 7977, 7978, 7952, 7946,11735, 1088, 1092,11735,
-     1105, 7990,    0, 1033,11735, 7946, 7955,11735, 1112, 1154,
-
-    11735, 1115, 7986,    0, 1089,11735, 7933, 7925, 7927,11735,
-     1118, 1160,11735, 1174, 7943,    0, 1090,11735, 7913, 7908,
-     7906,   15,11735, 1180,  559,  699,11735, 1183, 7934,    0,
-     1158,11735, 7885,  181,11735, 1186,  963, 7935, 7886,11735,
-     1241, 7924,    0, 1225,11735, 7868, 7863,  299,11735, 1247,
-     7921,  761,11735, 1303, 7910,    0, 1226,11735, 7872, 7866,
-    11735, 1309, 1352,11735, 1365, 7897,    0, 1231,11735, 7845,
-     7845,11735, 1368, 7897,  851,11735, 1372, 7887,    0, 1287,
-    11735, 7839, 7833, 7832,11735, 1376, 7878,  944,11735, 1433,
-     7869,    0, 1288,11735, 7818, 7818, 7823, 7816, 7801,11735,
-
-     1436, 1437, 7852,  512,11735, 1439, 7830,    0, 1293,11735,
-     7795,11735, 1444, 1482,11735, 1502, 7823,    0, 1360,11735,
-     7789,11735, 1507,  350,  814,11735, 1510, 7802,    0, 1423,
-    11735, 7765, 7767,11735, 1551, 1556, 1568,  677, 7733,11735,
-     7794, 7782,11735,11735,11735, 1566,  254, 7733, 7731, 7725,
-     7762, 7720,11735,    0, 7708, 7707, 7725, 7697,  104,  970,
-     7698, 7688, 7692,  372, 1574,  378, 7675, 7676, 1433,  429,
-     7701, 1500, 7667, 1575, 7661, 1590, 1643, 1644,11735,    0,
-     7666, 7667,11735,    0, 7659, 1964, 7652,  372, 7648, 7695,
-    11735,    0, 7638, 2031, 7627, 7631, 7617, 7624, 7615, 7606,
-
-     7591, 1654,11735,    0, 7593, 7583, 7590, 7569,11735,    0,
-     2098, 7567, 7612, 7590,  172, 7561, 7565,  493, 7553, 7580,
-      639,  680,  841,  888,  627, 1659,  707, 1282,11735,    0,
-     7549, 2155, 7554, 7531, 7536,11735,    0, 7536, 2462, 7532,
-     7528,11735,    0, 2480, 7532, 7527,11735,    0, 7526, 7521,
-     7519,11735,    0, 7529,  434, 2523, 7505, 7526, 7517, 1091,
-    11735,    0, 7496, 2534, 2541, 7503,11735,    0, 7499, 7493,
-     2546, 7474, 2587, 7470, 7456, 7473, 7472, 7450, 7469, 7466,
-     7459, 7457,11735,    0, 2590, 2593, 7438, 7434, 7443, 7443,
-     7439, 7437,11735,    0, 7438, 7434, 7418, 2596, 7411, 7399,
-
-     7418, 7401,11735,    0, 7398, 2599, 7383,11735,    0, 7386,
-     2654, 7378, 7388,11735,    0, 7375, 2657, 7367, 7381, 7379,
-     7366,11735,    0, 7357, 7372, 7349, 7343, 7350,11735,    0,
-     7331, 7348, 7340, 7329, 7366,11735,    0, 7320, 2660, 7324,
-    11735,    0, 7315, 7330, 7314,11735,    0, 7295, 7312, 7307,
-     7301,11735,    0, 7288, 7272, 7278, 7286, 7283, 7267, 7255,
-    11735,    0, 7260, 7269,11735,    0, 2663, 7259,11735,    0,
-     2666, 7249, 7243, 7286, 7290, 1471, 7237,11735, 1630,    0,
-     7232, 7227, 7272, 7267, 7220,11735, 7228, 7209, 2721, 2724,
-     1847, 7219, 7212, 7198, 7210, 7190, 7194, 7183, 7184, 7172,
-
-     7163, 7155, 7169, 7171, 7152, 7146, 7138, 7142, 7147, 7129,
-     7128, 1856, 7134, 7110, 7127, 7123, 7105, 7118, 7112, 2729,
-     2732, 7109, 2735, 1914, 7102, 7110, 2778, 2783,11735, 7079,
-     2787, 1983, 2793, 7063, 2835, 7067, 7070, 7073, 2838, 2849,
-     7049, 7033, 7037, 7037, 2843, 2853, 2862, 2050, 7018, 2902,
-     2905, 2229, 7030, 7012, 7006, 7000, 6988, 6992, 2289, 6986,
-     6985, 6978, 6967, 6967, 2908, 2416, 6980, 6979, 2911, 2970,
-     6962, 2914, 2466, 6976, 2973, 2977, 2980, 2488, 6974, 2983,
-     3044, 6973, 6956, 3037, 3047, 6951, 6935, 6947, 3040, 2552,
-     6939, 6919, 3050, 3113, 6916, 6911, 6912, 3106, 2621, 3109,
-
-     2688, 3116, 3120, 6905, 1786, 3170, 2805, 6908, 3175, 2868,
-     3182, 6903, 6899, 6889, 6876, 6876, 6873, 6881, 3178, 3188,
-     3237, 2933, 3240, 3003, 3243, 3250, 3263, 3316, 3325, 3310,
-     3334, 6877,   37, 6844, 3307, 3070, 3320, 6853, 6833, 3378,
-     3385, 6834, 3382, 3268, 3388, 3391, 6846, 3437, 3277, 6821,
-     3442, 3445, 6821, 3448, 3339, 6818, 6800, 6797, 3493, 3500,
-     3496, 3503, 3506, 3561, 3569, 6790, 3566, 3572, 3575, 3580,
-     3593, 3598, 6786, 3601, 3347, 3605, 3613, 3619, 3632, 3640,
-     3645, 3650, 3674, 3677, 3680, 3683, 6786, 6767, 6770, 6765,
-     6752, 3686, 3695, 6752, 6734, 3705, 3708, 3717, 3527, 3720,
-
-     3727, 3730, 3742, 6733, 3735, 3750, 6771,11735,11735, 1334,
-     6729,11735, 6771, 6767, 6716,11735,11735, 6710, 6709, 6718,
-     3755, 3760,11735, 3763, 1713, 6694, 6683, 6691, 6700, 6690,
-     6672, 6678, 6661, 6664, 6660, 6649, 6645, 6634, 6631,  633,
-     6645, 6628, 6624, 6638, 6629, 6620, 1923, 6610, 6599, 6604,
-     6597, 1109, 6610, 3769, 3774, 3782,11735, 3789, 3794, 3797,
-    11735,11735, 3815, 6628, 3818, 3821,11735, 3824, 6585, 3827,
-    11735,11735, 3843, 3846, 3855, 3861, 3866, 6599, 3879, 6596,
-     3882, 3885,11735, 3888, 1648, 6579, 3891, 6577, 3897, 3909,
-    11735, 3912, 3916,11735,11735, 6571, 3924, 3931,11735, 3934,
-
-     6564, 6565, 6573, 6551, 6545, 6534, 6532, 6544, 6542, 6518,
-     6517, 6530, 3937,11735,11735, 6506, 3945, 3953, 3956,11735,
-     3963, 6512, 3966,11735,11735, 6514, 3975, 3978,11735, 3982,
-     3985,11735,11735, 3997, 4001, 4004,11735, 4007, 4010, 4016,
-     4028, 4034,11735, 4037, 6473, 6480, 4040, 4047,11735,11735,
-     6464, 6472, 4058, 4061,11735, 4064, 6462, 6450, 4067, 4071,
-    11735,11735, 4085,11735,11735, 4093, 4096,11735, 4099, 6452,
-     6434, 6430, 6422, 4105,11735,11735, 4118, 4121,11735,11735,
-     4130, 4136, 6406, 6413, 6410, 6407, 6399, 6398, 6393, 4144,
-     4148,11735, 4151, 4154,11735,11735, 4170,11735,11735, 4178,
-
-     4181, 6378, 6384, 6388, 6381, 4189, 4192,11735, 4196, 6376,
-     6366, 6355, 6370, 4199,11735,11735, 4211, 4215, 6355, 6366,
-     4223, 4229,11735, 4232, 6357, 4235,11735,11735, 4251, 4254,
-    11735, 4257, 6335, 4260,11735,11735, 6339, 4276, 4279,11735,
-     4284, 6325, 4288,11735,11735, 6332, 6336, 6338, 4298, 4303,
-    11735, 4307, 4310, 4313, 4328, 4334, 6327, 4342, 4346,11735,
-     4350, 6319, 4353, 4371, 6306, 6306, 4357, 4379, 6317, 4387,
-     4390,11735, 4393, 6314, 4396,11735,11735, 4412, 4418,11735,
-     4421, 4424, 4427, 4442, 4445, 4453, 4460,11735, 4464, 4467,
-     4472, 6290, 6290, 4485, 4488, 4496, 4499,11735, 4503, 6286,
-
-     4506, 6297, 6277, 6247, 4509, 4518,11735, 4528, 6245, 6255,
-     4531, 4537,11735, 4540, 4543,11735,11735, 4551, 4559,11735,
-     4562, 4566,11735,11735, 6250, 4574, 4581,11735, 4584,  940,
-     4594,11735,11735, 6276, 6264, 6226, 6201, 4603, 6190, 6191,
-     6195, 6169, 6173, 6146, 6139, 2116, 6088, 2173, 6086, 6012,
-     2349, 6002, 6002, 2358, 5990, 5920, 5921, 5896, 5838, 5793,
-     5788, 5716, 5684, 2361, 5693, 5649, 4606, 4624, 4609, 4615,
-     4633, 5635, 5641, 4641, 5557, 4646,11735,11735, 4654, 4661,
-     4672,11735,11735, 5555, 4680, 4684, 5550, 4692, 2425, 5520,
-     4698, 4701, 4711, 4716, 5517, 4618,11735, 5485, 5418, 5394,
-
-     2428, 2560,   13,   40,  127,  304,  352,  383,  384, 4719,
-     4722, 4725, 4743,  434,  498, 4746, 4749, 4752, 4767, 4770,
-     4773,  566, 4781,  636,  637, 4788, 4791, 4800, 4811, 4814,
-      676,  686, 4818, 4822, 4836,  713, 4839,  703,  748, 4843,
-     4846, 4861,11735,11735, 4869,  740,  775,  765,  784,  844,
-      825, 4872, 4875,11735,11735, 4883, 4887, 4891, 4894, 4897,
-      853, 4905,  852,  895, 4912,11735,11735, 4923,  918, 4926,
-      924, 4929,  929,  974, 4932,  971, 1020, 1024, 4941, 4953,
-     4959,11735,11735, 4968,11735,11735, 1030, 4976, 2629, 4979,
-    11735,11735, 1032, 1054, 4996,11735,11735, 1071, 4991, 1094,
-
-     5004, 5011,11735,11735, 5019,11735,11735, 5027, 5030,11735,
-    11735, 1100, 1156, 5039,11735,11735, 5047, 1165, 5053, 5056,
-     1165, 1177, 1192, 5066, 1180, 5071, 5075, 5078, 5081, 5085,
-     1405, 1249, 5089,11735, 1264,11735,11735, 1232, 1234, 5099,
-     1234, 1250, 1283, 1293, 1329, 1346, 1359, 2696, 1362, 1371,
-     2753, 1375, 2797, 1383, 2876, 1370, 1400, 2943, 1427, 3011,
-     1435, 3078, 1461, 1456, 1481, 1504, 1506, 3141, 1506, 3145,
-     5104,11735,11735, 5118, 5121,11735,11735, 1517, 1536, 5131,
-     1510, 5137,11735,11735, 1523, 5152,11735,11735, 1514, 5160,
-     3208, 1533, 5163, 2965, 3032, 5112, 5172, 5186, 1561, 1556,
-
-     1562, 1563, 3212, 1586, 3247, 3455, 1593, 1582, 1584, 3466,
-     5189, 1584, 5192, 5195, 5206,11735,11735, 5214, 1602, 5217,
-     5222, 5226,11735,11735, 5241, 5244,11735,11735, 5254, 5262,
-     1635, 1631, 5266,11735,11735, 5274, 5277, 5285, 5288, 1640,
-     5296, 3535, 1664, 5299,11735,11735, 5309, 1668, 5315, 5318,
-     5328, 1655, 5333,11735,11735, 5341, 5346, 5359, 1753, 1780,
-     1782, 1785, 5362, 5365, 5368, 5371, 5380, 5386, 5389, 5392,
-     1790, 5398, 5407, 5416, 1780, 5419, 5422, 1798, 5437, 1793,
-     5440, 1804, 1789, 5445, 1828, 1822, 1848, 5448, 5460, 1850,
-     5468, 1840, 5471, 1856, 5475, 5478, 5481, 5499, 1852, 5502,
-
-     5505, 5508, 5511, 5514, 1856, 5529,11735,11735, 1872, 1887,
-     1894, 5537, 1917, 5540, 5549, 5558, 5563, 5567, 5571, 5585,
-     1953, 1976, 2043,11735, 1905, 5589, 5592, 1921, 1914, 1922,
-     2019, 1925, 1928, 4361, 1940, 1961, 1961, 5595, 1982, 1974,
-     1976, 5598, 5607, 5611, 1998, 5614, 2009, 5619, 5622, 1993,
-     1998, 2028, 2037, 5625, 2054, 5628, 2056, 2086, 5631, 2047,
-     5634, 2057, 5637, 5640, 2093, 2085, 2131, 2102, 2140, 2129,
-     2188, 2131, 5643,11735,11735, 5658, 5662, 2118, 2110, 2197,
-     2121, 5665, 5668, 2142, 2200, 2256, 5671, 5680,11735,11735,
-     5689, 5692, 5697, 5701, 5710, 5715, 5718, 5722, 5730, 2167,
-
-     2179, 5736,11735,11735, 5745, 2198, 2201, 2198, 5753,11735,
-     5756, 2215, 5760, 2222, 5765,11735,11735, 5773, 5779, 2224,
-     5787,11735,11735, 5795, 5798, 5806, 2225, 2236, 2231, 5809,
-     5813, 5827, 5830,11735,11735, 5838, 5842, 5850, 5856, 5859,
-     5868, 2240, 5875,11735,11735, 5883, 5887, 2249, 5895,11735,
-    11735, 2258, 5903,11735, 2281, 5906, 2270, 5909, 5912, 2271,
-     5915, 2293, 5927, 2306, 2308, 2291, 5935,11735, 2297, 5938,
-     2289, 5941, 5944, 5962, 5965, 2301, 5974, 2319, 5980, 5983,
-     5986, 5989, 6004, 6007, 6015, 2335, 2344, 2337, 2351, 6018,
-     2347, 6023,11735,11735, 6037, 6041, 6045,11735,11735, 6056,
-
-    11735, 2531, 2442, 2395, 2363, 6060, 6063, 6071, 6084, 2405,
-     2425, 2449, 2426, 6090, 6095, 6098, 2436, 6101, 2466, 2478,
-     2471, 6104, 6107, 6110, 6113, 2472, 6116, 6119, 6122, 6125,
-     6128, 6131, 2496, 6136, 2509, 2537, 6139,11735, 2538, 6143,
-     6146, 2556, 6161, 6164, 6167, 2572, 2571, 2571, 2581, 2574,
-     2585, 2582, 2586, 2593, 2586, 6175, 6182, 6188, 6196, 2597,
-     2632, 2609, 2612, 6200, 6203, 6206, 6209, 6217, 6220, 6225,
-     6238,11735,11735, 6246, 6251,11735, 6254,11735,11735, 6265,
-     2615, 2610, 2660, 2661, 2623, 2631, 6270, 2633, 6273,11735,
-    11735, 2655, 6285,11735,11735, 6293, 6298, 2677, 2666, 2680,
-
-     6307,11735,11735, 6315, 6319,11735,11735, 6327, 6330, 6338,
-    11735,11735, 6346, 2682, 6349,11735,11735, 2675, 2685, 2678,
-     6357, 2694, 6360, 6365, 6380, 2695, 6383, 6386, 2720, 2719,
-     2833, 2897, 2728, 2741, 6395,11735, 2731, 6401,11735,11735,
-     6414,11735,11735, 2751, 6409, 2751, 6423, 6428, 6431,11735,
-    11735, 6443,11735,11735, 6451, 6455, 6461, 6465, 6473, 6479,
-     2763, 6483, 6486, 6491, 2928, 2856, 6494, 6498,11735,11735,
-     6506, 6513, 6516, 6519, 2777, 2775, 6525, 6533, 2789, 6536,
-     6539, 6545, 6548, 6551, 6554, 2782, 2797, 6557, 6560, 6566,
-     6569, 2813, 6572, 2852,11735, 6575, 6578,11735,11735, 6586,
-
-     6593,11735, 6597,11735,11735, 2896, 2886, 2904, 2906, 2914,
-     2916, 2903, 2939, 2939, 2952, 6605, 6608, 6591, 6596, 6633,
-     6637, 2923, 2923, 2941, 6640, 2940, 6643,11735,11735, 6653,
-     6656,11735,11735, 6667, 6672, 2953, 2958, 3005, 3050, 3031,
-     3051, 3013, 6675, 6678, 3018, 3023, 6682,11735,11735, 6691,
-     3036, 3052, 6700, 6703,11735,11735, 6711, 3049, 3068, 3074,
-     3078, 6714,11735, 6719, 6724,11735,11735, 6733, 6739, 6742,
-    11735,11735, 6752, 6757, 3105, 3128, 3108, 3129, 6760, 3092,
-     6763, 3117, 6770, 6766, 6778, 6790, 6797, 6793, 6802, 6812,
-     6819, 6822, 6825, 6830, 6840, 6844,11735, 6847, 3155, 3258,
-
-     6852, 6859, 6855, 6866, 3124, 3120, 6874, 6878, 6881, 6884,
-     3122, 3137, 3138, 6887,11735, 3129, 6890, 6893, 3146, 3162,
-     3185, 3220, 3209, 3220, 3217, 3213, 3233, 3225, 3237, 6901,
-     3216, 3227, 3256, 3222, 3252, 3274, 3272, 3283, 3286, 3284,
-     3283, 3339, 6910, 3334, 3331, 6913, 3327, 6916, 6920,11735,
-     6923, 3334, 3339, 3401,11735, 3400,11735, 6926, 6929, 6935,
-     3342, 3364, 6945, 6948, 3353, 6956, 6963,11735, 6966,11735,
-     3362, 3369, 6969, 3370, 6974, 6993, 6978, 6987, 7001, 7009,
-     7012, 7015, 3436,11735, 3434,11735, 7018, 3393, 7021, 3395,
-     7036,11735, 7039, 7042, 7050, 7057, 7062, 7065,11735,11735,
-
-     7076, 7081, 7089, 7094, 7097,11735, 7100, 7103, 3467, 3444,
-     3503, 7107,11735, 3394, 3413, 7112, 3429, 3458, 3459, 7116,
-     7127, 3555, 3666, 3451, 3486, 3497, 3500, 3504, 3528, 3505,
-     3518, 3562, 3570, 3597, 7135, 3541, 3556, 3563, 3567, 3568,
-     3571, 3570, 3576, 3588, 3587, 3595, 3597, 3601, 3592, 3597,
-     3619, 7138, 3628, 7141, 7144,11735, 3621, 7147,11735,11735,
-     7150, 7154, 7168, 3622, 3638, 7171,11735,11735, 3648, 7179,
-     7183, 3640, 7191, 7197, 7200, 7209, 7215,11735,11735, 7223,
-    11735, 7227,11735,11735, 7235, 7238, 7242,11735,11735, 7245,
-     7249, 7263, 7266, 7269, 3754, 3826, 7277,11735, 7284, 7291,
-
-     7299,11735,11735, 7310, 7313, 7321, 7324, 7333,11735, 3694,
-     3707, 3748, 3648, 7339, 3664, 3684, 3691, 7342, 7353, 3712,
-     3724, 3821, 3743, 3746, 3831, 3725, 3779, 3763, 3762, 3766,
-    11735, 3786, 3772, 3770, 3790,11735, 7345, 3768, 3778, 3766,
-     3782, 3801, 3807, 3822, 3809, 3818, 3806, 3836, 3844, 3850,
-     3855, 3838, 7364, 3854, 7367, 7370, 7373, 7376, 7391,11735,
-    11735, 7399,11735, 3861, 3858, 3872, 7402,11735,11735, 3876,
-     7410, 7418, 7430,11735,11735, 7438, 7441, 7449, 7452, 7456,
-     7460,11735,11735, 7470, 7474, 7482, 7488, 3894, 3895, 3905,
-     3909, 3916, 3916, 7496, 7500, 7508, 3990, 4009, 7519,11735,
-
-    11735, 3954, 3942, 7527, 3910, 7413, 7530, 3903, 3922, 7533,
-    11735,11735, 3970, 3958, 3961, 3989, 4001, 3990, 3998, 4024,
-     7541, 4015, 4036, 4066, 4057, 4042, 4061, 4076, 4068, 7548,
-     4024, 4026, 4052, 4100, 4104, 4089, 4055, 4049, 4051, 4074,
-     4119, 4120, 4112, 4076, 4088, 7551, 7554, 7559, 7562, 7568,
-     4089, 7580,11735,11735, 4090, 4099, 4088, 4108, 7588,11735,
-    11735, 7598,11735,11735, 7606, 7611, 7614, 7624, 7629, 4130,
-     4132, 7638, 4143, 4205, 4126, 4135, 4180, 4146, 4169, 4197,
-     7646, 7649, 4177, 4184, 4181, 4196, 4222, 7652, 7658, 7661,
-     7671, 7680, 7683, 7686, 4188, 4202, 4204, 4206, 4212, 4222,
-
-     4226, 4226, 7689, 7692, 4238, 4238,11735, 4240, 4243, 4243,
-    11735, 4245, 7700, 4231, 4221, 4287,11735,11735, 4246, 4246,
-     4250, 4240, 4311,11735,11735, 4272, 4272, 7703, 7707, 7710,
-     7719,11735,11735, 4268, 4271, 4276, 7729, 4277, 7732, 7735,
-    11735,11735, 7743, 4303, 4315, 4306, 4325, 4322, 4341, 4332,
-     4345, 4343, 4353,11735, 4349, 4360,11735, 7750,11735, 7753,
-     4361, 4362, 4377, 4365, 4389, 7756, 7763, 7775, 7806, 7853,
-     7783, 7786, 7789, 4381, 4402, 4405, 4372, 4392, 4409, 4425,
-     4395, 7794,11735,11735, 4431, 4406, 4407, 4433, 4417, 4420,
-     7817, 4392, 4394,11735, 4398, 4415, 4411, 4413,11735, 4415,
-
-     4428, 7826, 7829,11735, 4433, 4435, 4445, 7832, 7836, 4454,
-     7844, 7873, 7864, 7882, 4509, 4478, 4509, 4485, 4520, 4488,
-     4527, 4498, 4544, 4550, 4549, 4550, 7890, 4567, 4534, 4571,
-     4541, 4580, 7899, 4583, 4631, 7919, 7966, 4576,11735,11735,
-     4554, 4579,11735,11735, 4561,11735, 4596, 4610,11735, 4622,
-     4623, 7893,11735, 4635, 4604, 4601, 4653, 4651, 4613, 4613,
-     4659, 4619, 4624, 4606, 7939, 4658, 4759, 4627, 7947,11735,
-    11735, 7955, 4769, 4772,11735, 4683,11735, 4682,11735, 4692,
-    11735, 4697,11735,11735,11735,11735, 7912,11735,11735, 4686,
-    11735, 4687, 4696, 4758, 4712, 4705, 4848, 4726, 7977, 4722,
-
-     4713, 4725, 4716,11735,11735,11735,11735,11735, 4756, 4691,
-    11735,11735, 4827, 4707,11735, 7986, 7989, 7992, 4813, 4731,
-     4839, 4736, 7997, 4881, 4752, 4897, 4759,11735,11735,11735,
-    11735, 4767, 4768, 8000, 4804, 4802, 4818, 8015, 4826, 4811,
-     4844, 4838,11735, 4817, 4863,11735, 4834, 4896, 8019, 8022,
-     8030, 8037, 8048, 8051, 4871, 4879, 4898, 4883, 4904, 4919,
-     8059, 8067, 4907, 4915, 4928, 4911, 4920, 4936, 4924, 4927,
-     8062, 4949,11735, 4941,11735, 4942, 4933,11735, 4935,11735,
-     8077,11735,11735, 8085,11735,11735, 8093, 4977, 4999, 4950,
-     4957, 4963, 4966, 4976, 4972, 8101,11735,11735, 4981, 4986,
-
-     4989, 4998, 5004, 5002, 5040, 5043, 5084,11735, 5047, 5052,
-     5008, 5010, 5049, 5065, 5075, 5070, 5081, 5087, 5092, 5096,
-     5103, 5110, 5107, 5120, 5121, 5118, 5125, 5126,11735,11735,
-     5140,11735,11735, 5104, 5115, 5130, 5149, 5133, 5155, 5145,
-     5142, 5160, 5149, 5159, 5177, 5166, 5164, 5182, 5176, 5173,
-     5197, 5211, 5221, 5224, 5200, 5200, 5203, 5203, 5223, 5215,
-     5248, 5233, 5223, 5253, 5241, 5237, 5278, 5259, 5258, 5287,
-     5320,11735,11735, 5276, 5281, 5280, 5288, 5309, 5290,11735,
-     5316, 5293,11735, 5327, 5305,11735, 5332, 5318,11735, 5395,
-     5316, 5329, 5319, 5333,11735, 5333,11735, 5350,11735, 5353,
-
-    11735, 5360, 8109, 5371, 5392, 5377, 5395, 5362, 5363, 5370,
-     5383, 8112, 5424,11735, 5423,11735, 5428, 5427, 5431, 5436,
-     5433, 5436,11735,11735,11735,11735,11735,11735, 5478, 5508,
-     5516, 5517, 5435, 5456, 5470, 5529, 5509, 5536, 5638, 5665,
-     5587, 5656, 5439, 5506, 5503, 5636, 5688, 5732, 5695, 5752,
-     5709, 5721, 5774, 5775, 5668, 5716, 5750, 5766, 5783, 5829,
-     5803, 5804, 5854, 5856, 5818, 5872, 5904, 5959, 5844, 5883,
-     5786, 5905, 5934, 5939, 5931, 5936, 5979, 5995, 5438, 5984,
-     5941, 6017, 5960, 6014, 6004, 6116, 6069, 6160, 5815, 6010,
-     6026, 6131, 6155, 6223, 5880, 6138, 6167, 6212, 6226, 6241,
-
-     6210, 6272, 6060, 6133, 6285, 6286, 6197, 6218, 6323, 6356,
-     6154, 6075, 8120, 8123,11735,11735, 8143, 8152, 8161, 8170,
-     8179, 8188, 8197, 8206, 8215, 8224, 8233, 8242, 8251, 8260,
-     8269, 8278, 8287, 8296, 8305, 8314, 8323, 8332, 8341, 8350,
-     8359, 8368, 8377, 8386, 8395, 8404, 8413, 8422, 8431, 8440,
-     8449, 8458, 8467, 8476, 8485, 8494, 8503, 8512, 8521, 8530,
-     8539, 8548, 8557, 8566, 8575, 8584, 8593, 8602, 8611, 8620,
-     8629, 8638, 8647, 8656, 8665, 8672, 8679, 8686, 8693, 8700,
-     8707, 8714, 8721, 8728, 8735, 8742, 8749, 8756, 8763, 8770,
-     8777, 8784, 8791, 8798, 8805, 8812, 8819, 8826, 8833, 8840,
-
-     8847, 8854, 8863, 8870, 8875, 8882, 8887, 8894, 8899, 8906,
-     8911, 8918, 8923, 8930, 8935, 8942, 8947, 8954, 8959, 8966,
-     8971, 8978, 8983, 8990, 8995, 9002, 9007, 9014, 9019, 9026,
-     9031, 9038, 9043, 9050, 9055, 9062, 9067, 9074, 9079, 9086,
-     9091, 9098, 9103, 9110, 9115, 9122, 9127, 9134, 9139, 9146,
-     9151, 9158, 9163, 9170, 9175, 9182, 9187, 9196, 9202, 9209,
-     9217, 9224, 9232, 9239, 9247, 9254, 9262, 9269, 9277, 9284,
-     9292, 9299, 9307, 9314, 9322, 9329, 9337, 9344, 9352, 9359,
-     9367, 9374, 9382, 9389, 9397, 9405, 9413, 9420, 9428, 9435,
-     9443, 9450, 9458, 9465, 9473, 9481, 9489, 9497, 9505, 9512,
-
-     9520, 9528, 9536, 9544, 9552, 9559, 9567, 9574, 9582, 9590,
-     9597, 9605, 9614, 9620, 9627, 9635, 9643, 9651, 9659, 9667,
-     9674, 9682, 9689, 9697, 9704, 9712, 9719, 9727, 9734, 9742,
-     9750, 9758, 9766, 9774, 9781, 9789, 9797, 9805, 9812, 9820,
-     9827, 9835, 9842, 9850, 9857, 9865, 9872, 9880, 9887, 9895,
-     9902, 9910, 9917, 9925, 9932, 9940, 9948, 9955, 9963, 9970,
-     9978, 9985, 9993,10001,10008,10016,10025,10034,10041,10049,
-    10057,10064,10072,10079,10087,10094,10102,10109,10116,10124,
-    10131,10139,10147,10154,10162,10169,10177,10185,10192,10200,
-    10208,10216,10223,10231,10238,10246,10253,10261,10268,10276,
-
-    10283,10291,10298,10306,10313,10321,10329,10336,10344,10351,
-    10359,10367,10375,10383,10391,10399,10408,10417,10424,10432,
-    10440,10447,10455,10462,10470,10477,10485,10492,10499,10507,
-    10514,10522,10530,10538,10546,10553,10561,10569,10576,10584,
-    10592,10600,10607,10615,10622,10630,10637,10645,10652,10660,
-    10667,10675,10683,10691,10698,10706,10714,10722,10730,10737,
-    10745,10753,10761,10769,10778,10787,10795,10803,10811,10818,
-    10826,10833,10841,10849,10857,10865,10873,10881,10889,10897,
-    10905,10913,10920,10928,10935,10943,10951,10959,10966,10973,
-    10981,10988,10996,11003,11010,11018,11025,11033,11040,11048,
-
-    11056,11064,11071,11079,11087,11095,11104,11113,11121,11129,
-    11136,11143,11151,11159,11167,11175,11183,11190,11198,11205,
-    11213,11221,11228,11235,11243,11250,11258,11265,11272,11279,
-    11287,11294,11302,11310,11318,11326,11334,11342,11350,11359,
-    11368,11376,11384,11391,11399,11407,11415,11423,11431,11438,
-    11446,11453,11461,11469,11476,11483,11491,11499,11507,11514,
-    11521,11529,11537,11545,11553,11561,11569,11577,11585,11594,
-    11603,11611,11618,11625,11633,11641,11649,11656,11664,11671,
-    11680,11689,11698,11707,11716,11725
+     2396, 2399, 3471, 3541, 2453, 2456,    0,    0, 8759,11752,
+    11752,   95,  100,   29,   41,11752,  103,   51,11752,11752,
+     8748,11752,11752, 8733,11752, 8748, 8748,  202,11752,11752,
+    11752,11752, 8742, 8742, 8697,  153,11752,  161, 8719,    0,
+      145,11752, 8685,11752,  165, 3607,   73, 2465,  315,  357,
+     8725, 8668,11752,  168, 8711,    0,  152,11752, 8673,11752,
+
+      261, 8713,   31,11752,  266, 8704,    0,  245,11752, 8666,
+     8666, 8664,  421, 8669,11752,  269, 8691,    0,  340,11752,
+     8657, 8657,  271, 8655,  238,11752,  441,  484,11752,  504,
+     8683,    0,  401,11752, 8642, 8640, 8630,11752,  561,  548,
+    11752,  571, 8675,    0,  481,11752, 8107, 8095,11752,  628,
+     3671, 8092,  163, 2399,  567,  206,   38, 8143,  954, 2473,
+      572,  907, 8142,   79,11752,  638, 8133,    0,  482,11752,
+     8089, 8099, 8087, 8091,11752,  697,  313,  368,11752,  703,
+     8127,    0,  546,11752, 8082, 8085, 8063,11752,  706,  426,
+      497,11752,  765, 8114,    0,  549,11752, 8074, 8076,11752,
+
+      771,  682,11752,  774, 8103,    0,  616,11752, 8068, 8042,
+    11752,  831,  690,11752,  837, 8090,    0,  750,11752, 8039,
+     8044, 8050, 8038, 8026,11752,  840,  825, 8080,   87,11752,
+      906, 8071,    0,  758,11752, 8026, 8024, 8011,11752,  914,
+      891,11752,  977, 8053,    0,  815,11752, 7995,  203, 8001,
+     8010, 8012,  157,  311,  902,11752,  981, 1019,11752, 1039,
+     8039,    0,  825,11752, 7983, 8001, 7998,  251, 7997, 7975,
+    11752, 1044, 1032,11752, 1048, 8012,    0,  956,11752, 7961,
+     7956, 7963, 7972, 7974, 7936, 7926,11752, 1088, 1092,11752,
+     1105, 7973,    0, 1033,11752, 7917, 7927,11752, 1112, 1154,
+
+    11752, 1115, 7957,    0, 1089,11752, 7923, 7919, 7920,11752,
+     1118, 1160,11752, 1174, 7944,    0, 1090,11752, 7914, 7909,
+     7903,   15,11752, 1180,  466,  597,11752, 1183, 7931,    0,
+     1158,11752, 7883,  181,11752, 1186,  963, 7935, 7886,11752,
+     1241, 7915,    0, 1225,11752, 7867, 7858,  299,11752, 1247,
+     7916,  785,11752, 1303, 7906,    0, 1226,11752, 7867, 7871,
+    11752, 1309, 1352,11752, 1365, 7901,    0, 1231,11752, 7848,
+     7841,11752, 1368, 7894,  851,11752, 1372, 7884,    0, 1287,
+    11752, 7831, 7826, 7829,11752, 1376, 7874, 1286,11752, 1433,
+     7861,    0, 1288,11752, 7798, 7798, 7803, 7796, 7771,11752,
+
+     1436, 1437, 7822,  507,11752, 1439, 7813,    0, 1360,11752,
+     7773,11752, 1444, 1482,11752, 1502, 7801,    0, 1423,11752,
+     7767,11752, 1507,  350,  814,11752, 1510, 7798,    0, 1486,
+    11752, 7764, 7762,11752, 1551, 1556, 1568,  687, 7727,11752,
+     7787, 7771,11752,11752,11752, 1566,  254, 7720, 7713, 7711,
+     7758, 7707,11752,    0, 7700, 7696, 7720, 7691,  104,  970,
+     7683, 7682, 7686,  372, 1574,  378, 7673, 7670, 1433,  627,
+     7696, 1500, 7671, 1575, 7666, 1590, 1643, 1644,11752,    0,
+     7657, 7659,11752,    0, 7637, 1964, 7630,  372, 7625, 7665,
+    11752,    0, 7613, 2031, 7602, 7614, 7600, 7604, 7601, 7601,
+
+     7585,11752,    0, 7593, 7579, 7590, 7570,11752,    0, 2098,
+     7567, 7606, 7584,  172, 7559, 7563, 1654,  695, 7547, 1655,
+     7574,  680,  707,  841,  914,  911, 1779, 1037, 1282,11752,
+        0, 7550, 2155, 7558, 7531, 7537,11752,    0, 7540, 2462,
+     7533, 7528,11752,    0, 2480, 7532, 7531,11752,    0, 7529,
+     7520, 7515,11752,    0, 7516,  434, 2522, 7487, 7508, 7499,
+      621,11752,    0, 7473, 2532, 2540, 7487,11752,    0, 7492,
+     7488, 2546, 7469, 2587, 7464, 7459, 7472, 7471, 7453, 7464,
+     7463, 7456, 7454,11752,    0, 2590, 2593, 7436, 7428, 7445,
+     7444, 7433, 7433,11752,    0, 7433, 7430, 7403, 2596, 7397,
+
+     7392, 7406, 7390,11752,    0, 7389, 2599, 7381,11752,    0,
+     7383, 2654, 7375, 7392,11752,    0, 7378, 2657, 7359, 7377,
+     7375, 7356,11752,    0, 7345, 7357, 7346, 7339, 7346,11752,
+        0, 7333, 7352, 7347, 7320, 7358,11752,    0, 7311, 2660,
+     7315,11752,    0, 7300, 7316, 7306,11752,    0, 7287, 7303,
+     7298, 7298,11752,    0, 7276, 7270, 7275, 7279, 7277, 7260,
+     7257,11752,    0, 7257, 7266,11752,    0, 2663, 7262,11752,
+        0, 2666, 7247, 7242, 7281, 7290, 1537, 7233,11752, 1630,
+        0, 7229, 7228, 7263, 7262, 7214,11752, 7227, 7206, 2466,
+     2721, 1847, 7212, 7201, 7187, 7199, 7171, 7177, 7170, 7181,
+
+     7163, 7155, 7154, 7160, 7159, 7144, 7139, 7127, 7132, 7144,
+     7123, 7122, 1856, 7132, 7110, 7125, 7098, 7086, 7093, 7088,
+     2724, 2729, 7086, 2732, 1914, 7081, 7105, 2735, 2780,11752,
+     7058, 2783, 1983, 2790, 7044, 2793, 7048, 7051, 7050, 2786,
+     2849, 7032, 7038, 7028, 2835, 2838, 2841, 2050, 7006, 2845,
+     2903, 2229, 7021, 7003, 6999, 7002, 6990, 6983, 6987, 2289,
+     6985, 6983, 6977, 6975, 6975, 2906, 2416, 6973, 6972, 2910,
+     2913, 6950, 2916, 2487, 6964, 2969, 2972, 2975, 2551, 6956,
+     2980, 2983, 6951, 6949, 2995, 3039, 6939, 6925, 6926, 3045,
+     2621, 6925, 6905, 3049, 3052, 6901, 6895, 6899, 3063, 2688,
+
+     3105, 2868, 3108, 3114, 6902, 1786, 3117, 2934, 6905, 3129,
+     3003, 3170, 6899, 6897, 6870, 6855, 6852, 6849, 6861, 3123,
+     3179, 3176, 3071, 3182, 3238, 3188, 3250, 3255, 3258, 3263,
+     3308, 3333, 6834,   37, 6824, 3319, 3269, 3322, 6835, 6815,
+     3327, 3377, 6816, 3381, 3277, 3385, 3388, 6817, 3391, 3340,
+     6803, 3434, 3438, 6802, 3443, 3446, 6799, 6781, 6768, 3491,
+     3500, 3494, 3497, 3503, 3506, 3563, 6773, 3521, 3566, 3570,
+     3573, 3576, 3597, 6771, 3591, 3461, 3600, 3603, 3611, 3635,
+     3639, 3642, 3646, 3677, 3682, 3649, 3685, 6769, 6751, 6748,
+     6752, 6739, 3696, 3704, 6746, 6731, 3710, 3739, 3700, 3527,
+
+     3743, 3746, 3707, 3751, 6726, 3765, 3769, 6774,11752,11752,
+      932, 6732,11752, 6757, 6752, 6700,11752,11752, 6698, 6696,
+     6699, 3772, 3775,11752, 3778, 1714, 6686, 6677, 6682, 6687,
+     6671, 6658, 6663, 6648, 6654, 6654, 6645, 6643, 6634, 6621,
+      701, 6632, 6615, 6615, 6629, 6624, 6618, 1923, 6611, 6600,
+     6605, 6583, 1109, 6596, 3784, 3797, 3804,11752, 3808, 3811,
+     3816,11752,11752, 3829, 6620, 3834, 3837,11752, 3840, 6578,
+     3843,11752,11752, 3859, 3862, 3871, 3877, 3882, 6590, 3891,
+     6587, 3895, 3898,11752, 3901, 6583, 3904, 6568, 3909, 3922,
+    11752, 3928, 3931,11752,11752, 6562, 3941, 3947,11752, 3950,
+
+     6552, 6551, 6559, 6535, 6543, 1648, 6532, 6517, 6533, 6512,
+     6482, 6481, 6494, 3953,11752,11752, 6482, 3962, 3969, 3972,
+    11752, 3976, 6488, 3981,11752,11752, 6500, 3991, 3995,11752,
+     3998, 4001,11752,11752, 4010, 4017, 4020,11752, 4023, 4028,
+     4032, 4046, 4050,11752, 4053, 6469, 6470, 4056, 4065,11752,
+    11752, 6430, 6442, 4061, 4074,11752, 4080, 6427, 6424, 4083,
+     4087,11752,11752, 4095,11752,11752, 4103, 4106,11752, 4109,
+     6418, 6406, 6424, 6412, 4113,11752,11752, 4129, 4132,11752,
+    11752, 4140, 4147, 6401, 6404, 6407, 6403, 6398, 6400, 6388,
+     4158, 4161,11752, 4164, 4168,11752,11752, 4183,11752,11752,
+
+     4191, 4194, 6375, 6382, 6387, 6379, 4202, 4205,11752, 4209,
+     6366, 6363, 6354, 6366, 4212,11752,11752, 4224, 4228, 6347,
+     6358, 4236, 4242,11752, 4245, 6358, 4248,11752,11752, 4264,
+     4267,11752, 4270, 6337, 4273,11752,11752, 6335, 4289, 4292,
+    11752, 4297, 6324, 4301,11752,11752, 6331, 6335, 6337, 4311,
+     4316,11752, 4320, 4323, 4326, 4341, 4347, 6336, 4355, 4359,
+    11752, 4363, 6328, 4366, 4384, 6315, 6308, 4370, 4392, 6320,
+     4400, 4403,11752, 4406, 6320, 4409,11752,11752, 4425, 4431,
+    11752, 4434, 4437, 4440, 4455, 4458, 4466, 4473,11752, 4477,
+     4480, 4485, 6295, 6294, 4498, 4501, 4509, 4512,11752, 4516,
+
+     6287, 4519, 6295, 6283, 6257, 4522, 4531,11752, 4541, 6254,
+     6262, 4544, 4550,11752, 4553, 4556,11752,11752, 4564, 4572,
+    11752, 4575, 4579,11752,11752, 6245, 4587, 4594,11752, 4597,
+     1538, 4607,11752,11752, 6280, 6265, 6227, 6216, 4616, 6207,
+     6202, 6210, 6146, 6129, 6109, 6117, 2116, 6102, 2173, 6044,
+     6029, 2349, 6034, 6032, 2358, 6010, 6019, 5996, 5968, 5939,
+     5927, 5849, 5823, 5821, 2361, 5814, 5788, 4619, 4637, 4622,
+     4628, 4646, 5731, 5741, 4654, 5665, 4659,11752,11752, 4667,
+     4674, 4685,11752,11752, 5644, 4693, 4697, 5540, 4705, 5530,
+     4711, 4714, 4724, 4729, 5506, 4631,11752, 5414, 5432,   22,
+
+     2425, 2428, 2528,  141,  322,  338,  369,  393,  439,  437,
+     4732, 4735, 4738, 4756,  448,  490, 4759, 4762, 4765, 4780,
+     4783, 4786,  498, 4794,  527,  561, 4801, 4804, 4813, 4824,
+     4827,  552,  577, 4831, 4835, 4849,  636, 4852,  694,  721,
+     4856, 4859, 4874,11752,11752, 4882,  740,  772,  757,  762,
+      783,  815, 4885, 4888,11752,11752, 4896, 4900, 4904, 4907,
+     4910,  843, 4918,  829,  845, 4925,11752,11752, 4936,  872,
+     4939,  880, 4942,  907,  935, 4945,  968,  977, 1009, 4954,
+     4966, 4972,11752,11752, 4981,11752,11752, 1030, 4989, 2559,
+     4992,11752,11752, 1037, 1088, 5009,11752,11752, 1086, 5004,
+
+     1090, 5017, 5024,11752,11752, 5032,11752,11752, 5040, 5043,
+    11752,11752, 1094, 1117, 5052,11752,11752, 5060, 1150, 5066,
+     5069, 1154, 1176, 1186, 5079, 1179, 5084, 5088, 5091, 5094,
+     5098, 1405, 1221, 5102,11752, 1249,11752,11752, 1221, 1233,
+     5112, 1228, 1249, 1240, 1247, 1301, 1305, 1305, 2629, 1322,
+     1347, 2696, 1363, 2876, 1373, 2942, 1360, 1359, 3208, 1371,
+     3247, 1378, 3348, 1412, 1427, 1437, 1463, 1465, 3212, 1467,
+     3409, 5117,11752,11752, 5131, 5134,11752,11752, 1517, 1536,
+     5144, 1515, 5150,11752,11752, 1524, 5165,11752,11752, 1531,
+     5173, 1548, 5176, 2717, 3112, 5125, 5185, 5199, 1569, 1557,
+
+     1567, 1579, 3316, 1588, 3352, 3535, 5202, 1594, 1584, 1585,
+     5205, 5208, 1602, 5211, 5214, 5222,11752,11752, 5230, 1617,
+     5235, 5238, 5242,11752,11752, 5253, 5257,11752,11752, 5273,
+     5278, 1643, 1632, 5282,11752,11752, 5291, 5297, 5305, 5309,
+     1659, 5323, 4042, 1670, 5326,11752,11752, 5334, 1672, 5337,
+     5343, 5355, 1747, 5358,11752,11752, 5366, 5369, 5377, 1777,
+     1792, 1797, 1801, 5384, 5387, 5390, 5395, 5408, 5411, 5414,
+     5417, 1806, 5420, 5432, 5440, 1800, 5443, 5447, 1826, 5461,
+     1833, 5464, 1851, 1831, 5470, 1854, 1834, 1854, 5473, 5485,
+     1865, 5493, 1863, 5496, 1896, 5499, 5502, 5505, 5508, 1905,
+
+     5527, 5523, 5531, 5534, 5537, 1907, 5542,11752,11752, 1914,
+     1913, 1906, 5552, 1923, 5557, 5560, 5576, 5579, 5582, 5585,
+     5604, 1977, 1976, 2043,11752, 1918, 5607, 5610, 1937, 1931,
+     1932, 2019, 1961, 1971, 4374, 1983, 1990, 1983, 5613, 2005,
+     1995, 1997, 5616, 5619, 5625, 2028, 5629, 2053, 5636, 5639,
+     2037, 2041, 2055, 2043, 5642, 2063, 5645, 2064, 2099, 5648,
+     2075, 5651, 2096, 5654, 5657, 2139, 2126, 2188, 2129, 2145,
+     2135, 2248, 2136, 5660,11752,11752, 5675, 5679, 2125, 2133,
+     2197, 2165, 5682, 5685, 2171, 2259, 2260, 5688, 5697,11752,
+    11752, 5706, 5709, 5714, 5718, 5727, 5732, 5735, 5739, 5747,
+
+     2171, 2185, 5753,11752,11752, 5762, 2201, 2202, 2198, 5770,
+    11752, 5773, 2224, 5777, 2227, 5782,11752,11752, 5790, 5796,
+     2231, 5804,11752,11752, 5812, 5815, 5823, 2237, 2267, 2273,
+     5826, 5830, 5844, 5847,11752,11752, 5855, 5859, 5867, 5873,
+     5876, 5885, 2281, 5892,11752,11752, 5900, 5904, 2290, 5912,
+    11752,11752, 2284, 5920,11752, 2293, 5923, 2276, 5926, 5929,
+     2280, 5932, 2306, 5944, 2321, 2322, 2325, 5952,11752, 2340,
+     5955, 2337, 5958, 5961, 5979, 5982, 2349, 5991, 2345, 5997,
+     6000, 6003, 6006, 6021, 6024, 6032, 2347, 2354, 2355, 2404,
+     6035, 2400, 6040,11752,11752, 6054, 6058, 6062,11752,11752,
+
+     6073,11752, 2452, 2477, 2472, 2414, 6077, 6080, 6088, 6101,
+     2420, 2441, 2459, 2464, 6107, 6112, 6115, 2475, 6118, 2478,
+     2492, 2495, 6121, 6124, 6127, 6130, 2495, 6133, 6136, 6139,
+     6142, 6145, 6148, 2501, 6153, 2509, 2537, 6156,11752, 2538,
+     6160, 6163, 2556, 6178, 6181, 6184, 2573, 2571, 2571, 2581,
+     2574, 2585, 2582, 2586, 2593, 2586, 6192, 6199, 6205, 6213,
+     2597, 2632, 2609, 2612, 6217, 6220, 6223, 6226, 6234, 6237,
+     6242, 6255,11752,11752, 6263, 6268,11752, 6271,11752,11752,
+     6282, 2615, 2609, 2660, 2661, 2618, 2630, 6287, 2624, 6290,
+    11752,11752, 2631, 6302,11752,11752, 6310, 6315, 2665, 2665,
+
+     2670, 6324,11752,11752, 6332, 6336,11752,11752, 6344, 6347,
+     6355,11752,11752, 6363, 2682, 6366,11752,11752, 2675, 2685,
+     2684, 6374, 2700, 6377, 6382, 6397, 2701, 6400, 6403, 2720,
+     2716, 2772, 2776, 2738, 2750, 6412,11752, 2746, 6418,11752,
+    11752, 6431,11752,11752, 2762, 6426, 2752, 6440, 6445, 6448,
+    11752,11752, 6460,11752,11752, 6468, 6472, 6478, 6482, 6490,
+     6496, 2763, 6500, 6503, 6508, 2848, 2855, 6511, 6515,11752,
+    11752, 6523, 6530, 6533, 6536, 2784, 2785, 6542, 6550, 2797,
+     6553, 6556, 6562, 6565, 6568, 6571, 2789, 2797, 6574, 6577,
+     6583, 6586, 2801, 6589, 2796,11752, 6592, 6595,11752,11752,
+
+     6603, 6610,11752, 6614,11752,11752, 2841, 2833, 2850, 2849,
+     2895, 2899, 2886, 2901, 2899, 2906, 6622, 6625, 6608, 6613,
+     6650, 6654, 2873, 2872, 2888, 6657, 2880, 6660,11752,11752,
+     6670, 6673,11752,11752, 6684, 6689, 2908, 2927, 2961, 2984,
+     2964, 2984, 2949, 6692, 6695, 2951, 2955, 6699,11752,11752,
+     6708, 2948, 2960, 6717, 6720,11752,11752, 6728, 2957, 2979,
+     2985, 2986, 6731,11752, 6736, 6741,11752,11752, 6750, 6756,
+     6759,11752,11752, 6769, 6774, 3017, 3039, 3023, 3048, 6777,
+     3009, 6780, 3011, 6787, 6783, 6795, 6807, 6814, 6810, 6819,
+     6829, 6836, 6839, 6842, 6847, 6857, 6861,11752, 6864, 3061,
+
+     3118, 6869, 6876, 6872, 6883, 2998, 3002, 6891, 6895, 6898,
+     6901, 3003, 3016, 3017, 6904,11752, 3026, 6907, 6910, 3048,
+     3071, 3074, 3088, 3092, 3106, 3104, 3118, 3141, 3139, 3150,
+     6918, 3133, 3137, 3186, 3135, 3131, 3145, 3143, 3148, 3216,
+     3145, 3164, 3186, 6927, 3182, 3180, 6930, 3183, 6933, 6937,
+    11752, 6940, 3200, 3203, 3278,11752, 3305,11752, 6943, 6946,
+     6952, 3248, 3279, 6962, 6965, 3272, 6973, 6980,11752, 6983,
+    11752, 3271, 3273, 6986, 3278, 6991, 7010, 6995, 7004, 7018,
+     7026, 7029, 7032, 3342,11752, 3364,11752, 7035, 3326, 7038,
+     3338, 7053,11752, 7056, 7059, 7067, 7074, 7079, 7082,11752,
+
+    11752, 7093, 7098, 7106, 7111, 7114,11752, 7117, 7120, 3379,
+     3386, 3381, 7124,11752, 3333, 3354, 7129, 3345, 3400, 3403,
+     7133, 7144, 3546, 3597, 3396, 3436, 3446, 3445, 3490, 3508,
+     3485, 3497, 3497, 3505, 3523, 7152, 3465, 3477, 3500, 3522,
+     3524, 3530, 3521, 3528, 3550, 3546, 3556, 3559, 3564, 3555,
+     3558, 3578, 7155, 3576, 7158, 7161,11752, 3574, 7164,11752,
+    11752, 7167, 7171, 7185, 3582, 3597, 7188,11752,11752, 3609,
+     7196, 7200, 3597, 7208, 7214, 7217, 7226, 7232,11752,11752,
+     7240,11752, 7244,11752,11752, 7252, 7255, 7259,11752,11752,
+     7262, 7266, 7280, 7283, 7286, 3842, 4089, 7294,11752, 7301,
+
+     7308, 7316,11752,11752, 7327, 7330, 7338, 7341, 7350,11752,
+     3674, 3671, 3731, 3604, 7356, 3624, 3627, 3631, 7359, 7370,
+     3652, 3659, 3730, 3659, 3681, 3761, 3656, 3700, 3692, 3691,
+     3698,11752, 3731, 3719, 3717, 3722,11752, 7362, 3717, 3731,
+     3718, 3734, 3744, 3749, 3755, 3749, 3762, 3750, 3766, 3776,
+     3781, 3801, 3783, 7381, 3800, 7384, 7387, 7390, 7393, 7408,
+    11752,11752, 7416,11752, 3807, 3793, 3807, 7419,11752,11752,
+     3821, 7427, 7435, 7447,11752,11752, 7455, 7458, 7466, 7469,
+     7473, 7477,11752,11752, 7487, 7491, 7499, 7505, 3834, 3836,
+     3839, 3846, 3851, 3872, 7513, 7517, 7525, 3889, 3903, 7536,
+
+    11752,11752, 3900, 3927, 7544, 3863, 7430, 7547, 3849, 3851,
+     7550,11752,11752, 3900, 3901, 3903, 3911, 3924, 3923, 3925,
+     3941, 7558, 3946, 3966, 3985, 3984, 3968, 3987, 4007, 3995,
+     7565, 3960, 3966, 3986, 4035, 4036, 4049, 4019, 4012, 4021,
+     4043, 4094, 4109, 4097, 4065, 4074, 7568, 7571, 7576, 7579,
+     7585, 4074, 7597,11752,11752, 4083, 4079, 4067, 4091, 7605,
+    11752,11752, 7615,11752,11752, 7623, 7628, 7631, 7641, 7646,
+     4134, 4138, 7655, 4145, 4156, 4103, 4117, 4148, 4112, 4122,
+     4149, 7663, 7666, 4145, 4156, 4158, 4173, 4182, 7669, 7675,
+     7678, 7688, 7697, 7700, 7703, 4182, 4193, 4195, 4184, 4189,
+
+     4209, 4216, 4203, 7706, 7709, 4224, 4225,11752, 4228, 4231,
+     4231,11752, 4233, 7717, 4211, 4210, 4274,11752,11752, 4232,
+     4231, 4232, 4218, 4279,11752,11752, 4240, 4245, 7720, 7724,
+     7727, 7736,11752,11752, 4245, 4249, 4251, 7746, 4254, 7749,
+     7752,11752,11752, 7760, 4280, 4295, 4297, 4308, 4301, 4312,
+     4305, 4320, 4312, 4326,11752, 4319, 4329,11752, 7767,11752,
+     7770, 4338, 4332, 4354, 4342, 4402, 7773, 7780, 7792, 7823,
+     7870, 7800, 7803, 7806, 4359, 4385, 4386, 4357, 4374, 4391,
+     4405, 4376, 7811,11752,11752, 4411, 4386, 4388, 4415, 4392,
+     4397, 7834, 4365, 4381,11752, 4381, 4393, 4386, 4387,11752,
+
+     4388, 4406, 7843, 7846,11752, 4406, 4411, 4422, 7849, 7853,
+     4418, 7861, 7890, 7881, 7899, 4479, 4451, 4483, 4456, 4492,
+     4467, 4499, 4470, 4521, 4522, 4521, 4522, 7907, 4531, 4499,
+     4531, 4509, 4549, 7916, 4566, 4585, 7936, 7983, 4536,11752,
+    11752, 4525, 4557,11752,11752, 4549,11752, 4587, 4596,11752,
+     4594, 4597, 7910,11752, 4606, 4564, 4563, 4623, 4635, 4596,
+     4600, 4645, 4606, 4611, 4593, 7956, 4640, 4646, 4619, 7964,
+    11752,11752, 7972, 4654, 4663,11752, 4669,11752, 4683,11752,
+     4692,11752, 4695,11752,11752,11752,11752, 7929,11752,11752,
+     4688,11752, 4689, 4709, 4771, 4701, 4713, 4736, 4715, 7994,
+
+     4731, 4722, 4735, 4726,11752,11752,11752,11752,11752, 4749,
+     4701,11752,11752, 4769, 4720,11752, 8003, 8006, 8009, 4753,
+     4770, 4799, 4772, 8014, 4823, 4780, 4826, 4782,11752,11752,
+    11752,11752, 4774, 4780, 8017, 4813, 4802, 4815, 8032, 4830,
+     4824, 4840, 4844,11752, 4821, 4867,11752, 4825, 4870, 8036,
+     8039, 8047, 8054, 8065, 8068, 4841, 4849, 4871, 4856, 4883,
+     4896, 8076, 8084, 4884, 4892, 4910, 4893, 4902, 4914, 4910,
+     4911, 8079, 4934,11752, 4926,11752, 4927, 4912,11752, 4913,
+    11752, 8094,11752,11752, 8102,11752,11752, 8110, 4950, 4961,
+     4929, 4938, 4942, 4945, 4964, 4961, 8118,11752,11752, 4966,
+
+     4981, 4978, 4980, 4989, 4985, 5023, 5022, 5020,11752, 5026,
+     5030, 4992, 4994, 5029, 5024, 5037, 5037, 5044, 5052, 5053,
+     5054, 5082, 5084, 5082, 5092, 5098, 5095, 5106, 5113,11752,
+    11752, 5121,11752,11752, 5089, 5096, 5110, 5136, 5121, 5141,
+     5128, 5129, 5148, 5144, 5142, 5159, 5149, 5149, 5167, 5158,
+     5155, 5173, 5207, 5193, 5212, 5185, 5191, 5198, 5205, 5223,
+     5216, 5256, 5238, 5228, 5258, 5243, 5233, 5266, 5252, 5246,
+     5280, 5270,11752,11752, 5267, 5276, 5274, 5279, 5308, 5283,
+    11752, 5308, 5286,11752, 5314, 5289,11752, 5314, 5298,11752,
+     5314, 5296, 5317, 5313, 5326,11752, 5327,11752, 5329,11752,
+
+     5337,11752, 5339, 8126, 5340, 5370, 5351, 5374, 5340, 5351,
+     5356, 5358, 8129, 5399,11752, 5397,11752, 5402, 5416, 5420,
+     5419, 5437, 5458,11752,11752,11752,11752,11752,11752, 5412,
+     5499, 5502, 5532, 5538, 5655, 5432, 5438, 5449, 5503, 5553,
+     5583, 5465, 5605, 5577, 5578, 5409, 5685, 5647, 5705, 5420,
+     5674, 5712, 5738, 5522, 5783, 5660, 5733, 5767, 5800, 5750,
+     5758, 5781, 5791, 5818, 5846, 5889, 5897, 5820, 5840, 5832,
+     5861, 5863, 5880, 5879, 5951, 5948, 5953, 5919, 5922, 5411,
+     5967, 5958, 6021, 5769, 5977, 6031, 6034, 5684, 5954, 6027,
+     6086, 6030, 6148, 6009, 6172, 5998, 6043, 6184, 6229, 6177,
+
+     6190, 6049, 6179, 6150, 6242, 6249, 6258, 6232, 6235, 6289,
+     6302, 6169, 6311, 8137, 8140,11752,11752, 8160, 8169, 8178,
+     8187, 8196, 8205, 8214, 8223, 8232, 8241, 8250, 8259, 8268,
+     8277, 8286, 8295, 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, 8689, 8696, 8703, 8710,
+     8717, 8724, 8731, 8738, 8745, 8752, 8759, 8766, 8773, 8780,
+     8787, 8794, 8801, 8808, 8815, 8822, 8829, 8836, 8843, 8850,
+
+     8857, 8864, 8871, 8880, 8887, 8892, 8899, 8904, 8911, 8916,
+     8923, 8928, 8935, 8940, 8947, 8952, 8959, 8964, 8971, 8976,
+     8983, 8988, 8995, 9000, 9007, 9012, 9019, 9024, 9031, 9036,
+     9043, 9048, 9055, 9060, 9067, 9072, 9079, 9084, 9091, 9096,
+     9103, 9108, 9115, 9120, 9127, 9132, 9139, 9144, 9151, 9156,
+     9163, 9168, 9175, 9180, 9187, 9192, 9199, 9204, 9213, 9219,
+     9226, 9234, 9241, 9249, 9256, 9264, 9271, 9279, 9286, 9294,
+     9301, 9309, 9316, 9324, 9331, 9339, 9346, 9354, 9361, 9369,
+     9376, 9384, 9391, 9399, 9406, 9414, 9422, 9430, 9437, 9445,
+     9452, 9460, 9467, 9475, 9482, 9490, 9498, 9506, 9514, 9522,
+
+     9529, 9537, 9545, 9553, 9561, 9569, 9576, 9584, 9591, 9599,
+     9607, 9614, 9622, 9631, 9637, 9644, 9652, 9660, 9668, 9676,
+     9684, 9691, 9699, 9706, 9714, 9721, 9729, 9736, 9744, 9751,
+     9759, 9767, 9775, 9783, 9791, 9798, 9806, 9814, 9822, 9829,
+     9837, 9844, 9852, 9859, 9867, 9874, 9882, 9889, 9897, 9904,
+     9912, 9919, 9927, 9934, 9942, 9949, 9957, 9965, 9972, 9980,
+     9987, 9995,10002,10010,10018,10025,10033,10042,10051,10058,
+    10066,10074,10081,10089,10096,10104,10111,10119,10126,10133,
+    10141,10148,10156,10164,10171,10179,10186,10194,10202,10209,
+    10217,10225,10233,10240,10248,10255,10263,10270,10278,10285,
+
+    10293,10300,10308,10315,10323,10330,10338,10346,10353,10361,
+    10368,10376,10384,10392,10400,10408,10416,10425,10434,10441,
+    10449,10457,10464,10472,10479,10487,10494,10502,10509,10516,
+    10524,10531,10539,10547,10555,10563,10570,10578,10586,10593,
+    10601,10609,10617,10624,10632,10639,10647,10654,10662,10669,
+    10677,10684,10692,10700,10708,10715,10723,10731,10739,10747,
+    10754,10762,10770,10778,10786,10795,10804,10812,10820,10828,
+    10835,10843,10850,10858,10866,10874,10882,10890,10898,10906,
+    10914,10922,10930,10937,10945,10952,10960,10968,10976,10983,
+    10990,10998,11005,11013,11020,11027,11035,11042,11050,11057,
+
+    11065,11073,11081,11088,11096,11104,11112,11121,11130,11138,
+    11146,11153,11160,11168,11176,11184,11192,11200,11207,11215,
+    11222,11230,11238,11245,11252,11260,11267,11275,11282,11289,
+    11296,11304,11311,11319,11327,11335,11343,11351,11359,11367,
+    11376,11385,11393,11401,11408,11416,11424,11432,11440,11448,
+    11455,11463,11470,11478,11486,11493,11500,11508,11516,11524,
+    11531,11538,11546,11554,11562,11570,11578,11586,11594,11602,
+    11611,11620,11628,11635,11642,11650,11658,11666,11673,11681,
+    11688,11697,11706,11715,11724,11733,11742
     } ;
 
-static yyconst flex_int16_t yy_def[3687] =
+static yyconst flex_int16_t yy_def[3688] =
     {   0,
-     3217, 3217, 3218, 3218, 3218, 3218, 3219, 3219, 3220, 3220,
-     3221, 3221, 3222, 3222, 3222, 3222, 3223, 3223, 3217, 3217,
-     3224, 3224, 3225, 3225, 3225, 3225, 3217, 3217, 3225, 3225,
-     3225, 3225, 3217, 3217, 3225, 3225, 3217, 3217, 3225, 3225,
-     3225, 3225, 3226, 3226, 3227, 3227, 3217, 3217, 3227, 3227,
-     3227, 3227, 3228, 3228, 3222, 3222, 3229, 3229, 3230, 3230,
-     3217, 3217, 3230, 3230, 3230, 3230, 3231, 3231, 3232, 3232,
-     3233, 3233, 3234, 3234, 3234, 3234, 3217, 3217, 3234, 3234,
-     3234, 3234, 3217, 3217, 3234, 3234, 3217, 3217, 3234, 3234,
-     3234, 3234, 3217, 3217, 3234, 3234, 3217, 3217, 3234, 3234,
-
-     3234, 3234, 3235, 3235, 3236, 3236, 3217, 3217, 3236, 3236,
-     3236, 3236, 3237, 3237, 3238, 3238, 3217, 3217, 3238, 3238,
-     3238, 3238, 3239, 3239, 3240, 3240, 3241, 3241, 3242, 3242,
-     3243, 3243, 3244, 3244, 3217, 3217, 3244, 3244, 3244, 3244,
-     3245, 3245, 3246, 3246, 3216,  145, 3247, 3247, 3248, 3248,
-     3249, 3249, 3250, 3250, 3251, 3251, 3252, 3252, 3253, 3253,
-     3254, 3254, 3255, 3255, 3256, 3256, 3257, 3257, 3217, 3217,
-     3257, 3257, 3257, 3257, 3258, 3258, 3259, 3259, 3217, 3217,
-     3259, 3259, 3259, 3259, 3260, 3260, 3261, 3261, 3217, 3217,
-     3261, 3261, 3261, 3261, 3262, 3262, 3263, 3263, 3264, 3264,
-
-     3265, 3265, 3217, 3217, 3265, 3265, 3265, 3265, 3266, 3266,
-     3267, 3267, 3217, 3217, 3267, 3267, 3267, 3267, 3268, 3268,
-     3269, 3269, 3217, 3217, 3269, 3269, 3269, 3269, 3270, 3270,
-     3271, 3271, 3272, 3272, 3273, 3273, 3217, 3217, 3273, 3273,
-     3273, 3273, 3274, 3274, 3275, 3275, 3217, 3217, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3276,
-     3216, 3216, 3276, 3216, 3216, 3216,  286,  286,  288,  286,
-      289,  289, 3216, 3216, 3216, 3277, 3216, 3216, 3277, 3216,
-
-     3216,  290,  289, 3216, 3216, 3216, 3278, 3216, 3216, 3278,
-     3278, 3278, 3216, 3216, 3216, 3216, 3216, 3279, 3216, 3216,
-     3279, 3279, 3279, 3279, 3279, 3216, 3216,  289,  289,  289,
-     3216, 3216, 3216, 3280, 3216, 3216, 3280, 3280, 3280, 3216,
-     3216, 3216, 3216, 3216, 3216, 3281, 3216, 3216, 3281, 3281,
-     3216, 3216,  290,  289,  290,  355,  354,  354,  354,  354,
-      355,  361,  360,  359, 3216, 3216, 3216, 3282, 3216, 3216,
-     3282, 3282, 3282, 3282, 3216, 3216,  289,  289, 3216, 3216,
-     3216, 3283, 3216, 3216, 3283, 3283, 3283, 3216, 3216,  289,
-      289, 3216, 3216, 3216, 3284, 3216, 3216, 3284, 3284, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3285, 3216, 3216, 3285, 3285,
-     3216, 3216, 3216, 3216, 3216, 3216, 3286, 3216, 3216, 3286,
-     3286, 3286, 3286, 3286, 3216, 3216,  289,  427,  427, 3216,
-     3216, 3216, 3287, 3216, 3216, 3287, 3287, 3287, 3216, 3216,
-     3216, 3216, 3216, 3216, 3288, 3216, 3216, 3288, 3288, 3288,
-     3288, 3288, 3288, 3288, 3288, 3216, 3216, 3216, 3216, 3216,
-     3216, 3289, 3216, 3216, 3289, 3289, 3289, 3289, 3289, 3289,
-     3216, 3216, 3216, 3216, 3216, 3216, 3290, 3216, 3216, 3290,
-     3290, 3290, 3290, 3290, 3290, 3290, 3216, 3216, 3216, 3216,
-     3216, 3216, 3291, 3216, 3216, 3291, 3291, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3292, 3216, 3216, 3292, 3292, 3292, 3216,
-     3216, 3216, 3216, 3216, 3216, 3293, 3216, 3216, 3293, 3293,
-     3293, 3293, 3216, 3216,  427,  289, 3216, 3216, 3216, 3294,
-     3216, 3216, 3294, 3294, 3216, 3216,  289,  537,  537, 3216,
-     3216, 3216, 3295, 3216, 3216, 3295, 3295, 3295, 3216, 3216,
-      537,  537, 3216, 3216, 3216, 3296, 3216, 3216, 3296, 3296,
-     3216, 3216, 3216, 3216, 3216, 3216, 3297, 3216, 3216, 3297,
-     3297, 3216, 3216,  537,  537, 3216, 3216, 3216, 3298, 3216,
-     3216, 3298, 3298, 3298, 3216, 3216,  537,  537, 3216, 3216,
-     3216, 3299, 3216, 3216, 3299, 3299, 3299, 3299, 3299, 3216,
-
-     3216,  289,  602,  602, 3216, 3216, 3216, 3300, 3216, 3216,
-     3300, 3216, 3216, 3216, 3216, 3216, 3216, 3301, 3216, 3216,
-     3301, 3216, 3216,  602,  289, 3216, 3216, 3216, 3302, 3216,
-     3216, 3302, 3302, 3216, 3216, 3216, 3216, 3303, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3304, 3304, 3305, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3306,
-     3306, 3307, 3216, 3308, 3308, 3308, 3308, 3216, 3309, 3216,
-     3216, 3310, 3310, 3310, 3310, 3310, 3310, 3310, 3310, 3310,
-
-     3311, 3216, 3216, 3312, 3312, 3312, 3312, 3313, 3216, 3314,
-     3314, 3314, 3315, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3316,
-     3316, 3316, 3316, 3316, 3317, 3216, 3318, 3318, 3318, 3318,
-     3319, 3216, 3320, 3320, 3320, 3321, 3216, 3322, 3322, 3322,
-     3323, 3216, 3324, 3324, 3324, 3324, 3324, 3324, 3325, 3216,
-     3216, 3326, 3326, 3326, 3326, 3327, 3216, 3328, 3328, 3328,
-     3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328, 3328,
-     3328, 3329, 3216, 3330, 3330, 3330, 3330, 3330, 3330, 3330,
-     3330, 3331, 3216, 3332, 3332, 3332, 3332, 3332, 3332, 3332,
-
-     3332, 3333, 3216, 3334, 3334, 3334, 3335, 3216, 3336, 3336,
-     3336, 3336, 3337, 3216, 3338, 3338, 3338, 3338, 3338, 3338,
-     3339, 3216, 3340, 3340, 3340, 3340, 3341, 3216, 3216, 3342,
-     3342, 3342, 3342, 3342, 3343, 3216, 3344, 3344, 3344, 3345,
-     3216, 3346, 3346, 3346, 3347, 3216, 3348, 3348, 3348, 3348,
-     3349, 3216, 3350, 3350, 3350, 3350, 3350, 3350, 3351, 3216,
-     3216, 3352, 3352, 3353, 3216, 3354, 3354, 3355, 3216, 3356,
-     3356, 3356, 3357, 3358, 3216, 3358, 3216, 3216, 3216, 3359,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3360, 3361, 3361,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3362, 3363,
-     3363, 3364, 3216, 3216, 3364, 3216, 3365, 3365, 3216, 3366,
-     3216, 3216, 3366, 3366, 3366, 3366, 3366, 3366, 3367, 3367,
-     3216, 3368, 3368, 3368, 3369, 3369, 3216, 3216, 3370, 3371,
-     3371, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3372, 3216, 3216, 3372, 3372, 3373, 3373,
-     3374, 3216, 3216, 3374, 3375, 3375, 3216, 3216, 3376, 3377,
-     3377, 3378, 3378, 3379, 3379, 3380, 3380, 3380, 3216, 3216,
-     3380, 3380, 3381, 3381, 3216, 3216, 3382, 3216, 3216, 3216,
-
-     3216, 3383, 3383, 3384, 3384, 3216, 3216, 3384, 3216, 3216,
-     3384, 3384, 3384, 3384, 3384, 3384, 3384, 3384, 3385, 3385,
-     3216, 3216, 3216, 3216, 3386, 3386, 3386, 3386, 3386, 3387,
-     3387, 3388, 3388, 3388, 3216, 3216, 3388, 3388, 3388, 3389,
-     3389, 3390, 3216, 3216, 3391, 3391, 3392, 3216, 3216, 3392,
-     3393, 3393, 3394, 3216, 3216, 3394, 3394, 3394, 3395, 3395,
-     3396, 3396, 3396, 3397, 3397, 3216, 3398, 3398, 3398, 3398,
-     3399, 3399, 3400, 3216, 3216, 3401, 3401, 3402, 3402, 3403,
-     3403, 3404, 3404, 3404, 3405, 3405, 3406, 3406, 3406, 3406,
-     3406, 3407, 3407, 3216, 3408, 3409, 3409, 3216, 3216, 3410,
-
-     3410, 3216, 3216, 3411, 3412, 3412, 3413, 3216, 3216, 3413,
-     3216, 3216, 3414, 3216, 3216, 3216, 3216, 3216, 3216, 3415,
-     3216, 3416, 3216, 3416, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3417, 3216, 3418, 3216, 3418, 3419, 3216,
-     3216, 3216, 3419, 3216, 3216, 3420, 3216, 3420, 3421, 3216,
-     3216, 3216, 3216, 3216, 3421, 3216, 3216, 3421, 3421, 3421,
-     3216, 3422, 3216, 3422, 3216, 3423, 3423, 3423, 3216, 3424,
-     3216, 3424, 3216, 3216, 3216, 3425, 3216, 3426, 3216, 3426,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3427, 3216, 3216, 3216, 3427, 3427, 3216, 3428, 3216,
-     3428, 3429, 3216, 3216, 3216, 3429, 3216, 3430, 3216, 3430,
-     3216, 3216, 3216, 3431, 3216, 3432, 3216, 3432, 3433, 3433,
-     3216, 3434, 3216, 3434, 3435, 3435, 3435, 3216, 3216, 3216,
-     3435, 3435, 3216, 3436, 3216, 3436, 3216, 3216, 3437, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3438, 3216, 3438, 3439,
-     3439, 3439, 3439, 3216, 3216, 3216, 3439, 3216, 3216, 3216,
-     3216, 3216, 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3216,
-     3440, 3216, 3440, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3441, 3441, 3441, 3441, 3216, 3442, 3216, 3442, 3443,
-     3443, 3443, 3443, 3216, 3216, 3216, 3216, 3216, 3443, 3443,
-     3216, 3444, 3216, 3444, 3445, 3216, 3216, 3216, 3216, 3446,
-     3216, 3446, 3447, 3216, 3216, 3216, 3447, 3216, 3448, 3216,
-     3448, 3449, 3216, 3216, 3216, 3449, 3449, 3449, 3216, 3450,
-     3216, 3450, 3216, 3216, 3216, 3216, 3451, 3216, 3452, 3216,
-     3452, 3216, 3216, 3216, 3453, 3453, 3216, 3216, 3453, 3216,
-     3454, 3216, 3454, 3455, 3216, 3216, 3216, 3216, 3456, 3216,
-     3456, 3216, 3216, 3216, 3216, 3216, 3457, 3216, 3457, 3216,
-     3216, 3458, 3458, 3216, 3216, 3216, 3459, 3216, 3459, 3460,
-
-     3460, 3460, 3460, 3460, 3216, 3461, 3216, 3461, 3216, 3462,
-     3216, 3463, 3216, 3463, 3216, 3216, 3216, 3216, 3464, 3216,
-     3464, 3216, 3216, 3216, 3465, 3216, 3466, 3216, 3466, 3467,
-     3468, 3216, 3216, 3216, 3216, 3216, 3469, 3470, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3471, 3216,
-     3216, 3472, 3216, 3473, 3474, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3474, 3216, 3216, 3474, 3475, 3216, 3476,
-     3216, 3216, 3476, 3477, 3478, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3479, 3479,
-     3216, 3216, 3480, 3481, 3481, 3482, 3216, 3216, 3483, 3216,
-     3216, 3484, 3485, 3486, 3486, 3216, 3216, 3486, 3486, 3487,
-     3216, 3216, 3216, 3216, 3488, 3489, 3489, 3489, 3489, 3216,
-     3216, 3216, 3216, 3216, 3489, 3489, 3489, 3489, 3489, 3489,
-     3489, 3490, 3216, 3216, 3216, 3491, 3491, 3491, 3491, 3492,
-     3493, 3493, 3493, 3493, 3216, 3216, 3216, 3493, 3493, 3494,
-     3495, 3496, 3497, 3497, 3498, 3499, 3499, 3499, 3499, 3500,
-     3216, 3216, 3216, 3216, 3216, 3216, 3501, 3502, 3216, 3216,
-     3216, 3216, 3503, 3503, 3216, 3216, 3216, 3503, 3504, 3505,
-
-     3506, 3216, 3216, 3216, 3216, 3216, 3216, 3507, 3216, 3216,
-     3216, 3508, 3508, 3216, 3216, 3216, 3509, 3510, 3216, 3216,
-     3510, 3510, 3510, 3511, 3216, 3512, 3513, 3514, 3515, 3516,
-     3517, 3518, 3518, 3216, 3518, 3216, 3216, 3216, 3519, 3520,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3521, 3216, 3216, 3216, 3522, 3216, 3523,
-     3524, 3216, 3216, 3216, 3524, 3216, 3216, 3216, 3524, 3525,
-     3216, 3526, 3216, 3216, 3216, 3216, 3216, 3527, 3528, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3529, 3216, 3216, 3216, 3216, 3216, 3530, 3531, 3531,
-     3532, 3216, 3216, 3216, 3533, 3216, 3216, 3216, 3534, 3535,
-     3536, 3536, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3536,
-     3537, 3216, 3216, 3216, 3216, 3216, 3538, 3539, 3216, 3216,
-     3539, 3539, 3216, 3216, 3216, 3216, 3216, 3539, 3539, 3539,
-     3539, 3539, 3539, 3540, 3216, 3216, 3541, 3541, 3541, 3542,
-     3543, 3216, 3216, 3543, 3543, 3216, 3216, 3543, 3544, 3545,
-     3546, 3547, 3547, 3548, 3549, 3549, 3549, 3216, 3216, 3549,
-     3550, 3551, 3552, 3216, 3553, 3553, 3553, 3554, 3555, 3556,
-
-     3557, 3558, 3558, 3559, 3560, 3216, 3216, 3216, 3560, 3560,
-     3560, 3561, 3216, 3216, 3216, 3562, 3563, 3216, 3216, 3564,
-     3565, 3566, 3566, 3216, 3216, 3567, 3568, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3569, 3570, 3216, 3571, 3572,
-     3572, 3572, 3573, 3574, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3575, 3576, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3577, 3216, 3216, 3216,
-     3578, 3579, 3216, 3216, 3580, 3581, 3216, 3216, 3582, 3583,
-
-     3583, 3216, 3216, 3216, 3216, 3216, 3216, 3583, 3216, 3216,
-     3216, 3216, 3584, 3585, 3216, 3216, 3216, 3216, 3216, 3585,
-     3216, 3216, 3216, 3216, 3216, 3585, 3585, 3585, 3585, 3216,
-     3216, 3586, 3216, 3216, 3216, 3216, 3216, 3587, 3216, 3216,
-     3588, 3589, 3216, 3216, 3216, 3216, 3216, 3589, 3216, 3216,
-     3216, 3589, 3216, 3216, 3590, 3591, 3592, 3592, 3593, 3594,
-     3594, 3594, 3216, 3216, 3216, 3594, 3216, 3216, 3595, 3596,
-     3216, 3216, 3216, 3216, 3216, 3597, 3598, 3599, 3600, 3601,
-     3216, 3216, 3216, 3216, 3602, 3603, 3603, 3603, 3603, 3604,
-     3216, 3216, 3216, 3216, 3605, 3606, 3216, 3216, 3216, 3216,
-
-     3216, 3607, 3608, 3608, 3216, 3216, 3216, 3609, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3610, 3611, 3216, 3216, 3216, 3612, 3216,
-     3216, 3612, 3613, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3614, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3615, 3216, 3216,
-     3216, 3216, 3216, 3616, 3216, 3216, 3216, 3216, 3216, 3617,
-     3618, 3618, 3216, 3216, 3618, 3216, 3619, 3620, 3216, 3216,
-     3216, 3620, 3216, 3216, 3216, 3216, 3216, 3620, 3620, 3620,
-
-     3216, 3216, 3216, 3621, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3622, 3623, 3216, 3216, 3216, 3623, 3623, 3624,
-     3625, 3626, 3216, 3216, 3627, 3628, 3216, 3216, 3628, 3628,
-     3216, 3216, 3628, 3629, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3630, 3631, 3632, 3633, 3634, 3216, 3216,
-     3216, 3216, 3216, 3216, 3635, 3636, 3636, 3636, 3636, 3637,
-     3216, 3638, 3639, 3640, 3641, 3641, 3216, 3216, 3216, 3216,
-     3642, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3643, 3644, 3216, 3645, 3216, 3216, 3216, 3645,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3646, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3647,
-     3216, 3216, 3216, 3648, 3649, 3650, 3650, 3216, 3216, 3216,
-     3216, 3650, 3216, 3651, 3652, 3652, 3216, 3216, 3216, 3652,
-     3652, 3652, 3653, 3216, 3216, 3216, 3654, 3655, 3655, 3655,
-     3656, 3216, 3216, 3657, 3216, 3216, 3216, 3658, 3659, 3216,
-     3216, 3216, 3659, 3659, 3216, 3216, 3216, 3216, 3659, 3660,
-     3216, 3661, 3662, 3663, 3664, 3665, 3666, 3216, 3216, 3667,
-     3667, 3667, 3668, 3216, 3669, 3216, 3216, 3670, 3671, 3671,
-
-     3216, 3672, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3673, 3216, 3216, 3674, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3675,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3676, 3216, 3216,
-     3677, 3678, 3678, 3216, 3216, 3216, 3216, 3678, 3216, 3679,
-     3680, 3680, 3216, 3216, 3680, 3680, 3216, 3216, 3216, 3216,
-     3655, 3655, 3655, 3656, 3216, 3216, 3658, 3216, 3216, 3659,
-     3659, 3659, 3216, 3216, 3216, 3216, 3659, 3660, 3216, 3661,
-     3216, 3216, 3216, 3216, 3664, 3665, 3666, 3216, 3216, 3216,
-
-     3216, 3216, 3667, 3667, 3216, 3216, 3216, 3669, 3670, 3671,
-     3671, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3673,
-     3216, 3216, 3216, 3674, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3675, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3676, 3216, 3216, 3678, 3678, 3216, 3216,
-     3216, 3216, 3679, 3680, 3680, 3216, 3216, 3216, 3680, 3216,
-     3216, 3655, 3655, 3216, 3216, 3656, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3659, 3659, 3659, 3216, 3216, 3216,
-     3216, 3660, 3661, 3216, 3216, 3216, 3216, 3216, 3665, 3666,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3670,
-     3671, 3671, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3674, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3675, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3676, 3678, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3680, 3680, 3680, 3216, 3216, 3216, 3655,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3659, 3659, 3659,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3665, 3666, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3670, 3671, 3671, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3674, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3675,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3676, 3216, 3216,
-     3678, 3216, 3216, 3216, 3680, 3680, 3680, 3655, 3216, 3216,
-     3216, 3216, 3216, 3216, 3659, 3216, 3216, 3659, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3665, 3666, 3216, 3216, 3216, 3216, 3670, 3671, 3671, 3671,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3675, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3676,
-     3216, 3216, 3216, 3678, 3680, 3680, 3680, 3655, 3659, 3216,
-     3216, 3216, 3659, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3666,
-     3216, 3216, 3216, 3216, 3670, 3671, 3671, 3671, 3681, 3682,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3675, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3678, 3680, 3680, 3216, 3216, 3655,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3666, 3216, 3216, 3216,
-     3216, 3670, 3671, 3683, 3684, 3681, 3682, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3678, 3680, 3680, 3216, 3216, 3216, 3655, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3670, 3683, 3671, 3685, 3684, 3686, 3671, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3678, 3680, 3680, 3216, 3216,
-     3216, 3216, 3655, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3670, 3685, 3216, 3686, 3671, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3670, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3670, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3670, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3670, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3670, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3670,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3670, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3670, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3670, 3670, 3216, 3216, 3216, 3216, 3216, 3216, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-
-     3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670, 3670,
-     3670, 3670, 3670, 3670, 3216,    0, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216
+     3218, 3218, 3219, 3219, 3219, 3219, 3220, 3220, 3221, 3221,
+     3222, 3222, 3223, 3223, 3223, 3223, 3224, 3224, 3218, 3218,
+     3225, 3225, 3226, 3226, 3226, 3226, 3218, 3218, 3226, 3226,
+     3226, 3226, 3218, 3218, 3226, 3226, 3218, 3218, 3226, 3226,
+     3226, 3226, 3227, 3227, 3228, 3228, 3218, 3218, 3228, 3228,
+     3228, 3228, 3229, 3229, 3223, 3223, 3230, 3230, 3231, 3231,
+     3232, 3232, 3233, 3233, 3234, 3234, 3235, 3235, 3235, 3235,
+     3218, 3218, 3235, 3235, 3235, 3235, 3218, 3218, 3235, 3235,
+     3235, 3235, 3218, 3218, 3235, 3235, 3218, 3218, 3235, 3235,
+     3235, 3235, 3218, 3218, 3235, 3235, 3218, 3218, 3235, 3235,
+
+     3235, 3235, 3236, 3236, 3237, 3237, 3218, 3218, 3237, 3237,
+     3237, 3237, 3238, 3238, 3239, 3239, 3218, 3218, 3239, 3239,
+     3239, 3239, 3240, 3240, 3241, 3241, 3242, 3242, 3243, 3243,
+     3244, 3244, 3245, 3245, 3218, 3218, 3245, 3245, 3245, 3245,
+     3246, 3246, 3247, 3247, 3217,  145, 3248, 3248, 3249, 3249,
+     3250, 3250, 3251, 3251, 3252, 3252, 3253, 3253, 3254, 3254,
+     3255, 3255, 3256, 3256, 3257, 3257, 3258, 3258, 3218, 3218,
+     3258, 3258, 3258, 3258, 3259, 3259, 3260, 3260, 3218, 3218,
+     3260, 3260, 3260, 3260, 3261, 3261, 3262, 3262, 3218, 3218,
+     3262, 3262, 3262, 3262, 3263, 3263, 3264, 3264, 3265, 3265,
+
+     3266, 3266, 3218, 3218, 3266, 3266, 3266, 3266, 3267, 3267,
+     3268, 3268, 3218, 3218, 3268, 3268, 3268, 3268, 3269, 3269,
+     3270, 3270, 3218, 3218, 3270, 3270, 3270, 3270, 3271, 3271,
+     3272, 3272, 3273, 3273, 3274, 3274, 3218, 3218, 3274, 3274,
+     3274, 3274, 3275, 3275, 3276, 3276, 3218, 3218, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3277,
+     3217, 3217, 3277, 3217, 3217, 3217,  286,  286,  288,  286,
+      289,  289, 3217, 3217, 3217, 3278, 3217, 3217, 3278, 3217,
+
+     3217,  290,  289, 3217, 3217, 3217, 3279, 3217, 3217, 3279,
+     3279, 3279, 3217, 3217, 3217, 3217, 3217, 3280, 3217, 3217,
+     3280, 3280, 3280, 3280, 3280, 3217, 3217, 3217, 3217, 3217,
+     3217, 3281, 3217, 3217, 3281, 3281, 3281, 3217, 3217, 3217,
+     3217, 3217, 3217, 3282, 3217, 3217, 3282, 3282, 3217, 3217,
+     3217,  351,  289,  289,  290,  355,  354,  354,  354,  354,
+      355,  361,  360,  359, 3217, 3217, 3217, 3283, 3217, 3217,
+     3283, 3283, 3283, 3283, 3217, 3217,  289,  289, 3217, 3217,
+     3217, 3284, 3217, 3217, 3284, 3284, 3284, 3217, 3217,  289,
+      289, 3217, 3217, 3217, 3285, 3217, 3217, 3285, 3285, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3286, 3217, 3217, 3286, 3286,
+     3217, 3217, 3217, 3217, 3217, 3217, 3287, 3217, 3217, 3287,
+     3287, 3287, 3287, 3287, 3217, 3217,  289,  427,  427, 3217,
+     3217, 3217, 3288, 3217, 3217, 3288, 3288, 3288, 3217, 3217,
+     3217, 3217, 3217, 3217, 3289, 3217, 3217, 3289, 3289, 3289,
+     3289, 3289, 3289, 3289, 3289, 3217, 3217, 3217, 3217, 3217,
+     3217, 3290, 3217, 3217, 3290, 3290, 3290, 3290, 3290, 3290,
+     3217, 3217, 3217, 3217, 3217, 3217, 3291, 3217, 3217, 3291,
+     3291, 3291, 3291, 3291, 3291, 3291, 3217, 3217, 3217, 3217,
+     3217, 3217, 3292, 3217, 3217, 3292, 3292, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3293, 3217, 3217, 3293, 3293, 3293, 3217,
+     3217, 3217, 3217, 3217, 3217, 3294, 3217, 3217, 3294, 3294,
+     3294, 3294, 3217, 3217,  427,  289, 3217, 3217, 3217, 3295,
+     3217, 3217, 3295, 3295, 3217, 3217,  289,  537,  537, 3217,
+     3217, 3217, 3296, 3217, 3217, 3296, 3296, 3296, 3217, 3217,
+      537,  537, 3217, 3217, 3217, 3297, 3217, 3217, 3297, 3297,
+     3217, 3217, 3217, 3217, 3217, 3217, 3298, 3217, 3217, 3298,
+     3298, 3217, 3217,  537,  537, 3217, 3217, 3217, 3299, 3217,
+     3217, 3299, 3299, 3299, 3217, 3217,  537,  537, 3217, 3217,
+     3217, 3300, 3217, 3217, 3300, 3300, 3300, 3300, 3300, 3217,
+
+     3217,  289,  602,  602, 3217, 3217, 3217, 3301, 3217, 3217,
+     3301, 3217, 3217, 3217, 3217, 3217, 3217, 3302, 3217, 3217,
+     3302, 3217, 3217,  602,  289, 3217, 3217, 3217, 3303, 3217,
+     3217, 3303, 3303, 3217, 3217, 3217, 3217, 3304, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3305, 3305, 3306, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3307,
+     3307, 3308, 3217, 3309, 3309, 3309, 3309, 3217, 3310, 3217,
+     3217, 3311, 3311, 3311, 3311, 3311, 3311, 3311, 3311, 3311,
+
+     3312, 3217, 3313, 3313, 3313, 3313, 3314, 3217, 3315, 3315,
+     3315, 3316, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3317, 3317, 3317, 3317, 3317, 3318, 3217, 3319, 3319, 3319,
+     3319, 3320, 3217, 3321, 3321, 3321, 3322, 3217, 3323, 3323,
+     3323, 3324, 3217, 3325, 3325, 3325, 3325, 3325, 3325, 3326,
+     3217, 3217, 3327, 3327, 3327, 3327, 3328, 3217, 3329, 3329,
+     3329, 3329, 3329, 3329, 3329, 3329, 3329, 3329, 3329, 3329,
+     3329, 3329, 3330, 3217, 3331, 3331, 3331, 3331, 3331, 3331,
+     3331, 3331, 3332, 3217, 3333, 3333, 3333, 3333, 3333, 3333,
+
+     3333, 3333, 3334, 3217, 3335, 3335, 3335, 3336, 3217, 3337,
+     3337, 3337, 3337, 3338, 3217, 3339, 3339, 3339, 3339, 3339,
+     3339, 3340, 3217, 3341, 3341, 3341, 3341, 3342, 3217, 3217,
+     3343, 3343, 3343, 3343, 3343, 3344, 3217, 3345, 3345, 3345,
+     3346, 3217, 3347, 3347, 3347, 3348, 3217, 3349, 3349, 3349,
+     3349, 3350, 3217, 3351, 3351, 3351, 3351, 3351, 3351, 3352,
+     3217, 3217, 3353, 3353, 3354, 3217, 3355, 3355, 3356, 3217,
+     3357, 3357, 3357, 3358, 3359, 3217, 3359, 3217, 3217, 3217,
+     3360, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3361, 3362,
+     3362, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3363,
+     3364, 3364, 3365, 3217, 3217, 3365, 3217, 3366, 3366, 3217,
+     3367, 3217, 3217, 3367, 3367, 3367, 3367, 3367, 3367, 3368,
+     3368, 3369, 3369, 3369, 3370, 3370, 3217, 3217, 3371, 3372,
+     3372, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3373, 3217, 3217, 3373, 3373, 3374,
+     3374, 3375, 3217, 3217, 3375, 3376, 3376, 3217, 3217, 3377,
+     3378, 3378, 3379, 3379, 3380, 3380, 3381, 3381, 3381, 3217,
+     3217, 3381, 3381, 3382, 3382, 3217, 3217, 3383, 3217, 3217,
+
+     3217, 3217, 3384, 3384, 3385, 3385, 3217, 3217, 3385, 3217,
+     3217, 3385, 3385, 3385, 3385, 3385, 3385, 3385, 3385, 3386,
+     3386, 3217, 3217, 3217, 3217, 3387, 3387, 3387, 3387, 3387,
+     3388, 3388, 3389, 3389, 3389, 3217, 3217, 3389, 3389, 3389,
+     3390, 3390, 3391, 3217, 3217, 3392, 3392, 3393, 3217, 3217,
+     3393, 3394, 3394, 3395, 3217, 3217, 3395, 3395, 3395, 3396,
+     3396, 3397, 3397, 3397, 3398, 3398, 3217, 3399, 3399, 3399,
+     3399, 3400, 3400, 3401, 3217, 3217, 3402, 3402, 3403, 3403,
+     3404, 3404, 3405, 3405, 3405, 3406, 3406, 3407, 3407, 3407,
+     3407, 3407, 3408, 3408, 3217, 3409, 3410, 3410, 3217, 3217,
+
+     3411, 3411, 3217, 3217, 3412, 3413, 3413, 3414, 3217, 3217,
+     3414, 3217, 3217, 3415, 3217, 3217, 3217, 3217, 3217, 3217,
+     3416, 3217, 3417, 3217, 3417, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3418, 3217, 3419, 3217, 3419, 3420,
+     3217, 3217, 3217, 3420, 3217, 3217, 3421, 3217, 3421, 3422,
+     3217, 3217, 3217, 3217, 3217, 3422, 3217, 3217, 3422, 3422,
+     3422, 3217, 3423, 3217, 3423, 3424, 3424, 3424, 3217, 3425,
+     3217, 3425, 3217, 3217, 3217, 3426, 3217, 3427, 3217, 3427,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3428, 3217, 3217, 3217, 3428, 3428, 3217, 3429,
+     3217, 3429, 3430, 3217, 3217, 3217, 3430, 3217, 3431, 3217,
+     3431, 3217, 3217, 3217, 3432, 3217, 3433, 3217, 3433, 3434,
+     3434, 3217, 3435, 3217, 3435, 3436, 3436, 3436, 3217, 3217,
+     3217, 3436, 3436, 3217, 3437, 3217, 3437, 3217, 3217, 3438,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3439, 3217, 3439,
+     3440, 3440, 3440, 3440, 3217, 3217, 3217, 3440, 3217, 3217,
+     3217, 3217, 3217, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+     3217, 3441, 3217, 3441, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3442, 3442, 3442, 3442, 3217, 3443, 3217, 3443,
+     3444, 3444, 3444, 3444, 3217, 3217, 3217, 3217, 3217, 3444,
+     3444, 3217, 3445, 3217, 3445, 3446, 3217, 3217, 3217, 3217,
+     3447, 3217, 3447, 3448, 3217, 3217, 3217, 3448, 3217, 3449,
+     3217, 3449, 3450, 3217, 3217, 3217, 3450, 3450, 3450, 3217,
+     3451, 3217, 3451, 3217, 3217, 3217, 3217, 3452, 3217, 3453,
+     3217, 3453, 3217, 3217, 3217, 3454, 3454, 3217, 3217, 3454,
+     3217, 3455, 3217, 3455, 3456, 3217, 3217, 3217, 3217, 3457,
+     3217, 3457, 3217, 3217, 3217, 3217, 3217, 3458, 3217, 3458,
+     3217, 3217, 3459, 3459, 3217, 3217, 3217, 3460, 3217, 3460,
+
+     3461, 3461, 3461, 3461, 3461, 3217, 3462, 3217, 3462, 3217,
+     3463, 3217, 3464, 3217, 3464, 3217, 3217, 3217, 3217, 3465,
+     3217, 3465, 3217, 3217, 3217, 3466, 3217, 3467, 3217, 3467,
+     3468, 3469, 3217, 3217, 3217, 3217, 3217, 3470, 3471, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3472,
+     3217, 3217, 3473, 3217, 3474, 3475, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3475, 3217, 3217, 3475, 3476, 3477,
+     3217, 3217, 3477, 3478, 3479, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3480,
+     3480, 3217, 3217, 3481, 3482, 3482, 3483, 3217, 3217, 3484,
+     3217, 3217, 3485, 3486, 3487, 3487, 3217, 3217, 3487, 3487,
+     3488, 3217, 3217, 3217, 3217, 3489, 3490, 3490, 3490, 3490,
+     3217, 3217, 3217, 3217, 3217, 3490, 3490, 3490, 3490, 3490,
+     3490, 3490, 3491, 3217, 3217, 3217, 3492, 3492, 3492, 3492,
+     3493, 3494, 3494, 3494, 3494, 3217, 3217, 3217, 3494, 3494,
+     3495, 3496, 3497, 3498, 3498, 3499, 3500, 3500, 3500, 3500,
+     3501, 3217, 3217, 3217, 3217, 3217, 3217, 3502, 3503, 3217,
+     3217, 3217, 3217, 3504, 3504, 3217, 3217, 3217, 3504, 3505,
+
+     3506, 3507, 3217, 3217, 3217, 3217, 3217, 3217, 3508, 3217,
+     3217, 3217, 3509, 3509, 3217, 3217, 3217, 3510, 3511, 3217,
+     3217, 3511, 3511, 3511, 3512, 3217, 3513, 3514, 3515, 3516,
+     3517, 3518, 3519, 3519, 3217, 3519, 3217, 3217, 3217, 3520,
+     3521, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3522, 3217, 3217, 3217, 3523, 3217,
+     3524, 3525, 3217, 3217, 3217, 3525, 3217, 3217, 3217, 3525,
+     3526, 3527, 3217, 3217, 3217, 3217, 3217, 3528, 3529, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3530, 3217, 3217, 3217, 3217, 3217, 3531, 3532,
+     3532, 3533, 3217, 3217, 3217, 3534, 3217, 3217, 3217, 3535,
+     3536, 3537, 3537, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3537, 3538, 3217, 3217, 3217, 3217, 3217, 3539, 3540, 3217,
+     3217, 3540, 3540, 3217, 3217, 3217, 3217, 3217, 3540, 3540,
+     3540, 3540, 3540, 3540, 3541, 3217, 3217, 3542, 3542, 3542,
+     3543, 3544, 3217, 3217, 3544, 3544, 3217, 3217, 3544, 3545,
+     3546, 3547, 3548, 3548, 3549, 3550, 3550, 3550, 3217, 3217,
+     3550, 3551, 3552, 3553, 3217, 3554, 3554, 3554, 3555, 3556,
+
+     3557, 3558, 3559, 3559, 3560, 3561, 3217, 3217, 3217, 3561,
+     3561, 3561, 3562, 3217, 3217, 3217, 3563, 3564, 3217, 3217,
+     3565, 3566, 3567, 3567, 3217, 3217, 3568, 3569, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3570, 3571, 3217, 3572,
+     3573, 3573, 3573, 3574, 3575, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3576, 3577, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3578, 3217, 3217,
+     3217, 3579, 3580, 3217, 3217, 3581, 3582, 3217, 3217, 3583,
+
+     3584, 3584, 3217, 3217, 3217, 3217, 3217, 3217, 3584, 3217,
+     3217, 3217, 3217, 3585, 3586, 3217, 3217, 3217, 3217, 3217,
+     3586, 3217, 3217, 3217, 3217, 3217, 3586, 3586, 3586, 3586,
+     3217, 3217, 3587, 3217, 3217, 3217, 3217, 3217, 3588, 3217,
+     3217, 3589, 3590, 3217, 3217, 3217, 3217, 3217, 3590, 3217,
+     3217, 3217, 3590, 3217, 3217, 3591, 3592, 3593, 3593, 3594,
+     3595, 3595, 3595, 3217, 3217, 3217, 3595, 3217, 3217, 3596,
+     3597, 3217, 3217, 3217, 3217, 3217, 3598, 3599, 3600, 3601,
+     3602, 3217, 3217, 3217, 3217, 3603, 3604, 3604, 3604, 3604,
+     3605, 3217, 3217, 3217, 3217, 3606, 3607, 3217, 3217, 3217,
+
+     3217, 3217, 3608, 3609, 3609, 3217, 3217, 3217, 3610, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3611, 3612, 3217, 3217, 3217, 3613,
+     3217, 3217, 3613, 3614, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3615, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3616, 3217,
+     3217, 3217, 3217, 3217, 3617, 3217, 3217, 3217, 3217, 3217,
+     3618, 3619, 3619, 3217, 3217, 3619, 3217, 3620, 3621, 3217,
+     3217, 3217, 3621, 3217, 3217, 3217, 3217, 3217, 3621, 3621,
+
+     3621, 3217, 3217, 3217, 3622, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3623, 3624, 3217, 3217, 3217, 3624, 3624,
+     3625, 3626, 3627, 3217, 3217, 3628, 3629, 3217, 3217, 3629,
+     3629, 3217, 3217, 3629, 3630, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3631, 3632, 3633, 3634, 3635, 3217,
+     3217, 3217, 3217, 3217, 3217, 3636, 3637, 3637, 3637, 3637,
+     3638, 3217, 3639, 3640, 3641, 3642, 3642, 3217, 3217, 3217,
+     3217, 3643, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3644, 3645, 3217, 3646, 3217, 3217, 3217,
+
+     3646, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3647, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3648, 3217, 3217, 3217, 3649, 3650, 3651, 3651, 3217, 3217,
+     3217, 3217, 3651, 3217, 3652, 3653, 3653, 3217, 3217, 3217,
+     3653, 3653, 3653, 3654, 3217, 3217, 3217, 3655, 3656, 3656,
+     3656, 3657, 3217, 3217, 3658, 3217, 3217, 3217, 3659, 3660,
+     3217, 3217, 3217, 3660, 3660, 3217, 3217, 3217, 3217, 3660,
+     3661, 3217, 3662, 3663, 3664, 3665, 3666, 3667, 3217, 3217,
+     3668, 3668, 3668, 3669, 3217, 3670, 3217, 3217, 3671, 3672,
+
+     3672, 3217, 3673, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3674, 3217, 3217, 3675,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3676, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3677, 3217,
+     3217, 3678, 3679, 3679, 3217, 3217, 3217, 3217, 3679, 3217,
+     3680, 3681, 3681, 3217, 3217, 3681, 3681, 3217, 3217, 3217,
+     3217, 3656, 3656, 3656, 3657, 3217, 3217, 3659, 3217, 3217,
+     3660, 3660, 3660, 3217, 3217, 3217, 3217, 3660, 3661, 3217,
+     3662, 3217, 3217, 3217, 3217, 3665, 3666, 3667, 3217, 3217,
+
+     3217, 3217, 3217, 3668, 3668, 3217, 3217, 3217, 3670, 3671,
+     3672, 3672, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3674, 3217, 3217, 3217, 3675, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3676, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3677, 3217, 3217, 3679, 3679, 3217,
+     3217, 3217, 3217, 3680, 3681, 3681, 3217, 3217, 3217, 3681,
+     3217, 3217, 3656, 3656, 3217, 3217, 3657, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3660, 3660, 3660, 3217, 3217,
+     3217, 3217, 3661, 3662, 3217, 3217, 3217, 3217, 3217, 3666,
+
+     3667, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3671, 3672, 3672, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3675, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3676, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3677, 3679, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3681, 3681, 3681, 3217, 3217, 3217,
+     3656, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3660, 3660,
+     3660, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3666, 3667, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3671, 3672, 3672, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3675, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3676, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3677, 3217,
+     3217, 3679, 3217, 3217, 3217, 3681, 3681, 3681, 3656, 3217,
+     3217, 3217, 3217, 3217, 3217, 3660, 3217, 3217, 3660, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3666, 3667, 3217, 3217, 3217, 3217, 3671, 3672, 3672,
+     3672, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3676, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3677, 3217, 3217, 3217, 3679, 3681, 3681, 3681, 3656, 3660,
+     3217, 3217, 3217, 3660, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3667, 3217, 3217, 3217, 3217, 3671, 3672, 3672, 3672, 3682,
+     3683, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3676, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3679, 3681, 3681, 3217, 3217,
+     3656, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3667, 3217, 3217,
+     3217, 3217, 3671, 3672, 3684, 3685, 3682, 3683, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3679, 3681, 3681, 3217, 3217, 3217, 3656, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3671, 3684, 3672, 3686, 3685, 3687, 3672,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3679, 3681, 3681, 3217,
+     3217, 3217, 3217, 3656, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3671, 3686, 3217, 3687, 3672, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3671, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3671, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3671, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3671, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3671, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3671, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3671, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3671, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3671, 3671, 3217, 3217, 3217, 3217, 3217, 3217, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+
+     3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3671, 3671, 3671, 3671, 3671, 3217,    0, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217
     } ;
 
-static yyconst flex_int16_t yy_nxt[11810] =
+static yyconst flex_int16_t yy_nxt[11827] =
     {   0,
-     3216,  252,  253,  252,  252,  253,  252,  252,  253,  252,
+     3217,  252,  253,  252,  252,  253,  252,  252,  253,  252,
       252,  253,  252,  257,  253,  257,  263,  254,  260,  263,
-      254,  260, 3216,  255, 3216,  261,  255, 3216,  261,  258,
+      254,  260, 3217,  255, 3217,  261,  255, 3217,  261,  258,
       257,  253,  257,  638,  264,  266,  267,  264,  266,  267,
       268,  269,  682,  268,  269,  638,  258,  273,  274,  639,
       270,  266,  267,  270,  271,  641,  268,  266,  267,  671,
-      271,  640,  268,  273,  274, 1706,  270,  253,  253,  253,
-      819,  640,  270,  253,  253,  253,  285,  253,  285,  285,
-      253,  285,  820,  276,  285,  253,  285,  659, 1707,  276,
-      713,  275,  286, 1311,  674,  286,  637,  637,  637, 1312,
+      271,  640,  268,  273,  274, 3217,  270,  253,  253,  253,
+      820,  640,  270,  253,  253,  253,  285,  253,  285,  285,
+      253,  285,  821,  276,  285,  253,  285,  659, 1702,  276,
+      712,  275,  286, 1312,  674,  286,  637,  637,  637, 1313,
 
       287,  637,  637,  637,  637,  637,  637,  275,  277,  278,
       253,  278,  277,  277,  277,  277,  277,  277,  277,  279,
       277,  277,  277,  669,  277,  281,  277,  282,  277,  285,
       253,  285,  253,  253,  253,  253,  253,  253,  670,  285,
       253,  285,  285,  253,  285,  287,  675,  664,  288,  641,
-      674,  288,  893,  277,  277,  286,  641,  641,  286,  285,
+      674,  288,  894,  277,  277,  286,  641,  641,  286,  285,
       253,  285,  637,  637,  637,  640,  637,  637,  637,  637,
-      637,  637,  640,  640,  701,  289,  894,  283,  277,  278,
+      637,  637,  640,  640, 3217,  289,  895,  283,  277,  278,
       253,  278,  277,  277,  277,  277,  277,  277,  277,  279,
-      277,  277,  277, 1708,  277,  281,  277,  282,  277,  285,
+      277,  277,  277, 1707,  277,  281,  277,  282,  277,  285,
 
       253,  285,  253,  253,  253,  253,  253,  253,  646,  285,
-      253,  285,  285,  253,  285,  289,  652,  713,  290,  775,
-      953,  290,  776,  277,  277,  287,  702,  714,  287,  253,
+      253,  285,  285,  253,  285,  289,  652,  712,  290,  776,
+      953,  290,  777,  277,  277,  287,  720,  713,  287,  253,
       253,  253,  253,  253,  253,  285,  253,  285,  285,  253,
-      285,  285,  253,  285,  954,  291,  825,  283,  291,  641,
-      647,  289,  770,  826,  289,  723,  648,  292,  285,  253,
+      285,  285,  253,  285,  954,  291,  826,  283,  291,  641,
+      647,  289,  771,  827,  289,  724,  648,  292,  285,  253,
       285,  649,  637,  637,  637,  640,  650,  637,  637,  637,
-      637,  637,  637,  771,  292,  293,  294,  253,  294,  293,
+      637,  637,  637,  772,  292,  293,  294,  253,  294,  293,
       293,  293,  293,  293,  293,  293,  295,  293,  293,  293,
       699,  293,  297,  293,  298,  293,  301,  253,  301,  301,
 
       253,  301,  253,  253,  253,  700,  253,  253,  253,  301,
-      253,  301,  302,  788,  881,  302,  789,  882,  290,  695,
-      293,  293,  290,  696, 3216,  302,  656,  697,  299,  293,
+      253,  301,  302,  789,  882,  302,  790,  883,  290,  695,
+      293,  293,  290,  696,  736,  302,  656,  697,  299,  293,
       294,  253,  294,  293,  293,  293,  293,  293,  293,  293,
       295,  293,  293,  293,  641,  293,  297,  293,  298,  293,
-      301,  253,  301,  301,  253,  301,  301,  253,  301,  777,
-      640,  868,  266,  267,  833,  676,  302,  268, 3216,  303,
-     1709,  834,  303,  778,  293,  293,  702,  313,  677,  701,
-      670,  875,  299,  304,  305,  253,  305,  304,  304,  304,
+      301,  253,  301,  301,  253,  301,  301,  253,  301,  778,
+      640,  869,  266,  267,  834,  676,  302,  268, 3217,  303,
+     1708,  835,  303,  779,  293,  293,  720,  313,  677,  736,
+      670,  876,  299,  304,  305,  253,  305,  304,  304,  304,
       304,  304,  304,  304,  306,  304,  304,  304,  658,  304,
 
-      308,  304,  309,  304, 1710,  641,  314,  669,  327,  253,
-      327,  327,  253,  327,  253,  253,  253,  926,  266,  267,
-      678,  640,  670,  268,  328,  688,  906,  328,  304,  304,
-      329,  674,  689,  313,  901, 1711,  310,  735,  902,  311,
-      907,  640,  637,  637,  637, 1712,  312,  304,  305,  253,
+      308,  304,  309,  304, 1709,  641,  314,  669,  327,  253,
+      327,  327,  253,  327,  339,  253,  339,  927,  266,  267,
+      678,  640,  670,  268,  328,  688,  907,  328,  304,  304,
+      340,  674,  689,  313,  902, 1710,  310,  742,  903,  311,
+      908,  640,  637,  637,  637, 1711,  312,  304,  305,  253,
       305,  304,  304,  304,  304,  304,  304,  304,  306,  304,
-      304,  304,  314,  304,  308,  304,  309,  304,  253,  253,
-      253,  327,  253,  327,  327,  253,  327,  911,  327,  253,
-      327,  327,  253,  327,  329,  641,  641,  328, 3216,  702,
-      328,  907,  304,  304,  330, 1719,  987,  330,  671,  988,
+      304,  304,  314,  304,  308,  304,  309,  304,  339,  253,
+      339,  350,  253,  350,  350,  253,  350,  822,  350,  253,
+      350,  350,  253,  350,  340,  641,  641,  351,  641,  720,
+      351, 1712,  304,  304,  352,  701,  988,  352, 1713,  989,
 
-      310,  640,  640,  311,  637,  637,  637,  637,  637,  637,
+      310,  640,  640,  311,  640,  637,  637,  637,  742, 1720,
       312,  315,  316,  253,  316,  315,  315,  315,  315,  315,
-      315,  315,  317,  315,  315,  315,  659,  315,  319,  315,
-      320,  315,  341,  253,  341,  341,  253,  341,  352,  253,
-      352,  911,  352,  253,  352,  352,  253,  352,  342, 1720,
-      641,  342,  641,  641,  353,  957,  315,  315,  353,  708,
-      658,  354,  637,  637,  637,  321,  640,  322,  640,  640,
-      821,  323,  637,  637,  637,  674,  324,  325,  315,  316,
+      315,  315,  317,  315,  315,  315,  664,  315,  319,  315,
+      320,  315,  253,  253,  253,  253,  253,  253,  350,  253,
+      350, 1721,  350,  253,  350,  350,  253,  350,  353, 1730,
+      641,  353,  641,  641,  351,  658,  315,  315,  351,  707,
+      674,  354,  637,  637,  637,  321,  640,  322,  640,  640,
+      674,  323,  637,  637,  637, 1732,  324,  325,  315,  316,
       253,  316,  315,  315,  315,  315,  315,  315,  315,  317,
-      315,  315,  315,  671,  315,  319,  315,  320,  315,  352,
-
-      253,  352,  253,  253,  253,  253,  253,  253,  735,  352,
-      253,  352,  352,  253,  352,  354,  722, 1729,  355,  664,
-      641,  355,  726,  315,  315,  356,  717,  716,  356,  637,
-      637,  637,  321,  719,  322,  674,  640,  727,  323,  637,
-      637,  637,  741,  324,  325,  331,  332,  253,  332,  331,
-      331,  331,  331,  331,  331,  331,  333,  331,  331,  331,
-      674,  331,  335,  331,  336,  331,  352,  253,  352,  352,
-      253,  352,  253,  253,  253,  911,  253,  253,  253,  352,
-      253,  352,  357, 1453, 1731,  357,  875,  893,  358,  962,
-      331,  331,  358, 1732,  702,  354, 1454,  337,  637,  637,
-
-      637,  876,  741,  338,  637,  637,  637,  637,  637,  637,
-      821,  960,  339,  331,  332,  253,  332,  331,  331,  331,
-      331,  331,  331,  331,  333,  331,  331,  331,  953,  331,
-      335,  331,  336,  331,  352,  253,  352,  253,  253,  253,
-      253,  253,  253, 1742,  352,  253,  352,  352,  253,  352,
-      354, 1743,  894,  359,  674,  911,  359,  641,  331,  331,
-      357, 1748,  674,  357,  746,  337,  637,  637,  637,  963,
-     1751,  338,  835,  640,  637,  637,  637,  637,  637,  637,
-      339,  343,  344,  253,  344,  343,  343,  343,  343,  343,
-      343,  343,  345,  343,  343,  343, 1752,  343,  347,  343,
-
-      348,  343,  352,  253,  352,  352,  253,  352,  253,  253,
-      253, 1758,  253,  253,  253,  352,  253,  352,  360,  641,
-      663,  360,  641, 1759,  361,  868,  343,  343,  361,  751,
-     1760,  362,  637,  637,  637,  640,  759,  349,  640,  637,
-      637,  637,  637,  637,  637, 1761,  350,  343,  344,  253,
-      344,  343,  343,  343,  343,  343,  343,  343,  345,  343,
-      343,  343,  845,  343,  347,  343,  348,  343,  352,  253,
-      352,  253,  253,  253,  253,  253,  253,  674,  352,  253,
-      352,  352,  253,  352,  362,  760,  641,  363,  702,  953,
-      363, 1762,  343,  343,  360,  641, 1763,  360,  352,  253,
-
-      352, 1771,  640,  349,  352,  253,  352,  637,  637,  637,
-      663,  640,  350,  960,  364,  637,  637,  637,  713, 1774,
+      315,  315,  315,  671,  315,  319,  315,  320,  315,  350,
+
+      253,  350,  253,  253,  253,  253,  253,  253,  822,  350,
+      253,  350,  350,  253,  350,  354,  723, 1733,  355, 1743,
+      641,  355,  727,  315,  315,  356,  716,  715,  356,  637,
+      637,  637,  321,  719,  322,  674,  640,  728,  323,  637,
+      637,  637, 1744,  324,  325,  329,  330,  253,  330,  329,
+      329,  329,  329,  329,  329,  329,  331,  329,  329,  329,
+      674,  329,  333,  329,  334,  329,  350,  253,  350,  350,
+      253,  350,  253,  253,  253,  912,  253,  253,  253,  350,
+      253,  350,  357,  996, 1749,  357,  641,  997,  358,  908,
+      329,  329,  358,  747,  641,  354,  876,  335,  637,  637,
+
+      637,  752,  640,  336,  637,  637,  637,  637,  637,  637,
+      640,  877,  337,  329,  330,  253,  330,  329,  329,  329,
+      329,  329,  329,  329,  331,  329,  329,  329,  894,  329,
+      333,  329,  334,  329,  350,  253,  350,  253,  253,  253,
+      253,  253,  253,  912,  350,  253,  350,  350,  253,  350,
+      354, 1454,  961,  359,  641,  953,  359,  958,  329,  329,
+      357, 1752,  641,  357, 1455,  335,  637,  637,  637, 1753,
+      640,  336,  637,  637,  637,  637,  637,  637,  640,  895,
+      337,  341,  342,  253,  342,  341,  341,  341,  341,  341,
+      341,  341,  343,  341,  341,  341,  836,  341,  345,  341,
+
+      346,  341,  350,  253,  350,  350,  253,  350,  253,  253,
+      253, 1759,  253,  253,  253,  350,  253,  350,  360,  641,
+     1760,  360, 1761, 1762,  361,  869,  341,  341,  361,  641,
+     1763,  362,  637,  637,  637,  640,  760,  347,  637,  637,
+      637,  637,  637,  637,  663,  640,  348,  341,  342,  253,
+      342,  341,  341,  341,  341,  341,  341,  341,  343,  341,
+      341,  341,  846,  341,  345,  341,  346,  341,  350,  253,
+      350,  253,  253,  253,  253,  253,  253,  674,  350,  253,
+      350,  350,  253,  350,  362,  761, 1764,  363,  720,  953,
+      363, 1772,  341,  341,  360,  641, 1775,  360,  350,  253,
+
+      350, 1776,  767,  347,  350,  253,  350,  637,  637,  637,
+      663,  640,  348,  961,  364,  637,  637,  637,  712, 1779,
       364,  365,  366,  253,  366,  365,  365,  365,  365,  365,
-      365,  365,  367,  365,  365,  365,  893,  365,  369,  365,
+      365,  365,  367,  365,  365,  365, 1781,  365,  369,  365,
       370,  365,  376,  253,  376,  376,  253,  376,  253,  253,
-      253, 1775,  253,  253,  253,  851,  728,  641,  377, 1108,
-      961,  377,  641,  779,  329, 1778,  365,  365,  329,  766,
-      641,  371,  718,  640,  827,  780,  781,  372,  640, 1631,
-     1780,  373,  637,  637,  637, 1782,  640,  374,  365,  366,
+      253, 1109,  253,  253,  253, 1431,  729,  780,  377,  912,
+      641,  377,  894, 1783,  353, 3217,  365,  365,  353,  781,
+      782,  371,  718,  963,  828,  671,  640,  372,  637,  637,
+      637,  373,  637,  637,  637, 1784,  962,  374,  365,  366,
       253,  366,  365,  365,  365,  365,  365,  365,  365,  367,
 
-      365,  365,  365,  663,  365,  369,  365,  370,  365,  376,
-      253,  376,  376,  253,  376,  376,  253,  376,  895,  376,
-      253,  376,  828,  641, 1783,  377,  674, 1785,  377,  896,
-      782,  378,  897,  365,  365,  378,  641,  641,  371,  640,
-      637,  637,  637,  792,  372,  637,  637,  637,  373,  637,
+      365,  365,  365,  659,  365,  369,  365,  370,  365,  376,
+      253,  376,  376,  253,  376,  376,  253,  376,  896,  376,
+      253,  376,  829,  641, 1786,  377,  674, 1787,  377,  897,
+      783,  378,  898,  365,  365,  378,  641,  641,  371,  640,
+      637,  637,  637,  793,  372,  637,  637,  637,  373,  637,
       637,  637,  640,  640,  374,  379,  380,  253,  380,  379,
       379,  379,  379,  379,  379,  379,  381,  379,  379,  379,
-     1786,  379,  383,  379,  384,  379,  389,  253,  389,  389,
-      253,  389,  253,  253,  253, 1787,  253,  253,  253,  637,
-      637,  637,  390,  641,  641,  390,  641, 1792,  329, 1795,
+     1788,  379,  383,  379,  384,  379,  389,  253,  389,  389,
+      253,  389,  253,  253,  253,  912,  253,  253,  253,  637,
+      637,  637,  390,  641,  641,  390,  641, 1793,  353,  964,
 
-      379,  379,  329,  802, 1796,  385,  637,  637,  637,  640,
+      379,  379,  353,  803, 1796,  385,  637,  637,  637,  640,
       640,  386,  640,  637,  637,  637,  637,  637,  637,  637,
       637,  637,  387,  379,  380,  253,  380,  379,  379,  379,
       379,  379,  379,  379,  381,  379,  379,  379, 1797,  379,
       383,  379,  384,  379,  389,  253,  389,  389,  253,  389,
-      389,  253,  389,  995,  389,  253,  389,  996,  641, 1465,
-      390, 1799,  641,  390,  641,  807,  391, 1802,  379,  379,
-      391,  813, 1454,  385,  640,  637,  637,  637,  640,  386,
+      389,  253,  389, 1798,  389,  253,  389, 1800,  641, 1466,
+      390, 1803,  641,  390,  641,  808,  391, 1804,  379,  379,
+      391,  814, 1455,  385,  640,  637,  637,  637,  640,  386,
       640,  637,  637,  637,  637,  637,  637,  637,  637,  637,
       387,  392,  393,  253,  393,  392,  392,  392,  392,  392,
 
-      392,  392,  394,  392,  392,  392, 1803,  392,  396,  392,
+      392,  392,  394,  392,  392,  392, 1806,  392,  396,  392,
       397,  392,  401,  253,  401,  401,  253,  401,  412,  253,
-      412, 1805,  412,  253,  412,  426,  253,  426,  402,  641,
-      641,  402, 1809, 1810,  413,  641,  392,  392,  413, 1811,
-     1813,  427,  637,  637,  637,  640,  640,  398,  637,  637,
+      412, 1810,  412,  253,  412,  426,  253,  426,  402,  641,
+      641,  402, 1811, 1812,  413,  641,  392,  392,  413, 1814,
+     1635,  427,  637,  637,  637,  640,  640,  398,  637,  637,
       637,  640,  399,  392,  393,  253,  393,  392,  392,  392,
-      392,  392,  392,  392,  394,  392,  392,  392, 1634,  392,
+      392,  392,  392,  392,  394,  392,  392,  392, 1825,  392,
       396,  392,  397,  392,  426,  253,  426,  253,  253,  253,
-      253,  253,  253, 1824,  426,  253,  426,  426,  253,  426,
-      427,  641,  641,  428, 1825, 1826,  428,  641,  392,  392,
+      253,  253,  253, 1826,  426,  253,  426,  426,  253,  426,
+      427,  641,  641,  428, 1827, 1829,  428,  852,  392,  392,
 
-      427, 1828, 1829,  427,  637,  637,  637,  640,  640,  398,
-      637,  637,  637,  640,  399,  403,  404,  253,  404,  403,
+      427, 1830, 1831,  427,  637,  637,  637,  640,  640,  398,
+      637,  637,  637, 1832,  399,  403,  404,  253,  404,  403,
       403,  403,  403,  403,  403,  403,  405,  403,  403,  403,
       953,  403,  407,  403,  408,  403,  426,  253,  426,  426,
-      253,  426,  440,  253,  440, 1830,  440,  253,  440,  457,
-      253,  457,  429, 1108,  961,  429,  641, 1430,  441, 1831,
-      403,  403,  441,  840,  641,  458,  637,  637,  637,  637,
+      253,  426,  440,  253,  440,  663,  440,  253,  440,  457,
+      253,  457,  429, 1833,  962,  429,  641, 1834,  441, 1835,
+      403,  403,  441,  841,  641,  458,  637,  637,  637,  637,
       637,  637,  640,  637,  637,  637,  409,  637,  637,  637,
-      640, 1832,  410,  403,  404,  253,  404,  403,  403,  403,
-      403,  403,  403,  403,  405,  403,  403,  403, 1833,  403,
+      640, 1836,  410,  403,  404,  253,  404,  403,  403,  403,
+      403,  403,  403,  403,  405,  403,  403,  403, 1837,  403,
 
       407,  403,  408,  403,  457,  253,  457,  472,  253,  472,
-      472,  253,  472, 1834,  488,  253,  488,  488,  253,  488,
-      458, 1835, 1836,  473, 1108, 1837,  473,  641,  403,  403,
-      489, 1839, 1840,  489,  637,  637,  637,  637,  637,  637,
-      637,  637,  637,  640,  409,  637,  637,  637,  859, 1821,
+      472,  253,  472, 1838,  488,  253,  488,  488,  253,  488,
+      458, 1840, 1841,  473, 1109, 1842,  473,  641,  403,  403,
+      489, 1843, 1846,  489,  637,  637,  637,  637,  637,  637,
+      637,  637,  637,  640,  409,  637,  637,  637,  860, 1822,
       410,  414,  415,  253,  415,  414,  414,  414,  414,  414,
-      414,  414,  416,  414,  414,  414, 1841,  414,  418,  414,
+      414,  414,  416,  414,  414,  414, 1849,  414,  418,  414,
       419,  414,  499,  253,  499,  499,  253,  499,  511,  253,
-      511,  895,  511,  253,  511,  860,  641, 1842,  500, 1845,
-     1108,  500,  896,  864,  512,  910,  414,  414,  512,  420,
+      511,  896,  511,  253,  511,  861,  641, 1850,  500, 1851,
+      641,  500,  897,  865,  512,  911,  414,  414,  512,  420,
 
-      702,  421,  640,  637,  637,  637, 1110,  422,  637,  637,
-      637,  637,  637,  637,  423, 1848, 1849,  424,  414,  415,
+      720,  421,  640,  637,  637,  637,  640,  422,  637,  637,
+      637,  637,  637,  637,  423, 1852, 1853,  424,  414,  415,
       253,  415,  414,  414,  414,  414,  414,  414,  414,  416,
-      414,  414,  414, 1850,  414,  418,  414,  419,  414,  524,
-      253,  524,  524,  253,  524,  253,  253,  253,  913,  253,
-      253,  253,  637,  637,  637,  525, 1851, 1852,  525,  914,
-      641,  329,  897,  414,  414,  329,  420,  873,  421,  637,
-      637,  637, 1853, 1857,  422, 1858,  640, 1860,  879,  879,
-      879,  423, 1861, 1862,  424,  430,  431,  253,  431,  430,
+      414,  414,  414, 1854,  414,  418,  414,  419,  414,  524,
+      253,  524,  524,  253,  524,  253,  253,  253,  914,  253,
+      253,  253,  637,  637,  637,  525, 1109, 1109,  525,  915,
+      641,  353,  898,  414,  414,  353,  420,  874,  421,  637,
+      637,  637, 1111, 1858,  422, 1859,  640, 1632,  880,  880,
+      880,  423, 1861, 1862,  424,  430,  431,  253,  431,  430,
       430,  430,  430,  430,  430,  430,  432,  430,  430,  430,
 
-     1864,  430,  434,  430,  435,  430,  524,  253,  524,  524,
-      253,  524,  524,  253,  524, 1877,  524,  253,  524,  536,
-      253,  536,  525, 1878, 1879,  525,  903,  916,  526, 1880,
-      430,  430,  526,  904,  904,  537,  436,  880,  913,  905,
-      917,  437,  879,  879,  879, 1881, 1112, 1884, 1885,  914,
-     1886, 1887,  910,  438,  430,  431,  253,  431,  430,  430,
-      430,  430,  430,  430,  430,  432,  430,  430,  430, 1892,
+     1863,  430,  434,  430,  435,  430,  524,  253,  524,  524,
+      253,  524,  524,  253,  524, 1865,  524,  253,  524,  536,
+      253,  536,  525, 1878, 1879,  525,  904,  917,  526, 1880,
+      430,  430,  526,  905,  905,  537,  436,  881,  914,  906,
+      918,  437,  880,  880,  880, 1881, 1113, 1882, 1885,  915,
+     1886, 1887,  911,  438,  430,  431,  253,  431,  430,  430,
+      430,  430,  430,  430,  430,  432,  430,  430,  430, 1888,
       430,  434,  430,  435,  430,  536,  253,  536,  253,  253,
-      253,  253,  253,  253, 1900,  536,  253,  536,  536,  253,
-      536,  537, 1901, 1908,  538,  916,  903,  538, 1465,  430,
+      253,  253,  253,  253, 1893,  536,  253,  536,  536,  253,
+      536,  537, 1901, 1902,  538,  917,  904,  538, 1466,  430,
 
-      430,  537,  904,  904,  537,  436,  916,  895,  905,  917,
-      437, 1489, 1912,  904, 1125, 1125, 1125, 1914,  914,  941,
-     1920,  910,  438,  442,  443,  253,  443,  442,  442,  442,
+      430,  537,  905,  905,  537,  436,  904,  917,  906,  918,
+      437, 1503, 1909,  905,  905, 1126, 1126, 1126, 1913,  957,
+      957, 1915,  438,  442,  443,  253,  443,  442,  442,  442,
       442,  442,  442,  442,  444,  442,  442,  442,  445,  442,
       446,  442,  447,  442,  445,  445,  445,  445,  445,  445,
       445,  445,  445,  445,  445,  445,  445,  445,  445,  445,
@@ -1833,1109 +1833,1111 @@ static yyconst flex_int16_t yy_nxt[11810] =
       445,  445,  445,  445,  445,  445,  445,  459,  460,  253,
 
       460,  459,  459,  459,  459,  459,  459,  459,  461,  459,
-      459,  459, 1926,  459,  463,  459,  464,  459,  536,  253,
-      536,  536,  253,  536,  550,  253,  550, 1927,  550,  253,
-      550,  253,  253,  253,  539, 1271, 1928,  539, 1929, 1942,
-      551, 1948,  459,  459,  551, 1272,  465,  538, 1125, 1125,
-     1125, 1952, 1273,  466, 1955, 1957,  467, 1147, 1147, 1147,
-      468, 1958,  469,  470,  459,  460,  253,  460,  459,  459,
-      459,  459,  459,  459,  459,  461,  459,  459,  459, 1960,
+      459,  459, 1921,  459,  463,  459,  464,  459,  536,  253,
+      536,  536,  253,  536,  550,  253,  550,  896,  550,  253,
+      550,  253,  253,  253,  539, 1272, 1927,  539,  915, 1928,
+      551,  911,  459,  459,  551, 1273,  465,  538, 1126, 1126,
+     1126, 1929, 1274,  466, 1930, 1943,  467, 1148, 1148, 1148,
+      468, 1949,  469,  470,  459,  460,  253,  460,  459,  459,
+      459,  459,  459,  459,  459,  461,  459,  459,  459, 1953,
       459,  463,  459,  464,  459,  253,  253,  253,  550,  253,
-      550,  550,  253,  550, 1961,  550,  253,  550,  550,  253,
+      550,  550,  253,  550, 1956,  550,  253,  550,  550,  253,
 
-      550,  538, 1962, 1966,  551, 1969, 1971,  551, 1978,  459,
-      459,  552, 1126,  465,  552, 1160, 1160, 1160, 1986, 1161,
-      466, 1126, 1162,  467, 1147, 1147, 1147,  468, 1987,  469,
+      550,  538, 1958, 1959,  551, 1961, 1962,  551, 1963,  459,
+      459,  552, 1127,  465,  552, 1161, 1161, 1161, 1967, 1162,
+      466, 1127, 1163,  467, 1148, 1148, 1148,  468, 1970,  469,
       470,  474,  475,  253,  475,  474,  474,  474,  474,  474,
-      474,  474,  476,  474,  474,  474, 1988,  474,  478,  474,
+      474,  474,  476,  474,  474,  474, 1972,  474,  478,  474,
       479,  474,  562,  253,  562,  562,  253,  562,  573,  253,
-      573, 1989,  573,  253,  573,  923,  923,  923,  563, 1991,
-     2005,  563, 1108, 2009,  574, 2010,  474,  474,  574,  480,
-      481,  482,  924, 2011, 1170, 1170, 1170,  483, 1171, 2002,
-      484, 1172, 2014, 2015,  485, 1634, 2017,  486,  474,  475,
+      573, 1979,  573,  253,  573,  924,  924,  924,  563, 1987,
+     1988,  563, 1989, 1990,  574, 1992,  474,  474,  574,  480,
+      481,  482,  925, 2006, 1171, 1171, 1171,  483, 1172, 2010,
+      484, 1173, 2011, 2012,  485, 1635, 1109,  486,  474,  475,
 
       253,  475,  474,  474,  474,  474,  474,  474,  474,  476,
-      474,  474,  474, 2018,  474,  478,  474,  479,  474,  253,
-      253,  253,  253,  253,  253,  573,  253,  573, 2019,  573,
-      253,  573,  931,  931,  931,  538, 2020, 2003,  538, 2021,
-     2012,  574, 2022,  474,  474,  574,  480,  481,  482,  932,
-     2025, 1193, 1193, 1193,  483, 1194, 2013,  484, 1195, 2026,
-     2029,  485, 1634, 2030,  486,  490,  491,  253,  491,  490,
+      474,  474,  474, 2003,  474,  478,  474,  479,  474,  253,
+      253,  253,  253,  253,  253,  573,  253,  573, 2015,  573,
+      253,  573,  932,  932,  932,  538, 2016, 2004,  538, 2018,
+     2013,  574, 2019,  474,  474,  574,  480,  481,  482,  933,
+     2020, 1193, 1193, 1193,  483, 1194, 2014,  484, 1195, 2021,
+     2022,  485, 1635, 2023,  486,  490,  491,  253,  491,  490,
       490,  490,  490,  490,  490,  490,  492,  490,  490,  490,
-     2031,  490,  494,  490,  495,  490,  573,  253,  573,  573,
-      253,  573,  586,  253,  586, 2004,  586,  253,  586,  947,
+     2026,  490,  494,  490,  495,  490,  573,  253,  573,  573,
+      253,  573,  586,  253,  586, 2005,  586,  253,  586,  947,
 
-      947,  947,  575, 2032, 2033,  575, 2035, 2036,  587, 2039,
-      490,  490,  587, 2042, 2046,  496,  948, 1648, 1648, 1648,
-     2047,  497,  490,  491,  253,  491,  490,  490,  490,  490,
-      490,  490,  490,  492,  490,  490,  490, 2050,  490,  494,
+      947,  947,  575, 2027, 2030,  575, 2031, 2032,  587, 2033,
+      490,  490,  587, 2034, 2036,  496,  948, 1649, 1649, 1649,
+     2037,  497,  490,  491,  253,  491,  490,  490,  490,  490,
+      490,  490,  490,  492,  490,  490,  490, 2040,  490,  494,
       490,  495,  490,  253,  253,  253,  253,  253,  253,  586,
-      253,  586, 2048,  586,  253,  586,  965,  965,  965,  538,
-     2049, 2051,  538, 1649, 2052,  587, 2055,  490,  490,  587,
-     2059, 2060,  496,  966, 1651, 1651, 1651, 2063,  497,  501,
+      253,  586, 2043,  586,  253,  586,  966,  966,  966,  538,
+     2047, 2048,  538, 1650, 2051,  587, 2052,  490,  490,  587,
+     2053, 2056,  496,  967, 1652, 1652, 1652, 2060,  497,  501,
       502,  253,  502,  501,  501,  501,  501,  501,  501,  501,
-      503,  501,  501,  501, 2065,  501,  505,  501,  506,  501,
+      503,  501,  501,  501, 2061,  501,  505,  501,  506,  501,
 
-      586,  253,  586,  586,  253,  586,  601,  253,  601, 2053,
-      601,  253,  601,  253,  253,  253,  588, 2054, 2061,  588,
-     1652, 2061,  602, 2081,  501,  501,  602, 2082,  507,  603,
-     1125, 1125, 1125, 2083, 2062,  508, 2084, 2013,  509,  501,
+      586,  253,  586,  586,  253,  586,  601,  253,  601, 2049,
+      601,  253,  601,  253,  253,  253,  588, 2050, 2062,  588,
+     1653, 2064,  602, 2066,  501,  501,  602, 2082,  507,  603,
+     1126, 1126, 1126, 2083, 2063,  508, 2084, 2085,  509,  501,
       502,  253,  502,  501,  501,  501,  501,  501,  501,  501,
-      503,  501,  501,  501, 2085,  501,  505,  501,  506,  501,
-      253,  253,  253,  601,  253,  601,  601,  253,  601, 2086,
-      601,  253,  601,  601,  253,  601,  603, 2012, 2088,  602,
-     2092, 2098,  602, 2099,  501,  501,  604, 2100,  507,  604,
-     1147, 1147, 1147, 2062, 1201,  508, 2114, 2118,  509,  513,
+      503,  501,  501,  501, 2086,  501,  505,  501,  506,  501,
+      253,  253,  253,  601,  253,  601,  601,  253,  601, 2054,
+      601,  253,  601,  601,  253,  601,  603, 2055, 2087,  602,
+     2062, 2013,  602, 2089,  501,  501,  604, 2093,  507,  604,
+     1148, 1148, 1148, 2099, 1201,  508, 2014, 2063,  509,  513,
 
       514,  253,  514,  513,  513,  513,  513,  513,  513,  513,
-      515,  513,  513,  513, 2119,  513,  517,  513,  518,  513,
-      613,  253,  613,  613,  253,  613,  623,  253,  623, 2120,
-      623,  253,  623,  253,  253,  253,  614, 2122, 2126,  614,
-     2130, 2131,  624, 2132,  513,  513,  624, 2133,  519,  329,
-     1655, 1655, 1655, 2134, 1201,  520, 2137, 2144,  521, 1658,
-     1658, 1658, 1668, 1668, 1668,  522,  513,  514,  253,  514,
+      515,  513,  513,  513, 2100,  513,  517,  513,  518,  513,
+      613,  253,  613,  613,  253,  613,  623,  253,  623, 2101,
+      623,  253,  623,  253,  253,  253,  614, 2115, 2119,  614,
+     2120, 2121,  624, 2123,  513,  513,  624, 2127,  519,  353,
+     1656, 1656, 1656, 2131, 1201,  520, 2132, 2133,  521, 1659,
+     1659, 1659, 1669, 1669, 1669,  522,  513,  514,  253,  514,
       513,  513,  513,  513,  513,  513,  513,  515,  513,  513,
-      513, 2146,  513,  517,  513,  518,  513,  253,  253,  253,
-      623,  253,  623,  623,  253,  623, 2156,  623,  253,  623,
-
-      623,  253,  623,  329, 2157, 2158,  624, 2159, 2161,  624,
-      713,  513,  513,  625, 1634,  519,  625, 1213, 1213, 1213,
-      720, 1214,  520, 2167, 1215,  521, 1691, 1691, 1691, 1703,
-     1703, 1703,  522,  527,  528,  253,  528,  527,  527,  527,
-      527,  527,  527,  527,  529,  527,  527,  527,  721,  527,
+      513, 2134,  513,  517,  513,  518,  513,  253,  253,  253,
+      623,  253,  623,  623,  253,  623, 2135,  623,  253,  623,
+
+      623,  253,  623,  353, 2138, 2145,  624, 2147, 2157,  624,
+      712,  513,  513,  625, 2158,  519,  625, 1214, 1214, 1214,
+      721, 1215,  520, 2159, 1216,  521, 1703, 1703, 1703, 1705,
+     1705, 1705,  522,  527,  528,  253,  528,  527,  527,  527,
+      527,  527,  527,  527,  529,  527,  527,  527,  722,  527,
       531,  527,  532,  527,  635,  253,  635,  635,  253,  635,
-     2166, 1634,  674,  972,  972,  972,  668, 1223, 1223, 1223,
-      636, 1224, 2173,  636, 1225, 1704, 3216, 2174,  527,  527,
-      973,  977,  977,  977,  533,  713,  671, 2175, 2176, 1231,
-     1231, 1231, 2165, 1232,  671,  714, 1233, 2179,  978,  534,
+     2160, 2162,  674,  973,  973,  973,  668, 1122, 1122, 1122,
+      636, 1109, 1704,  636, 2168, 1653, 3217, 2165,  527,  527,
+      974,  978,  978,  978,  533, 1124,  671, 2174, 1224, 1224,
+     1224, 1635, 1225, 2175,  671, 1226, 1635, 2176,  979,  534,
 
       527,  528,  253,  528,  527,  527,  527,  527,  527,  527,
       527,  529,  527,  527,  527,  672,  527,  531,  527,  532,
-      527,  673,  724,  715,  989,  989,  989, 2181,  674,  716,
-     2182, 2183,  675,  717, 2187,  998,  998,  998,  725,  718,
-      719,  990, 1000, 1000, 1000,  527,  527, 1006, 1006, 1006,
-     1108,  533,  999, 1248, 1248, 1248, 2164, 1249, 2192, 1001,
-     1250, 1705, 1705, 1705, 1007, 2194,  534,  540,  541,  253,
+      527,  673,  725,  990,  990,  990, 2177, 2166,  674, 1706,
+     1706, 1706,  675,  999,  999,  999, 2180, 2167,  726, 2182,
+      991, 1001, 1001, 1001, 2183,  527,  527, 1007, 1007, 1007,
+     1000,  533, 1232, 1232, 1232, 2184, 1233, 2188, 1002, 1234,
+     1652, 1652, 1652, 2193, 1008, 2195,  534,  540,  541,  253,
       541,  540,  540,  540,  540,  540,  540,  540,  542,  540,
-      540,  540, 2195,  540,  544,  540,  545,  540, 1009, 1009,
-     1009, 1021, 1021, 1021, 1023, 1023, 1023, 1035, 1035, 1035,
-
-     1043, 1043, 1043, 2196, 2200, 1010, 2206, 1652, 1022, 2207,
-     2208, 1024,  540,  540, 1036, 2209, 2210, 1044,  546, 2211,
-     2212,  547, 1260, 1260, 1260, 2213, 1261, 2214, 2215, 1262,
-     1651, 1651, 1651,  548,  540,  541,  253,  541,  540,  540,
-      540,  540,  540,  540,  540,  542,  540,  540,  540, 2221,
-      540,  544,  540,  545,  540, 1048, 1048, 1048, 1054, 1054,
-     1054, 1074, 1074, 1074, 1098, 1098, 1098, 1102, 1102, 1102,
-     2222, 2223, 1049, 2224, 2236, 1055, 1794, 2237, 1075,  540,
-      540, 1099, 2242, 2243, 1103,  546, 2238, 2240,  547, 1263,
-     1263, 1263, 2245, 1264, 2239, 2241, 1265, 1648, 1648, 1648,
+      540,  540, 2196,  540,  544,  540,  545,  540, 1010, 1010,
+     1010, 1022, 1022, 1022, 1024, 1024, 1024, 1036, 1036, 1036,
+
+     1044, 1044, 1044, 2197, 2201, 1011, 1795, 2207, 1023, 2208,
+     2209, 1025,  540,  540, 1037, 2210, 2211, 1045,  546, 2212,
+     2213,  547, 1249, 1249, 1249, 2214, 1250, 2215, 2216, 1251,
+     1649, 1649, 1649,  548,  540,  541,  253,  541,  540,  540,
+      540,  540,  540,  540,  540,  542,  540,  540,  540, 2222,
+      540,  544,  540,  545,  540, 1049, 1049, 1049, 1055, 1055,
+     1055, 1075, 1075, 1075, 1099, 1099, 1099, 1103, 1103, 1103,
+     2223, 2224, 1050, 2225, 2237, 1056, 2238, 2243, 1076,  540,
+      540, 1100, 2244, 2246, 1104,  546, 2239, 2241,  547, 1261,
+     1261, 1261, 2247, 1262, 2240, 2242, 1263, 1652, 1652, 1652,
 
       548,  553,  554,  253,  554,  553,  553,  553,  553,  553,
-      553,  553,  555,  553,  553,  553, 2246,  553,  557,  553,
-      558,  553, 1121, 1121, 1121, 1121, 1121, 1121, 2250, 2251,
-     1155, 1155, 1155, 1155, 1155, 1155,  923,  923,  923, 2252,
-     1123, 2258, 2259, 1123, 2260, 2261,  553,  553, 1157, 2264,
-     2269, 1157,  559,  924, 1651, 1651, 1651,  560,  553,  554,
+      553,  553,  555,  553,  553,  553, 2251,  553,  557,  553,
+      558,  553, 1122, 1122, 1122, 1156, 1156, 1156, 2252, 2253,
+     1156, 1156, 1156,  924,  924,  924, 1166, 1166, 1166, 1866,
+     1124, 2259, 2260, 1158, 2261, 1867,  553,  553, 1158, 1868,
+      925, 2262,  559, 1869, 1168, 2265, 2270,  560,  553,  554,
       253,  554,  553,  553,  553,  553,  553,  553,  553,  555,
-      553,  553,  553, 2273,  553,  557,  553,  558,  553, 1165,
-     1165, 1165, 2274, 1124, 1165, 1165, 1165, 2279,  931,  931,
-      931, 2280, 2281, 1158, 1173, 1173, 1173, 1167, 1838, 1838,
+      553,  553,  553, 2274,  553,  557,  553,  558,  553, 2275,
+     1125, 1166, 1166, 1166,  932,  932,  932, 1182, 1182, 1182,
+     1159, 1174, 1174, 1174, 1177, 1177, 1177, 2280, 2276, 1168,
 
-     1838, 2282, 1167,  553,  553,  932, 1274, 1274, 1274,  559,
-     1275, 1174, 2284, 1276,  560,  564,  565,  253,  565,  564,
+     2281,  933, 2278,  553,  553, 1184, 2277, 2282, 1175,  559,
+     2279, 1178, 2283, 2285,  560,  564,  565,  253,  565,  564,
       564,  564,  564,  564,  564,  564,  566,  564,  564,  564,
-     2294,  564,  568,  564,  569,  564, 1176, 1176, 1176, 1181,
-     1181, 1181, 2305, 2306, 1189, 1189, 1189, 2307, 1168, 2311,
-     1181, 1181, 1181, 1177, 1189, 1189, 1189, 1183, 2312, 2275,
-      564,  564, 1191,  947,  947,  947,  570, 2276, 1183, 1278,
-     1278, 1278, 1191, 1279, 2313, 1634, 1280, 1655, 1655, 1655,
-      948,  571,  564,  565,  253,  565,  564,  564,  564,  564,
-      564,  564,  564,  566,  564,  564,  564, 1184,  564,  568,
-
-      564,  569,  564, 1197, 1197, 1197, 1197, 1197, 1197,  965,
-      965,  965, 1218, 1218, 1218,  972,  972,  972, 1192, 2316,
-     2320, 1199, 2300, 2277, 1199, 2321,  966,  564,  564, 2322,
-     1220, 2278,  973,  570, 1294, 1294, 1294, 2323, 1295, 2324,
-     2325, 1296, 2326, 1200, 1658, 1658, 1658, 1634,  571,  576,
+     2295,  564,  568,  564,  569,  564, 1189, 1189, 1189, 1189,
+     1189, 1189,  947,  947,  947, 1169, 1197, 1197, 1197, 2306,
+     1182, 1182, 1182, 2307, 1191, 2308, 2312, 1191, 2313,  948,
+      564,  564, 2314, 2317, 1199, 2321,  570, 1635, 1184, 1264,
+     1264, 1264, 2322, 1265, 1635, 2323, 1266, 1839, 1839, 1839,
+     2324,  571,  564,  565,  253,  565,  564,  564,  564,  564,
+      564,  564,  564,  566,  564,  564,  564, 1185,  564,  568,
+
+      564,  569,  564, 1192, 1197, 1197, 1197,  966,  966,  966,
+     2300, 1219, 1219, 1219, 1219, 1219, 1219,  973,  973,  973,
+     2325, 2301, 1199, 2326,  967, 2327, 2328,  564,  564, 1221,
+     2329, 2330, 1221,  570,  974, 1275, 1275, 1275, 2345, 1276,
+     2346, 1200, 1277, 1656, 1656, 1656, 2347, 2348,  571,  576,
       577,  253,  577,  576,  576,  576,  576,  576,  576,  576,
-      578,  576,  576,  576, 2327,  576,  580,  576,  581,  576,
-     2328, 1218, 1218, 1218, 1227, 1227, 1227, 2329, 1227, 1227,
-     1227,  977,  977,  977, 1235, 1235, 1235, 1865, 2344, 1220,
-     2299, 2345, 1229, 1866,  576,  576, 1229, 1867,  978, 2346,
+      578,  576,  576,  576, 2353,  576,  580,  576,  581,  576,
+     1228, 1228, 1228, 1228, 1228, 1228,  978,  978,  978, 2354,
+     1222, 1236, 1236, 1236, 1236, 1236, 1236, 2355, 1230, 2356,
+     2357, 1230, 2358,  979,  576,  576, 1242, 1242, 1242, 1238,
 
-      582, 1868, 1237,  583, 1297, 1297, 1297, 2347, 1298, 2352,
-     2353, 1299, 1843, 1843, 1843,  584,  576,  577,  253,  577,
+      582, 2359, 1238,  583, 1279, 1279, 1279, 2362, 1280, 2363,
+     2366, 1281, 2367, 2372, 1244,  584,  576,  577,  253,  577,
       576,  576,  576,  576,  576,  576,  576,  578,  576,  576,
-      576, 2354,  576,  580,  576,  581,  576, 1221, 1241, 1241,
-     1241,  989,  989,  989, 1230, 1235, 1235, 1235, 1241, 1241,
-     1241, 1253, 1253, 1253, 1869, 2355, 1243, 2356,  990, 2357,
-     1870,  576,  576, 1237, 1871, 2358, 1243,  582, 1872, 1255,
-      583, 1314, 1314, 1314, 2361, 1315, 1844, 2362, 1316, 1846,
-     1846, 1846,  584,  589,  590,  253,  590,  589,  589,  589,
-      589,  589,  589,  589,  591,  589,  589,  589, 2365,  589,
-
-      593,  589,  594,  589, 2366, 2371, 1238,  998,  998,  998,
-     1000, 1000, 1000, 1244, 1253, 1253, 1253, 1266, 1266, 1266,
-     2372, 1266, 1266, 1266,  999, 1847, 2373, 1001,  589,  589,
-     2374, 2383, 1255, 2384, 2385, 1268,  595, 2386,  596, 1268,
-     2388,  597, 1668, 1668, 1668,  598, 1854, 1854, 1854,  599,
+      576, 2373,  576,  580,  576,  581,  576, 2374, 2375, 1231,
+     1242, 1242, 1242, 2384, 2385, 1239,  990,  990,  990, 2386,
+     1254, 1254, 1254, 1254, 1254, 1254, 2387, 2389, 1244, 2391,
+     2415,  576,  576,  991,  999,  999,  999,  582, 1256, 2416,
+      583, 1256, 1295, 1295, 1295, 2418, 1296, 2419, 2420, 1297,
+     1635, 1000,  584,  589,  590,  253,  590,  589,  589,  589,
+      589,  589,  589,  589,  591,  589,  589,  589, 2421,  589,
+
+      593,  589,  594,  589, 2425, 1245, 1001, 1001, 1001, 1267,
+     1267, 1267, 2411, 2426, 1257, 1267, 1267, 1267, 1007, 1007,
+     1007, 2427, 2428, 1002, 1291, 1291, 1291, 1269,  589,  589,
+     1010, 1010, 1010, 1269, 1870, 1008,  595, 1635,  596, 2429,
+     1871,  597, 1293, 2430, 1872,  598, 2431, 1011, 1873,  599,
       589,  590,  253,  590,  589,  589,  589,  589,  589,  589,
-      589,  591,  589,  589,  589, 2390,  589,  593,  589,  594,
-      589, 1006, 1006, 1006, 1634, 1256, 1009, 1009, 1009, 1290,
-     1290, 1290, 1269, 1281, 1281, 1281, 2414, 2415, 1007, 1290,
-     1290, 1290, 1855, 1010, 2417,  589,  589, 1292, 2418, 2419,
+      589,  591,  589,  589,  589, 2432,  589,  593,  589,  594,
+      589, 1282, 1282, 1282, 2412, 2433, 1270, 1022, 1022, 1022,
+     1291, 1291, 1291, 1024, 1024, 1024, 2434, 2435, 1283, 1301,
+     1301, 1301, 2437, 2438, 1023,  589,  589, 2441, 1293, 2442,
 
-     1282, 2420, 2424,  595, 2425,  596, 2410, 1292,  597, 1691,
-     1691, 1691,  598, 1703, 1703, 1703,  599,  605,  606,  253,
+     1025, 2443, 2444,  595, 2445,  596, 1302, 2448,  597, 1659,
+     1659, 1659,  598, 1669, 1669, 1669,  599,  605,  606,  253,
       606,  605,  605,  605,  605,  605,  605,  605,  607,  605,
-      605,  605, 2426,  605,  609,  605,  610,  605, 1021, 1021,
-     1021, 1023, 1023, 1023, 1300, 1300, 1300, 1293, 1705, 1705,
-     1705, 3216, 3216, 3216, 2427, 1022, 2428, 2429, 1024, 2430,
-     2431, 1301,  605,  605, 3216, 3216, 3216, 2432, 3216, 1326,
-     1326, 1326, 2433, 1327, 2434, 2436, 1328, 1634, 1334, 1334,
-     1334, 3216, 1335, 2437, 2440, 1336,  611,  605,  606,  253,
+      605,  605, 2449,  605,  609,  605,  610,  605, 1294, 1298,
+     1298, 1298, 2450, 1299, 2451, 2439, 1300, 2452, 1844, 1844,
+     1844, 3217, 3217, 3217, 2440, 2454, 3217, 3217, 3217, 3217,
+     3217, 3217,  605,  605, 3217, 3217, 3217, 2458, 3217, 2459,
+     1315, 1315, 1315, 3217, 1316, 2446, 3217, 1317, 1327, 1327,
+     1327, 3217, 1328, 2460, 2447, 1329,  611,  605,  606,  253,
       606,  605,  605,  605,  605,  605,  605,  605,  607,  605,
 
-      605,  605, 1302,  605,  609,  605,  610,  605, 1035, 1035,
-     1035, 1306, 1306, 1306, 2411, 2438, 1303, 3216, 3216, 3216,
-     2441, 1317, 1317, 1317, 2439, 1036, 3216, 3216, 3216, 1308,
-     2442, 2443,  605,  605, 3216, 1306, 1306, 1306, 1318, 2444,
-     1343, 1343, 1343, 3216, 1344, 2445, 2447, 1345, 1375, 1375,
-     1375, 2448, 1376, 1308, 2446, 1377,  611,  615,  616,  253,
+      605,  605, 1303,  605,  609,  605,  610,  605, 1304, 1307,
+     1307, 1307, 1845, 2461, 1305, 2465, 1306, 1703, 1703, 1703,
+     1036, 1036, 1036, 1318, 1318, 1318, 2466, 1309, 1322, 1322,
+     1322, 2470,  605,  605, 1307, 1307, 1307, 1037, 2473, 2474,
+     1319, 1335, 1335, 1335, 2477, 1336, 1324, 2489, 1337, 1847,
+     1847, 1847, 1309, 1705, 1705, 1705,  611,  615,  616,  253,
       616,  615,  615,  615,  615,  615,  615,  615,  617,  615,
-      615,  615, 1304,  615,  619,  615,  620,  615, 1305, 1321,
-     1321, 1321, 1309, 1043, 1043, 1043, 1321, 1321, 1321, 1329,
-     1329, 1329, 1329, 1329, 1329, 2449, 2450, 1323, 2451, 2453,
-
-     1044, 2457,  615,  615, 1323, 2458, 2459, 1331, 2460, 2464,
-     1331, 2465, 2469,  621,  615,  616,  253,  616,  615,  615,
-      615,  615,  615,  615,  615,  617,  615,  615,  615, 2472,
-      615,  619,  615,  620,  615, 2473, 2476, 1324, 1048, 1048,
-     1048, 2488, 2489, 1338, 1338, 1338, 1338, 1338, 1338, 1054,
-     1054, 1054, 2492, 1332, 2493, 1049, 1882, 1882, 1882,  615,
-      615, 1340, 2513, 1634, 1340, 2514, 1055, 1882, 1882, 1882,
+      615,  615, 2490,  615,  619,  615,  620,  615, 1322, 1322,
+     1322, 1310, 1044, 1044, 1044, 2493, 1330, 1330, 1330, 1330,
+     1330, 1330, 1049, 1049, 1049, 1848, 1324, 2494, 1109, 1045,
+
+     1635, 2514,  615,  615, 1332, 1635, 2515, 1332, 2516, 1050,
+     1855, 1855, 1855,  621,  615,  616,  253,  616,  615,  615,
+      615,  615,  615,  615,  615,  617,  615,  615,  615, 1325,
+      615,  619,  615,  620,  615, 1339, 1339, 1339, 2511, 1339,
+     1339, 1339, 2512, 2513, 1055, 1055, 1055, 1344, 1344, 1344,
+     1333, 1345, 2517, 1341, 1346, 2518, 1856, 1341, 2527,  615,
+      615, 1056, 1376, 1376, 1376, 2528, 1377, 2529, 2530, 1378,
       621,  626,  627,  253,  627,  626,  626,  626,  626,  626,
-      626,  626,  628,  626,  626,  626, 1108,  626,  630,  626,
-      631,  626, 2515, 1341, 1349, 1349, 1349, 1353, 1353, 1353,
+      626,  626,  628,  626,  626,  626, 1342,  626,  630,  626,
+      631,  626, 1350, 1350, 1350, 1354, 1354, 1354, 1356, 1356,
 
-     2511, 1349, 1349, 1349, 1355, 1355, 1355, 3216, 3216, 3216,
-     2516, 2517, 1351, 2526, 1354, 2527,  626,  626, 2528, 1351,
-     1883, 1356, 1634, 2529, 3216, 2530, 2510,  632, 1415, 1415,
-     1415, 1844, 1416, 2531, 2532, 1417, 1911, 1911, 1911, 2533,
+     1356, 1350, 1350, 1350, 3217, 3217, 3217, 1359, 1359, 1359,
+     1352, 2531, 1355, 2532, 2533, 1357,  626,  626, 2534, 1352,
+     2535, 3217, 1364, 1364, 1364, 1361, 2536,  632, 1416, 1416,
+     1416, 2537, 1417, 2539, 2540, 1418, 1706, 1706, 1706, 1365,
       633,  626,  627,  253,  627,  626,  626,  626,  626,  626,
-      626,  626,  628,  626,  626,  626, 1352,  626,  630,  626,
-      631,  626, 1358, 1358, 1358, 2512, 1357, 1363, 1363, 1363,
-     1358, 1358, 1358, 3216, 3216, 3216, 1367, 1367, 1367, 2520,
-     1360, 3216, 3216, 3216, 1364, 2534,  626,  626, 1360, 2521,
-     3216, 2535, 2522, 1368, 1370, 1370, 1370,  632, 3216, 1370,
-
-     1370, 1370, 1074, 1074, 1074, 2536, 1378, 1378, 1378, 2538,
-      633,  641, 1372, 2539, 1378, 1378, 1378, 1372,  656, 1075,
-     1382, 1382, 1382, 1365, 1380, 2540, 2541,  640,  657, 2542,
-     2543, 1361, 1380, 1384, 1384, 1384, 1373, 1383, 1366, 2544,
-     1369, 1386, 1386, 1386, 2545, 2546, 1386, 1386, 1386, 2547,
-     1385, 1390, 1390, 1390, 2548,  658,  659,  660, 2549, 1388,
-     2550, 2551,  661,  662, 1388, 2552,  663,  664, 1391, 1381,
-      665, 2553,  666,  667,  668, 3216, 3216, 3216, 1394, 1394,
-     1394, 1396, 1396, 1396, 1396, 1396, 1396, 1405, 1405, 1405,
-     2523, 2554, 3216, 2556, 2564, 1395, 1405, 1405, 1405, 1398,
-
-     2524, 2565, 1398, 2525, 2566, 1407, 1411, 1411, 1411, 1411,
-     1411, 1411, 2570, 1108, 1407, 2605, 2607, 1389, 1098, 1098,
-     1098, 1418, 1418, 1418, 1413, 1392, 1634, 1413, 1418, 1418,
-     1418, 1102, 1102, 1102, 2608, 1099, 1426, 1426, 1426, 1420,
-     1393, 2609, 2602, 1422, 1422, 1422, 1420, 1423, 1103, 2613,
-     1424, 1426, 1426, 1426, 1428, 1399, 1121, 1121, 1121, 2614,
-     1408, 1121, 1121, 1121, 1121, 1121, 1121, 1634, 2603, 1428,
-     1467, 1467, 1467, 1414, 1123, 1155, 1155, 1155, 2588, 1123,
-     2617, 2618, 1123, 1155, 1155, 1155, 2621, 1468, 2589, 1421,
-     1155, 1155, 1155, 1157, 2590, 1470, 1470, 1470, 1160, 1160,
-
-     1160, 1157, 1161, 2622, 2623, 1162, 2624, 2625, 1157, 2604,
-     2626, 1438, 1471, 2627, 2628, 1429, 3216, 3216, 3216, 1165,
-     1165, 1165, 1165, 1165, 1165, 1165, 1165, 1165, 1170, 1170,
-     1170, 2629, 1171, 3216, 2631, 1172, 2632, 1167, 2633, 1469,
-     1167, 2634, 2615, 1167, 1173, 1173, 1173, 1476, 1476, 1476,
-     2591, 1477, 2619, 2635, 1478, 2616, 1479, 1479, 1479, 2636,
-     2592, 1174, 1176, 1176, 1176, 2620, 2593, 1481, 1481, 1481,
-     2637, 1482, 1474, 1480, 1483, 2638, 2639, 1472, 2640, 1177,
-     1485, 1485, 1485, 1181, 1181, 1181, 1181, 1181, 1181, 1181,
-     1181, 1181, 1491, 1491, 1491, 2641, 2642, 1486, 1189, 1189,
-
-     1189, 1183, 2643, 2644, 1183, 2645, 2647, 1183, 2655, 1492,
-     1189, 1189, 1189, 1189, 1189, 1189, 1191, 1193, 1193, 1193,
-     2656, 1194, 2657, 2658, 1195, 1197, 1197, 1197, 1191, 2675,
-     2676, 1191, 1197, 1197, 1197, 1496, 1496, 1496, 1213, 1213,
-     1213, 2677, 1214, 1199, 2678, 1215, 1511, 1511, 1511, 1488,
-     1199, 2679, 2680, 1497, 1218, 1218, 1218, 1218, 1218, 1218,
-     1494, 1634, 2691, 1512, 1218, 1218, 1218, 1223, 1223, 1223,
-     2693, 1224, 1220, 1108, 1225, 1220, 1227, 1227, 1227, 1227,
-     1227, 1227, 1220, 1227, 1227, 1227, 1231, 1231, 1231, 2694,
-     1232, 2695, 2696, 1233, 1229, 2697, 2688, 1229, 1517, 1517,
-
-     1517, 1229, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235,
-     1235, 1520, 1520, 1520, 2683, 1518, 2698, 3216, 3216, 3216,
-     1237, 2687, 2699, 1237, 2700, 1513, 1237, 2684, 1521, 1241,
-     1241, 1241, 2701, 2685, 3216, 1241, 1241, 1241, 1241, 1241,
-     1241, 1526, 1526, 1526, 1516, 1522, 2686, 1243, 1248, 1248,
-     1248, 2702, 1249, 1243, 2705, 1250, 1243, 2706, 1527, 1253,
-     1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1533, 1533,
-     1533, 2707, 1260, 1260, 1260, 1519, 1261, 1255, 2708, 1262,
-     1255, 2709, 2710, 1255, 2711, 1534, 1263, 1263, 1263, 2712,
-     1264, 2714, 2715, 1265, 1266, 1266, 1266, 1266, 1266, 1266,
-
-     1266, 1266, 1266, 2716, 1523, 2717, 1274, 1274, 1274, 2718,
-     1275, 2719, 1268, 1276, 2720, 1268, 2721, 2722, 1268, 1540,
-     1540, 1540, 1278, 1278, 1278, 2723, 1279, 2724, 2725, 1280,
-     1530, 1281, 1281, 1281, 2726, 2727, 1541, 1542, 1542, 1542,
-     2728, 1543, 2734, 2735, 1544, 1290, 1290, 1290, 1282, 1290,
-     1290, 1290, 1290, 1290, 1290, 1294, 1294, 1294, 2736, 1295,
-     2737, 2738, 1296, 1292, 2744, 1535, 2746, 1292, 2752, 2753,
-     1292, 1297, 1297, 1297, 2745, 1298, 2747, 2748, 1299, 1300,
-     1300, 1300, 1553, 1553, 1553, 2754, 1554, 2749, 2755, 1555,
-     1306, 1306, 1306, 1306, 1306, 1306, 1301, 1306, 1306, 1306,
-
-     1314, 1314, 1314, 2756, 1315, 2757, 2761, 1316, 1308, 2762,
-     2763, 1308, 1317, 1317, 1317, 1308, 1565, 1565, 1565, 1552,
-     1566, 2764, 2774, 1567, 1321, 1321, 1321, 2775, 2776, 1318,
-     1321, 1321, 1321, 1321, 1321, 1321, 1326, 1326, 1326, 2750,
-     1327, 1108, 1323, 1328, 2777, 1560, 2778, 2779, 1323, 2751,
-     2780, 1323, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329,
-     1329, 1334, 1334, 1334, 2781, 1335, 2785, 2786, 1336, 2787,
-     1331, 2788, 2789, 1331, 2790, 2765, 1331, 1338, 1338, 1338,
-     1338, 1338, 1338, 2792, 1570, 1338, 1338, 1338, 2793, 1343,
-     1343, 1343, 2794, 1344, 2795, 1340, 1345, 2796, 1340, 1349,
-
-     1349, 1349, 2797, 1340, 1349, 1349, 1349, 2798, 1349, 1349,
-     1349, 1353, 1353, 1353, 1581, 1581, 1581, 1351, 1582, 2799,
-     2800, 1583, 1351, 2801, 2805, 1572, 1351, 2806, 1354, 1355,
-     1355, 1355, 2807, 2810, 1575, 1584, 1584, 1584, 2815, 1585,
-     2816, 2817, 1586, 1358, 1358, 1358, 1356, 1358, 1358, 1358,
-     2818, 1358, 1358, 1358, 1363, 1363, 1363, 2819, 1367, 1367,
-     1367, 1360, 2016, 2016, 2016, 1360, 2820, 2821, 1580, 1360,
-     2822, 1364, 1590, 1590, 1590, 1368, 1591, 2823, 2824, 1592,
-     1595, 1595, 1595, 2825, 1596, 2826, 2828, 1597, 1370, 1370,
-     1370, 1370, 1370, 1370, 1370, 1370, 1370, 1375, 1375, 1375,
-
-     2829, 1376, 2830, 2831, 1377, 2838, 1372, 2839, 1108, 1372,
-     2840, 2841, 1372, 1378, 1378, 1378, 2842, 2843, 1588, 1378,
-     1378, 1378, 1378, 1378, 1378, 1382, 1382, 1382, 1602, 1602,
-     1602, 1380, 1603, 2844, 2845, 1604, 2846, 1380, 2847, 2848,
-     1380, 2849, 1383, 1384, 1384, 1384, 1605, 1605, 1605, 2850,
-     1606, 2832, 2851, 1607, 1386, 1386, 1386, 2854, 1599, 2855,
-     1385, 1386, 1386, 1386, 2856, 1386, 1386, 1386, 1390, 1390,
-     1390, 2857, 1388, 1609, 1609, 1609, 2858, 1610, 2859, 1388,
-     1611, 2860, 1601, 1388, 2861, 1391, 1394, 1394, 1394, 1614,
-     1614, 1614, 2862, 1615, 2863, 2864, 1616, 1396, 1396, 1396,
-
-     1396, 1396, 1396, 1395, 1396, 1396, 1396, 1619, 1619, 1619,
-     1405, 1405, 1405, 2868, 2875, 1398, 2876, 2877, 1398, 1405,
-     1405, 1405, 1398, 2878, 1620, 2879, 2880, 1608, 1407, 1405,
-     1405, 1405, 1411, 1411, 1411, 2881, 2882, 1407, 1411, 1411,
-     1411, 1411, 1411, 1411, 1415, 1415, 1415, 1407, 1416, 2883,
-     1413, 1417, 1418, 1418, 1418, 2884, 1413, 2885, 2886, 1413,
-     1418, 1418, 1418, 1418, 1418, 1418, 1617, 1422, 1422, 1422,
-     1420, 1423, 2889, 2890, 1424, 1426, 1426, 1426, 1420, 2891,
-     2892, 1420, 1426, 1426, 1426, 1426, 1426, 1426, 2895, 2900,
-     1624, 2901, 2902, 1428, 1627, 1633, 1633, 1633, 2903, 1108,
-
-     1428, 2904, 2896, 1428, 1121, 1121, 1121, 1467, 1467, 1467,
-     1155, 1155, 1155, 1634, 1635, 2905, 1470, 1470, 1470, 1496,
-     1496, 1496, 1123, 1628, 1468, 1671, 1671, 1671, 1157, 1672,
-     2906, 2907, 1673, 1471, 1675, 1675, 1675, 1497, 1676, 2895,
-     2908, 1677, 1165, 1165, 1165, 2893, 1630, 1476, 1476, 1476,
-     2898, 1477, 2909, 2910, 1478, 1479, 1479, 1479, 2911, 2912,
-     1167, 2913, 1682, 1682, 1682, 2914, 1683, 2915, 1674, 1684,
-     1640, 2916, 1480, 1481, 1481, 1481, 2917, 1482, 2918, 2923,
-     1483, 1485, 1485, 1485, 2919, 1686, 1686, 1686, 2928, 1687,
-     2929, 1680, 1688, 1181, 1181, 1181, 2920, 2930, 1486, 1491,
-
-     1491, 1491, 1693, 1693, 1693, 2931, 1694, 2932, 2933, 1695,
-     2936, 1183, 1696, 1696, 1696, 1108, 1492, 1189, 1189, 1189,
-     1713, 1713, 1713, 1511, 1511, 1511, 1715, 1715, 1715, 1697,
-     1716, 1634, 1635, 1717, 2936, 1191, 2939, 1714, 2940, 2941,
-     1512, 2942, 2945, 1690, 1218, 1218, 1218, 1227, 1227, 1227,
-     1517, 1517, 1517, 1722, 1722, 1722, 2934, 1723, 2948, 2957,
-     1724, 2943, 1220, 2895, 2960, 1229, 1698, 1518, 1235, 1235,
-     1235, 1520, 1520, 1520, 1726, 1726, 1726, 2896, 1727, 2944,
-     2965, 1728, 1241, 1241, 1241, 2921, 1237, 2968, 1521, 1526,
-     1526, 1526, 1733, 1733, 1733, 2924, 1734, 2922, 2926, 1735,
-
-     1243, 1736, 1736, 1736, 2969, 2970, 1527, 2925, 1718, 2936,
-     2927, 1721, 1738, 1738, 1738, 1253, 1253, 1253, 1737, 1533,
-     1533, 1533, 2972, 1744, 1744, 1744, 2936, 1745, 1725, 1739,
-     1746, 2973, 2974, 1255, 2955, 2946, 1534, 1266, 1266, 1266,
-     1749, 1749, 1749, 1730, 1540, 1540, 1540, 1753, 1753, 1753,
-     2947, 1754, 2975, 2956, 1755, 1268, 2895, 1750, 1740, 2976,
-     2958, 1541, 1542, 1542, 1542, 2977, 1543, 2898, 2978, 1544,
-     1756, 1756, 1756, 1290, 1290, 1290, 1553, 1553, 1553, 2959,
-     1554, 1741, 2979, 1555, 1765, 1765, 1765, 1757, 3216, 3216,
-     3216, 1292, 3216, 3216, 3216, 3216, 3216, 3216, 1306, 1306,
-
-     1306, 1766, 2963, 1747, 2980, 3216, 1772, 1772, 1772, 3216,
-     2990, 2991, 3216, 1565, 1565, 1565, 1308, 1566, 2966, 2992,
-     1567, 2964, 2993, 1773, 1776, 1776, 1776, 1321, 1321, 1321,
-     1329, 1329, 1329, 1338, 1338, 1338, 2994, 2967, 1764, 1768,
-     2995, 1777, 1788, 1788, 1788, 1323, 2999, 3000, 1331, 3001,
-     3002, 1340, 3003, 1770, 1349, 1349, 1349, 3004, 1767, 1789,
-     1581, 1581, 1581, 3005, 1582, 1769, 3006, 1583, 3008, 1584,
-     1584, 1584, 1351, 1585, 3009, 3010, 1586, 1358, 1358, 1358,
-     1590, 1590, 1590, 3011, 1591, 3012, 3017, 1592, 1790, 3018,
-     1784, 1779, 1370, 1370, 1370, 1360, 1781, 1595, 1595, 1595,
-
-     3019, 1596, 3020, 3013, 1597, 1378, 1378, 1378, 3021, 3022,
-     1372, 1791, 1602, 1602, 1602, 3014, 1603, 3023, 3024, 1604,
-     1605, 1605, 1605, 1380, 1606, 3015, 3025, 1607, 1386, 1386,
-     1386, 1609, 1609, 1609, 3026, 1610, 3027, 3016, 1611, 3028,
-     1614, 1614, 1614, 1793, 1615, 3029, 1388, 1616, 1396, 1396,
-     1396, 3030, 3032, 1798, 1619, 1619, 1619, 1806, 1806, 1806,
-     3033, 1807, 1800, 3034, 1808, 3035, 1398, 1405, 1405, 1405,
-     3036, 1620, 1814, 1814, 1814, 1801, 1411, 1411, 1411, 1418,
-     1418, 1418, 1818, 1818, 1818, 1407, 1426, 1426, 1426, 1815,
-     1633, 1633, 1633, 3037, 1413, 1804, 3038, 1420, 3039, 1819,
-
-     1121, 1121, 1121, 1108, 1428, 1671, 1671, 1671, 1634, 1672,
-     3040, 3041, 1673, 1696, 1696, 1696, 1812, 3042, 1123, 1155,
-     1155, 1155, 1675, 1675, 1675, 3043, 1676, 3044, 3031, 1677,
-     1697, 1817, 1165, 1165, 1165, 3045, 3046, 1157, 1682, 1682,
-     1682, 1822, 1683, 1816, 3047, 1684, 3048, 3049, 1820, 3050,
-     1167, 3051, 1827, 1686, 1686, 1686, 3053, 1687, 1823, 1108,
-     1688, 1181, 1181, 1181, 1693, 1693, 1693, 3054, 1694, 3055,
-     3056, 1695, 3057, 1873, 1873, 1873, 3058, 1874, 3052, 1183,
-     1875, 3059, 3060, 1859, 3061, 3062, 1856, 1189, 1189, 1189,
-     1843, 1843, 1843, 1713, 1713, 1713, 1888, 1888, 1888, 3063,
-
-     1889, 3064, 3065, 1890, 3066, 1191, 3067, 1715, 1715, 1715,
-     1714, 1716, 3068, 3069, 1717, 1218, 1218, 1218, 1893, 1893,
-     1893, 3070, 1863, 1227, 1227, 1227, 3072, 1722, 1722, 1722,
-     1108, 1723, 3073, 1220, 1724, 1894, 3074, 3075, 1876, 3076,
-     3077, 1229, 1235, 1235, 1235, 1726, 1726, 1726, 3078, 1727,
-     3071, 3079, 1728, 3080, 1883, 1897, 1897, 1897, 3081, 3082,
-     1237, 3083, 1891, 1241, 1241, 1241, 3084, 1733, 1733, 1733,
-     1895, 1734, 1898, 3085, 1735, 1736, 1736, 1736, 1902, 1902,
-     1902, 1243, 1903, 3086, 3087, 1904, 1738, 1738, 1738, 1905,
-     1905, 1905, 1737, 1906, 3088, 3089, 1907, 1909, 1909, 1909,
-
-     1744, 1744, 1744, 1739, 1745, 3091, 3092, 1746, 1896, 3093,
-     1266, 1266, 1266, 3094, 3095, 1910, 1749, 1749, 1749, 1915,
-     1915, 1915, 3096, 1916, 3097, 3098, 1917, 1899, 1268, 1918,
-     1918, 1918, 3099, 1750, 1753, 1753, 1753, 3100, 1754, 1108,
-     3101, 1755, 1756, 1756, 1756, 3090, 1919, 1921, 1921, 1921,
-     3102, 1922, 3104, 3105, 1923, 3106, 1913, 3107, 3108, 1757,
-     1924, 1924, 1924, 1930, 1930, 1930, 1290, 1290, 1290, 1765,
-     1765, 1765, 1933, 1933, 1933, 3109, 1934, 1925, 3110, 1935,
-     1931, 1936, 1936, 1936, 1292, 3111, 1766, 3216, 3216, 3216,
-     1939, 1939, 1939, 1306, 1306, 1306, 3113, 3114, 1937, 1772,
-
-     1772, 1772, 3115, 3116, 3216, 3117, 3118, 1940, 1943, 1943,
-     1943, 1308, 1944, 3119, 1108, 1945, 1773, 1946, 1946, 1946,
-     1776, 1776, 1776, 1949, 1949, 1949, 3120, 1950, 3103, 3123,
-     1951, 3124, 1932, 3125, 1947, 3126, 3127, 1777, 1953, 1953,
-     1953, 1329, 1329, 1329, 3128, 1938, 1338, 1338, 1338, 1788,
-     1788, 1788, 1108, 1941, 1108, 1108, 1954, 1108, 1108, 1331,
-     1702, 1963, 1963, 1963, 1340, 1964, 1789, 1701, 1965, 1967,
-     1967, 1967, 1358, 1358, 1358, 1108, 1972, 1972, 1972, 1974,
-     1974, 1974, 3216, 3216, 3216, 3137, 3181, 1968, 3129, 1108,
-     1360, 3130, 1956, 1973, 1959, 3145, 1975, 1108, 3135, 3216,
-
-     1370, 1370, 1370, 1378, 1378, 1378, 1386, 1386, 1386, 1981,
-     1981, 1981, 1983, 1983, 1983, 1396, 1396, 1396, 1372, 3136,
-     3139, 1380, 1108, 1970, 1388, 1108, 1982, 1108, 1108, 1984,
-     1806, 1806, 1806, 1398, 1807, 1108, 1108, 1808, 1405, 1405,
-     1405, 1814, 1814, 1814, 3138, 3131, 1976, 3140, 1108, 1979,
-     1992, 1992, 1992, 1700, 1993, 1108, 1407, 1994, 1815, 1411,
-     1411, 1411, 3146, 3147, 1418, 1418, 1418, 1977, 1818, 1818,
-     1818, 1980, 1997, 1997, 1997, 3132, 1998, 1413, 1699, 1999,
-     1985, 1692, 1420, 3133, 3134, 1819, 2000, 2000, 2000, 1990,
-     2006, 2006, 2006, 1121, 1121, 1121, 1838, 1838, 1838, 2023,
-
-     2023, 2023, 1689, 1685, 2001, 1681, 1108, 2007, 1843, 1843,
-     1843, 1123, 2024, 2024, 2024, 1846, 1846, 1846, 1995, 1996,
-     2027, 2027, 2027, 2028, 2028, 2028, 1854, 1854, 1854, 1155,
-     1155, 1155, 2037, 2037, 2037, 2040, 2040, 2040, 1181, 1181,
-     1181, 2044, 2044, 2044, 1873, 1873, 1873, 1157, 1874, 3141,
-     2038, 1875, 2041, 3143, 2008, 1108, 1183, 1108, 2045, 1189,
-     1189, 1189, 1679, 2057, 2057, 2057, 1882, 1882, 1882, 2064,
-     2064, 2064, 2066, 2066, 2066, 1108, 3142, 1191, 3157, 2034,
-     2058, 1888, 1888, 1888, 1108, 1889, 1678, 1108, 1890, 2067,
-     1218, 1218, 1218, 2069, 2069, 2069, 3148, 2043, 1893, 1893,
-
-     1893, 1670, 2071, 2071, 2071, 2056, 2072, 1108, 1220, 2073,
-     2070, 1227, 1227, 1227, 1108, 1894, 2075, 2075, 2075, 1897,
-     1897, 1897, 3144, 2077, 2077, 2077, 3158, 2078, 1108, 1229,
-     2079, 1241, 1241, 1241, 2076, 1108, 1898, 1902, 1902, 1902,
-     1108, 1903, 3149, 2068, 1904, 1669, 1905, 1905, 1905, 1243,
-     1906, 1108, 1667, 1907, 1909, 1909, 1909, 1911, 1911, 1911,
-     3151, 1266, 1266, 1266, 2074, 3153, 1915, 1915, 1915, 1108,
-     1916, 1108, 1910, 1917, 1918, 1918, 1918, 3154, 2080, 1268,
-     2089, 2089, 2089, 1666, 2090, 1108, 3150, 2091, 1921, 1921,
-     1921, 1919, 1922, 1108, 1108, 1923, 1924, 1924, 1924, 2093,
-
-     2093, 2093, 1108, 2094, 3159, 1108, 2095, 2096, 2096, 2096,
-     1930, 1930, 1930, 1925, 2101, 2101, 2101, 3152, 2102, 2087,
-     3160, 2103, 1108, 1108, 2097, 3155, 3156, 1931, 1290, 1290,
-     1290, 1933, 1933, 1933, 1108, 1934, 3161, 1108, 1935, 1936,
-     1936, 1936, 3173, 2105, 2105, 2105, 1292, 2106, 1108, 1665,
-     2107, 2108, 2108, 2108, 3171, 1664, 1937, 1939, 1939, 1939,
-     2110, 2110, 2110, 1108, 2111, 3163, 3164, 2112, 2109, 1306,
-     1306, 1306, 3167, 1108, 1940, 1108, 1943, 1943, 1943, 2104,
-     1944, 3191, 3162, 1945, 1946, 1946, 1946, 1308, 2115, 2115,
-     2115, 1108, 2116, 3172, 1663, 2117, 1949, 1949, 1949, 1108,
-
-     1950, 1947, 1108, 1951, 1953, 1953, 1953, 1329, 1329, 1329,
-     2123, 2123, 2123, 1338, 1338, 1338, 2127, 2127, 2127, 3165,
-     2113, 3166, 1954, 1108, 1108, 1331, 3168, 2124, 1963, 1963,
-     1963, 1340, 1964, 2128, 3197, 1965, 1967, 1967, 1967, 2135,
-     2135, 2135, 1972, 1972, 1972, 2138, 2138, 2138, 1662, 2139,
-     1108, 3183, 2140, 1108, 1968, 1108, 3169, 2136, 1108, 1973,
-     1108, 3174, 2129, 1974, 1974, 1974, 2141, 2141, 2141, 1661,
-     2142, 2121, 1660, 2143, 2125, 1370, 1370, 1370, 1108, 1108,
-     1975, 1378, 1378, 1378, 1386, 1386, 1386, 1981, 1981, 1981,
-     2149, 2149, 2149, 1372, 2150, 3175, 3177, 2151, 1108, 1380,
-
-     3176, 3178, 1388, 1108, 1982, 1983, 1983, 1983, 2152, 2152,
-     2152, 3170, 2153, 3185, 1108, 2154, 1396, 1396, 1396, 1405,
-     1405, 1405, 1984, 1108, 1992, 1992, 1992, 3184, 1993, 1108,
-     2147, 1994, 3182, 1108, 1398, 3179, 1108, 1407, 1411, 1411,
-     1411, 2145, 1418, 1418, 1418, 1108, 1997, 1997, 1997, 2148,
-     1998, 3180, 1659, 1999, 1657, 1656, 1413, 2000, 2000, 2000,
-     1420, 2006, 2006, 2006, 2168, 2168, 2168, 3186, 2169, 3187,
-     3205, 2170, 1121, 1121, 1121, 2001, 3192, 1654, 2007, 1108,
-     3189, 2155, 3193, 3213, 2160, 2172, 2172, 2172, 1108, 2162,
-     1123, 2177, 2177, 2177, 1108, 2163, 2178, 2178, 2178, 2016,
-
-     2016, 2016, 2180, 2180, 2180, 2184, 2184, 2184, 2023, 2023,
-     2023, 2024, 2024, 2024, 2185, 2185, 2185, 2027, 2027, 2027,
-     2028, 2028, 2028, 2188, 2188, 2188, 2189, 2189, 2189, 2190,
-     2190, 2190, 2191, 2191, 2191, 1108, 2171, 1155, 1155, 1155,
-     2037, 2037, 2037, 3206, 2040, 2040, 2040, 2197, 2197, 2197,
-     1108, 2198, 1108, 1653, 2199, 1157, 1650, 1108, 2038, 3213,
-     2186, 2041, 2201, 2201, 2201, 2044, 2044, 2044, 2203, 2203,
-     2203, 3190, 2204, 1108, 1108, 2205, 1189, 1189, 1189, 1108,
-     2202, 3188, 2045, 2057, 2057, 2057, 1108, 3194, 2193, 2217,
-     2217, 2217, 3198, 2218, 1191, 1647, 2219, 2220, 2220, 2220,
-
-     2058, 2064, 2064, 2064, 2225, 2225, 2225, 2066, 2066, 2066,
-     2227, 2227, 2227, 1646, 2228, 3195, 1108, 2229, 1218, 1218,
-     1218, 2069, 2069, 2069, 2067, 2216, 2231, 2231, 2231, 1108,
-     2232, 1108, 3199, 2233, 1645, 1644, 1220, 1108, 2070, 2071,
-     2071, 2071, 1108, 2072, 1643, 1108, 2073, 1227, 1227, 1227,
-     2226, 1642, 2075, 2075, 2075, 2077, 2077, 2077, 1641, 2078,
-     1108, 3203, 2079, 1639, 3209, 1229, 1241, 1241, 1241, 2230,
-     2076, 1266, 1266, 1266, 2089, 2089, 2089, 3200, 2090, 1638,
-     1637, 2091, 3201, 3196, 1243, 3210, 2093, 2093, 2093, 1268,
-     2094, 1108, 1636, 2095, 2096, 2096, 2096, 3202, 2234, 2247,
-
-     2247, 2247, 1629, 2248, 1108, 1108, 2249, 1626, 2101, 2101,
-     2101, 2097, 2102, 1625, 1623, 2103, 1290, 1290, 1290, 2235,
-     2105, 2105, 2105, 3204, 2106, 1622, 2244, 2107, 2108, 2108,
-     2108, 2254, 2254, 2254, 1292, 2255, 3207, 3208, 2256, 2110,
-     2110, 2110, 1108, 2111, 1621, 2109, 2112, 1306, 1306, 1306,
-     2115, 2115, 2115, 1618, 2116, 1613, 1612, 2117, 2262, 2262,
-     2262, 2123, 2123, 2123, 1600, 1308, 2265, 2265, 2265, 1598,
-     2266, 1594, 1593, 2267, 3211, 1108, 2263, 1589, 2124, 1587,
-     2253, 1338, 1338, 1338, 2127, 2127, 2127, 2270, 2270, 2270,
-     1579, 2271, 1578, 1577, 2272, 1576, 2135, 2135, 2135, 1340,
-
-     1574, 2128, 2138, 2138, 2138, 1573, 2139, 3212, 1571, 2140,
-     1370, 1370, 1370, 2257, 2136, 2141, 2141, 2141, 1569, 2142,
-     1568, 1564, 2143, 1563, 1378, 1378, 1378, 1562, 1372, 1386,
-     1386, 1386, 2149, 2149, 2149, 1561, 2150, 1559, 1558, 2151,
-     1557, 2268, 1380, 1556, 2152, 2152, 2152, 1388, 2153, 1551,
-     1550, 2154, 1396, 1396, 1396, 1549, 2288, 2288, 2288, 1548,
-     1547, 2283, 3216, 3216, 3216, 2286, 3216, 3216, 3216, 1546,
-     1398, 1545, 2287, 2289, 3216, 3216, 3216, 1539, 1538, 3216,
-     1405, 1405, 1405, 3216, 1411, 1411, 1411, 2296, 2296, 2296,
-     2285, 3216, 2298, 2298, 2298, 2301, 2301, 2301, 1407, 2168,
-
-     2168, 2168, 1413, 2169, 1537, 2297, 2170, 1121, 1121, 1121,
-     1108, 1536, 1532, 2290, 2172, 2172, 2172, 2303, 2303, 2303,
-     2304, 2304, 2304, 1531, 1529, 1123, 2177, 2177, 2177, 1528,
-     2291, 1525, 1524, 2292, 2178, 2178, 2178, 2180, 2180, 2180,
-     2308, 2308, 2308, 1515, 2295, 2293, 2309, 2309, 2309, 2310,
-     2310, 2310, 2184, 2184, 2184, 2185, 2185, 2185, 2188, 2188,
-     2188, 2189, 2189, 2189, 1514, 1510, 2302, 2190, 2190, 2190,
-     2191, 2191, 2191, 2314, 2314, 2314, 2317, 2317, 2317, 2197,
-     2197, 2197, 1509, 2198, 1508, 1507, 2199, 3216, 3216, 3216,
-     1506, 2315, 1505, 2318, 2201, 2201, 2201, 1504, 2203, 2203,
-
-     2203, 1503, 2204, 1502, 3216, 2205, 1189, 1189, 1189, 2217,
-     2217, 2217, 2202, 2218, 2331, 2332, 2219, 2333, 1501, 2337,
-     2338, 1500, 2339, 1499, 1191, 2334, 1498, 1495, 2335, 1493,
-     2340, 1490, 2336, 2341, 2220, 2220, 2220, 2342, 2343, 2343,
-     2343, 2225, 2225, 2225, 2227, 2227, 2227, 1487, 2228, 1484,
-     1475, 2229, 1473, 2319, 1218, 1218, 1218, 2231, 2231, 2231,
-     1466, 2232, 1464, 1463, 2233, 1462, 1461, 2330, 2349, 2349,
-     2349, 1460, 1220, 1241, 1241, 1241, 2359, 2359, 2359, 1266,
-     1266, 1266, 1459, 2247, 2247, 2247, 2350, 2248, 1458, 1457,
-     2249, 1243, 2363, 2363, 2363, 1456, 1455, 1268, 1452, 1451,
-
-     2348, 2367, 2367, 2367, 2254, 2254, 2254, 1450, 2255, 2364,
-     1449, 2256, 2369, 2369, 2369, 2262, 2262, 2262, 1448, 2368,
-     2375, 2375, 2375, 1447, 2351, 2265, 2265, 2265, 1446, 2266,
-     2370, 1445, 2267, 2263, 1338, 1338, 1338, 2376, 1444, 2360,
-     2378, 2378, 2378, 2270, 2270, 2270, 1443, 2271, 1442, 1441,
-     2272, 1440, 1340, 3216, 3216, 3216, 1439, 2379, 3216, 3216,
-     3216, 3216, 3216, 3216, 2389, 2389, 2389, 2393, 2393, 2393,
-     3216, 2391, 2391, 2391, 1437, 3216, 1436, 1435, 3216, 1378,
-     1378, 1378, 1434, 1433, 2394, 2377, 2380, 1432, 1431, 2392,
-     1108, 1386, 1386, 1386, 2288, 2288, 2288, 1380, 1396, 1396,
-
-     1396, 1425, 1410, 2398, 2398, 2398, 1409, 2399, 2381, 1388,
-     2400, 2289, 2387, 2401, 2401, 2401, 1398, 1404, 1403, 2382,
-     3216, 3216, 3216, 3216, 3216, 3216, 2405, 2405, 2405, 1402,
-     2402, 2407, 2407, 2407, 1401, 2397, 1400, 3216, 1374, 2395,
-     3216, 1411, 1411, 1411, 2406, 2296, 2296, 2296, 2298, 2298,
-     2298, 1362, 2396, 2301, 2301, 2301, 2303, 2303, 2303, 1413,
-     2412, 2412, 2412, 2297, 1348, 1347, 1108, 2304, 2304, 2304,
-     1346, 2403, 1342, 1337, 2404, 2416, 2416, 2416, 2413, 2308,
-     2308, 2308, 2309, 2309, 2309, 2310, 2310, 2310, 2314, 2314,
-     2314, 2317, 2317, 2317, 2421, 2421, 2421, 1333, 2422, 1325,
-
-     1320, 2423, 1189, 1189, 1189, 1319, 2315, 2408, 2318, 1313,
-     2409, 2343, 2343, 2343, 2452, 2452, 2452, 1218, 1218, 1218,
-     1191, 2349, 2349, 2349, 2455, 2455, 2455, 2461, 2461, 2461,
-     2359, 2359, 2359, 1310, 1289, 1220, 1266, 1266, 1266, 2350,
-     1288, 1287, 2456, 1286, 2462, 1285, 2363, 2363, 2363, 2466,
-     2466, 2466, 1284, 2467, 1268, 1283, 2468, 2470, 2470, 2470,
-     1277, 1270, 2435, 2364, 2367, 2367, 2367, 2369, 2369, 2369,
-     2474, 2474, 2474, 1259, 2471, 2375, 2375, 2375, 1258, 2480,
-     2480, 2480, 2368, 2454, 1257, 2370, 1252, 2475, 2378, 2378,
-     2378, 1251, 2376, 2463, 2477, 2477, 2477, 2481, 2478, 1247,
-
-     1246, 2479, 2482, 2482, 2482, 2379, 2483, 1245, 1240, 2484,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 2490,
-     2490, 2490, 2389, 2389, 2389, 1239, 1234, 3216, 1226, 1222,
-     3216, 1217, 1216, 3216, 1212, 1211, 2491, 2391, 2391, 2391,
-     2393, 2393, 2393, 2494, 2494, 2494, 1210, 2495, 1209, 1208,
-     2496, 2497, 2497, 2497, 1207, 2392, 1206, 2394, 1386, 1386,
-     1386, 1205, 2485, 1396, 1396, 1396, 2398, 2398, 2398, 2498,
-     2399, 2486, 1204, 2400, 2487, 1203, 1388, 2401, 2401, 2401,
-     1202, 1398, 2501, 2501, 2501, 1196, 2502, 1188, 1187, 2503,
-     2504, 2504, 2504, 1186, 2402, 2506, 2506, 2506, 2405, 2405,
-
-     2405, 2407, 2407, 2407, 2508, 2508, 2508, 2505, 2412, 2412,
-     2412, 1185, 2507, 2416, 2416, 2416, 2406, 2518, 2518, 2518,
-     1180, 1179, 2509, 1178, 1175, 2499, 2413, 2500, 2421, 2421,
-     2421, 1169, 2422, 1164, 2519, 2423, 1189, 1189, 1189, 2452,
-     2452, 2452, 1218, 1218, 1218, 2455, 2455, 2455, 2557, 2557,
-     2557, 2461, 2461, 2461, 1191, 2559, 2559, 2559, 1163, 2560,
-     1220, 1159, 2561, 2456, 1154, 2558, 1153, 1152, 2462, 2562,
-     2562, 2562, 2466, 2466, 2466, 1151, 2467, 1150, 1149, 2468,
-     2470, 2470, 2470, 1148, 2567, 2567, 2567, 2563, 2568, 1146,
-     1145, 2569, 2571, 2571, 2571, 1144, 2537, 2471, 2474, 2474,
-
-     2474, 2573, 2573, 2573, 1143, 2574, 1142, 1141, 2575, 2572,
-     2576, 2576, 2576, 2555, 1140, 2475, 2477, 2477, 2477, 1139,
-     2478, 1138, 1137, 2479, 2480, 2480, 2480, 2577, 2482, 2482,
-     2482, 1136, 2483, 1135, 1134, 2484, 3216, 3216, 3216, 3216,
-     3216, 3216, 2481, 3216, 3216, 3216, 2490, 2490, 2490, 1133,
-     2581, 2581, 2581, 3216, 2582, 1132, 3216, 2583, 1131, 1130,
-     3216, 1129, 1128, 2491, 2584, 2584, 2584, 2586, 2586, 2586,
-     2494, 2494, 2494, 1127, 2495, 1120, 1119, 2496, 2497, 2497,
-     2497, 2585, 1118, 1117, 2587, 1386, 1386, 1386, 1116, 1115,
-     2579, 2578, 1396, 1396, 1396, 1114, 2498, 1111, 2580, 1109,
-
-     2501, 2501, 2501, 1388, 2502, 1108, 1106, 2503, 1104, 1101,
-     1398, 2504, 2504, 2504, 2596, 2596, 2596, 1097, 2597, 1095,
-     1094, 2598, 2506, 2506, 2506, 2599, 2599, 2599, 2505, 2600,
-     1093, 1091, 2601, 1090, 2508, 2508, 2508, 1089, 1088, 2507,
-     2606, 2606, 2606, 2518, 2518, 2518, 1189, 1189, 1189, 1087,
-     1086, 2594, 2509, 2595, 2610, 2610, 2610, 1084, 2611, 1083,
-     2519, 2612, 1082, 1081, 1191, 2646, 2646, 2646, 1218, 1218,
-     1218, 2649, 2649, 2649, 2557, 2557, 2557, 2652, 2652, 2652,
-     1079, 2653, 1078, 1077, 2654, 1073, 1220, 1072, 2650, 1070,
-     1069, 2558, 2559, 2559, 2559, 1068, 2560, 2630, 1067, 2561,
-
-     2562, 2562, 2562, 2567, 2567, 2567, 1066, 2568, 1065, 1063,
-     2569, 2571, 2571, 2571, 2606, 2606, 2606, 2651, 2563, 2659,
-     2659, 2659, 1062, 2660, 1061, 1060, 2661, 1058, 2572, 1057,
-     2648, 2573, 2573, 2573, 1056, 2574, 1053, 1052, 2575, 2576,
-     2576, 2576, 2662, 2662, 2662, 1050, 2663, 1047, 1046, 2664,
-     3216, 3216, 3216, 2666, 2666, 2666, 2577, 3216, 3216, 3216,
-     1042, 2581, 2581, 2581, 1041, 2582, 1039, 3216, 2583, 1038,
-     2667, 2584, 2584, 2584, 3216, 2669, 2669, 2669, 1037, 2670,
-     1034, 1033, 2671, 2586, 2586, 2586, 1032, 1031, 2585, 2672,
-     2672, 2672, 1029, 2673, 1028, 1027, 2674, 1386, 1386, 1386,
-
-     2587, 1396, 1396, 1396, 1026, 1025, 2668, 1020, 2665, 2596,
-     2596, 2596, 1018, 2597, 1017, 1388, 2598, 1016, 1015, 1398,
-     2599, 2599, 2599, 1014, 2600, 1013, 1012, 2601, 2689, 2689,
-     2689, 2692, 2692, 2692, 2610, 2610, 2610, 1011, 2611, 1008,
-     1005, 2612, 2703, 2703, 2703, 2690, 1634, 1004, 2681, 1189,
-     1189, 1189, 2646, 2646, 2646, 2729, 2729, 2729, 1003, 2704,
-     1218, 1218, 1218, 2649, 2649, 2649,  997, 1191, 2682, 2731,
-     2731, 2731,  994, 2732,  992,  991, 2733,  986, 1220,  985,
-     2650, 2652, 2652, 2652,  983, 2653,  982,  981, 2654, 2659,
-     2659, 2659,  979, 2660,  976,  974, 2661,  971, 2713, 2662,
-
-     2662, 2662,  970, 2663,  968,  967, 2664, 3216, 3216, 3216,
-      964, 2730, 2666, 2666, 2666, 2740, 2740, 2740,  959, 2741,
-      958,  956, 2742,  955, 3216, 3216, 3216, 3216,  952, 2667,
-     2669, 2669, 2669,  951, 2670,  949,  946, 2671,  944, 2672,
-     2672, 2672, 3216, 2673,  943,  942, 2674, 2758, 2758, 2758,
-     1396, 1396, 1396, 2766, 2766, 2766,  940,  938, 2739, 2689,
-     2689, 2689, 2768, 2768, 2768, 2759, 2769,  937, 1398, 2770,
-     2767, 1634, 2771, 2771, 2771,  936, 2690, 1634,  935,  934,
-     1634, 2692, 2692, 2692, 2772, 2772, 2772, 2773, 2773, 2773,
-     2703, 2703, 2703, 2782, 2782, 2782, 2743, 2783,  933,  930,
-
-     2784, 1189, 1189, 1189, 2802, 2802, 2802, 2704, 2729, 2729,
-     2729, 2803, 2803, 2803,  929,  928, 2760,  925,  922, 1191,
-     2731, 2731, 2731,  921, 2732,  919,  918, 2733,  915, 2804,
-     2808, 2808, 2808, 2811, 2811, 2811, 2740, 2740, 2740,  912,
-     2741,  909,  908, 2742, 2813, 2813, 2813, 2809,  900,  899,
-     2812, 2758, 2758, 2758, 1396, 1396, 1396, 2766, 2766, 2766,
-      898, 2814,  892,  891, 2833, 2833, 2833, 2791, 2834, 2759,
-      890, 2835, 1398,  888, 2767, 1634, 2768, 2768, 2768,  887,
-     2769,  886, 1634, 2770, 2771, 2771, 2771, 2772, 2772, 2772,
-     2773, 2773, 2773,  885, 1634, 2782, 2782, 2782,  884, 2783,
-
-      883,  878, 2784,  875,  877, 2827, 1632, 1632, 1632, 1632,
-     1632, 1632, 1632, 1632, 1632,  872,  871, 1632, 2852, 2852,
-     2852,  869, 1632, 1632, 1632, 1634, 1632, 2802, 2802, 2802,
-     2803, 2803, 2803, 2808, 2808, 2808, 2853, 2865, 2865, 2865,
-      867, 2866,  865,  863, 2867, 2811, 2811, 2811, 2804,  861,
-     2809, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632,
-     1632, 1632, 2812, 3216, 1632, 2813, 2813, 2813,  858, 1632,
-     1632, 1632, 1634, 1632, 2869, 2869, 2869,  857, 2870,  856,
-      855, 2871, 2814, 2872, 2872, 2872,  854, 2873,  852,  851,
-     2874, 2887, 2887, 2887, 2852, 2852, 2852,  850, 1632, 1632,
-
-     2833, 2833, 2833,  849, 2834,  848,  846, 2835,  845, 2888,
-      844,  843, 2853, 2887, 2887, 2887,  841,  839, 1634, 1632,
-     1632, 1632, 1632, 1632, 2899, 1632, 1632, 1632,  838,  836,
-     1632, 2888,  835,  832,  831, 1632, 1632, 1632, 1634, 1632,
-     2865, 2865, 2865,  829, 2866,  663, 3216, 2867, 2869, 2869,
-     2869,  824, 2870,  822,  818, 2871, 2872, 2872, 2872,  817,
-     2873,  816,  814, 2874, 1632, 1632, 1632, 1632, 1632, 1632,
-     1632, 1632, 1632, 1632, 2899,  812,  811, 1632, 2938, 2938,
-     2938,  810, 1632, 1632, 1632, 1634, 1632, 2949, 2949, 2949,
-     2951, 2951, 2951, 2953, 2953, 2953, 1634, 1635, 2961, 2961,
-
-     2961, 2971, 2971, 2971, 2950,  808,  806, 2952,  805,  803,
-     2954, 1632, 1632,  801,  800, 2962, 2938, 2938, 2938, 1108,
-     2949, 2949, 2949, 2981, 2981, 2981,  799, 2982,  798,  797,
-     2983, 2951, 2951, 2951, 1634,  796,  795, 2950, 2984, 2984,
-     2984,  793, 2985,  791,  790, 2986,  787,  786, 2952, 2953,
-     2953, 2953, 2987, 2987, 2987,  785, 2988,  783,  774, 2989,
-     2961, 2961, 2961, 2971, 2971, 2971, 2954, 1822, 2996, 2996,
-     2996,  773, 2997,  772,  769, 2998,  767, 2962, 2981, 2981,
-     2981, 1108, 2982,  765,  764, 2983, 2984, 2984, 2984,  763,
-     2985,  761, 3216, 2986, 2987, 2987, 2987,  758, 2988,  757,
-
-     3007, 2989, 2996, 2996, 2996,  756, 2997,  755,  754, 2998,
-     3112, 3112, 3112, 3112, 3112, 3112,  752, 3121,  750,  749,
-     3122, 3214, 3214, 3214, 3214, 3214, 3214,  747, 1108,  745,
-      744, 1108,  742,  740,  739,  738,  736,  734,  733, 3215,
-      732,  731, 3215,  250,  250,  250,  250,  250,  250,  250,
-      250,  250,  251,  251,  251,  251,  251,  251,  251,  251,
-      251,  256,  256,  256,  256,  256,  256,  256,  256,  256,
-      259,  259,  259,  259,  259,  259,  259,  259,  259,  262,
-      262,  262,  262,  262,  262,  262,  262,  262,  265,  265,
-      265,  265,  265,  265,  265,  265,  265,  272,  272,  272,
-
-      272,  272,  272,  272,  272,  272,  280,  280,  280,  280,
-      280,  280,  280,  280,  280,  284,  284,  284,  284,  284,
-      284,  284,  284,  284,  296,  296,  296,  296,  296,  296,
-      296,  296,  296,  300,  300,  300,  300,  300,  300,  300,
-      300,  300,  307,  307,  307,  307,  307,  307,  307,  307,
-      307,  318,  318,  318,  318,  318,  318,  318,  318,  318,
-      326,  326,  326,  326,  326,  326,  326,  326,  326,  334,
-      334,  334,  334,  334,  334,  334,  334,  334,  340,  340,
-      340,  340,  340,  340,  340,  340,  340,  346,  346,  346,
-      346,  346,  346,  346,  346,  346,  351,  351,  351,  351,
-
-      351,  351,  351,  351,  351,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  375,  375,  375,  375,  375,  375,
-      375,  375,  375,  382,  382,  382,  382,  382,  382,  382,
-      382,  382,  388,  388,  388,  388,  388,  388,  388,  388,
-      388,  395,  395,  395,  395,  395,  395,  395,  395,  395,
-      400,  400,  400,  400,  400,  400,  400,  400,  400,  406,
-      406,  406,  406,  406,  406,  406,  406,  406,  411,  411,
-      411,  411,  411,  411,  411,  411,  411,  417,  417,  417,
-      417,  417,  417,  417,  417,  417,  425,  425,  425,  425,
-      425,  425,  425,  425,  425,  433,  433,  433,  433,  433,
-
-      433,  433,  433,  433,  439,  439,  439,  439,  439,  439,
-      439,  439,  439,  456,  456,  456,  456,  456,  456,  456,
-      456,  456,  462,  462,  462,  462,  462,  462,  462,  462,
-      462,  471,  471,  471,  471,  471,  471,  471,  471,  471,
-      477,  477,  477,  477,  477,  477,  477,  477,  477,  487,
-      487,  487,  487,  487,  487,  487,  487,  487,  493,  493,
-      493,  493,  493,  493,  493,  493,  493,  498,  498,  498,
-      498,  498,  498,  498,  498,  498,  504,  504,  504,  504,
-      504,  504,  504,  504,  504,  510,  510,  510,  510,  510,
-      510,  510,  510,  510,  516,  516,  516,  516,  516,  516,
-
-      516,  516,  516,  523,  523,  523,  523,  523,  523,  523,
-      523,  523,  530,  530,  530,  530,  530,  530,  530,  530,
-      530,  535,  535,  535,  535,  535,  535,  535,  535,  535,
-      543,  543,  543,  543,  543,  543,  543,  543,  543,  549,
-      549,  549,  549,  549,  549,  549,  549,  549,  556,  556,
-      556,  556,  556,  556,  556,  556,  556,  561,  561,  561,
-      561,  561,  561,  561,  561,  561,  567,  567,  567,  567,
-      567,  567,  567,  567,  567,  572,  572,  572,  572,  572,
-      572,  572,  572,  572,  579,  579,  579,  579,  579,  579,
-      579,  579,  579,  585,  585,  585,  585,  585,  585,  585,
-
-      585,  585,  592,  592,  592,  592,  592,  592,  592,  592,
-      592,  600,  600,  600,  600,  600,  600,  600,  600,  600,
-      608,  608,  608,  608,  608,  608,  608,  608,  608,  612,
-      612,  612,  612,  612,  612,  612,  612,  612,  618,  618,
-      618,  618,  618,  618,  618,  618,  618,  622,  622,  622,
-      622,  622,  622,  622,  622,  622,  629,  629,  629,  629,
-      629,  629,  629,  629,  629,  634,  634,  634,  634,  634,
-      634,  634,  634,  634,  654,  654,  654,  729, 3216, 3216,
-      654,  680,  680,  680,  712,  711,  709,  680,  684,  684,
-      684,  707,  706,  705,  684,  692,  692,  692,  703,  698,
-
-      694,  692,  704,  704,  704,  693,  691,  690,  704,  710,
-      710,  710,  687,  686,  685,  710,  730,  730,  730,  683,
-      682,  681,  730,  737,  737,  737,  679,  674, 3216,  737,
-      743,  743,  743,  655,  653,  651,  743,  748,  748,  748,
-      645,  644,  645,  748,  753,  753,  753,  644,  643,  642,
-      753,  762,  762,  762, 3216, 3216, 3216,  762,  768,  768,
-      768, 3216, 3216, 3216,  768,  784,  784,  784, 3216, 3216,
-     3216,  784,  794,  794,  794, 3216, 3216, 3216,  794,  804,
-      804,  804, 3216, 3216, 3216,  804,  809,  809,  809, 3216,
-     3216, 3216,  809,  815,  815,  815, 3216, 3216, 3216,  815,
-
-      823,  823,  823, 3216, 3216, 3216,  823,  830,  830,  830,
-     3216, 3216, 3216,  830,  837,  837,  837, 3216, 3216, 3216,
-      837,  842,  842,  842, 3216, 3216, 3216,  842,  847,  847,
-      847, 3216, 3216, 3216,  847,  853,  853,  853, 3216, 3216,
-     3216,  853,  862,  862,  862, 3216, 3216, 3216,  862,  866,
-      866,  866, 3216, 3216, 3216,  866,  870,  870,  870, 3216,
-     3216, 3216,  870,  874,  874,  874,  874,  874,  874,  874,
-     3216,  874,  654,  654,  654, 3216, 3216, 3216,  654,  889,
-     3216, 3216, 3216,  889,  680,  680,  680, 3216, 3216, 3216,
-      680,  920, 3216, 3216, 3216,  920,  684,  684,  684, 3216,
-
-     3216, 3216,  684,  927, 3216, 3216, 3216,  927,  692,  692,
-      692, 3216, 3216, 3216,  692,  939, 3216, 3216, 3216,  939,
-      704,  704,  704, 3216, 3216, 3216,  704,  945, 3216, 3216,
-     3216,  945,  710,  710,  710, 3216, 3216, 3216,  710,  950,
-     3216, 3216, 3216,  950,  730,  730,  730, 3216, 3216, 3216,
-      730,  969, 3216, 3216, 3216,  969,  737,  737,  737, 3216,
-     3216, 3216,  737,  975, 3216, 3216, 3216,  975,  743,  743,
-      743, 3216, 3216, 3216,  743,  980, 3216, 3216, 3216,  980,
-      748,  748,  748, 3216, 3216, 3216,  748,  984, 3216, 3216,
-     3216,  984,  753,  753,  753, 3216, 3216, 3216,  753,  993,
-
-     3216, 3216, 3216,  993,  762,  762,  762, 3216, 3216, 3216,
-      762, 1002, 3216, 3216, 3216, 1002,  768,  768,  768, 3216,
-     3216, 3216,  768, 1019, 3216, 3216, 3216, 1019,  784,  784,
-      784, 3216, 3216, 3216,  784, 1030, 3216, 3216, 3216, 1030,
-      794,  794,  794, 3216, 3216, 3216,  794, 1040, 3216, 3216,
-     3216, 1040,  804,  804,  804, 3216, 3216, 3216,  804, 1045,
-     3216, 3216, 3216, 1045,  809,  809,  809, 3216, 3216, 3216,
-      809, 1051, 3216, 3216, 3216, 1051,  815,  815,  815, 3216,
-     3216, 3216,  815, 1059, 3216, 3216, 3216, 1059,  823,  823,
-      823, 3216, 3216, 3216,  823, 1064, 3216, 3216, 3216, 1064,
-
-      830,  830,  830, 3216, 3216, 3216,  830, 1071, 3216, 3216,
-     3216, 1071,  837,  837,  837, 3216, 3216, 3216,  837, 1076,
-     3216, 3216, 3216, 1076,  842,  842,  842, 3216, 3216, 3216,
-      842, 1080, 3216, 3216, 3216, 1080,  847,  847,  847, 3216,
-     3216, 3216,  847, 1085, 3216, 3216, 3216, 1085,  853,  853,
-      853, 3216, 3216, 3216,  853, 1092, 3216, 3216, 3216, 1092,
-      862,  862,  862, 3216, 3216, 3216,  862, 1096, 3216, 3216,
-     3216, 1096,  866,  866,  866, 3216, 3216, 3216,  866, 1100,
-     3216, 3216, 3216, 1100,  870,  870,  870, 3216, 3216, 3216,
-      870, 1105, 3216, 3216, 3216, 1105, 1107, 1107, 1107, 1107,
-
-     1107, 1107, 1107, 1107, 1107, 1113, 3216, 3216, 3216, 3216,
-     1113,  654,  654,  654, 3216, 3216, 3216,  654, 1122, 1122,
-     1122, 1122, 3216, 3216, 1122, 1122,  680,  680,  680, 3216,
-     3216, 3216,  680, 1156, 1156, 1156, 1156, 3216, 3216, 1156,
-     1156,  684,  684,  684, 3216, 3216, 3216,  684, 1166, 1166,
-     1166, 1166, 3216, 3216, 1166, 1166,  692,  692,  692, 3216,
-     3216, 3216,  692, 1182, 1182, 1182, 1182, 3216, 3216, 1182,
-     1182,  704,  704,  704, 3216, 3216, 3216,  704, 1190, 1190,
-     1190, 1190, 3216, 3216, 1190, 1190,  710,  710,  710, 3216,
-     3216, 3216,  710, 1198, 1198, 1198, 1198, 3216, 3216, 1198,
-
-     1198,  730,  730,  730, 3216, 3216, 3216,  730, 1219, 1219,
-     1219, 1219, 3216, 3216, 1219, 1219,  737,  737,  737, 3216,
-     3216, 3216,  737, 1228, 1228, 1228, 1228, 3216, 3216, 1228,
-     1228,  743,  743,  743, 3216, 3216, 3216,  743, 1236, 1236,
-     1236, 1236, 3216, 3216, 1236, 1236,  748,  748,  748, 3216,
-     3216, 3216,  748, 1242, 1242, 1242, 1242, 3216, 3216, 1242,
-     1242,  753,  753,  753, 3216, 3216, 3216,  753, 1254, 1254,
-     1254, 1254, 3216, 3216, 1254, 1254,  762,  762,  762, 3216,
-     3216, 3216,  762, 1267, 1267, 1267, 1267, 3216, 3216, 1267,
-     1267,  768,  768,  768, 3216, 3216, 3216,  768, 1291, 1291,
-
-     1291, 1291, 3216, 3216, 1291, 1291,  784,  784,  784,  784,
-     3216,  784, 3216,  784, 1307, 1307, 1307, 1307, 3216, 3216,
-     1307, 1307,  794,  794,  794, 3216, 3216, 3216,  794, 1322,
-     1322, 1322, 1322, 3216, 3216, 1322, 1322,  804,  804,  804,
-     3216, 3216, 3216,  804, 1330, 1330, 1330, 1330, 3216, 3216,
-     1330, 1330,  809,  809,  809, 3216, 3216, 3216,  809, 1339,
-     1339, 1339, 1339, 3216, 3216, 1339, 1339,  815,  815,  815,
-     3216, 3216, 3216,  815, 1350, 1350, 1350, 1350, 3216, 3216,
-     1350, 1350,  823,  823,  823,  823, 3216,  823, 3216,  823,
-     1359, 1359, 1359, 1359, 3216, 3216, 1359, 1359,  830,  830,
-
-      830,  830, 3216,  830, 3216,  830, 1371, 1371, 1371, 1371,
-     3216, 3216, 1371, 1371,  837,  837,  837, 3216, 3216, 3216,
-      837, 1379, 1379, 1379, 1379, 3216, 3216, 1379, 1379,  842,
-      842,  842,  842, 3216,  842, 3216,  842, 1387, 1387, 1387,
-     1387, 3216, 3216, 1387, 1387,  847,  847,  847,  847, 3216,
-      847, 3216,  847, 1397, 1397, 1397, 1397, 3216, 3216, 1397,
-     1397,  853,  853,  853, 3216, 3216, 3216,  853, 1406, 1406,
-     1406, 1406, 3216, 3216, 1406, 1406,  862,  862,  862, 3216,
-     3216, 3216,  862, 1412, 1412, 1412, 1412, 3216, 3216, 1412,
-     1412, 1419, 1419, 1419, 1419, 3216, 3216, 1419, 1419,  870,
-
-      870,  870, 3216, 3216, 3216,  870, 1427, 1427, 1427, 1427,
-     3216, 3216, 1427, 1427, 1107, 1107, 1107, 1107, 1107, 1107,
-     1107, 1107, 1107, 1113, 3216, 1113, 3216, 3216, 1113,  654,
-      654,  654, 3216, 3216, 3216,  654, 1122, 1122, 1122, 1122,
-     3216, 3216, 1122, 1122,  680,  680,  680,  680, 3216,  680,
-     3216,  680, 1156, 1156, 1156, 1156, 3216, 3216, 1156, 1156,
-      684,  684,  684,  684, 3216,  684, 3216,  684, 1166, 1166,
-     1166, 1166, 3216, 3216, 1166, 1166,  692,  692,  692, 3216,
-     3216, 3216,  692, 1182, 1182, 1182, 1182, 3216, 3216, 1182,
-     1182,  704,  704,  704, 3216, 3216, 3216,  704, 1190, 1190,
-
-     1190, 1190, 3216, 3216, 1190, 1190,  710,  710,  710, 3216,
-     3216, 3216,  710, 1198, 1198, 1198, 1198, 3216, 3216, 1198,
-     1198,  730,  730,  730, 3216, 3216, 3216,  730, 1219, 1219,
-     1219, 1219, 3216, 3216, 1219, 1219,  737,  737,  737, 3216,
-     3216, 3216,  737, 1228, 1228, 1228, 1228, 3216, 3216, 1228,
-     1228,  743,  743,  743,  743, 3216,  743, 3216,  743, 1236,
-     1236, 1236, 1236, 3216, 3216, 1236, 1236,  748,  748,  748,
-      748, 3216,  748, 3216,  748, 1242, 1242, 1242, 1242, 3216,
-     3216, 1242, 1242,  753,  753,  753, 3216, 3216, 3216,  753,
-     1254, 1254, 1254, 1254, 3216, 3216, 1254, 1254,  762,  762,
-
-      762,  762, 3216,  762, 3216,  762, 1267, 1267, 1267, 1267,
-     3216, 3216, 1267, 1267,  768,  768,  768, 3216, 3216, 3216,
-      768, 1291, 1291, 1291, 1291, 3216, 3216, 1291, 1291,  784,
-      784,  784, 3216, 3216, 3216,  784, 1307, 1307, 1307, 1307,
-     3216, 3216, 1307, 1307,  794,  794,  794, 3216, 3216, 3216,
-      794, 1322, 1322, 1322, 1322, 3216, 3216, 1322, 1322,  804,
-      804,  804, 3216, 3216, 3216,  804, 1330, 1330, 1330, 1330,
-     3216, 3216, 1330, 1330,  809,  809,  809, 3216, 3216, 3216,
-      809, 1339, 1339, 1339, 1339, 3216, 3216, 1339, 1339,  815,
-      815,  815, 3216, 3216, 3216,  815, 1350, 1350, 1350, 1350,
-
-     3216, 3216, 1350, 1350,  823,  823,  823, 3216, 3216, 3216,
-      823, 1359, 1359, 1359, 1359, 3216, 3216, 1359, 1359,  830,
-      830,  830, 3216, 3216, 3216,  830, 1371, 1371, 1371, 1371,
-     3216, 3216, 1371, 1371,  837,  837,  837, 3216, 3216, 3216,
-      837, 1379, 1379, 1379, 1379, 3216, 3216, 1379, 1379, 1387,
-     1387, 1387, 1387, 3216, 3216, 1387, 1387,  847,  847,  847,
-     3216, 3216, 3216,  847, 1397, 1397, 1397, 1397, 3216, 3216,
-     1397, 1397,  853,  853,  853, 3216, 3216, 3216,  853, 1406,
-     1406, 1406, 1406, 3216, 3216, 1406, 1406,  862,  862,  862,
-     3216, 3216, 3216,  862, 1412, 1412, 1412, 1412, 3216, 3216,
-
-     1412, 1412, 1419, 1419, 1419, 1419, 3216, 3216, 1419, 1419,
-      870,  870,  870, 3216, 3216, 3216,  870, 1427, 1427, 1427,
-     1427, 3216, 3216, 1427, 1427, 1107, 1107, 1107, 1107, 1107,
-     1107, 1107, 1107, 1107, 1632, 1632, 1632, 1632, 1632, 1632,
-     1632, 1632, 1632,  654,  654,  654, 3216, 3216, 3216,  654,
-     1122, 1122, 1122, 1122, 3216, 3216, 1122, 1122, 1156, 1156,
-     1156, 1156, 3216, 3216, 1156, 1156,  684,  684,  684, 3216,
-     3216, 3216,  684, 1166, 1166, 1166, 1166, 3216, 3216, 1166,
-     1166,  692,  692,  692, 3216, 3216, 3216,  692, 1182, 1182,
-     1182, 1182, 3216, 3216, 1182, 1182,  704,  704,  704, 3216,
-
-     3216, 3216,  704, 1190, 1190, 1190, 1190, 3216, 3216, 1190,
-     1190,  710,  710,  710, 3216, 3216, 3216,  710,  730,  730,
-      730, 3216, 3216, 3216,  730, 1219, 1219, 1219, 1219, 3216,
-     3216, 1219, 1219,  737,  737,  737, 3216, 3216, 3216,  737,
-     1228, 1228, 1228, 1228, 3216, 3216, 1228, 1228, 1236, 1236,
-     1236, 1236, 3216, 3216, 1236, 1236,  748,  748,  748, 3216,
-     3216, 3216,  748, 1242, 1242, 1242, 1242, 3216, 3216, 1242,
-     1242,  753,  753,  753, 3216, 3216, 3216,  753, 1254, 1254,
-     1254, 1254, 3216, 3216, 1254, 1254, 1267, 1267, 1267, 1267,
-     3216, 3216, 1267, 1267,  768,  768,  768, 3216, 3216, 3216,
-
-      768, 1291, 1291, 1291, 1291, 3216, 3216, 1291, 1291,  784,
-      784,  784,  784, 3216,  784, 3216,  784, 1307, 1307, 1307,
-     1307, 3216, 3216, 1307, 1307,  794,  794,  794, 3216, 3216,
-     3216,  794, 1322, 1322, 1322, 1322, 3216, 3216, 1322, 1322,
-      804,  804,  804, 3216, 3216, 3216,  804, 1330, 1330, 1330,
-     1330, 3216, 3216, 1330, 1330,  809,  809,  809, 3216, 3216,
-     3216,  809, 1339, 1339, 1339, 1339, 3216, 3216, 1339, 1339,
-      815,  815,  815, 3216, 3216, 3216,  815, 1350, 1350, 1350,
-     1350, 3216, 3216, 1350, 1350,  823,  823,  823, 3216, 3216,
-     3216,  823, 1359, 1359, 1359, 1359, 3216, 3216, 1359, 1359,
-
-      830,  830,  830, 3216, 3216, 3216,  830, 1371, 1371, 1371,
-     1371, 3216, 3216, 1371, 1371,  837,  837,  837, 3216, 3216,
-     3216,  837, 1379, 1379, 1379, 1379, 3216, 3216, 1379, 1379,
-     1387, 1387, 1387, 1387, 3216, 3216, 1387, 1387,  847,  847,
-      847, 3216, 3216, 3216,  847, 1397, 1397, 1397, 1397, 3216,
-     3216, 1397, 1397,  853,  853,  853, 3216, 3216, 3216,  853,
-     1406, 1406, 1406, 1406, 3216, 3216, 1406, 1406,  862,  862,
-      862,  862, 3216,  862, 3216,  862, 1412, 1412, 1412, 1412,
-     3216, 3216, 1412, 1412, 1419, 1419, 1419, 1419, 3216, 3216,
-     1419, 1419,  870,  870,  870,  870, 3216,  870, 3216,  870,
-
-     1427, 1427, 1427, 1427, 3216, 3216, 1427, 1427, 1107, 1107,
-     1107, 1107, 1107, 1107, 1107, 1107, 1107, 1632, 1632, 1632,
-     1632, 1632, 1632, 1632, 1632, 1632,  654,  654,  654, 3216,
-     3216, 3216,  654, 1122, 1122, 1122, 1122, 3216, 3216, 1122,
-     1122, 1156, 1156, 1156, 1156, 3216, 3216, 1156, 1156,  684,
-      684,  684, 3216, 3216, 3216,  684, 1166, 1166, 1166, 1166,
-     3216, 3216, 1166, 1166,  692,  692,  692, 3216, 3216, 3216,
-      692, 1182, 1182, 1182, 1182, 3216, 3216, 1182, 1182,  704,
-      704,  704, 3216, 3216, 3216,  704, 1190, 1190, 1190, 1190,
-     3216, 3216, 1190, 1190,  710,  710,  710, 3216, 3216, 3216,
-
-      710,  730,  730,  730, 3216, 3216, 3216,  730, 1219, 1219,
-     1219, 1219, 3216, 3216, 1219, 1219,  737,  737,  737, 3216,
-     3216, 3216,  737, 1228, 1228, 1228, 1228, 3216, 3216, 1228,
-     1228, 1236, 1236, 1236, 1236, 3216, 3216, 1236, 1236,  748,
-      748,  748,  748, 3216,  748, 3216,  748, 1242, 1242, 1242,
-     1242, 3216, 3216, 1242, 1242,  753,  753,  753, 3216, 3216,
-     3216,  753, 1254, 1254, 1254, 1254, 3216, 3216, 1254, 1254,
-     1267, 1267, 1267, 1267, 3216, 3216, 1267, 1267,  768,  768,
-      768, 3216, 3216, 3216,  768, 1291, 1291, 1291, 1291, 3216,
-     3216, 1291, 1291,  784,  784,  784,  784, 3216,  784, 3216,
-
-      784, 1307, 1307, 1307, 1307, 3216, 3216, 1307, 1307,  794,
-      794,  794, 3216, 3216, 3216,  794, 1322, 1322, 1322, 1322,
-     3216, 3216, 1322, 1322,  804,  804,  804, 3216, 3216, 3216,
-      804, 1330, 1330, 1330, 1330, 3216, 3216, 1330, 1330,  809,
-      809,  809, 3216, 3216, 3216,  809, 1339, 1339, 1339, 1339,
-     3216, 3216, 1339, 1339,  815,  815,  815, 3216, 3216, 3216,
-      815, 1350, 1350, 1350, 1350, 3216, 3216, 1350, 1350,  823,
-      823,  823, 3216, 3216, 3216,  823, 1359, 1359, 1359, 1359,
-     3216, 3216, 1359, 1359,  830,  830,  830,  830, 3216,  830,
-     3216,  830, 1371, 1371, 1371, 1371, 3216, 3216, 1371, 1371,
-
-      837,  837,  837, 3216, 3216, 3216,  837, 1379, 1379, 1379,
-     1379, 3216, 3216, 1379, 1379, 1387, 1387, 1387, 1387, 3216,
-     3216, 1387, 1387,  847,  847,  847,  847, 3216,  847, 3216,
-      847, 1397, 1397, 1397, 1397, 3216, 3216, 1397, 1397,  853,
-      853,  853, 3216, 3216, 3216,  853, 1406, 1406, 1406, 1406,
-     3216, 3216, 1406, 1406, 1412, 1412, 1412, 1412, 3216, 3216,
-     1412, 1412, 1419, 1419, 1419, 1419, 3216, 3216, 1419, 1419,
-     1427, 1427, 1427, 1427, 3216, 3216, 1427, 1427, 1107, 1107,
-     1107, 1107, 1107, 1107, 1107, 1107, 1107, 1632, 1632, 1632,
-     1632, 1632, 1632, 1632, 1632, 1632,  654,  654,  654,  654,
-
-     3216,  654, 3216,  654, 1122, 1122, 1122, 1122, 3216, 3216,
-     1122, 1122, 1156, 1156, 1156, 1156, 3216, 3216, 1156, 1156,
-      684,  684,  684, 3216, 3216, 3216,  684, 1166, 1166, 1166,
-     1166, 3216, 3216, 1166, 1166,  692,  692,  692, 3216, 3216,
-     3216,  692, 1182, 1182, 1182, 1182, 3216, 3216, 1182, 1182,
-      704,  704,  704,  704, 3216,  704, 3216,  704, 1190, 1190,
-     1190, 1190, 3216, 3216, 1190, 1190,  710,  710,  710,  710,
-     3216,  710, 3216,  710,  730,  730,  730,  730, 3216,  730,
-     3216,  730, 1219, 1219, 1219, 1219, 3216, 3216, 1219, 1219,
-      737,  737,  737,  737, 3216,  737, 3216,  737, 1228, 1228,
-
-     1228, 1228, 3216, 3216, 1228, 1228, 1236, 1236, 1236, 1236,
-     3216, 3216, 1236, 1236, 1242, 1242, 1242, 1242, 3216, 3216,
-     1242, 1242,  753,  753,  753, 3216, 3216, 3216,  753, 1267,
-     1267, 1267, 1267, 3216, 3216, 1267, 1267,  768,  768,  768,
-     3216, 3216, 3216,  768, 1291, 1291, 1291, 1291, 3216, 3216,
-     1291, 1291,  784,  784,  784,  784, 3216,  784, 3216,  784,
-     1307, 1307, 1307, 1307, 3216, 3216, 1307, 1307,  794,  794,
-      794, 3216, 3216, 3216,  794,  804,  804,  804, 3216, 3216,
-     3216,  804, 1330, 1330, 1330, 1330, 3216, 3216, 1330, 1330,
-      809,  809,  809, 3216, 3216, 3216,  809, 1339, 1339, 1339,
-
-     1339, 3216, 3216, 1339, 1339,  815,  815,  815, 3216, 3216,
-     3216,  815,  823,  823,  823, 3216, 3216, 3216,  823, 1359,
-     1359, 1359, 1359, 3216, 3216, 1359, 1359,  830,  830,  830,
-     3216, 3216, 3216,  830, 1371, 1371, 1371, 1371, 3216, 3216,
-     1371, 1371,  837,  837,  837, 3216, 3216, 3216,  837, 1379,
-     1379, 1379, 1379, 3216, 3216, 1379, 1379, 1387, 1387, 1387,
-     1387, 3216, 3216, 1387, 1387, 1397, 1397, 1397, 1397, 3216,
-     3216, 1397, 1397,  853,  853,  853, 3216, 3216, 3216,  853,
-     1406, 1406, 1406, 1406, 3216, 3216, 1406, 1406, 1412, 1412,
-     1412, 1412, 3216, 3216, 1412, 1412, 1419, 1419, 1419, 1419,
-
-     3216, 3216, 1419, 1419, 1107, 1107, 1107, 1107, 1107, 1107,
-     1107, 1107, 1107, 1632, 1632, 1632, 1632, 1632, 1632, 1632,
-     1632, 1632, 1122, 1122, 1122, 1122, 3216, 3216, 1122, 1122,
-     1156, 1156, 1156, 1156, 3216, 3216, 1156, 1156,  684,  684,
-      684, 3216, 3216, 3216,  684,  692,  692,  692, 3216, 3216,
-     3216,  692, 1182, 1182, 1182, 1182, 3216, 3216, 1182, 1182,
-     1190, 1190, 1190, 1190, 3216, 3216, 1190, 1190, 1219, 1219,
-     1219, 1219, 3216, 3216, 1219, 1219, 1228, 1228, 1228, 1228,
-     3216, 3216, 1228, 1228, 1242, 1242, 1242, 1242, 3216, 3216,
-     1242, 1242,  753,  753,  753, 3216, 3216, 3216,  753, 1267,
-
-     1267, 1267, 1267, 3216, 3216, 1267, 1267,  768,  768,  768,
-     3216, 3216, 3216,  768, 1291, 1291, 1291, 1291, 3216, 3216,
-     1291, 1291, 1307, 1307, 1307, 1307, 3216, 3216, 1307, 1307,
-      794,  794,  794, 3216, 3216, 3216,  794,  804,  804,  804,
-     3216, 3216, 3216,  804, 1330, 1330, 1330, 1330, 3216, 3216,
-     1330, 1330,  809,  809,  809, 3216, 3216, 3216,  809, 1339,
-     1339, 1339, 1339, 3216, 3216, 1339, 1339,  815,  815,  815,
-     3216, 3216, 3216,  815,  823,  823,  823, 3216, 3216, 3216,
-      823,  830,  830,  830, 3216, 3216, 3216,  830, 1371, 1371,
-     1371, 1371, 3216, 3216, 1371, 1371,  837,  837,  837, 3216,
-
-     3216, 3216,  837, 1379, 1379, 1379, 1379, 3216, 3216, 1379,
-     1379, 1387, 1387, 1387, 1387, 3216, 3216, 1387, 1387, 1397,
-     1397, 1397, 1397, 3216, 3216, 1397, 1397,  853,  853,  853,
-      853, 3216,  853, 3216,  853, 1406, 1406, 1406, 1406, 3216,
-     3216, 1406, 1406, 1412, 1412, 1412, 1412, 3216, 3216, 1412,
-     1412, 1419, 1419, 1419, 1419, 3216, 3216, 1419, 1419, 1107,
-     1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1632, 1632,
-     1632, 1632, 1632, 1632, 1632, 1632, 1632, 1122, 1122, 1122,
-     1122, 3216, 3216, 1122, 1122, 1156, 1156, 1156, 1156, 3216,
-     3216, 1156, 1156,  684,  684,  684, 3216, 3216, 3216,  684,
-
-      692,  692,  692,  692, 3216,  692, 3216,  692, 1190, 1190,
-     1190, 1190, 3216, 3216, 1190, 1190, 1219, 1219, 1219, 1219,
-     3216, 3216, 1219, 1219, 1228, 1228, 1228, 1228, 3216, 3216,
-     1228, 1228, 1242, 1242, 1242, 1242, 3216, 3216, 1242, 1242,
-      753,  753,  753, 3216, 3216, 3216,  753, 1267, 1267, 1267,
-     1267, 3216, 3216, 1267, 1267,  768,  768,  768, 3216, 3216,
-     3216,  768, 1291, 1291, 1291, 1291, 3216, 3216, 1291, 1291,
-     1307, 1307, 1307, 1307, 3216, 3216, 1307, 1307,  794,  794,
-      794, 3216, 3216, 3216,  794,  804,  804,  804, 3216, 3216,
-     3216,  804,  809,  809,  809,  809, 3216,  809, 3216,  809,
-
-     1339, 1339, 1339, 1339, 3216, 3216, 1339, 1339,  815,  815,
-      815,  815, 3216,  815, 3216,  815,  823,  823,  823, 3216,
-     3216, 3216,  823,  830,  830,  830, 3216, 3216, 3216,  830,
-     1371, 1371, 1371, 1371, 3216, 3216, 1371, 1371,  837,  837,
-      837,  837, 3216,  837, 3216,  837, 1379, 1379, 1379, 1379,
-     3216, 3216, 1379, 1379, 1387, 1387, 1387, 1387, 3216, 3216,
-     1387, 1387, 1397, 1397, 1397, 1397, 3216, 3216, 1397, 1397,
-      853,  853,  853,  853, 3216,  853, 3216,  853, 1406, 1406,
-     1406, 1406, 3216, 3216, 1406, 1406, 1412, 1412, 1412, 1412,
-     3216, 3216, 1412, 1412, 1107, 1107, 1107, 1107, 1107, 1107,
-
-     1107, 1107, 1107, 1632, 1632, 1632, 1632, 1632, 1632, 1632,
-     1632, 1632, 1122, 1122, 1122, 1122, 3216, 3216, 1122, 1122,
-      684,  684,  684, 3216, 3216, 3216,  684,  692,  692,  692,
-     3216, 3216, 3216,  692, 1190, 1190, 1190, 1190, 3216, 3216,
-     1190, 1190, 1219, 1219, 1219, 1219, 3216, 3216, 1219, 1219,
-     1242, 1242, 1242, 1242, 3216, 3216, 1242, 1242,  753,  753,
-      753, 3216, 3216, 3216,  753, 1267, 1267, 1267, 1267, 3216,
-     3216, 1267, 1267,  768,  768,  768, 3216, 3216, 3216,  768,
-     2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2837,
-     2837, 2837, 2837, 2837, 2837, 2837, 2837, 2837, 2894, 2894,
-
-     2894, 2894, 2894, 2894, 2894, 2894, 2894, 2897, 2897, 2897,
-     2897, 2897, 2897, 2897, 2897, 2897, 2935, 2935, 2935, 2935,
-     2935, 2935, 2935, 2935, 2935, 2937, 2937, 2937, 2937, 2937,
-     2937, 2937, 2937, 2937,  249, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216
+      626,  626,  628,  626,  626,  626, 1353,  626,  630,  626,
+      631,  626, 2541, 1358, 1359, 1359, 1359, 3217, 3217, 3217,
+     2521, 1368, 1368, 1368, 3217, 3217, 3217, 1371, 1371, 1371,
+     2522, 2542, 1361, 2523, 3217, 2543,  626,  626, 1369, 2544,
+     2545, 3217, 1075, 1075, 1075, 1373, 2546,  632, 1371, 1371,
+
+     1371, 1379, 1379, 1379, 1379, 1379, 1379, 2547, 2548, 1076,
+      633,  641, 1383, 1383, 1383, 2549, 1373, 1366,  656, 1381,
+     2550, 2524, 1381, 2551, 2552, 1362, 2553,  640,  657, 1384,
+     2554, 2525, 1367, 1370, 2526, 1374, 1385, 1385, 1385, 2555,
+     1387, 1387, 1387, 1387, 1387, 1387, 2557, 1391, 1391, 1391,
+     1397, 1397, 1397, 1386, 2565,  658,  659,  660, 1389, 1382,
+     2566, 1389,  661,  662, 1392, 2567,  663,  664, 1399, 2571,
+      665, 2606,  666,  667,  668,  641, 2608, 2609, 3217, 3217,
+     3217, 2610,  712, 1395, 1395, 1395, 1397, 1397, 1397, 2614,
+     1635,  640,  713, 1109, 2615, 3217, 2618, 1406, 1406, 1406,
+
+     1396, 1099, 1099, 1099, 1399, 1406, 1406, 1406, 1103, 1103,
+     1103, 1412, 1412, 1412, 1390, 1408, 2619, 2622, 1100,  658,
+      714,  669, 2603, 1408, 2623, 1104,  715,  662, 1393, 1414,
+      716,  664, 2604, 2624,  717, 2625,  718,  719,  668, 2626,
+     1412, 1412, 1412, 1394, 1419, 1419, 1419, 1419, 1419, 1419,
+     1635, 2616, 1423, 1423, 1423, 2627, 1424, 1400, 1414, 1425,
+     2628, 2629, 1421, 2630, 2617, 1421, 1427, 1427, 1427, 1409,
+     1427, 1427, 1427, 1122, 1122, 1122, 1122, 1122, 1122, 1122,
+     1122, 1122, 2620, 2632, 1429, 1468, 1468, 1468, 1429, 2633,
+     2634, 1124, 2605, 2635, 1124, 2621, 2636, 1124, 1156, 1156,
+
+     1156, 2637, 1469, 2638, 1415, 1156, 1156, 1156, 1422, 1156,
+     1156, 1156, 1471, 1471, 1471, 2639, 1158, 1161, 1161, 1161,
+     2640, 1162, 2641, 1158, 1163, 2642, 1439, 1158, 2643, 1472,
+     3217, 3217, 3217, 2644, 1430, 1166, 1166, 1166, 1166, 1166,
+     1166, 1166, 1166, 1166, 1171, 1171, 1171, 3217, 1172, 2645,
+     2646, 1173, 2648, 1168, 2656, 2657, 1168, 2658, 1470, 1168,
+     1174, 1174, 1174, 1477, 1477, 1477, 2589, 1478, 2659, 2676,
+     1479, 2677, 1480, 1480, 1480, 2678, 2590, 1175, 1177, 1177,
+     1177, 2679, 2591, 1482, 1482, 1482, 2680, 1483, 1475, 1481,
+     1484, 1473, 1486, 1486, 1486, 1178, 1182, 1182, 1182, 1182,
+
+     1182, 1182, 1182, 1182, 1182, 1491, 1491, 1491, 2681, 1487,
+     1189, 1189, 1189, 2684, 1184, 2692, 2694, 1184, 2695, 1109,
+     1184, 2696, 1492, 1189, 1189, 1189, 2685, 2686, 1191, 1189,
+     1189, 1189, 1193, 1193, 1193, 2697, 1194, 2698, 2699, 1195,
+     2687, 1191, 1197, 1197, 1197, 2700, 1635, 1191, 1197, 1197,
+     1197, 1496, 1496, 1496, 1214, 1214, 1214, 2701, 1215, 2702,
+     1199, 1216, 1489, 1512, 1512, 1512, 1199, 2688, 2703, 1497,
+     1219, 1219, 1219, 1219, 1219, 1219, 1494, 1219, 1219, 1219,
+     1513, 2689, 1224, 1224, 1224, 2706, 1225, 2707, 1221, 1226,
+     2708, 1221, 1228, 1228, 1228, 1221, 1228, 1228, 1228, 1228,
+
+     1228, 1228, 1232, 1232, 1232, 2709, 1233, 2710, 2711, 1234,
+     1230, 1518, 1518, 1518, 1230, 2712, 2713, 1230, 1236, 1236,
+     1236, 1236, 1236, 1236, 1236, 1236, 1236, 2715, 1519, 1521,
+     1521, 1521, 2716, 3217, 3217, 3217, 1238, 2717, 1514, 1238,
+     2718, 2719, 1238, 1912, 1912, 1912, 1522, 1242, 1242, 1242,
+     3217, 1242, 1242, 1242, 1242, 1242, 1242, 1527, 1527, 1527,
+     1517, 1523, 1254, 1254, 1254, 1244, 1249, 1249, 1249, 1244,
+     1250, 2720, 1244, 1251, 1528, 1254, 1254, 1254, 2721, 2722,
+     1256, 1254, 1254, 1254, 1534, 1534, 1534, 2723, 1261, 1261,
+     1261, 1520, 1262, 1256, 2724, 1263, 1264, 1264, 1264, 1256,
+
+     1265, 1535, 2725, 1266, 1267, 1267, 1267, 1267, 1267, 1267,
+     1267, 1267, 1267, 2592, 1275, 1275, 1275, 2726, 1276, 2727,
+     1524, 1277, 1269, 2593, 2728, 1269, 2729, 2735, 1269, 2594,
+     1541, 1541, 1541, 1279, 1279, 1279, 2736, 1280, 2737, 2738,
+     1281, 1282, 1282, 1282, 2739, 2753, 1531, 1542, 1543, 1543,
+     1543, 2754, 1544, 2755, 2756, 1545, 2757, 2758, 1283, 1291,
+     1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291, 2745, 1295,
+     1295, 1295, 2747, 1296, 2762, 1536, 1297, 1293, 2746, 2749,
+     1293, 2763, 2748, 1293, 1298, 1298, 1298, 2764, 1299, 2750,
+     2751, 1300, 1301, 1301, 1301, 1554, 1554, 1554, 2765, 1555,
+
+     2752, 1109, 1556, 1307, 1307, 1307, 1307, 1307, 1307, 1302,
+     1307, 1307, 1307, 1315, 1315, 1315, 2775, 1316, 2776, 2777,
+     1317, 1309, 2778, 2779, 1309, 1318, 1318, 1318, 1309, 1566,
+     1566, 1566, 1553, 1567, 2780, 2766, 1568, 1322, 1322, 1322,
+     2781, 2782, 1319, 1322, 1322, 1322, 1322, 1322, 1322, 1327,
+     1327, 1327, 2786, 1328, 2787, 1324, 1329, 2788, 1561, 2789,
+     2790, 1324, 2791, 2793, 1324, 1330, 1330, 1330, 1330, 1330,
+     1330, 1330, 1330, 1330, 1335, 1335, 1335, 2794, 1336, 2795,
+     2796, 1337, 2797, 1332, 2798, 2799, 1332, 2800, 2801, 1332,
+     1339, 1339, 1339, 1339, 1339, 1339, 2802, 1571, 1339, 1339,
+
+     1339, 2806, 1344, 1344, 1344, 2807, 1345, 2808, 1341, 1346,
+     2811, 1341, 1350, 1350, 1350, 2816, 1341, 1350, 1350, 1350,
+     2817, 1350, 1350, 1350, 1354, 1354, 1354, 1582, 1582, 1582,
+     1352, 1583, 2818, 2819, 1584, 1352, 2820, 2821, 1573, 1352,
+     2822, 1355, 1356, 1356, 1356, 2823, 2824, 1576, 1585, 1585,
+     1585, 2825, 1586, 2826, 2827, 1587, 1359, 1359, 1359, 1357,
+     1359, 1359, 1359, 2829, 1359, 1359, 1359, 1364, 1364, 1364,
+     2830, 1368, 1368, 1368, 1361, 2017, 2017, 2017, 1361, 2831,
+     2832, 1581, 1361, 2839, 1365, 1591, 1591, 1591, 1369, 1592,
+     2840, 2841, 1593, 1596, 1596, 1596, 2842, 1597, 2843, 2844,
+
+     1598, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371, 1371,
+     1376, 1376, 1376, 2845, 1377, 2846, 2847, 1378, 2848, 1373,
+     2849, 1109, 1373, 2850, 2851, 1373, 1379, 1379, 1379, 2852,
+     2855, 1589, 1379, 1379, 1379, 1379, 1379, 1379, 1383, 1383,
+     1383, 1603, 1603, 1603, 1381, 1604, 2856, 2857, 1605, 2858,
+     1381, 2859, 2860, 1381, 2861, 1384, 1385, 1385, 1385, 1606,
+     1606, 1606, 2862, 1607, 2833, 2863, 1608, 1387, 1387, 1387,
+     2864, 1600, 2865, 1386, 1387, 1387, 1387, 2869, 1387, 1387,
+     1387, 1391, 1391, 1391, 2876, 1389, 1610, 1610, 1610, 2877,
+     1611, 2878, 1389, 1612, 2879, 1602, 1389, 2880, 1392, 1395,
+
+     1395, 1395, 1615, 1615, 1615, 2881, 1616, 2882, 2883, 1617,
+     1397, 1397, 1397, 1397, 1397, 1397, 1396, 1397, 1397, 1397,
+     1620, 1620, 1620, 1406, 1406, 1406, 2884, 2885, 1399, 2886,
+     2887, 1399, 1406, 1406, 1406, 1399, 2890, 1621, 2891, 2892,
+     1609, 1408, 1406, 1406, 1406, 1412, 1412, 1412, 2893, 2901,
+     1408, 1412, 1412, 1412, 1412, 1412, 1412, 1416, 1416, 1416,
+     1408, 1417, 2902, 1414, 1418, 1419, 1419, 1419, 1109, 1414,
+     2903, 2896, 1414, 1419, 1419, 1419, 1419, 1419, 1419, 1618,
+     1423, 1423, 1423, 1421, 1424, 2897, 2904, 1425, 1427, 1427,
+     1427, 1421, 2905, 2896, 1421, 1427, 1427, 1427, 1427, 1427,
+
+     1427, 2906, 2907, 1625, 2899, 2908, 1429, 1628, 1634, 1634,
+     1634, 2909, 2910, 1429, 2894, 2911, 1429, 1122, 1122, 1122,
+     1468, 1468, 1468, 1156, 1156, 1156, 1635, 1636, 2912, 1471,
+     1471, 1471, 1496, 1496, 1496, 1124, 1629, 1469, 1672, 1672,
+     1672, 1158, 1673, 2913, 2914, 1674, 1472, 1676, 1676, 1676,
+     1497, 1677, 2915, 2916, 1678, 1166, 1166, 1166, 2917, 1631,
+     1477, 1477, 1477, 2918, 1478, 2919, 2920, 1479, 1480, 1480,
+     1480, 2924, 2922, 1168, 2929, 1683, 1683, 1683, 2921, 1684,
+     2925, 1675, 1685, 1641, 2923, 1481, 1482, 1482, 1482, 2927,
+     1483, 2930, 2926, 1484, 1486, 1486, 1486, 2931, 1687, 1687,
+
+     1687, 2928, 1688, 2932, 1681, 1689, 1182, 1182, 1182, 2933,
+     2934, 1487, 1491, 1491, 1491, 1693, 1693, 1693, 2937, 1694,
+     1635, 1636, 1695, 2937, 1184, 1696, 1696, 1696, 1109, 1492,
+     1189, 1189, 1189, 1714, 1714, 1714, 1512, 1512, 1512, 1716,
+     1716, 1716, 1697, 1717, 2896, 2940, 1718, 2941, 1191, 2942,
+     1715, 2943, 2946, 1513, 2944, 2899, 1691, 1219, 1219, 1219,
+     1228, 1228, 1228, 1518, 1518, 1518, 1723, 1723, 1723, 2935,
+     1724, 2949, 2945, 1725, 2956, 1221, 2896, 2947, 1230, 1698,
+     1519, 1236, 1236, 1236, 1521, 1521, 1521, 1727, 1727, 1727,
+     2897, 1728, 2948, 2957, 1729, 1242, 1242, 1242, 2958, 1238,
+
+     2961, 1522, 1527, 1527, 1527, 1734, 1734, 1734, 2966, 1735,
+     2969, 2970, 1736, 1244, 1737, 1737, 1737, 2971, 2937, 1528,
+     2959, 1719, 2973, 2937, 1722, 1739, 1739, 1739, 1254, 1254,
+     1254, 1738, 1534, 1534, 1534, 2974, 1745, 1745, 1745, 2960,
+     1746, 1726, 1740, 1747, 2964, 2975, 1256, 2967, 2976, 1535,
+     1267, 1267, 1267, 1750, 1750, 1750, 1731, 1541, 1541, 1541,
+     1754, 1754, 1754, 2965, 1755, 2977, 2968, 1756, 1269, 2978,
+     1751, 1741, 2979, 2980, 1542, 1543, 1543, 1543, 2981, 1544,
+     2991, 2992, 1545, 1757, 1757, 1757, 1291, 1291, 1291, 1554,
+     1554, 1554, 2993, 1555, 1742, 2994, 1556, 1766, 1766, 1766,
+
+     1758, 3217, 3217, 3217, 1293, 3217, 3217, 3217, 3217, 3217,
+     3217, 1307, 1307, 1307, 1767, 2995, 1748, 2996, 3217, 1773,
+     1773, 1773, 3217, 3000, 3001, 3217, 1566, 1566, 1566, 1309,
+     1567, 3002, 3003, 1568, 3004, 3005, 1774, 1777, 1777, 1777,
+     1322, 1322, 1322, 1330, 1330, 1330, 1339, 1339, 1339, 3006,
+     3007, 1765, 1769, 3009, 1778, 1789, 1789, 1789, 1324, 3010,
+     3011, 1332, 3012, 3013, 1341, 3018, 1771, 1350, 1350, 1350,
+     3019, 1768, 1790, 1582, 1582, 1582, 3014, 1583, 1770, 3020,
+     1584, 3021, 1585, 1585, 1585, 1352, 1586, 3016, 3015, 1587,
+     1359, 1359, 1359, 1591, 1591, 1591, 3022, 1592, 3023, 3017,
+
+     1593, 1791, 3024, 1785, 1780, 1371, 1371, 1371, 1361, 1782,
+     1596, 1596, 1596, 3025, 1597, 3026, 3027, 1598, 1379, 1379,
+     1379, 3028, 3029, 1373, 1792, 1603, 1603, 1603, 3030, 1604,
+     3031, 3033, 1605, 1606, 1606, 1606, 1381, 1607, 3034, 1109,
+     1608, 1387, 1387, 1387, 1610, 1610, 1610, 3035, 1611, 3036,
+     3037, 1612, 3038, 1615, 1615, 1615, 1794, 1616, 3039, 1389,
+     1617, 1397, 1397, 1397, 3032, 3040, 1799, 1620, 1620, 1620,
+     1807, 1807, 1807, 3041, 1808, 1801, 3042, 1809, 3043, 1399,
+     1406, 1406, 1406, 3044, 1621, 1815, 1815, 1815, 1802, 1412,
+     1412, 1412, 1419, 1419, 1419, 1819, 1819, 1819, 1408, 1427,
+
+     1427, 1427, 1816, 1634, 1634, 1634, 3045, 1414, 1805, 3046,
+     1421, 3047, 1820, 1122, 1122, 1122, 3048, 1429, 1672, 1672,
+     1672, 1635, 1673, 3049, 3050, 1674, 1696, 1696, 1696, 1813,
+     3051, 1124, 1156, 1156, 1156, 1676, 1676, 1676, 3052, 1677,
+     1109, 3054, 1678, 1697, 1818, 1166, 1166, 1166, 3055, 3056,
+     1158, 1683, 1683, 1683, 1823, 1684, 1817, 3057, 1685, 3053,
+     3058, 1821, 3059, 1168, 3060, 1828, 1687, 1687, 1687, 3061,
+     1688, 1824, 3062, 1689, 1182, 1182, 1182, 1693, 1693, 1693,
+     3063, 1694, 3064, 3065, 1695, 3066, 1874, 1874, 1874, 3067,
+     1875, 3068, 1184, 1876, 3069, 3070, 1860, 3071, 3073, 1857,
+
+     1189, 1189, 1189, 1883, 1883, 1883, 1883, 1883, 1883, 1844,
+     1844, 1844, 1714, 1714, 1714, 1889, 1889, 1889, 1191, 1890,
+     3074, 3075, 1891, 1716, 1716, 1716, 1109, 1717, 3076, 1715,
+     1718, 1219, 1219, 1219, 3077, 1864, 1894, 1894, 1894, 1228,
+     1228, 1228, 3078, 1723, 1723, 1723, 3072, 1724, 3079, 1221,
+     1725, 1877, 3080, 1895, 1236, 1236, 1236, 1230, 1727, 1727,
+     1727, 3081, 1728, 3082, 3083, 1729, 3084, 1884, 3085, 3086,
+     1845, 3087, 1238, 1884, 1898, 1898, 1898, 3088, 1892, 1242,
+     1242, 1242, 3089, 1734, 1734, 1734, 1896, 1735, 3090, 1109,
+     1736, 1899, 1737, 1737, 1737, 3091, 3092, 1244, 1903, 1903,
+
+     1903, 3093, 1904, 3094, 3095, 1905, 1739, 1739, 1739, 1738,
+     1906, 1906, 1906, 3096, 1907, 3097, 3098, 1908, 3099, 3100,
+     1897, 3101, 3102, 1740, 1910, 1910, 1910, 1745, 1745, 1745,
+     3103, 1746, 3105, 1109, 1747, 1267, 1267, 1267, 1750, 1750,
+     1750, 3106, 1911, 1900, 1916, 1916, 1916, 3104, 1917, 3107,
+     3108, 1918, 3109, 1269, 3110, 1751, 1919, 1919, 1919, 1754,
+     1754, 1754, 3111, 1755, 3112, 3114, 1756, 1757, 1757, 1757,
+     1922, 1922, 1922, 1920, 1923, 3115, 3116, 1924, 1925, 1925,
+     1925, 1914, 3117, 3118, 1758, 1931, 1931, 1931, 1291, 1291,
+     1291, 1766, 1766, 1766, 3119, 1926, 1934, 1934, 1934, 3120,
+
+     1935, 3121, 1932, 1936, 3124, 3125, 1293, 3126, 1767, 1937,
+     1937, 1937, 3217, 3217, 3217, 1940, 1940, 1940, 1307, 1307,
+     1307, 1773, 1773, 1773, 3127, 3128, 1938, 3129, 1109, 3217,
+     1109, 1109, 1941, 1944, 1944, 1944, 1309, 1945, 1774, 1109,
+     1946, 1947, 1947, 1947, 1777, 1777, 1777, 3138, 1950, 1950,
+     1950, 1109, 1951, 3139, 1933, 1952, 1109, 1109, 1948, 3182,
+     3140, 1778, 1954, 1954, 1954, 1330, 1330, 1330, 1109, 3148,
+     1939, 1339, 1339, 1339, 1789, 1789, 1789, 1109, 1942, 3132,
+     1955, 1701, 1700, 1332, 1109, 3152, 1964, 1964, 1964, 1341,
+     1965, 1790, 3130, 1966, 1968, 1968, 1968, 1359, 1359, 1359,
+
+     1973, 1973, 1973, 1975, 1975, 1975, 3217, 3217, 3217, 1371,
+     1371, 1371, 1969, 3131, 3141, 1361, 1957, 1974, 1109, 1960,
+     1976, 1109, 1109, 3217, 1387, 1387, 1387, 1373, 1379, 1379,
+     1379, 3144, 1982, 1982, 1982, 1984, 1984, 1984, 1397, 1397,
+     1397, 1109, 1389, 1807, 1807, 1807, 1381, 1808, 1971, 1983,
+     1809, 1109, 1985, 1406, 1406, 1406, 1399, 1109, 1815, 1815,
+     1815, 1993, 1993, 1993, 3142, 1994, 3133, 1699, 1995, 3134,
+     1977, 1408, 1109, 3156, 1980, 1816, 1978, 1412, 1412, 1412,
+     1419, 1419, 1419, 1819, 1819, 1819, 1998, 1998, 1998, 1981,
+     1999, 1692, 1690, 2000, 3143, 1414, 1109, 1109, 1421, 3135,
+
+     1820, 3136, 1109, 1986, 1991, 2001, 2001, 2001, 2007, 2007,
+     2007, 1122, 1122, 1122, 1839, 1839, 1839, 2024, 2024, 2024,
+     1844, 1844, 1844, 2002, 1109, 2008, 2025, 2025, 2025, 1124,
+     1847, 1847, 1847, 3146, 3147, 1997, 1996, 2028, 2028, 2028,
+     2029, 2029, 2029, 1855, 1855, 1855, 1156, 1156, 1156, 2038,
+     2038, 2038, 2041, 2041, 2041, 1182, 1182, 1182, 2045, 2045,
+     2045, 1874, 1874, 1874, 1158, 1875, 1109, 2039, 1876, 2042,
+     3158, 3145, 2009, 1184, 1109, 2046, 1189, 1189, 1189, 1109,
+     2058, 2058, 2058, 1883, 1883, 1883, 2065, 2065, 2065, 2067,
+     2067, 2067, 1686, 1109, 1191, 3190, 2035, 2059, 1889, 1889,
+
+     1889, 3150, 1890, 1109, 1109, 1891, 2068, 1219, 1219, 1219,
+     2070, 2070, 2070, 1682, 2044, 1894, 1894, 1894, 3137, 2072,
+     2072, 2072, 2057, 2073, 1109, 1221, 2074, 2071, 1228, 1228,
+     1228, 1109, 1895, 2076, 2076, 2076, 1898, 1898, 1898, 3153,
+     2078, 2078, 2078, 3159, 2079, 3149, 1230, 2080, 1242, 1242,
+     1242, 2077, 1109, 1899, 1903, 1903, 1903, 1109, 1904, 3151,
+     2069, 1905, 1680, 1906, 1906, 1906, 1244, 1907, 3154, 1109,
+     1908, 1910, 1910, 1910, 1912, 1912, 1912, 1109, 1267, 1267,
+     1267, 2075, 1679, 1916, 1916, 1916, 1109, 1917, 1109, 1911,
+     1918, 1919, 1919, 1919, 3155, 2081, 1269, 2090, 2090, 2090,
+
+     1109, 2091, 1109, 3162, 2092, 1922, 1922, 1922, 1920, 1923,
+     1109, 3163, 1924, 1925, 1925, 1925, 2094, 2094, 2094, 1109,
+     2095, 3160, 3186, 2096, 2097, 2097, 2097, 1931, 1931, 1931,
+     1926, 2102, 2102, 2102, 3157, 2103, 2088, 1109, 2104, 1109,
+     1671, 2098, 3172, 3164, 1932, 1291, 1291, 1291, 1934, 1934,
+     1934, 1109, 1935, 3165, 3161, 1936, 1937, 1937, 1937, 1109,
+     2106, 2106, 2106, 1293, 2107, 1109, 1670, 2108, 2109, 2109,
+     2109, 3173, 3170, 1938, 1940, 1940, 1940, 2111, 2111, 2111,
+     1109, 2112, 1109, 3166, 2113, 2110, 1307, 1307, 1307, 1668,
+     1667, 1941, 3171, 1944, 1944, 1944, 2105, 1945, 1109, 1109,
+
+     1946, 1947, 1947, 1947, 1309, 2116, 2116, 2116, 1109, 2117,
+     1666, 3167, 2118, 1950, 1950, 1950, 1109, 1951, 1948, 3174,
+     1952, 1954, 1954, 1954, 1330, 1330, 1330, 2124, 2124, 2124,
+     1339, 1339, 1339, 2128, 2128, 2128, 3175, 2114, 1109, 1955,
+     3176, 1109, 1332, 3168, 2125, 1964, 1964, 1964, 1341, 1965,
+     2129, 3169, 1966, 1968, 1968, 1968, 2136, 2136, 2136, 1973,
+     1973, 1973, 2139, 2139, 2139, 3191, 2140, 1109, 3184, 2141,
+     1109, 1969, 1109, 1109, 2137, 3180, 1974, 1109, 3181, 2130,
+     1975, 1975, 1975, 2142, 2142, 2142, 1109, 2143, 2122, 1665,
+     2144, 2126, 1371, 1371, 1371, 1664, 1109, 1976, 1379, 1379,
+
+     1379, 1387, 1387, 1387, 1982, 1982, 1982, 2150, 2150, 2150,
+     1373, 2151, 3177, 3178, 2152, 3183, 1381, 1109, 3179, 1389,
+     1663, 1983, 1984, 1984, 1984, 2153, 2153, 2153, 1109, 2154,
+     3187, 3185, 2155, 1397, 1397, 1397, 1406, 1406, 1406, 1985,
+     1109, 1993, 1993, 1993, 1662, 1994, 1109, 2148, 1995, 1109,
+     1109, 1399, 3198, 1109, 1408, 1412, 1412, 1412, 2146, 1419,
+     1419, 1419, 1109, 1998, 1998, 1998, 2149, 1999, 1109, 3196,
+     2000, 1661, 1660, 1414, 2001, 2001, 2001, 1421, 2007, 2007,
+     2007, 2169, 2169, 2169, 1658, 2170, 3194, 1657, 2171, 1122,
+     1122, 1122, 2002, 3192, 1655, 2008, 3188, 3199, 2156, 3189,
+
+     3204, 2161, 2173, 2173, 2173, 1109, 2163, 1124, 2178, 2178,
+     2178, 1654, 2164, 2179, 2179, 2179, 2017, 2017, 2017, 2181,
+     2181, 2181, 2185, 2185, 2185, 2024, 2024, 2024, 2025, 2025,
+     2025, 2186, 2186, 2186, 2028, 2028, 2028, 2029, 2029, 2029,
+     2189, 2189, 2189, 2190, 2190, 2190, 2191, 2191, 2191, 2192,
+     2192, 2192, 3193, 2172, 1156, 1156, 1156, 2038, 2038, 2038,
+     3206, 2041, 2041, 2041, 2198, 2198, 2198, 1109, 2199, 1109,
+     1651, 2200, 1158, 1648, 3214, 2039, 1647, 2187, 2042, 2202,
+     2202, 2202, 2045, 2045, 2045, 2204, 2204, 2204, 1109, 2205,
+     1646, 1109, 2206, 1189, 1189, 1189, 1109, 2203, 1109, 2046,
+
+     2058, 2058, 2058, 1109, 3195, 2194, 2218, 2218, 2218, 1109,
+     2219, 1191, 1645, 2220, 2221, 2221, 2221, 2059, 2065, 2065,
+     2065, 2226, 2226, 2226, 2067, 2067, 2067, 2228, 2228, 2228,
+     3205, 2229, 3197, 3202, 2230, 1219, 1219, 1219, 2070, 2070,
+     2070, 2068, 2217, 2232, 2232, 2232, 3203, 2233, 1109, 3200,
+     2234, 1109, 3207, 1221, 1109, 2071, 2072, 2072, 2072, 1644,
+     2073, 1109, 1643, 2074, 1228, 1228, 1228, 2227, 1109, 2076,
+     2076, 2076, 2078, 2078, 2078, 1642, 2079, 1109, 1640, 2080,
+     1639, 1638, 1230, 1242, 1242, 1242, 2231, 2077, 1267, 1267,
+     1267, 2090, 2090, 2090, 3201, 2091, 1637, 1630, 2092, 3210,
+
+     3208, 1244, 3211, 2094, 2094, 2094, 1269, 2095, 1109, 3209,
+     2096, 2097, 2097, 2097, 1627, 2235, 2248, 2248, 2248, 3214,
+     2249, 1109, 1626, 2250, 1624, 2102, 2102, 2102, 2098, 2103,
+     1109, 1623, 2104, 1291, 1291, 1291, 2236, 2106, 2106, 2106,
+     3212, 2107, 1622, 2245, 2108, 2109, 2109, 2109, 2255, 2255,
+     2255, 1293, 2256, 3213, 1619, 2257, 2111, 2111, 2111, 1614,
+     2112, 1613, 2110, 2113, 1307, 1307, 1307, 2116, 2116, 2116,
+     1601, 2117, 1599, 1595, 2118, 2263, 2263, 2263, 2124, 2124,
+     2124, 1594, 1309, 2266, 2266, 2266, 1590, 2267, 1588, 1580,
+     2268, 1579, 1578, 2264, 1577, 2125, 1575, 2254, 1339, 1339,
+
+     1339, 2128, 2128, 2128, 2271, 2271, 2271, 1574, 2272, 1572,
+     1570, 2273, 1569, 2136, 2136, 2136, 1341, 1565, 2129, 2139,
+     2139, 2139, 1564, 2140, 1563, 1562, 2141, 1371, 1371, 1371,
+     2258, 2137, 2142, 2142, 2142, 1560, 2143, 1559, 1558, 2144,
+     1557, 1379, 1379, 1379, 1552, 1373, 1387, 1387, 1387, 2150,
+     2150, 2150, 1551, 2151, 1550, 1549, 2152, 1548, 2269, 1381,
+     1547, 2153, 2153, 2153, 1389, 2154, 1546, 1540, 2155, 1397,
+     1397, 1397, 1539, 2289, 2289, 2289, 1538, 1537, 2284, 3217,
+     3217, 3217, 2287, 3217, 3217, 3217, 1533, 1399, 1532, 2288,
+     2290, 3217, 3217, 3217, 1530, 1529, 3217, 1406, 1406, 1406,
+
+     3217, 1412, 1412, 1412, 2297, 2297, 2297, 2286, 3217, 2299,
+     2299, 2299, 2302, 2302, 2302, 1408, 2169, 2169, 2169, 1414,
+     2170, 1526, 2298, 2171, 1122, 1122, 1122, 1109, 1525, 1516,
+     2291, 2173, 2173, 2173, 2304, 2304, 2304, 2305, 2305, 2305,
+     1515, 1511, 1124, 2178, 2178, 2178, 1510, 2292, 1509, 1508,
+     2293, 2179, 2179, 2179, 2181, 2181, 2181, 2309, 2309, 2309,
+     1507, 2296, 2294, 2310, 2310, 2310, 2311, 2311, 2311, 2185,
+     2185, 2185, 2186, 2186, 2186, 2189, 2189, 2189, 2190, 2190,
+     2190, 1506, 1505, 2303, 2191, 2191, 2191, 2192, 2192, 2192,
+     2315, 2315, 2315, 2318, 2318, 2318, 2198, 2198, 2198, 1504,
+
+     2199, 1502, 1501, 2200, 3217, 3217, 3217, 1500, 2316, 1499,
+     2319, 2202, 2202, 2202, 1498, 2204, 2204, 2204, 1495, 2205,
+     1493, 3217, 2206, 1189, 1189, 1189, 2218, 2218, 2218, 2203,
+     2219, 2332, 2333, 2220, 2334, 1490, 2338, 2339, 1488, 2340,
+     1485, 1191, 2335, 1476, 1474, 2336, 1467, 2341, 1465, 2337,
+     2342, 2221, 2221, 2221, 2343, 2344, 2344, 2344, 2226, 2226,
+     2226, 2228, 2228, 2228, 1464, 2229, 1463, 1462, 2230, 1461,
+     2320, 1219, 1219, 1219, 2232, 2232, 2232, 1460, 2233, 1459,
+     1458, 2234, 1457, 1456, 2331, 2350, 2350, 2350, 1453, 1221,
+     1242, 1242, 1242, 2360, 2360, 2360, 1267, 1267, 1267, 1452,
+
+     2248, 2248, 2248, 2351, 2249, 1451, 1450, 2250, 1244, 2364,
+     2364, 2364, 1449, 1448, 1269, 1447, 1446, 2349, 2368, 2368,
+     2368, 2255, 2255, 2255, 1445, 2256, 2365, 1444, 2257, 2370,
+     2370, 2370, 2263, 2263, 2263, 1443, 2369, 2376, 2376, 2376,
+     1442, 2352, 2266, 2266, 2266, 1441, 2267, 2371, 1440, 2268,
+     2264, 1339, 1339, 1339, 2377, 1438, 2361, 2379, 2379, 2379,
+     2271, 2271, 2271, 1437, 2272, 1436, 1435, 2273, 1434, 1341,
+     3217, 3217, 3217, 1433, 2380, 3217, 3217, 3217, 3217, 3217,
+     3217, 2390, 2390, 2390, 2394, 2394, 2394, 3217, 2392, 2392,
+     2392, 1432, 3217, 1109, 1426, 3217, 1379, 1379, 1379, 1411,
+
+     1410, 2395, 2378, 2381, 1405, 1404, 2393, 1403, 1387, 1387,
+     1387, 2289, 2289, 2289, 1381, 1397, 1397, 1397, 1402, 1401,
+     2399, 2399, 2399, 1375, 2400, 2382, 1389, 2401, 2290, 2388,
+     2402, 2402, 2402, 1399, 1363, 1349, 2383, 3217, 3217, 3217,
+     3217, 3217, 3217, 2406, 2406, 2406, 1348, 2403, 2408, 2408,
+     2408, 1347, 2398, 1343, 3217, 1338, 2396, 3217, 1412, 1412,
+     1412, 2407, 2297, 2297, 2297, 2299, 2299, 2299, 1334, 2397,
+     2302, 2302, 2302, 2304, 2304, 2304, 1414, 2413, 2413, 2413,
+     2298, 1326, 1321, 1109, 2305, 2305, 2305, 1320, 2404, 1314,
+     1311, 2405, 2417, 2417, 2417, 2414, 2309, 2309, 2309, 2310,
+
+     2310, 2310, 2311, 2311, 2311, 2315, 2315, 2315, 2318, 2318,
+     2318, 2422, 2422, 2422, 1290, 2423, 1289, 1288, 2424, 1189,
+     1189, 1189, 1287, 2316, 2409, 2319, 1286, 2410, 2344, 2344,
+     2344, 2453, 2453, 2453, 1219, 1219, 1219, 1191, 2350, 2350,
+     2350, 2456, 2456, 2456, 2462, 2462, 2462, 2360, 2360, 2360,
+     1285, 1284, 1221, 1267, 1267, 1267, 2351, 1278, 1271, 2457,
+     1260, 2463, 1259, 2364, 2364, 2364, 2467, 2467, 2467, 1258,
+     2468, 1269, 1253, 2469, 2471, 2471, 2471, 1252, 1248, 2436,
+     2365, 2368, 2368, 2368, 2370, 2370, 2370, 2475, 2475, 2475,
+     1247, 2472, 2376, 2376, 2376, 1246, 2481, 2481, 2481, 2369,
+
+     2455, 1241, 2371, 1240, 2476, 2379, 2379, 2379, 1235, 2377,
+     2464, 2478, 2478, 2478, 2482, 2479, 1227, 1223, 2480, 2483,
+     2483, 2483, 2380, 2484, 1218, 1217, 2485, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 2491, 2491, 2491, 2390,
+     2390, 2390, 1213, 1212, 3217, 1211, 1210, 3217, 1209, 1208,
+     3217, 1207, 1206, 2492, 2392, 2392, 2392, 2394, 2394, 2394,
+     2495, 2495, 2495, 1205, 2496, 1204, 1203, 2497, 2498, 2498,
+     2498, 1202, 2393, 1196, 2395, 1387, 1387, 1387, 1188, 2486,
+     1397, 1397, 1397, 2399, 2399, 2399, 2499, 2400, 2487, 1187,
+     2401, 2488, 1186, 1389, 2402, 2402, 2402, 1181, 1399, 2502,
+
+     2502, 2502, 1180, 2503, 1179, 1176, 2504, 2505, 2505, 2505,
+     1170, 2403, 2507, 2507, 2507, 2406, 2406, 2406, 2408, 2408,
+     2408, 2509, 2509, 2509, 2506, 2413, 2413, 2413, 1165, 2508,
+     2417, 2417, 2417, 2407, 2519, 2519, 2519, 1164, 1160, 2510,
+     1155, 1154, 2500, 2414, 2501, 2422, 2422, 2422, 1153, 2423,
+     1152, 2520, 2424, 1189, 1189, 1189, 2453, 2453, 2453, 1219,
+     1219, 1219, 2456, 2456, 2456, 2558, 2558, 2558, 2462, 2462,
+     2462, 1191, 2560, 2560, 2560, 1151, 2561, 1221, 1150, 2562,
+     2457, 1149, 2559, 1147, 1146, 2463, 2563, 2563, 2563, 2467,
+     2467, 2467, 1145, 2468, 1144, 1143, 2469, 2471, 2471, 2471,
+
+     1142, 2568, 2568, 2568, 2564, 2569, 1141, 1140, 2570, 2572,
+     2572, 2572, 1139, 2538, 2472, 2475, 2475, 2475, 2574, 2574,
+     2574, 1138, 2575, 1137, 1136, 2576, 2573, 2577, 2577, 2577,
+     2556, 1135, 2476, 2478, 2478, 2478, 1134, 2479, 1133, 1132,
+     2480, 2481, 2481, 2481, 2578, 2483, 2483, 2483, 1131, 2484,
+     1130, 1129, 2485, 3217, 3217, 3217, 3217, 3217, 3217, 2482,
+     3217, 3217, 3217, 2491, 2491, 2491, 1128, 2582, 2582, 2582,
+     3217, 2583, 1121, 3217, 2584, 1120, 1119, 3217, 1118, 1117,
+     2492, 2585, 2585, 2585, 2587, 2587, 2587, 2495, 2495, 2495,
+     1116, 2496, 1115, 1112, 2497, 2498, 2498, 2498, 2586, 1110,
+
+     1109, 2588, 1387, 1387, 1387, 1107, 1105, 2580, 2579, 1397,
+     1397, 1397, 1102, 2499, 1098, 2581, 1096, 2502, 2502, 2502,
+     1389, 2503, 1095, 1094, 2504, 1092, 1091, 1399, 2505, 2505,
+     2505, 2597, 2597, 2597, 1090, 2598, 1089, 1088, 2599, 2507,
+     2507, 2507, 2600, 2600, 2600, 2506, 2601, 1087, 1085, 2602,
+     1084, 2509, 2509, 2509, 1083, 1082, 2508, 2607, 2607, 2607,
+     2519, 2519, 2519, 1189, 1189, 1189, 1080, 1079, 2595, 2510,
+     2596, 2611, 2611, 2611, 1078, 2612, 1074, 2520, 2613, 1073,
+     1071, 1191, 2647, 2647, 2647, 1219, 1219, 1219, 2650, 2650,
+     2650, 2558, 2558, 2558, 2653, 2653, 2653, 1070, 2654, 1069,
+
+     1068, 2655, 1067, 1221, 1066, 2651, 1064, 1063, 2559, 2560,
+     2560, 2560, 1062, 2561, 2631, 1061, 2562, 2563, 2563, 2563,
+     2568, 2568, 2568, 1059, 2569, 1058, 1057, 2570, 2572, 2572,
+     2572, 2607, 2607, 2607, 2652, 2564, 2660, 2660, 2660, 1054,
+     2661, 1053, 1051, 2662, 1048, 2573, 1047, 2649, 2574, 2574,
+     2574, 1043, 2575, 1042, 1040, 2576, 2577, 2577, 2577, 2663,
+     2663, 2663, 1039, 2664, 1038, 1035, 2665, 3217, 3217, 3217,
+     2667, 2667, 2667, 2578, 3217, 3217, 3217, 1034, 2582, 2582,
+     2582, 1033, 2583, 1032, 3217, 2584, 1030, 2668, 2585, 2585,
+     2585, 3217, 2670, 2670, 2670, 1029, 2671, 1028, 1027, 2672,
+
+     2587, 2587, 2587, 1026, 1021, 2586, 2673, 2673, 2673, 1019,
+     2674, 1018, 1017, 2675, 1387, 1387, 1387, 2588, 1397, 1397,
+     1397, 1016, 1015, 2669, 1014, 2666, 2597, 2597, 2597, 1013,
+     2598, 1012, 1389, 2599, 1009, 1006, 1399, 2600, 2600, 2600,
+     1005, 2601, 1004,  998, 2602, 2690, 2690, 2690, 2693, 2693,
+     2693, 2611, 2611, 2611,  995, 2612,  993,  992, 2613, 2704,
+     2704, 2704, 2691, 1635,  987, 2682, 1189, 1189, 1189, 2647,
+     2647, 2647, 2730, 2730, 2730,  986, 2705, 1219, 1219, 1219,
+     2650, 2650, 2650,  984, 1191, 2683, 2732, 2732, 2732,  983,
+     2733,  982,  980, 2734,  977, 1221,  975, 2651, 2653, 2653,
+
+     2653,  972, 2654,  971,  969, 2655, 2660, 2660, 2660,  968,
+     2661,  965,  960, 2662,  959, 2714, 2663, 2663, 2663,  956,
+     2664,  955,  952, 2665, 3217, 3217, 3217,  951, 2731, 2667,
+     2667, 2667, 2741, 2741, 2741,  949, 2742,  946,  944, 2743,
+      943, 3217, 3217, 3217, 3217,  942, 2668, 2670, 2670, 2670,
+      941, 2671,  939,  938, 2672,  937, 2673, 2673, 2673, 3217,
+     2674,  936,  935, 2675, 2759, 2759, 2759, 1397, 1397, 1397,
+     2767, 2767, 2767,  934,  931, 2740, 2690, 2690, 2690, 2769,
+     2769, 2769, 2760, 2770,  930, 1399, 2771, 2768, 1635, 2772,
+     2772, 2772,  929, 2691, 1635,  926,  923, 1635, 2693, 2693,
+
+     2693, 2773, 2773, 2773, 2774, 2774, 2774, 2704, 2704, 2704,
+     2783, 2783, 2783, 2744, 2784,  922,  920, 2785, 1189, 1189,
+     1189, 2803, 2803, 2803, 2705, 2730, 2730, 2730, 2804, 2804,
+     2804,  919,  916, 2761,  913,  910, 1191, 2732, 2732, 2732,
+      909, 2733,  901,  900, 2734,  899, 2805, 2809, 2809, 2809,
+     2812, 2812, 2812, 2741, 2741, 2741,  893, 2742,  892,  891,
+     2743, 2814, 2814, 2814, 2810,  889,  888, 2813, 2759, 2759,
+     2759, 1397, 1397, 1397, 2767, 2767, 2767,  887, 2815,  886,
+      885, 2834, 2834, 2834, 2792, 2835, 2760,  884, 2836, 1399,
+      879, 2768, 1635, 2769, 2769, 2769,  876, 2770,  878, 1635,
+
+     2771, 2772, 2772, 2772, 2773, 2773, 2773, 2774, 2774, 2774,
+      873, 1635, 2783, 2783, 2783,  872, 2784,  870,  868, 2785,
+      866,  864, 2828, 1633, 1633, 1633, 1633, 1633, 1633, 1633,
+     1633, 1633,  862, 3217, 1633, 2853, 2853, 2853,  859, 1633,
+     1633, 1633, 1635, 1633, 2803, 2803, 2803, 2804, 2804, 2804,
+     2809, 2809, 2809, 2854, 2866, 2866, 2866,  858, 2867,  857,
+      856, 2868, 2812, 2812, 2812, 2805,  855, 2810, 1633, 1633,
+     1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 2813,
+      853, 1633, 2814, 2814, 2814,  852, 1633, 1633, 1633, 1635,
+     1633, 2870, 2870, 2870,  851, 2871,  850,  849, 2872, 2815,
+
+     2873, 2873, 2873,  847, 2874,  846,  845, 2875, 2888, 2888,
+     2888, 2853, 2853, 2853,  844, 1633, 1633, 2834, 2834, 2834,
+      842, 2835,  840,  839, 2836,  837, 2889,  836,  833, 2854,
+     2888, 2888, 2888,  832,  830, 1635, 1633, 1633, 1633, 1633,
+     1633, 2900, 1633, 1633, 1633,  663, 3217, 1633, 2889,  825,
+      823,  819, 1633, 1633, 1633, 1635, 1633, 2866, 2866, 2866,
+      818, 2867,  817,  815, 2868, 2870, 2870, 2870,  813, 2871,
+      812,  811, 2872, 2873, 2873, 2873,  809, 2874,  807,  806,
+     2875, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633,
+     1633, 2900,  804,  802, 1633, 2939, 2939, 2939,  801, 1633,
+
+     1633, 1633, 1635, 1633, 2950, 2950, 2950, 2952, 2952, 2952,
+     2954, 2954, 2954, 1635, 1636, 2962, 2962, 2962, 2972, 2972,
+     2972, 2951,  800,  799, 2953,  798,  797, 2955, 1633, 1633,
+      796,  794, 2963, 2939, 2939, 2939, 1109, 2950, 2950, 2950,
+     2982, 2982, 2982,  792, 2983,  791,  788, 2984, 2952, 2952,
+     2952, 1635,  787,  786, 2951, 2985, 2985, 2985,  784, 2986,
+      775,  774, 2987,  773,  770, 2953, 2954, 2954, 2954, 2988,
+     2988, 2988,  768, 2989,  766,  765, 2990, 2962, 2962, 2962,
+     2972, 2972, 2972, 2955, 1823, 2997, 2997, 2997,  764, 2998,
+      762, 3217, 2999,  759, 2963, 2982, 2982, 2982, 1109, 2983,
+
+      758,  757, 2984, 2985, 2985, 2985,  756, 2986,  755,  753,
+     2987, 2988, 2988, 2988,  751, 2989,  750, 3008, 2990, 2997,
+     2997, 2997,  748, 2998,  746,  745, 2999, 3113, 3113, 3113,
+     3113, 3113, 3113,  743, 3122,  741,  740, 3123, 3215, 3215,
+     3215, 3215, 3215, 3215,  739, 1109,  737,  735, 1109,  734,
+      733,  732,  730, 3217, 3217,  678, 3216,  711,  710, 3216,
+      250,  250,  250,  250,  250,  250,  250,  250,  250,  251,
+      251,  251,  251,  251,  251,  251,  251,  251,  256,  256,
+      256,  256,  256,  256,  256,  256,  256,  259,  259,  259,
+      259,  259,  259,  259,  259,  259,  262,  262,  262,  262,
+
+      262,  262,  262,  262,  262,  265,  265,  265,  265,  265,
+      265,  265,  265,  265,  272,  272,  272,  272,  272,  272,
+      272,  272,  272,  280,  280,  280,  280,  280,  280,  280,
+      280,  280,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  296,  296,  296,  296,  296,  296,  296,  296,  296,
+      300,  300,  300,  300,  300,  300,  300,  300,  300,  307,
+      307,  307,  307,  307,  307,  307,  307,  307,  318,  318,
+      318,  318,  318,  318,  318,  318,  318,  326,  326,  326,
+      326,  326,  326,  326,  326,  326,  332,  332,  332,  332,
+      332,  332,  332,  332,  332,  338,  338,  338,  338,  338,
+
+      338,  338,  338,  338,  344,  344,  344,  344,  344,  344,
+      344,  344,  344,  349,  349,  349,  349,  349,  349,  349,
+      349,  349,  368,  368,  368,  368,  368,  368,  368,  368,
+      368,  375,  375,  375,  375,  375,  375,  375,  375,  375,
+      382,  382,  382,  382,  382,  382,  382,  382,  382,  388,
+      388,  388,  388,  388,  388,  388,  388,  388,  395,  395,
+      395,  395,  395,  395,  395,  395,  395,  400,  400,  400,
+      400,  400,  400,  400,  400,  400,  406,  406,  406,  406,
+      406,  406,  406,  406,  406,  411,  411,  411,  411,  411,
+      411,  411,  411,  411,  417,  417,  417,  417,  417,  417,
+
+      417,  417,  417,  425,  425,  425,  425,  425,  425,  425,
+      425,  425,  433,  433,  433,  433,  433,  433,  433,  433,
+      433,  439,  439,  439,  439,  439,  439,  439,  439,  439,
+      456,  456,  456,  456,  456,  456,  456,  456,  456,  462,
+      462,  462,  462,  462,  462,  462,  462,  462,  471,  471,
+      471,  471,  471,  471,  471,  471,  471,  477,  477,  477,
+      477,  477,  477,  477,  477,  477,  487,  487,  487,  487,
+      487,  487,  487,  487,  487,  493,  493,  493,  493,  493,
+      493,  493,  493,  493,  498,  498,  498,  498,  498,  498,
+      498,  498,  498,  504,  504,  504,  504,  504,  504,  504,
+
+      504,  504,  510,  510,  510,  510,  510,  510,  510,  510,
+      510,  516,  516,  516,  516,  516,  516,  516,  516,  516,
+      523,  523,  523,  523,  523,  523,  523,  523,  523,  530,
+      530,  530,  530,  530,  530,  530,  530,  530,  535,  535,
+      535,  535,  535,  535,  535,  535,  535,  543,  543,  543,
+      543,  543,  543,  543,  543,  543,  549,  549,  549,  549,
+      549,  549,  549,  549,  549,  556,  556,  556,  556,  556,
+      556,  556,  556,  556,  561,  561,  561,  561,  561,  561,
+      561,  561,  561,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  572,  572,  572,  572,  572,  572,  572,  572,
+
+      572,  579,  579,  579,  579,  579,  579,  579,  579,  579,
+      585,  585,  585,  585,  585,  585,  585,  585,  585,  592,
+      592,  592,  592,  592,  592,  592,  592,  592,  600,  600,
+      600,  600,  600,  600,  600,  600,  600,  608,  608,  608,
+      608,  608,  608,  608,  608,  608,  612,  612,  612,  612,
+      612,  612,  612,  612,  612,  618,  618,  618,  618,  618,
+      618,  618,  618,  618,  622,  622,  622,  622,  622,  622,
+      622,  622,  622,  629,  629,  629,  629,  629,  629,  629,
+      629,  629,  634,  634,  634,  634,  634,  634,  634,  634,
+      634,  654,  654,  654,  708,  706,  705,  654,  680,  680,
+
+      680,  704,  702,  698,  680,  684,  684,  684,  694,  693,
+      691,  684,  692,  692,  692,  690,  687,  686,  692,  703,
+      703,  703,  685,  683,  682,  703,  709,  709,  709,  681,
+      679,  674,  709,  731,  731,  731, 3217,  655,  653,  731,
+      738,  738,  738,  651,  645,  644,  738,  744,  744,  744,
+      645,  644,  643,  744,  749,  749,  749,  642, 3217, 3217,
+      749,  754,  754,  754, 3217, 3217, 3217,  754,  763,  763,
+      763, 3217, 3217, 3217,  763,  769,  769,  769, 3217, 3217,
+     3217,  769,  785,  785,  785, 3217, 3217, 3217,  785,  795,
+      795,  795, 3217, 3217, 3217,  795,  805,  805,  805, 3217,
+
+     3217, 3217,  805,  810,  810,  810, 3217, 3217, 3217,  810,
+      816,  816,  816, 3217, 3217, 3217,  816,  824,  824,  824,
+     3217, 3217, 3217,  824,  831,  831,  831, 3217, 3217, 3217,
+      831,  838,  838,  838, 3217, 3217, 3217,  838,  843,  843,
+      843, 3217, 3217, 3217,  843,  848,  848,  848, 3217, 3217,
+     3217,  848,  854,  854,  854, 3217, 3217, 3217,  854,  863,
+      863,  863, 3217, 3217, 3217,  863,  867,  867,  867, 3217,
+     3217, 3217,  867,  871,  871,  871, 3217, 3217, 3217,  871,
+      875,  875,  875,  875,  875,  875,  875, 3217,  875,  654,
+      654,  654, 3217, 3217, 3217,  654,  890, 3217, 3217, 3217,
+
+      890,  680,  680,  680, 3217, 3217, 3217,  680,  921, 3217,
+     3217, 3217,  921,  684,  684,  684, 3217, 3217, 3217,  684,
+      928, 3217, 3217, 3217,  928,  692,  692,  692, 3217, 3217,
+     3217,  692,  940, 3217, 3217, 3217,  940,  703,  703,  703,
+     3217, 3217, 3217,  703,  945, 3217, 3217, 3217,  945,  709,
+      709,  709, 3217, 3217, 3217,  709,  950, 3217, 3217, 3217,
+      950,  731,  731,  731, 3217, 3217, 3217,  731,  970, 3217,
+     3217, 3217,  970,  738,  738,  738, 3217, 3217, 3217,  738,
+      976, 3217, 3217, 3217,  976,  744,  744,  744, 3217, 3217,
+     3217,  744,  981, 3217, 3217, 3217,  981,  749,  749,  749,
+
+     3217, 3217, 3217,  749,  985, 3217, 3217, 3217,  985,  754,
+      754,  754, 3217, 3217, 3217,  754,  994, 3217, 3217, 3217,
+      994,  763,  763,  763, 3217, 3217, 3217,  763, 1003, 3217,
+     3217, 3217, 1003,  769,  769,  769, 3217, 3217, 3217,  769,
+     1020, 3217, 3217, 3217, 1020,  785,  785,  785, 3217, 3217,
+     3217,  785, 1031, 3217, 3217, 3217, 1031,  795,  795,  795,
+     3217, 3217, 3217,  795, 1041, 3217, 3217, 3217, 1041,  805,
+      805,  805, 3217, 3217, 3217,  805, 1046, 3217, 3217, 3217,
+     1046,  810,  810,  810, 3217, 3217, 3217,  810, 1052, 3217,
+     3217, 3217, 1052,  816,  816,  816, 3217, 3217, 3217,  816,
+
+     1060, 3217, 3217, 3217, 1060,  824,  824,  824, 3217, 3217,
+     3217,  824, 1065, 3217, 3217, 3217, 1065,  831,  831,  831,
+     3217, 3217, 3217,  831, 1072, 3217, 3217, 3217, 1072,  838,
+      838,  838, 3217, 3217, 3217,  838, 1077, 3217, 3217, 3217,
+     1077,  843,  843,  843, 3217, 3217, 3217,  843, 1081, 3217,
+     3217, 3217, 1081,  848,  848,  848, 3217, 3217, 3217,  848,
+     1086, 3217, 3217, 3217, 1086,  854,  854,  854, 3217, 3217,
+     3217,  854, 1093, 3217, 3217, 3217, 1093,  863,  863,  863,
+     3217, 3217, 3217,  863, 1097, 3217, 3217, 3217, 1097,  867,
+      867,  867, 3217, 3217, 3217,  867, 1101, 3217, 3217, 3217,
+
+     1101,  871,  871,  871, 3217, 3217, 3217,  871, 1106, 3217,
+     3217, 3217, 1106, 1108, 1108, 1108, 1108, 1108, 1108, 1108,
+     1108, 1108, 1114, 3217, 3217, 3217, 3217, 1114,  654,  654,
+      654, 3217, 3217, 3217,  654, 1123, 1123, 1123, 1123, 3217,
+     3217, 1123, 1123,  680,  680,  680, 3217, 3217, 3217,  680,
+     1157, 1157, 1157, 1157, 3217, 3217, 1157, 1157,  684,  684,
+      684, 3217, 3217, 3217,  684, 1167, 1167, 1167, 1167, 3217,
+     3217, 1167, 1167,  692,  692,  692, 3217, 3217, 3217,  692,
+     1183, 1183, 1183, 1183, 3217, 3217, 1183, 1183,  703,  703,
+      703, 3217, 3217, 3217,  703, 1190, 1190, 1190, 1190, 3217,
+
+     3217, 1190, 1190,  709,  709,  709, 3217, 3217, 3217,  709,
+     1198, 1198, 1198, 1198, 3217, 3217, 1198, 1198,  731,  731,
+      731, 3217, 3217, 3217,  731, 1220, 1220, 1220, 1220, 3217,
+     3217, 1220, 1220,  738,  738,  738, 3217, 3217, 3217,  738,
+     1229, 1229, 1229, 1229, 3217, 3217, 1229, 1229,  744,  744,
+      744, 3217, 3217, 3217,  744, 1237, 1237, 1237, 1237, 3217,
+     3217, 1237, 1237,  749,  749,  749, 3217, 3217, 3217,  749,
+     1243, 1243, 1243, 1243, 3217, 3217, 1243, 1243,  754,  754,
+      754, 3217, 3217, 3217,  754, 1255, 1255, 1255, 1255, 3217,
+     3217, 1255, 1255,  763,  763,  763, 3217, 3217, 3217,  763,
+
+     1268, 1268, 1268, 1268, 3217, 3217, 1268, 1268,  769,  769,
+      769, 3217, 3217, 3217,  769, 1292, 1292, 1292, 1292, 3217,
+     3217, 1292, 1292,  785,  785,  785,  785, 3217,  785, 3217,
+      785, 1308, 1308, 1308, 1308, 3217, 3217, 1308, 1308,  795,
+      795,  795, 3217, 3217, 3217,  795, 1323, 1323, 1323, 1323,
+     3217, 3217, 1323, 1323,  805,  805,  805, 3217, 3217, 3217,
+      805, 1331, 1331, 1331, 1331, 3217, 3217, 1331, 1331,  810,
+      810,  810, 3217, 3217, 3217,  810, 1340, 1340, 1340, 1340,
+     3217, 3217, 1340, 1340,  816,  816,  816, 3217, 3217, 3217,
+      816, 1351, 1351, 1351, 1351, 3217, 3217, 1351, 1351,  824,
+
+      824,  824,  824, 3217,  824, 3217,  824, 1360, 1360, 1360,
+     1360, 3217, 3217, 1360, 1360,  831,  831,  831,  831, 3217,
+      831, 3217,  831, 1372, 1372, 1372, 1372, 3217, 3217, 1372,
+     1372,  838,  838,  838, 3217, 3217, 3217,  838, 1380, 1380,
+     1380, 1380, 3217, 3217, 1380, 1380,  843,  843,  843,  843,
+     3217,  843, 3217,  843, 1388, 1388, 1388, 1388, 3217, 3217,
+     1388, 1388,  848,  848,  848,  848, 3217,  848, 3217,  848,
+     1398, 1398, 1398, 1398, 3217, 3217, 1398, 1398,  854,  854,
+      854, 3217, 3217, 3217,  854, 1407, 1407, 1407, 1407, 3217,
+     3217, 1407, 1407,  863,  863,  863, 3217, 3217, 3217,  863,
+
+     1413, 1413, 1413, 1413, 3217, 3217, 1413, 1413, 1420, 1420,
+     1420, 1420, 3217, 3217, 1420, 1420,  871,  871,  871, 3217,
+     3217, 3217,  871, 1428, 1428, 1428, 1428, 3217, 3217, 1428,
+     1428, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108,
+     1114, 3217, 1114, 3217, 3217, 1114,  654,  654,  654, 3217,
+     3217, 3217,  654, 1123, 1123, 1123, 1123, 3217, 3217, 1123,
+     1123,  680,  680,  680,  680, 3217,  680, 3217,  680, 1157,
+     1157, 1157, 1157, 3217, 3217, 1157, 1157,  684,  684,  684,
+      684, 3217,  684, 3217,  684, 1167, 1167, 1167, 1167, 3217,
+     3217, 1167, 1167,  692,  692,  692, 3217, 3217, 3217,  692,
+
+     1183, 1183, 1183, 1183, 3217, 3217, 1183, 1183,  703,  703,
+      703, 3217, 3217, 3217,  703, 1190, 1190, 1190, 1190, 3217,
+     3217, 1190, 1190,  709,  709,  709, 3217, 3217, 3217,  709,
+     1198, 1198, 1198, 1198, 3217, 3217, 1198, 1198,  731,  731,
+      731, 3217, 3217, 3217,  731, 1220, 1220, 1220, 1220, 3217,
+     3217, 1220, 1220,  738,  738,  738, 3217, 3217, 3217,  738,
+     1229, 1229, 1229, 1229, 3217, 3217, 1229, 1229,  744,  744,
+      744,  744, 3217,  744, 3217,  744, 1237, 1237, 1237, 1237,
+     3217, 3217, 1237, 1237,  749,  749,  749,  749, 3217,  749,
+     3217,  749, 1243, 1243, 1243, 1243, 3217, 3217, 1243, 1243,
+
+      754,  754,  754, 3217, 3217, 3217,  754, 1255, 1255, 1255,
+     1255, 3217, 3217, 1255, 1255,  763,  763,  763,  763, 3217,
+      763, 3217,  763, 1268, 1268, 1268, 1268, 3217, 3217, 1268,
+     1268,  769,  769,  769, 3217, 3217, 3217,  769, 1292, 1292,
+     1292, 1292, 3217, 3217, 1292, 1292,  785,  785,  785, 3217,
+     3217, 3217,  785, 1308, 1308, 1308, 1308, 3217, 3217, 1308,
+     1308,  795,  795,  795, 3217, 3217, 3217,  795, 1323, 1323,
+     1323, 1323, 3217, 3217, 1323, 1323,  805,  805,  805, 3217,
+     3217, 3217,  805, 1331, 1331, 1331, 1331, 3217, 3217, 1331,
+     1331,  810,  810,  810, 3217, 3217, 3217,  810, 1340, 1340,
+
+     1340, 1340, 3217, 3217, 1340, 1340,  816,  816,  816, 3217,
+     3217, 3217,  816, 1351, 1351, 1351, 1351, 3217, 3217, 1351,
+     1351,  824,  824,  824, 3217, 3217, 3217,  824, 1360, 1360,
+     1360, 1360, 3217, 3217, 1360, 1360,  831,  831,  831, 3217,
+     3217, 3217,  831, 1372, 1372, 1372, 1372, 3217, 3217, 1372,
+     1372,  838,  838,  838, 3217, 3217, 3217,  838, 1380, 1380,
+     1380, 1380, 3217, 3217, 1380, 1380, 1388, 1388, 1388, 1388,
+     3217, 3217, 1388, 1388,  848,  848,  848, 3217, 3217, 3217,
+      848, 1398, 1398, 1398, 1398, 3217, 3217, 1398, 1398,  854,
+      854,  854, 3217, 3217, 3217,  854, 1407, 1407, 1407, 1407,
+
+     3217, 3217, 1407, 1407,  863,  863,  863, 3217, 3217, 3217,
+      863, 1413, 1413, 1413, 1413, 3217, 3217, 1413, 1413, 1420,
+     1420, 1420, 1420, 3217, 3217, 1420, 1420,  871,  871,  871,
+     3217, 3217, 3217,  871, 1428, 1428, 1428, 1428, 3217, 3217,
+     1428, 1428, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108,
+     1108, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633,
+      654,  654,  654, 3217, 3217, 3217,  654, 1123, 1123, 1123,
+     1123, 3217, 3217, 1123, 1123, 1157, 1157, 1157, 1157, 3217,
+     3217, 1157, 1157,  684,  684,  684, 3217, 3217, 3217,  684,
+     1167, 1167, 1167, 1167, 3217, 3217, 1167, 1167,  692,  692,
+
+      692, 3217, 3217, 3217,  692, 1183, 1183, 1183, 1183, 3217,
+     3217, 1183, 1183,  703,  703,  703, 3217, 3217, 3217,  703,
+     1190, 1190, 1190, 1190, 3217, 3217, 1190, 1190,  709,  709,
+      709, 3217, 3217, 3217,  709,  731,  731,  731, 3217, 3217,
+     3217,  731, 1220, 1220, 1220, 1220, 3217, 3217, 1220, 1220,
+      738,  738,  738, 3217, 3217, 3217,  738, 1229, 1229, 1229,
+     1229, 3217, 3217, 1229, 1229, 1237, 1237, 1237, 1237, 3217,
+     3217, 1237, 1237,  749,  749,  749, 3217, 3217, 3217,  749,
+     1243, 1243, 1243, 1243, 3217, 3217, 1243, 1243,  754,  754,
+      754, 3217, 3217, 3217,  754, 1255, 1255, 1255, 1255, 3217,
+
+     3217, 1255, 1255, 1268, 1268, 1268, 1268, 3217, 3217, 1268,
+     1268,  769,  769,  769, 3217, 3217, 3217,  769, 1292, 1292,
+     1292, 1292, 3217, 3217, 1292, 1292,  785,  785,  785,  785,
+     3217,  785, 3217,  785, 1308, 1308, 1308, 1308, 3217, 3217,
+     1308, 1308,  795,  795,  795, 3217, 3217, 3217,  795, 1323,
+     1323, 1323, 1323, 3217, 3217, 1323, 1323,  805,  805,  805,
+     3217, 3217, 3217,  805, 1331, 1331, 1331, 1331, 3217, 3217,
+     1331, 1331,  810,  810,  810, 3217, 3217, 3217,  810, 1340,
+     1340, 1340, 1340, 3217, 3217, 1340, 1340,  816,  816,  816,
+     3217, 3217, 3217,  816, 1351, 1351, 1351, 1351, 3217, 3217,
+
+     1351, 1351,  824,  824,  824, 3217, 3217, 3217,  824, 1360,
+     1360, 1360, 1360, 3217, 3217, 1360, 1360,  831,  831,  831,
+     3217, 3217, 3217,  831, 1372, 1372, 1372, 1372, 3217, 3217,
+     1372, 1372,  838,  838,  838, 3217, 3217, 3217,  838, 1380,
+     1380, 1380, 1380, 3217, 3217, 1380, 1380, 1388, 1388, 1388,
+     1388, 3217, 3217, 1388, 1388,  848,  848,  848, 3217, 3217,
+     3217,  848, 1398, 1398, 1398, 1398, 3217, 3217, 1398, 1398,
+      854,  854,  854, 3217, 3217, 3217,  854, 1407, 1407, 1407,
+     1407, 3217, 3217, 1407, 1407,  863,  863,  863,  863, 3217,
+      863, 3217,  863, 1413, 1413, 1413, 1413, 3217, 3217, 1413,
+
+     1413, 1420, 1420, 1420, 1420, 3217, 3217, 1420, 1420,  871,
+      871,  871,  871, 3217,  871, 3217,  871, 1428, 1428, 1428,
+     1428, 3217, 3217, 1428, 1428, 1108, 1108, 1108, 1108, 1108,
+     1108, 1108, 1108, 1108, 1633, 1633, 1633, 1633, 1633, 1633,
+     1633, 1633, 1633,  654,  654,  654, 3217, 3217, 3217,  654,
+     1123, 1123, 1123, 1123, 3217, 3217, 1123, 1123, 1157, 1157,
+     1157, 1157, 3217, 3217, 1157, 1157,  684,  684,  684, 3217,
+     3217, 3217,  684, 1167, 1167, 1167, 1167, 3217, 3217, 1167,
+     1167,  692,  692,  692, 3217, 3217, 3217,  692, 1183, 1183,
+     1183, 1183, 3217, 3217, 1183, 1183,  703,  703,  703, 3217,
+
+     3217, 3217,  703, 1190, 1190, 1190, 1190, 3217, 3217, 1190,
+     1190,  709,  709,  709, 3217, 3217, 3217,  709,  731,  731,
+      731, 3217, 3217, 3217,  731, 1220, 1220, 1220, 1220, 3217,
+     3217, 1220, 1220,  738,  738,  738, 3217, 3217, 3217,  738,
+     1229, 1229, 1229, 1229, 3217, 3217, 1229, 1229, 1237, 1237,
+     1237, 1237, 3217, 3217, 1237, 1237,  749,  749,  749,  749,
+     3217,  749, 3217,  749, 1243, 1243, 1243, 1243, 3217, 3217,
+     1243, 1243,  754,  754,  754, 3217, 3217, 3217,  754, 1255,
+     1255, 1255, 1255, 3217, 3217, 1255, 1255, 1268, 1268, 1268,
+     1268, 3217, 3217, 1268, 1268,  769,  769,  769, 3217, 3217,
+
+     3217,  769, 1292, 1292, 1292, 1292, 3217, 3217, 1292, 1292,
+      785,  785,  785,  785, 3217,  785, 3217,  785, 1308, 1308,
+     1308, 1308, 3217, 3217, 1308, 1308,  795,  795,  795, 3217,
+     3217, 3217,  795, 1323, 1323, 1323, 1323, 3217, 3217, 1323,
+     1323,  805,  805,  805, 3217, 3217, 3217,  805, 1331, 1331,
+     1331, 1331, 3217, 3217, 1331, 1331,  810,  810,  810, 3217,
+     3217, 3217,  810, 1340, 1340, 1340, 1340, 3217, 3217, 1340,
+     1340,  816,  816,  816, 3217, 3217, 3217,  816, 1351, 1351,
+     1351, 1351, 3217, 3217, 1351, 1351,  824,  824,  824, 3217,
+     3217, 3217,  824, 1360, 1360, 1360, 1360, 3217, 3217, 1360,
+
+     1360,  831,  831,  831,  831, 3217,  831, 3217,  831, 1372,
+     1372, 1372, 1372, 3217, 3217, 1372, 1372,  838,  838,  838,
+     3217, 3217, 3217,  838, 1380, 1380, 1380, 1380, 3217, 3217,
+     1380, 1380, 1388, 1388, 1388, 1388, 3217, 3217, 1388, 1388,
+      848,  848,  848,  848, 3217,  848, 3217,  848, 1398, 1398,
+     1398, 1398, 3217, 3217, 1398, 1398,  854,  854,  854, 3217,
+     3217, 3217,  854, 1407, 1407, 1407, 1407, 3217, 3217, 1407,
+     1407, 1413, 1413, 1413, 1413, 3217, 3217, 1413, 1413, 1420,
+     1420, 1420, 1420, 3217, 3217, 1420, 1420, 1428, 1428, 1428,
+     1428, 3217, 3217, 1428, 1428, 1108, 1108, 1108, 1108, 1108,
+
+     1108, 1108, 1108, 1108, 1633, 1633, 1633, 1633, 1633, 1633,
+     1633, 1633, 1633,  654,  654,  654,  654, 3217,  654, 3217,
+      654, 1123, 1123, 1123, 1123, 3217, 3217, 1123, 1123, 1157,
+     1157, 1157, 1157, 3217, 3217, 1157, 1157,  684,  684,  684,
+     3217, 3217, 3217,  684, 1167, 1167, 1167, 1167, 3217, 3217,
+     1167, 1167,  692,  692,  692, 3217, 3217, 3217,  692, 1183,
+     1183, 1183, 1183, 3217, 3217, 1183, 1183,  703,  703,  703,
+      703, 3217,  703, 3217,  703, 1190, 1190, 1190, 1190, 3217,
+     3217, 1190, 1190,  709,  709,  709,  709, 3217,  709, 3217,
+      709,  731,  731,  731,  731, 3217,  731, 3217,  731, 1220,
+
+     1220, 1220, 1220, 3217, 3217, 1220, 1220,  738,  738,  738,
+      738, 3217,  738, 3217,  738, 1229, 1229, 1229, 1229, 3217,
+     3217, 1229, 1229, 1237, 1237, 1237, 1237, 3217, 3217, 1237,
+     1237, 1243, 1243, 1243, 1243, 3217, 3217, 1243, 1243,  754,
+      754,  754, 3217, 3217, 3217,  754, 1268, 1268, 1268, 1268,
+     3217, 3217, 1268, 1268,  769,  769,  769, 3217, 3217, 3217,
+      769, 1292, 1292, 1292, 1292, 3217, 3217, 1292, 1292,  785,
+      785,  785,  785, 3217,  785, 3217,  785, 1308, 1308, 1308,
+     1308, 3217, 3217, 1308, 1308,  795,  795,  795, 3217, 3217,
+     3217,  795,  805,  805,  805, 3217, 3217, 3217,  805, 1331,
+
+     1331, 1331, 1331, 3217, 3217, 1331, 1331,  810,  810,  810,
+     3217, 3217, 3217,  810, 1340, 1340, 1340, 1340, 3217, 3217,
+     1340, 1340,  816,  816,  816, 3217, 3217, 3217,  816,  824,
+      824,  824, 3217, 3217, 3217,  824, 1360, 1360, 1360, 1360,
+     3217, 3217, 1360, 1360,  831,  831,  831, 3217, 3217, 3217,
+      831, 1372, 1372, 1372, 1372, 3217, 3217, 1372, 1372,  838,
+      838,  838, 3217, 3217, 3217,  838, 1380, 1380, 1380, 1380,
+     3217, 3217, 1380, 1380, 1388, 1388, 1388, 1388, 3217, 3217,
+     1388, 1388, 1398, 1398, 1398, 1398, 3217, 3217, 1398, 1398,
+      854,  854,  854, 3217, 3217, 3217,  854, 1407, 1407, 1407,
+
+     1407, 3217, 3217, 1407, 1407, 1413, 1413, 1413, 1413, 3217,
+     3217, 1413, 1413, 1420, 1420, 1420, 1420, 3217, 3217, 1420,
+     1420, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108,
+     1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1123,
+     1123, 1123, 1123, 3217, 3217, 1123, 1123, 1157, 1157, 1157,
+     1157, 3217, 3217, 1157, 1157,  684,  684,  684, 3217, 3217,
+     3217,  684,  692,  692,  692, 3217, 3217, 3217,  692, 1183,
+     1183, 1183, 1183, 3217, 3217, 1183, 1183, 1190, 1190, 1190,
+     1190, 3217, 3217, 1190, 1190, 1220, 1220, 1220, 1220, 3217,
+     3217, 1220, 1220, 1229, 1229, 1229, 1229, 3217, 3217, 1229,
+
+     1229, 1243, 1243, 1243, 1243, 3217, 3217, 1243, 1243,  754,
+      754,  754, 3217, 3217, 3217,  754, 1268, 1268, 1268, 1268,
+     3217, 3217, 1268, 1268,  769,  769,  769, 3217, 3217, 3217,
+      769, 1292, 1292, 1292, 1292, 3217, 3217, 1292, 1292, 1308,
+     1308, 1308, 1308, 3217, 3217, 1308, 1308,  795,  795,  795,
+     3217, 3217, 3217,  795,  805,  805,  805, 3217, 3217, 3217,
+      805, 1331, 1331, 1331, 1331, 3217, 3217, 1331, 1331,  810,
+      810,  810, 3217, 3217, 3217,  810, 1340, 1340, 1340, 1340,
+     3217, 3217, 1340, 1340,  816,  816,  816, 3217, 3217, 3217,
+      816,  824,  824,  824, 3217, 3217, 3217,  824,  831,  831,
+
+      831, 3217, 3217, 3217,  831, 1372, 1372, 1372, 1372, 3217,
+     3217, 1372, 1372,  838,  838,  838, 3217, 3217, 3217,  838,
+     1380, 1380, 1380, 1380, 3217, 3217, 1380, 1380, 1388, 1388,
+     1388, 1388, 3217, 3217, 1388, 1388, 1398, 1398, 1398, 1398,
+     3217, 3217, 1398, 1398,  854,  854,  854,  854, 3217,  854,
+     3217,  854, 1407, 1407, 1407, 1407, 3217, 3217, 1407, 1407,
+     1413, 1413, 1413, 1413, 3217, 3217, 1413, 1413, 1420, 1420,
+     1420, 1420, 3217, 3217, 1420, 1420, 1108, 1108, 1108, 1108,
+     1108, 1108, 1108, 1108, 1108, 1633, 1633, 1633, 1633, 1633,
+     1633, 1633, 1633, 1633, 1123, 1123, 1123, 1123, 3217, 3217,
+
+     1123, 1123, 1157, 1157, 1157, 1157, 3217, 3217, 1157, 1157,
+      684,  684,  684, 3217, 3217, 3217,  684,  692,  692,  692,
+      692, 3217,  692, 3217,  692, 1190, 1190, 1190, 1190, 3217,
+     3217, 1190, 1190, 1220, 1220, 1220, 1220, 3217, 3217, 1220,
+     1220, 1229, 1229, 1229, 1229, 3217, 3217, 1229, 1229, 1243,
+     1243, 1243, 1243, 3217, 3217, 1243, 1243,  754,  754,  754,
+     3217, 3217, 3217,  754, 1268, 1268, 1268, 1268, 3217, 3217,
+     1268, 1268,  769,  769,  769, 3217, 3217, 3217,  769, 1292,
+     1292, 1292, 1292, 3217, 3217, 1292, 1292, 1308, 1308, 1308,
+     1308, 3217, 3217, 1308, 1308,  795,  795,  795, 3217, 3217,
+
+     3217,  795,  805,  805,  805, 3217, 3217, 3217,  805,  810,
+      810,  810,  810, 3217,  810, 3217,  810, 1340, 1340, 1340,
+     1340, 3217, 3217, 1340, 1340,  816,  816,  816,  816, 3217,
+      816, 3217,  816,  824,  824,  824, 3217, 3217, 3217,  824,
+      831,  831,  831, 3217, 3217, 3217,  831, 1372, 1372, 1372,
+     1372, 3217, 3217, 1372, 1372,  838,  838,  838,  838, 3217,
+      838, 3217,  838, 1380, 1380, 1380, 1380, 3217, 3217, 1380,
+     1380, 1388, 1388, 1388, 1388, 3217, 3217, 1388, 1388, 1398,
+     1398, 1398, 1398, 3217, 3217, 1398, 1398,  854,  854,  854,
+      854, 3217,  854, 3217,  854, 1407, 1407, 1407, 1407, 3217,
+
+     3217, 1407, 1407, 1413, 1413, 1413, 1413, 3217, 3217, 1413,
+     1413, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108,
+     1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1633, 1123,
+     1123, 1123, 1123, 3217, 3217, 1123, 1123,  684,  684,  684,
+     3217, 3217, 3217,  684,  692,  692,  692, 3217, 3217, 3217,
+      692, 1190, 1190, 1190, 1190, 3217, 3217, 1190, 1190, 1220,
+     1220, 1220, 1220, 3217, 3217, 1220, 1220, 1243, 1243, 1243,
+     1243, 3217, 3217, 1243, 1243,  754,  754,  754, 3217, 3217,
+     3217,  754, 1268, 1268, 1268, 1268, 3217, 3217, 1268, 1268,
+      769,  769,  769, 3217, 3217, 3217,  769, 2837, 2837, 2837,
+
+     2837, 2837, 2837, 2837, 2837, 2837, 2838, 2838, 2838, 2838,
+     2838, 2838, 2838, 2838, 2838, 2895, 2895, 2895, 2895, 2895,
+     2895, 2895, 2895, 2895, 2898, 2898, 2898, 2898, 2898, 2898,
+     2898, 2898, 2898, 2936, 2936, 2936, 2936, 2936, 2936, 2936,
+     2936, 2936, 2938, 2938, 2938, 2938, 2938, 2938, 2938, 2938,
+     2938,  249, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217
     } ;
 
-static yyconst flex_int16_t yy_chk[11810] =
+static yyconst flex_int16_t yy_chk[11827] =
     {   0,
         0,    3,    3,    3,    4,    4,    4,    5,    5,    5,
         6,    6,    6,    7,    7,    7,   11,    3,    9,   12,
@@ -2943,10 +2945,10 @@ static yyconst flex_int16_t yy_chk[11810] =
         8,    8,    8,  254,   11,   13,   13,   12,   14,   14,
        13,   13,  303,   14,   14,  255,    8,   17,   17,  254,
        13,   15,   15,   14,   15,  258,   15,   16,   16,  357,
-       16,  255,   16,   18,   18, 1503,   15,   19,   19,   19,
+       16,  255,   16,   18,   18,    0,   15,   19,   19,   19,
       522,  258,   16,   20,   20,   20,   23,   23,   23,   24,
-       24,   24,  522,   19,   25,   25,   25,  357, 1504,   20,
-      364,   17,   23, 1033,  303,   24,  252,  252,  252, 1033,
+       24,   24,  522,   19,   25,   25,   25,  357, 1500,   20,
+      364,   17,   23, 1034,  303,   24,  252,  252,  252, 1034,
 
        25,  253,  253,  253,  257,  257,  257,   18,   21,   21,
        21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
@@ -2955,15 +2957,15 @@ static yyconst flex_int16_t yy_chk[11810] =
        29,   29,   30,   30,   30,   26,  364,  429,   27,  281,
       429,   28,  659,   21,   21,   29,  297,  276,   30,   31,
        31,   31,  278,  278,  278,  281,  285,  285,  285,  294,
-      294,  294,  297,  276,  328,   31,  659,   21,   22,   22,
+      294,  294,  297,  276,  353,   31,  659,   21,   22,   22,
        22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
-       22,   22,   22, 1505,   22,   22,   22,   22,   22,   32,
+       22,   22,   22, 1504,   22,   22,   22,   22,   22,   32,
 
        32,   32,   33,   33,   33,   34,   34,   34,  268,   35,
        35,   35,   36,   36,   36,   32,  276,  356,   33,  453,
-      715,   34,  453,   22,   22,   35,  328,  356,   36,   37,
+      714,   34,  453,   22,   22,   35,  353,  356,   36,   37,
        37,   37,   38,   38,   38,   39,   39,   39,   40,   40,
-       40,   41,   41,   41,  715,   37,  534,   22,   38,  308,
+       40,   41,   41,   41,  714,   37,  534,   22,   38,  308,
       268,   39,  449,  534,   40,  356,  268,   41,   42,   42,
        42,  268,  301,  301,  301,  308,  268,  305,  305,  305,
       316,  316,  316,  449,   42,   43,   43,   43,   43,   43,
@@ -2972,161 +2974,161 @@ static yyconst flex_int16_t yy_chk[11810] =
 
        46,   46,   47,   47,   47,  325,   48,   48,   48,   49,
        49,   49,   45,  468,  647,   46,  468,  647,   47,  323,
-       43,   43,   48,  323,  329,   49,  289,  323,   43,   44,
+       43,   43,   48,  323,  377,   49,  289,  323,   43,   44,
        44,   44,   44,   44,   44,   44,   44,   44,   44,   44,
        44,   44,   44,   44,  319,   44,   44,   44,   44,   44,
        50,   50,   50,   51,   51,   51,   52,   52,   52,  454,
       319,  624,   55,   55,  548,  289,   50,   55,  290,   51,
-     1506,  548,   52,  454,   44,   44,  329,   55,  289,  330,
+     1505,  548,   52,  454,   44,   44,  377,   55,  289,  378,
       289,  688,   44,   53,   53,   53,   53,   53,   53,   53,
        53,   53,   53,   53,   53,   53,   53,   53,  624,   53,
 
-       53,   53,   53,   53, 1507,  335,   55,  290,   59,   59,
-       59,   60,   60,   60,   61,   61,   61,  688,   56,   56,
-      290,  335,  290,   56,   59,  313,  666,   60,   53,   53,
-       61,  330,  313,   56,  664, 1508,   53,  377,  664,   53,
-      666,  313,  327,  327,  327, 1509,   53,   54,   54,   54,
+       53,   53,   53,   53, 1506,  333,   55,  290,   59,   59,
+       59,   60,   60,   60,   63,   63,   63,  688,   56,   56,
+      290,  333,  290,   56,   59,  313,  666,   60,   53,   53,
+       63,  378,  313,   56,  664, 1507,   53,  390,  664,   53,
+      666,  313,  327,  327,  327, 1508,   53,   54,   54,   54,
        54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   54,   56,   54,   54,   54,   54,   54,   62,   62,
-       62,   63,   63,   63,   64,   64,   64,  670,   65,   65,
-       65,   66,   66,   66,   62,  347,  369,   63,  359,  377,
-       64,  670,   54,   54,   65, 1514,  755,   66,  359,  755,
+       54,   54,   56,   54,   54,   54,   54,   54,   64,   64,
+       64,   67,   67,   67,   68,   68,   68,  525,   69,   69,
+       69,   70,   70,   70,   64,  345,  369,   67,  328,  390,
+       68, 1509,   54,   54,   69,  328,  756,   70, 1510,  756,
 
-       54,  347,  369,   54,  332,  332,  332,  341,  341,  341,
+       54,  345,  369,   54,  328,  330,  330,  330,  391, 1515,
        54,   57,   57,   57,   57,   57,   57,   57,   57,   57,
-       57,   57,   57,   57,   57,   57,  359,   57,   57,   57,
-       57,   57,   69,   69,   69,   70,   70,   70,   73,   73,
-       73,  718,   74,   74,   74,   75,   75,   75,   69, 1515,
-      383,   70,  342,  396,   73,  718,   57,   57,   74,  342,
-      604,   75,  344,  344,  344,   57,  383,   57,  342,  396,
-      525,   57,  352,  352,  352,  604,   57,   57,   58,   58,
+       57,   57,   57,   57,   57,   57,  525,   57,   57,   57,
+       57,   57,   71,   71,   71,   72,   72,   72,   73,   73,
+       73, 1516,   74,   74,   74,   75,   75,   75,   71, 1523,
+      383,   72,  340,  396,   73,  604,   57,   57,   74,  340,
+      391,   75,  339,  339,  339,   57,  383,   57,  340,  396,
+      604,   57,  342,  342,  342, 1525,   57,   57,   58,   58,
        58,   58,   58,   58,   58,   58,   58,   58,   58,   58,
        58,   58,   58,  361,   58,   58,   58,   58,   58,   76,
 
-       76,   76,   77,   77,   77,   78,   78,   78,  378,   79,
-       79,   79,   80,   80,   80,   76,  355, 1522,   77,  525,
-      407,   78,  361,   58,   58,   79,  355,  361,   80,  366,
-      366,  366,   58,  355,   58,  361,  407,  361,   58,  376,
-      376,  376,  390,   58,   58,   67,   67,   67,   67,   67,
-       67,   67,   67,   67,   67,   67,   67,   67,   67,   67,
-      378,   67,   67,   67,   67,   67,   81,   81,   81,   82,
-       82,   82,   83,   83,   83,  725,   84,   84,   84,   85,
-       85,   85,   81, 1140, 1524,   82,  638,  721,   83,  725,
-       67,   67,   84, 1525,  390,   85, 1140,   67,  380,  380,
-
-      380,  638,  391,   67,  389,  389,  389,  393,  393,  393,
-      526,  721,   67,   68,   68,   68,   68,   68,   68,   68,
-       68,   68,   68,   68,   68,   68,   68,   68,  722,   68,
-       68,   68,   68,   68,   86,   86,   86,   87,   87,   87,
-       88,   88,   88, 1531,   89,   89,   89,   90,   90,   90,
-       86, 1532,  722,   87,  391,  727,   88,  402,   68,   68,
-       89, 1536,  526,   90,  402,   68,  401,  401,  401,  727,
-     1538,   68,  552,  402,  404,  404,  404,  412,  412,  412,
-       68,   71,   71,   71,   71,   71,   71,   71,   71,   71,
-       71,   71,   71,   71,   71,   71, 1539,   71,   71,   71,
-
-       71,   71,   91,   91,   91,   92,   92,   92,   93,   93,
-       93, 1546,   94,   94,   94,   95,   95,   95,   91,  418,
-      552,   92,  413, 1547,   93,  625,   71,   71,   94,  413,
-     1548,   95,  415,  415,  415,  418,  427,   71,  413,  426,
-      426,  426,  431,  431,  431, 1549,   71,   72,   72,   72,
-       72,   72,   72,   72,   72,   72,   72,   72,   72,   72,
-       72,   72,  575,   72,   72,   72,   72,   72,   96,   96,
+       76,   76,   77,   77,   77,   78,   78,   78,  526,   79,
+       79,   79,   80,   80,   80,   76,  355, 1526,   77, 1532,
+      407,   78,  361,   58,   58,   79,  355,  361,   80,  350,
+      350,  350,   58,  355,   58,  361,  407,  361,   58,  366,
+      366,  366, 1533,   58,   58,   61,   61,   61,   61,   61,
+       61,   61,   61,   61,   61,   61,   61,   61,   61,   61,
+      526,   61,   61,   61,   61,   61,   81,   81,   81,   82,
+       82,   82,   83,   83,   83,  670,   84,   84,   84,   85,
+       85,   85,   81,  761, 1537,   82,  402,  761,   83,  670,
+       61,   61,   84,  402,  413,   85,  638,   61,  376,  376,
+
+      376,  413,  402,   61,  380,  380,  380,  389,  389,  389,
+      413,  638,   61,   62,   62,   62,   62,   62,   62,   62,
+       62,   62,   62,   62,   62,   62,   62,   62,  722,   62,
+       62,   62,   62,   62,   86,   86,   86,   87,   87,   87,
+       88,   88,   88,  718,   89,   89,   89,   90,   90,   90,
+       86, 1141,  722,   87,  418,  723,   88,  718,   62,   62,
+       89, 1539,  434,   90, 1141,   62,  393,  393,  393, 1540,
+      418,   62,  401,  401,  401,  404,  404,  404,  434,  723,
+       62,   65,   65,   65,   65,   65,   65,   65,   65,   65,
+       65,   65,   65,   65,   65,   65,  552,   65,   65,   65,
+
+       65,   65,   91,   91,   91,   92,   92,   92,   93,   93,
+       93, 1547,   94,   94,   94,   95,   95,   95,   91,  446,
+     1548,   92, 1549, 1550,   93,  625,   65,   65,   94,  463,
+     1551,   95,  412,  412,  412,  446,  427,   65,  415,  415,
+      415,  426,  426,  426,  552,  463,   65,   66,   66,   66,
+       66,   66,   66,   66,   66,   66,   66,   66,   66,   66,
+       66,   66,  575,   66,   66,   66,   66,   66,   96,   96,
        96,   97,   97,   97,   98,   98,   98,  625,   99,   99,
-       99,  100,  100,  100,   96,  427,  434,   97,  427,  723,
-       98, 1550,   72,   72,   99,  446, 1551,  100,  101,  101,
+       99,  100,  100,  100,   96,  427, 1552,   97,  427,  724,
+       98, 1562,   66,   66,   99,  441, 1564,  100,  101,  101,
 
-      101, 1561,  434,   72,  102,  102,  102,  440,  440,  440,
-      575,  446,   72,  723,  101,  443,  443,  443,  362, 1563,
+      101, 1565,  441,   66,  102,  102,  102,  431,  431,  431,
+      575,  441,   66,  724,  101,  440,  440,  440,  362, 1570,
       102,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  724,  103,  103,  103,
+      103,  103,  103,  103,  103,  103, 1572,  103,  103,  103,
       103,  103,  105,  105,  105,  106,  106,  106,  107,  107,
-      107, 1564,  108,  108,  108,  588,  362,  463,  105, 1430,
-      724,  106,  441,  455,  107, 1569,  103,  103,  108,  441,
-      478,  103,  362,  463,  537,  455,  455,  103,  441, 1430,
-     1571,  103,  457,  457,  457, 1573,  478,  103,  104,  104,
+      107, 1111,  108,  108,  108, 1111,  362,  455,  105,  726,
+      478,  106,  725, 1574,  107,  359,  103,  103,  108,  455,
+      455,  103,  362,  726,  537,  359,  478,  103,  443,  443,
+      443,  103,  457,  457,  457, 1575,  725,  103,  104,  104,
       104,  104,  104,  104,  104,  104,  104,  104,  104,  104,
 
-      104,  104,  104,  588,  104,  104,  104,  104,  104,  109,
+      104,  104,  104,  359,  104,  104,  104,  104,  104,  109,
       109,  109,  110,  110,  110,  111,  111,  111,  660,  112,
-      112,  112,  537,  458, 1574,  109,  537, 1576,  110,  660,
+      112,  112,  537,  458, 1577,  109,  537, 1578,  110,  660,
       458,  111,  660,  104,  104,  112,  473,  494,  104,  458,
       460,  460,  460,  473,  104,  472,  472,  472,  104,  475,
       475,  475,  473,  494,  104,  113,  113,  113,  113,  113,
       113,  113,  113,  113,  113,  113,  113,  113,  113,  113,
-     1577,  113,  113,  113,  113,  113,  115,  115,  115,  116,
-      116,  116,  117,  117,  117, 1578,  118,  118,  118,  488,
-      488,  488,  115,  505,  517,  116,  489, 1587,  117, 1593,
+     1579,  113,  113,  113,  113,  113,  115,  115,  115,  116,
+      116,  116,  117,  117,  117,  728,  118,  118,  118,  488,
+      488,  488,  115,  505,  517,  116,  489, 1588,  117,  728,
 
       113,  113,  118,  489, 1594,  113,  491,  491,  491,  505,
       517,  113,  489,  499,  499,  499,  502,  502,  502,  511,
       511,  511,  113,  114,  114,  114,  114,  114,  114,  114,
-      114,  114,  114,  114,  114,  114,  114,  114, 1598,  114,
+      114,  114,  114,  114,  114,  114,  114,  114, 1595,  114,
       114,  114,  114,  114,  119,  119,  119,  120,  120,  120,
-      121,  121,  121,  760,  122,  122,  122,  760,  500, 1152,
-      119, 1600,  531,  120,  512,  500,  121, 1612,  114,  114,
-      122,  512, 1152,  114,  500,  514,  514,  514,  531,  114,
+      121,  121,  121, 1599,  122,  122,  122, 1601,  500, 1153,
+      119, 1613,  531,  120,  512,  500,  121, 1614,  114,  114,
+      122,  512, 1153,  114,  500,  514,  514,  514,  531,  114,
       512,  524,  524,  524,  528,  528,  528,  536,  536,  536,
       114,  123,  123,  123,  123,  123,  123,  123,  123,  123,
 
-      123,  123,  123,  123,  123,  123, 1613,  123,  123,  123,
+      123,  123,  123,  123,  123,  123, 1619,  123,  123,  123,
       123,  123,  125,  125,  125,  126,  126,  126,  129,  129,
-      129, 1618,  130,  130,  130,  133,  133,  133,  125,  544,
-      557,  126, 1621, 1622,  129,  568,  123,  123,  130, 1623,
-     1625,  133,  541,  541,  541,  544,  557,  123,  550,  550,
+      129, 1622,  130,  130,  130,  133,  133,  133,  125,  544,
+      557,  126, 1623, 1624,  129,  568,  123,  123,  130, 1626,
+     1633,  133,  541,  541,  541,  544,  557,  123,  550,  550,
       550,  568,  123,  124,  124,  124,  124,  124,  124,  124,
-      124,  124,  124,  124,  124,  124,  124,  124, 1632,  124,
+      124,  124,  124,  124,  124,  124,  124,  124, 1636,  124,
       124,  124,  124,  124,  134,  134,  134,  135,  135,  135,
-      136,  136,  136, 1635,  137,  137,  137,  138,  138,  138,
-      134,  580,  593,  135, 1638, 1639,  136,  609,  124,  124,
+      136,  136,  136, 1639,  137,  137,  137,  138,  138,  138,
+      134,  580,  593,  135, 1640, 1642,  136,  588,  124,  124,
 
-      137, 1641, 1642,  138,  554,  554,  554,  580,  593,  124,
-      562,  562,  562,  609,  124,  127,  127,  127,  127,  127,
+      137, 1643, 1644,  138,  554,  554,  554,  580,  593,  124,
+      562,  562,  562, 1645,  124,  127,  127,  127,  127,  127,
       127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      728,  127,  127,  127,  127,  127,  139,  139,  139,  140,
-      140,  140,  143,  143,  143, 1643,  144,  144,  144,  147,
-      147,  147,  139, 1110,  728,  140,  563, 1110,  143, 1644,
-      127,  127,  144,  563,  619,  147,  565,  565,  565,  573,
+      729,  127,  127,  127,  127,  127,  139,  139,  139,  140,
+      140,  140,  143,  143,  143,  588,  144,  144,  144,  147,
+      147,  147,  139, 1646,  729,  140,  563, 1647,  143, 1648,
+      127,  127,  144,  563,  609,  147,  565,  565,  565,  573,
       573,  573,  563,  577,  577,  577,  127,  586,  586,  586,
-      619, 1645,  127,  128,  128,  128,  128,  128,  128,  128,
-      128,  128,  128,  128,  128,  128,  128,  128, 1646,  128,
+      609, 1650,  127,  128,  128,  128,  128,  128,  128,  128,
+      128,  128,  128,  128,  128,  128,  128,  128, 1651,  128,
 
       128,  128,  128,  128,  148,  148,  148,  151,  151,  151,
-      152,  152,  152, 1647,  155,  155,  155,  156,  156,  156,
-      148, 1649, 1650,  151, 1631, 1652,  152,  630,  128,  128,
-      155, 1654, 1656,  156,  590,  590,  590,  601,  601,  601,
-      606,  606,  606,  630,  128,  613,  613,  613,  602, 1631,
+      152,  152,  152, 1653,  155,  155,  155,  156,  156,  156,
+      148, 1655, 1657,  151, 1632, 1658,  152,  619,  128,  128,
+      155, 1660, 1662,  156,  590,  590,  590,  601,  601,  601,
+      606,  606,  606,  619,  128,  613,  613,  613,  602, 1632,
       128,  131,  131,  131,  131,  131,  131,  131,  131,  131,
-      131,  131,  131,  131,  131,  131, 1657,  131,  131,  131,
+      131,  131,  131,  131,  131,  131, 1664,  131,  131,  131,
       131,  131,  159,  159,  159,  160,  160,  160,  163,  163,
-      163,  669,  164,  164,  164,  602,  614, 1659,  159, 1661,
-      876,  160,  669,  614,  163,  669,  131,  131,  164,  131,
+      163,  669,  164,  164,  164,  602,  614, 1665,  159, 1666,
+      630,  160,  669,  614,  163,  669,  131,  131,  164,  131,
 
-      602,  131,  614,  616,  616,  616,  876,  131,  623,  623,
-      623,  627,  627,  627,  131, 1663, 1664,  131,  132,  132,
+      602,  131,  614,  616,  616,  616,  630,  131,  623,  623,
+      623,  627,  627,  627,  131, 1667, 1668,  131,  132,  132,
       132,  132,  132,  132,  132,  132,  132,  132,  132,  132,
-      132,  132,  132, 1665,  132,  132,  132,  132,  132,  167,
+      132,  132,  132, 1670,  132,  132,  132,  132,  132,  167,
       167,  167,  168,  168,  168,  169,  169,  169,  672,  170,
-      170,  170,  635,  635,  635,  167, 1666, 1667,  168,  672,
+      170,  170,  635,  635,  635,  167,  877, 1431,  168,  672,
       636,  169,  672,  132,  132,  170,  132,  636,  132,  637,
-      637,  637, 1669, 1678,  132, 1679,  636, 1681,  646,  646,
-      646,  132, 1685, 1689,  132,  141,  141,  141,  141,  141,
+      637,  637,  877, 1679,  132, 1680,  636, 1431,  646,  646,
+      646,  132, 1682, 1686,  132,  141,  141,  141,  141,  141,
       141,  141,  141,  141,  141,  141,  141,  141,  141,  141,
 
-     1692,  141,  141,  141,  141,  141,  171,  171,  171,  172,
-      172,  172,  173,  173,  173, 1699,  174,  174,  174,  177,
-      177,  177,  171, 1700, 1701,  172,  665,  674,  173, 1702,
+     1690,  141,  141,  141,  141,  141,  171,  171,  171,  172,
+      172,  172,  173,  173,  173, 1692,  174,  174,  174,  177,
+      177,  177,  171, 1699, 1700,  172,  665,  674,  173, 1701,
       141,  141,  174,  665,  674,  177,  141,  646,  676,  665,
-      674,  141,  879,  879,  879, 1704,  879, 1707, 1708,  676,
-     1709, 1712,  676,  141,  142,  142,  142,  142,  142,  142,
-      142,  142,  142,  142,  142,  142,  142,  142,  142, 1719,
+      674,  141,  880,  880,  880, 1702,  880, 1704, 1708,  676,
+     1709, 1710,  676,  141,  142,  142,  142,  142,  142,  142,
+      142,  142,  142,  142,  142,  142,  142,  142,  142, 1713,
       142,  142,  142,  142,  142,  178,  178,  178,  179,  179,
-      179,  180,  180,  180, 1731,  181,  181,  181,  182,  182,
-      182,  178, 1732, 1740,  179,  677,  678,  180, 1185,  142,
+      179,  180,  180,  180, 1720,  181,  181,  181,  182,  182,
+      182,  178, 1732, 1733,  179,  677,  678,  180, 1206,  142,
 
-      142,  181,  677,  678,  182,  142,  702,  726,  677,  678,
-      142, 1185, 1743,  702, 1125, 1125, 1125, 1748,  726,  702,
-     1752,  726,  142,  145,  145,  145,  145,  145,  145,  145,
+      142,  181,  677,  678,  182,  142,  717,  720,  677,  678,
+      142, 1206, 1741,  717,  720, 1126, 1126, 1126, 1744,  717,
+      720, 1749,  142,  145,  145,  145,  145,  145,  145,  145,
       145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
       145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
       145,  145,  145,  145,  145,  145,  145,  145,  145,  145,
@@ -3136,1106 +3138,1108 @@ static yyconst flex_int16_t yy_chk[11810] =
       145,  145,  145,  145,  145,  145,  145,  149,  149,  149,
 
       149,  149,  149,  149,  149,  149,  149,  149,  149,  149,
-      149,  149, 1759,  149,  149,  149,  149,  149,  183,  183,
-      183,  184,  184,  184,  187,  187,  187, 1760,  188,  188,
-      188,  189,  189,  189,  183, 1005, 1761,  184, 1762, 1771,
-      187, 1775,  149,  149,  188, 1005,  149,  189,  891,  891,
-      891, 1778, 1005,  149, 1780, 1782,  149,  912,  912,  912,
-      149, 1783,  149,  149,  150,  150,  150,  150,  150,  150,
-      150,  150,  150,  150,  150,  150,  150,  150,  150, 1785,
+      149,  149, 1753,  149,  149,  149,  149,  149,  183,  183,
+      183,  184,  184,  184,  187,  187,  187,  727,  188,  188,
+      188,  189,  189,  189,  183, 1006, 1760,  184,  727, 1761,
+      187,  727,  149,  149,  188, 1006,  149,  189,  892,  892,
+      892, 1762, 1006,  149, 1763, 1772,  149,  913,  913,  913,
+      149, 1776,  149,  149,  150,  150,  150,  150,  150,  150,
+      150,  150,  150,  150,  150,  150,  150,  150,  150, 1779,
       150,  150,  150,  150,  150,  190,  190,  190,  191,  191,
-      191,  192,  192,  192, 1786,  193,  193,  193,  194,  194,
+      191,  192,  192,  192, 1781,  193,  193,  193,  194,  194,
 
-      194,  190, 1787, 1790,  191, 1792, 1794,  192, 1799,  150,
-      150,  193,  891,  150,  194,  924,  924,  924, 1805,  924,
-      150,  912,  924,  150, 1147, 1147, 1147,  150, 1809,  150,
+      194,  190, 1783, 1784,  191, 1786, 1787,  192, 1788,  150,
+      150,  193,  892,  150,  194,  925,  925,  925, 1791,  925,
+      150,  913,  925,  150, 1148, 1148, 1148,  150, 1793,  150,
       150,  153,  153,  153,  153,  153,  153,  153,  153,  153,
-      153,  153,  153,  153,  153,  153, 1810,  153,  153,  153,
+      153,  153,  153,  153,  153,  153, 1795,  153,  153,  153,
       153,  153,  197,  197,  197,  198,  198,  198,  201,  201,
-      201, 1811,  202,  202,  202,  686,  686,  686,  197, 1813,
-     1825,  198, 1821, 1828,  201, 1829,  153,  153,  202,  153,
-      153,  153,  686, 1830,  932,  932,  932,  153,  932, 1821,
-      153,  932, 1832, 1833,  153, 1822, 1835,  153,  154,  154,
+      201, 1800,  202,  202,  202,  686,  686,  686,  197, 1806,
+     1810,  198, 1811, 1812,  201, 1814,  153,  153,  202,  153,
+      153,  153,  686, 1826,  933,  933,  933,  153,  933, 1829,
+      153,  933, 1830, 1831,  153, 1823, 1822,  153,  154,  154,
 
       154,  154,  154,  154,  154,  154,  154,  154,  154,  154,
-      154,  154,  154, 1836,  154,  154,  154,  154,  154,  203,
-      203,  203,  204,  204,  204,  205,  205,  205, 1837,  206,
-      206,  206,  694,  694,  694,  203, 1839, 1822,  204, 1840,
-     1831,  205, 1841,  154,  154,  206,  154,  154,  154,  694,
-     1845,  948,  948,  948,  154,  948, 1831,  154,  948, 1847,
-     1850,  154, 1823, 1851,  154,  157,  157,  157,  157,  157,
+      154,  154,  154, 1822,  154,  154,  154,  154,  154,  203,
+      203,  203,  204,  204,  204,  205,  205,  205, 1833,  206,
+      206,  206,  694,  694,  694,  203, 1834, 1823,  204, 1836,
+     1832,  205, 1837,  154,  154,  206,  154,  154,  154,  694,
+     1838,  948,  948,  948,  154,  948, 1832,  154,  948, 1840,
+     1841,  154, 1824, 1842,  154,  157,  157,  157,  157,  157,
       157,  157,  157,  157,  157,  157,  157,  157,  157,  157,
-     1852,  157,  157,  157,  157,  157,  207,  207,  207,  208,
-      208,  208,  211,  211,  211, 1823,  212,  212,  212,  711,
+     1846,  157,  157,  157,  157,  157,  207,  207,  207,  208,
+      208,  208,  211,  211,  211, 1824,  212,  212,  212,  710,
 
-      711,  711,  207, 1853, 1855,  208, 1857, 1858,  211, 1860,
-      157,  157,  212, 1862, 1865,  157,  711, 1446, 1446, 1446,
-     1866,  157,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158, 1868,  158,  158,
+      710,  710,  207, 1848, 1851,  208, 1852, 1853,  211, 1854,
+      157,  157,  212, 1856, 1858,  157,  710, 1447, 1447, 1447,
+     1859,  157,  158,  158,  158,  158,  158,  158,  158,  158,
+      158,  158,  158,  158,  158,  158,  158, 1861,  158,  158,
       158,  158,  158,  213,  213,  213,  214,  214,  214,  215,
-      215,  215, 1867,  216,  216,  216,  732,  732,  732,  213,
-     1867, 1869,  214, 1446, 1870,  215, 1872,  158,  158,  216,
-     1878, 1879,  158,  732, 1448, 1448, 1448, 1881,  158,  161,
+      215,  215, 1863,  216,  216,  216,  733,  733,  733,  213,
+     1866, 1867,  214, 1447, 1869,  215, 1870,  158,  158,  216,
+     1871, 1873,  158,  733, 1449, 1449, 1449, 1879,  158,  161,
       161,  161,  161,  161,  161,  161,  161,  161,  161,  161,
-      161,  161,  161,  161, 1884,  161,  161,  161,  161,  161,
+      161,  161,  161,  161, 1880,  161,  161,  161,  161,  161,
 
-      217,  217,  217,  218,  218,  218,  221,  221,  221, 1871,
-      222,  222,  222,  223,  223,  223,  217, 1871, 1880,  218,
-     1448, 1885,  221, 1900,  161,  161,  222, 1901,  161,  223,
-      952,  952,  952, 1906, 1880,  161, 1907, 1885,  161,  162,
+      217,  217,  217,  218,  218,  218,  221,  221,  221, 1868,
+      222,  222,  222,  223,  223,  223,  217, 1868, 1881,  218,
+     1449, 1882,  221, 1885,  161,  161,  222, 1901,  161,  223,
+      952,  952,  952, 1902, 1881,  161, 1907, 1908,  161,  162,
       162,  162,  162,  162,  162,  162,  162,  162,  162,  162,
-      162,  162,  162,  162, 1908,  162,  162,  162,  162,  162,
-      224,  224,  224,  225,  225,  225,  226,  226,  226, 1912,
-      227,  227,  227,  228,  228,  228,  224, 1886, 1914,  225,
-     1920, 1927,  226, 1928,  162,  162,  227, 1929,  162,  228,
-      959,  959,  959, 1886,  952,  162, 1942, 1948,  162,  165,
+      162,  162,  162,  162, 1909,  162,  162,  162,  162,  162,
+      224,  224,  224,  225,  225,  225,  226,  226,  226, 1872,
+      227,  227,  227,  228,  228,  228,  224, 1872, 1913,  225,
+     1886, 1887,  226, 1915,  162,  162,  227, 1921,  162,  228,
+      960,  960,  960, 1928,  952,  162, 1886, 1887,  162,  165,
 
       165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
-      165,  165,  165,  165, 1952,  165,  165,  165,  165,  165,
-      231,  231,  231,  232,  232,  232,  235,  235,  235, 1955,
-      236,  236,  236,  237,  237,  237,  231, 1957, 1960,  232,
-     1962, 1964,  235, 1965,  165,  165,  236, 1966,  165,  237,
-     1451, 1451, 1451, 1969,  959,  165, 1971, 1976,  165, 1454,
-     1454, 1454, 1464, 1464, 1464,  165,  166,  166,  166,  166,
+      165,  165,  165,  165, 1929,  165,  165,  165,  165,  165,
+      231,  231,  231,  232,  232,  232,  235,  235,  235, 1930,
+      236,  236,  236,  237,  237,  237,  231, 1943, 1949,  232,
+     1953, 1956,  235, 1958,  165,  165,  236, 1961,  165,  237,
+     1452, 1452, 1452, 1963,  960,  165, 1965, 1966,  165, 1455,
+     1455, 1455, 1465, 1465, 1465,  165,  166,  166,  166,  166,
       166,  166,  166,  166,  166,  166,  166,  166,  166,  166,
-      166, 1978,  166,  166,  166,  166,  166,  238,  238,  238,
-      239,  239,  239,  240,  240,  240, 1986,  241,  241,  241,
+      166, 1967,  166,  166,  166,  166,  166,  238,  238,  238,
+      239,  239,  239,  240,  240,  240, 1970,  241,  241,  241,
 
-      242,  242,  242,  238, 1987, 1988,  239, 1989, 1991,  240,
-      354,  166,  166,  241, 2004,  166,  242,  966,  966,  966,
-      354,  966,  166, 2005,  966,  166, 1489, 1489, 1489, 1501,
-     1501, 1501,  166,  175,  175,  175,  175,  175,  175,  175,
+      242,  242,  242,  238, 1972, 1977,  239, 1979, 1987,  240,
+      354,  166,  166,  241, 1988,  166,  242,  967,  967,  967,
+      354,  967,  166, 1989,  967,  166, 1501, 1501, 1501, 1502,
+     1502, 1502,  166,  175,  175,  175,  175,  175,  175,  175,
       175,  175,  175,  175,  175,  175,  175,  175,  354,  175,
       175,  175,  175,  175,  245,  245,  245,  246,  246,  246,
-     2004, 2003,  354,  739,  739,  739,  354,  973,  973,  973,
-      245,  973, 2010,  246,  973, 1501,  288, 2011,  175,  175,
-      739,  744,  744,  744,  175,  353,  288, 2012, 2013,  978,
-      978,  978, 2003,  978,  360,  353,  978, 2017,  744,  175,
+     1990, 1992,  354,  740,  740,  740,  354,  890,  890,  890,
+      245, 2003, 1501,  246, 2006, 1502,  288, 2003,  175,  175,
+      740,  745,  745,  745,  175,  890,  288, 2011,  974,  974,
+      974, 2005,  974, 2012,  360,  974, 2004, 2013,  745,  175,
 
       176,  176,  176,  176,  176,  176,  176,  176,  176,  176,
       176,  176,  176,  176,  176,  288,  176,  176,  176,  176,
-      176,  288,  360,  353,  756,  756,  756, 2019,  288,  353,
-     2020, 2021,  288,  353, 2026,  764,  764,  764,  360,  353,
-      353,  756,  765,  765,  765,  176,  176,  771,  771,  771,
-     2002,  176,  764,  990,  990,  990, 2002,  990, 2033,  765,
-      990, 1502, 1502, 1502,  771, 2035,  176,  185,  185,  185,
+      176,  288,  360,  757,  757,  757, 2014, 2004,  288, 1503,
+     1503, 1503,  288,  765,  765,  765, 2018, 2005,  360, 2020,
+      757,  766,  766,  766, 2021,  176,  176,  772,  772,  772,
+      765,  176,  979,  979,  979, 2022,  979, 2027,  766,  979,
+     1590, 1590, 1590, 2034,  772, 2036,  176,  185,  185,  185,
       185,  185,  185,  185,  185,  185,  185,  185,  185,  185,
-      185,  185, 2036,  185,  185,  185,  185,  185,  773,  773,
-      773,  785,  785,  785,  786,  786,  786,  798,  798,  798,
-
-      806,  806,  806, 2039, 2042,  773, 2046, 1502,  785, 2047,
-     2048,  786,  185,  185,  798, 2049, 2050,  806,  185, 2051,
-     2052,  185,  999,  999,  999, 2053,  999, 2054, 2055,  999,
-     1589, 1589, 1589,  185,  186,  186,  186,  186,  186,  186,
-      186,  186,  186,  186,  186,  186,  186,  186,  186, 2060,
-      186,  186,  186,  186,  186,  811,  811,  811,  817,  817,
-      817,  839,  839,  839,  867,  867,  867,  871,  871,  871,
-     2061, 2062,  811, 2063, 2081,  817, 1589, 2082,  839,  186,
-      186,  867, 2085, 2086,  871,  186, 2083, 2084,  186, 1001,
-     1001, 1001, 2088, 1001, 2083, 2084, 1001, 1648, 1648, 1648,
+      185,  185, 2037,  185,  185,  185,  185,  185,  774,  774,
+      774,  786,  786,  786,  787,  787,  787,  799,  799,  799,
+
+      807,  807,  807, 2040, 2043,  774, 1590, 2047,  786, 2048,
+     2049,  787,  185,  185,  799, 2050, 2051,  807,  185, 2052,
+     2053,  185,  991,  991,  991, 2054,  991, 2055, 2056,  991,
+     1649, 1649, 1649,  185,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186, 2061,
+      186,  186,  186,  186,  186,  812,  812,  812,  818,  818,
+      818,  840,  840,  840,  868,  868,  868,  872,  872,  872,
+     2062, 2063,  812, 2064, 2082,  818, 2083, 2086,  840,  186,
+      186,  868, 2087, 2089,  872,  186, 2084, 2085,  186, 1000,
+     1000, 1000, 2093, 1000, 2084, 2085, 1000, 1652, 1652, 1652,
 
       186,  195,  195,  195,  195,  195,  195,  195,  195,  195,
-      195,  195,  195,  195,  195,  195, 2092,  195,  195,  195,
-      195,  195,  889,  889,  889,  890,  890,  890, 2098, 2099,
-      920,  920,  920,  921,  921,  921,  923,  923,  923, 2100,
-      889, 2114, 2118,  890, 2119, 2120,  195,  195,  920, 2122,
-     2126,  921,  195,  923, 1651, 1651, 1651,  195,  196,  196,
+      195,  195,  195,  195,  195,  195, 2099,  195,  195,  195,
+      195,  195,  891,  891,  891,  921,  921,  921, 2100, 2101,
+      922,  922,  922,  924,  924,  924,  928,  928,  928, 1694,
+      891, 2115, 2119,  921, 2120, 1694,  195,  195,  922, 1694,
+      924, 2121,  195, 1694,  928, 2123, 2127,  195,  196,  196,
       196,  196,  196,  196,  196,  196,  196,  196,  196,  196,
-      196,  196,  196, 2129,  196,  196,  196,  196,  196,  927,
-      927,  927, 2130,  890,  928,  928,  928, 2133,  931,  931,
-      931, 2134, 2137,  921,  933,  933,  933,  927, 1653, 1653,
+      196,  196,  196, 2130,  196,  196,  196,  196,  196, 2131,
+      891,  929,  929,  929,  932,  932,  932,  940,  940,  940,
+      922,  934,  934,  934,  936,  936,  936, 2134, 2132,  929,
 
-     1653, 2144,  928,  196,  196,  931, 1007, 1007, 1007,  196,
-     1007,  933, 2146, 1007,  196,  199,  199,  199,  199,  199,
+     2135,  932, 2133,  196,  196,  940, 2132, 2138,  934,  196,
+     2133,  936, 2145, 2147,  196,  199,  199,  199,  199,  199,
       199,  199,  199,  199,  199,  199,  199,  199,  199,  199,
-     2161,  199,  199,  199,  199,  199,  935,  935,  935,  939,
-      939,  939, 2175, 2176,  945,  945,  945, 2179,  928, 2186,
-      940,  940,  940,  935,  946,  946,  946,  939, 2187, 2131,
-      199,  199,  945,  947,  947,  947,  199, 2131,  940, 1010,
-     1010, 1010,  946, 1010, 2192, 2166, 1010, 1655, 1655, 1655,
-      947,  199,  200,  200,  200,  200,  200,  200,  200,  200,
-      200,  200,  200,  200,  200,  200,  200,  940,  200,  200,
-
-      200,  200,  200,  950,  950,  950,  951,  951,  951,  965,
-      965,  965,  969,  969,  969,  972,  972,  972,  946, 2194,
-     2206,  950, 2166, 2132,  951, 2207,  965,  200,  200, 2208,
-      969, 2132,  972,  200, 1022, 1022, 1022, 2209, 1022, 2210,
-     2211, 1022, 2212,  951, 1658, 1658, 1658, 2165,  200,  209,
+     2162,  199,  199,  199,  199,  199,  945,  945,  945,  946,
+      946,  946,  947,  947,  947,  929,  950,  950,  950, 2176,
+      941,  941,  941, 2177,  945, 2180, 2187,  946, 2188,  947,
+      199,  199, 2193, 2195,  950, 2207,  199, 2166,  941, 1002,
+     1002, 1002, 2208, 1002, 2167, 2209, 1002, 1654, 1654, 1654,
+     2210,  199,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  941,  200,  200,
+
+      200,  200,  200,  946,  951,  951,  951,  966,  966,  966,
+     2166,  970,  970,  970,  971,  971,  971,  973,  973,  973,
+     2211, 2167,  951, 2212,  966, 2213, 2214,  200,  200,  970,
+     2215, 2216,  971,  200,  973, 1008, 1008, 1008, 2223, 1008,
+     2224,  951, 1008, 1656, 1656, 1656, 2225, 2227,  200,  209,
       209,  209,  209,  209,  209,  209,  209,  209,  209,  209,
-      209,  209,  209,  209, 2213,  209,  209,  209,  209,  209,
-     2214,  970,  970,  970,  975,  975,  975, 2215,  976,  976,
-      976,  977,  977,  977,  980,  980,  980, 1694, 2222,  970,
-     2165, 2223,  975, 1694,  209,  209,  976, 1694,  977, 2224,
+      209,  209,  209,  209, 2237,  209,  209,  209,  209,  209,
+      976,  976,  976,  977,  977,  977,  978,  978,  978, 2238,
+      971,  981,  981,  981,  982,  982,  982, 2239,  976, 2240,
+     2241,  977, 2242,  978,  209,  209,  985,  985,  985,  981,
 
-      209, 1694,  980,  209, 1024, 1024, 1024, 2226, 1024, 2236,
-     2237, 1024, 1660, 1660, 1660,  209,  210,  210,  210,  210,
+      209, 2243,  982,  209, 1011, 1011, 1011, 2246, 1011, 2247,
+     2252, 1011, 2253, 2259,  985,  209,  210,  210,  210,  210,
       210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210, 2238,  210,  210,  210,  210,  210,  970,  984,  984,
-      984,  989,  989,  989,  976,  981,  981,  981,  985,  985,
-      985,  993,  993,  993, 1695, 2239,  984, 2240,  989, 2241,
-     1695,  210,  210,  981, 1695, 2242,  985,  210, 1695,  993,
-      210, 1036, 1036, 1036, 2245, 1036, 1660, 2246, 1036, 1662,
-     1662, 1662,  210,  219,  219,  219,  219,  219,  219,  219,
-      219,  219,  219,  219,  219,  219,  219,  219, 2251,  219,
-
-      219,  219,  219,  219, 2252, 2258,  981,  998,  998,  998,
-     1000, 1000, 1000,  985,  994,  994,  994, 1002, 1002, 1002,
-     2259, 1003, 1003, 1003,  998, 1662, 2260, 1000,  219,  219,
-     2261, 2275,  994, 2276, 2277, 1002,  219, 2278,  219, 1003,
-     2280,  219, 1668, 1668, 1668,  219, 1670, 1670, 1670,  219,
+      210, 2260,  210,  210,  210,  210,  210, 2261, 2262,  977,
+      986,  986,  986, 2276, 2277,  982,  990,  990,  990, 2278,
+      994,  994,  994,  995,  995,  995, 2279, 2281,  986, 2283,
+     2306,  210,  210,  990,  999,  999,  999,  210,  994, 2307,
+      210,  995, 1023, 1023, 1023, 2312, 1023, 2313, 2314, 1023,
+     2300,  999,  210,  219,  219,  219,  219,  219,  219,  219,
+      219,  219,  219,  219,  219,  219,  219,  219, 2317,  219,
+
+      219,  219,  219,  219, 2320,  986, 1001, 1001, 1001, 1003,
+     1003, 1003, 2300, 2321,  995, 1004, 1004, 1004, 1007, 1007,
+     1007, 2322, 2323, 1001, 1020, 1020, 1020, 1003,  219,  219,
+     1010, 1010, 1010, 1004, 1695, 1007,  219, 2301,  219, 2324,
+     1695,  219, 1020, 2325, 1695,  219, 2326, 1010, 1695,  219,
       220,  220,  220,  220,  220,  220,  220,  220,  220,  220,
-      220,  220,  220,  220,  220, 2282,  220,  220,  220,  220,
-      220, 1006, 1006, 1006, 2299,  994, 1009, 1009, 1009, 1019,
-     1019, 1019, 1003, 1011, 1011, 1011, 2305, 2306, 1006, 1020,
-     1020, 1020, 1670, 1009, 2311,  220,  220, 1019, 2312, 2313,
+      220,  220,  220,  220,  220, 2327,  220,  220,  220,  220,
+      220, 1012, 1012, 1012, 2301, 2328, 1004, 1022, 1022, 1022,
+     1021, 1021, 1021, 1024, 1024, 1024, 2329, 2330, 1012, 1026,
+     1026, 1026, 2332, 2333, 1022,  220,  220, 2335, 1021, 2336,
 
-     1011, 2316, 2319,  220, 2320,  220, 2299, 1020,  220, 1691,
-     1691, 1691,  220, 1703, 1703, 1703,  220,  229,  229,  229,
+     1024, 2337, 2338,  220, 2339,  220, 1026, 2341,  220, 1659,
+     1659, 1659,  220, 1669, 1669, 1669,  220,  229,  229,  229,
       229,  229,  229,  229,  229,  229,  229,  229,  229,  229,
-      229,  229, 2321,  229,  229,  229,  229,  229, 1021, 1021,
-     1021, 1023, 1023, 1023, 1025, 1025, 1025, 1020, 1705, 1705,
-     1705, 1026, 1026, 1026, 2322, 1021, 2323, 2324, 1023, 2325,
-     2326, 1025,  229,  229, 1027, 1027, 1027, 2327, 1026, 1044,
-     1044, 1044, 2328, 1044, 2329, 2331, 1044, 2300, 1049, 1049,
-     1049, 1027, 1049, 2332, 2334, 1049,  229,  230,  230,  230,
+      229,  229, 2342,  229,  229,  229,  229,  229, 1021, 1025,
+     1025, 1025, 2343, 1025, 2345, 2334, 1025, 2346, 1661, 1661,
+     1661, 1027, 1027, 1027, 2334, 2348, 1028, 1028, 1028, 1029,
+     1029, 1029,  229,  229, 1030, 1030, 1030, 2353, 1027, 2354,
+     1037, 1037, 1037, 1028, 1037, 2340, 1029, 1037, 1045, 1045,
+     1045, 1030, 1045, 2355, 2340, 1045,  229,  230,  230,  230,
       230,  230,  230,  230,  230,  230,  230,  230,  230,  230,
 
-      230,  230, 1026,  230,  230,  230,  230,  230, 1035, 1035,
-     1035, 1030, 1030, 1030, 2300, 2333, 1027, 1028, 1028, 1028,
-     2335, 1037, 1037, 1037, 2333, 1035, 1029, 1029, 1029, 1030,
-     2336, 2337,  230,  230, 1028, 1031, 1031, 1031, 1037, 2338,
-     1055, 1055, 1055, 1029, 1055, 2339, 2340, 1055, 1075, 1075,
-     1075, 2341, 1075, 1031, 2339, 1075,  230,  233,  233,  233,
+      230,  230, 1027,  230,  230,  230,  230,  230, 1028, 1031,
+     1031, 1031, 1661, 2357, 1029, 2362, 1030, 1703, 1703, 1703,
+     1036, 1036, 1036, 1038, 1038, 1038, 2363, 1031, 1041, 1041,
+     1041, 2366,  230,  230, 1032, 1032, 1032, 1036, 2372, 2373,
+     1038, 1050, 1050, 1050, 2375, 1050, 1041, 2384, 1050, 1663,
+     1663, 1663, 1032, 1705, 1705, 1705,  230,  233,  233,  233,
       233,  233,  233,  233,  233,  233,  233,  233,  233,  233,
-      233,  233, 1028,  233,  233,  233,  233,  233, 1029, 1040,
-     1040, 1040, 1031, 1043, 1043, 1043, 1041, 1041, 1041, 1045,
-     1045, 1045, 1046, 1046, 1046, 2342, 2344, 1040, 2345, 2347,
-
-     1043, 2352,  233,  233, 1041, 2353, 2354, 1045, 2356, 2361,
-     1046, 2362, 2365,  233,  234,  234,  234,  234,  234,  234,
-      234,  234,  234,  234,  234,  234,  234,  234,  234, 2371,
-      234,  234,  234,  234,  234, 2372, 2374, 1041, 1048, 1048,
-     1048, 2383, 2385, 1051, 1051, 1051, 1052, 1052, 1052, 1054,
-     1054, 1054, 2388, 1046, 2390, 1048, 1706, 1706, 1706,  234,
-      234, 1051, 2414, 2410, 1052, 2415, 1054, 1710, 1710, 1710,
+      233,  233, 2386,  233,  233,  233,  233,  233, 1042, 1042,
+     1042, 1032, 1044, 1044, 1044, 2389, 1046, 1046, 1046, 1047,
+     1047, 1047, 1049, 1049, 1049, 1663, 1042, 2391, 2410, 1044,
+
+     2412, 2415,  233,  233, 1046, 2411, 2416, 1047, 2418, 1049,
+     1671, 1671, 1671,  233,  234,  234,  234,  234,  234,  234,
+      234,  234,  234,  234,  234,  234,  234,  234,  234, 1042,
+      234,  234,  234,  234,  234, 1052, 1052, 1052, 2410, 1053,
+     1053, 1053, 2411, 2412, 1055, 1055, 1055, 1056, 1056, 1056,
+     1047, 1056, 2419, 1052, 1056, 2420, 1671, 1053, 2425,  234,
+      234, 1055, 1076, 1076, 1076, 2426, 1076, 2427, 2428, 1076,
       234,  243,  243,  243,  243,  243,  243,  243,  243,  243,
-      243,  243,  243,  243,  243,  243, 2409,  243,  243,  243,
-      243,  243, 2417, 1052, 1059, 1059, 1059, 1061, 1061, 1061,
+      243,  243,  243,  243,  243,  243, 1053,  243,  243,  243,
+      243,  243, 1060, 1060, 1060, 1062, 1062, 1062, 1063, 1063,
 
-     2410, 1060, 1060, 1060, 1062, 1062, 1062, 1063, 1063, 1063,
-     2418, 2419, 1059, 2424, 1061, 2425,  243,  243, 2426, 1060,
-     1706, 1062, 2411, 2427, 1063, 2428, 2409,  243, 1099, 1099,
-     1099, 1710, 1099, 2429, 2430, 1099, 1742, 1742, 1742, 2431,
+     1063, 1061, 1061, 1061, 1064, 1064, 1064, 1065, 1065, 1065,
+     1060, 2429, 1062, 2430, 2431, 1063,  243,  243, 2432, 1061,
+     2433, 1064, 1068, 1068, 1068, 1065, 2434,  243, 1100, 1100,
+     1100, 2435, 1100, 2437, 2438, 1100, 1706, 1706, 1706, 1068,
       243,  244,  244,  244,  244,  244,  244,  244,  244,  244,
-      244,  244,  244,  244,  244,  244, 1060,  244,  244,  244,
-      244,  244, 1064, 1064, 1064, 2411, 1063, 1067, 1067, 1067,
-     1065, 1065, 1065, 1068, 1068, 1068, 1069, 1069, 1069, 2422,
-     1064, 1070, 1070, 1070, 1067, 2432,  244,  244, 1065, 2422,
-     1068, 2433, 2422, 1069, 1071, 1071, 1071,  244, 1070, 1072,
-
-     1072, 1072, 1074, 1074, 1074, 2434, 1076, 1076, 1076, 2436,
-      244,  286, 1071, 2437, 1077, 1077, 1077, 1072,  286, 1074,
-     1078, 1078, 1078, 1068, 1076, 2438, 2439,  286,  286, 2440,
-     2441, 1065, 1077, 1079, 1079, 1079, 1072, 1078, 1068, 2442,
-     1070, 1080, 1080, 1080, 2443, 2444, 1081, 1081, 1081, 2445,
-     1079, 1082, 1082, 1082, 2446,  286,  286,  286, 2447, 1080,
-     2448, 2449,  286,  286, 1081, 2450,  286,  286, 1082, 1077,
-      286, 2451,  286,  286,  286, 1083, 1083, 1083, 1084, 1084,
-     1084, 1085, 1085, 1085, 1086, 1086, 1086, 1092, 1092, 1092,
-     2423, 2453, 1083, 2457, 2464, 1084, 1093, 1093, 1093, 1085,
-
-     2423, 2465, 1086, 2423, 2469, 1092, 1096, 1096, 1096, 1097,
-     1097, 1097, 2472, 2510, 1093, 2513, 2515, 1081, 1098, 1098,
-     1098, 1100, 1100, 1100, 1096, 1083, 2511, 1097, 1101, 1101,
-     1101, 1102, 1102, 1102, 2516, 1098, 1105, 1105, 1105, 1100,
-     1083, 2517, 2510, 1103, 1103, 1103, 1101, 1103, 1102, 2520,
-     1103, 1106, 1106, 1106, 1105, 1086, 1121, 1121, 1121, 2521,
-     1093, 1122, 1122, 1122, 1124, 1124, 1124, 2512, 2511, 1106,
-     1154, 1154, 1154, 1097, 1121, 1155, 1155, 1155, 2495, 1122,
-     2523, 2524, 1124, 1156, 1156, 1156, 2526, 1154, 2495, 1101,
-     1158, 1158, 1158, 1155, 2495, 1159, 1159, 1159, 1160, 1160,
-
-     1160, 1156, 1160, 2527, 2528, 1160, 2529, 2530, 1158, 2512,
-     2532, 1124, 1159, 2533, 2534, 1106, 1163, 1163, 1163, 1165,
-     1165, 1165, 1166, 1166, 1166, 1168, 1168, 1168, 1170, 1170,
-     1170, 2535, 1170, 1163, 2538, 1170, 2539, 1165, 2540, 1158,
-     1166, 2541, 2522, 1168, 1173, 1173, 1173, 1174, 1174, 1174,
-     2496, 1174, 2525, 2542, 1174, 2522, 1175, 1175, 1175, 2543,
-     2496, 1173, 1176, 1176, 1176, 2525, 2496, 1177, 1177, 1177,
-     2544, 1177, 1168, 1175, 1177, 2545, 2546, 1163, 2547, 1176,
-     1179, 1179, 1179, 1181, 1181, 1181, 1182, 1182, 1182, 1184,
-     1184, 1184, 1187, 1187, 1187, 2548, 2549, 1179, 1189, 1189,
-
-     1189, 1181, 2550, 2551, 1182, 2552, 2554, 1184, 2564, 1187,
-     1190, 1190, 1190, 1192, 1192, 1192, 1189, 1193, 1193, 1193,
-     2565, 1193, 2566, 2570, 1193, 1197, 1197, 1197, 1190, 2588,
-     2589, 1192, 1198, 1198, 1198, 1200, 1200, 1200, 1213, 1213,
-     1213, 2590, 1213, 1197, 2591, 1213, 1217, 1217, 1217, 1184,
-     1198, 2592, 2593, 1200, 1218, 1218, 1218, 1219, 1219, 1219,
-     1192, 2603, 2605, 1217, 1221, 1221, 1221, 1223, 1223, 1223,
-     2608, 1223, 1218, 2602, 1223, 1219, 1227, 1227, 1227, 1228,
-     1228, 1228, 1221, 1230, 1230, 1230, 1231, 1231, 1231, 2609,
-     1231, 2613, 2614, 1231, 1227, 2615, 2603, 1228, 1234, 1234,
-
-     1234, 1230, 1235, 1235, 1235, 1236, 1236, 1236, 1238, 1238,
-     1238, 1239, 1239, 1239, 2597, 1234, 2616, 1240, 1240, 1240,
-     1235, 2602, 2617, 1236, 2618, 1221, 1238, 2597, 1239, 1241,
-     1241, 1241, 2619, 2598, 1240, 1242, 1242, 1242, 1244, 1244,
-     1244, 1247, 1247, 1247, 1230, 1240, 2598, 1241, 1248, 1248,
-     1248, 2620, 1248, 1242, 2622, 1248, 1244, 2623, 1247, 1253,
-     1253, 1253, 1254, 1254, 1254, 1256, 1256, 1256, 1259, 1259,
-     1259, 2624, 1260, 1260, 1260, 1238, 1260, 1253, 2625, 1260,
-     1254, 2626, 2627, 1256, 2628, 1259, 1263, 1263, 1263, 2629,
-     1263, 2631, 2632, 1263, 1266, 1266, 1266, 1267, 1267, 1267,
-
-     1269, 1269, 1269, 2633, 1244, 2634, 1274, 1274, 1274, 2635,
-     1274, 2636, 1266, 1274, 2637, 1267, 2638, 2639, 1269, 1277,
-     1277, 1277, 1278, 1278, 1278, 2640, 1278, 2641, 2642, 1278,
-     1256, 1281, 1281, 1281, 2643, 2644, 1277, 1282, 1282, 1282,
-     2645, 1282, 2651, 2655, 1282, 1290, 1290, 1290, 1281, 1291,
-     1291, 1291, 1293, 1293, 1293, 1294, 1294, 1294, 2656, 1294,
-     2657, 2658, 1294, 1290, 2670, 1269, 2671, 1291, 2675, 2676,
-     1293, 1297, 1297, 1297, 2670, 1297, 2671, 2673, 1297, 1300,
-     1300, 1300, 1301, 1301, 1301, 2677, 1301, 2673, 2678, 1301,
-     1306, 1306, 1306, 1307, 1307, 1307, 1300, 1309, 1309, 1309,
-
-     1314, 1314, 1314, 2679, 1314, 2680, 2683, 1314, 1306, 2684,
-     2685, 1307, 1317, 1317, 1317, 1309, 1318, 1318, 1318, 1293,
-     1318, 2686, 2695, 1318, 1321, 1321, 1321, 2696, 2697, 1317,
-     1322, 1322, 1322, 1324, 1324, 1324, 1326, 1326, 1326, 2674,
-     1326, 2687, 1321, 1326, 2698, 1309, 2699, 2700, 1322, 2674,
-     2701, 1324, 1329, 1329, 1329, 1330, 1330, 1330, 1332, 1332,
-     1332, 1334, 1334, 1334, 2702, 1334, 2705, 2706, 1334, 2708,
-     1329, 2709, 2710, 1330, 2712, 2687, 1332, 1338, 1338, 1338,
-     1339, 1339, 1339, 2714, 1324, 1341, 1341, 1341, 2715, 1343,
-     1343, 1343, 2716, 1343, 2719, 1338, 1343, 2720, 1339, 1349,
-
-     1349, 1349, 2721, 1341, 1350, 1350, 1350, 2722, 1352, 1352,
-     1352, 1353, 1353, 1353, 1354, 1354, 1354, 1349, 1354, 2723,
-     2726, 1354, 1350, 2727, 2734, 1332, 1352, 2735, 1353, 1355,
-     1355, 1355, 2736, 2738, 1341, 1356, 1356, 1356, 2744, 1356,
-     2745, 2746, 1356, 1358, 1358, 1358, 1355, 1359, 1359, 1359,
-     2747, 1361, 1361, 1361, 1363, 1363, 1363, 2748, 1367, 1367,
-     1367, 1358, 1834, 1834, 1834, 1359, 2749, 2750, 1352, 1361,
-     2751, 1363, 1364, 1364, 1364, 1367, 1364, 2752, 2753, 1364,
-     1368, 1368, 1368, 2755, 1368, 2756, 2761, 1368, 1370, 1370,
-     1370, 1371, 1371, 1371, 1373, 1373, 1373, 1375, 1375, 1375,
-
-     2762, 1375, 2763, 2764, 1375, 2774, 1370, 2775, 2765, 1371,
-     2776, 2777, 1373, 1378, 1378, 1378, 2778, 2779, 1361, 1379,
-     1379, 1379, 1381, 1381, 1381, 1382, 1382, 1382, 1383, 1383,
-     1383, 1378, 1383, 2780, 2781, 1383, 2785, 1379, 2786, 2787,
-     1381, 2788, 1382, 1384, 1384, 1384, 1385, 1385, 1385, 2789,
-     1385, 2765, 2790, 1385, 1386, 1386, 1386, 2792, 1373, 2793,
-     1384, 1387, 1387, 1387, 2795, 1389, 1389, 1389, 1390, 1390,
-     1390, 2796, 1386, 1391, 1391, 1391, 2797, 1391, 2798, 1387,
-     1391, 2800, 1381, 1389, 2801, 1390, 1394, 1394, 1394, 1395,
-     1395, 1395, 2805, 1395, 2806, 2807, 1395, 1396, 1396, 1396,
-
-     1397, 1397, 1397, 1394, 1399, 1399, 1399, 1401, 1401, 1401,
-     1405, 1405, 1405, 2810, 2815, 1396, 2816, 2817, 1397, 1406,
-     1406, 1406, 1399, 2818, 1401, 2819, 2820, 1389, 1405, 1408,
-     1408, 1408, 1411, 1411, 1411, 2821, 2822, 1406, 1412, 1412,
-     1412, 1414, 1414, 1414, 1415, 1415, 1415, 1408, 1415, 2823,
-     1411, 1415, 1418, 1418, 1418, 2824, 1412, 2825, 2826, 1414,
-     1419, 1419, 1419, 1421, 1421, 1421, 1399, 1422, 1422, 1422,
-     1418, 1422, 2828, 2829, 1422, 1426, 1426, 1426, 1419, 2830,
-     2831, 1421, 1427, 1427, 1427, 1429, 1429, 1429, 2834, 2838,
-     1408, 2841, 2842, 1426, 1414, 1431, 1431, 1431, 2845, 2832,
-
-     1427, 2847, 2834, 1429, 1438, 1438, 1438, 1467, 1467, 1467,
-     1469, 1469, 1469, 1431, 1431, 2848, 1470, 1470, 1470, 1496,
-     1496, 1496, 1438, 1421, 1467, 1468, 1468, 1468, 1469, 1468,
-     2850, 2851, 1468, 1470, 1471, 1471, 1471, 1496, 1471, 2835,
-     2854, 1471, 1474, 1474, 1474, 2832, 1429, 1476, 1476, 1476,
-     2835, 1476, 2855, 2856, 1476, 1479, 1479, 1479, 2857, 2858,
-     1474, 2859, 1480, 1480, 1480, 2860, 1480, 2861, 1469, 1480,
-     1438, 2862, 1479, 1481, 1481, 1481, 2863, 1481, 2864, 2868,
-     1481, 1485, 1485, 1485, 2866, 1486, 1486, 1486, 2876, 1486,
-     2878, 1474, 1486, 1488, 1488, 1488, 2866, 2880, 1485, 1491,
-
-     1491, 1491, 1492, 1492, 1492, 2882, 1492, 2890, 2892, 1492,
-     2896, 1488, 1493, 1493, 1493, 2893, 1491, 1494, 1494, 1494,
-     1510, 1510, 1510, 1511, 1511, 1511, 1512, 1512, 1512, 1493,
-     1512, 2895, 2895, 1512, 2898, 1494, 2900, 1510, 2901, 2902,
-     1511, 2903, 2910, 1488, 1513, 1513, 1513, 1516, 1516, 1516,
-     1517, 1517, 1517, 1518, 1518, 1518, 2893, 1518, 2914, 2920,
-     1518, 2909, 1513, 2894, 2922, 1516, 1494, 1517, 1519, 1519,
-     1519, 1520, 1520, 1520, 1521, 1521, 1521, 2894, 1521, 2909,
-     2925, 1521, 1523, 1523, 1523, 2867, 1519, 2927, 1520, 1526,
-     1526, 1526, 1527, 1527, 1527, 2873, 1527, 2867, 2874, 1527,
-
-     1523, 1528, 1528, 1528, 2932, 2933, 1526, 2873, 1513, 2935,
-     2874, 1516, 1529, 1529, 1529, 1530, 1530, 1530, 1528, 1533,
-     1533, 1533, 2936, 1534, 1534, 1534, 2937, 1534, 1519, 1529,
-     1534, 2939, 2940, 1530, 2919, 2913, 1533, 1535, 1535, 1535,
-     1537, 1537, 1537, 1523, 1540, 1540, 1540, 1541, 1541, 1541,
-     2913, 1541, 2941, 2919, 1541, 1535, 2897, 1537, 1529, 2942,
-     2921, 1540, 1542, 1542, 1542, 2944, 1542, 2897, 2945, 1542,
-     1545, 1545, 1545, 1552, 1552, 1552, 1553, 1553, 1553, 2921,
-     1553, 1530, 2947, 1553, 1556, 1556, 1556, 1545, 1557, 1557,
-     1557, 1552, 1558, 1558, 1558, 1559, 1559, 1559, 1560, 1560,
-
-     1560, 1556, 2924, 1535, 2948, 1557, 1562, 1562, 1562, 1558,
-     2955, 2956, 1559, 1565, 1565, 1565, 1560, 1565, 2926, 2957,
-     1565, 2924, 2958, 1562, 1568, 1568, 1568, 1570, 1570, 1570,
-     1572, 1572, 1572, 1575, 1575, 1575, 2959, 2926, 1552, 1558,
-     2960, 1568, 1579, 1579, 1579, 1570, 2963, 2964, 1572, 2965,
-     2966, 1575, 2967, 1560, 1580, 1580, 1580, 2968, 1557, 1579,
-     1581, 1581, 1581, 2969, 1581, 1559, 2970, 1581, 2972, 1584,
-     1584, 1584, 1580, 1584, 2974, 2976, 1584, 1588, 1588, 1588,
-     1590, 1590, 1590, 2977, 1590, 2979, 2990, 1590, 1579, 2991,
-     1575, 1570, 1599, 1599, 1599, 1588, 1572, 1595, 1595, 1595,
-
-     2992, 1595, 2993, 2988, 1595, 1601, 1601, 1601, 2994, 2995,
-     1599, 1580, 1602, 1602, 1602, 2988, 1602, 2999, 3000, 1602,
-     1605, 1605, 1605, 1601, 1605, 2989, 3001, 1605, 1608, 1608,
-     1608, 1609, 1609, 1609, 3002, 1609, 3003, 2989, 1609, 3004,
-     1614, 1614, 1614, 1588, 1614, 3005, 1608, 1614, 1617, 1617,
-     1617, 3006, 3009, 1599, 1619, 1619, 1619, 1620, 1620, 1620,
-     3010, 1620, 1601, 3011, 1620, 3012, 1617, 1624, 1624, 1624,
-     3013, 1619, 1626, 1626, 1626, 1608, 1627, 1627, 1627, 1628,
-     1628, 1628, 1629, 1629, 1629, 1624, 1630, 1630, 1630, 1626,
-     1633, 1633, 1633, 3014, 1627, 1617, 3015, 1628, 3016, 1629,
-
-     1640, 1640, 1640, 3007, 1630, 1671, 1671, 1671, 1633, 1671,
-     3017, 3018, 1671, 1696, 1696, 1696, 1624, 3019, 1640, 1674,
-     1674, 1674, 1675, 1675, 1675, 3020, 1675, 3021, 3007, 1675,
-     1696, 1628, 1680, 1680, 1680, 3022, 3023, 1674, 1682, 1682,
-     1682, 1633, 1682, 1627, 3024, 1682, 3025, 3026, 1630, 3027,
-     1680, 3028, 1640, 1686, 1686, 1686, 3034, 1686, 1633, 3031,
-     1686, 1690, 1690, 1690, 1693, 1693, 1693, 3035, 1693, 3036,
-     3037, 1693, 3038, 1697, 1697, 1697, 3039, 1697, 3031, 1690,
-     1697, 3040, 3041, 1680, 3042, 3043, 1674, 1698, 1698, 1698,
-     1711, 1711, 1711, 1713, 1713, 1713, 1714, 1714, 1714, 3044,
-
-     1714, 3045, 3046, 1714, 3047, 1698, 3048, 1715, 1715, 1715,
-     1713, 1715, 3049, 3050, 1715, 1718, 1718, 1718, 1720, 1720,
-     1720, 3051, 1690, 1721, 1721, 1721, 3053, 1722, 1722, 1722,
-     3052, 1722, 3054, 1718, 1722, 1720, 3055, 3056, 1698, 3057,
-     3058, 1721, 1725, 1725, 1725, 1726, 1726, 1726, 3059, 1726,
-     3052, 3060, 1726, 3061, 1711, 1729, 1729, 1729, 3062, 3063,
-     1725, 3064, 1718, 1730, 1730, 1730, 3065, 1733, 1733, 1733,
-     1721, 1733, 1729, 3066, 1733, 1736, 1736, 1736, 1737, 1737,
-     1737, 1730, 1737, 3067, 3068, 1737, 1738, 1738, 1738, 1739,
-     1739, 1739, 1736, 1739, 3069, 3070, 1739, 1741, 1741, 1741,
-
-     1744, 1744, 1744, 1738, 1744, 3074, 3075, 1744, 1725, 3076,
-     1747, 1747, 1747, 3077, 3078, 1741, 1749, 1749, 1749, 1750,
-     1750, 1750, 3079, 1750, 3081, 3082, 1750, 1730, 1747, 1751,
-     1751, 1751, 3084, 1749, 1753, 1753, 1753, 3085, 1753, 3071,
-     3087, 1753, 1756, 1756, 1756, 3071, 1751, 1757, 1757, 1757,
-     3088, 1757, 3091, 3092, 1757, 3093, 1747, 3094, 3096, 1756,
-     1758, 1758, 1758, 1763, 1763, 1763, 1764, 1764, 1764, 1765,
-     1765, 1765, 1766, 1766, 1766, 3098, 1766, 1758, 3100, 1766,
-     1763, 1767, 1767, 1767, 1764, 3102, 1765, 1768, 1768, 1768,
-     1769, 1769, 1769, 1770, 1770, 1770, 3104, 3105, 1767, 1772,
-
-     1772, 1772, 3106, 3107, 1768, 3108, 3109, 1769, 1773, 1773,
-     1773, 1770, 1773, 3110, 3090, 1773, 1772, 1774, 1774, 1774,
-     1776, 1776, 1776, 1777, 1777, 1777, 3111, 1777, 3090, 3113,
-     1777, 3115, 1764, 3117, 1774, 3118, 3119, 1776, 1779, 1779,
-     1779, 1781, 1781, 1781, 3120, 1768, 1784, 1784, 1784, 1788,
-     1788, 1788, 3121, 1770, 3133, 3122, 1779, 3179, 3143, 1781,
-     1500, 1789, 1789, 1789, 1784, 1789, 1788, 1499, 1789, 1791,
-     1791, 1791, 1793, 1793, 1793, 3134, 1795, 1795, 1795, 1796,
-     1796, 1796, 1797, 1797, 1797, 3135, 3179, 1791, 3121, 3135,
-     1793, 3122, 1781, 1795, 1784, 3143, 1796, 3129, 3133, 1797,
-
-     1798, 1798, 1798, 1800, 1800, 1800, 1801, 1801, 1801, 1802,
-     1802, 1802, 1803, 1803, 1803, 1804, 1804, 1804, 1798, 3134,
-     3137, 1800, 3145, 1793, 1801, 3144, 1802, 3130, 3137, 1803,
-     1806, 1806, 1806, 1804, 1806, 3131, 3132, 1806, 1812, 1812,
-     1812, 1814, 1814, 1814, 3136, 3129, 1797, 3138, 3136, 1800,
-     1815, 1815, 1815, 1498, 1815, 3138, 1812, 1815, 1814, 1816,
-     1816, 1816, 3144, 3145, 1817, 1817, 1817, 1798, 1818, 1818,
-     1818, 1801, 1819, 1819, 1819, 3130, 1819, 1816, 1495, 1819,
-     1804, 1490, 1817, 3131, 3132, 1818, 1820, 1820, 1820, 1812,
-     1826, 1826, 1826, 1827, 1827, 1827, 1838, 1838, 1838, 1842,
-
-     1842, 1842, 1487, 1484, 1820, 1475, 3141, 1826, 1843, 1843,
-     1843, 1827, 1844, 1844, 1844, 1846, 1846, 1846, 1816, 1817,
-     1848, 1848, 1848, 1849, 1849, 1849, 1854, 1854, 1854, 1856,
-     1856, 1856, 1859, 1859, 1859, 1861, 1861, 1861, 1863, 1863,
-     1863, 1864, 1864, 1864, 1873, 1873, 1873, 1856, 1873, 3139,
-     1859, 1873, 1861, 3141, 1827, 3146, 1863, 3139, 1864, 1876,
-     1876, 1876, 1473, 1877, 1877, 1877, 1882, 1882, 1882, 1883,
-     1883, 1883, 1887, 1887, 1887, 3142, 3140, 1876, 3155, 1856,
-     1877, 1888, 1888, 1888, 3140, 1888, 1472, 3155, 1888, 1887,
-     1891, 1891, 1891, 1892, 1892, 1892, 3146, 1863, 1893, 1893,
-
-     1893, 1466, 1894, 1894, 1894, 1876, 1894, 3147, 1891, 1894,
-     1892, 1895, 1895, 1895, 3149, 1893, 1896, 1896, 1896, 1897,
-     1897, 1897, 3142, 1898, 1898, 1898, 3156, 1898, 3151, 1895,
-     1898, 1899, 1899, 1899, 1896, 3156, 1897, 1902, 1902, 1902,
-     3152, 1902, 3147, 1891, 1902, 1465, 1905, 1905, 1905, 1899,
-     1905, 3148, 1463, 1905, 1909, 1909, 1909, 1911, 1911, 1911,
-     3149, 1913, 1913, 1913, 1895, 3151, 1915, 1915, 1915, 3157,
-     1915, 3150, 1909, 1915, 1918, 1918, 1918, 3152, 1899, 1913,
-     1919, 1919, 1919, 1462, 1919, 3158, 3148, 1919, 1921, 1921,
-     1921, 1918, 1921, 3153, 3154, 1921, 1924, 1924, 1924, 1925,
-
-     1925, 1925, 3159, 1925, 3157, 3171, 1925, 1926, 1926, 1926,
-     1930, 1930, 1930, 1924, 1931, 1931, 1931, 3150, 1931, 1913,
-     3158, 1931, 3161, 3162, 1926, 3153, 3154, 1930, 1932, 1932,
-     1932, 1933, 1933, 1933, 3189, 1933, 3159, 3165, 1933, 1936,
-     1936, 1936, 3171, 1937, 1937, 1937, 1932, 1937, 3160, 1461,
-     1937, 1938, 1938, 1938, 3169, 1460, 1936, 1939, 1939, 1939,
-     1940, 1940, 1940, 3169, 1940, 3161, 3162, 1940, 1938, 1941,
-     1941, 1941, 3165, 3163, 1939, 3164, 1943, 1943, 1943, 1932,
-     1943, 3189, 3160, 1943, 1946, 1946, 1946, 1941, 1947, 1947,
-     1947, 3166, 1947, 3170, 1459, 1947, 1949, 1949, 1949, 3195,
-
-     1949, 1946, 3170, 1949, 1953, 1953, 1953, 1956, 1956, 1956,
-     1958, 1958, 1958, 1959, 1959, 1959, 1961, 1961, 1961, 3163,
-     1941, 3164, 1953, 3167, 3172, 1956, 3166, 1958, 1963, 1963,
-     1963, 1959, 1963, 1961, 3195, 1963, 1967, 1967, 1967, 1970,
-     1970, 1970, 1972, 1972, 1972, 1973, 1973, 1973, 1458, 1973,
-     3175, 3181, 1973, 3173, 1967, 3176, 3167, 1970, 3174, 1972,
-     3181, 3172, 1961, 1974, 1974, 1974, 1975, 1975, 1975, 1457,
-     1975, 1956, 1456, 1975, 1959, 1977, 1977, 1977, 3168, 3183,
-     1974, 1979, 1979, 1979, 1980, 1980, 1980, 1981, 1981, 1981,
-     1982, 1982, 1982, 1977, 1982, 3173, 3175, 1982, 3177, 1979,
-
-     3174, 3176, 1980, 3180, 1981, 1983, 1983, 1983, 1984, 1984,
-     1984, 3168, 1984, 3183, 3178, 1984, 1985, 1985, 1985, 1990,
-     1990, 1990, 1983, 3185, 1992, 1992, 1992, 3182, 1992, 3190,
-     1979, 1992, 3180, 3184, 1985, 3177, 3182, 1990, 1995, 1995,
-     1995, 1977, 1996, 1996, 1996, 3191, 1997, 1997, 1997, 1980,
-     1997, 3178, 1455, 1997, 1453, 1452, 1995, 2000, 2000, 2000,
-     1996, 2006, 2006, 2006, 2007, 2007, 2007, 3184, 2007, 3185,
-     3203, 2007, 2008, 2008, 2008, 2000, 3190, 1450, 2006, 3203,
-     3187, 1985, 3191, 3212, 1990, 2009, 2009, 2009, 3187, 1995,
-     2008, 2014, 2014, 2014, 3212, 1996, 2015, 2015, 2015, 2016,
-
-     2016, 2016, 2018, 2018, 2018, 2022, 2022, 2022, 2023, 2023,
-     2023, 2024, 2024, 2024, 2025, 2025, 2025, 2027, 2027, 2027,
-     2028, 2028, 2028, 2029, 2029, 2029, 2030, 2030, 2030, 2031,
-     2031, 2031, 2032, 2032, 2032, 3186, 2008, 2034, 2034, 2034,
-     2037, 2037, 2037, 3204, 2040, 2040, 2040, 2041, 2041, 2041,
-     3192, 2041, 3204, 1449, 2041, 2034, 1447, 3196, 2037, 3211,
-     2025, 2040, 2043, 2043, 2043, 2044, 2044, 2044, 2045, 2045,
-     2045, 3188, 2045, 3211, 3193, 2045, 2056, 2056, 2056, 3188,
-     2043, 3186, 2044, 2057, 2057, 2057, 3197, 3192, 2034, 2058,
-     2058, 2058, 3196, 2058, 2056, 1445, 2058, 2059, 2059, 2059,
-
-     2057, 2064, 2064, 2064, 2065, 2065, 2065, 2066, 2066, 2066,
-     2067, 2067, 2067, 1444, 2067, 3193, 3207, 2067, 2068, 2068,
-     2068, 2069, 2069, 2069, 2066, 2056, 2070, 2070, 2070, 3201,
-     2070, 3198, 3197, 2070, 1443, 1442, 2068, 3208, 2069, 2071,
-     2071, 2071, 3194, 2071, 1441, 3199, 2071, 2074, 2074, 2074,
-     2065, 1440, 2075, 2075, 2075, 2077, 2077, 2077, 1439, 2077,
-     3200, 3201, 2077, 1437, 3207, 2074, 2080, 2080, 2080, 2068,
-     2075, 2087, 2087, 2087, 2089, 2089, 2089, 3198, 2089, 1436,
-     1435, 2089, 3199, 3194, 2080, 3208, 2093, 2093, 2093, 2087,
-     2093, 3202, 1434, 2093, 2096, 2096, 2096, 3200, 2074, 2097,
-
-     2097, 2097, 1425, 2097, 3205, 3206, 2097, 1410, 2101, 2101,
-     2101, 2096, 2101, 1409, 1404, 2101, 2104, 2104, 2104, 2080,
-     2105, 2105, 2105, 3202, 2105, 1403, 2087, 2105, 2108, 2108,
-     2108, 2109, 2109, 2109, 2104, 2109, 3205, 3206, 2109, 2110,
-     2110, 2110, 3209, 2110, 1402, 2108, 2110, 2113, 2113, 2113,
-     2115, 2115, 2115, 1400, 2115, 1393, 1392, 2115, 2121, 2121,
-     2121, 2123, 2123, 2123, 1374, 2113, 2124, 2124, 2124, 1369,
-     2124, 1366, 1365, 2124, 3209, 3210, 2121, 1362, 2123, 1357,
-     2104, 2125, 2125, 2125, 2127, 2127, 2127, 2128, 2128, 2128,
-     1348, 2128, 1347, 1346, 2128, 1342, 2135, 2135, 2135, 2125,
-
-     1337, 2127, 2138, 2138, 2138, 1333, 2138, 3210, 1325, 2138,
-     2145, 2145, 2145, 2113, 2135, 2141, 2141, 2141, 1320, 2141,
-     1319, 1313, 2141, 1312, 2147, 2147, 2147, 1311, 2145, 2148,
-     2148, 2148, 2149, 2149, 2149, 1310, 2149, 1305, 1304, 2149,
-     1303, 2125, 2147, 1302, 2152, 2152, 2152, 2148, 2152, 1289,
-     1288, 2152, 2155, 2155, 2155, 1287, 2156, 2156, 2156, 1286,
-     1285, 2145, 2157, 2157, 2157, 2148, 2158, 2158, 2158, 1284,
-     2155, 1283, 2155, 2156, 2159, 2159, 2159, 1273, 1272, 2157,
-     2160, 2160, 2160, 2158, 2162, 2162, 2162, 2163, 2163, 2163,
-     2147, 2159, 2164, 2164, 2164, 2167, 2167, 2167, 2160, 2168,
-
-     2168, 2168, 2162, 2168, 1271, 2163, 2168, 2171, 2171, 2171,
-     2164, 1270, 1258, 2157, 2172, 2172, 2172, 2173, 2173, 2173,
-     2174, 2174, 2174, 1257, 1252, 2171, 2177, 2177, 2177, 1251,
-     2158, 1246, 1245, 2159, 2178, 2178, 2178, 2180, 2180, 2180,
-     2181, 2181, 2181, 1226, 2162, 2160, 2182, 2182, 2182, 2183,
-     2183, 2183, 2184, 2184, 2184, 2185, 2185, 2185, 2188, 2188,
-     2188, 2189, 2189, 2189, 1222, 1216, 2171, 2190, 2190, 2190,
-     2191, 2191, 2191, 2193, 2193, 2193, 2196, 2196, 2196, 2197,
-     2197, 2197, 1212, 2197, 1211, 1210, 2197, 2200, 2200, 2200,
-     1209, 2193, 1208, 2196, 2201, 2201, 2201, 1207, 2203, 2203,
-
-     2203, 1206, 2203, 1205, 2200, 2203, 2216, 2216, 2216, 2217,
-     2217, 2217, 2201, 2217, 2218, 2218, 2217, 2218, 1204, 2219,
-     2219, 1203, 2219, 1202, 2216, 2218, 1201, 1196, 2218, 1188,
-     2219, 1186, 2218, 2219, 2220, 2220, 2220, 2219, 2221, 2221,
-     2221, 2225, 2225, 2225, 2227, 2227, 2227, 1180, 2227, 1178,
-     1169, 2227, 1164, 2200, 2230, 2230, 2230, 2231, 2231, 2231,
-     1153, 2231, 1151, 1150, 2231, 1149, 1148, 2216, 2234, 2234,
-     2234, 1146, 2230, 2235, 2235, 2235, 2243, 2243, 2243, 2244,
-     2244, 2244, 1145, 2247, 2247, 2247, 2234, 2247, 1144, 1143,
-     2247, 2235, 2250, 2250, 2250, 1142, 1141, 2244, 1139, 1138,
-
-     2230, 2253, 2253, 2253, 2254, 2254, 2254, 1137, 2254, 2250,
-     1136, 2254, 2257, 2257, 2257, 2262, 2262, 2262, 1135, 2253,
-     2264, 2264, 2264, 1134, 2235, 2265, 2265, 2265, 1133, 2265,
-     2257, 1132, 2265, 2262, 2268, 2268, 2268, 2264, 1131, 2244,
-     2269, 2269, 2269, 2270, 2270, 2270, 1130, 2270, 1129, 1128,
-     2270, 1127, 2268, 2273, 2273, 2273, 1126, 2269, 2274, 2274,
-     2274, 2279, 2279, 2279, 2281, 2281, 2281, 2284, 2284, 2284,
-     2273, 2283, 2283, 2283, 1120, 2274, 1119, 1118, 2279, 2285,
-     2285, 2285, 1115, 1114, 2284, 2268, 2269, 1113, 1111, 2283,
-     1107, 2286, 2286, 2286, 2288, 2288, 2288, 2285, 2287, 2287,
-
-     2287, 1104, 1095, 2289, 2289, 2289, 1094, 2289, 2273, 2286,
-     2289, 2288, 2279, 2290, 2290, 2290, 2287, 1091, 1090, 2274,
-     2291, 2291, 2291, 2292, 2292, 2292, 2293, 2293, 2293, 1089,
-     2290, 2294, 2294, 2294, 1088, 2287, 1087, 2291, 1073, 2285,
-     2292, 2295, 2295, 2295, 2293, 2296, 2296, 2296, 2298, 2298,
-     2298, 1066, 2286, 2301, 2301, 2301, 2303, 2303, 2303, 2295,
-     2302, 2302, 2302, 2296, 1058, 1057, 2298, 2304, 2304, 2304,
-     1056, 2291, 1053, 1050, 2292, 2307, 2307, 2307, 2302, 2308,
-     2308, 2308, 2309, 2309, 2309, 2310, 2310, 2310, 2314, 2314,
-     2314, 2317, 2317, 2317, 2318, 2318, 2318, 1047, 2318, 1042,
-
-     1039, 2318, 2330, 2330, 2330, 1038, 2314, 2295, 2317, 1034,
-     2298, 2343, 2343, 2343, 2346, 2346, 2346, 2348, 2348, 2348,
-     2330, 2349, 2349, 2349, 2351, 2351, 2351, 2358, 2358, 2358,
-     2359, 2359, 2359, 1032, 1018, 2348, 2360, 2360, 2360, 2349,
-     1017, 1016, 2351, 1015, 2358, 1014, 2363, 2363, 2363, 2364,
-     2364, 2364, 1013, 2364, 2360, 1012, 2364, 2366, 2366, 2366,
-     1008, 1004, 2330, 2363, 2367, 2367, 2367, 2369, 2369, 2369,
-     2373, 2373, 2373,  997, 2366, 2375, 2375, 2375,  996, 2377,
-     2377, 2377, 2367, 2348,  995, 2369,  992, 2373, 2378, 2378,
-     2378,  991, 2375, 2360, 2376, 2376, 2376, 2377, 2376,  988,
-
-      987, 2376, 2379, 2379, 2379, 2378, 2379,  986,  983, 2379,
-     2380, 2380, 2380, 2381, 2381, 2381, 2382, 2382, 2382, 2387,
-     2387, 2387, 2389, 2389, 2389,  982,  979, 2380,  974,  971,
-     2381,  968,  967, 2382,  964,  963, 2387, 2391, 2391, 2391,
-     2393, 2393, 2393, 2394, 2394, 2394,  962, 2394,  961,  960,
-     2394, 2395, 2395, 2395,  958, 2391,  957, 2393, 2396, 2396,
-     2396,  956, 2380, 2397, 2397, 2397, 2398, 2398, 2398, 2395,
-     2398, 2381,  955, 2398, 2382,  954, 2396, 2401, 2401, 2401,
-      953, 2397, 2402, 2402, 2402,  949, 2402,  944,  943, 2402,
-     2403, 2403, 2403,  942, 2401, 2404, 2404, 2404, 2405, 2405,
-
-     2405, 2407, 2407, 2407, 2408, 2408, 2408, 2403, 2412, 2412,
-     2412,  941, 2404, 2416, 2416, 2416, 2405, 2420, 2420, 2420,
-      938,  937, 2408,  936,  934, 2396, 2412, 2397, 2421, 2421,
-     2421,  930, 2421,  926, 2420, 2421, 2435, 2435, 2435, 2452,
-     2452, 2452, 2454, 2454, 2454, 2455, 2455, 2455, 2458, 2458,
-     2458, 2461, 2461, 2461, 2435, 2462, 2462, 2462,  925, 2462,
-     2454,  922, 2462, 2455,  919, 2458,  918,  917, 2461, 2463,
-     2463, 2463, 2466, 2466, 2466,  916, 2466,  915,  914, 2466,
-     2470, 2470, 2470,  913, 2471, 2471, 2471, 2463, 2471,  911,
-      910, 2471, 2473, 2473, 2473,  909, 2435, 2470, 2474, 2474,
-
-     2474, 2475, 2475, 2475,  908, 2475,  907,  906, 2475, 2473,
-     2476, 2476, 2476, 2454,  905, 2474, 2477, 2477, 2477,  904,
-     2477,  903,  902, 2477, 2480, 2480, 2480, 2476, 2482, 2482,
-     2482,  901, 2482,  900,  899, 2482, 2485, 2485, 2485, 2486,
-     2486, 2486, 2480, 2487, 2487, 2487, 2490, 2490, 2490,  898,
-     2491, 2491, 2491, 2485, 2491,  897, 2486, 2491,  896,  895,
-     2487,  894,  893, 2490, 2492, 2492, 2492, 2493, 2493, 2493,
-     2494, 2494, 2494,  892, 2494,  888,  887, 2494, 2497, 2497,
-     2497, 2492,  885,  884, 2493, 2499, 2499, 2499,  883,  882,
-     2486, 2485, 2500, 2500, 2500,  881, 2497,  877, 2487,  875,
-
-     2501, 2501, 2501, 2499, 2501,  874,  873, 2501,  872,  868,
-     2500, 2504, 2504, 2504, 2505, 2505, 2505,  864, 2505,  863,
-      860, 2505, 2506, 2506, 2506, 2507, 2507, 2507, 2504, 2507,
-      859,  858, 2507,  857, 2508, 2508, 2508,  856,  855, 2506,
-     2514, 2514, 2514, 2518, 2518, 2518, 2537, 2537, 2537,  854,
-      851, 2499, 2508, 2500, 2519, 2519, 2519,  850, 2519,  849,
-     2518, 2519,  848,  845, 2537, 2553, 2553, 2553, 2555, 2555,
-     2555, 2556, 2556, 2556, 2557, 2557, 2557, 2558, 2558, 2558,
-      844, 2558,  843,  840, 2558,  838, 2555,  835, 2556,  834,
-      833, 2557, 2559, 2559, 2559,  832, 2559, 2537,  831, 2559,
-
-     2562, 2562, 2562, 2567, 2567, 2567,  828, 2567,  827,  826,
-     2567, 2571, 2571, 2571, 2606, 2606, 2606, 2556, 2562, 2572,
-     2572, 2572,  825, 2572,  824,  821, 2572,  820, 2571,  819,
-     2555, 2573, 2573, 2573,  818, 2573,  816,  813, 2573, 2576,
-     2576, 2576, 2577, 2577, 2577,  812, 2577,  810,  807, 2577,
-     2578, 2578, 2578, 2579, 2579, 2579, 2576, 2580, 2580, 2580,
-      805, 2581, 2581, 2581,  802, 2581,  801, 2578, 2581,  800,
-     2579, 2584, 2584, 2584, 2580, 2585, 2585, 2585,  799, 2585,
-      797,  796, 2585, 2586, 2586, 2586,  795,  792, 2584, 2587,
-     2587, 2587,  791, 2587,  790,  789, 2587, 2594, 2594, 2594,
-
-     2586, 2595, 2595, 2595,  788,  787, 2580,  782, 2578, 2596,
-     2596, 2596,  781, 2596,  780, 2594, 2596,  779,  778, 2595,
-     2599, 2599, 2599,  777, 2599,  776,  775, 2599, 2604, 2604,
-     2604, 2607, 2607, 2607, 2610, 2610, 2610,  774, 2610,  772,
-      770, 2610, 2621, 2621, 2621, 2604, 2604,  769, 2594, 2630,
-     2630, 2630, 2646, 2646, 2646, 2647, 2647, 2647,  766, 2621,
-     2648, 2648, 2648, 2649, 2649, 2649,  763, 2630, 2595, 2650,
-     2650, 2650,  759, 2650,  758,  757, 2650,  754, 2648,  751,
-     2649, 2652, 2652, 2652,  750, 2652,  749,  746, 2652, 2659,
-     2659, 2659,  745, 2659,  741,  740, 2659,  738, 2630, 2662,
-
-     2662, 2662,  735, 2662,  734,  733, 2662, 2665, 2665, 2665,
-      731, 2648, 2666, 2666, 2666, 2667, 2667, 2667,  720, 2667,
-      719,  717, 2667,  716, 2665, 2668, 2668, 2668,  714, 2666,
-     2669, 2669, 2669,  713, 2669,  712,  708, 2669,  707, 2672,
-     2672, 2672, 2668, 2672,  706,  705, 2672, 2681, 2681, 2681,
-     2682, 2682, 2682, 2688, 2688, 2688,  701,  700, 2665, 2689,
-     2689, 2689, 2690, 2690, 2690, 2681, 2690,  699, 2682, 2690,
-     2688, 2688, 2691, 2691, 2691,  698, 2689, 2689,  697,  696,
-     2690, 2692, 2692, 2692, 2693, 2693, 2693, 2694, 2694, 2694,
-     2703, 2703, 2703, 2704, 2704, 2704, 2668, 2704,  695,  693,
-
-     2704, 2713, 2713, 2713, 2728, 2728, 2728, 2703, 2729, 2729,
-     2729, 2730, 2730, 2730,  690,  689, 2682,  687,  685, 2713,
-     2731, 2731, 2731,  682, 2731,  681,  675, 2731,  673, 2730,
-     2737, 2737, 2737, 2739, 2739, 2739, 2740, 2740, 2740,  671,
-     2740,  668,  667, 2740, 2743, 2743, 2743, 2737,  663,  662,
-     2739, 2758, 2758, 2758, 2760, 2760, 2760, 2766, 2766, 2766,
-      661, 2743,  658,  657, 2767, 2767, 2767, 2713, 2767, 2758,
-      656, 2767, 2760,  655, 2766, 2766, 2768, 2768, 2768,  652,
-     2768,  651, 2767, 2768, 2771, 2771, 2771, 2772, 2772, 2772,
-     2773, 2773, 2773,  650, 2768, 2782, 2782, 2782,  649, 2782,
-
-      648,  642, 2782,  641,  639, 2760, 2769, 2769, 2769, 2769,
-     2769, 2769, 2769, 2769, 2769,  633,  632, 2769, 2791, 2791,
-     2791,  628, 2769, 2769, 2769, 2769, 2769, 2802, 2802, 2802,
-     2803, 2803, 2803, 2808, 2808, 2808, 2791, 2809, 2809, 2809,
-      621, 2809,  617,  611, 2809, 2811, 2811, 2811, 2803,  607,
-     2808, 2769, 2769, 2770, 2770, 2770, 2770, 2770, 2770, 2770,
-     2770, 2770, 2811,  603, 2770, 2813, 2813, 2813,  599, 2770,
-     2770, 2770, 2770, 2770, 2812, 2812, 2812,  598, 2812,  597,
-      596, 2812, 2813, 2814, 2814, 2814,  595, 2814,  591,  587,
-     2814, 2827, 2827, 2827, 2852, 2852, 2852,  584, 2770, 2770,
-
-     2833, 2833, 2833,  583, 2833,  582,  578, 2833,  574, 2827,
-      571,  570, 2852, 2887, 2887, 2887,  566,  560, 2833, 2836,
-     2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836,  559,  555,
-     2836, 2887,  551,  547,  546, 2836, 2836, 2836, 2836, 2836,
-     2865, 2865, 2865,  542, 2865,  539,  538, 2865, 2869, 2869,
-     2869,  533, 2869,  529,  521, 2869, 2872, 2872, 2872,  520,
-     2872,  519,  515, 2872, 2836, 2836, 2837, 2837, 2837, 2837,
-     2837, 2837, 2837, 2837, 2837,  509,  508, 2837, 2899, 2899,
-     2899,  507, 2837, 2837, 2837, 2837, 2837, 2916, 2916, 2916,
-     2917, 2917, 2917, 2918, 2918, 2918, 2899, 2899, 2923, 2923,
-
-     2923, 2934, 2934, 2934, 2916,  503,  497, 2917,  496,  492,
-     2918, 2837, 2837,  486,  485, 2923, 2938, 2938, 2938, 2934,
-     2949, 2949, 2949, 2950, 2950, 2950,  484, 2950,  483,  482,
-     2950, 2951, 2951, 2951, 2938,  481,  480, 2949, 2952, 2952,
-     2952,  476, 2952,  470,  469, 2952,  467,  466, 2951, 2953,
-     2953, 2953, 2954, 2954, 2954,  465, 2954,  461,  452, 2954,
-     2961, 2961, 2961, 2971, 2971, 2971, 2953, 2938, 2962, 2962,
-     2962,  451, 2962,  450,  448, 2962,  444, 2961, 2981, 2981,
-     2981, 2971, 2981,  438,  437, 2981, 2984, 2984, 2984,  436,
-     2984,  432,  428, 2984, 2987, 2987, 2987,  424, 2987,  423,
-
-     2971, 2987, 2996, 2996, 2996,  422, 2996,  421,  420, 2996,
-     3103, 3103, 3103, 3112, 3112, 3112,  416, 3112,  410,  409,
-     3112, 3213, 3213, 3213, 3214, 3214, 3214,  405, 3103,  399,
-      398, 3112,  394,  387,  386,  385,  381,  374,  373, 3213,
-      372,  371, 3214, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
-     3217, 3217, 3218, 3218, 3218, 3218, 3218, 3218, 3218, 3218,
-     3218, 3219, 3219, 3219, 3219, 3219, 3219, 3219, 3219, 3219,
-     3220, 3220, 3220, 3220, 3220, 3220, 3220, 3220, 3220, 3221,
-     3221, 3221, 3221, 3221, 3221, 3221, 3221, 3221, 3222, 3222,
-     3222, 3222, 3222, 3222, 3222, 3222, 3222, 3223, 3223, 3223,
-
-     3223, 3223, 3223, 3223, 3223, 3223, 3224, 3224, 3224, 3224,
-     3224, 3224, 3224, 3224, 3224, 3225, 3225, 3225, 3225, 3225,
-     3225, 3225, 3225, 3225, 3226, 3226, 3226, 3226, 3226, 3226,
-     3226, 3226, 3226, 3227, 3227, 3227, 3227, 3227, 3227, 3227,
-     3227, 3227, 3228, 3228, 3228, 3228, 3228, 3228, 3228, 3228,
-     3228, 3229, 3229, 3229, 3229, 3229, 3229, 3229, 3229, 3229,
-     3230, 3230, 3230, 3230, 3230, 3230, 3230, 3230, 3230, 3231,
-     3231, 3231, 3231, 3231, 3231, 3231, 3231, 3231, 3232, 3232,
-     3232, 3232, 3232, 3232, 3232, 3232, 3232, 3233, 3233, 3233,
-     3233, 3233, 3233, 3233, 3233, 3233, 3234, 3234, 3234, 3234,
-
-     3234, 3234, 3234, 3234, 3234, 3235, 3235, 3235, 3235, 3235,
-     3235, 3235, 3235, 3235, 3236, 3236, 3236, 3236, 3236, 3236,
-     3236, 3236, 3236, 3237, 3237, 3237, 3237, 3237, 3237, 3237,
-     3237, 3237, 3238, 3238, 3238, 3238, 3238, 3238, 3238, 3238,
-     3238, 3239, 3239, 3239, 3239, 3239, 3239, 3239, 3239, 3239,
-     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3241,
-     3241, 3241, 3241, 3241, 3241, 3241, 3241, 3241, 3242, 3242,
-     3242, 3242, 3242, 3242, 3242, 3242, 3242, 3243, 3243, 3243,
-     3243, 3243, 3243, 3243, 3243, 3243, 3244, 3244, 3244, 3244,
-     3244, 3244, 3244, 3244, 3244, 3245, 3245, 3245, 3245, 3245,
-
-     3245, 3245, 3245, 3245, 3246, 3246, 3246, 3246, 3246, 3246,
-     3246, 3246, 3246, 3247, 3247, 3247, 3247, 3247, 3247, 3247,
-     3247, 3247, 3248, 3248, 3248, 3248, 3248, 3248, 3248, 3248,
-     3248, 3249, 3249, 3249, 3249, 3249, 3249, 3249, 3249, 3249,
-     3250, 3250, 3250, 3250, 3250, 3250, 3250, 3250, 3250, 3251,
-     3251, 3251, 3251, 3251, 3251, 3251, 3251, 3251, 3252, 3252,
-     3252, 3252, 3252, 3252, 3252, 3252, 3252, 3253, 3253, 3253,
-     3253, 3253, 3253, 3253, 3253, 3253, 3254, 3254, 3254, 3254,
-     3254, 3254, 3254, 3254, 3254, 3255, 3255, 3255, 3255, 3255,
-     3255, 3255, 3255, 3255, 3256, 3256, 3256, 3256, 3256, 3256,
-
-     3256, 3256, 3256, 3257, 3257, 3257, 3257, 3257, 3257, 3257,
-     3257, 3257, 3258, 3258, 3258, 3258, 3258, 3258, 3258, 3258,
-     3258, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259,
-     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,  367,  363,  358,
-     3276, 3277, 3277, 3277,  350,  349,  345, 3277, 3278, 3278,
-     3278,  339,  338,  337, 3278, 3279, 3279, 3279,  333,  324,
-
-      322, 3279, 3280, 3280, 3280,  321,  317,  314, 3280, 3281,
-     3281, 3281,  312,  311,  310, 3281, 3282, 3282, 3282,  306,
-      302,  299, 3282, 3283, 3283, 3283,  295,  292,  291, 3283,
-     3284, 3284, 3284,  283,  279,  275, 3284, 3285, 3285, 3285,
-      274,  273,  267, 3285, 3286, 3286, 3286,  266,  264,  261,
-     3286, 3287, 3287, 3287,  249,    0,    0, 3287, 3288, 3288,
+      244,  244,  244,  244,  244,  244, 1061,  244,  244,  244,
+      244,  244, 2439, 1064, 1066, 1066, 1066, 1069, 1069, 1069,
+     2423, 1070, 1070, 1070, 1071, 1071, 1071, 1072, 1072, 1072,
+     2423, 2440, 1066, 2423, 1069, 2441,  244,  244, 1070, 2442,
+     2443, 1071, 1075, 1075, 1075, 1072, 2444,  244, 1073, 1073,
+
+     1073, 1077, 1077, 1077, 1078, 1078, 1078, 2445, 2446, 1075,
+      244,  286, 1079, 1079, 1079, 2447, 1073, 1069,  286, 1077,
+     2448, 2424, 1078, 2449, 2450, 1066, 2451,  286,  286, 1079,
+     2452, 2424, 1069, 1071, 2424, 1073, 1080, 1080, 1080, 2454,
+     1081, 1081, 1081, 1082, 1082, 1082, 2458, 1083, 1083, 1083,
+     1086, 1086, 1086, 1080, 2465,  286,  286,  286, 1081, 1078,
+     2466, 1082,  286,  286, 1083, 2470,  286,  286, 1086, 2473,
+      286, 2514,  286,  286,  286,  351, 2516, 2517, 1084, 1084,
+     1084, 2518,  351, 1085, 1085, 1085, 1087, 1087, 1087, 2521,
+     2512,  351,  351, 2511, 2522, 1084, 2524, 1093, 1093, 1093,
+
+     1085, 1099, 1099, 1099, 1087, 1094, 1094, 1094, 1103, 1103,
+     1103, 1097, 1097, 1097, 1082, 1093, 2525, 2527, 1099,  351,
+      351,  351, 2511, 1094, 2528, 1103,  351,  351, 1084, 1097,
+      351,  351, 2512, 2529,  351, 2530,  351,  351,  351, 2531,
+     1098, 1098, 1098, 1084, 1101, 1101, 1101, 1102, 1102, 1102,
+     2513, 2523, 1104, 1104, 1104, 2533, 1104, 1087, 1098, 1104,
+     2534, 2535, 1101, 2536, 2523, 1102, 1106, 1106, 1106, 1094,
+     1107, 1107, 1107, 1122, 1122, 1122, 1123, 1123, 1123, 1125,
+     1125, 1125, 2526, 2539, 1106, 1155, 1155, 1155, 1107, 2540,
+     2541, 1122, 2513, 2542, 1123, 2526, 2543, 1125, 1156, 1156,
+
+     1156, 2544, 1155, 2545, 1098, 1157, 1157, 1157, 1102, 1159,
+     1159, 1159, 1160, 1160, 1160, 2546, 1156, 1161, 1161, 1161,
+     2547, 1161, 2548, 1157, 1161, 2549, 1125, 1159, 2550, 1160,
+     1164, 1164, 1164, 2551, 1107, 1166, 1166, 1166, 1167, 1167,
+     1167, 1169, 1169, 1169, 1171, 1171, 1171, 1164, 1171, 2552,
+     2553, 1171, 2555, 1166, 2565, 2566, 1167, 2567, 1159, 1169,
+     1174, 1174, 1174, 1175, 1175, 1175, 2496, 1175, 2571, 2589,
+     1175, 2590, 1176, 1176, 1176, 2591, 2496, 1174, 1177, 1177,
+     1177, 2592, 2496, 1178, 1178, 1178, 2593, 1178, 1169, 1176,
+     1178, 1164, 1180, 1180, 1180, 1177, 1182, 1182, 1182, 1183,
+
+     1183, 1183, 1185, 1185, 1185, 1187, 1187, 1187, 2594, 1180,
+     1189, 1189, 1189, 2598, 1182, 2606, 2609, 1183, 2610, 2603,
+     1185, 2614, 1187, 1190, 1190, 1190, 2598, 2599, 1189, 1192,
+     1192, 1192, 1193, 1193, 1193, 2615, 1193, 2616, 2617, 1193,
+     2599, 1190, 1197, 1197, 1197, 2618, 2604, 1192, 1198, 1198,
+     1198, 1200, 1200, 1200, 1214, 1214, 1214, 2619, 1214, 2620,
+     1197, 1214, 1185, 1218, 1218, 1218, 1198, 2603, 2621, 1200,
+     1219, 1219, 1219, 1220, 1220, 1220, 1192, 1222, 1222, 1222,
+     1218, 2604, 1224, 1224, 1224, 2623, 1224, 2624, 1219, 1224,
+     2625, 1220, 1228, 1228, 1228, 1222, 1229, 1229, 1229, 1231,
+
+     1231, 1231, 1232, 1232, 1232, 2626, 1232, 2627, 2628, 1232,
+     1228, 1235, 1235, 1235, 1229, 2629, 2630, 1231, 1236, 1236,
+     1236, 1237, 1237, 1237, 1239, 1239, 1239, 2632, 1235, 1240,
+     1240, 1240, 2633, 1241, 1241, 1241, 1236, 2634, 1222, 1237,
+     2635, 2636, 1239, 1743, 1743, 1743, 1240, 1242, 1242, 1242,
+     1241, 1243, 1243, 1243, 1245, 1245, 1245, 1248, 1248, 1248,
+     1231, 1241, 1254, 1254, 1254, 1242, 1249, 1249, 1249, 1243,
+     1249, 2637, 1245, 1249, 1248, 1255, 1255, 1255, 2638, 2639,
+     1254, 1257, 1257, 1257, 1260, 1260, 1260, 2640, 1261, 1261,
+     1261, 1239, 1261, 1255, 2641, 1261, 1264, 1264, 1264, 1257,
+
+     1264, 1260, 2642, 1264, 1267, 1267, 1267, 1268, 1268, 1268,
+     1270, 1270, 1270, 2497, 1275, 1275, 1275, 2643, 1275, 2644,
+     1245, 1275, 1267, 2497, 2645, 1268, 2646, 2652, 1270, 2497,
+     1278, 1278, 1278, 1279, 1279, 1279, 2656, 1279, 2657, 2658,
+     1279, 1282, 1282, 1282, 2659, 2676, 1257, 1278, 1283, 1283,
+     1283, 2677, 1283, 2678, 2679, 1283, 2680, 2681, 1282, 1291,
+     1291, 1291, 1292, 1292, 1292, 1294, 1294, 1294, 2671, 1295,
+     1295, 1295, 2672, 1295, 2684, 1270, 1295, 1291, 2671, 2674,
+     1292, 2685, 2672, 1294, 1298, 1298, 1298, 2686, 1298, 2674,
+     2675, 1298, 1301, 1301, 1301, 1302, 1302, 1302, 2687, 1302,
+
+     2675, 2688, 1302, 1307, 1307, 1307, 1308, 1308, 1308, 1301,
+     1310, 1310, 1310, 1315, 1315, 1315, 2696, 1315, 2697, 2698,
+     1315, 1307, 2699, 2700, 1308, 1318, 1318, 1318, 1310, 1319,
+     1319, 1319, 1294, 1319, 2701, 2688, 1319, 1322, 1322, 1322,
+     2702, 2703, 1318, 1323, 1323, 1323, 1325, 1325, 1325, 1327,
+     1327, 1327, 2706, 1327, 2707, 1322, 1327, 2709, 1310, 2710,
+     2711, 1323, 2713, 2715, 1325, 1330, 1330, 1330, 1331, 1331,
+     1331, 1333, 1333, 1333, 1335, 1335, 1335, 2716, 1335, 2717,
+     2720, 1335, 2721, 1330, 2722, 2723, 1331, 2724, 2727, 1333,
+     1339, 1339, 1339, 1340, 1340, 1340, 2728, 1325, 1342, 1342,
+
+     1342, 2735, 1344, 1344, 1344, 2736, 1344, 2737, 1339, 1344,
+     2739, 1340, 1350, 1350, 1350, 2745, 1342, 1351, 1351, 1351,
+     2746, 1353, 1353, 1353, 1354, 1354, 1354, 1355, 1355, 1355,
+     1350, 1355, 2747, 2748, 1355, 1351, 2749, 2750, 1333, 1353,
+     2751, 1354, 1356, 1356, 1356, 2752, 2753, 1342, 1357, 1357,
+     1357, 2754, 1357, 2756, 2757, 1357, 1359, 1359, 1359, 1356,
+     1360, 1360, 1360, 2762, 1362, 1362, 1362, 1364, 1364, 1364,
+     2763, 1368, 1368, 1368, 1359, 1835, 1835, 1835, 1360, 2764,
+     2765, 1353, 1362, 2775, 1364, 1365, 1365, 1365, 1368, 1365,
+     2776, 2777, 1365, 1369, 1369, 1369, 2778, 1369, 2779, 2780,
+
+     1369, 1371, 1371, 1371, 1372, 1372, 1372, 1374, 1374, 1374,
+     1376, 1376, 1376, 2781, 1376, 2782, 2786, 1376, 2787, 1371,
+     2788, 2766, 1372, 2789, 2790, 1374, 1379, 1379, 1379, 2791,
+     2793, 1362, 1380, 1380, 1380, 1382, 1382, 1382, 1383, 1383,
+     1383, 1384, 1384, 1384, 1379, 1384, 2794, 2796, 1384, 2797,
+     1380, 2798, 2799, 1382, 2801, 1383, 1385, 1385, 1385, 1386,
+     1386, 1386, 2802, 1386, 2766, 2806, 1386, 1387, 1387, 1387,
+     2807, 1374, 2808, 1385, 1388, 1388, 1388, 2811, 1390, 1390,
+     1390, 1391, 1391, 1391, 2816, 1387, 1392, 1392, 1392, 2817,
+     1392, 2818, 1388, 1392, 2819, 1382, 1390, 2820, 1391, 1395,
+
+     1395, 1395, 1396, 1396, 1396, 2821, 1396, 2822, 2823, 1396,
+     1397, 1397, 1397, 1398, 1398, 1398, 1395, 1400, 1400, 1400,
+     1402, 1402, 1402, 1406, 1406, 1406, 2824, 2825, 1397, 2826,
+     2827, 1398, 1407, 1407, 1407, 1400, 2829, 1402, 2830, 2831,
+     1390, 1406, 1409, 1409, 1409, 1412, 1412, 1412, 2832, 2839,
+     1407, 1413, 1413, 1413, 1415, 1415, 1415, 1416, 1416, 1416,
+     1409, 1416, 2842, 1412, 1416, 1419, 1419, 1419, 2833, 1413,
+     2843, 2835, 1415, 1420, 1420, 1420, 1422, 1422, 1422, 1400,
+     1423, 1423, 1423, 1419, 1423, 2835, 2846, 1423, 1427, 1427,
+     1427, 1420, 2848, 2836, 1422, 1428, 1428, 1428, 1430, 1430,
+
+     1430, 2849, 2851, 1409, 2836, 2852, 1427, 1415, 1432, 1432,
+     1432, 2855, 2856, 1428, 2833, 2857, 1430, 1439, 1439, 1439,
+     1468, 1468, 1468, 1470, 1470, 1470, 1432, 1432, 2858, 1471,
+     1471, 1471, 1496, 1496, 1496, 1439, 1422, 1468, 1469, 1469,
+     1469, 1470, 1469, 2859, 2860, 1469, 1471, 1472, 1472, 1472,
+     1496, 1472, 2861, 2862, 1472, 1475, 1475, 1475, 2863, 1430,
+     1477, 1477, 1477, 2864, 1477, 2865, 2867, 1477, 1480, 1480,
+     1480, 2869, 2868, 1475, 2877, 1481, 1481, 1481, 2867, 1481,
+     2874, 1470, 1481, 1439, 2868, 1480, 1482, 1482, 1482, 2875,
+     1482, 2879, 2874, 1482, 1486, 1486, 1486, 2881, 1487, 1487,
+
+     1487, 2875, 1487, 2883, 1475, 1487, 1489, 1489, 1489, 2891,
+     2893, 1486, 1491, 1491, 1491, 1492, 1492, 1492, 2897, 1492,
+     2896, 2896, 1492, 2899, 1489, 1493, 1493, 1493, 2894, 1491,
+     1494, 1494, 1494, 1511, 1511, 1511, 1512, 1512, 1512, 1513,
+     1513, 1513, 1493, 1513, 2898, 2901, 1513, 2902, 1494, 2903,
+     1511, 2904, 2911, 1512, 2910, 2898, 1489, 1514, 1514, 1514,
+     1517, 1517, 1517, 1518, 1518, 1518, 1519, 1519, 1519, 2894,
+     1519, 2915, 2910, 1519, 2920, 1514, 2895, 2914, 1517, 1494,
+     1518, 1520, 1520, 1520, 1521, 1521, 1521, 1522, 1522, 1522,
+     2895, 1522, 2914, 2920, 1522, 1524, 1524, 1524, 2921, 1520,
+
+     2923, 1521, 1527, 1527, 1527, 1528, 1528, 1528, 2926, 1528,
+     2928, 2933, 1528, 1524, 1529, 1529, 1529, 2934, 2936, 1527,
+     2922, 1514, 2937, 2938, 1517, 1530, 1530, 1530, 1531, 1531,
+     1531, 1529, 1534, 1534, 1534, 2940, 1535, 1535, 1535, 2922,
+     1535, 1520, 1530, 1535, 2925, 2941, 1531, 2927, 2942, 1534,
+     1536, 1536, 1536, 1538, 1538, 1538, 1524, 1541, 1541, 1541,
+     1542, 1542, 1542, 2925, 1542, 2943, 2927, 1542, 1536, 2945,
+     1538, 1530, 2946, 2948, 1541, 1543, 1543, 1543, 2949, 1543,
+     2956, 2957, 1543, 1546, 1546, 1546, 1553, 1553, 1553, 1554,
+     1554, 1554, 2958, 1554, 1531, 2959, 1554, 1557, 1557, 1557,
+
+     1546, 1558, 1558, 1558, 1553, 1559, 1559, 1559, 1560, 1560,
+     1560, 1561, 1561, 1561, 1557, 2960, 1536, 2961, 1558, 1563,
+     1563, 1563, 1559, 2964, 2965, 1560, 1566, 1566, 1566, 1561,
+     1566, 2966, 2967, 1566, 2968, 2969, 1563, 1569, 1569, 1569,
+     1571, 1571, 1571, 1573, 1573, 1573, 1576, 1576, 1576, 2970,
+     2971, 1553, 1559, 2973, 1569, 1580, 1580, 1580, 1571, 2975,
+     2977, 1573, 2978, 2980, 1576, 2991, 1561, 1581, 1581, 1581,
+     2992, 1558, 1580, 1582, 1582, 1582, 2989, 1582, 1560, 2993,
+     1582, 2994, 1585, 1585, 1585, 1581, 1585, 2990, 2989, 1585,
+     1589, 1589, 1589, 1591, 1591, 1591, 2995, 1591, 2996, 2990,
+
+     1591, 1580, 3000, 1576, 1571, 1600, 1600, 1600, 1589, 1573,
+     1596, 1596, 1596, 3001, 1596, 3002, 3003, 1596, 1602, 1602,
+     1602, 3004, 3005, 1600, 1581, 1603, 1603, 1603, 3006, 1603,
+     3007, 3010, 1603, 1606, 1606, 1606, 1602, 1606, 3011, 3008,
+     1606, 1609, 1609, 1609, 1610, 1610, 1610, 3012, 1610, 3013,
+     3014, 1610, 3015, 1615, 1615, 1615, 1589, 1615, 3016, 1609,
+     1615, 1618, 1618, 1618, 3008, 3017, 1600, 1620, 1620, 1620,
+     1621, 1621, 1621, 3018, 1621, 1602, 3019, 1621, 3020, 1618,
+     1625, 1625, 1625, 3021, 1620, 1627, 1627, 1627, 1609, 1628,
+     1628, 1628, 1629, 1629, 1629, 1630, 1630, 1630, 1625, 1631,
+
+     1631, 1631, 1627, 1634, 1634, 1634, 3022, 1628, 1618, 3023,
+     1629, 3024, 1630, 1641, 1641, 1641, 3025, 1631, 1672, 1672,
+     1672, 1634, 1672, 3026, 3027, 1672, 1696, 1696, 1696, 1625,
+     3028, 1641, 1675, 1675, 1675, 1676, 1676, 1676, 3029, 1676,
+     3032, 3035, 1676, 1696, 1629, 1681, 1681, 1681, 3036, 3037,
+     1675, 1683, 1683, 1683, 1634, 1683, 1628, 3038, 1683, 3032,
+     3039, 1631, 3040, 1681, 3041, 1641, 1687, 1687, 1687, 3042,
+     1687, 1634, 3043, 1687, 1691, 1691, 1691, 1693, 1693, 1693,
+     3044, 1693, 3045, 3046, 1693, 3047, 1697, 1697, 1697, 3048,
+     1697, 3049, 1691, 1697, 3050, 3051, 1681, 3052, 3054, 1675,
+
+     1698, 1698, 1698, 1707, 1707, 1707, 1711, 1711, 1711, 1712,
+     1712, 1712, 1714, 1714, 1714, 1715, 1715, 1715, 1698, 1715,
+     3055, 3056, 1715, 1716, 1716, 1716, 3053, 1716, 3057, 1714,
+     1716, 1719, 1719, 1719, 3058, 1691, 1721, 1721, 1721, 1722,
+     1722, 1722, 3059, 1723, 1723, 1723, 3053, 1723, 3060, 1719,
+     1723, 1698, 3061, 1721, 1726, 1726, 1726, 1722, 1727, 1727,
+     1727, 3062, 1727, 3063, 3064, 1727, 3065, 1707, 3066, 3067,
+     1711, 3068, 1726, 1712, 1730, 1730, 1730, 3069, 1719, 1731,
+     1731, 1731, 3070, 1734, 1734, 1734, 1722, 1734, 3071, 3072,
+     1734, 1730, 1737, 1737, 1737, 3072, 3075, 1731, 1738, 1738,
+
+     1738, 3076, 1738, 3077, 3078, 1738, 1739, 1739, 1739, 1737,
+     1740, 1740, 1740, 3079, 1740, 3080, 3082, 1740, 3083, 3085,
+     1726, 3086, 3088, 1739, 1742, 1742, 1742, 1745, 1745, 1745,
+     3089, 1745, 3092, 3091, 1745, 1748, 1748, 1748, 1750, 1750,
+     1750, 3093, 1742, 1731, 1751, 1751, 1751, 3091, 1751, 3094,
+     3095, 1751, 3097, 1748, 3099, 1750, 1752, 1752, 1752, 1754,
+     1754, 1754, 3101, 1754, 3103, 3105, 1754, 1757, 1757, 1757,
+     1758, 1758, 1758, 1752, 1758, 3106, 3107, 1758, 1759, 1759,
+     1759, 1748, 3108, 3109, 1757, 1764, 1764, 1764, 1765, 1765,
+     1765, 1766, 1766, 1766, 3110, 1759, 1767, 1767, 1767, 3111,
+
+     1767, 3112, 1764, 1767, 3114, 3116, 1765, 3118, 1766, 1768,
+     1768, 1768, 1769, 1769, 1769, 1770, 1770, 1770, 1771, 1771,
+     1771, 1773, 1773, 1773, 3119, 3120, 1768, 3121, 3146, 1769,
+     3180, 3130, 1770, 1774, 1774, 1774, 1771, 1774, 1773, 3150,
+     1774, 1775, 1775, 1775, 1777, 1777, 1777, 3136, 1778, 1778,
+     1778, 3136, 1778, 3137, 1765, 1778, 3122, 3137, 1775, 3180,
+     3138, 1777, 1780, 1780, 1780, 1782, 1782, 1782, 3138, 3146,
+     1769, 1785, 1785, 1785, 1789, 1789, 1789, 3123, 1771, 3130,
+     1780, 1499, 1498, 1782, 3142, 3150, 1790, 1790, 1790, 1785,
+     1790, 1789, 3122, 1790, 1792, 1792, 1792, 1794, 1794, 1794,
+
+     1796, 1796, 1796, 1797, 1797, 1797, 1798, 1798, 1798, 1799,
+     1799, 1799, 1792, 3123, 3139, 1794, 1782, 1796, 3131, 1785,
+     1797, 3132, 3139, 1798, 1802, 1802, 1802, 1799, 1801, 1801,
+     1801, 3142, 1803, 1803, 1803, 1804, 1804, 1804, 1805, 1805,
+     1805, 3154, 1802, 1807, 1807, 1807, 1801, 1807, 1794, 1803,
+     1807, 3133, 1804, 1813, 1813, 1813, 1805, 3134, 1815, 1815,
+     1815, 1816, 1816, 1816, 3140, 1816, 3131, 1495, 1816, 3132,
+     1798, 1813, 3140, 3154, 1801, 1815, 1799, 1817, 1817, 1817,
+     1818, 1818, 1818, 1819, 1819, 1819, 1820, 1820, 1820, 1802,
+     1820, 1490, 1488, 1820, 3141, 1817, 3144, 3145, 1818, 3133,
+
+     1819, 3134, 3141, 1805, 1813, 1821, 1821, 1821, 1827, 1827,
+     1827, 1828, 1828, 1828, 1839, 1839, 1839, 1843, 1843, 1843,
+     1844, 1844, 1844, 1821, 3143, 1827, 1845, 1845, 1845, 1828,
+     1847, 1847, 1847, 3144, 3145, 1818, 1817, 1849, 1849, 1849,
+     1850, 1850, 1850, 1855, 1855, 1855, 1857, 1857, 1857, 1860,
+     1860, 1860, 1862, 1862, 1862, 1864, 1864, 1864, 1865, 1865,
+     1865, 1874, 1874, 1874, 1857, 1874, 3148, 1860, 1874, 1862,
+     3156, 3143, 1828, 1864, 3135, 1865, 1877, 1877, 1877, 3156,
+     1878, 1878, 1878, 1883, 1883, 1883, 1884, 1884, 1884, 1888,
+     1888, 1888, 1485, 3151, 1877, 3188, 1857, 1878, 1889, 1889,
+
+     1889, 3148, 1889, 3188, 3147, 1889, 1888, 1892, 1892, 1892,
+     1893, 1893, 1893, 1476, 1864, 1894, 1894, 1894, 3135, 1895,
+     1895, 1895, 1877, 1895, 3149, 1892, 1895, 1893, 1896, 1896,
+     1896, 3152, 1894, 1897, 1897, 1897, 1898, 1898, 1898, 3151,
+     1899, 1899, 1899, 3157, 1899, 3147, 1896, 1899, 1900, 1900,
+     1900, 1897, 3157, 1898, 1903, 1903, 1903, 3153, 1903, 3149,
+     1892, 1903, 1474, 1906, 1906, 1906, 1900, 1906, 3152, 3160,
+     1906, 1910, 1910, 1910, 1912, 1912, 1912, 3161, 1914, 1914,
+     1914, 1896, 1473, 1916, 1916, 1916, 3158, 1916, 3184, 1910,
+     1916, 1919, 1919, 1919, 3153, 1900, 1914, 1920, 1920, 1920,
+
+     3162, 1920, 3155, 3160, 1920, 1922, 1922, 1922, 1919, 1922,
+     3163, 3161, 1922, 1925, 1925, 1925, 1926, 1926, 1926, 3159,
+     1926, 3158, 3184, 1926, 1927, 1927, 1927, 1931, 1931, 1931,
+     1925, 1932, 1932, 1932, 3155, 1932, 1914, 3164, 1932, 3168,
+     1467, 1927, 3170, 3162, 1931, 1933, 1933, 1933, 1934, 1934,
+     1934, 3170, 1934, 3163, 3159, 1934, 1937, 1937, 1937, 3169,
+     1938, 1938, 1938, 1933, 1938, 3165, 1466, 1938, 1939, 1939,
+     1939, 3171, 3168, 1937, 1940, 1940, 1940, 1941, 1941, 1941,
+     3171, 1941, 3172, 3164, 1941, 1939, 1942, 1942, 1942, 1464,
+     1463, 1940, 3169, 1944, 1944, 1944, 1933, 1944, 3174, 3173,
+
+     1944, 1947, 1947, 1947, 1942, 1948, 1948, 1948, 3166, 1948,
+     1462, 3165, 1948, 1950, 1950, 1950, 3167, 1950, 1947, 3172,
+     1950, 1954, 1954, 1954, 1957, 1957, 1957, 1959, 1959, 1959,
+     1960, 1960, 1960, 1962, 1962, 1962, 3173, 1942, 3178, 1954,
+     3174, 3179, 1957, 3166, 1959, 1964, 1964, 1964, 1960, 1964,
+     1962, 3167, 1964, 1968, 1968, 1968, 1971, 1971, 1971, 1973,
+     1973, 1973, 1974, 1974, 1974, 3189, 1974, 3176, 3182, 1974,
+     3175, 1968, 3177, 3189, 1971, 3178, 1973, 3182, 3179, 1962,
+     1975, 1975, 1975, 1976, 1976, 1976, 3181, 1976, 1957, 1461,
+     1976, 1960, 1978, 1978, 1978, 1460, 3185, 1975, 1980, 1980,
+
+     1980, 1981, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1983,
+     1978, 1983, 3175, 3176, 1983, 3181, 1980, 3196, 3177, 1981,
+     1459, 1982, 1984, 1984, 1984, 1985, 1985, 1985, 3194, 1985,
+     3185, 3183, 1985, 1986, 1986, 1986, 1991, 1991, 1991, 1984,
+     3183, 1993, 1993, 1993, 1458, 1993, 3190, 1980, 1993, 3192,
+     3186, 1986, 3196, 3187, 1991, 1996, 1996, 1996, 1978, 1997,
+     1997, 1997, 3197, 1998, 1998, 1998, 1981, 1998, 3202, 3194,
+     1998, 1457, 1456, 1996, 2001, 2001, 2001, 1997, 2007, 2007,
+     2007, 2008, 2008, 2008, 1454, 2008, 3192, 1453, 2008, 2009,
+     2009, 2009, 2001, 3190, 1451, 2007, 3186, 3197, 1986, 3187,
+
+     3202, 1991, 2010, 2010, 2010, 3191, 1996, 2009, 2015, 2015,
+     2015, 1450, 1997, 2016, 2016, 2016, 2017, 2017, 2017, 2019,
+     2019, 2019, 2023, 2023, 2023, 2024, 2024, 2024, 2025, 2025,
+     2025, 2026, 2026, 2026, 2028, 2028, 2028, 2029, 2029, 2029,
+     2030, 2030, 2030, 2031, 2031, 2031, 2032, 2032, 2032, 2033,
+     2033, 2033, 3191, 2009, 2035, 2035, 2035, 2038, 2038, 2038,
+     3204, 2041, 2041, 2041, 2042, 2042, 2042, 3193, 2042, 3204,
+     1448, 2042, 2035, 1446, 3212, 2038, 1445, 2026, 2041, 2044,
+     2044, 2044, 2045, 2045, 2045, 2046, 2046, 2046, 3212, 2046,
+     1444, 3195, 2046, 2057, 2057, 2057, 3200, 2044, 3203, 2045,
+
+     2058, 2058, 2058, 3198, 3193, 2035, 2059, 2059, 2059, 3201,
+     2059, 2057, 1443, 2059, 2060, 2060, 2060, 2058, 2065, 2065,
+     2065, 2066, 2066, 2066, 2067, 2067, 2067, 2068, 2068, 2068,
+     3203, 2068, 3195, 3200, 2068, 2069, 2069, 2069, 2070, 2070,
+     2070, 2067, 2057, 2071, 2071, 2071, 3201, 2071, 3199, 3198,
+     2071, 3208, 3205, 2069, 3209, 2070, 2072, 2072, 2072, 1442,
+     2072, 3205, 1441, 2072, 2075, 2075, 2075, 2066, 3206, 2076,
+     2076, 2076, 2078, 2078, 2078, 1440, 2078, 3207, 1438, 2078,
+     1437, 1436, 2075, 2081, 2081, 2081, 2069, 2076, 2088, 2088,
+     2088, 2090, 2090, 2090, 3199, 2090, 1435, 1426, 2090, 3208,
+
+     3206, 2081, 3209, 2094, 2094, 2094, 2088, 2094, 3210, 3207,
+     2094, 2097, 2097, 2097, 1411, 2075, 2098, 2098, 2098, 3213,
+     2098, 3211, 1410, 2098, 1405, 2102, 2102, 2102, 2097, 2102,
+     3213, 1404, 2102, 2105, 2105, 2105, 2081, 2106, 2106, 2106,
+     3210, 2106, 1403, 2088, 2106, 2109, 2109, 2109, 2110, 2110,
+     2110, 2105, 2110, 3211, 1401, 2110, 2111, 2111, 2111, 1394,
+     2111, 1393, 2109, 2111, 2114, 2114, 2114, 2116, 2116, 2116,
+     1375, 2116, 1370, 1367, 2116, 2122, 2122, 2122, 2124, 2124,
+     2124, 1366, 2114, 2125, 2125, 2125, 1363, 2125, 1358, 1349,
+     2125, 1348, 1347, 2122, 1343, 2124, 1338, 2105, 2126, 2126,
+
+     2126, 2128, 2128, 2128, 2129, 2129, 2129, 1334, 2129, 1326,
+     1321, 2129, 1320, 2136, 2136, 2136, 2126, 1314, 2128, 2139,
+     2139, 2139, 1313, 2139, 1312, 1311, 2139, 2146, 2146, 2146,
+     2114, 2136, 2142, 2142, 2142, 1306, 2142, 1305, 1304, 2142,
+     1303, 2148, 2148, 2148, 1290, 2146, 2149, 2149, 2149, 2150,
+     2150, 2150, 1289, 2150, 1288, 1287, 2150, 1286, 2126, 2148,
+     1285, 2153, 2153, 2153, 2149, 2153, 1284, 1274, 2153, 2156,
+     2156, 2156, 1273, 2157, 2157, 2157, 1272, 1271, 2146, 2158,
+     2158, 2158, 2149, 2159, 2159, 2159, 1259, 2156, 1258, 2156,
+     2157, 2160, 2160, 2160, 1253, 1252, 2158, 2161, 2161, 2161,
+
+     2159, 2163, 2163, 2163, 2164, 2164, 2164, 2148, 2160, 2165,
+     2165, 2165, 2168, 2168, 2168, 2161, 2169, 2169, 2169, 2163,
+     2169, 1247, 2164, 2169, 2172, 2172, 2172, 2165, 1246, 1227,
+     2158, 2173, 2173, 2173, 2174, 2174, 2174, 2175, 2175, 2175,
+     1223, 1217, 2172, 2178, 2178, 2178, 1213, 2159, 1212, 1211,
+     2160, 2179, 2179, 2179, 2181, 2181, 2181, 2182, 2182, 2182,
+     1210, 2163, 2161, 2183, 2183, 2183, 2184, 2184, 2184, 2185,
+     2185, 2185, 2186, 2186, 2186, 2189, 2189, 2189, 2190, 2190,
+     2190, 1209, 1208, 2172, 2191, 2191, 2191, 2192, 2192, 2192,
+     2194, 2194, 2194, 2197, 2197, 2197, 2198, 2198, 2198, 1207,
+
+     2198, 1205, 1204, 2198, 2201, 2201, 2201, 1203, 2194, 1202,
+     2197, 2202, 2202, 2202, 1201, 2204, 2204, 2204, 1196, 2204,
+     1188, 2201, 2204, 2217, 2217, 2217, 2218, 2218, 2218, 2202,
+     2218, 2219, 2219, 2218, 2219, 1186, 2220, 2220, 1181, 2220,
+     1179, 2217, 2219, 1170, 1165, 2219, 1154, 2220, 1152, 2219,
+     2220, 2221, 2221, 2221, 2220, 2222, 2222, 2222, 2226, 2226,
+     2226, 2228, 2228, 2228, 1151, 2228, 1150, 1149, 2228, 1147,
+     2201, 2231, 2231, 2231, 2232, 2232, 2232, 1146, 2232, 1145,
+     1144, 2232, 1143, 1142, 2217, 2235, 2235, 2235, 1140, 2231,
+     2236, 2236, 2236, 2244, 2244, 2244, 2245, 2245, 2245, 1139,
+
+     2248, 2248, 2248, 2235, 2248, 1138, 1137, 2248, 2236, 2251,
+     2251, 2251, 1136, 1135, 2245, 1134, 1133, 2231, 2254, 2254,
+     2254, 2255, 2255, 2255, 1132, 2255, 2251, 1131, 2255, 2258,
+     2258, 2258, 2263, 2263, 2263, 1130, 2254, 2265, 2265, 2265,
+     1129, 2236, 2266, 2266, 2266, 1128, 2266, 2258, 1127, 2266,
+     2263, 2269, 2269, 2269, 2265, 1121, 2245, 2270, 2270, 2270,
+     2271, 2271, 2271, 1120, 2271, 1119, 1116, 2271, 1115, 2269,
+     2274, 2274, 2274, 1114, 2270, 2275, 2275, 2275, 2280, 2280,
+     2280, 2282, 2282, 2282, 2285, 2285, 2285, 2274, 2284, 2284,
+     2284, 1112, 2275, 1108, 1105, 2280, 2286, 2286, 2286, 1096,
+
+     1095, 2285, 2269, 2270, 1092, 1091, 2284, 1090, 2287, 2287,
+     2287, 2289, 2289, 2289, 2286, 2288, 2288, 2288, 1089, 1088,
+     2290, 2290, 2290, 1074, 2290, 2274, 2287, 2290, 2289, 2280,
+     2291, 2291, 2291, 2288, 1067, 1059, 2275, 2292, 2292, 2292,
+     2293, 2293, 2293, 2294, 2294, 2294, 1058, 2291, 2295, 2295,
+     2295, 1057, 2288, 1054, 2292, 1051, 2286, 2293, 2296, 2296,
+     2296, 2294, 2297, 2297, 2297, 2299, 2299, 2299, 1048, 2287,
+     2302, 2302, 2302, 2304, 2304, 2304, 2296, 2303, 2303, 2303,
+     2297, 1043, 1040, 2299, 2305, 2305, 2305, 1039, 2292, 1035,
+     1033, 2293, 2308, 2308, 2308, 2303, 2309, 2309, 2309, 2310,
+
+     2310, 2310, 2311, 2311, 2311, 2315, 2315, 2315, 2318, 2318,
+     2318, 2319, 2319, 2319, 1019, 2319, 1018, 1017, 2319, 2331,
+     2331, 2331, 1016, 2315, 2296, 2318, 1015, 2299, 2344, 2344,
+     2344, 2347, 2347, 2347, 2349, 2349, 2349, 2331, 2350, 2350,
+     2350, 2352, 2352, 2352, 2359, 2359, 2359, 2360, 2360, 2360,
+     1014, 1013, 2349, 2361, 2361, 2361, 2350, 1009, 1005, 2352,
+      998, 2359,  997, 2364, 2364, 2364, 2365, 2365, 2365,  996,
+     2365, 2361,  993, 2365, 2367, 2367, 2367,  992,  989, 2331,
+     2364, 2368, 2368, 2368, 2370, 2370, 2370, 2374, 2374, 2374,
+      988, 2367, 2376, 2376, 2376,  987, 2378, 2378, 2378, 2368,
+
+     2349,  984, 2370,  983, 2374, 2379, 2379, 2379,  980, 2376,
+     2361, 2377, 2377, 2377, 2378, 2377,  975,  972, 2377, 2380,
+     2380, 2380, 2379, 2380,  969,  968, 2380, 2381, 2381, 2381,
+     2382, 2382, 2382, 2383, 2383, 2383, 2388, 2388, 2388, 2390,
+     2390, 2390,  965,  964, 2381,  963,  962, 2382,  961,  959,
+     2383,  958,  957, 2388, 2392, 2392, 2392, 2394, 2394, 2394,
+     2395, 2395, 2395,  956, 2395,  955,  954, 2395, 2396, 2396,
+     2396,  953, 2392,  949, 2394, 2397, 2397, 2397,  944, 2381,
+     2398, 2398, 2398, 2399, 2399, 2399, 2396, 2399, 2382,  943,
+     2399, 2383,  942, 2397, 2402, 2402, 2402,  939, 2398, 2403,
+
+     2403, 2403,  938, 2403,  937,  935, 2403, 2404, 2404, 2404,
+      931, 2402, 2405, 2405, 2405, 2406, 2406, 2406, 2408, 2408,
+     2408, 2409, 2409, 2409, 2404, 2413, 2413, 2413,  927, 2405,
+     2417, 2417, 2417, 2406, 2421, 2421, 2421,  926,  923, 2409,
+      920,  919, 2397, 2413, 2398, 2422, 2422, 2422,  918, 2422,
+      917, 2421, 2422, 2436, 2436, 2436, 2453, 2453, 2453, 2455,
+     2455, 2455, 2456, 2456, 2456, 2459, 2459, 2459, 2462, 2462,
+     2462, 2436, 2463, 2463, 2463,  916, 2463, 2455,  915, 2463,
+     2456,  914, 2459,  912,  911, 2462, 2464, 2464, 2464, 2467,
+     2467, 2467,  910, 2467,  909,  908, 2467, 2471, 2471, 2471,
+
+      907, 2472, 2472, 2472, 2464, 2472,  906,  905, 2472, 2474,
+     2474, 2474,  904, 2436, 2471, 2475, 2475, 2475, 2476, 2476,
+     2476,  903, 2476,  902,  901, 2476, 2474, 2477, 2477, 2477,
+     2455,  900, 2475, 2478, 2478, 2478,  899, 2478,  898,  897,
+     2478, 2481, 2481, 2481, 2477, 2483, 2483, 2483,  896, 2483,
+      895,  894, 2483, 2486, 2486, 2486, 2487, 2487, 2487, 2481,
+     2488, 2488, 2488, 2491, 2491, 2491,  893, 2492, 2492, 2492,
+     2486, 2492,  889, 2487, 2492,  888,  886, 2488,  885,  884,
+     2491, 2493, 2493, 2493, 2494, 2494, 2494, 2495, 2495, 2495,
+      883, 2495,  882,  878, 2495, 2498, 2498, 2498, 2493,  876,
+
+      875, 2494, 2500, 2500, 2500,  874,  873, 2487, 2486, 2501,
+     2501, 2501,  869, 2498,  865, 2488,  864, 2502, 2502, 2502,
+     2500, 2502,  861,  860, 2502,  859,  858, 2501, 2505, 2505,
+     2505, 2506, 2506, 2506,  857, 2506,  856,  855, 2506, 2507,
+     2507, 2507, 2508, 2508, 2508, 2505, 2508,  852,  851, 2508,
+      850, 2509, 2509, 2509,  849,  846, 2507, 2515, 2515, 2515,
+     2519, 2519, 2519, 2538, 2538, 2538,  845,  844, 2500, 2509,
+     2501, 2520, 2520, 2520,  841, 2520,  839, 2519, 2520,  836,
+      835, 2538, 2554, 2554, 2554, 2556, 2556, 2556, 2557, 2557,
+     2557, 2558, 2558, 2558, 2559, 2559, 2559,  834, 2559,  833,
+
+      832, 2559,  829, 2556,  828, 2557,  827,  826, 2558, 2560,
+     2560, 2560,  825, 2560, 2538,  822, 2560, 2563, 2563, 2563,
+     2568, 2568, 2568,  821, 2568,  820,  819, 2568, 2572, 2572,
+     2572, 2607, 2607, 2607, 2557, 2563, 2573, 2573, 2573,  817,
+     2573,  814,  813, 2573,  811, 2572,  808, 2556, 2574, 2574,
+     2574,  806, 2574,  803,  802, 2574, 2577, 2577, 2577, 2578,
+     2578, 2578,  801, 2578,  800,  798, 2578, 2579, 2579, 2579,
+     2580, 2580, 2580, 2577, 2581, 2581, 2581,  797, 2582, 2582,
+     2582,  796, 2582,  793, 2579, 2582,  792, 2580, 2585, 2585,
+     2585, 2581, 2586, 2586, 2586,  791, 2586,  790,  789, 2586,
+
+     2587, 2587, 2587,  788,  783, 2585, 2588, 2588, 2588,  782,
+     2588,  781,  780, 2588, 2595, 2595, 2595, 2587, 2596, 2596,
+     2596,  779,  778, 2581,  777, 2579, 2597, 2597, 2597,  776,
+     2597,  775, 2595, 2597,  773,  771, 2596, 2600, 2600, 2600,
+      770, 2600,  767,  764, 2600, 2605, 2605, 2605, 2608, 2608,
+     2608, 2611, 2611, 2611,  760, 2611,  759,  758, 2611, 2622,
+     2622, 2622, 2605, 2605,  755, 2595, 2631, 2631, 2631, 2647,
+     2647, 2647, 2648, 2648, 2648,  752, 2622, 2649, 2649, 2649,
+     2650, 2650, 2650,  751, 2631, 2596, 2651, 2651, 2651,  750,
+     2651,  747,  746, 2651,  742, 2649,  741, 2650, 2653, 2653,
+
+     2653,  739, 2653,  736,  735, 2653, 2660, 2660, 2660,  734,
+     2660,  732,  721, 2660,  719, 2631, 2663, 2663, 2663,  716,
+     2663,  715,  713, 2663, 2666, 2666, 2666,  712, 2649, 2667,
+     2667, 2667, 2668, 2668, 2668,  711, 2668,  707,  706, 2668,
+      705, 2666, 2669, 2669, 2669,  704, 2667, 2670, 2670, 2670,
+      701, 2670,  700,  699, 2670,  698, 2673, 2673, 2673, 2669,
+     2673,  697,  696, 2673, 2682, 2682, 2682, 2683, 2683, 2683,
+     2689, 2689, 2689,  695,  693, 2666, 2690, 2690, 2690, 2691,
+     2691, 2691, 2682, 2691,  690, 2683, 2691, 2689, 2689, 2692,
+     2692, 2692,  689, 2690, 2690,  687,  685, 2691, 2693, 2693,
+
+     2693, 2694, 2694, 2694, 2695, 2695, 2695, 2704, 2704, 2704,
+     2705, 2705, 2705, 2669, 2705,  682,  681, 2705, 2714, 2714,
+     2714, 2729, 2729, 2729, 2704, 2730, 2730, 2730, 2731, 2731,
+     2731,  675,  673, 2683,  671,  668, 2714, 2732, 2732, 2732,
+      667, 2732,  663,  662, 2732,  661, 2731, 2738, 2738, 2738,
+     2740, 2740, 2740, 2741, 2741, 2741,  658, 2741,  657,  656,
+     2741, 2744, 2744, 2744, 2738,  655,  652, 2740, 2759, 2759,
+     2759, 2761, 2761, 2761, 2767, 2767, 2767,  651, 2744,  650,
+      649, 2768, 2768, 2768, 2714, 2768, 2759,  648, 2768, 2761,
+      642, 2767, 2767, 2769, 2769, 2769,  641, 2769,  639, 2768,
+
+     2769, 2772, 2772, 2772, 2773, 2773, 2773, 2774, 2774, 2774,
+      633, 2769, 2783, 2783, 2783,  632, 2783,  628,  621, 2783,
+      617,  611, 2761, 2770, 2770, 2770, 2770, 2770, 2770, 2770,
+     2770, 2770,  607,  603, 2770, 2792, 2792, 2792,  599, 2770,
+     2770, 2770, 2770, 2770, 2803, 2803, 2803, 2804, 2804, 2804,
+     2809, 2809, 2809, 2792, 2810, 2810, 2810,  598, 2810,  597,
+      596, 2810, 2812, 2812, 2812, 2804,  595, 2809, 2770, 2770,
+     2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2812,
+      591, 2771, 2814, 2814, 2814,  587, 2771, 2771, 2771, 2771,
+     2771, 2813, 2813, 2813,  584, 2813,  583,  582, 2813, 2814,
+
+     2815, 2815, 2815,  578, 2815,  574,  571, 2815, 2828, 2828,
+     2828, 2853, 2853, 2853,  570, 2771, 2771, 2834, 2834, 2834,
+      566, 2834,  560,  559, 2834,  555, 2828,  551,  547, 2853,
+     2888, 2888, 2888,  546,  542, 2834, 2837, 2837, 2837, 2837,
+     2837, 2837, 2837, 2837, 2837,  539,  538, 2837, 2888,  533,
+      529,  521, 2837, 2837, 2837, 2837, 2837, 2866, 2866, 2866,
+      520, 2866,  519,  515, 2866, 2870, 2870, 2870,  509, 2870,
+      508,  507, 2870, 2873, 2873, 2873,  503, 2873,  497,  496,
+     2873, 2837, 2837, 2838, 2838, 2838, 2838, 2838, 2838, 2838,
+     2838, 2838,  492,  486, 2838, 2900, 2900, 2900,  485, 2838,
+
+     2838, 2838, 2838, 2838, 2917, 2917, 2917, 2918, 2918, 2918,
+     2919, 2919, 2919, 2900, 2900, 2924, 2924, 2924, 2935, 2935,
+     2935, 2917,  484,  483, 2918,  482,  481, 2919, 2838, 2838,
+      480,  476, 2924, 2939, 2939, 2939, 2935, 2950, 2950, 2950,
+     2951, 2951, 2951,  470, 2951,  469,  467, 2951, 2952, 2952,
+     2952, 2939,  466,  465, 2950, 2953, 2953, 2953,  461, 2953,
+      452,  451, 2953,  450,  448, 2952, 2954, 2954, 2954, 2955,
+     2955, 2955,  444, 2955,  438,  437, 2955, 2962, 2962, 2962,
+     2972, 2972, 2972, 2954, 2939, 2963, 2963, 2963,  436, 2963,
+      432,  428, 2963,  424, 2962, 2982, 2982, 2982, 2972, 2982,
+
+      423,  422, 2982, 2985, 2985, 2985,  421, 2985,  420,  416,
+     2985, 2988, 2988, 2988,  410, 2988,  409, 2972, 2988, 2997,
+     2997, 2997,  405, 2997,  399,  398, 2997, 3104, 3104, 3104,
+     3113, 3113, 3113,  394, 3113,  387,  386, 3113, 3214, 3214,
+     3214, 3215, 3215, 3215,  385, 3104,  381,  374, 3113,  373,
+      372,  371,  367,  363,  358,  352, 3214,  348,  347, 3215,
+     3218, 3218, 3218, 3218, 3218, 3218, 3218, 3218, 3218, 3219,
+     3219, 3219, 3219, 3219, 3219, 3219, 3219, 3219, 3220, 3220,
+     3220, 3220, 3220, 3220, 3220, 3220, 3220, 3221, 3221, 3221,
+     3221, 3221, 3221, 3221, 3221, 3221, 3222, 3222, 3222, 3222,
+
+     3222, 3222, 3222, 3222, 3222, 3223, 3223, 3223, 3223, 3223,
+     3223, 3223, 3223, 3223, 3224, 3224, 3224, 3224, 3224, 3224,
+     3224, 3224, 3224, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
+     3225, 3225, 3226, 3226, 3226, 3226, 3226, 3226, 3226, 3226,
+     3226, 3227, 3227, 3227, 3227, 3227, 3227, 3227, 3227, 3227,
+     3228, 3228, 3228, 3228, 3228, 3228, 3228, 3228, 3228, 3229,
+     3229, 3229, 3229, 3229, 3229, 3229, 3229, 3229, 3230, 3230,
+     3230, 3230, 3230, 3230, 3230, 3230, 3230, 3231, 3231, 3231,
+     3231, 3231, 3231, 3231, 3231, 3231, 3232, 3232, 3232, 3232,
+     3232, 3232, 3232, 3232, 3232, 3233, 3233, 3233, 3233, 3233,
+
+     3233, 3233, 3233, 3233, 3234, 3234, 3234, 3234, 3234, 3234,
+     3234, 3234, 3234, 3235, 3235, 3235, 3235, 3235, 3235, 3235,
+     3235, 3235, 3236, 3236, 3236, 3236, 3236, 3236, 3236, 3236,
+     3236, 3237, 3237, 3237, 3237, 3237, 3237, 3237, 3237, 3237,
+     3238, 3238, 3238, 3238, 3238, 3238, 3238, 3238, 3238, 3239,
+     3239, 3239, 3239, 3239, 3239, 3239, 3239, 3239, 3240, 3240,
+     3240, 3240, 3240, 3240, 3240, 3240, 3240, 3241, 3241, 3241,
+     3241, 3241, 3241, 3241, 3241, 3241, 3242, 3242, 3242, 3242,
+     3242, 3242, 3242, 3242, 3242, 3243, 3243, 3243, 3243, 3243,
+     3243, 3243, 3243, 3243, 3244, 3244, 3244, 3244, 3244, 3244,
+
+     3244, 3244, 3244, 3245, 3245, 3245, 3245, 3245, 3245, 3245,
+     3245, 3245, 3246, 3246, 3246, 3246, 3246, 3246, 3246, 3246,
+     3246, 3247, 3247, 3247, 3247, 3247, 3247, 3247, 3247, 3247,
+     3248, 3248, 3248, 3248, 3248, 3248, 3248, 3248, 3248, 3249,
+     3249, 3249, 3249, 3249, 3249, 3249, 3249, 3249, 3250, 3250,
+     3250, 3250, 3250, 3250, 3250, 3250, 3250, 3251, 3251, 3251,
+     3251, 3251, 3251, 3251, 3251, 3251, 3252, 3252, 3252, 3252,
+     3252, 3252, 3252, 3252, 3252, 3253, 3253, 3253, 3253, 3253,
+     3253, 3253, 3253, 3253, 3254, 3254, 3254, 3254, 3254, 3254,
+     3254, 3254, 3254, 3255, 3255, 3255, 3255, 3255, 3255, 3255,
+
+     3255, 3255, 3256, 3256, 3256, 3256, 3256, 3256, 3256, 3256,
+     3256, 3257, 3257, 3257, 3257, 3257, 3257, 3257, 3257, 3257,
+     3258, 3258, 3258, 3258, 3258, 3258, 3258, 3258, 3258, 3259,
+     3259, 3259, 3259, 3259, 3259, 3259, 3259, 3259, 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,  343,  337,  336, 3277, 3278, 3278,
+
+     3278,  335,  331,  324, 3278, 3279, 3279, 3279,  322,  321,
+      317, 3279, 3280, 3280, 3280,  314,  312,  311, 3280, 3281,
+     3281, 3281,  310,  306,  302, 3281, 3282, 3282, 3282,  299,
+      295,  292, 3282, 3283, 3283, 3283,  291,  283,  279, 3283,
+     3284, 3284, 3284,  275,  274,  273, 3284, 3285, 3285, 3285,
+      267,  266,  264, 3285, 3286, 3286, 3286,  261,  249,    0,
+     3286, 3287, 3287, 3287,    0,    0,    0, 3287, 3288, 3288,
      3288,    0,    0,    0, 3288, 3289, 3289, 3289,    0,    0,
         0, 3289, 3290, 3290, 3290,    0,    0,    0, 3290, 3291,
      3291, 3291,    0,    0,    0, 3291, 3292, 3292, 3292,    0,
-        0,    0, 3292, 3293, 3293, 3293,    0,    0,    0, 3293,
 
+        0,    0, 3292, 3293, 3293, 3293,    0,    0,    0, 3293,
      3294, 3294, 3294,    0,    0,    0, 3294, 3295, 3295, 3295,
         0,    0,    0, 3295, 3296, 3296, 3296,    0,    0,    0,
      3296, 3297, 3297, 3297,    0,    0,    0, 3297, 3298, 3298,
      3298,    0,    0,    0, 3298, 3299, 3299, 3299,    0,    0,
         0, 3299, 3300, 3300, 3300,    0,    0,    0, 3300, 3301,
      3301, 3301,    0,    0,    0, 3301, 3302, 3302, 3302,    0,
-        0,    0, 3302, 3303, 3303, 3303, 3303, 3303, 3303, 3303,
-        0, 3303, 3304, 3304, 3304,    0,    0,    0, 3304, 3305,
-        0,    0,    0, 3305, 3306, 3306, 3306,    0,    0,    0,
-     3306, 3307,    0,    0,    0, 3307, 3308, 3308, 3308,    0,
-
-        0,    0, 3308, 3309,    0,    0,    0, 3309, 3310, 3310,
-     3310,    0,    0,    0, 3310, 3311,    0,    0,    0, 3311,
-     3312, 3312, 3312,    0,    0,    0, 3312, 3313,    0,    0,
-        0, 3313, 3314, 3314, 3314,    0,    0,    0, 3314, 3315,
-        0,    0,    0, 3315, 3316, 3316, 3316,    0,    0,    0,
-     3316, 3317,    0,    0,    0, 3317, 3318, 3318, 3318,    0,
-        0,    0, 3318, 3319,    0,    0,    0, 3319, 3320, 3320,
-     3320,    0,    0,    0, 3320, 3321,    0,    0,    0, 3321,
-     3322, 3322, 3322,    0,    0,    0, 3322, 3323,    0,    0,
-        0, 3323, 3324, 3324, 3324,    0,    0,    0, 3324, 3325,
-
-        0,    0,    0, 3325, 3326, 3326, 3326,    0,    0,    0,
-     3326, 3327,    0,    0,    0, 3327, 3328, 3328, 3328,    0,
-        0,    0, 3328, 3329,    0,    0,    0, 3329, 3330, 3330,
-     3330,    0,    0,    0, 3330, 3331,    0,    0,    0, 3331,
-     3332, 3332, 3332,    0,    0,    0, 3332, 3333,    0,    0,
-        0, 3333, 3334, 3334, 3334,    0,    0,    0, 3334, 3335,
-        0,    0,    0, 3335, 3336, 3336, 3336,    0,    0,    0,
-     3336, 3337,    0,    0,    0, 3337, 3338, 3338, 3338,    0,
-        0,    0, 3338, 3339,    0,    0,    0, 3339, 3340, 3340,
-     3340,    0,    0,    0, 3340, 3341,    0,    0,    0, 3341,
-
-     3342, 3342, 3342,    0,    0,    0, 3342, 3343,    0,    0,
-        0, 3343, 3344, 3344, 3344,    0,    0,    0, 3344, 3345,
-        0,    0,    0, 3345, 3346, 3346, 3346,    0,    0,    0,
-     3346, 3347,    0,    0,    0, 3347, 3348, 3348, 3348,    0,
-        0,    0, 3348, 3349,    0,    0,    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, 3358,
-
-     3358, 3358, 3358, 3358, 3358, 3359,    0,    0,    0,    0,
-     3359, 3360, 3360, 3360,    0,    0,    0, 3360, 3361, 3361,
-     3361, 3361,    0,    0, 3361, 3361, 3362, 3362, 3362,    0,
-        0,    0, 3362, 3363, 3363, 3363, 3363,    0,    0, 3363,
-     3363, 3364, 3364, 3364,    0,    0,    0, 3364, 3365, 3365,
-     3365, 3365,    0,    0, 3365, 3365, 3366, 3366, 3366,    0,
-        0,    0, 3366, 3367, 3367, 3367, 3367,    0,    0, 3367,
-     3367, 3368, 3368, 3368,    0,    0,    0, 3368, 3369, 3369,
-     3369, 3369,    0,    0, 3369, 3369, 3370, 3370, 3370,    0,
-        0,    0, 3370, 3371, 3371, 3371, 3371,    0,    0, 3371,
-
-     3371, 3372, 3372, 3372,    0,    0,    0, 3372, 3373, 3373,
-     3373, 3373,    0,    0, 3373, 3373, 3374, 3374, 3374,    0,
-        0,    0, 3374, 3375, 3375, 3375, 3375,    0,    0, 3375,
-     3375, 3376, 3376, 3376,    0,    0,    0, 3376, 3377, 3377,
-     3377, 3377,    0,    0, 3377, 3377, 3378, 3378, 3378,    0,
-        0,    0, 3378, 3379, 3379, 3379, 3379,    0,    0, 3379,
-     3379, 3380, 3380, 3380,    0,    0,    0, 3380, 3381, 3381,
-     3381, 3381,    0,    0, 3381, 3381, 3382, 3382, 3382,    0,
-        0,    0, 3382, 3383, 3383, 3383, 3383,    0,    0, 3383,
-     3383, 3384, 3384, 3384,    0,    0,    0, 3384, 3385, 3385,
-
-     3385, 3385,    0,    0, 3385, 3385, 3386, 3386, 3386, 3386,
-        0, 3386,    0, 3386, 3387, 3387, 3387, 3387,    0,    0,
-     3387, 3387, 3388, 3388, 3388,    0,    0,    0, 3388, 3389,
-     3389, 3389, 3389,    0,    0, 3389, 3389, 3390, 3390, 3390,
-        0,    0,    0, 3390, 3391, 3391, 3391, 3391,    0,    0,
-     3391, 3391, 3392, 3392, 3392,    0,    0,    0, 3392, 3393,
-     3393, 3393, 3393,    0,    0, 3393, 3393, 3394, 3394, 3394,
-        0,    0,    0, 3394, 3395, 3395, 3395, 3395,    0,    0,
-     3395, 3395, 3396, 3396, 3396, 3396,    0, 3396,    0, 3396,
-     3397, 3397, 3397, 3397,    0,    0, 3397, 3397, 3398, 3398,
-
-     3398, 3398,    0, 3398,    0, 3398, 3399, 3399, 3399, 3399,
-        0,    0, 3399, 3399, 3400, 3400, 3400,    0,    0,    0,
-     3400, 3401, 3401, 3401, 3401,    0,    0, 3401, 3401, 3402,
-     3402, 3402, 3402,    0, 3402,    0, 3402, 3403, 3403, 3403,
-     3403,    0,    0, 3403, 3403, 3404, 3404, 3404, 3404,    0,
-     3404,    0, 3404, 3405, 3405, 3405, 3405,    0,    0, 3405,
-     3405, 3406, 3406, 3406,    0,    0,    0, 3406, 3407, 3407,
-     3407, 3407,    0,    0, 3407, 3407, 3408, 3408, 3408,    0,
-        0,    0, 3408, 3409, 3409, 3409, 3409,    0,    0, 3409,
-     3409, 3410, 3410, 3410, 3410,    0,    0, 3410, 3410, 3411,
-
-     3411, 3411,    0,    0,    0, 3411, 3412, 3412, 3412, 3412,
-        0,    0, 3412, 3412, 3413, 3413, 3413, 3413, 3413, 3413,
-     3413, 3413, 3413, 3414,    0, 3414,    0,    0, 3414, 3415,
-     3415, 3415,    0,    0,    0, 3415, 3416, 3416, 3416, 3416,
-        0,    0, 3416, 3416, 3417, 3417, 3417, 3417,    0, 3417,
-        0, 3417, 3418, 3418, 3418, 3418,    0,    0, 3418, 3418,
-     3419, 3419, 3419, 3419,    0, 3419,    0, 3419, 3420, 3420,
-     3420, 3420,    0,    0, 3420, 3420, 3421, 3421, 3421,    0,
-        0,    0, 3421, 3422, 3422, 3422, 3422,    0,    0, 3422,
-     3422, 3423, 3423, 3423,    0,    0,    0, 3423, 3424, 3424,
-
-     3424, 3424,    0,    0, 3424, 3424, 3425, 3425, 3425,    0,
-        0,    0, 3425, 3426, 3426, 3426, 3426,    0,    0, 3426,
-     3426, 3427, 3427, 3427,    0,    0,    0, 3427, 3428, 3428,
-     3428, 3428,    0,    0, 3428, 3428, 3429, 3429, 3429,    0,
-        0,    0, 3429, 3430, 3430, 3430, 3430,    0,    0, 3430,
-     3430, 3431, 3431, 3431, 3431,    0, 3431,    0, 3431, 3432,
-     3432, 3432, 3432,    0,    0, 3432, 3432, 3433, 3433, 3433,
-     3433,    0, 3433,    0, 3433, 3434, 3434, 3434, 3434,    0,
-        0, 3434, 3434, 3435, 3435, 3435,    0,    0,    0, 3435,
-     3436, 3436, 3436, 3436,    0,    0, 3436, 3436, 3437, 3437,
-
-     3437, 3437,    0, 3437,    0, 3437, 3438, 3438, 3438, 3438,
-        0,    0, 3438, 3438, 3439, 3439, 3439,    0,    0,    0,
-     3439, 3440, 3440, 3440, 3440,    0,    0, 3440, 3440, 3441,
-     3441, 3441,    0,    0,    0, 3441, 3442, 3442, 3442, 3442,
-        0,    0, 3442, 3442, 3443, 3443, 3443,    0,    0,    0,
-     3443, 3444, 3444, 3444, 3444,    0,    0, 3444, 3444, 3445,
-     3445, 3445,    0,    0,    0, 3445, 3446, 3446, 3446, 3446,
-        0,    0, 3446, 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, 3457,    0,    0, 3457, 3457, 3458, 3458, 3458,
-        0,    0,    0, 3458, 3459, 3459, 3459, 3459,    0,    0,
-     3459, 3459, 3460, 3460, 3460,    0,    0,    0, 3460, 3461,
-     3461, 3461, 3461,    0,    0, 3461, 3461, 3462, 3462, 3462,
-        0,    0,    0, 3462, 3463, 3463, 3463, 3463,    0,    0,
-
-     3463, 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, 3467, 3467,
-     3467, 3467, 3467, 3467, 3468, 3468, 3468, 3468, 3468, 3468,
-     3468, 3468, 3468, 3469, 3469, 3469,    0,    0,    0, 3469,
-     3470, 3470, 3470, 3470,    0,    0, 3470, 3470, 3471, 3471,
-     3471, 3471,    0,    0, 3471, 3471, 3472, 3472, 3472,    0,
-        0,    0, 3472, 3473, 3473, 3473, 3473,    0,    0, 3473,
-     3473, 3474, 3474, 3474,    0,    0,    0, 3474, 3475, 3475,
-     3475, 3475,    0,    0, 3475, 3475, 3476, 3476, 3476,    0,
-
-        0,    0, 3476, 3477, 3477, 3477, 3477,    0,    0, 3477,
-     3477, 3478, 3478, 3478,    0,    0,    0, 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, 3483,    0,    0, 3483, 3483, 3484, 3484, 3484,    0,
-        0,    0, 3484, 3485, 3485, 3485, 3485,    0,    0, 3485,
-     3485, 3486, 3486, 3486,    0,    0,    0, 3486, 3487, 3487,
-     3487, 3487,    0,    0, 3487, 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,    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, 3507,    0,    0, 3507, 3507, 3508, 3508,
-     3508,    0,    0,    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, 3512,    0, 3512,    0, 3512, 3513, 3513, 3513, 3513,
-        0,    0, 3513, 3513, 3514, 3514, 3514, 3514,    0,    0,
-     3514, 3514, 3515, 3515, 3515, 3515,    0, 3515,    0, 3515,
-
-     3516, 3516, 3516, 3516,    0,    0, 3516, 3516, 3517, 3517,
-     3517, 3517, 3517, 3517, 3517, 3517, 3517, 3518, 3518, 3518,
-     3518, 3518, 3518, 3518, 3518, 3518, 3519, 3519, 3519,    0,
-        0,    0, 3519, 3520, 3520, 3520, 3520,    0,    0, 3520,
-     3520, 3521, 3521, 3521, 3521,    0,    0, 3521, 3521, 3522,
-     3522, 3522,    0,    0,    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,    0,    0,    0, 3526, 3527, 3527, 3527, 3527,
-        0,    0, 3527, 3527, 3528, 3528, 3528,    0,    0,    0,
-
+        0,    0, 3302, 3303, 3303, 3303,    0,    0,    0, 3303,
+     3304, 3304, 3304, 3304, 3304, 3304, 3304,    0, 3304, 3305,
+     3305, 3305,    0,    0,    0, 3305, 3306,    0,    0,    0,
+
+     3306, 3307, 3307, 3307,    0,    0,    0, 3307, 3308,    0,
+        0,    0, 3308, 3309, 3309, 3309,    0,    0,    0, 3309,
+     3310,    0,    0,    0, 3310, 3311, 3311, 3311,    0,    0,
+        0, 3311, 3312,    0,    0,    0, 3312, 3313, 3313, 3313,
+        0,    0,    0, 3313, 3314,    0,    0,    0, 3314, 3315,
+     3315, 3315,    0,    0,    0, 3315, 3316,    0,    0,    0,
+     3316, 3317, 3317, 3317,    0,    0,    0, 3317, 3318,    0,
+        0,    0, 3318, 3319, 3319, 3319,    0,    0,    0, 3319,
+     3320,    0,    0,    0, 3320, 3321, 3321, 3321,    0,    0,
+        0, 3321, 3322,    0,    0,    0, 3322, 3323, 3323, 3323,
+
+        0,    0,    0, 3323, 3324,    0,    0,    0, 3324, 3325,
+     3325, 3325,    0,    0,    0, 3325, 3326,    0,    0,    0,
+     3326, 3327, 3327, 3327,    0,    0,    0, 3327, 3328,    0,
+        0,    0, 3328, 3329, 3329, 3329,    0,    0,    0, 3329,
+     3330,    0,    0,    0, 3330, 3331, 3331, 3331,    0,    0,
+        0, 3331, 3332,    0,    0,    0, 3332, 3333, 3333, 3333,
+        0,    0,    0, 3333, 3334,    0,    0,    0, 3334, 3335,
+     3335, 3335,    0,    0,    0, 3335, 3336,    0,    0,    0,
+     3336, 3337, 3337, 3337,    0,    0,    0, 3337, 3338,    0,
+        0,    0, 3338, 3339, 3339, 3339,    0,    0,    0, 3339,
+
+     3340,    0,    0,    0, 3340, 3341, 3341, 3341,    0,    0,
+        0, 3341, 3342,    0,    0,    0, 3342, 3343, 3343, 3343,
+        0,    0,    0, 3343, 3344,    0,    0,    0, 3344, 3345,
+     3345, 3345,    0,    0,    0, 3345, 3346,    0,    0,    0,
+     3346, 3347, 3347, 3347,    0,    0,    0, 3347, 3348,    0,
+        0,    0, 3348, 3349, 3349, 3349,    0,    0,    0, 3349,
+     3350,    0,    0,    0, 3350, 3351, 3351, 3351,    0,    0,
+        0, 3351, 3352,    0,    0,    0, 3352, 3353, 3353, 3353,
+        0,    0,    0, 3353, 3354,    0,    0,    0, 3354, 3355,
+     3355, 3355,    0,    0,    0, 3355, 3356,    0,    0,    0,
+
+     3356, 3357, 3357, 3357,    0,    0,    0, 3357, 3358,    0,
+        0,    0, 3358, 3359, 3359, 3359, 3359, 3359, 3359, 3359,
+     3359, 3359, 3360,    0,    0,    0,    0, 3360, 3361, 3361,
+     3361,    0,    0,    0, 3361, 3362, 3362, 3362, 3362,    0,
+        0, 3362, 3362, 3363, 3363, 3363,    0,    0,    0, 3363,
+     3364, 3364, 3364, 3364,    0,    0, 3364, 3364, 3365, 3365,
+     3365,    0,    0,    0, 3365, 3366, 3366, 3366, 3366,    0,
+        0, 3366, 3366, 3367, 3367, 3367,    0,    0,    0, 3367,
+     3368, 3368, 3368, 3368,    0,    0, 3368, 3368, 3369, 3369,
+     3369,    0,    0,    0, 3369, 3370, 3370, 3370, 3370,    0,
+
+        0, 3370, 3370, 3371, 3371, 3371,    0,    0,    0, 3371,
+     3372, 3372, 3372, 3372,    0,    0, 3372, 3372, 3373, 3373,
+     3373,    0,    0,    0, 3373, 3374, 3374, 3374, 3374,    0,
+        0, 3374, 3374, 3375, 3375, 3375,    0,    0,    0, 3375,
+     3376, 3376, 3376, 3376,    0,    0, 3376, 3376, 3377, 3377,
+     3377,    0,    0,    0, 3377, 3378, 3378, 3378, 3378,    0,
+        0, 3378, 3378, 3379, 3379, 3379,    0,    0,    0, 3379,
+     3380, 3380, 3380, 3380,    0,    0, 3380, 3380, 3381, 3381,
+     3381,    0,    0,    0, 3381, 3382, 3382, 3382, 3382,    0,
+        0, 3382, 3382, 3383, 3383, 3383,    0,    0,    0, 3383,
+
+     3384, 3384, 3384, 3384,    0,    0, 3384, 3384, 3385, 3385,
+     3385,    0,    0,    0, 3385, 3386, 3386, 3386, 3386,    0,
+        0, 3386, 3386, 3387, 3387, 3387, 3387,    0, 3387,    0,
+     3387, 3388, 3388, 3388, 3388,    0,    0, 3388, 3388, 3389,
+     3389, 3389,    0,    0,    0, 3389, 3390, 3390, 3390, 3390,
+        0,    0, 3390, 3390, 3391, 3391, 3391,    0,    0,    0,
+     3391, 3392, 3392, 3392, 3392,    0,    0, 3392, 3392, 3393,
+     3393, 3393,    0,    0,    0, 3393, 3394, 3394, 3394, 3394,
+        0,    0, 3394, 3394, 3395, 3395, 3395,    0,    0,    0,
+     3395, 3396, 3396, 3396, 3396,    0,    0, 3396, 3396, 3397,
+
+     3397, 3397, 3397,    0, 3397,    0, 3397, 3398, 3398, 3398,
+     3398,    0,    0, 3398, 3398, 3399, 3399, 3399, 3399,    0,
+     3399,    0, 3399, 3400, 3400, 3400, 3400,    0,    0, 3400,
+     3400, 3401, 3401, 3401,    0,    0,    0, 3401, 3402, 3402,
+     3402, 3402,    0,    0, 3402, 3402, 3403, 3403, 3403, 3403,
+        0, 3403,    0, 3403, 3404, 3404, 3404, 3404,    0,    0,
+     3404, 3404, 3405, 3405, 3405, 3405,    0, 3405,    0, 3405,
+     3406, 3406, 3406, 3406,    0,    0, 3406, 3406, 3407, 3407,
+     3407,    0,    0,    0, 3407, 3408, 3408, 3408, 3408,    0,
+        0, 3408, 3408, 3409, 3409, 3409,    0,    0,    0, 3409,
+
+     3410, 3410, 3410, 3410,    0,    0, 3410, 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, 3414, 3414, 3414, 3414, 3414, 3414,
+     3415,    0, 3415,    0,    0, 3415, 3416, 3416, 3416,    0,
+        0,    0, 3416, 3417, 3417, 3417, 3417,    0,    0, 3417,
+     3417, 3418, 3418, 3418, 3418,    0, 3418,    0, 3418, 3419,
+     3419, 3419, 3419,    0,    0, 3419, 3419, 3420, 3420, 3420,
+     3420,    0, 3420,    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, 3432,    0, 3432,    0, 3432, 3433, 3433, 3433, 3433,
+        0,    0, 3433, 3433, 3434, 3434, 3434, 3434,    0, 3434,
+        0, 3434, 3435, 3435, 3435, 3435,    0,    0, 3435, 3435,
+
+     3436, 3436, 3436,    0,    0,    0, 3436, 3437, 3437, 3437,
+     3437,    0,    0, 3437, 3437, 3438, 3438, 3438, 3438,    0,
+     3438,    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,    0,
+        0,    0, 3446, 3447, 3447, 3447, 3447,    0,    0, 3447,
+     3447, 3448, 3448, 3448,    0,    0,    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,    0,    0,    0, 3452, 3453, 3453,
+     3453, 3453,    0,    0, 3453, 3453, 3454, 3454, 3454,    0,
+        0,    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, 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, 3465,    0,    0, 3465, 3465, 3466, 3466, 3466,
+        0,    0,    0, 3466, 3467, 3467, 3467, 3467,    0,    0,
+     3467, 3467, 3468, 3468, 3468, 3468, 3468, 3468, 3468, 3468,
+     3468, 3469, 3469, 3469, 3469, 3469, 3469, 3469, 3469, 3469,
+     3470, 3470, 3470,    0,    0,    0, 3470, 3471, 3471, 3471,
+     3471,    0,    0, 3471, 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,    0,    0,
+        0, 3480, 3481, 3481, 3481, 3481,    0,    0, 3481, 3481,
+     3482, 3482, 3482,    0,    0,    0, 3482, 3483, 3483, 3483,
+     3483,    0,    0, 3483, 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,    0,    0,    0, 3487, 3488, 3488, 3488, 3488,    0,
+
+        0, 3488, 3488, 3489, 3489, 3489, 3489,    0,    0, 3489,
+     3489, 3490, 3490, 3490,    0,    0,    0, 3490, 3491, 3491,
+     3491, 3491,    0,    0, 3491, 3491, 3492, 3492, 3492, 3492,
+        0, 3492,    0, 3492, 3493, 3493, 3493, 3493,    0,    0,
+     3493, 3493, 3494, 3494, 3494,    0,    0,    0, 3494, 3495,
+     3495, 3495, 3495,    0,    0, 3495, 3495, 3496, 3496, 3496,
+        0,    0,    0, 3496, 3497, 3497, 3497, 3497,    0,    0,
+     3497, 3497, 3498, 3498, 3498,    0,    0,    0, 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,    0,    0,    0, 3502, 3503,
+     3503, 3503, 3503,    0,    0, 3503, 3503, 3504, 3504, 3504,
+        0,    0,    0, 3504, 3505, 3505, 3505, 3505,    0,    0,
+     3505, 3505, 3506, 3506, 3506,    0,    0,    0, 3506, 3507,
+     3507, 3507, 3507,    0,    0, 3507, 3507, 3508, 3508, 3508,
+     3508,    0,    0, 3508, 3508, 3509, 3509, 3509,    0,    0,
+        0, 3509, 3510, 3510, 3510, 3510,    0,    0, 3510, 3510,
+     3511, 3511, 3511,    0,    0,    0, 3511, 3512, 3512, 3512,
+     3512,    0,    0, 3512, 3512, 3513, 3513, 3513, 3513,    0,
+     3513,    0, 3513, 3514, 3514, 3514, 3514,    0,    0, 3514,
+
+     3514, 3515, 3515, 3515, 3515,    0,    0, 3515, 3515, 3516,
+     3516, 3516, 3516,    0, 3516,    0, 3516, 3517, 3517, 3517,
+     3517,    0,    0, 3517, 3517, 3518, 3518, 3518, 3518, 3518,
+     3518, 3518, 3518, 3518, 3519, 3519, 3519, 3519, 3519, 3519,
+     3519, 3519, 3519, 3520, 3520, 3520,    0,    0,    0, 3520,
+     3521, 3521, 3521, 3521,    0,    0, 3521, 3521, 3522, 3522,
+     3522, 3522,    0,    0, 3522, 3522, 3523, 3523, 3523,    0,
+        0,    0, 3523, 3524, 3524, 3524, 3524,    0,    0, 3524,
+     3524, 3525, 3525, 3525,    0,    0,    0, 3525, 3526, 3526,
+     3526, 3526,    0,    0, 3526, 3526, 3527, 3527, 3527,    0,
+
+        0,    0, 3527, 3528, 3528, 3528, 3528,    0,    0, 3528,
      3528, 3529, 3529, 3529,    0,    0,    0, 3529, 3530, 3530,
-     3530, 3530,    0,    0, 3530, 3530, 3531, 3531, 3531,    0,
-        0,    0, 3531, 3532, 3532, 3532, 3532,    0,    0, 3532,
-     3532, 3533, 3533, 3533, 3533,    0,    0, 3533, 3533, 3534,
-     3534, 3534, 3534,    0, 3534,    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, 3538,    0,    0, 3538, 3538, 3539, 3539,
-     3539,    0,    0,    0, 3539, 3540, 3540, 3540, 3540,    0,
-        0, 3540, 3540, 3541, 3541, 3541, 3541,    0, 3541,    0,
-
-     3541, 3542, 3542, 3542, 3542,    0,    0, 3542, 3542, 3543,
-     3543, 3543,    0,    0,    0, 3543, 3544, 3544, 3544, 3544,
-        0,    0, 3544, 3544, 3545, 3545, 3545,    0,    0,    0,
-     3545, 3546, 3546, 3546, 3546,    0,    0, 3546, 3546, 3547,
-     3547, 3547,    0,    0,    0, 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, 3553,    0, 3553,
-        0, 3553, 3554, 3554, 3554, 3554,    0,    0, 3554, 3554,
-
-     3555, 3555, 3555,    0,    0,    0, 3555, 3556, 3556, 3556,
-     3556,    0,    0, 3556, 3556, 3557, 3557, 3557, 3557,    0,
-        0, 3557, 3557, 3558, 3558, 3558, 3558,    0, 3558,    0,
-     3558, 3559, 3559, 3559, 3559,    0,    0, 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, 3563,    0,    0, 3563, 3563,
-     3564, 3564, 3564, 3564,    0,    0, 3564, 3564, 3565, 3565,
-     3565, 3565, 3565, 3565, 3565, 3565, 3565, 3566, 3566, 3566,
-     3566, 3566, 3566, 3566, 3566, 3566, 3567, 3567, 3567, 3567,
-
-        0, 3567,    0, 3567, 3568, 3568, 3568, 3568,    0,    0,
-     3568, 3568, 3569, 3569, 3569, 3569,    0,    0, 3569, 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, 3574,    0, 3574, 3575, 3575,
-     3575, 3575,    0,    0, 3575, 3575, 3576, 3576, 3576, 3576,
-        0, 3576,    0, 3576, 3577, 3577, 3577, 3577,    0, 3577,
-        0, 3577, 3578, 3578, 3578, 3578,    0,    0, 3578, 3578,
-     3579, 3579, 3579, 3579,    0, 3579,    0, 3579, 3580, 3580,
-
-     3580, 3580,    0,    0, 3580, 3580, 3581, 3581, 3581, 3581,
-        0,    0, 3581, 3581, 3582, 3582, 3582, 3582,    0,    0,
-     3582, 3582, 3583, 3583, 3583,    0,    0,    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, 3587,    0, 3587,    0, 3587,
-     3588, 3588, 3588, 3588,    0,    0, 3588, 3588, 3589, 3589,
-     3589,    0,    0,    0, 3589, 3590, 3590, 3590,    0,    0,
-        0, 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,    0,    0,
-        0, 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,    0,    0,    0, 3599, 3600,
-     3600, 3600, 3600,    0,    0, 3600, 3600, 3601, 3601, 3601,
-     3601,    0,    0, 3601, 3601, 3602, 3602, 3602, 3602,    0,
-        0, 3602, 3602, 3603, 3603, 3603,    0,    0,    0, 3603,
-     3604, 3604, 3604, 3604,    0,    0, 3604, 3604, 3605, 3605,
-     3605, 3605,    0,    0, 3605, 3605, 3606, 3606, 3606, 3606,
-
-        0,    0, 3606, 3606, 3607, 3607, 3607, 3607, 3607, 3607,
-     3607, 3607, 3607, 3608, 3608, 3608, 3608, 3608, 3608, 3608,
-     3608, 3608, 3609, 3609, 3609, 3609,    0,    0, 3609, 3609,
-     3610, 3610, 3610, 3610,    0,    0, 3610, 3610, 3611, 3611,
-     3611,    0,    0,    0, 3611, 3612, 3612, 3612,    0,    0,
-        0, 3612, 3613, 3613, 3613, 3613,    0,    0, 3613, 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,    0,    0,    0, 3618, 3619,
-
-     3619, 3619, 3619,    0,    0, 3619, 3619, 3620, 3620, 3620,
-        0,    0,    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,
-        0,    0,    0, 3624, 3625, 3625, 3625, 3625,    0,    0,
-     3625, 3625, 3626, 3626, 3626,    0,    0,    0, 3626, 3627,
-     3627, 3627, 3627,    0,    0, 3627, 3627, 3628, 3628, 3628,
-        0,    0,    0, 3628, 3629, 3629, 3629,    0,    0,    0,
+     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, 3534,    0,    0, 3534, 3534, 3535, 3535, 3535, 3535,
+        0, 3535,    0, 3535, 3536, 3536, 3536, 3536,    0,    0,
+     3536, 3536, 3537, 3537, 3537,    0,    0,    0, 3537, 3538,
+     3538, 3538, 3538,    0,    0, 3538, 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, 3542,    0, 3542,    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,    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, 3554,    0, 3554,    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, 3558,    0,    0, 3558, 3558,
+     3559, 3559, 3559, 3559,    0, 3559,    0, 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, 3563,    0,    0, 3563, 3563, 3564,
+     3564, 3564, 3564,    0,    0, 3564, 3564, 3565, 3565, 3565,
+     3565,    0,    0, 3565, 3565, 3566, 3566, 3566, 3566, 3566,
+
+     3566, 3566, 3566, 3566, 3567, 3567, 3567, 3567, 3567, 3567,
+     3567, 3567, 3567, 3568, 3568, 3568, 3568,    0, 3568,    0,
+     3568, 3569, 3569, 3569, 3569,    0,    0, 3569, 3569, 3570,
+     3570, 3570, 3570,    0,    0, 3570, 3570, 3571, 3571, 3571,
+        0,    0,    0, 3571, 3572, 3572, 3572, 3572,    0,    0,
+     3572, 3572, 3573, 3573, 3573,    0,    0,    0, 3573, 3574,
+     3574, 3574, 3574,    0,    0, 3574, 3574, 3575, 3575, 3575,
+     3575,    0, 3575,    0, 3575, 3576, 3576, 3576, 3576,    0,
+        0, 3576, 3576, 3577, 3577, 3577, 3577,    0, 3577,    0,
+     3577, 3578, 3578, 3578, 3578,    0, 3578,    0, 3578, 3579,
+
+     3579, 3579, 3579,    0,    0, 3579, 3579, 3580, 3580, 3580,
+     3580,    0, 3580,    0, 3580, 3581, 3581, 3581, 3581,    0,
+        0, 3581, 3581, 3582, 3582, 3582, 3582,    0,    0, 3582,
+     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,    0,    0,    0,
+     3586, 3587, 3587, 3587, 3587,    0,    0, 3587, 3587, 3588,
+     3588, 3588, 3588,    0, 3588,    0, 3588, 3589, 3589, 3589,
+     3589,    0,    0, 3589, 3589, 3590, 3590, 3590,    0,    0,
+        0, 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,    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, 3602,    0,    0,
+     3602, 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,
+        0, 3606, 3606, 3607, 3607, 3607, 3607,    0,    0, 3607,
+     3607, 3608, 3608, 3608, 3608, 3608, 3608, 3608, 3608, 3608,
+     3609, 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3609, 3610,
+     3610, 3610, 3610,    0,    0, 3610, 3610, 3611, 3611, 3611,
+     3611,    0,    0, 3611, 3611, 3612, 3612, 3612,    0,    0,
+        0, 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,    0,    0, 3618, 3618, 3619,
+     3619, 3619,    0,    0,    0, 3619, 3620, 3620, 3620, 3620,
+        0,    0, 3620, 3620, 3621, 3621, 3621,    0,    0,    0,
+     3621, 3622, 3622, 3622, 3622,    0,    0, 3622, 3622, 3623,
+     3623, 3623, 3623,    0,    0, 3623, 3623, 3624, 3624, 3624,
+        0,    0,    0, 3624, 3625, 3625, 3625,    0,    0,    0,
+     3625, 3626, 3626, 3626, 3626,    0,    0, 3626, 3626, 3627,
+     3627, 3627,    0,    0,    0, 3627, 3628, 3628, 3628, 3628,
+        0,    0, 3628, 3628, 3629, 3629, 3629,    0,    0,    0,
      3629, 3630, 3630, 3630,    0,    0,    0, 3630, 3631, 3631,
-     3631, 3631,    0,    0, 3631, 3631, 3632, 3632, 3632,    0,
-
-        0,    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,
-     3636,    0, 3636,    0, 3636, 3637, 3637, 3637, 3637,    0,
-        0, 3637, 3637, 3638, 3638, 3638, 3638,    0,    0, 3638,
-     3638, 3639, 3639, 3639, 3639,    0,    0, 3639, 3639, 3640,
-     3640, 3640, 3640, 3640, 3640, 3640, 3640, 3640, 3641, 3641,
-     3641, 3641, 3641, 3641, 3641, 3641, 3641, 3642, 3642, 3642,
-     3642,    0,    0, 3642, 3642, 3643, 3643, 3643, 3643,    0,
-        0, 3643, 3643, 3644, 3644, 3644,    0,    0,    0, 3644,
-
-     3645, 3645, 3645, 3645,    0, 3645,    0, 3645, 3646, 3646,
-     3646, 3646,    0,    0, 3646, 3646, 3647, 3647, 3647, 3647,
-        0,    0, 3647, 3647, 3648, 3648, 3648, 3648,    0,    0,
-     3648, 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,    0,    0,    0, 3655, 3656, 3656, 3656,    0,    0,
-        0, 3656, 3657, 3657, 3657, 3657,    0, 3657,    0, 3657,
-
-     3658, 3658, 3658, 3658,    0,    0, 3658, 3658, 3659, 3659,
-     3659, 3659,    0, 3659,    0, 3659, 3660, 3660, 3660,    0,
-        0,    0, 3660, 3661, 3661, 3661,    0,    0,    0, 3661,
-     3662, 3662, 3662, 3662,    0,    0, 3662, 3662, 3663, 3663,
-     3663, 3663,    0, 3663,    0, 3663, 3664, 3664, 3664, 3664,
-        0,    0, 3664, 3664, 3665, 3665, 3665, 3665,    0,    0,
-     3665, 3665, 3666, 3666, 3666, 3666,    0,    0, 3666, 3666,
-     3667, 3667, 3667, 3667,    0, 3667,    0, 3667, 3668, 3668,
-     3668, 3668,    0,    0, 3668, 3668, 3669, 3669, 3669, 3669,
-        0,    0, 3669, 3669, 3670, 3670, 3670, 3670, 3670, 3670,
-
-     3670, 3670, 3670, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
-     3671, 3671, 3672, 3672, 3672, 3672,    0,    0, 3672, 3672,
-     3673, 3673, 3673,    0,    0,    0, 3673, 3674, 3674, 3674,
-        0,    0,    0, 3674, 3675, 3675, 3675, 3675,    0,    0,
-     3675, 3675, 3676, 3676, 3676, 3676,    0,    0, 3676, 3676,
-     3677, 3677, 3677, 3677,    0,    0, 3677, 3677, 3678, 3678,
-     3678,    0,    0,    0, 3678, 3679, 3679, 3679, 3679,    0,
-        0, 3679, 3679, 3680, 3680, 3680,    0,    0,    0, 3680,
-     3681, 3681, 3681, 3681, 3681, 3681, 3681, 3681, 3681, 3682,
-     3682, 3682, 3682, 3682, 3682, 3682, 3682, 3682, 3683, 3683,
-
-     3683, 3683, 3683, 3683, 3683, 3683, 3683, 3684, 3684, 3684,
-     3684, 3684, 3684, 3684, 3684, 3684, 3685, 3685, 3685, 3685,
-     3685, 3685, 3685, 3685, 3685, 3686, 3686, 3686, 3686, 3686,
-     3686, 3686, 3686, 3686, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216,
-
-     3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216, 3216
+
+     3631,    0,    0,    0, 3631, 3632, 3632, 3632, 3632,    0,
+        0, 3632, 3632, 3633, 3633, 3633,    0,    0,    0, 3633,
+     3634, 3634, 3634, 3634,    0,    0, 3634, 3634, 3635, 3635,
+     3635, 3635,    0,    0, 3635, 3635, 3636, 3636, 3636, 3636,
+        0,    0, 3636, 3636, 3637, 3637, 3637, 3637,    0, 3637,
+        0, 3637, 3638, 3638, 3638, 3638,    0,    0, 3638, 3638,
+     3639, 3639, 3639, 3639,    0,    0, 3639, 3639, 3640, 3640,
+     3640, 3640,    0,    0, 3640, 3640, 3641, 3641, 3641, 3641,
+     3641, 3641, 3641, 3641, 3641, 3642, 3642, 3642, 3642, 3642,
+     3642, 3642, 3642, 3642, 3643, 3643, 3643, 3643,    0,    0,
+
+     3643, 3643, 3644, 3644, 3644, 3644,    0,    0, 3644, 3644,
+     3645, 3645, 3645,    0,    0,    0, 3645, 3646, 3646, 3646,
+     3646,    0, 3646,    0, 3646, 3647, 3647, 3647, 3647,    0,
+        0, 3647, 3647, 3648, 3648, 3648, 3648,    0,    0, 3648,
+     3648, 3649, 3649, 3649, 3649,    0,    0, 3649, 3649, 3650,
+     3650, 3650, 3650,    0,    0, 3650, 3650, 3651, 3651, 3651,
+        0,    0,    0, 3651, 3652, 3652, 3652, 3652,    0,    0,
+     3652, 3652, 3653, 3653, 3653,    0,    0,    0, 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,    0,    0,    0, 3657, 3658,
+     3658, 3658, 3658,    0, 3658,    0, 3658, 3659, 3659, 3659,
+     3659,    0,    0, 3659, 3659, 3660, 3660, 3660, 3660,    0,
+     3660,    0, 3660, 3661, 3661, 3661,    0,    0,    0, 3661,
+     3662, 3662, 3662,    0,    0,    0, 3662, 3663, 3663, 3663,
+     3663,    0,    0, 3663, 3663, 3664, 3664, 3664, 3664,    0,
+     3664,    0, 3664, 3665, 3665, 3665, 3665,    0,    0, 3665,
+     3665, 3666, 3666, 3666, 3666,    0,    0, 3666, 3666, 3667,
+     3667, 3667, 3667,    0,    0, 3667, 3667, 3668, 3668, 3668,
+     3668,    0, 3668,    0, 3668, 3669, 3669, 3669, 3669,    0,
+
+        0, 3669, 3669, 3670, 3670, 3670, 3670,    0,    0, 3670,
+     3670, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671, 3671,
+     3672, 3672, 3672, 3672, 3672, 3672, 3672, 3672, 3672, 3673,
+     3673, 3673, 3673,    0,    0, 3673, 3673, 3674, 3674, 3674,
+        0,    0,    0, 3674, 3675, 3675, 3675,    0,    0,    0,
+     3675, 3676, 3676, 3676, 3676,    0,    0, 3676, 3676, 3677,
+     3677, 3677, 3677,    0,    0, 3677, 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,
+
+     3682, 3682, 3682, 3682, 3682, 3682, 3683, 3683, 3683, 3683,
+     3683, 3683, 3683, 3683, 3683, 3684, 3684, 3684, 3684, 3684,
+     3684, 3684, 3684, 3684, 3685, 3685, 3685, 3685, 3685, 3685,
+     3685, 3685, 3685, 3686, 3686, 3686, 3686, 3686, 3686, 3686,
+     3686, 3686, 3687, 3687, 3687, 3687, 3687, 3687, 3687, 3687,
+     3687, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217, 3217,
+     3217, 3217, 3217, 3217, 3217, 3217
     } ;
 
 /* Table of booleans, true if rule could match eol. */
@@ -4752,27 +4756,27 @@ const char* *surfxml_statenames=NULL;
 #define AL_surfxml_trace 26
 #define IN_trace 27
 #define AL_surfxml_random 28
-#define S_surfxml_random 29
-#define S_surfxml_random_1 30
-#define S_surfxml_random_2 31
-#define E_surfxml_random 32
-#define AL_surfxml_trace_connect 33
-#define E_surfxml_trace_connect 34
-#define AL_surfxml_AS 35
-#define S_surfxml_AS 36
-#define S_surfxml_AS_1 37
-#define S_surfxml_AS_2 38
-#define S_surfxml_AS_3 39
-#define S_surfxml_AS_4 40
-#define S_surfxml_AS_5 41
-#define S_surfxml_AS_6 42
-#define S_surfxml_AS_7 43
-#define S_surfxml_AS_8 44
-#define S_surfxml_AS_9 45
-#define S_surfxml_AS_10 46
-#define S_surfxml_AS_11 47
-#define S_surfxml_AS_12 48
-#define S_surfxml_AS_13 49
+#define E_surfxml_random 29
+#define AL_surfxml_trace_connect 30
+#define E_surfxml_trace_connect 31
+#define AL_surfxml_AS 32
+#define S_surfxml_AS 33
+#define S_surfxml_AS_1 34
+#define S_surfxml_AS_2 35
+#define S_surfxml_AS_3 36
+#define S_surfxml_AS_4 37
+#define S_surfxml_AS_5 38
+#define S_surfxml_AS_6 39
+#define S_surfxml_AS_7 40
+#define S_surfxml_AS_8 41
+#define S_surfxml_AS_9 42
+#define S_surfxml_AS_10 43
+#define S_surfxml_AS_11 44
+#define S_surfxml_AS_12 45
+#define S_surfxml_AS_13 46
+#define S_surfxml_AS_14 47
+#define S_surfxml_AS_15 48
+#define S_surfxml_AS_16 49
 #define E_surfxml_AS 50
 #define AL_surfxml_storage_type 51
 #define S_surfxml_storage_type 52
@@ -5101,9 +5105,6 @@ YY_DECL
   surfxml_statenames[AL_surfxml_trace] = NULL;
   surfxml_statenames[IN_trace] = "trace";
   surfxml_statenames[AL_surfxml_random] = NULL;
-  surfxml_statenames[S_surfxml_random] = "random";
-  surfxml_statenames[S_surfxml_random_1] = "random";
-  surfxml_statenames[S_surfxml_random_2] = "random";
   surfxml_statenames[E_surfxml_random] = "random";
   surfxml_statenames[AL_surfxml_trace_connect] = NULL;
   surfxml_statenames[E_surfxml_trace_connect] = "trace_connect";
@@ -5122,6 +5123,9 @@ YY_DECL
   surfxml_statenames[S_surfxml_AS_11] = "AS";
   surfxml_statenames[S_surfxml_AS_12] = "AS";
   surfxml_statenames[S_surfxml_AS_13] = "AS";
+  surfxml_statenames[S_surfxml_AS_14] = "AS";
+  surfxml_statenames[S_surfxml_AS_15] = "AS";
+  surfxml_statenames[S_surfxml_AS_16] = "AS";
   surfxml_statenames[E_surfxml_AS] = "AS";
   surfxml_statenames[AL_surfxml_storage_type] = NULL;
   surfxml_statenames[S_surfxml_storage_type] = "storage_type";
@@ -5250,13 +5254,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 >= 3217 )
+                               if ( yy_current_state >= 3218 )
                                        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] != 11735 );
+               while ( yy_base[yy_current_state] != 11752 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -5487,9 +5491,9 @@ YY_RULE_SETUP
   if (!AX_surfxml_include_file) FAIL("Required attribute `file' not set for `include' element.");
   LEAVE; STag_surfxml_include(); surfxml_pcdata_ix = 0; ETag_surfxml_include(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_6: case S_surfxml_AS_5: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_6: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_3: case S_surfxml_AS_13: case S_surfxml_AS: SET(S_surfxml_AS_14); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -5514,9 +5518,9 @@ YY_RULE_SETUP
   ETag_surfxml_include();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_6: case S_surfxml_AS_5: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_6: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_3: case S_surfxml_AS_13: case S_surfxml_AS: SET(S_surfxml_AS_14); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -5597,12 +5601,12 @@ YY_RULE_SETUP
   if (!AX_surfxml_trace_periodicity) FAIL("Required attribute `periodicity' not set for `trace' element.");
   LEAVE; STag_surfxml_trace(); surfxml_pcdata_ix = 0; ETag_surfxml_trace(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_6: SET(S_surfxml_AS_8); break;
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: SET(S_surfxml_AS_3); break;
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS_7: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_15: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
+   case S_surfxml_AS_5: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_13: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_14: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -5629,12 +5633,12 @@ YY_RULE_SETUP
   surfxml_pcdata_ix = popbuffer();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_6: SET(S_surfxml_AS_8); break;
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: SET(S_surfxml_AS_3); break;
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS_7: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_15: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
+   case S_surfxml_AS_5: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_13: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_14: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -5775,7 +5779,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_random_max) FAIL("Required attribute `max' not set for `random' element.");
   if (!AX_surfxml_random_mean) FAIL("Required attribute `mean' not set for `random' element.");
   if (!AX_surfxml_random_std_deviation) FAIL("Required attribute `std_deviation' not set for `random' element.");
-  LEAVE; STag_surfxml_random();surfxml_pcdata_ix = 0; ENTER(S_surfxml_random);
+  LEAVE; STag_surfxml_random();surfxml_pcdata_ix = 0; ENTER(E_surfxml_random);
  }
        YY_BREAK
 case 77:
@@ -5825,8 +5829,6 @@ case 82:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</random>' expected.",surf_parse_text[0]);
        YY_BREAK
-case YY_STATE_EOF(S_surfxml_random):
-case YY_STATE_EOF(S_surfxml_random_2):
 case YY_STATE_EOF(E_surfxml_random):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</random>' expected.");
        YY_BREAK
@@ -5917,12 +5919,12 @@ YY_RULE_SETUP
   if (!AX_surfxml_trace_connect_element) FAIL("Required attribute `element' not set for `trace_connect' element.");
   LEAVE; STag_surfxml_trace_connect(); surfxml_pcdata_ix = 0; ETag_surfxml_trace_connect(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_6: SET(S_surfxml_AS_8); break;
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: SET(S_surfxml_AS_3); break;
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS_7: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_15: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
+   case S_surfxml_AS_5: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_13: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_14: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -5947,12 +5949,12 @@ YY_RULE_SETUP
   ETag_surfxml_trace_connect();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_7: case S_surfxml_AS_6: SET(S_surfxml_AS_8); break;
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: SET(S_surfxml_AS_3); break;
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS_7: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_15: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
+   case S_surfxml_AS_5: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_13: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_14: case S_surfxml_AS_13: SET(S_surfxml_AS_14); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -6064,7 +6066,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_AS_id) FAIL("Required attribute `id' not set for `AS' element.");
   LEAVE; STag_surfxml_AS(); surfxml_pcdata_ix = 0; ETag_surfxml_AS(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
@@ -6090,7 +6092,7 @@ YY_RULE_SETUP
   ETag_surfxml_AS();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
@@ -6105,14 +6107,16 @@ case 132:
 YY_RULE_SETUP
 FAIL("Unexpected character `%c': `</AS>' expected.",surf_parse_text[0]);
        YY_BREAK
+case YY_STATE_EOF(S_surfxml_AS_12):
 case YY_STATE_EOF(S_surfxml_AS_9):
 case YY_STATE_EOF(S_surfxml_AS_1):
+case YY_STATE_EOF(S_surfxml_AS_7):
 case YY_STATE_EOF(S_surfxml_AS_11):
+case YY_STATE_EOF(S_surfxml_AS_14):
 case YY_STATE_EOF(S_surfxml_AS_6):
 case YY_STATE_EOF(E_surfxml_AS):
+case YY_STATE_EOF(S_surfxml_AS_16):
 case YY_STATE_EOF(S_surfxml_AS_3):
-case YY_STATE_EOF(S_surfxml_AS_13):
-case YY_STATE_EOF(S_surfxml_AS_8):
 case YY_STATE_EOF(S_surfxml_AS):
 case YY_STATE_EOF(S_surfxml_AS_4):
 if(!ETag_surfxml_include_state()) FAIL("Premature EOF: `</AS>' expected.");
@@ -6192,8 +6196,8 @@ YY_RULE_SETUP
   if (!AX_surfxml_storage_type_size) FAIL("Required attribute `size' not set for `storage_type' element.");
   LEAVE; STag_surfxml_storage_type(); surfxml_pcdata_ix = 0; ETag_surfxml_storage_type(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6217,8 +6221,8 @@ YY_RULE_SETUP
   ETag_surfxml_storage_type();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6298,8 +6302,8 @@ YY_RULE_SETUP
   if (!AX_surfxml_storage_typeId) FAIL("Required attribute `typeId' not set for `storage' element.");
   LEAVE; STag_surfxml_storage(); surfxml_pcdata_ix = 0; ETag_surfxml_storage(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6323,8 +6327,8 @@ YY_RULE_SETUP
   ETag_surfxml_storage();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6645,7 +6649,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_host_power) FAIL("Required attribute `power' not set for `host' element.");
   LEAVE; STag_surfxml_host(); surfxml_pcdata_ix = 0; ETag_surfxml_host(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6669,7 +6673,7 @@ YY_RULE_SETUP
   ETag_surfxml_host();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6751,7 +6755,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_host_link_down) FAIL("Required attribute `down' not set for `host_link' element.");
   LEAVE; STag_surfxml_host_link(); surfxml_pcdata_ix = 0; ETag_surfxml_host_link(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -6775,7 +6779,7 @@ YY_RULE_SETUP
   ETag_surfxml_host_link();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7010,7 +7014,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_cluster_lat) FAIL("Required attribute `lat' not set for `cluster' element.");
   LEAVE; STag_surfxml_cluster(); surfxml_pcdata_ix = 0; ETag_surfxml_cluster(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
@@ -7036,7 +7040,7 @@ YY_RULE_SETUP
   ETag_surfxml_cluster();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
@@ -7170,9 +7174,9 @@ YY_RULE_SETUP
   if (!AX_surfxml_cabinet_lat) FAIL("Required attribute `lat' not set for `cabinet' element.");
   LEAVE; STag_surfxml_cabinet(); surfxml_pcdata_ix = 0; ETag_surfxml_cabinet(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -7197,9 +7201,9 @@ YY_RULE_SETUP
   ETag_surfxml_cabinet();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
  }
@@ -7339,7 +7343,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_peer_lat) FAIL("Required attribute `lat' not set for `peer' element.");
   LEAVE; STag_surfxml_peer(); surfxml_pcdata_ix = 0; ETag_surfxml_peer(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
@@ -7365,7 +7369,7 @@ YY_RULE_SETUP
   ETag_surfxml_peer();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
    case S_surfxml_platform_6: case S_surfxml_platform_5: case S_surfxml_platform_1: case S_surfxml_platform: case S_surfxml_platform_3: SET(S_surfxml_platform_6); break;
    case S_surfxml_include: case S_surfxml_include_2: case S_surfxml_include_1: SET(S_surfxml_include_2); break;
   }
@@ -7432,7 +7436,7 @@ 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; ETag_surfxml_router(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7456,7 +7460,7 @@ YY_RULE_SETUP
   ETag_surfxml_router();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7536,8 +7540,8 @@ YY_RULE_SETUP
   if (!AX_surfxml_backbone_latency) FAIL("Required attribute `latency' not set for `backbone' element.");
   LEAVE; STag_surfxml_backbone(); surfxml_pcdata_ix = 0; ETag_surfxml_backbone(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7561,8 +7565,8 @@ YY_RULE_SETUP
   ETag_surfxml_backbone();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7710,8 +7714,8 @@ YY_RULE_SETUP
   if (!AX_surfxml_link_bandwidth) FAIL("Required attribute `bandwidth' not set for `link' element.");
   LEAVE; STag_surfxml_link(); surfxml_pcdata_ix = 0; ETag_surfxml_link(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7735,8 +7739,8 @@ YY_RULE_SETUP
   ETag_surfxml_link();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_11: case S_surfxml_AS_10: case S_surfxml_AS: SET(S_surfxml_AS_11); break;
-   case S_surfxml_AS_2: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
+   case S_surfxml_AS_5: case S_surfxml_AS_6: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS_13: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_14); break;
   }
  }
        YY_BREAK
@@ -7820,7 +7824,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_route_dst) FAIL("Required attribute `dst' not set for `route' element.");
   LEAVE; STag_surfxml_route(); surfxml_pcdata_ix = 0; ETag_surfxml_route(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_11: case S_surfxml_AS_13: case S_surfxml_AS: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS: case S_surfxml_AS_15: case S_surfxml_AS_3: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
   }
  }
        YY_BREAK
@@ -7844,7 +7848,7 @@ YY_RULE_SETUP
   ETag_surfxml_route();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_11: case S_surfxml_AS_13: case S_surfxml_AS: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS: case S_surfxml_AS_15: case S_surfxml_AS_3: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
   }
  }
        YY_BREAK
@@ -7954,7 +7958,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_ASroute_gw_dst) FAIL("Required attribute `gw_dst' not set for `ASroute' element.");
   LEAVE; STag_surfxml_ASroute(); surfxml_pcdata_ix = 0; ETag_surfxml_ASroute(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
   }
  }
        YY_BREAK
@@ -7978,7 +7982,7 @@ YY_RULE_SETUP
   ETag_surfxml_ASroute();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
   }
  }
        YY_BREAK
@@ -8153,7 +8157,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_bypassRoute_dst) FAIL("Required attribute `dst' not set for `bypassRoute' element.");
   LEAVE; STag_surfxml_bypassRoute(); surfxml_pcdata_ix = 0; ETag_surfxml_bypassRoute(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_11: case S_surfxml_AS_13: case S_surfxml_AS: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS: case S_surfxml_AS_15: case S_surfxml_AS_3: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
   }
  }
        YY_BREAK
@@ -8177,7 +8181,7 @@ YY_RULE_SETUP
   ETag_surfxml_bypassRoute();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_12: case S_surfxml_AS_9: case S_surfxml_AS_11: case S_surfxml_AS_13: case S_surfxml_AS: SET(S_surfxml_AS_13); break;
+   case S_surfxml_AS_12: case S_surfxml_AS_1: case S_surfxml_AS_14: case S_surfxml_AS: case S_surfxml_AS_15: case S_surfxml_AS_3: case S_surfxml_AS_16: SET(S_surfxml_AS_16); break;
   }
  }
        YY_BREAK
@@ -8272,7 +8276,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_bypassASroute_gw_dst) FAIL("Required attribute `gw_dst' not set for `bypassASroute' element.");
   LEAVE; STag_surfxml_bypassASroute(); surfxml_pcdata_ix = 0; ETag_surfxml_bypassASroute(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
   }
  }
        YY_BREAK
@@ -8296,7 +8300,7 @@ YY_RULE_SETUP
   ETag_surfxml_bypassASroute();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_AS_1: case S_surfxml_AS_5: case S_surfxml_AS: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_6); break;
+   case S_surfxml_AS_9: case S_surfxml_AS_1: case S_surfxml_AS: case S_surfxml_AS_8: case S_surfxml_AS_4: case S_surfxml_AS_6: case S_surfxml_AS_3: SET(S_surfxml_AS_9); break;
   }
  }
        YY_BREAK
@@ -8653,7 +8657,7 @@ YY_RULE_SETUP
   if (!AX_surfxml_prop_value) FAIL("Required attribute `value' not set for `prop' element.");
   LEAVE; STag_surfxml_prop(); surfxml_pcdata_ix = 0; ETag_surfxml_prop(); popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_random: case S_surfxml_random_2: case S_surfxml_random_1: SET(S_surfxml_random_2); break;
+   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
    case S_surfxml_storage_1: case S_surfxml_storage_2: case S_surfxml_storage: SET(S_surfxml_storage_2); break;
    case S_surfxml_config_1: case S_surfxml_config: case S_surfxml_config_2: SET(S_surfxml_config_2); break;
    case S_surfxml_process_1: case S_surfxml_process: case S_surfxml_process_2: SET(S_surfxml_process_2); break;
@@ -8683,7 +8687,7 @@ YY_RULE_SETUP
   ETag_surfxml_prop();
   popbuffer(); /* attribute */
   switch (YY_START) {
-   case S_surfxml_random: case S_surfxml_random_2: case S_surfxml_random_1: SET(S_surfxml_random_2); break;
+   case S_surfxml_AS_2: case S_surfxml_AS: case S_surfxml_AS_3: SET(S_surfxml_AS_3); break;
    case S_surfxml_storage_1: case S_surfxml_storage_2: case S_surfxml_storage: SET(S_surfxml_storage_2); break;
    case S_surfxml_config_1: case S_surfxml_config: case S_surfxml_config_2: SET(S_surfxml_config_2); break;
    case S_surfxml_process_1: case S_surfxml_process: case S_surfxml_process_2: SET(S_surfxml_process_2); break;
@@ -8829,12 +8833,12 @@ case YY_STATE_EOF(S_surfxml_platform_2):
 case YY_STATE_EOF(S_surfxml_platform_5):
 case YY_STATE_EOF(S_surfxml_platform_7):
 case YY_STATE_EOF(S_surfxml_include_1):
-case YY_STATE_EOF(S_surfxml_random_1):
 case YY_STATE_EOF(S_surfxml_AS_2):
 case YY_STATE_EOF(S_surfxml_AS_5):
-case YY_STATE_EOF(S_surfxml_AS_7):
+case YY_STATE_EOF(S_surfxml_AS_8):
 case YY_STATE_EOF(S_surfxml_AS_10):
-case YY_STATE_EOF(S_surfxml_AS_12):
+case YY_STATE_EOF(S_surfxml_AS_13):
+case YY_STATE_EOF(S_surfxml_AS_15):
 case YY_STATE_EOF(S_surfxml_storage_type_1):
 case YY_STATE_EOF(S_surfxml_storage_1):
 case YY_STATE_EOF(S_surfxml_host_1):
@@ -9136,7 +9140,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 >= 3217 )
+                       if ( yy_current_state >= 3218 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -9164,11 +9168,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 >= 3217 )
+               if ( yy_current_state >= 3218 )
                        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 == 3216);
+       yy_is_jam = (yy_current_state == 3217);
 
        return yy_is_jam ? 0 : yy_current_state;
 }
index 7aed75e..107208b 100644 (file)
@@ -38,6 +38,7 @@ static xbt_dynar_t storage_list;
 static xbt_dict_t parse_storage_content(char *filename, unsigned long *used_size);
 static void storage_action_state_set(surf_action_t action, e_surf_action_state_t state);
 static surf_action_t storage_action_execute (void *storage, double size, e_surf_action_storage_type_t type);
+static void free_storage_content(void *p);
 
 static surf_action_t storage_action_stat(void *storage, surf_file_t stream)
 {
@@ -47,12 +48,84 @@ static surf_action_t storage_action_stat(void *storage, surf_file_t stream)
   return action;
 }
 
+static surf_action_t storage_action_ls(void *storage, const char* path)
+{
+  surf_action_t action = storage_action_execute(storage,0, LS);
+  action->ls_dict = NULL;
+  xbt_dict_t ls_dict = xbt_dict_new();
+
+  char* key;
+  surf_stat_t data = NULL;
+  xbt_dict_cursor_t cursor = NULL;
+
+  xbt_dynar_t dyn = NULL;
+  char* file = NULL;
+
+  // foreach file int the storage
+  xbt_dict_foreach(((storage_t)storage)->content,cursor,key,data){
+    // Search if file start with the prefix 'path'
+    if(xbt_str_start_with(key,path)){
+      file = &key[strlen(path)];
+
+      // Split file with '/'
+      dyn = xbt_str_split(file,"/");
+      file = xbt_dynar_get_as(dyn,0,char*);
+
+      // file
+      if(xbt_dynar_length(dyn) == 1){
+        xbt_dict_set(ls_dict,file,&(data->stat),NULL);
+      }
+      // Directory
+      else
+      {
+        // if directory does not exist yet in dict
+        if(!xbt_dict_get_or_null(ls_dict,file));
+          xbt_dict_set(ls_dict,file,NULL,NULL);
+      }
+      xbt_dynar_free(&dyn);
+    }
+  }
+
+  action->ls_dict = ls_dict;
+  return action;
+}
+
+static surf_action_t storage_action_unlink(void *storage, surf_file_t stream)
+{
+  surf_action_t action = storage_action_execute(storage,0, UNLINK);
+
+  // Add memory to storage
+  ((storage_t)storage)->used_size -= stream->content->stat.size;
+
+  // Remove the file from storage
+  xbt_dict_t content_dict = ((storage_t)storage)->content;
+  xbt_dict_remove(content_dict,stream->name);
+
+  free(stream->name);
+  stream->content = NULL;
+  xbt_free(stream);
+
+  return action;
+}
+
 static surf_action_t storage_action_open(void *storage, const char* mount, const char* path, const char* mode)
 {
   XBT_DEBUG("\tOpen file '%s'",path);
   xbt_dict_t content_dict = ((storage_t)storage)->content;
-  surf_stat_t content = xbt_dict_get(content_dict,path);
+  surf_stat_t content = xbt_dict_get_or_null(content_dict,path);
 
+  // if file does not exist create an empty file
+  if(!content){
+    content = xbt_new0(s_surf_stat_t,1);
+    content->stat.date = xbt_strdup("");
+    content->stat.group = xbt_strdup("");
+    content->stat.size = 0;
+    content->stat.time = xbt_strdup("");
+    content->stat.user = xbt_strdup("");
+    content->stat.user_rights = xbt_strdup("");
+    xbt_dict_set(content_dict,path,content,NULL);
+    XBT_DEBUG("File '%s' was not found, file created.",path);
+  }
   surf_file_t file = xbt_new0(s_surf_file_t,1);
   file->name = xbt_strdup(path);
   file->content = content;
@@ -125,6 +198,8 @@ static surf_action_t storage_action_execute (void *storage, double size, e_surf_
   case OPEN:
   case CLOSE:
   case STAT:
+  case UNLINK:
+  case LS:
     break;
   case READ:
     lmm_expand(storage_maxmin_system, STORAGE->constraint_read,
@@ -134,7 +209,6 @@ static surf_action_t storage_action_execute (void *storage, double size, e_surf_
     lmm_expand(storage_maxmin_system, STORAGE->constraint_write,
                GENERIC_LMM_ACTION(action).variable, 1.0);
     xbt_dynar_push(((storage_t)storage)->write_actions,&action);
-
     break;
   }
   action->type = type;
@@ -177,7 +251,7 @@ static void* storage_create_resource(const char* id, const char* model,const cha
       storage_type->properties,
       Bread);
 
-  if(!storage_list) storage_list=xbt_dynar_new(sizeof(char *),free);
+  if(!storage_list) storage_list=xbt_dynar_new(sizeof(char *),NULL);
   xbt_dynar_push(storage_list,&storage);
 
   return storage;
@@ -191,6 +265,9 @@ static void storage_finalize(void)
   surf_model_exit(surf_storage_model);
   surf_storage_model = NULL;
 
+  if(storage_list)
+    xbt_dynar_free(&storage_list);
+
   xbt_swag_free
       (storage_running_action_set_that_does_not_need_being_checked);
   storage_running_action_set_that_does_not_need_being_checked = NULL;
@@ -427,6 +504,8 @@ static void surf_storage_model_init_internal(void)
   surf_storage_model->extension.storage.read = storage_action_read;
   surf_storage_model->extension.storage.write = storage_action_write;
   surf_storage_model->extension.storage.stat = storage_action_stat;
+  surf_storage_model->extension.storage.unlink = storage_action_unlink;
+  surf_storage_model->extension.storage.ls = storage_action_ls;
   surf_storage_model->extension.storage.create_resource = storage_create_resource;
 
   if (!storage_maxmin_system) {
@@ -608,6 +687,7 @@ static XBT_INLINE void surf_storage_resource_free(void *r)
   // specific to storage
   storage_t storage = r;
   xbt_dict_free(&storage->content);
+  xbt_dynar_free(&storage->write_actions);
   // generic resource
   surf_resource_free(r);
 }
index f27d650..c62f265 100644 (file)
@@ -45,7 +45,7 @@ typedef struct storage {
 } s_storage_t, *storage_t;
 
 typedef enum {
-  READ=0, WRITE, STAT, OPEN, CLOSE
+  READ=0, WRITE, STAT, OPEN, CLOSE, UNLINK, LS
 } e_surf_action_storage_type_t;
 
 typedef struct surf_action_storage {
index be19fb7..19e441e 100644 (file)
@@ -369,6 +369,12 @@ static XBT_INLINE void routing_asr_host_free(void *p)
   xbt_free(elm);
 }
 
+static XBT_INLINE void routing_asr_prop_free(void *p)
+{
+  xbt_dict_t elm = p;
+  xbt_dict_free(&elm);
+}
+
 void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
   *ver_major = SIMGRID_VERSION_MAJOR;
   *ver_minor = SIMGRID_VERSION_MINOR;
@@ -388,6 +394,7 @@ void surf_init(int *argc, char **argv)
   XBT_DEBUG("Add routing levels");
   ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
   ROUTING_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
+  ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
 
   XBT_DEBUG("Add SURF levels");
   SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_resource_free);
index 24cc5e4..4d286c2 100644 (file)
@@ -610,6 +610,12 @@ void surf_config_init(int *argc, char **argv)
                      xbt_cfgelm_double, &default_threshold, 1, 1, NULL,
                      NULL);
 
+    int default_small_messages_threshold = 0;
+    xbt_cfg_register(&_surf_cfg_set, "smpi/async_small_thres",
+                     "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
+                     xbt_cfgelm_int, &default_small_messages_threshold, 1, 1, NULL,
+                     NULL);
+
     //For smpi/bw_factor and smpi/lat_factor
     //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
     //test is if( size >= thresholdN ) return valueN;
index 6e87529..6588dab 100644 (file)
@@ -132,7 +132,7 @@ typedef struct s_routing_edge {
   e_surf_network_element_type_t rc_type;
   int id;
   char *name;
-} s_network_element_t;
+} s_routing_edge_t;
 
 /*
  * Link of lenght 1, alongside with its source and destination. This is mainly usefull in the bindings to gtnets and ns3
@@ -154,12 +154,6 @@ typedef struct s_model_type {
   void (*end) (AS_t as);
 } s_routing_model_description_t, *routing_model_description_t;
 
-typedef struct s_route {
-  xbt_dynar_t link_list;
-  sg_routing_edge_t src_gateway;
-  sg_routing_edge_t dst_gateway;
-} s_route_t, *route_t;
-
 /* This enum used in the routing structure helps knowing in which situation we are. */
 typedef enum {
   SURF_ROUTING_NULL = 0,   /**< Undefined type                                   */
@@ -178,10 +172,10 @@ typedef struct s_as {
   sg_routing_edge_t net_elem;
   xbt_dynar_t link_up_down_list;
 
-  void (*get_route_and_latency) (AS_t as, sg_routing_edge_t src, sg_routing_edge_t dst, route_t into, double *latency);
+  void (*get_route_and_latency) (AS_t as, sg_routing_edge_t src, sg_routing_edge_t dst, sg_platf_route_cbarg_t into, double *latency);
 
   xbt_dynar_t(*get_onelink_routes) (AS_t as);
-  route_t(*get_bypass_route) (AS_t as, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat);
+  sg_platf_route_cbarg_t(*get_bypass_route) (AS_t as, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat);
   void (*finalize) (AS_t as);
 
 
@@ -191,12 +185,10 @@ typedef struct s_as {
    * Of course, only the routing model of this AS is informed, not every ones */
   int (*parse_PU) (AS_t as, sg_routing_edge_t elm); /* A host or a router, whatever */
   int (*parse_AS) (AS_t as, sg_routing_edge_t elm);
-  void (*parse_route) (AS_t as, const char *src,
-                     const char *dst, route_t route);
-  void (*parse_ASroute) (AS_t as, const char *src,
-                       const char *dst, route_t route);
-  void (*parse_bypassroute) (AS_t as, const char *src,
-                           const char *dst, route_t e_route);
+  void (*parse_route) (AS_t as, sg_platf_route_cbarg_t route);
+  void (*parse_ASroute) (AS_t as, sg_platf_route_cbarg_t route);
+  void (*parse_bypassroute) (AS_t as, sg_platf_route_cbarg_t e_route);
+
 } s_as_t;
 
 struct s_routing_platf {
@@ -210,7 +202,7 @@ XBT_PUBLIC(void) routing_model_create(void *loopback);
 XBT_PUBLIC(void) routing_exit(void);
 XBT_PUBLIC(void) storage_register_callbacks(void);
 XBT_PUBLIC(void) routing_register_callbacks(void);
-XBT_PUBLIC(void) generic_free_route(route_t route); // FIXME rename to routing_route_free
+XBT_PUBLIC(void) generic_free_route(sg_platf_route_cbarg_t route); // FIXME rename to routing_route_free
  // FIXME: make previous function private to routing again?
 
 
index 098651b..8561b86 100644 (file)
@@ -42,6 +42,7 @@ xbt_lib_t as_router_lib;
 int ROUTING_ASR_LEVEL;          //Routing level
 int COORD_ASR_LEVEL;            //Coordinates level
 int NS3_ASR_LEVEL;              //host node for ns3
+int ROUTING_PROP_ASR_LEVEL;     //Where the properties are stored
 
 static xbt_dict_t random_value = NULL;
 
@@ -60,14 +61,8 @@ routing_platf_t routing_platf = NULL;
 AS_t current_routing = NULL;
 
 /* global parse functions */
-xbt_dynar_t parsed_link_list = NULL;   /* temporary store of current list link of a route */
 extern xbt_dynar_t mount_list;
 
-static const char *src = NULL;  /* temporary store the source name of a route */
-static const char *dst = NULL;  /* temporary store the destination name of a route */
-static char *gw_src = NULL;     /* temporary store the gateway source name of a route */
-static char *gw_dst = NULL;     /* temporary store the gateway destination name of a route */
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
 
 static void routing_parse_peer(sg_platf_peer_cbarg_t peer);     /* peer bypass */
@@ -153,7 +148,7 @@ static void parse_S_host(sg_platf_host_cbarg_t host)
   xbt_assert(!xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL),
              "Reading a host, processing unit \"%s\" already exists", host->id);
 
-  info = xbt_new0(s_network_element_t, 1);
+  info = xbt_new0(s_routing_edge_t, 1);
   info->rc_component = current_routing;
   info->rc_type = SURF_NETWORK_ELEMENT_HOST;
   info->name = xbt_strdup(host->id);
@@ -198,7 +193,7 @@ static void parse_S_router(sg_platf_router_cbarg_t router)
              "Reading a router, processing unit \"%s\" already exists",
              router->id);
 
-  info = xbt_new0(s_network_element_t, 1);
+  info = xbt_new0(s_routing_edge_t, 1);
   info->rc_component = current_routing;
   info->rc_type = SURF_NETWORK_ELEMENT_ROUTER;
   info->name = xbt_strdup(router->id);
@@ -206,7 +201,7 @@ static void parse_S_router(sg_platf_router_cbarg_t router)
   xbt_lib_set(as_router_lib, router->id, ROUTING_ASR_LEVEL, (void *) info);
   XBT_DEBUG("Having set name '%s' id '%d'",router->id,info->id);
 
-  if (strcmp(router->coord, "")) {
+  if (router->coord && strcmp(router->coord, "")) {
     unsigned int cursor;
     char*str;
 
@@ -226,171 +221,104 @@ static void parse_S_router(sg_platf_router_cbarg_t router)
   }
 }
 
-
-/**
- * \brief Set the end points for a route
- */
-static void routing_parse_S_route(void)
-{
-  src = A_surfxml_route_src;
-  dst = A_surfxml_route_dst;
-  xbt_assert(strlen(src) > 0 || strlen(dst) > 0,
-             "Missing end-points while defining route \"%s\"->\"%s\"",
-             src, dst);
-  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
-}
-
-/**
- * \brief Set the end points and gateways for a ASroute
- */
-static void routing_parse_S_ASroute(void)
-{
-  src = A_surfxml_ASroute_src;
-  dst = A_surfxml_ASroute_dst;
-  gw_src = A_surfxml_ASroute_gw_src;
-  gw_dst = A_surfxml_ASroute_gw_dst;
-  xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0 || strlen(gw_dst) > 0,
-             "Missing end-points while defining route \"%s\"->\"%s\" (with %s and %s as gateways)",
-             src, dst,gw_src,gw_dst);
-  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
-}
-
-/**
- * \brief Set the end points for a bypassRoute
- */
-static void routing_parse_S_bypassRoute(void)
-{
-  src = A_surfxml_bypassRoute_src;
-  dst = A_surfxml_bypassRoute_dst;
-  gw_src = NULL;
-  gw_dst = NULL;
-  xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0 || strlen(gw_dst) > 0,
-             "Missing end-points while defining route \"%s\"->\"%s\" (with %s and %s as gateways)",
-             src, dst,gw_src,gw_dst);
-  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
-}
-
-/**
- * \brief Set the end points for a bypassASroute
- */
-static void routing_parse_S_bypassASroute(void)
-{
-  src = A_surfxml_bypassASroute_src;
-  dst = A_surfxml_bypassASroute_dst;
-  gw_src = A_surfxml_bypassASroute_gw_src;
-  gw_dst = A_surfxml_bypassASroute_gw_dst;
-  xbt_assert(strlen(src) > 0 || strlen(dst) > 0 || strlen(gw_src) > 0 || strlen(gw_dst) > 0,
-             "Missing end-points while defining route \"%s\"->\"%s\" (with %s and %s as gateways)",
-             src, dst,gw_src,gw_dst);
-  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
-}
-/**
- * \brief Set a new link on the actual list of link for a route or ASroute from XML
- */
-
-static void routing_parse_link_ctn(void)
-{
-  char *link_id;
-  switch (A_surfxml_link_ctn_direction) {
-  case AU_surfxml_link_ctn_direction:
-  case A_surfxml_link_ctn_direction_NONE:
-    link_id = xbt_strdup(A_surfxml_link_ctn_id);
-    break;
-  case A_surfxml_link_ctn_direction_UP:
-    link_id = bprintf("%s_UP", A_surfxml_link_ctn_id);
-    break;
-  case A_surfxml_link_ctn_direction_DOWN:
-    link_id = bprintf("%s_DOWN", A_surfxml_link_ctn_id);
-    break;
-  }
-  xbt_dynar_push(parsed_link_list, &link_id);
-}
-
 /**
  * \brief Store the route by calling the set_route function of the current routing component
  */
-static void routing_parse_E_route(void)
+static void parse_E_route(sg_platf_route_cbarg_t route)
 {
-  route_t route = xbt_new0(s_route_t, 1);
-  route->link_list = parsed_link_list;
   xbt_assert(current_routing->parse_route,
              "no defined method \"set_route\" in \"%s\"",
              current_routing->name);
-  current_routing->parse_route(current_routing, src, dst, route);
-  generic_free_route(route);
-  parsed_link_list = NULL;
-  src = NULL;
-  dst = NULL;
+
+  current_routing->parse_route(current_routing, route);
 }
 
 /**
  * \brief Store the ASroute by calling the set_ASroute function of the current routing component
  */
-static void routing_parse_E_ASroute(void)
+static void parse_E_ASroute(sg_platf_route_cbarg_t ASroute)
 {
-  route_t e_route = xbt_new0(s_route_t, 1);
-  e_route->link_list = parsed_link_list;
-
-  if (!strcmp(current_routing->model_desc->name,"RuleBased")) {
-    // DIRTY PERL HACK AHEAD: with the rulebased routing, the {src,dst}_gateway fields
-    // store the provided name instead of the entity directly (model_rulebased_parse_ASroute knows)
-    //
-    // This is because the user will provide something like "^AS_(.*)$" instead of the proper name of a given entity
-    e_route->src_gateway = (sg_routing_edge_t) gw_src;
-    e_route->dst_gateway = (sg_routing_edge_t) gw_dst;
-  } else {
-    e_route->src_gateway = sg_routing_edge_by_name_or_null(gw_src);
-    e_route->dst_gateway = sg_routing_edge_by_name_or_null(gw_dst);
-  }
   xbt_assert(current_routing->parse_ASroute,
              "no defined method \"set_ASroute\" in \"%s\"",
              current_routing->name);
-  current_routing->parse_ASroute(current_routing, src, dst, e_route);
-  generic_free_route(e_route);
-  parsed_link_list = NULL;
-  src = NULL;
-  dst = NULL;
-  gw_src = NULL;
-  gw_dst = NULL;
+  current_routing->parse_ASroute(current_routing, ASroute);
 }
 
 /**
  * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
  */
-static void routing_parse_E_bypassRoute(void)
+static void parse_E_bypassRoute(sg_platf_route_cbarg_t route)
 {
-  route_t e_route = xbt_new0(s_route_t, 1);
-  e_route->link_list = parsed_link_list;
-
   xbt_assert(current_routing->parse_bypassroute,
              "Bypassing mechanism not implemented by routing '%s'",
              current_routing->name);
 
-  current_routing->parse_bypassroute(current_routing, src, dst, e_route);
-  parsed_link_list = NULL;
-  src = NULL;
-  dst = NULL;
-  gw_src = NULL;
-  gw_dst = NULL;
+  current_routing->parse_bypassroute(current_routing, route);
 }
+
 /**
  * \brief Store the bypass route by calling the set_bypassroute function of the current routing component
  */
-static void routing_parse_E_bypassASroute(void)
+static void parse_E_bypassASroute(sg_platf_route_cbarg_t ASroute)
 {
-  route_t e_route = xbt_new0(s_route_t, 1);
-  e_route->link_list = parsed_link_list;
-  e_route->src_gateway = sg_routing_edge_by_name_or_null(gw_src);
-  e_route->dst_gateway = sg_routing_edge_by_name_or_null(gw_dst);
   xbt_assert(current_routing->parse_bypassroute,
              "Bypassing mechanism not implemented by routing '%s'",
              current_routing->name);
-  current_routing->parse_bypassroute(current_routing, src, dst, e_route);
-  parsed_link_list = NULL;
-  src = NULL;
-  dst = NULL;
-  gw_src = NULL;
-  gw_dst = NULL;
+  current_routing->parse_bypassroute(current_routing, ASroute);
+}
+
+static void routing_parse_trace(sg_platf_trace_cbarg_t trace)
+{
+  tmgr_trace_t tmgr_trace;
+  if (!trace->file || strcmp(trace->file, "") != 0) {
+    tmgr_trace = tmgr_trace_new_from_file(trace->file);
+  } else if (strcmp(trace->pc_data, "") == 0) {
+    tmgr_trace = NULL;
+  } else {
+    tmgr_trace =
+          tmgr_trace_new_from_string(trace->id, trace->pc_data,
+                                     trace->periodicity);
+  }
+  xbt_dict_set(traces_set_list, trace->id, (void *) tmgr_trace, NULL);
+}
+
+static void routing_parse_trace_connect(sg_platf_trace_connect_cbarg_t trace_connect)
+{
+  xbt_assert(xbt_dict_get_or_null
+              (traces_set_list, trace_connect->trace),
+              "Cannot connect trace %s to %s: trace unknown",
+              trace_connect->trace,
+              trace_connect->element);
+
+  switch (trace_connect->kind) {
+  case SURF_TRACE_CONNECT_KIND_HOST_AVAIL:
+    xbt_dict_set(trace_connect_list_host_avail,
+        trace_connect->trace,
+        xbt_strdup(trace_connect->element), NULL);
+    break;
+  case SURF_TRACE_CONNECT_KIND_POWER:
+    xbt_dict_set(trace_connect_list_power, trace_connect->trace,
+        xbt_strdup(trace_connect->element), NULL);
+    break;
+  case SURF_TRACE_CONNECT_KIND_LINK_AVAIL:
+    xbt_dict_set(trace_connect_list_link_avail,
+        trace_connect->trace,
+        xbt_strdup(trace_connect->element), NULL);
+    break;
+  case SURF_TRACE_CONNECT_KIND_BANDWIDTH:
+    xbt_dict_set(trace_connect_list_bandwidth,
+        trace_connect->trace,
+        xbt_strdup(trace_connect->element), NULL);
+    break;
+  case SURF_TRACE_CONNECT_KIND_LATENCY:
+    xbt_dict_set(trace_connect_list_latency, trace_connect->trace,
+        xbt_strdup(trace_connect->element), NULL);
+    break;
+  default:
+    xbt_die("Cannot connect trace %s to %s: kind of trace unknown",
+        trace_connect->trace, trace_connect->element);
+    break;
+  }
 }
 
 /**
@@ -406,17 +334,18 @@ static void routing_parse_E_bypassASroute(void)
  * @param AS_id name of this autonomous system. Must be unique in the platform
  * @param wanted_routing_type one of Full, Floyd, Dijkstra or similar. Full list in the variable routing_models, in src/surf/surf_routing.c
  */
-void routing_AS_begin(const char *AS_id, int wanted_routing_type)
+void routing_AS_begin(sg_platf_AS_cbarg_t AS)
 {
+  XBT_DEBUG("routing_AS_begin");
   AS_t new_as;
   routing_model_description_t model = NULL;
 
   xbt_assert(!xbt_lib_get_or_null
-             (as_router_lib, AS_id, ROUTING_ASR_LEVEL),
-             "The AS \"%s\" already exists", AS_id);
+             (as_router_lib, AS->id, ROUTING_ASR_LEVEL),
+             "The AS \"%s\" already exists", AS->id);
 
   /* search the routing model */
-  switch(wanted_routing_type){
+  switch(AS->routing){
     case A_surfxml_AS_routing_Cluster:       model = &routing_models[SURF_MODEL_CLUSTER];break;
     case A_surfxml_AS_routing_Dijkstra:      model = &routing_models[SURF_MODEL_DIJKSTRA];break;
     case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break;
@@ -425,16 +354,18 @@ void routing_AS_begin(const char *AS_id, int wanted_routing_type)
     case A_surfxml_AS_routing_None:          model = &routing_models[SURF_MODEL_NONE];break;
     case A_surfxml_AS_routing_RuleBased:     model = &routing_models[SURF_MODEL_RULEBASED];break;
     case A_surfxml_AS_routing_Vivaldi:       model = &routing_models[SURF_MODEL_VIVALDI];break;
+    default: xbt_die("Not a valid model!!!");
+    break;
   }
 
   /* make a new routing component */
   new_as = (AS_t) model->create();
   new_as->model_desc = model;
   new_as->hierarchy = SURF_ROUTING_NULL;
-  new_as->name = xbt_strdup(AS_id);
+  new_as->name = xbt_strdup(AS->id);
 
   sg_routing_edge_t info = NULL;
-  info = xbt_new0(s_network_element_t, 1);
+  info = xbt_new0(s_routing_edge_t, 1);
 
   if (current_routing == NULL && routing_platf->root == NULL) {
 
@@ -445,15 +376,15 @@ void routing_AS_begin(const char *AS_id, int wanted_routing_type)
   } else if (current_routing != NULL && routing_platf->root != NULL) {
 
     xbt_assert(!xbt_dict_get_or_null
-               (current_routing->routing_sons, AS_id),
-               "The AS \"%s\" already exists", AS_id);
+               (current_routing->routing_sons, AS->id),
+               "The AS \"%s\" already exists", AS->id);
     /* it is a part of the tree */
     new_as->routing_father = current_routing;
     /* set the father behavior */
     if (current_routing->hierarchy == SURF_ROUTING_NULL)
       current_routing->hierarchy = SURF_ROUTING_RECURSIVE;
     /* add to the sons dictionary */
-    xbt_dict_set(current_routing->routing_sons, AS_id,
+    xbt_dict_set(current_routing->routing_sons, AS->id,
                  (void *) new_as, NULL);
     /* add to the father element list */
     info->id = current_routing->parse_AS(current_routing, (void *) info);
@@ -465,7 +396,7 @@ void routing_AS_begin(const char *AS_id, int wanted_routing_type)
   info->rc_type = SURF_NETWORK_ELEMENT_AS;
   info->name = new_as->name;
 
-  xbt_lib_set(as_router_lib, new_as->name, ROUTING_ASR_LEVEL,
+  xbt_lib_set(as_router_lib, info->name, ROUTING_ASR_LEVEL,
               (void *) info);
   XBT_DEBUG("Having set name '%s' id '%d'",new_as->name,info->id);
 
@@ -486,7 +417,7 @@ void routing_AS_begin(const char *AS_id, int wanted_routing_type)
  * even if you add stuff to a closed AS
  *
  */
-void routing_AS_end()
+void routing_AS_end(sg_platf_AS_cbarg_t AS)
 {
 
   if (current_routing == NULL) {
@@ -587,11 +518,11 @@ static void elements_father(sg_routing_edge_t src, sg_routing_edge_t dst,
 static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
                                    xbt_dynar_t * links, double *latency)
 {
-  s_route_t route;
+  s_sg_platf_route_cbarg_t route;
   memset(&route,0,sizeof(route));
 
-  XBT_DEBUG("Solve route/latency  \"%s\" to \"%s\"", src->name, dst->name);
   xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
+  XBT_DEBUG("Solve route/latency  \"%s\" to \"%s\"", src->name, dst->name);
 
   /* Find how src and dst are interconnected */
   AS_t common_father, src_father, dst_father;
@@ -600,7 +531,7 @@ static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
       common_father->name,src_father->name,dst_father->name);
 
   /* Check whether a direct bypass is defined */
-  route_t e_route_bypass = NULL;
+  sg_platf_route_cbarg_t e_route_bypass = NULL;
   if (common_father->get_bypass_route)
     e_route_bypass = common_father->get_bypass_route(common_father, src, dst, latency);
 
@@ -630,11 +561,11 @@ static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
                                        src_father_net_elm, dst_father_net_elm,
                                        &route, latency);
 
-  xbt_assert((route.src_gateway != NULL) && (route.dst_gateway != NULL),
+  xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
       "bad gateways for route from \"%s\" to \"%s\"", src->name, dst->name);
 
-  sg_routing_edge_t src_gateway_net_elm = route.src_gateway;
-  sg_routing_edge_t dst_gateway_net_elm = route.dst_gateway;
+  sg_routing_edge_t src_gateway_net_elm = route.gw_src;
+  sg_routing_edge_t dst_gateway_net_elm = route.gw_dst;
 
   /* If source gateway is not our source, we have to recursively find our way up to this point */
   if (src != src_gateway_net_elm)
@@ -867,8 +798,8 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
   xbt_dynar_t radical_elements;
   xbt_dynar_t radical_ends;
 
-  if (strcmp(cluster->availability_trace, "")
-      || strcmp(cluster->state_trace, "")) {
+  if ((cluster->availability_trace && strcmp(cluster->availability_trace, ""))
+      || (cluster->state_trace && strcmp(cluster->state_trace, ""))) {
     patterns = xbt_dict_new_homogeneous(xbt_free_f);
     xbt_dict_set(patterns, "id", xbt_strdup(cluster->id), NULL);
     xbt_dict_set(patterns, "prefix", xbt_strdup(cluster->prefix), NULL);
@@ -876,7 +807,10 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
   }
 
   XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", cluster->id);
-  sg_platf_new_AS_begin(cluster->id, A_surfxml_AS_routing_Cluster);
+  s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+  AS.id = cluster->id;
+  AS.routing = A_surfxml_AS_routing_Cluster;
+  sg_platf_new_AS_begin(&AS);
 
   current_routing->link_up_down_list
             = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
@@ -908,7 +842,7 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
 
       memset(&host, 0, sizeof(host));
       host.id = host_id;
-      if (strcmp(cluster->availability_trace, "")) {
+      if (cluster->availability_trace && strcmp(cluster->availability_trace, "")) {
         xbt_dict_set(patterns, "radical", bprintf("%d", i), NULL);
         char *avail_file = xbt_str_varsubst(cluster->availability_trace, patterns);
         XBT_DEBUG("\tavailability_file=\"%s\"", avail_file);
@@ -918,7 +852,7 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
         XBT_DEBUG("\tavailability_file=\"\"");
       }
 
-      if (strcmp(cluster->state_trace, "")) {
+      if (cluster->state_trace && strcmp(cluster->state_trace, "")) {
         char *avail_file = xbt_str_varsubst(cluster->state_trace, patterns);
         XBT_DEBUG("\tstate_file=\"%s\"", avail_file);
         host.state_trace = tmgr_trace_new_from_file(avail_file);
@@ -1200,24 +1134,10 @@ void routing_register_callbacks()
   sg_platf_host_add_cb(parse_S_host);
   sg_platf_router_add_cb(parse_S_router);
   sg_platf_host_link_add_cb(parse_S_host_link);
-
-  surfxml_add_callback(STag_surfxml_random_cb_list, &routing_parse_Srandom);
-
-  surfxml_add_callback(STag_surfxml_route_cb_list, &routing_parse_S_route);
-  surfxml_add_callback(STag_surfxml_ASroute_cb_list, &routing_parse_S_ASroute);
-  surfxml_add_callback(STag_surfxml_bypassRoute_cb_list,
-                       &routing_parse_S_bypassRoute);
-  surfxml_add_callback(STag_surfxml_bypassASroute_cb_list,
-                       &routing_parse_S_bypassASroute);
-
-  surfxml_add_callback(ETag_surfxml_link_ctn_cb_list, &routing_parse_link_ctn);
-
-  surfxml_add_callback(ETag_surfxml_route_cb_list, &routing_parse_E_route);
-  surfxml_add_callback(ETag_surfxml_ASroute_cb_list, &routing_parse_E_ASroute);
-  surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list,
-                       &routing_parse_E_bypassRoute);
-  surfxml_add_callback(ETag_surfxml_bypassASroute_cb_list,
-                       &routing_parse_E_bypassASroute);
+  sg_platf_route_add_cb(parse_E_route);
+  sg_platf_ASroute_add_cb(parse_E_ASroute);
+  sg_platf_bypassRoute_add_cb(parse_E_bypassRoute);
+  sg_platf_bypassASroute_add_cb(parse_E_bypassASroute);
 
   sg_platf_cluster_add_cb(routing_parse_cluster);
   sg_platf_cabinet_add_cb(routing_parse_cabinet);
@@ -1229,6 +1149,9 @@ void routing_register_callbacks()
   sg_platf_AS_end_add_cb(routing_AS_end);
   sg_platf_AS_begin_add_cb(routing_AS_begin);
 
+  sg_platf_trace_add_cb(routing_parse_trace);
+  sg_platf_trace_connect_add_cb(routing_parse_trace_connect);
+
 #ifdef HAVE_TRACING
   instr_routing_define_callbacks();
 #endif
index d30668d..37f2e32 100644 (file)
@@ -16,7 +16,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster, surf, "Routing part of surf"
 /* Business methods */
 static void cluster_get_route_and_latency(AS_t as,
     sg_routing_edge_t src, sg_routing_edge_t dst,
-                                          route_t route, double *lat) {
+    sg_platf_route_cbarg_t route, double *lat) {
 
       s_surf_parsing_link_up_down_t info;
     XBT_DEBUG("cluster_get_route_and_latency from '%s'[%d] to '%s'[%d]",
index 2d7b1dd..7d7eac4 100644 (file)
@@ -53,7 +53,7 @@ static void graph_node_map_elem_free(void *e)
 
 static void graph_edge_data_free(void *e) // FIXME: useless code dupplication
 {
-  route_t e_route = (route_t) e;
+  sg_platf_route_cbarg_t e_route = (sg_platf_route_cbarg_t) e;
   if (e_route) {
     xbt_dynar_free(&(e_route->link_list));
     xbt_free(e_route);
@@ -95,7 +95,7 @@ graph_node_map_search(as_dijkstra_t as, int id)
 /* Parsing */
 
 static void route_new_dijkstra(as_dijkstra_t as, int src_id,
-    int dst_id, route_t e_route)
+    int dst_id, sg_platf_route_cbarg_t e_route)
 {
   XBT_DEBUG("Load Route from \"%d\" to \"%d\"", src_id, dst_id);
   xbt_node_t src = NULL;
@@ -154,7 +154,7 @@ static void add_loopback_dijkstra(as_dijkstra_t as) {
     }
 
     if (!found) {
-      route_t e_route = xbt_new0(s_route_t, 1);
+      sg_platf_route_cbarg_t e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
       e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
       xbt_dynar_push(e_route->link_list,
           &routing_platf->loopback);
@@ -164,12 +164,12 @@ static void add_loopback_dijkstra(as_dijkstra_t as) {
 }
 
 static void dijkstra_get_route_and_latency(AS_t as_generic,
-    sg_routing_edge_t src, sg_routing_edge_t dst, route_t route, double *lat);
+    sg_routing_edge_t src, sg_routing_edge_t dst, sg_platf_route_cbarg_t route, double *lat);
 
 static xbt_dynar_t dijkstra_get_onelink_routes(AS_t as)
 {
   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
-  route_t route = xbt_new0(s_route_t,1);
+  sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1);
   route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
 
   int src,dst;
@@ -190,8 +190,8 @@ static xbt_dynar_t dijkstra_get_onelink_routes(AS_t as)
           onelink->src = src_elm;
           onelink->dst = dst_elm;
         } else if (as->hierarchy == SURF_ROUTING_RECURSIVE) {
-          onelink->src = route->src_gateway;
-          onelink->dst = route->dst_gateway;
+          onelink->src = route->gw_src;
+          onelink->dst = route->gw_dst;
         }
         xbt_dynar_push(ret, &onelink);
       }
@@ -202,7 +202,7 @@ static xbt_dynar_t dijkstra_get_onelink_routes(AS_t as)
 
 static void dijkstra_get_route_and_latency(AS_t asg,
     sg_routing_edge_t src, sg_routing_edge_t dst,
-    route_t route, double *lat)
+    sg_platf_route_cbarg_t route, double *lat)
 {
 
   /* set utils vars */
@@ -220,7 +220,7 @@ static void dijkstra_get_route_and_latency(AS_t asg,
   int dst_node_id = 0;
   int *nodeid = NULL;
   int v;
-  route_t e_route;
+  sg_platf_route_cbarg_t e_route;
   int size = 0;
   unsigned int cpt;
   void *link;
@@ -250,7 +250,7 @@ static void dijkstra_get_route_and_latency(AS_t asg,
     if (edge == NULL)
       THROWF(arg_error,0,"No route from '%s' to '%s'",src->name,dst->name);
 
-    e_route = (route_t) xbt_graph_edge_get_data(edge);
+    e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
 
     links = e_route->link_list;
     xbt_dynar_foreach(links, cpt, link) {
@@ -309,7 +309,7 @@ static void dijkstra_get_route_and_latency(AS_t asg,
         xbt_node_t u_node = xbt_graph_edge_get_target(edge);
         graph_node_data_t data = xbt_graph_node_get_data(u_node);
         int u_id = data->graph_id;
-        route_t tmp_e_route = (route_t) xbt_graph_edge_get_data(edge);
+        sg_platf_route_cbarg_t tmp_e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
         int cost_v_u = (tmp_e_route->link_list)->used;    /* count of links, old model assume 1 */
 
         if (cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
@@ -345,9 +345,9 @@ static void dijkstra_get_route_and_latency(AS_t asg,
 
     prev_gw_src = gw_src;
 
-    e_route = (route_t) xbt_graph_edge_get_data(edge);
-    gw_src = e_route->src_gateway;
-    gw_dst = e_route->dst_gateway;
+    e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
+    gw_src = e_route->gw_src;
+    gw_dst = e_route->gw_dst;
 
     if (v == dst_node_id)
       first_gw = gw_dst;
@@ -378,8 +378,8 @@ static void dijkstra_get_route_and_latency(AS_t asg,
   }
 
   if (asg->hierarchy == SURF_ROUTING_RECURSIVE) {
-    route->src_gateway = gw_src;
-    route->dst_gateway = first_gw;
+    route->gw_src = gw_src;
+    route->gw_dst = first_gw;
   }
 
   if (as->cached && elm == NULL) {
@@ -466,20 +466,22 @@ void model_dijkstra_both_end(AS_t as)
   }
 
 }
-void model_dijkstra_both_parse_route (AS_t asg, const char *src,
-    const char *dst, route_t route)
+void model_dijkstra_both_parse_route (AS_t asg, sg_platf_route_cbarg_t route)
 {
+  char *src = (char*)(route->src);
+  char *dst = (char*)(route->dst);
+
   int as_route = 0;
-  if(!route->dst_gateway && !route->src_gateway)
+  if(!route->gw_dst && !route->gw_src)
     XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
   else{
     XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
-        route->src_gateway->name, dst, route->dst_gateway->name);
+        route->gw_src->name, dst, route->gw_dst->name);
     as_route = 1;
-    if(route->dst_gateway->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The dst_gateway '%s' does not exist!",route->dst_gateway->name);
-    if(route->src_gateway->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The src_gateway '%s' does not exist!",route->src_gateway->name);
+    if(route->gw_dst->rc_type == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The gw_dst '%s' does not exist!",route->gw_dst->name);
+    if(route->gw_src->rc_type == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The gw_src '%s' does not exist!",route->gw_src->name);
   }
 
   as_dijkstra_t as = (as_dijkstra_t) asg;
@@ -500,19 +502,19 @@ void model_dijkstra_both_parse_route (AS_t asg, const char *src,
   if (as->cached && !as->route_cache)
     as->route_cache = xbt_dict_new_homogeneous(&route_cache_elem_free);
 
-  route_t e_route = generic_new_extended_route(asg->hierarchy, route, 1);
+  sg_platf_route_cbarg_t e_route = generic_new_extended_route(asg->hierarchy, route, 1);
   route_new_dijkstra(as, src_net_elm->id, dst_net_elm->id, e_route);
 
   // Symmetrical YES
-  if ( (A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES && as_route == 0)
-      || (A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES && as_route == 1)
+  if ( (route->symmetrical == TRUE && as_route == 0)
+      || (route->symmetrical == TRUE && as_route == 1)
   )
   {
-    if(!route->dst_gateway && !route->src_gateway)
+    if(!route->gw_dst && !route->gw_src)
       XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
     else
       XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
-          route->dst_gateway->name, src, route->src_gateway->name);
+          route->gw_dst->name, src, route->gw_src->name);
 
     xbt_dynar_t nodes = xbt_graph_get_nodes(as->route_graph);
     xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_net_elm->id, xbt_node_t);
@@ -523,13 +525,14 @@ void model_dijkstra_both_parse_route (AS_t asg, const char *src,
     if (edge)
       THROWF(arg_error,0,"(AS)Route from '%s' to '%s' already exists",src,dst);
 
-    if (route->dst_gateway && route->src_gateway) {
+    if (route->gw_dst && route->gw_src) {
       sg_routing_edge_t gw_tmp;
-      gw_tmp = route->src_gateway;
-      route->src_gateway = route->dst_gateway;
-      route->dst_gateway = gw_tmp;
+      gw_tmp = route->gw_src;
+      route->gw_src = route->gw_dst;
+      route->gw_dst = gw_tmp;
     }
-    route_t link_route_back = generic_new_extended_route(asg->hierarchy, route, 0);
+    sg_platf_route_cbarg_t link_route_back = generic_new_extended_route(asg->hierarchy, route, 0);
     route_new_dijkstra(as, dst_net_elm->id, src_net_elm->id, link_route_back);
   }
+  xbt_dynar_free(&route->link_list);
 }
index bcb048e..5bce7d4 100644 (file)
@@ -22,17 +22,17 @@ typedef struct {
   /* vars for calculate the floyd algorith. */
   int *predecessor_table;
   double *cost_table;
-  route_t *link_table;
+  sg_platf_route_cbarg_t *link_table;
 } s_as_floyd_t, *as_floyd_t;
 
 static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_routing_edge_t dst,
-    route_t res, double *lat);
+    sg_platf_route_cbarg_t res, double *lat);
 
 /* Business methods */
 static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
 {
   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
-  route_t route =   xbt_new0(s_route_t, 1);
+  sg_platf_route_cbarg_t route =   xbt_new0(s_sg_platf_route_cbarg_t, 1);
   route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
 
   int src,dst;
@@ -53,8 +53,8 @@ static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
           onelink->src = src_elm;
           onelink->dst = dst_elm;
         } else if (asg->hierarchy == SURF_ROUTING_RECURSIVE) {
-          onelink->src = route->src_gateway;
-          onelink->dst = route->dst_gateway;
+          onelink->src = route->gw_src;
+          onelink->dst = route->gw_dst;
         }
         xbt_dynar_push(ret, &onelink);
       }
@@ -65,7 +65,7 @@ static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
 }
 
 static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_routing_edge_t dst,
-    route_t res, double *lat)
+    sg_platf_route_cbarg_t res, double *lat)
 {
 
   /* set utils vars */
@@ -75,32 +75,32 @@ static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_rout
   generic_src_dst_check(asg, src, dst);
 
   /* create a result route */
-  xbt_dynar_t route_stack = xbt_dynar_new(sizeof(route_t), NULL);
+  xbt_dynar_t route_stack = xbt_dynar_new(sizeof(sg_platf_route_cbarg_t), NULL);
   int pred;
   int cur = dst->id;
   do {
     pred = TO_FLOYD_PRED(src->id, cur);
     if (pred == -1)
       THROWF(arg_error, 0, "No route from '%s' to '%s'", src->name, dst->name);
-    xbt_dynar_push_as(route_stack, route_t, TO_FLOYD_LINK(pred, cur));
+    xbt_dynar_push_as(route_stack, sg_platf_route_cbarg_t, TO_FLOYD_LINK(pred, cur));
     cur = pred;
   } while (cur != src->id);
 
   if (asg->hierarchy == SURF_ROUTING_RECURSIVE) {
-    res->src_gateway = xbt_dynar_getlast_as(route_stack, route_t)->src_gateway;
-    res->dst_gateway = xbt_dynar_getfirst_as(route_stack, route_t)->dst_gateway;
+    res->gw_src = xbt_dynar_getlast_as(route_stack, sg_platf_route_cbarg_t)->gw_src;
+    res->gw_dst = xbt_dynar_getfirst_as(route_stack, sg_platf_route_cbarg_t)->gw_dst;
   }
 
   sg_routing_edge_t prev_dst_gw = NULL;
   while (!xbt_dynar_is_empty(route_stack)) {
-    route_t e_route = xbt_dynar_pop_as(route_stack, route_t);
+    sg_platf_route_cbarg_t e_route = xbt_dynar_pop_as(route_stack, sg_platf_route_cbarg_t);
     xbt_dynar_t links;
     sg_routing_link_t link;
     unsigned int cpt;
 
     if (asg->hierarchy == SURF_ROUTING_RECURSIVE && prev_dst_gw != NULL
-        && strcmp(prev_dst_gw->name, e_route->src_gateway->name)) {
-      routing_get_route_and_latency(prev_dst_gw, e_route->src_gateway,
+        && strcmp(prev_dst_gw->name, e_route->gw_src->name)) {
+      routing_get_route_and_latency(prev_dst_gw, e_route->gw_src,
                                     &res->link_list, lat);
     }
 
@@ -111,7 +111,7 @@ static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_rout
         *lat += surf_network_model->extension.network.get_link_latency(link);
     }
 
-    prev_dst_gw = e_route->dst_gateway;
+    prev_dst_gw = e_route->gw_dst;
   }
   xbt_dynar_free(&route_stack);
 }
@@ -166,7 +166,7 @@ void model_floyd_end(AS_t current_routing)
     /* Create Cost, Predecessor and Link tables */
     as->cost_table = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
     as->predecessor_table = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
-    as->link_table = xbt_new0(route_t, table_size * table_size);    /* actual link between src and dst */
+    as->link_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);    /* actual link between src and dst */
 
     /* Initialize costs and predecessors */
     for (i = 0; i < table_size; i++)
@@ -180,11 +180,11 @@ void model_floyd_end(AS_t current_routing)
   /* Add the loopback if needed */
   if (routing_platf->loopback && current_routing->hierarchy == SURF_ROUTING_BASE) {
     for (i = 0; i < table_size; i++) {
-      route_t e_route = TO_FLOYD_LINK(i, i);
+      sg_platf_route_cbarg_t e_route = TO_FLOYD_LINK(i, i);
       if (!e_route) {
-        e_route = xbt_new0(s_route_t, 1);
-        e_route->src_gateway = NULL;
-        e_route->dst_gateway = NULL;
+        e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+        e_route->gw_src = NULL;
+        e_route->gw_dst = NULL;
         e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
         xbt_dynar_push(e_route->link_list, &routing_platf->loopback);
         TO_FLOYD_LINK(i, i) = e_route;
@@ -217,9 +217,11 @@ static int floyd_pointer_resource_cmp(const void *a, const void *b) {
 
 //FIXME: kill dupplicates in next function with full routing
 
-void model_floyd_parse_route(AS_t rc, const char *src,
-    const char *dst, route_t route)
+void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
 {
+  char *src = (char*)(route->src);
+  char *dst = (char*)(route->dst);
+
   int as_route = 0;
   as_floyd_t as = (as_floyd_t) rc;
 
@@ -239,7 +241,7 @@ void model_floyd_parse_route(AS_t rc, const char *src,
     /* Create Cost, Predecessor and Link tables */
     as->cost_table = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
     as->predecessor_table = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
-    as->link_table = xbt_new0(route_t, table_size * table_size);    /* actual link between src and dst */
+    as->link_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);    /* actual link between src and dst */
 
     /* Initialize costs and predecessors */
     for (i = 0; i < table_size; i++)
@@ -249,16 +251,16 @@ void model_floyd_parse_route(AS_t rc, const char *src,
         TO_FLOYD_LINK(i, j) = NULL;       /* fixed, missing in the previous version */
       }
   }
-  if(!route->dst_gateway && !route->src_gateway)
+  if(!route->gw_dst && !route->gw_src)
     XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
   else{
     as_route = 1;
     XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
-        route->src_gateway->name, dst, route->dst_gateway->name);
-    if(route->dst_gateway->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The dst_gateway '%s' does not exist!",route->dst_gateway->name);
-    if(route->src_gateway->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The src_gateway '%s' does not exist!",route->src_gateway->name);
+        route->gw_src->name, dst, route->gw_dst->name);
+    if(route->gw_dst->rc_type == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The dst_gateway '%s' does not exist!",route->gw_dst->name);
+    if(route->gw_src->rc_type == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The src_gateway '%s' does not exist!",route->gw_src->name);
   }
 
   if(TO_FLOYD_LINK(src_net_elm->id, dst_net_elm->id))
@@ -288,17 +290,17 @@ void model_floyd_parse_route(AS_t rc, const char *src,
         ((TO_FLOYD_LINK(src_net_elm->id, dst_net_elm->id))->link_list)->used;   /* count of links, old model assume 1 */
   }
 
-  if ( (A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES && as_route == 0)
-      || (A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES && as_route == 1)
+  if ( (route->symmetrical == TRUE && as_route == 0)
+      || (route->symmetrical == TRUE && as_route == 1)
   )
   {
     if(TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id))
     {
-      if(!route->dst_gateway && !route->src_gateway)
+      if(!route->gw_dst && !route->gw_src)
         XBT_DEBUG("See Route from \"%s\" to \"%s\"", dst, src);
       else
         XBT_DEBUG("See ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
-            route->src_gateway->name, src, route->dst_gateway->name);
+            route->gw_src->name, src, route->gw_dst->name);
       char * link_name;
       unsigned int i;
       xbt_dynar_t link_route_to_test = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
@@ -317,19 +319,19 @@ void model_floyd_parse_route(AS_t rc, const char *src,
     }
     else
     {
-      if(route->dst_gateway && route->src_gateway)
+      if(route->gw_dst && route->gw_src)
       {
-        sg_routing_edge_t gw_src = route->src_gateway;
-        sg_routing_edge_t gw_dst = route->dst_gateway;
-        route->src_gateway = gw_dst;
-        route->dst_gateway = gw_src;
+        sg_routing_edge_t gw_src = route->gw_src;
+        sg_routing_edge_t gw_dst = route->gw_dst;
+        route->gw_src = gw_dst;
+        route->gw_dst = gw_src;
       }
 
-      if(!route->dst_gateway && !route->src_gateway)
+      if(!route->gw_src && !route->gw_dst)
         XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
       else
         XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
-            route->src_gateway->name, src, route->dst_gateway->name);
+            route->gw_src->name, src, route->gw_dst->name);
 
       TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id) =
           generic_new_extended_route(rc->hierarchy, route, 0);
@@ -338,4 +340,5 @@ void model_floyd_parse_route(AS_t rc, const char *src,
           ((TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id))->link_list)->used;   /* count of links, old model assume 1 */
     }
   }
+  xbt_dynar_free(&route->link_list);
 }
index ab14bf6..71cdfc6 100644 (file)
@@ -18,7 +18,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf");
 
 typedef struct s_routing_component_full {
   s_as_t generic_routing;
-  route_t *routing_table;
+  sg_platf_route_cbarg_t *routing_table;
 } s_routing_component_full_t, *routing_component_full_t;
 
 /* Business methods */
@@ -32,7 +32,7 @@ static xbt_dynar_t full_get_onelink_routes(AS_t rc)
 
   for(src=0; src < table_size; src++) {
     for(dst=0; dst< table_size; dst++) {
-      route_t route = TO_ROUTE_FULL(src, dst);
+      sg_platf_route_cbarg_t route = TO_ROUTE_FULL(src, dst);
       if (route) {
         if (xbt_dynar_length(route->link_list) == 1) {
           void *link = *(void **) xbt_dynar_get_ptr(route->link_list, 0);
@@ -44,8 +44,8 @@ static xbt_dynar_t full_get_onelink_routes(AS_t rc)
             onelink->dst = xbt_dynar_get_as(rc->index_network_elm,dst,sg_routing_edge_t);
             onelink->dst->id = dst;
           } else if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
-            onelink->src = route->src_gateway;
-            onelink->dst = route->dst_gateway;
+            onelink->src = route->gw_src;
+            onelink->dst = route->gw_dst;
           }
           xbt_dynar_push(ret, &onelink);
           XBT_DEBUG("Push route from '%d' to '%d'",
@@ -60,7 +60,7 @@ static xbt_dynar_t full_get_onelink_routes(AS_t rc)
 
 static void full_get_route_and_latency(AS_t rc,
     sg_routing_edge_t src, sg_routing_edge_t dst,
-    route_t res, double *lat)
+    sg_platf_route_cbarg_t res, double *lat)
 {
   XBT_DEBUG("full_get_route_and_latency from %s[%d] to %s[%d]",
       src->name,
@@ -72,15 +72,15 @@ static void full_get_route_and_latency(AS_t rc,
   routing_component_full_t routing = (routing_component_full_t) rc;
   size_t table_size = xbt_dynar_length(routing->generic_routing.index_network_elm);
 
-  route_t e_route = NULL;
+  sg_platf_route_cbarg_t e_route = NULL;
   void *link;
   unsigned int cpt = 0;
 
   e_route = TO_ROUTE_FULL(src->id, dst->id);
 
   if (e_route) {
-    res->src_gateway = e_route->src_gateway;
-    res->dst_gateway = e_route->dst_gateway;
+    res->gw_src = e_route->gw_src;
+    res->gw_dst = e_route->gw_dst;
     xbt_dynar_foreach(e_route->link_list, cpt, link) {
       xbt_dynar_push(res->link_list, &link);
       if (lat)
@@ -124,7 +124,7 @@ AS_t model_full_create(void)
 void model_full_end(AS_t current_routing)
 {
   unsigned int i;
-  route_t e_route;
+  sg_platf_route_cbarg_t e_route;
 
   /* set utils vars */
   routing_component_full_t routing =
@@ -133,16 +133,16 @@ void model_full_end(AS_t current_routing)
 
   /* Create table if necessary */
   if (!routing->routing_table)
-    routing->routing_table = xbt_new0(route_t, table_size * table_size);
+    routing->routing_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);
 
   /* Add the loopback if needed */
   if (routing_platf->loopback && current_routing->hierarchy == SURF_ROUTING_BASE) {
     for (i = 0; i < table_size; i++) {
       e_route = TO_ROUTE_FULL(i, i);
       if (!e_route) {
-        e_route = xbt_new0(s_route_t, 1);
-        e_route->src_gateway = NULL;
-        e_route->dst_gateway = NULL;
+        e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+        e_route->gw_src = NULL;
+        e_route->gw_dst = NULL;
         e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
         xbt_dynar_push(e_route->link_list, &routing_platf->loopback);
         TO_ROUTE_FULL(i, i) = e_route;
@@ -156,11 +156,12 @@ static int full_pointer_resource_cmp(const void *a, const void *b)
   return a != b;
 }
 
-void model_full_set_route(AS_t rc, const char *src,
-    const char *dst, route_t route)
+void model_full_set_route(AS_t rc, sg_platf_route_cbarg_t route)
 {
-  sg_routing_edge_t src_net_elm, dst_net_elm;
   int as_route = 0;
+  char *src = (char*)(route->src);
+  char *dst = (char*)(route->dst);
+  sg_routing_edge_t src_net_elm, dst_net_elm;
   src_net_elm = sg_routing_edge_by_name_or_null(src);
   dst_net_elm = sg_routing_edge_by_name_or_null(dst);
 
@@ -175,7 +176,7 @@ void model_full_set_route(AS_t rc, const char *src,
       src, dst);
 
   if (!routing->routing_table)
-    routing->routing_table = xbt_new0(route_t, table_size * table_size);
+    routing->routing_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);
 
   if (TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id)) {
     char *link_name;
@@ -199,10 +200,10 @@ void model_full_set_route(AS_t rc, const char *src,
           "between \"%s\" and \"%s\"", src, dst);
     }
   } else {
-    if (!route->dst_gateway && !route->src_gateway)
+    if (!route->gw_dst && !route->gw_dst)
       XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
     else {
-      // FIXME We can call a gw wich is down the current AS (cf g5k.xml) but not upper.
+      // FIXME We can call a gw which is down the current AS (cf g5k.xml) but not upper.
       //      AS_t subas = xbt_dict_get_or_null(rc->routing_sons, src);
       //      if (subas == NULL)
       //        surf_parse_error("The source of an ASroute must be a sub-AS "
@@ -230,25 +231,25 @@ void model_full_set_route(AS_t rc, const char *src,
       //                         route->dst_gateway, subas->name);
       as_route = 1;
       XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"",
-          src, route->src_gateway->name, dst, route->dst_gateway->name);
-      if (route->dst_gateway->rc_type == SURF_NETWORK_ELEMENT_NULL)
-        xbt_die("The dst_gateway '%s' does not exist!", route->dst_gateway->name);
-      if (route->src_gateway->rc_type == SURF_NETWORK_ELEMENT_NULL)
-        xbt_die("The src_gateway '%s' does not exist!", route->src_gateway->name);
+          src, route->gw_src->name, dst, route->gw_dst->name);
+      if (route->gw_dst->rc_type == SURF_NETWORK_ELEMENT_NULL)
+        xbt_die("The dst_gateway '%s' does not exist!", route->gw_dst->name);
+      if (route->gw_src->rc_type == SURF_NETWORK_ELEMENT_NULL)
+        xbt_die("The src_gateway '%s' does not exist!", route->gw_src->name);
     }
     TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id) =
         generic_new_extended_route(rc->hierarchy, route, 1);
     xbt_dynar_shrink(TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id)->link_list, 0);
   }
 
-  if ( (A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES && as_route == 0)
-      || (A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES && as_route == 1)
+  if ( (route->symmetrical == TRUE && as_route == 0)
+      || (route->symmetrical == TRUE && as_route == 1)
   ) {
-    if (route->dst_gateway && route->src_gateway) {
+    if (route->gw_dst && route->gw_src) {
       sg_routing_edge_t gw_tmp;
-      gw_tmp = route->src_gateway;
-      route->src_gateway = route->dst_gateway;
-      route->dst_gateway = gw_tmp;
+      gw_tmp = route->gw_src;
+      route->gw_src = route->gw_dst;
+      route->gw_dst = gw_tmp;
     }
     if (TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id)) {
       char *link_name;
@@ -267,14 +268,15 @@ void model_full_set_route(AS_t rc, const char *src,
           "The route between \"%s\" and \"%s\" already exists", src,
           dst);
     } else {
-      if (!route->dst_gateway && !route->src_gateway)
+      if (!route->gw_dst && !route->gw_src)
         XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
       else
         XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"",
-            dst, route->src_gateway->name, src, route->dst_gateway->name);
+            dst, route->gw_src->name, src, route->gw_dst->name);
       TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id) =
           generic_new_extended_route(rc->hierarchy, route, 0);
       xbt_dynar_shrink(TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id)->link_list, 0);
     }
   }
+  xbt_dynar_free(&route->link_list);
 }
index 2ee5f75..a3dd35c 100644 (file)
@@ -52,11 +52,12 @@ int generic_parse_AS(AS_t as, sg_routing_edge_t elm)
   return xbt_dynar_length(as->index_network_elm)-1;
 }
 
-void generic_parse_bypassroute(AS_t rc,
-    const char *src, const char *dst,
-    route_t e_route)
+void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route)
 {
-  if(e_route->dst_gateway)
+  char *src = (char*)(e_route->src);
+  char *dst = (char*)(e_route->dst);
+
+  if(e_route->gw_dst)
     XBT_DEBUG("Load bypassASroute from \"%s\" to \"%s\"", src, dst);
   else
     XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
@@ -69,16 +70,15 @@ void generic_parse_bypassroute(AS_t rc,
       src, dst);
   xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
       "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
-      src, e_route->src_gateway->name, dst, e_route->dst_gateway->name);
+      src, e_route->gw_src->name, dst, e_route->gw_dst->name);
 
-  route_t new_e_route = NULL;
-  if(e_route->dst_gateway)
+  sg_platf_route_cbarg_t new_e_route = NULL;
+  if(e_route->gw_dst)
     new_e_route =  generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 1);
   else
     new_e_route =  generic_new_extended_route(SURF_ROUTING_BASE, e_route, 1);
 
   xbt_dynar_free(&(e_route->link_list));
-  xbt_free(e_route);
 
   xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, NULL);
   no_bypassroute_declared = 0;
@@ -93,14 +93,14 @@ xbt_dynar_t generic_get_onelink_routes(AS_t rc) { // FIXME: kill that stub
   return NULL;
 }
 
-route_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat)
+sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat)
 {
   // If never set a bypass route return NULL without any further computations
   XBT_DEBUG("generic_get_bypassroute from %s to %s",src->name,dst->name);
   if(no_bypassroute_declared)
     return NULL;
 
-  route_t e_route_bypass = NULL;
+  sg_platf_route_cbarg_t e_route_bypass = NULL;
   xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
 
   if(dst->rc_component == rc && src->rc_component == rc ){
@@ -206,13 +206,13 @@ route_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src, sg_routing_edge_
     xbt_dynar_free(&path_dst);
   }
 
-  route_t new_e_route = NULL;
+  sg_platf_route_cbarg_t new_e_route = NULL;
   if (e_route_bypass) {
     void *link;
     unsigned int cpt = 0;
-    new_e_route = xbt_new0(s_route_t, 1);
-    new_e_route->src_gateway = e_route_bypass->src_gateway;
-    new_e_route->dst_gateway = e_route_bypass->dst_gateway;
+    new_e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+    new_e_route->gw_src = e_route_bypass->gw_src;
+    new_e_route->gw_dst = e_route_bypass->gw_dst;
     new_e_route->link_list =
         xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
     xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
@@ -228,15 +228,15 @@ route_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src, sg_routing_edge_
 /* ************************************************************************** */
 /* ************************* GENERIC AUX FUNCTIONS ************************** */
 /* change a route containing link names into a route containing link entities */
-route_t
+sg_platf_route_cbarg_t
 generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
-    route_t routearg, int change_order) {
+    sg_platf_route_cbarg_t routearg, int change_order) {
 
-  route_t result;
+  sg_platf_route_cbarg_t result;
   char *link_name;
   unsigned int cpt;
 
-  result = xbt_new0(s_route_t, 1);
+  result = xbt_new0(s_sg_platf_route_cbarg_t, 1);
   result->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
 
   xbt_assert(hierarchy == SURF_ROUTING_BASE
@@ -245,12 +245,12 @@ generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
 
   if (hierarchy == SURF_ROUTING_RECURSIVE) {
 
-    xbt_assert(routearg->src_gateway && routearg->dst_gateway,
+    xbt_assert(routearg->gw_src && routearg->gw_dst,
         "NULL is obviously a bad gateway");
 
     /* remeber not erase the gateway names */
-    result->src_gateway = routearg->src_gateway;
-    result->dst_gateway = routearg->dst_gateway;
+    result->gw_src = routearg->gw_src;
+    result->gw_dst = routearg->gw_dst;
   }
 
   xbt_dynar_foreach(routearg->link_list, cpt, link_name) {
@@ -268,7 +268,7 @@ generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
   return result;
 }
 
-void generic_free_route(route_t route)
+void generic_free_route(sg_platf_route_cbarg_t route)
 {
   if (route) {
     xbt_dynar_free(&route->link_list);
index 0342cfd..1f403c8 100644 (file)
@@ -13,12 +13,12 @@ static xbt_dynar_t none_get_onelink_routes(AS_t rc) {
 }
 
 static void none_get_route_and_latency(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst,
-                                       route_t res,double *lat)
+    sg_platf_route_cbarg_t res,double *lat)
 {
   *lat = 0.0;
 }
 
-static route_t none_get_bypass_route(AS_t rc,
+static sg_platf_route_cbarg_t none_get_bypass_route(AS_t rc,
     sg_routing_edge_t src,
     sg_routing_edge_t dst, double *lat) {
   return NULL;
index 112a13d..5490781 100644 (file)
@@ -31,14 +31,13 @@ void model_generic_finalize(AS_t as);
 
 int generic_parse_PU(AS_t rc, sg_routing_edge_t elm);
 int generic_parse_AS(AS_t rc, sg_routing_edge_t elm);
-void generic_parse_bypassroute(AS_t rc, const char *src, const char *dst,
-                               route_t e_route);
+void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route);
 
 /* ************************************************************************** */
 /* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
 
 xbt_dynar_t generic_get_onelink_routes(AS_t rc);
-route_t generic_get_bypassroute(AS_t rc,
+sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc,
     sg_routing_edge_t src,
     sg_routing_edge_t dst,
     double *lat);
@@ -49,8 +48,8 @@ route_t generic_get_bypassroute(AS_t rc,
 /* change a route containing link names into a route containing link entities.
  * If change_order is true, the links are put in reverse order in the
  * produced route */
-route_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
-                                   route_t data, int preserve_order);
+sg_platf_route_cbarg_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
+                                   sg_platf_route_cbarg_t data, int preserve_order);
 AS_t
 generic_autonomous_system_exist(AS_t rc, char *element);
 AS_t
@@ -63,8 +62,7 @@ void generic_src_dst_check(AS_t rc, sg_routing_edge_t src,
 /* *************************** FLOYD ROUTING ******************************** */
 AS_t model_floyd_create(void);  /* create structures for floyd routing model */
 void model_floyd_end(AS_t as);      /* finalize the creation of floyd routing model */
-void model_floyd_parse_route(AS_t rc, const char *src,
-        const char *dst, route_t route);
+void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route);
 
 /* ************************************************** */
 /* ************** RULE-BASED ROUTING **************** */
@@ -92,15 +90,14 @@ AS_t model_dijkstra_both_create(int cached);    /* create by calling dijkstra or
 AS_t model_dijkstra_create(void);       /* create structures for dijkstra routing model */
 AS_t model_dijkstracache_create(void);  /* create structures for dijkstracache routing model */
 void model_dijkstra_both_end(AS_t as);      /* finalize the creation of dijkstra routing model */
-void model_dijkstra_both_parse_route (AS_t rc, const char *src,
-                     const char *dst, route_t route);
+void model_dijkstra_both_parse_route (AS_t rc, sg_platf_route_cbarg_t route);
 
 /* ************************************************************************** */
 /* *************************** FULL ROUTING ********************************* */
 AS_t model_full_create(void);   /* create structures for full routing model */
 void model_full_end(AS_t as);       /* finalize the creation of full routing model */
 void model_full_set_route(  /* Set the route and ASroute between src and dst */
-    AS_t rc, const char *src, const char *dst, route_t route);
+    AS_t rc, sg_platf_route_cbarg_t route);
 
 
 #endif                          /* _SURF_SURF_ROUTING_PRIVATE_H */
index ca03d30..53d87be 100644 (file)
@@ -20,11 +20,10 @@ typedef struct {
 } s_AS_rulebased_t, *AS_rulebased_t;
 
 typedef struct s_rule_route s_rule_route_t, *rule_route_t;
-typedef struct s_rule_route_extended s_rule_route_extended_t,
-*rule_route_extended_t;
+typedef struct s_rule_route_extended s_rule_route_extended_t, *rule_route_extended_t;
 
 struct s_rule_route {
-  xbt_dynar_t re_str_link;      // dynar of char*
+  xbt_dynar_t re_str_link;  // dynar of char*
   pcre *re_src;
   pcre *re_dst;
 };
@@ -76,10 +75,11 @@ static int model_rulebased_parse_AS(AS_t rc, sg_routing_edge_t elm)
   return -1;
 }
 
-static void model_rulebased_parse_route(AS_t rc,
-    const char *src, const char *dst,
-    route_t route)
+static void model_rulebased_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
 {
+  char *src = (char*)(route->src);
+  char *dst = (char*)(route->dst);
+
   AS_rulebased_t routing = (AS_rulebased_t) rc;
   rule_route_t ruleroute = xbt_new0(s_rule_route_t, 1);
   const char *error;
@@ -105,10 +105,11 @@ static void model_rulebased_parse_route(AS_t rc,
   xbt_dynar_push(routing->list_route, &ruleroute);
 }
 
-static void model_rulebased_parse_ASroute(AS_t rc,
-    const char *src, const char *dst,
-    route_t route)
+static void model_rulebased_parse_ASroute(AS_t rc, sg_platf_route_cbarg_t route)
 {
+  char *src = (char*)(route->src);
+  char *dst = (char*)(route->dst);
+
   AS_rulebased_t routing = (AS_rulebased_t) rc;
   rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t, 1);
   const char *error;
@@ -126,29 +127,26 @@ static void model_rulebased_parse_ASroute(AS_t rc,
       erroffset, src, error);
   ruleroute_e->generic_rule_route.re_dst =
       pcre_compile(dst, 0, &error, &erroffset, NULL);
-  xbt_assert(ruleroute_e->generic_rule_route.re_src,
+  xbt_assert(ruleroute_e->generic_rule_route.re_dst,
       "PCRE compilation failed at offset %d (\"%s\"): %s\n",
       erroffset, dst, error);
-  ruleroute_e->generic_rule_route.re_str_link =
-      route->link_list;
+
+  ruleroute_e->generic_rule_route.re_str_link = route->link_list;
 
   // DIRTY PERL HACK AHEAD: with the rulebased routing, the {src,dst}_gateway fields
   // store the provided name instead of the entity directly (routing_parse_E_ASroute knows)
   //
   // This is because the user will provide something like "^AS_(.*)$" instead of the proper name of a given entity
-  ruleroute_e->re_src_gateway = xbt_strdup((char *)route->src_gateway);
-  ruleroute_e->re_dst_gateway = xbt_strdup((char *)route->dst_gateway);
+  ruleroute_e->re_src_gateway = xbt_strdup((char *)route->gw_src);
+  ruleroute_e->re_dst_gateway = xbt_strdup((char *)route->gw_dst);
   xbt_dynar_push(routing->list_ASroute, &ruleroute_e);
 
   /* make sure that they don't get freed */
   route->link_list = NULL;
-  route->src_gateway = route->dst_gateway = NULL;
+  route->gw_src = route->gw_dst = NULL;
 }
 
-static void model_rulebased_parse_bypassroute(AS_t rc,
-    const char *src,
-    const char *dst,
-    route_t e_route)
+static void model_rulebased_parse_bypassroute(AS_t rc,  sg_platf_route_cbarg_t e_route)
 {
   xbt_die("bypass routing not supported for Route-Based model");
 }
@@ -213,7 +211,7 @@ static char *remplace(char *value, const char **src_list, int src_size,
 
 static void rulebased_get_route_and_latency(AS_t rc,
     sg_routing_edge_t src, sg_routing_edge_t dst,
-    route_t res,double*lat);
+    sg_platf_route_cbarg_t res,double*lat);
 static xbt_dynar_t rulebased_get_onelink_routes(AS_t rc)
 {
   xbt_dynar_t ret = xbt_dynar_new (sizeof(onelink_t), xbt_free);
@@ -237,27 +235,26 @@ static xbt_dynar_t rulebased_get_onelink_routes(AS_t rc)
 
   sg_routing_edge_t host = NULL;
   xbt_lib_foreach(as_router_lib, cursor, k1, host){
-    route_t route = xbt_new0(s_route_t,1);
+    void *link_ptr;
+    sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1);
     route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
     rulebased_get_route_and_latency (rc, router, host, route,NULL);
 
-    int number_of_links = xbt_dynar_length(route->link_list);
-
-    if(number_of_links == 1) {
+    switch (xbt_dynar_length(route->link_list)) {
+    case 1:
       //loopback
-    }
-    else{
-      if (number_of_links != 2) {
-        xbt_die ("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
-      }
-
-      void *link_ptr;
+      break;
+    case 2:
       xbt_dynar_get_cpy (route->link_list, 1, &link_ptr);
       onelink_t onelink = xbt_new0 (s_onelink_t, 1);
       onelink->src = host;
       onelink->dst = router;
       onelink->link_ptr = link_ptr;
       xbt_dynar_push (ret, &onelink);
+      break;
+    default:
+      xbt_die("rulebased_get_onelink_routes works only if the AS is a cluster, sorry.");
+      break;
     }
   }
   return ret;
@@ -266,7 +263,7 @@ static xbt_dynar_t rulebased_get_onelink_routes(AS_t rc)
 /* Business methods */
 static void rulebased_get_route_and_latency(AS_t rc,
     sg_routing_edge_t src, sg_routing_edge_t dst,
-    route_t route, double *lat)
+    sg_platf_route_cbarg_t route, double *lat)
 {
   XBT_DEBUG("rulebased_get_route_and_latency from '%s' to '%s'",src->name,dst->name);
   xbt_assert(rc && src
@@ -353,12 +350,12 @@ static void rulebased_get_route_and_latency(AS_t rc,
         (rule_route_extended_t) ruleroute;
     char *gw_src_name = remplace(ruleroute_extended->re_src_gateway, list_src, rc_src,
         list_dst, rc_dst);
-    route->src_gateway = sg_routing_edge_by_name_or_null(gw_src_name);
+    route->gw_src = sg_routing_edge_by_name_or_null(gw_src_name);
     xbt_free(gw_src_name);
 
     char *gw_dst_name = remplace(ruleroute_extended->re_dst_gateway, list_src, rc_src,
         list_dst, rc_dst);
-    route->dst_gateway = sg_routing_edge_by_name_or_null(gw_dst_name);
+    route->gw_dst = sg_routing_edge_by_name_or_null(gw_dst_name);
     xbt_free(gw_dst_name);
   }
 
@@ -368,7 +365,7 @@ static void rulebased_get_route_and_latency(AS_t rc,
     pcre_free_substring_list(list_dst);
 }
 
-static route_t rulebased_get_bypass_route(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat) {
+static sg_platf_route_cbarg_t rulebased_get_bypass_route(AS_t rc, sg_routing_edge_t src, sg_routing_edge_t dst, double *lat) {
   return NULL;
 }
 
index 00b7e77..2079a80 100644 (file)
@@ -18,7 +18,7 @@ static XBT_INLINE double euclidean_dist_comp(int index, xbt_dynar_t src, xbt_dyn
 
 static void vivaldi_get_route_and_latency(
     AS_t rc, sg_routing_edge_t src_p, sg_routing_edge_t dst_p,
-    route_t route, double *lat)
+    sg_platf_route_cbarg_t route, double *lat)
 {
   s_surf_parsing_link_up_down_t info;
 
@@ -27,8 +27,8 @@ static void vivaldi_get_route_and_latency(
   char *dst = (char*)dst_p->name;
 
   if(src_p->rc_type == SURF_NETWORK_ELEMENT_AS) {
-    route->src_gateway = xbt_lib_get_or_null(as_router_lib,ROUTER_PEER(src),ROUTING_ASR_LEVEL);
-    route->dst_gateway = xbt_lib_get_or_null(as_router_lib,ROUTER_PEER(dst),ROUTING_ASR_LEVEL);
+    route->gw_src = xbt_lib_get_or_null(as_router_lib,ROUTER_PEER(src),ROUTING_ASR_LEVEL);
+    route->gw_dst = xbt_lib_get_or_null(as_router_lib,ROUTER_PEER(dst),ROUTING_ASR_LEVEL);
   }
 
   double euclidean_dist;
@@ -54,7 +54,7 @@ static void vivaldi_get_route_and_latency(
     src_ctn = xbt_lib_get_or_null(as_router_lib, tmp_src_name, COORD_ASR_LEVEL);
   }
   else{
-    xbt_die(" ");
+    THROW_IMPOSSIBLE;
   }
 
   if(dst_p->rc_type == SURF_NETWORK_ELEMENT_HOST){
@@ -76,7 +76,7 @@ static void vivaldi_get_route_and_latency(
     dst_ctn = xbt_lib_get_or_null(as_router_lib, tmp_dst_name, COORD_ASR_LEVEL);
   }
   else{
-    xbt_die(" ");
+    THROW_IMPOSSIBLE;
   }
 
   xbt_assert(src_ctn,"No coordinate found for element '%s'",tmp_src_name);
index ce491e3..b9fc03b 100644 (file)
@@ -22,6 +22,8 @@ int ETag_surfxml_include_state(void);
 
 char* surf_parsed_filename = NULL; // to locate parse error messages
 
+xbt_dynar_t parsed_link_list = NULL;   /* temporary store of current list link of a route */
+extern AS_t current_routing;
 /*
  * Helping functions
  */
@@ -64,50 +66,19 @@ int surf_parse_get_int(const char *string) {
  */
 
 /* make sure these symbols are defined as strong ones in this file so that the linker can resolve them */
-xbt_dynar_t STag_surfxml_route_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_route_cb_list = NULL;
-xbt_dynar_t STag_surfxml_link_ctn_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_link_ctn_cb_list = NULL;
-xbt_dynar_t STag_surfxml_process_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_process_cb_list = NULL;
-xbt_dynar_t STag_surfxml_argument_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_argument_cb_list = NULL;
-xbt_dynar_t STag_surfxml_prop_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_prop_cb_list = NULL;
-xbt_dynar_t STag_surfxml_peer_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_peer_cb_list = NULL;
-xbt_dynar_t STag_surfxml_trace_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_trace_cb_list = NULL;
-xbt_dynar_t STag_surfxml_trace_connect_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_trace_connect_cb_list = NULL;
-xbt_dynar_t STag_surfxml_random_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_random_cb_list = NULL;
-xbt_dynar_t STag_surfxml_ASroute_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_ASroute_cb_list = NULL;
-xbt_dynar_t STag_surfxml_bypassRoute_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_bypassRoute_cb_list = NULL;
-xbt_dynar_t STag_surfxml_bypassASroute_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_bypassASroute_cb_list = NULL;
-xbt_dynar_t STag_surfxml_include_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_include_cb_list = NULL;
-
-xbt_dynar_t STag_surfxml_storage_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_storage_cb_list = NULL;
-xbt_dynar_t STag_surfxml_storage_type_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_storage_type_cb_list = NULL;
-xbt_dynar_t STag_surfxml_mount_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_mount_cb_list = NULL;
-xbt_dynar_t STag_surfxml_mstorage_cb_list = NULL;
-xbt_dynar_t ETag_surfxml_mstorage_cb_list = NULL;
 
 /* The default current property receiver. Setup in the corresponding opening callbacks. */
 xbt_dict_t current_property_set = NULL;
+xbt_dict_t as_current_property_set = NULL;
+int AS_TAG = 0;
+char* as_name_tab[1024];
+void* as_dict_tab[1024];
+int as_prop_nb = 0;
+
+
 /* dictionary of random generator data */
 xbt_dict_t random_data_list = NULL;
 
-/* Call all the callbacks of a specific SAX event */
-static XBT_INLINE void surfxml_call_cb_functions(xbt_dynar_t);
-
 YY_BUFFER_STATE surf_input_buffer;
 FILE *surf_file_to_parse = NULL;
 
@@ -119,7 +90,9 @@ static void add_randomness(void);
  */
 void STag_surfxml_storage(void)
 {
+  AS_TAG = 0;
   XBT_DEBUG("STag_surfxml_storage");
+  xbt_assert(current_property_set == NULL, "Someone forgot to reset the property set to NULL in its closing tag (or XML malformed)");
 }
 void ETag_surfxml_storage(void)
 {
@@ -129,10 +102,13 @@ void ETag_surfxml_storage(void)
   storage.id = A_surfxml_storage_id;
   storage.type_id = A_surfxml_storage_typeId;
   storage.content = A_surfxml_storage_content;
+  storage.properties = current_property_set;
   sg_platf_new_storage(&storage);
+  current_property_set = NULL;
 }
 void STag_surfxml_storage_type(void)
 {
+  AS_TAG = 0;
   XBT_DEBUG("STag_surfxml_storage_type");
   xbt_assert(current_property_set == NULL, "Someone forgot to reset the property set to NULL in its closing tag (or XML malformed)");
 }
@@ -241,61 +217,7 @@ int ETag_surfxml_include_state(void)
 
 void surf_parse_init_callbacks(void)
 {
-    sg_platf_init(); // FIXME: move to a proper place?
-
-    STag_surfxml_route_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_route_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_link_ctn_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_link_ctn_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_process_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_process_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_argument_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_argument_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_prop_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_prop_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_trace_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_trace_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_trace_connect_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_trace_connect_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_random_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_random_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_ASroute_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_ASroute_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_bypassRoute_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_bypassRoute_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      STag_surfxml_bypassASroute_cb_list =
-          xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      ETag_surfxml_bypassASroute_cb_list =
-          xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_peer_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_peer_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    STag_surfxml_include_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_include_cb_list =
-        xbt_dynar_new(sizeof(void_f_void_t), NULL);
-
-    STag_surfxml_storage_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-    ETag_surfxml_storage_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      STag_surfxml_storage_type_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      ETag_surfxml_storage_type_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      STag_surfxml_mount_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      ETag_surfxml_mount_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      STag_surfxml_mstorage_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
-      ETag_surfxml_mstorage_cb_list = xbt_dynar_new(sizeof(void_f_void_t), NULL);
+    sg_platf_init();
 }
 
 void surf_parse_reset_callbacks(void)
@@ -306,47 +228,10 @@ void surf_parse_reset_callbacks(void)
 
 void surf_parse_free_callbacks(void)
 {
-  sg_platf_exit(); // FIXME: better place?
-
-  xbt_dynar_free(&STag_surfxml_route_cb_list);
-  xbt_dynar_free(&ETag_surfxml_route_cb_list);
-  xbt_dynar_free(&STag_surfxml_link_ctn_cb_list);
-  xbt_dynar_free(&ETag_surfxml_link_ctn_cb_list);
-  xbt_dynar_free(&STag_surfxml_process_cb_list);
-  xbt_dynar_free(&ETag_surfxml_process_cb_list);
-  xbt_dynar_free(&STag_surfxml_argument_cb_list);
-  xbt_dynar_free(&ETag_surfxml_argument_cb_list);
-  xbt_dynar_free(&STag_surfxml_prop_cb_list);
-  xbt_dynar_free(&ETag_surfxml_prop_cb_list);
-  xbt_dynar_free(&STag_surfxml_trace_cb_list);
-  xbt_dynar_free(&ETag_surfxml_trace_cb_list);
-  xbt_dynar_free(&STag_surfxml_trace_connect_cb_list);
-  xbt_dynar_free(&ETag_surfxml_trace_connect_cb_list);
-  xbt_dynar_free(&STag_surfxml_random_cb_list);
-  xbt_dynar_free(&ETag_surfxml_random_cb_list);
-  xbt_dynar_free(&STag_surfxml_ASroute_cb_list);
-  xbt_dynar_free(&ETag_surfxml_ASroute_cb_list);
-  xbt_dynar_free(&STag_surfxml_bypassRoute_cb_list);
-  xbt_dynar_free(&ETag_surfxml_bypassRoute_cb_list);
-  xbt_dynar_free(&STag_surfxml_bypassASroute_cb_list);
-  xbt_dynar_free(&ETag_surfxml_bypassASroute_cb_list);
-  xbt_dynar_free(&STag_surfxml_peer_cb_list);
-  xbt_dynar_free(&ETag_surfxml_peer_cb_list);
-  xbt_dynar_free(&STag_surfxml_include_cb_list);
-  xbt_dynar_free(&ETag_surfxml_include_cb_list);
-
-  xbt_dynar_free(&STag_surfxml_storage_cb_list);
-  xbt_dynar_free(&ETag_surfxml_storage_cb_list);
-  xbt_dynar_free(&STag_surfxml_mstorage_cb_list);
-  xbt_dynar_free(&ETag_surfxml_mstorage_cb_list);
-  xbt_dynar_free(&STag_surfxml_mount_cb_list);
-  xbt_dynar_free(&ETag_surfxml_mount_cb_list);
-  xbt_dynar_free(&STag_surfxml_storage_type_cb_list);
-  xbt_dynar_free(&ETag_surfxml_storage_type_cb_list);
+  sg_platf_exit();
 }
 
 /* Stag and Etag parse functions */
-void ETag_surfxml_router(void)  { /* ignored -- do not add content here */ }
 
 void STag_surfxml_platform(void) {
   _XBT_GNUC_UNUSED double version = surf_parse_get_double(A_surfxml_platform_version);
@@ -378,9 +263,30 @@ void ETag_surfxml_platform(void){
 }
 
 void STag_surfxml_host(void){
+  AS_TAG = 0;
   xbt_assert(current_property_set == NULL, "Someone forgot to reset the property set to NULL in its closing tag (or XML malformed)");
 }
 
+void STag_surfxml_prop(void)
+{
+  if(AS_TAG){
+    if (!as_current_property_set){
+      xbt_assert(as_prop_nb < 1024, "Number of AS property reach the limit!!!");
+      as_current_property_set = xbt_dict_new_homogeneous(xbt_free_f); // Maybe, it should raise an error
+      as_name_tab[as_prop_nb] = xbt_strdup(A_surfxml_AS_id);
+      as_dict_tab[as_prop_nb] = as_current_property_set;
+      XBT_DEBUG("PUSH prop %p for AS '%s'",as_dict_tab[as_prop_nb],as_name_tab[as_prop_nb]);
+      as_prop_nb++;
+    }
+    xbt_dict_set(as_current_property_set, A_surfxml_prop_id, xbt_strdup(A_surfxml_prop_value), NULL);
+  }
+  else{
+    if (!current_property_set)
+      current_property_set = xbt_dict_new_homogeneous(xbt_free_f); // Maybe, it should raise an error
+    xbt_dict_set(current_property_set, A_surfxml_prop_id, xbt_strdup(A_surfxml_prop_value), NULL);
+  }
+}
+
 void ETag_surfxml_host(void)    {
   s_sg_platf_host_cbarg_t host;
   memset(&host,0,sizeof(host));
@@ -416,10 +322,6 @@ void STag_surfxml_host_link(void){
   sg_platf_new_host_link(&host_link);
 }
 
-void ETag_surfxml_host_link(void){
-  XBT_DEBUG("End create a Host_link for %s",A_surfxml_host_link_id);
-}
-
 void STag_surfxml_router(void){
   s_sg_platf_router_cbarg_t router;
   memset(&router, 0, sizeof(router));
@@ -479,9 +381,6 @@ void STag_surfxml_cluster(void){
   cluster.state_trace = A_surfxml_cluster_state_file;
   sg_platf_new_cluster(&cluster);
 }
-void ETag_surfxml_cluster(void){
-  /* nothing I can think of */
-}
 
 void STag_surfxml_cabinet(void){
   s_sg_platf_cabinet_cbarg_t cabinet;
@@ -496,9 +395,6 @@ void STag_surfxml_cabinet(void){
 
   sg_platf_new_cabinet(&cabinet);
 }
-void ETag_surfxml_cabinet(void){
-  /* nothing I can think of */
-}
 
 void STag_surfxml_peer(void){
   s_sg_platf_peer_cbarg_t peer;
@@ -514,17 +410,12 @@ void STag_surfxml_peer(void){
 
   sg_platf_new_peer(&peer);
 }
-void ETag_surfxml_peer(void){
-  /* nothing to do here */
-}
+
 void STag_surfxml_link(void){
+  AS_TAG = 0;
   xbt_assert(current_property_set == NULL, "Someone forgot to reset the property set to NULL in its closing tag (or XML malformed)");
 }
 
-void STag_surfxml_backbone(void){
-  /* nothing to do here */
-}
-
 void ETag_surfxml_link(void){
   s_sg_platf_link_cbarg_t link;
   memset(&link,0,sizeof(link));
@@ -570,6 +461,27 @@ void ETag_surfxml_link(void){
   current_property_set = NULL;
 }
 
+void STag_surfxml_link_ctn(void){
+
+  char *link_id;
+  switch (A_surfxml_link_ctn_direction) {
+  case AU_surfxml_link_ctn_direction:
+  case A_surfxml_link_ctn_direction_NONE:
+    link_id = xbt_strdup(A_surfxml_link_ctn_id);
+    break;
+  case A_surfxml_link_ctn_direction_UP:
+    link_id = bprintf("%s_UP", A_surfxml_link_ctn_id);
+    break;
+  case A_surfxml_link_ctn_direction_DOWN:
+    link_id = bprintf("%s_DOWN", A_surfxml_link_ctn_id);
+    break;
+  }
+
+  // FIXME we should push the surf link object but it don't
+  // work because of model rulebased
+  xbt_dynar_push(parsed_link_list, &link_id);
+}
+
 void ETag_surfxml_backbone(void){
   s_sg_platf_link_cbarg_t link;
   memset(&link,0,sizeof(link));
@@ -584,48 +496,208 @@ void ETag_surfxml_backbone(void){
 
   sg_platf_new_link(&link);
   routing_cluster_add_backbone(xbt_lib_get_or_null(link_lib, A_surfxml_backbone_id, SURF_LINK_LEVEL));
-  current_property_set = NULL;
 }
 
 void STag_surfxml_route(void){
-  surfxml_call_cb_functions(STag_surfxml_route_cb_list);
+  xbt_assert(strlen(A_surfxml_route_src) > 0 || strlen(A_surfxml_route_dst) > 0,
+      "Missing end-points while defining route \"%s\"->\"%s\"",
+      A_surfxml_route_src, A_surfxml_route_dst);
+  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
 }
-void STag_surfxml_link_ctn(void){
-  surfxml_call_cb_functions(STag_surfxml_link_ctn_cb_list);
+
+void STag_surfxml_ASroute(void){
+  xbt_assert(strlen(A_surfxml_ASroute_src) > 0 || strlen(A_surfxml_ASroute_dst) > 0
+      || strlen(A_surfxml_ASroute_gw_src) > 0 || strlen(A_surfxml_ASroute_gw_dst) > 0,
+      "Missing end-points while defining route \"%s\"->\"%s\" (with %s and %s as gateways)",
+      A_surfxml_ASroute_src, A_surfxml_ASroute_dst,
+      A_surfxml_ASroute_gw_src,A_surfxml_ASroute_gw_dst);
+  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
 }
-void STag_surfxml_process(void){
-  surfxml_call_cb_functions(STag_surfxml_process_cb_list);
+
+void STag_surfxml_bypassRoute(void){
+  xbt_assert(strlen(A_surfxml_bypassRoute_src) > 0 || strlen(A_surfxml_bypassRoute_dst) > 0,
+      "Missing end-points while defining bupass route \"%s\"->\"%s\"",
+      A_surfxml_bypassRoute_src, A_surfxml_bypassRoute_dst);
+  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
 }
-void STag_surfxml_argument(void){
-  surfxml_call_cb_functions(STag_surfxml_argument_cb_list);
+
+void STag_surfxml_bypassASroute(void){
+  xbt_assert(strlen(A_surfxml_bypassASroute_src) > 0 || strlen(A_surfxml_bypassASroute_dst) > 0
+      || strlen(A_surfxml_bypassASroute_gw_src) > 0 || strlen(A_surfxml_bypassASroute_gw_dst) > 0,
+      "Missing end-points while defining route \"%s\"->\"%s\" (with %s and %s as gateways)",
+      A_surfxml_bypassASroute_src, A_surfxml_bypassASroute_dst,
+      A_surfxml_bypassASroute_gw_src,A_surfxml_bypassASroute_gw_dst);
+  parsed_link_list = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
+}
+
+void ETag_surfxml_route(void){
+  s_sg_platf_route_cbarg_t route;
+  memset(&route,0,sizeof(route));
+
+  route.src = A_surfxml_route_src;
+  route.dst = A_surfxml_route_dst;
+  route.gw_src = NULL;
+  route.gw_dst = NULL;
+  route.link_list = parsed_link_list;
+
+  switch (A_surfxml_route_symmetrical) {
+  case AU_surfxml_route_symmetrical:
+  case A_surfxml_route_symmetrical_YES:
+    route.symmetrical = TRUE;
+    break;
+  case A_surfxml_route_symmetrical_NO:
+    route.symmetrical = FALSE;;
+    break;
+  }
+
+  sg_platf_new_route(&route);
+  parsed_link_list = NULL;
+}
+
+void ETag_surfxml_ASroute(void){
+  s_sg_platf_route_cbarg_t ASroute;
+  memset(&ASroute,0,sizeof(ASroute));
+
+  ASroute.src = A_surfxml_ASroute_src;
+  ASroute.dst = A_surfxml_ASroute_dst;
+
+  if (!strcmp(current_routing->model_desc->name,"RuleBased")) {
+    // DIRTY PERL HACK AHEAD: with the rulebased routing, the {src,dst}_gateway fields
+    // store the provided name instead of the entity directly (model_rulebased_parse_ASroute knows)
+    //
+    // This is because the user will provide something like "^AS_(.*)$" instead of the proper name of a given entity
+    ASroute.gw_src = (sg_routing_edge_t) A_surfxml_ASroute_gw_src;
+    ASroute.gw_dst = (sg_routing_edge_t) A_surfxml_ASroute_gw_dst;
+  } else {
+    ASroute.gw_src = sg_routing_edge_by_name_or_null(A_surfxml_ASroute_gw_src);
+    ASroute.gw_dst = sg_routing_edge_by_name_or_null(A_surfxml_ASroute_gw_dst);
+  }
+
+  ASroute.link_list = parsed_link_list;
+
+  switch (A_surfxml_ASroute_symmetrical) {
+  case AU_surfxml_ASroute_symmetrical:
+  case A_surfxml_ASroute_symmetrical_YES:
+    ASroute.symmetrical = TRUE;
+    break;
+  case A_surfxml_ASroute_symmetrical_NO:
+    ASroute.symmetrical = FALSE;
+    break;
+  }
+
+  sg_platf_new_ASroute(&ASroute);
+  parsed_link_list = NULL;
+}
+
+void ETag_surfxml_bypassRoute(void){
+  s_sg_platf_route_cbarg_t route;
+  memset(&route,0,sizeof(route));
+
+  route.src = A_surfxml_bypassRoute_src;
+  route.dst = A_surfxml_bypassRoute_dst;
+  route.gw_src = NULL;
+  route.gw_dst = NULL;
+  route.link_list = parsed_link_list;
+  route.symmetrical = FALSE;
+
+  sg_platf_new_bypassRoute(&route);
+  parsed_link_list = NULL;
 }
-void STag_surfxml_prop(void){
-  surfxml_call_cb_functions(STag_surfxml_prop_cb_list);
+
+void ETag_surfxml_bypassASroute(void){
+  s_sg_platf_route_cbarg_t ASroute;
+  memset(&ASroute,0,sizeof(ASroute));
+
+  ASroute.src = A_surfxml_bypassASroute_src;
+  ASroute.dst = A_surfxml_bypassASroute_dst;
+  ASroute.link_list = parsed_link_list;
+  ASroute.symmetrical = FALSE;
+
+  if (!strcmp(current_routing->model_desc->name,"RuleBased")) {
+    // DIRTY PERL HACK AHEAD: with the rulebased routing, the {src,dst}_gateway fields
+    // store the provided name instead of the entity directly (model_rulebased_parse_ASroute knows)
+    //
+    // This is because the user will provide something like "^AS_(.*)$" instead of the proper name of a given entity
+    ASroute.gw_src = (sg_routing_edge_t) A_surfxml_bypassASroute_gw_src;
+    ASroute.gw_dst = (sg_routing_edge_t) A_surfxml_bypassASroute_gw_dst;
+  } else {
+    ASroute.gw_src = sg_routing_edge_by_name_or_null(A_surfxml_bypassASroute_gw_src);
+    ASroute.gw_dst = sg_routing_edge_by_name_or_null(A_surfxml_bypassASroute_gw_dst);
+  }
+
+  sg_platf_new_bypassASroute(&ASroute);
+  parsed_link_list = NULL;
 }
-void STag_surfxml_trace(void){
-  surfxml_call_cb_functions(STag_surfxml_trace_cb_list);
+
+void ETag_surfxml_trace(void){
+  s_sg_platf_trace_cbarg_t trace;
+  memset(&trace,0,sizeof(trace));
+
+  trace.id = A_surfxml_trace_id;
+  trace.file = A_surfxml_trace_file;
+  trace.periodicity = surf_parse_get_double(A_surfxml_trace_periodicity);
+  trace.pc_data = surfxml_pcdata;
+
+  sg_platf_new_trace(&trace);
 }
+
 void STag_surfxml_trace_connect(void){
-  surfxml_call_cb_functions(STag_surfxml_trace_connect_cb_list);
+  s_sg_platf_trace_connect_cbarg_t trace_connect;
+  memset(&trace_connect,0,sizeof(trace_connect));
+
+  trace_connect.element = A_surfxml_trace_connect_element;
+  trace_connect.trace = A_surfxml_trace_connect_trace;
+
+  switch (A_surfxml_trace_connect_kind) {
+  case AU_surfxml_trace_connect_kind:
+  case A_surfxml_trace_connect_kind_POWER:
+    trace_connect.kind =  SURF_TRACE_CONNECT_KIND_POWER;
+    break;
+  case A_surfxml_trace_connect_kind_BANDWIDTH:
+    trace_connect.kind =  SURF_TRACE_CONNECT_KIND_BANDWIDTH;
+    break;
+  case A_surfxml_trace_connect_kind_HOST_AVAIL:
+    trace_connect.kind =  SURF_TRACE_CONNECT_KIND_HOST_AVAIL;
+    break;
+  case A_surfxml_trace_connect_kind_LATENCY:
+    trace_connect.kind =  SURF_TRACE_CONNECT_KIND_LATENCY;
+    break;
+  case A_surfxml_trace_connect_kind_LINK_AVAIL:
+    trace_connect.kind =  SURF_TRACE_CONNECT_KIND_LINK_AVAIL;
+    break;
+  }
+  sg_platf_new_trace_connect(&trace_connect);
 }
+
 void STag_surfxml_AS(void){
-  sg_platf_new_AS_begin(A_surfxml_AS_id, (int)A_surfxml_AS_routing);
+  AS_TAG = 1;
+  s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
+  AS.id = A_surfxml_AS_id;
+  AS.routing = (int)A_surfxml_AS_routing;
+
+  as_current_property_set = NULL;
+
+  sg_platf_new_AS_begin(&AS);
 }
 void ETag_surfxml_AS(void){
+  if(as_prop_nb){
+    char *name = as_name_tab[as_prop_nb-1];
+    xbt_dict_t dict = as_dict_tab[as_prop_nb-1];
+    as_prop_nb--;
+    XBT_DEBUG("POP prop %p for AS '%s'",dict,name);
+    xbt_lib_set(as_router_lib,
+        name,
+      ROUTING_PROP_ASR_LEVEL,
+      dict);
+    xbt_free(name);
+  }
   sg_platf_new_AS_end();
 }
-void STag_surfxml_ASroute(void){
-  surfxml_call_cb_functions(STag_surfxml_ASroute_cb_list);
-}
-void STag_surfxml_bypassRoute(void){
-  surfxml_call_cb_functions(STag_surfxml_bypassRoute_cb_list);
-}
-void STag_surfxml_bypassASroute(void){
-  surfxml_call_cb_functions(STag_surfxml_bypassASroute_cb_list);
-}
+
 void STag_surfxml_config(void){
-  XBT_DEBUG("START configuration name = %s",A_surfxml_config_id);
+  AS_TAG = 0;
   xbt_assert(current_property_set == NULL, "Someone forgot to reset the property set to NULL in its closing tag (or XML malformed)");
+  XBT_DEBUG("START configuration name = %s",A_surfxml_config_id);
 }
 void ETag_surfxml_config(void){
   xbt_dict_cursor_t cursor = NULL;
@@ -642,27 +714,66 @@ void ETag_surfxml_config(void){
   }
   XBT_DEBUG("End configuration name = %s",A_surfxml_config_id);
   xbt_dict_free(&current_property_set);
+  current_property_set = NULL;
 }
-void STag_surfxml_random(void){
-  surfxml_call_cb_functions(STag_surfxml_random_cb_list);
+
+static int argc;
+static char **argv;
+
+void STag_surfxml_process(void){
+  AS_TAG = 0;
+  argc = 1;
+  argv = xbt_new(char *, 1);
+  argv[0] = xbt_strdup(A_surfxml_process_function);
+  xbt_assert(current_property_set == NULL, "Someone forgot to reset the property set to NULL in its closing tag (or XML malformed)");
 }
 
-#define parse_method(type,name)                                         \
-  void type##Tag_surfxml_##name(void)                                   \
-  { surfxml_call_cb_functions(type##Tag_surfxml_##name##_cb_list); }    \
-  void type##Tag_surfxml_##name(void)
+void ETag_surfxml_process(void){
+  s_sg_platf_process_cbarg_t process;
+  memset(&process,0,sizeof(process));
+
+  process.argc = argc;
+  process.argv = (const char **)argv;
+  process.properties = current_property_set;
+  process.host = A_surfxml_process_host;
+  process.function = A_surfxml_process_function;
+  process.start_time = surf_parse_get_double(A_surfxml_process_start_time);
+  process.kill_time = surf_parse_get_double(A_surfxml_process_kill_time);
+
+  switch (A_surfxml_process_on_failure) {
+  case AU_surfxml_process_on_failure:
+  case A_surfxml_process_on_failure_DIE:
+    process.on_failure =  SURF_PROCESS_ON_FAILURE_DIE;
+    break;
+  case A_surfxml_process_on_failure_RESTART:
+    process.on_failure =  SURF_PROCESS_ON_FAILURE_RESTART;
+    break;
+  }
+
+  sg_platf_new_process(&process);
+  current_property_set = NULL;
+}
 
-parse_method(E, route);
-parse_method(E, link_ctn);
-parse_method(E, process);
-parse_method(E, argument);
-parse_method(E, prop);
-parse_method(E, trace);
-parse_method(E, trace_connect);
-parse_method(E, random);
-parse_method(E, ASroute);
-parse_method(E, bypassRoute);
-parse_method(E, bypassASroute);
+void STag_surfxml_argument(void){
+  argc++;
+  argv = xbt_realloc(argv, (argc) * sizeof(char *));
+  argv[(argc) - 1] = xbt_strdup(A_surfxml_argument_value);
+}
+
+/* nothing to do in those functions */
+void ETag_surfxml_prop(void){}
+void STag_surfxml_random(void){}
+void ETag_surfxml_random(void){}
+void ETag_surfxml_trace_connect(void){}
+void STag_surfxml_trace(void){}
+void ETag_surfxml_router(void){}
+void ETag_surfxml_host_link(void){}
+void ETag_surfxml_cluster(void){}
+void ETag_surfxml_cabinet(void){}
+void ETag_surfxml_peer(void){}
+void STag_surfxml_backbone(void){}
+void ETag_surfxml_link_ctn(void){}
+void ETag_surfxml_argument(void){}
 
 /* Open and Close parse file */
 
@@ -718,56 +829,11 @@ static int _surf_parse(void) {
 int_f_void_t surf_parse = _surf_parse;
 
 
-/* Aux parse functions */
-
-void surfxml_add_callback(xbt_dynar_t cb_list, void_f_void_t function)
-{
-  xbt_dynar_push(cb_list, &function);
-}
-
-void surfxml_del_callback(xbt_dynar_t cb_list, void_f_void_t function)
-{
-  xbt_ex_t e;
-  unsigned int it=0;
-  void_f_void_t null_f=NULL;
-
-  TRY {
-    it = xbt_dynar_search(cb_list,&function);
-  }
-  CATCH(e) {
-    if (e.category == not_found_error) {
-      xbt_ex_free(e);
-      xbt_die("Trying to remove a callback that is not here! This should not happen");
-    }
-    RETHROW;
-  }
-
-  xbt_dynar_replace(cb_list, it,&null_f);
-}
-
-static XBT_INLINE void surfxml_call_cb_functions(xbt_dynar_t cb_list)
-{
-  unsigned int iterator;
-  void_f_void_t fun;
-  xbt_dynar_foreach(cb_list, iterator, fun) {
-    if (fun) fun();
-  }
-}
-
-
 /* Prop tag functions */
 
 /**
  * With XML parser
  */
-void parse_properties(void)
-{
-  if (!current_property_set)
-    current_property_set = xbt_dict_new_homogeneous(xbt_free_f); // Maybe, it should raise an error
-
-  xbt_dict_set(current_property_set, A_surfxml_prop_id, xbt_strdup(A_surfxml_prop_value), NULL);
-}
-
 
 /* Random tag functions */
 
@@ -835,3 +901,9 @@ static void add_randomness(void)
                &xbt_free_ref);
 }
 
+
+xbt_dict_t get_as_router_properties(const char* name)
+{
+  return xbt_lib_get_or_null(as_router_lib, name, ROUTING_PROP_ASR_LEVEL);
+}
+
index 9555060..b86540c 100644 (file)
@@ -60,84 +60,14 @@ xbt_dict_t trace_connect_list_link_avail = NULL;
 xbt_dict_t trace_connect_list_bandwidth = NULL;
 xbt_dict_t trace_connect_list_latency = NULL;
 
-static double trace_periodicity = -1.0;
-static char *trace_file = NULL;
-static char *trace_id = NULL;
-
-static void parse_Stag_trace(void)
-{
-  trace_id = xbt_strdup(A_surfxml_trace_id);
-  trace_file = xbt_strdup(A_surfxml_trace_file);
-  trace_periodicity = surf_parse_get_double(A_surfxml_trace_periodicity);
-}
-
-static void parse_Etag_trace(void)
-{
-  tmgr_trace_t trace;
-  if (!trace_file || strcmp(trace_file, "") != 0) {
-    trace = tmgr_trace_new_from_file(trace_file);
-  } else if (strcmp(surfxml_pcdata, "") == 0) {
-      trace = NULL;
-  } else {
-      trace =
-          tmgr_trace_new_from_string(trace_id, surfxml_pcdata,
-                                     trace_periodicity);
-  }
-  xbt_dict_set(traces_set_list, trace_id, (void *) trace, NULL);
-  xbt_free(trace_file);
-  trace_file = NULL;
-  xbt_free(trace_id);
-  trace_id = NULL;
-}
-
-static void parse_Stag_trace_connect(void)
-{
-  xbt_assert(xbt_dict_get_or_null
-              (traces_set_list, A_surfxml_trace_connect_trace),
-              "Cannot connect trace %s to %s: trace unknown",
-              A_surfxml_trace_connect_trace,
-              A_surfxml_trace_connect_element);
-
-  switch (A_surfxml_trace_connect_kind) {
-  case A_surfxml_trace_connect_kind_HOST_AVAIL:
-    xbt_dict_set(trace_connect_list_host_avail,
-                 A_surfxml_trace_connect_trace,
-                 xbt_strdup(A_surfxml_trace_connect_element), NULL);
-    break;
-  case A_surfxml_trace_connect_kind_POWER:
-    xbt_dict_set(trace_connect_list_power, A_surfxml_trace_connect_trace,
-                 xbt_strdup(A_surfxml_trace_connect_element), NULL);
-    break;
-  case A_surfxml_trace_connect_kind_LINK_AVAIL:
-    xbt_dict_set(trace_connect_list_link_avail,
-                 A_surfxml_trace_connect_trace,
-                 xbt_strdup(A_surfxml_trace_connect_element), NULL);
-    break;
-  case A_surfxml_trace_connect_kind_BANDWIDTH:
-    xbt_dict_set(trace_connect_list_bandwidth,
-                 A_surfxml_trace_connect_trace,
-                 xbt_strdup(A_surfxml_trace_connect_element), NULL);
-    break;
-  case A_surfxml_trace_connect_kind_LATENCY:
-    xbt_dict_set(trace_connect_list_latency, A_surfxml_trace_connect_trace,
-                 xbt_strdup(A_surfxml_trace_connect_element), NULL);
-    break;
-  default:
-    xbt_die("Cannot connect trace %s to %s: kind of trace unknown",
-            A_surfxml_trace_connect_trace, A_surfxml_trace_connect_element);
-    break;
-  }
-}
-
 /* This function acts as a main in the parsing area. */
 void parse_platform_file(const char *file)
 {
   int parse_status;
 
-  surf_parse_reset_callbacks();
+  surf_parse_init_callbacks();
 
   /* Register classical callbacks */
-  surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties);
   storage_register_callbacks();
   routing_register_callbacks();
 
@@ -158,11 +88,6 @@ void parse_platform_file(const char *file)
   trace_connect_list_bandwidth = xbt_dict_new_homogeneous(free);
   trace_connect_list_latency = xbt_dict_new_homogeneous(free);
 
-  surfxml_add_callback(STag_surfxml_trace_cb_list, &parse_Stag_trace);
-  surfxml_add_callback(ETag_surfxml_trace_cb_list, &parse_Etag_trace);
-  surfxml_add_callback(STag_surfxml_trace_connect_cb_list,
-             &parse_Stag_trace_connect);
-
   /* Do the actual parsing */
   parse_status = surf_parse();
 
index aa70a21..e2a61fe 100644 (file)
@@ -34,33 +34,112 @@ XBT_INLINE void tmgr_history_free(tmgr_history_t h)
   free(h);
 }
 
-tmgr_trace_t tmgr_trace_new_from_generator(const char *id,
-                                          probabilist_event_generator_t generator1,
-                                          probabilist_event_generator_t generator2,
-                                          int is_state_trace)
+
+/**
+ * \brief Create a #tmgr_trace_t from probabilist generators
+ *
+ * This trace will generate an infinite set of events.
+ * It needs two #probabilist_event_generator_t. The date when the event are
+ * triggered is directed by date_generator, and will be interpreted as seconds.
+ * The value of the event is set by value_generator. The value should be between
+ * 0 and 1.
+ *
+ * \param id The name of the trace
+ * \param date_generator The #probabilist_event_generator_t which generates the time
+ *        between two events
+ * \param generator2 The #probabilist_event_generator_t which generates the value
+ *        of each events.
+ * \return The new #tmgr_trace_t
+ */
+tmgr_trace_t tmgr_trace_generator_value(const char *id,
+                                  probabilist_event_generator_t date_generator,
+                                  probabilist_event_generator_t value_generator)
 {
   tmgr_trace_t trace = NULL;
 
   trace = xbt_new0(s_tmgr_trace_t, 1);
   trace->type = e_trace_probabilist;
 
-  trace->s_probabilist.event_generator[0] = generator1;
+  trace->s_probabilist.event_generator[0] = date_generator;
+  trace->s_probabilist.event_generator[1] = value_generator;
+  trace->s_probabilist.is_state_trace = 0;
 
-  //FIXME : may also be a parameter
-  trace->s_probabilist.next_event = 0;
-  trace->s_probabilist.is_state_trace = is_state_trace;
+  return trace;
+}
 
-  if(generator2 != NULL) {
-    trace->s_probabilist.event_generator[1] = generator2;
-  } else if(is_state_trace) {
-    trace->s_probabilist.event_generator[1] = generator1;
-  } else {
-    THROW_IMPOSSIBLE; //That case should have been checked before, anyway...
-  }
+/**
+ * \brief Create a #tmgr_trace_t from probabilist generators
+ *
+ * This trace will generate an infinite set of events. Value of the events
+ * will be alternatively 0 and 1, so this should be used as a state trace.
+ *
+ * \param id The name of the trace
+ * \param date_generator The #probabilist_event_generator_t which generates the time
+ *        between two events
+ * \param first_event_value Set the first event value
+ * \return The new #tmgr_trace_t
+ */
+tmgr_trace_t tmgr_trace_generator_state(const char *id,
+                                  probabilist_event_generator_t date_generator,
+                                  e_surf_resource_state_t first_event_value)
+{
+  tmgr_trace_t trace = NULL;
+
+  trace = xbt_new0(s_tmgr_trace_t, 1);
+  trace->type = e_trace_probabilist;
+
+  trace->s_probabilist.event_generator[0] = date_generator;
+  trace->s_probabilist.event_generator[1] = date_generator;
+  trace->s_probabilist.is_state_trace = 1;
+  trace->s_probabilist.next_event = (first_event_value==SURF_RESOURCE_ON ? 1 : 0);
+
+  return trace;
+}
+
+/**
+ * \brief Create a #tmgr_trace_t from probabilist generators
+ *
+ * This trace will generate an infinite set of events. Value of the events
+ * will be alternatively 0 and 1, so this should be used as a state trace.
+ *
+ * \param id The name of the trace
+ * \param avail_duration_generator The #probabilist_event_generator_t which
+ *        set the duration of the available state, (ie 1 value)
+ * \param unavail_duration_generator The #probabilist_event_generator_t which
+ *        set the duration of the unavailable state, (ie 0 value)
+ * \param first_event_value Set the first event value
+ * \return The new #tmgr_trace_t
+ */
+tmgr_trace_t tmgr_trace_generator_avail_unavail(const char *id,
+                                probabilist_event_generator_t avail_duration_generator,
+                                probabilist_event_generator_t unavail_duration_generator,
+                                e_surf_resource_state_t first_event_value)
+{
+  tmgr_trace_t trace = NULL;
+
+  trace = xbt_new0(s_tmgr_trace_t, 1);
+  trace->type = e_trace_probabilist;
+
+  trace->s_probabilist.event_generator[0] = unavail_duration_generator;
+  trace->s_probabilist.event_generator[1] = avail_duration_generator;
+  trace->s_probabilist.is_state_trace = 1;
+  trace->s_probabilist.next_event = (first_event_value==SURF_RESOURCE_ON ? 1 : 0);
 
   return trace;
 }
 
+/**
+ * \brief Create a new #probabilist_event_generator_t following the uniform distribution
+ *
+ * This generator will generate uniformly distributed random values between min and max
+ * The id is important : it controls the seed of the generator. So, generators with the
+ * same id and the same parameters will generate the same values.
+ *
+ * \param id The name of the generator
+ * \param min The minimal generated value
+ * \param max The maximal generated value
+ * \return a new #probabilist_event_generator_t
+ */
 probabilist_event_generator_t tmgr_event_generator_new_uniform(const char* id,
                                                                double min,
                                                                double max)
@@ -81,6 +160,19 @@ probabilist_event_generator_t tmgr_event_generator_new_uniform(const char* id,
   return event_generator;
 }
 
+
+/**
+ * \brief Create a new #probabilist_event_generator_t following the exponential distribution
+ *
+ * This generator will generate random values following the exponential distribution.
+ * The mean value is 1/rate .
+ * The id is important : it controls the seed of the generator. So, generators with the
+ * same id and the same parameters will generate the same values.
+ *
+ * \param id The name of the generator
+ * \param rate The rate parameter
+ * \return a new #probabilist_event_generator_t
+ */
 probabilist_event_generator_t tmgr_event_generator_new_exponential(const char* id,
                                                                    double rate)
 {
@@ -99,6 +191,18 @@ probabilist_event_generator_t tmgr_event_generator_new_exponential(const char* i
   return event_generator;
 }
 
+/**
+ * \brief Create a new #probabilist_event_generator_t following the weibull distribution
+ *
+ * This generator will generate random values following the weibull distribution.
+ * The id is important : it controls the seed of the generator. So, generators with the
+ * same id and the same parameters will generate the same values.
+ *
+ * \param id The name of the generator
+ * \param scale The scale parameter
+ * \param shape The shape parameter
+ * \return a new #probabilist_event_generator_t
+ */
 probabilist_event_generator_t tmgr_event_generator_new_weibull(const char* id,
                                                                double scale,
                                                                double shape)
@@ -118,7 +222,11 @@ probabilist_event_generator_t tmgr_event_generator_new_weibull(const char* id,
 
   return event_generator;
 }
-
+/**
+ * \brief Get the next random value of a #probabilist_event_generator_t
+ * \param generator The #probabilist_event_generator_t
+ * \return the next random value
+ */
 double tmgr_event_generator_next_value(probabilist_event_generator_t generator)
 {
 
@@ -342,16 +450,17 @@ tmgr_trace_event_t tmgr_history_get_next_event_leq(tmgr_history_t h,
         *value = (double) trace->s_probabilist.next_event;
         if(trace->s_probabilist.next_event == 0) {
           event_delta = tmgr_event_generator_next_value(trace->s_probabilist.event_generator[0]);
-          trace->s_probabilist.next_event = 0;
+          trace->s_probabilist.next_event = 1;
         } else {
           event_delta = tmgr_event_generator_next_value(trace->s_probabilist.event_generator[1]);
-          trace->s_probabilist.next_event = 1;
+          trace->s_probabilist.next_event = 0;
         }
       } else {
         event_delta = tmgr_event_generator_next_value(trace->s_probabilist.event_generator[0]);
         *value = tmgr_event_generator_next_value(trace->s_probabilist.event_generator[1]);
       }
       xbt_heap_push(h->heap, trace_event, event_date + event_delta);
+      XBT_DEBUG("Generating a new event at date %f, with value %f", event_date + event_delta, *value);
 
       break;
   }
index 62797b0..30d3365 100644 (file)
@@ -343,6 +343,22 @@ static surf_action_t ws_action_stat(void *workstation, surf_file_t stream)
   return model->extension.storage.stat(st,  stream);
 }
 
+static surf_action_t ws_action_unlink(void *workstation, surf_file_t stream)
+{
+  storage_t st = find_storage_on_mount_list(workstation, stream->storage);
+  XBT_DEBUG("UNLINK on disk '%s'",st->generic_resource.name);
+  surf_model_t model = st->generic_resource.model;
+  return model->extension.storage.unlink(st,  stream);
+}
+
+static surf_action_t ws_action_ls(void *workstation, const char* mount, const char *path)
+{
+  XBT_DEBUG("LS on mount '%s' and file '%s'",mount, path);
+  storage_t st = find_storage_on_mount_list(workstation, mount);
+  surf_model_t model = st->generic_resource.model;
+  return model->extension.storage.ls(st, path);
+}
+
 static void surf_workstation_model_init_internal(void)
 {
   surf_workstation_model = surf_model_init();
@@ -400,6 +416,8 @@ static void surf_workstation_model_init_internal(void)
   surf_workstation_model->extension.workstation.read = ws_action_read;
   surf_workstation_model->extension.workstation.write = ws_action_write;
   surf_workstation_model->extension.workstation.stat = ws_action_stat;
+  surf_workstation_model->extension.workstation.unlink = ws_action_unlink;
+  surf_workstation_model->extension.workstation.ls = ws_action_ls;
 }
 
 void surf_workstation_model_init_current_default(void)
index 8211efc..64e0982 100644 (file)
@@ -19,7 +19,7 @@
 void mfree(struct mdesc *mdp, void *ptr)
 {
   int type;
-  size_t block;
+  size_t block, frag_nb;
   register size_t i;
   struct list *prev, *next;
   int it;
@@ -149,6 +149,10 @@ void mfree(struct mdesc *mdp, void *ptr)
       ((char *) ADDRESS(block) +
        (mdp->heapinfo[block].busy_frag.first << type));
 
+    /* Set size used in the fragment to 0 */
+    frag_nb = RESIDUAL(ptr, BLOCKSIZE) >> type;
+    mdp->heapinfo[block].busy_frag.frag_size[frag_nb] = 0;
+
     if (mdp->heapinfo[block].busy_frag.nfree ==
         (BLOCKSIZE >> type) - 1) {
       /* If all fragments of this block are free, remove them
@@ -191,8 +195,7 @@ void mfree(struct mdesc *mdp, void *ptr)
        it is the first free fragment of this block. */
       prev = (struct list *) ptr;
       mdp->heapinfo[block].busy_frag.nfree = 1;
-      mdp->heapinfo[block].busy_frag.first =
-        RESIDUAL(ptr, BLOCKSIZE) >> type;
+      mdp->heapinfo[block].busy_frag.first = frag_nb;
       prev->next = mdp->fraghead[type].next;
       prev->prev = &mdp->fraghead[type];
       prev->prev->next = prev;
index e61c97f..3935b9f 100644 (file)
@@ -14,35 +14,55 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mm_diff, xbt,
 
 extern char *xbt_binary_name;
 
-void mmalloc_backtrace_block_display(void* heapinfo, size_t block){
+xbt_dynar_t mmalloc_ignore;
+
+typedef struct s_heap_area_pair{
+  int block1;
+  int fragment1;
+  int block2;
+  int fragment2;
+}s_heap_area_pair_t, *heap_area_pair_t;
+
+static void heap_area_pair_free(heap_area_pair_t pair);
+static void heap_area_pair_free_voidp(void *d);
+static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2);
+static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2);
+
+static int compare_area(void *area1, void* area2, size_t size, xbt_dynar_t previous, int check_ignore);
+static void match_equals(xbt_dynar_t list);
+
+static int in_mmalloc_ignore(int block, int fragment);
+static size_t heap_comparison_ignore(void *address);
+
+void mmalloc_backtrace_block_display(void* heapinfo, int block){
 
   xbt_ex_t e;
 
   if (((malloc_info *)heapinfo)[block].busy_block.bt_size == 0) {
-    fprintf(stderr,"No backtrace available for that block, sorry.\n");
+    XBT_DEBUG("No backtrace available for that block, sorry.");
     return;
   }
 
   memcpy(&e.bt,&(((malloc_info *)heapinfo)[block].busy_block.bt),sizeof(void*)*XBT_BACKTRACE_SIZE);
-e.used = ((malloc_info *)heapinfo)[block].busy_block.bt_size;
+  e.used = ((malloc_info *)heapinfo)[block].busy_block.bt_size;
 
   xbt_ex_setup_backtrace(&e);
   if (e.used == 0) {
-    fprintf(stderr, "(backtrace not set)\n");
+    XBT_DEBUG("(backtrace not set)");
   } else if (e.bt_strings == NULL) {
-    fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet");
+    XBT_DEBUG("(backtrace not ready to be computed. %s)",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet");
   } else {
     int i;
 
-    fprintf(stderr, "Backtrace of where the block %zu was malloced (%d frames):\n", block ,e.used);
+    XBT_DEBUG("Backtrace of where the block %d was malloced (%d frames):", block ,e.used);
     for (i = 0; i < e.used; i++)       /* no need to display "xbt_backtrace_display" */{
-      fprintf(stderr,"%d",i);fflush(NULL);
-      fprintf(stderr, "---> %s\n", e.bt_strings[i] + 4);
+      XBT_DEBUG("%d ---> %s",i, e.bt_strings[i] + 4);
     }
   }
+
 }
 
-void mmalloc_backtrace_fragment_display(void* heapinfo, size_t block, size_t frag){
+void mmalloc_backtrace_fragment_display(void* heapinfo, int block, int frag){
 
   xbt_ex_t e;
 
@@ -51,585 +71,646 @@ void mmalloc_backtrace_fragment_display(void* heapinfo, size_t block, size_t fra
 
   xbt_ex_setup_backtrace(&e);
   if (e.used == 0) {
-    fprintf(stderr, "(backtrace not set)\n");
+    XBT_DEBUG("(backtrace not set)");
   } else if (e.bt_strings == NULL) {
-    fprintf(stderr, "(backtrace not ready to be computed. %s)\n",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet");
+    XBT_DEBUG("(backtrace not ready to be computed. %s)",xbt_binary_name?"Dunno why":"xbt_binary_name not setup yet");
   } else {
     int i;
 
-    fprintf(stderr, "Backtrace of where the fragment %zu in block %zu was malloced (%d frames):\n", frag, block ,e.used);
+    XBT_DEBUG("Backtrace of where the fragment %d in block %d was malloced (%d frames):", frag, block ,e.used);
     for (i = 0; i < e.used; i++)       /* no need to display "xbt_backtrace_display" */{
-      fprintf(stderr,"%d",i);fflush(NULL);
-      fprintf(stderr, "---> %s\n", e.bt_strings[i] + 4);
+      XBT_DEBUG("%d ---> %s",i, e.bt_strings[i] + 4);
     }
   }
-}
-
-int mmalloc_compare_heap(xbt_mheap_t mdp1, xbt_mheap_t mdp2){
-
-  if(mdp1 == NULL && mdp2 == NULL){
-    fprintf(stderr, "Malloc descriptors null\n");
-    return 0;
-  }
-
-  int errors = mmalloc_compare_mdesc(mdp1, mdp2);
-
-  return (errors > 0);
 
 }
 
-void *s_heap;
+void *s_heap, *heapbase1, *heapbase2;
 malloc_info *heapinfo1, *heapinfo2;
-void *heapbase1, *heapbase2;
-size_t heapsize1, heapsize2;
+size_t heaplimit, heapsize1, heapsize2;
 
-int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2){
+int ignore_done;
 
-  int errors = 0;
+int mmalloc_compare_heap(xbt_mheap_t heap1, xbt_mheap_t heap2){
 
-  if(mdp1->heaplimit != mdp2->heaplimit){
-    fprintf(stderr,"Different limit of valid info table indices\n");
-    return 1;
+  if(heap1 == NULL && heap1 == NULL){
+    XBT_DEBUG("Malloc descriptors null");
+    return 0;
   }
 
-  s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
+  if(heap1->heaplimit != heap2->heaplimit){
+    XBT_DEBUG("Different limit of valid info table indices");
+    return 1;
+  }
 
-  fprintf(stderr, "s_heap->heapbase : %p\n", ((struct mdesc*)s_heap)->heapbase);
+  /* Heap information */
+  heaplimit = ((struct mdesc *)heap1)->heaplimit;
 
-  heapbase1 = (char *)mdp1 + BLOCKSIZE;
-  heapbase2 = (char *)mdp2 + BLOCKSIZE;
+  s_heap = (char *)mmalloc_get_current_heap() - STD_HEAP_SIZE - getpagesize();
 
-  fprintf(stderr, "Heapbase1 : %p, Heapbase2 : %p\n", heapbase1, heapbase2);
-  fprintf(stderr, "Heapinfo : %p\n", mdp1->heapinfo);
+  heapbase1 = (char *)heap1 + BLOCKSIZE;
+  heapbase2 = (char *)heap2 + BLOCKSIZE;
 
-  heapinfo1 = (malloc_info *)((char *)mdp1 + ((char *)mdp1->heapinfo - (char *)s_heap));
-  heapinfo2 = (malloc_info *)((char *)mdp2 + ((char *)mdp2->heapinfo - (char *)s_heap));
+  heapinfo1 = (malloc_info *)((char *)heap1 + ((uintptr_t)((char *)heap1->heapinfo - (char *)s_heap)));
+  heapinfo2 = (malloc_info *)((char *)heap2 + ((uintptr_t)((char *)heap2->heapinfo - (char *)s_heap)));
 
-  fprintf(stderr, "Heapinfo1 : %p, Heapinfo2 : %p\n", heapinfo1, heapinfo2);
+  heapsize1 = heap1->heapsize;
+  heapsize2 = heap2->heapsize;
 
-  heapsize1 = mdp1->heapsize;
-  heapsize2 = mdp2->heapsize;
+  /* Start comparison */
+  size_t i1, i2, j1, j2, k, current_block, current_fragment;
+  void *addr_block1, *addr_block2, *addr_frag1, *addr_frag2;
 
-  size_t i, j;
-  void *addr_block1 = NULL, *addr_block2 = NULL, *addr_frag1 = NULL, *addr_frag2 = NULL;
-  size_t frag_size;
+  xbt_dynar_t previous = xbt_dynar_new(sizeof(heap_area_pair_t), heap_area_pair_free_voidp);
 
-  i = 1;
+  int equal, res_compare;
 
-  int k = 0;
-  int distance = 0;
-  int total_distance = 0;
+  ignore_done = 0;
 
-  int pointer_align;
-  void *address_pointed1 = NULL, *address_pointed2 = NULL;
+  /* Init equal information */
+  i1 = 1;
 
-  int block_pointed1, block_pointed2, frag_pointed1, frag_pointed2;
-  void *addr_block_pointed1 = NULL, *addr_block_pointed2 = NULL, *addr_frag_pointed1 = NULL, *addr_frag_pointed2 = NULL;
-
-  /* Check busy blocks*/
+  while(i1<=heaplimit){
+    if(heapinfo1[i1].type == 0){
+      heapinfo1[i1].busy_block.equal_to = -1;
+    }
+    if(heapinfo1[i1].type > 0){
+      for(j1=0; j1 < MAX_FRAGMENT_PER_BLOCK; j1++){
+        heapinfo1[i1].busy_frag.equal_to[j1] = -1;
+      }
+    }
+    i1++; 
+  }
 
-  while(i < mdp1->heaplimit){
+  i2 = 1;
 
-    if(heapinfo1[i].type != heapinfo2[i].type){
-      fprintf(stderr,"Different type of block : %d - %d\n", heapinfo1[i].type, heapinfo2[i].type);
-      errors++;
+  while(i2<=heaplimit){
+    if(heapinfo2[i2].type == 0){
+      heapinfo2[i2].busy_block.equal_to = -1;
     }
+    if(heapinfo2[i2].type > 0){
+      for(j2=0; j2 < MAX_FRAGMENT_PER_BLOCK; j2++){
+        heapinfo2[i2].busy_frag.equal_to[j2] = -1;
+      }
+    }
+    i2++; 
+  }
 
-    /* Get address of block i in each heap */
-    addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
-    addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
-
-    if(heapinfo1[i].type == 0){ /* busy large block */
+  /* Check busy blocks*/
 
-      if(heapinfo1[i].busy_block.size != heapinfo2[i].busy_block.size){
-        fprintf(stderr,"Different size of a large cluster : %zu - %zu\n", heapinfo1[i].busy_block.size, heapinfo2[i].busy_block.size); 
-        fflush(NULL);
-        errors++;
-      }
+  i1 = 1;
 
-      if(heapinfo1[i].busy_block.busy_size != heapinfo2[i].busy_block.busy_size){
-        fprintf(stderr,"Different busy_size of a large cluster : %zu - %zu\n", heapinfo1[i].busy_block.busy_size, heapinfo2[i].busy_block.busy_size); 
-        fflush(NULL);
-        errors++;
-      }
+  while(i1 <= heaplimit){
 
-      /* Hamming distance on different blocks */
-      distance = 0;
+    current_block = i1;
 
+    if(heapinfo1[i1].type == -1){ /* Free block */
+      i1++;
+      continue;
+    }
 
-      for(k=0;k<heapinfo1[i].busy_block.busy_size;k++){
+    addr_block1 = ((void*) (((ADDR2UINT(i1)) - 1) * BLOCKSIZE + (char*)heapbase1));
 
-        if(memcmp(((char *)addr_block1) + k, ((char *)addr_block2) + k, 1) != 0){
+    if(heapinfo1[i1].type == 0){  /* Large block */
 
-          fprintf(stderr, "Different byte (offset=%d) (%p - %p) in block %zu\n", k, (char *)addr_block1 + k, (char *)addr_block2 + k, i); fflush(NULL);
-          
-          /* Check if pointer difference */
-          pointer_align = (k >> sizeof(void*)) * sizeof(void*);
-          address_pointed1 = *((void **)((char *)addr_block1 + pointer_align));
-          address_pointed2 = *((void **)((char *)addr_block2 + pointer_align));
+      if(heapinfo1[i1].busy_block.busy_size == 0){
+        i1++;
+        continue;
+      }
+      
+      i2 = 1;
+      equal = 0;
+      
+      /* Try first to associate to same block in the other heap */
+      if(heapinfo2[current_block].type == heapinfo1[current_block].type){
+        
+        if(heapinfo1[current_block].busy_block.busy_size == heapinfo2[current_block].busy_block.busy_size){
 
-          fprintf(stderr, "Addresses pointed : %p - %p \n", address_pointed1, address_pointed2);
+          addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
           
-          /* Get block number */
-          block_pointed1 = ((char*)address_pointed1 - (char*)((struct mdesc*)s_heap)->heapbase) / BLOCKSIZE + 1;
-          block_pointed2 = ((char*)address_pointed2 - (char*)((struct mdesc*)s_heap)->heapbase) / BLOCKSIZE + 1;
+          add_heap_area_pair(previous, current_block, -1, current_block, -1);
           
-          fprintf(stderr, "Blocks pointed : %d - %d\n", block_pointed1, block_pointed2);
+          if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+            if(in_mmalloc_ignore((int)current_block, -1))
+              res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 1);
+            else
+              res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 0);
+          }else{
+            res_compare = compare_area(addr_block1, addr_block2, heapinfo1[current_block].busy_block.busy_size, previous, 0);
+          }
           
-          if((char *) address_pointed1 < (char*)((struct mdesc*)s_heap)->heapbase || block_pointed1 > heapsize1 || block_pointed1 < 1 || (char *) address_pointed2 < (char*)((struct mdesc*)s_heap)->heapbase || block_pointed2 > heapsize2 || block_pointed2 < 1) {
-            fprintf(stderr, "Unknown pointer(s) ! \n");
-            fflush(NULL);
-            distance++;
-            continue;
+          if(res_compare == 0){
+            for(k=1; k < heapinfo2[current_block].busy_block.size; k++)
+              heapinfo2[current_block+k].busy_block.equal_to = 1 ;
+            for(k=1; k < heapinfo1[current_block].busy_block.size; k++)
+              heapinfo1[current_block+k].busy_block.equal_to = 1 ;
+            equal = 1;
+            match_equals(previous);
+            i1 = i1 + heapinfo1[i1].busy_block.size;
           }
-    
-          addr_block_pointed1 = ((void*) (((ADDR2UINT((size_t)block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
-          addr_block_pointed2 = ((void*) (((ADDR2UINT((size_t)block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
-
-          fprintf(stderr, "Addr blocks pointed : %p - %p\n", addr_block_pointed1, addr_block_pointed2);
 
-          if(heapinfo1[block_pointed1].type == heapinfo2[block_pointed2].type){
-            
-            if(heapinfo1[block_pointed1].type == 0){ // Large block
-              
-              if(heapinfo1[block_pointed1].busy_block.busy_size == heapinfo2[block_pointed2].busy_block.busy_size){
-                
-                if(memcmp(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size) != 0){
-                  distance++;
-                }else{
-                  fprintf(stderr, "False difference detected\n");
-                }
-                
-              }else{
-                distance++;
-              }
-              
-            }else{ // Fragmented block
-
-              /* Get fragment number */
-              frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed1].type;
-              frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed2].type;
-              
-              fprintf(stderr, "Fragments pointed : %d - %d\n", frag_pointed1, frag_pointed2);
-              
-              addr_frag_pointed1 = (char*)addr_block_pointed1 + (frag_pointed1 * (int)pow(2, heapinfo1[block_pointed1].type));
-              addr_frag_pointed2 = (char*)addr_block_pointed2 + (frag_pointed2 * (int)pow(2, heapinfo2[block_pointed2].type));
-
-              fprintf(stderr, "Addr frag pointed : %p - %p\n", addr_frag_pointed1, addr_frag_pointed2);
-              
-              fprintf(stderr, "Size used in fragments pointed : %d - %d\n", heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]);  
-              
-              if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] == heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]){
-                
-                if(memcmp(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1]) != 0){
-                  distance++;
-                }else{
-                  fprintf(stderr, "False difference detected\n");
-                }
-                
-              }else{
-                distance ++;
-              }
-            }
-            
-          }else{
-
-            if(((heapinfo1[block_pointed1].type == 0) && (heapinfo2[block_pointed2].type != 0)) || ((heapinfo1[block_pointed1].type != 0) && (heapinfo2[block_pointed2].type == 0))){  
-              fprintf(stderr, "Pointers on blocks with different types \n");
-              distance++;
-            }else{
-             
-              frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed1].type;
-              frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed2].type;
-              
-              fprintf(stderr, "Fragments pointed : %d - %d\n", frag_pointed1, frag_pointed2);
-              
-              addr_frag_pointed1 = (char*)addr_block_pointed1 + (frag_pointed1 * (int)pow(2, heapinfo1[block_pointed1].type));
-              addr_frag_pointed2 = (char*)addr_block_pointed2 + (frag_pointed2 * (int)pow(2, heapinfo2[block_pointed2].type));
-
-              fprintf(stderr, "Addr frag pointed : %p - %p\n", addr_frag_pointed1, addr_frag_pointed2);
-              
-              fprintf(stderr, "Size used in fragments pointed : %d - %d\n", heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]); 
-              
-              if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] == heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]){
-                                
-                if(memcmp(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1]) != 0){
-                  distance++;
-                }else{
-                  fprintf(stderr, "False difference detected\n");
-                }
-                
-              }else{
-                distance ++;
-              }
-            }
-          }
+          xbt_dynar_reset(previous);
+          
         }
-     
-      }
 
-
-      if(distance>0){
-        fprintf(stderr,"\nDifferent data in large block %zu (size = %zu (in blocks), busy_size = %zu (in bytes))\n", i, heapinfo1[i].busy_block.size, heapinfo1[i].busy_block.busy_size);
-        fflush(NULL);
-        fprintf(stderr, "Hamming distance between blocks : %d\n", distance);
-        mmalloc_backtrace_block_display(heapinfo1, i);
-        mmalloc_backtrace_block_display(heapinfo2, i);
-        fprintf(stderr, "\n");
-        errors++;
-        total_distance += distance;
       }
 
-      i++;
+      while(i2 <= heaplimit && !equal){
 
-    }else{
-
-      if(heapinfo1[i].type > 0){ /* busy fragmented block */
+        if(i2 == current_block){
+          i2++;
+          continue;
+        }
 
-        if(heapinfo1[i].type != heapinfo2[i].type){
-          fprintf(stderr,"Different size of fragments in fragmented block %zu : %d - %d\n", i, heapinfo1[i].type, heapinfo2[i].type); fflush(NULL);
-          errors++;
+        if(heapinfo2[i2].type != 0){
+          i2++;
+          continue;
         }
 
-        if(heapinfo1[i].busy_frag.nfree != heapinfo2[i].busy_frag.nfree){
-          fprintf(stderr,"Different free fragments in fragmented block %zu : %zu - %zu\n", i, heapinfo1[i].busy_frag.nfree, heapinfo2[i].busy_frag.nfree); fflush(NULL);
-          errors++;
+        if(heapinfo2[i2].busy_block.equal_to == 1){         
+          i2++;
+          continue;
+        }
+        
+        if(heapinfo1[i1].busy_block.size != heapinfo2[i2].busy_block.size){
+          i2++;
+          continue;
+        }
+        
+        if(heapinfo1[i1].busy_block.busy_size != heapinfo2[i2].busy_block.busy_size){
+          i2++;
+          continue;
         }
 
-        if(heapinfo1[i].busy_frag.first != heapinfo2[i].busy_frag.first){
-          fprintf(stderr,"Different first free fragment in fragmented block %zu : %zu - %zu\n", i, heapinfo1[i].busy_frag.first, heapinfo2[i].busy_frag.first); fflush(NULL);
-          errors++;
+        addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+
+        /* Comparison */
+        add_heap_area_pair(previous, i1, -1, i2, -1);
+        
+        if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+          if(in_mmalloc_ignore((int)i1, -1))
+            res_compare = compare_area(addr_block1, addr_block2, heapinfo1[i1].busy_block.busy_size, previous, 1);
+          else
+            res_compare = compare_area(addr_block1, addr_block2, heapinfo1[i1].busy_block.busy_size, previous, 0);
+        }else{
+          res_compare = compare_area(addr_block1, addr_block2, heapinfo1[i1].busy_block.busy_size, previous, 0);
+        }
+        
+        if(!res_compare){
+          for(k=1; k < heapinfo2[i2].busy_block.size; k++)
+            heapinfo2[i2+k].busy_block.equal_to = 1;
+          for(k=1; k < heapinfo1[i1].busy_block.size; k++)
+            heapinfo1[i1+k].busy_block.equal_to = 1;
+          equal = 1;
+          match_equals(previous);
         }
 
-        frag_size = pow(2, heapinfo1[i].type);
+        xbt_dynar_reset(previous);
 
-        for(j=0; j< (BLOCKSIZE/frag_size); j++){
+        i2++;
 
-          if(heapinfo1[i].busy_frag.frag_size[j] != heapinfo2[i].busy_frag.frag_size[j]){
-            fprintf(stderr,"Different busy_size for fragment %zu in block %zu : %hu - %hu\n", j, i, heapinfo1[i].busy_frag.frag_size[j], heapinfo2[i].busy_frag.frag_size[j]); fflush(NULL);
-            errors++;
-          }
+      }
 
-          if(heapinfo1[i].busy_frag.frag_size[j] > 0){
+      if(!equal)
+        i1++;
+      
+    }else{ /* Fragmented block */
 
-            addr_frag1 = (char *)addr_block1 + (j * frag_size);
-            addr_frag2 = (char *)addr_block2 + (j * frag_size);
+      for(j1=0; j1 < (size_t) (BLOCKSIZE >> heapinfo1[i1].type); j1++){
 
-            /* Hamming distance on different blocks */
-            distance = 0;
+        current_fragment = j1;
 
-            for(k=0;k<heapinfo1[i].busy_frag.frag_size[j];k++){
+        if(heapinfo1[i1].busy_frag.frag_size[j1] == 0) /* Free fragment */
+          continue;
+        
+        addr_frag1 = (void*) ((char *)addr_block1 + (j1 << heapinfo1[i1].type));
 
-              if(memcmp(((char *)addr_frag1) + k, ((char *)addr_frag2) + k, 1) != 0){
+        i2 = 1;
+        equal = 0;
+        
+        /* Try first to associate to same fragment in the other heap */
+        if(heapinfo2[current_block].type == heapinfo1[current_block].type){
+          
+          if(heapinfo1[current_block].busy_frag.frag_size[current_fragment] == heapinfo2[current_block].busy_frag.frag_size[current_fragment]){
 
-                fprintf(stderr, "Different byte (offset=%d) (%p - %p) in fragment %zu in block %zu\n", k, (char *)addr_frag1 + k, (char *)addr_frag2 + k, j, i); fflush(NULL);
+            addr_block2 = ((void*) (((ADDR2UINT(current_block)) - 1) * BLOCKSIZE + (char*)heapbase2));
+            addr_frag2 = (void*) ((char *)addr_block2 + (current_fragment << heapinfo2[current_block].type));
 
-                pointer_align = (k / sizeof(void*)) * sizeof(void*);
-                address_pointed1 = *((void **)((char *)addr_frag1 + pointer_align));
-                address_pointed2 = *((void **)((char *)addr_frag2 + pointer_align));
-   
-                fprintf(stderr, "Addresses pointed : %p - %p \n", address_pointed1, address_pointed2);
-
-
-                block_pointed1 = ((char*)address_pointed1 - (char*)((struct mdesc*)s_heap)->heapbase) / BLOCKSIZE + 1;
-                block_pointed2 = ((char*)address_pointed2 - (char*)((struct mdesc*)s_heap)->heapbase) / BLOCKSIZE + 1;
-
-                fprintf(stderr, "Blocks pointed : %d - %d\n", block_pointed1, block_pointed2);
-                
-                if((char *) address_pointed1 < (char*)((struct mdesc*)s_heap)->heapbase || block_pointed1 > heapsize1 || block_pointed1 < 1 || (char *) address_pointed2 < (char*)((struct mdesc*)s_heap)->heapbase || block_pointed2 > heapsize2 || block_pointed2 < 1) {
-                  fprintf(stderr, "Unknown pointer(s) ! \n");
-                  fflush(NULL);
-                  distance++;
-                  continue;
-                }
-
-                addr_block_pointed1 = ((void*) (((ADDR2UINT((size_t)block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
-                addr_block_pointed2 = ((void*) (((ADDR2UINT((size_t)block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
-
-                fprintf(stderr, "Addr block pointed : %p - %p\n", addr_block_pointed1, addr_block_pointed2);
-                
-                if(heapinfo1[block_pointed1].type == heapinfo2[block_pointed2].type){
-                  
-                  if(heapinfo1[block_pointed1].type == 0){ // Large block
-                    
-                    if(heapinfo1[block_pointed1].busy_block.busy_size == heapinfo2[block_pointed2].busy_block.busy_size){
-                      
-                      if(memcmp(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size) != 0){
-                        distance++;
-                      }else{
-                        fprintf(stderr, "False difference detected\n");
-                      }
-                      
-                    }else{
-                      distance++;
-                    }
-                    
-                  }else{ // Fragmented block
-                    
-                    frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed1].type;
-                    frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed2].type;
-                            
-                    fprintf(stderr, "Fragments pointed : %d - %d\n", frag_pointed1, frag_pointed2);
-
-                    addr_frag_pointed1 = (char*)addr_block_pointed1 + (frag_pointed1 * (int)pow(2, heapinfo1[block_pointed1].type));
-                    addr_frag_pointed2 = (char*)addr_block_pointed2 + (frag_pointed2 * (int)pow(2, heapinfo2[block_pointed2].type));
-
-                    fprintf(stderr, "Addr frag pointed : %p - %p\n", addr_frag_pointed1, addr_frag_pointed2);
-                    
-                    fprintf(stderr, "Size used in fragments pointed : %d - %d\n", heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]); 
-                                        
-                    if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] == heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]){
-                      
-                      if(memcmp(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1]) != 0){
-                        distance++;
-                      }else{
-                        fprintf(stderr, "False difference detected\n");
-                      }
-                      
-                    }else{
-                      distance ++;
-                    }
-                  }
-
-                }else{
-
-                  if(((heapinfo1[block_pointed1].type == 0) && (heapinfo2[block_pointed2].type != 0)) || ((heapinfo1[block_pointed1].type != 0) && (heapinfo2[block_pointed2].type == 0))){  
-                    fprintf(stderr, "Pointers on blocks with different types \n");
-                    distance++;
-                  }else{
-
-                    frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed1].type;
-                    frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed2].type;
-                   
-                    fprintf(stderr, "Fragments pointed : %d - %d\n", frag_pointed1, frag_pointed2);
-
-                    addr_frag_pointed1 = (char*)addr_block_pointed1 + (frag_pointed1 * (int)pow(2, heapinfo1[block_pointed1].type));
-                    addr_frag_pointed2 = (char*)addr_block_pointed2 + (frag_pointed2 * (int)pow(2, heapinfo2[block_pointed2].type));
-
-                    fprintf(stderr, "Addr frag pointed : %p - %p\n", addr_frag_pointed1, addr_frag_pointed2);
-                                        
-                    fprintf(stderr, "Size used in fragments pointed : %d - %d\n", heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]); 
-                                        
-                    if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] == heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]){
-                      
-                      if(memcmp(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1]) != 0){
-                        distance++;
-                      }else{
-                        fprintf(stderr, "False difference detected\n");
-                      }
-                      
-                    }else{
-                      distance ++;
-                    }
-                  }
-                  
-                }
-              }
+            add_heap_area_pair(previous, current_block, current_fragment, current_block, current_fragment);
+            
+            if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+              if(in_mmalloc_ignore((int)current_block, (int)current_fragment))
+                res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 1);
+              else
+                res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 0);
+            }else{
+              res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[current_block].busy_frag.frag_size[current_fragment], previous, 0);
+            }
 
+            if(res_compare == 0){
+              equal = 1;
+              match_equals(previous);
             }
+            
+            xbt_dynar_reset(previous);
+            
+          }
+
+        }
+
+
+        while(i2 <= heaplimit && !equal){
+          
+          if(heapinfo2[i2].type <= 0){
+            i2++;
+            continue;
+          }
+
+          for(j2=0; j2 < (size_t) (BLOCKSIZE >> heapinfo2[i2].type); j2++){
 
-            if(distance > 0){
-              fprintf(stderr,"\nDifferent data in fragment %zu (size = %zu, size used = %hu) in block %zu \n", j, frag_size, heapinfo1[i].busy_frag.frag_size[j], i);
-              fprintf(stderr, "Hamming distance between fragments : %d\n", distance);
-              mmalloc_backtrace_fragment_display(heapinfo1, i, j);
-              mmalloc_backtrace_fragment_display(heapinfo2, i, j);
-              fprintf(stderr, "\n");
-              errors++;
-              total_distance += distance;
+            if(heapinfo2[i2].type == heapinfo1[i1].type && i2 == current_block && j2 == current_fragment)
+              continue;
 
+            if(heapinfo2[i2].busy_frag.equal_to[j2] == 1)                
+              continue;              
+             
+            if(heapinfo1[i1].busy_frag.frag_size[j1] != heapinfo2[i2].busy_frag.frag_size[j2]) /* Different size_used */    
+              continue;
+             
+            addr_block2 = ((void*) (((ADDR2UINT(i2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+            addr_frag2 = (void*) ((char *)addr_block2 + (j2 << heapinfo2[i2].type));
+             
+            /* Comparison */
+            add_heap_area_pair(previous, i1, j1, i2, j2);
+            
+            if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+              if(in_mmalloc_ignore((int)i1, (int)j1))
+                res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[i1].busy_frag.frag_size[j1], previous, 1);
+              else
+                res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[i1].busy_frag.frag_size[j1], previous, 0);
+            }else{
+              res_compare = compare_area(addr_frag1, addr_frag2, heapinfo1[i1].busy_frag.frag_size[j1], previous, 0);
+            }
+
+            if(!res_compare){
+              equal = 1;
+              match_equals(previous);
+              xbt_dynar_reset(previous);
+              break;
             }
 
+            xbt_dynar_reset(previous);
+
           }
+
+          i2++;
+
         }
 
-        i++;
+      }
 
-      }else{ /* free block */
+      i1++;
+      
+    }
 
-        i++;
+  }
 
+  /* All blocks/fragments are equal to another block/fragment ? */
+  size_t i = 1, j = 0;
+  int nb_diff1 = 0, nb_diff2 = 0;
+  while(i<heaplimit){
+    if(heapinfo1[i].type == 0){
+      if(heapinfo1[i].busy_block.busy_size > 0){
+        if(heapinfo1[i].busy_block.equal_to == -1){
+          if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
+            addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
+            XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block1, heapinfo1[i].busy_block.busy_size);
+            mmalloc_backtrace_block_display((void*)heapinfo1, i);
+          }
+          nb_diff1++;
+        }
       }
+    }
+    if(heapinfo1[i].type > 0){
+      for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo1[i].type); j++){
+        if(heapinfo1[i].busy_frag.frag_size[j] > 0){
+          if(heapinfo1[i].busy_frag.equal_to[j] == -1){
+            if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
+              addr_block1 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase1));
+              addr_frag1 = (void*) ((char *)addr_block1 + (j << heapinfo1[i].type));
+              XBT_DEBUG("Block %zu, Fragment %zu (%p) not found (size used = %d)", i, j, addr_frag1, heapinfo1[i].busy_frag.frag_size[j]);
+              mmalloc_backtrace_fragment_display((void*)heapinfo1, i, j);
+            }
+            nb_diff1++;
+          }
+        }
+      }
+    }
+    
+    i++; 
+  }
+
+  XBT_DEBUG("Different blocks or fragments in heap1 : %d\n", nb_diff1);
+
+  i = 1;
 
+  while(i<heaplimit){
+    if(heapinfo2[i].type == 0){
+      if(heapinfo2[i].busy_block.busy_size > 0){
+        if(heapinfo2[i].busy_block.equal_to == -1){
+          if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
+            addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
+            XBT_DEBUG("Block %zu (%p) not found (size used = %zu)", i, addr_block2, heapinfo2[i].busy_block.busy_size);
+            mmalloc_backtrace_block_display((void*)heapinfo2, i);
+          }
+          nb_diff2++;
+        }
+      }
     }
+    if(heapinfo2[i].type > 0){
+      for(j=0; j < (size_t) (BLOCKSIZE >> heapinfo2[i].type); j++){
+        if(heapinfo2[i].busy_frag.frag_size[j] > 0){
+          if(heapinfo2[i].busy_frag.equal_to[j] == -1){
+            if(XBT_LOG_ISENABLED(mm_diff, xbt_log_priority_debug)){
+              addr_block2 = ((void*) (((ADDR2UINT(i)) - 1) * BLOCKSIZE + (char*)heapbase2));
+              addr_frag2 = (void*) ((char *)addr_block2 + (j << heapinfo2[i].type));
+              XBT_DEBUG( "Block %zu, Fragment %zu (%p) not found (size used = %d)", i, j, addr_frag2, heapinfo2[i].busy_frag.frag_size[j]);
+              mmalloc_backtrace_fragment_display((void*)heapinfo2, i, j);
+            }
+            nb_diff2++;
+          }
+        }
+      }
+    }
+    i++; 
+  }
+
+  XBT_DEBUG("Different blocks or fragments in heap2 : %d\n", nb_diff2);
+
+  xbt_dynar_free(&previous);
+  return ((nb_diff1 > 0) || (nb_diff2 > 0));
+
+}
 
+static int in_mmalloc_ignore(int block, int fragment){
+
+  unsigned int cursor = 0;
+  int start = 0;
+  int end = xbt_dynar_length(mmalloc_ignore) - 1;
+  mc_ignore_region_t region;
+
+  while(start <= end){
+    cursor = (start + end) / 2;
+    region = (mc_ignore_region_t)xbt_dynar_get_as(mmalloc_ignore, cursor, mc_ignore_region_t);
+    if(region->block == block){
+      if(region->fragment == fragment)
+        return 1;
+      if(region->fragment < fragment)
+        start = cursor + 1;
+      if(region->fragment > fragment)
+        end = cursor - 1;
+    }
+    if(region->block < block)
+      start = cursor + 1;
+    if(region->block > block)
+      end = cursor - 1; 
   }
 
+  return 0;
+}
 
-  fprintf(stderr, "Hamming distance between heap regions : %d\n", total_distance);
+static size_t heap_comparison_ignore(void *address){
+  unsigned int cursor = 0;
+  int start = 0;
+  int end = xbt_dynar_length(mmalloc_ignore) - 1;
+  mc_ignore_region_t region;
+
+  while(start <= end){
+    cursor = (start + end) / 2;
+    region = (mc_ignore_region_t)xbt_dynar_get_as(mmalloc_ignore, cursor, mc_ignore_region_t);
+    if(region->address == address)
+      return region->size;
+    if(region->address < address)
+      start = cursor + 1;
+    if(region->address > address)
+      end = cursor - 1;   
+  }
 
-  return (errors);
+  return 0;
 }
 
 
-int compare_area(void *area1, void* area2, size_t size){
+static int compare_area(void *area1, void* area2, size_t size, xbt_dynar_t previous, int check_ignore){
 
-  int distance = 0;
-  int i, pointer_align;
-  void *address_pointed1 = NULL, *address_pointed2 = NULL;
-  int block_pointed1, block_pointed2, frag_pointed1, frag_pointed2;
-  void *addr_block_pointed1 = NULL, *addr_block_pointed2 = NULL, *addr_frag_pointed1 = NULL, *addr_frag_pointed2 = NULL;
-  
-  for(i=0; i<size; i++){
+  size_t i = 0, pointer_align = 0, ignore1 = 0, ignore2 = 0;
+  void *address_pointed1, *address_pointed2, *addr_block_pointed1, *addr_block_pointed2, *addr_frag_pointed1, *addr_frag_pointed2;
+  size_t block_pointed1, block_pointed2, frag_pointed1, frag_pointed2;
+  int res_compare;
+  void *current_area1, *current_area2;
+  while(i<size){
+
+    if(check_ignore){
 
+      current_area1 = (char*)((xbt_mheap_t)s_heap)->heapbase + ((((char *)area1) + i) - (char *)heapbase1);
+      if((ignore1 = heap_comparison_ignore(current_area1)) > 0){
+        current_area2 = (char*)((xbt_mheap_t)s_heap)->heapbase + ((((char *)area2) + i) - (char *)heapbase2);
+        if((ignore2 = heap_comparison_ignore(current_area2))  == ignore1){
+          i = i + ignore2;
+          ignore_done++;
+          continue;
+        }
+      }
+
+    }
+   
     if(memcmp(((char *)area1) + i, ((char *)area2) + i, 1) != 0){
 
       /* Check pointer difference */
       pointer_align = (i / sizeof(void*)) * sizeof(void*);
       address_pointed1 = *((void **)((char *)area1 + pointer_align));
       address_pointed2 = *((void **)((char *)area2 + pointer_align));
-      
+
       /* Get pointed blocks number */ 
-      block_pointed1 = ((char*)address_pointed1 - (char*)((struct mdesc*)s_heap)->heapbase) / BLOCKSIZE + 1;
-      block_pointed2 = ((char*)address_pointed2 - (char*)((struct mdesc*)s_heap)->heapbase) / BLOCKSIZE + 1;
-      
-      /* Check if valid blocks number */
-      if((char *)address_pointed1 < (char*)((struct mdesc*)s_heap)->heapbase || block_pointed1 > heapsize1 || block_pointed1 < 1 || (char *)address_pointed2 < (char*)((struct mdesc*)s_heap)->heapbase || block_pointed2 > heapsize2 || block_pointed2 < 1) {
-        fprintf(stderr, "Unknown pointer(s) ! \n");
-        fflush(NULL);
-        distance++;
-        continue;
-      }
+      block_pointed1 = ((char*)address_pointed1 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
+      block_pointed2 = ((char*)address_pointed2 - (char*)((xbt_mheap_t)s_heap)->heapbase) / BLOCKSIZE + 1;
 
-      /* Get address of pointed block in saved heaps */
-      addr_block_pointed1 = ((void*) (((ADDR2UINT((size_t)block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
-      addr_block_pointed2 = ((void*) (((ADDR2UINT((size_t)block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+      /* Check if valid blocks number */
+      if((char *)address_pointed1 < (char*)((xbt_mheap_t)s_heap)->heapbase || block_pointed1 > heapsize1 || block_pointed1 < 1 || (char *)address_pointed2 < (char*)((xbt_mheap_t)s_heap)->heapbase || block_pointed2 > heapsize2 || block_pointed2 < 1)
+        return 1;
 
       if(heapinfo1[block_pointed1].type == heapinfo2[block_pointed2].type){ /* Same type of block (large or fragmented) */
 
+        addr_block_pointed1 = ((void*) (((ADDR2UINT(block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
+        addr_block_pointed2 = ((void*) (((ADDR2UINT(block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+        
         if(heapinfo1[block_pointed1].type == 0){ /* Large block */
-          
-          if(heapinfo1[block_pointed1].busy_block.busy_size == heapinfo2[block_pointed2].busy_block.busy_size){
-            
-            if(compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size) != 0){
-              /* FIXME : Check temp list of differences */
-              distance++;
+
+          if(heapinfo1[block_pointed1].busy_block.size != heapinfo2[block_pointed2].busy_block.size){
+            return 1;
+          }
+
+          if(heapinfo1[block_pointed1].busy_block.busy_size != heapinfo2[block_pointed2].busy_block.busy_size){
+            return 1;
+          }
+
+          if(add_heap_area_pair(previous, block_pointed1, -1, block_pointed2, -1)){
+
+            if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+              if(in_mmalloc_ignore(block_pointed1, -1))
+                res_compare = compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size, previous, 1);
+              else
+                res_compare = compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size, previous, 0);
             }else{
-              fprintf(stderr, "False difference detected\n");
+              res_compare = compare_area(addr_block_pointed1, addr_block_pointed2, heapinfo1[block_pointed1].busy_block.busy_size, previous, 0);
             }
             
-          }else{
-            /* FIXME : Add blocks in temp list of differences */
-            distance++;
+            if(res_compare)    
+              return 1;
+           
           }
           
         }else{ /* Fragmented block */
 
-           /* Get pointed fragments number */ 
-          frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed1].type;
-          frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed2].type;
-          
-          /* Get address of pointed fragments in saved heaps */
-          addr_frag_pointed1 = (char*)addr_block_pointed1 + (frag_pointed1 * (int)pow(2, heapinfo1[block_pointed1].type));
-          addr_frag_pointed2 = (char*)addr_block_pointed2 + (frag_pointed2 * (int)pow(2, heapinfo2[block_pointed2].type));
-          
-          if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] == heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]){
+          /* Get pointed fragments number */ 
+          frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> heapinfo1[block_pointed1].type;
+          frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> heapinfo2[block_pointed2].type;
+         
+          if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] != heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]) /* Different size_used */    
+            return 1;
             
-            if(compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1]) != 0){
-              /* FIXME : Check in temp list of differences */
-              distance++;
+          addr_frag_pointed1 = (void*) ((char *)addr_block_pointed1 + (frag_pointed1 << heapinfo1[block_pointed1].type));
+          addr_frag_pointed2 = (void*) ((char *)addr_block_pointed2 + (frag_pointed2 << heapinfo2[block_pointed2].type));
+
+          if(add_heap_area_pair(previous, block_pointed1, frag_pointed1, block_pointed2, frag_pointed2)){
+
+            if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+              if(in_mmalloc_ignore(block_pointed1, frag_pointed1))
+                res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 1);
+              else
+                res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
             }else{
-              fprintf(stderr, "False difference detected\n");
+              res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
             }
-            
-          }else{
-            /* FIXME : Check in temp list of differences */
-            distance ++;
+
+            if(res_compare)
+              return 1;
+           
           }
           
         }
           
-      }else{ /* Can be fragmented block with different fragments size but same size_used */
+      }else{
 
-        if(((heapinfo1[block_pointed1].type == 0) && (heapinfo2[block_pointed2].type != 0)) || ((heapinfo1[block_pointed1].type != 0) && (heapinfo2[block_pointed2].type == 0))){  
-     
-          fprintf(stderr, "Pointers on blocks with different types \n");
-          distance++;
-        
-        }else{
-          
-           /* Get pointed fragments number */ 
-          frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed1].type;
-          frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> ((struct mdesc*)s_heap)->heapinfo[block_pointed2].type;
-          
-          /* Get address of pointed fragments in saved heaps */
-          addr_frag_pointed1 = (char*)addr_block_pointed1 + (frag_pointed1 * (int)pow(2, heapinfo1[block_pointed1].type));
-          addr_frag_pointed2 = (char*)addr_block_pointed2 + (frag_pointed2 * (int)pow(2, heapinfo2[block_pointed2].type));
+        if((heapinfo1[block_pointed1].type > 0) && (heapinfo2[block_pointed2].type > 0)){
           
-          if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] == heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]){
-            
-            if(compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1]) != 0){
-              /* FIXME : Check temp list of differences */
-              distance++;
+          addr_block_pointed1 = ((void*) (((ADDR2UINT(block_pointed1)) - 1) * BLOCKSIZE + (char*)heapbase1));
+          addr_block_pointed2 = ((void*) (((ADDR2UINT(block_pointed2)) - 1) * BLOCKSIZE + (char*)heapbase2));
+       
+          frag_pointed1 = ((uintptr_t) (ADDR2UINT (address_pointed1) % (BLOCKSIZE))) >> heapinfo1[block_pointed1].type;
+          frag_pointed2 = ((uintptr_t) (ADDR2UINT (address_pointed2) % (BLOCKSIZE))) >> heapinfo2[block_pointed2].type;
+
+          if(heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1] != heapinfo2[block_pointed2].busy_frag.frag_size[frag_pointed2]) /* Different size_used */    
+            return 1;
+
+          addr_frag_pointed1 = (void*) ((char *)addr_block_pointed1 + (frag_pointed1 << heapinfo1[block_pointed1].type));
+          addr_frag_pointed2 = (void*) ((char *)addr_block_pointed2 + (frag_pointed2 << heapinfo2[block_pointed2].type));
+
+          if(add_heap_area_pair(previous, block_pointed1, frag_pointed1, block_pointed2, frag_pointed2)){
+
+            if(ignore_done < xbt_dynar_length(mmalloc_ignore)){
+              if(in_mmalloc_ignore(block_pointed1, frag_pointed1))
+                res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 1);
+              else
+                res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
             }else{
-              fprintf(stderr, "False difference detected\n");
+              res_compare = compare_area(addr_frag_pointed1, addr_frag_pointed2, heapinfo1[block_pointed1].busy_frag.frag_size[frag_pointed1], previous, 0);
             }
             
-          }else{
-            /* FIXME : Check list of differences */
-            distance ++;
+            if(res_compare)
+              return 1;
+           
           }
-          
-        }
-        
-      }
-    }
-  }
-
-  return distance;
 
-}
+        }else{
+          return 1;
+        }
 
+      }
 
-/* void *get_end_addr_heap(void *heap){ */
+      i = pointer_align + sizeof(void *);
+      
+    }else{
 
-/*   FILE *fp;                     /\* File pointer to process's proc maps file *\/ */
-/*   char *line = NULL;            /\* Temporal storage for each line that is readed *\/ */
-/*   ssize_t read;                 /\* Number of bytes readed *\/ */
-/*   size_t n = 0;                 /\* Amount of bytes to read by getline *\/ */
+      i++;
 
-/*   fp = fopen("/proc/self/maps", "r"); */
+    }
+  }
 
-/*   if(fp == NULL) */
-/*     perror("fopen failed"); */
+  return 0;
+  
 
+}
 
-/*   xbt_dynar_t lfields = NULL; */
-/*   xbt_dynar_t start_end  = NULL; */
-/*   void *start_addr; */
-/*   void *end_addr; */
+static void heap_area_pair_free(heap_area_pair_t pair){
+  if (pair){
+    free(pair);
+    pair = NULL;
+  }
+}
 
-/*   while ((read = getline(&line, &n, fp)) != -1) { */
+static void heap_area_pair_free_voidp(void *d)
+{
+  heap_area_pair_free((heap_area_pair_t) * (void **) d);
+}
 
-/*     xbt_str_trim(line, NULL); */
-/*     xbt_str_strip_spaces(line); */
-/*     lfields = xbt_str_split(line,NULL); */
+static int add_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
 
-/*     start_end = xbt_str_split(xbt_dynar_get_as(lfields, 0, char*), "-"); */
-/*     start_addr = (void *) strtoul(xbt_dynar_get_as(start_end, 0, char*), NULL, 16); */
-/*     end_addr = (void *) strtoul(xbt_dynar_get_as(start_end, 1, char*), NULL, 16); */
+  if(is_new_heap_area_pair(list, block1, fragment1, block2, fragment2)){
+    heap_area_pair_t pair = NULL;
+    pair = xbt_new0(s_heap_area_pair_t, 1);
+    pair->block1 = block1;
+    pair->fragment1 = fragment1;
+    pair->block2 = block2;
+    pair->fragment2 = fragment2;
+    
+    xbt_dynar_push(list, &pair); 
 
-/*     if(start_addr == heap){ */
-/*       free(line); */
-/*       fclose(fp); */
-/*       xbt_dynar_reset(lfields); */
-/*       xbt_free(lfields); */
-/*       xbt_dynar_reset(start_end); */
-/*       xbt_free(start_end); */
-/*       return end_addr; */
-/*     } */
+    return 1;
+  }
 
-/*   } */
+  return 0;
+}
+static int is_new_heap_area_pair(xbt_dynar_t list, int block1, int fragment1, int block2, int fragment2){
+  
+  unsigned int cursor = 0;
+  heap_area_pair_t current_pair;
 
-/*   xbt_dynar_reset(lfields); */
-/*   xbt_free(lfields); */
-/*   xbt_dynar_reset(start_end); */
-/*   xbt_free(start_end); */
-/*   free(line); */
-/*   fclose(fp); */
-/*   return NULL; */
+  xbt_dynar_foreach(list, cursor, current_pair){
+    if(current_pair->block1 == block1 && current_pair->block2 == block2 && current_pair->fragment1 == fragment1 && current_pair->fragment2 == fragment2)
+      return 0; 
+  }
+  
+  return 1;
+}
 
+static void match_equals(xbt_dynar_t list){
 
-/* } */
+  unsigned int cursor = 0;
+  heap_area_pair_t current_pair;
 
+  xbt_dynar_foreach(list, cursor, current_pair){
+    if(current_pair->fragment1 != -1){
+      heapinfo1[current_pair->block1].busy_frag.equal_to[current_pair->fragment1] = 1;
+      heapinfo2[current_pair->block2].busy_frag.equal_to[current_pair->fragment2] = 1;
+    }else{
+      heapinfo1[current_pair->block1].busy_block.equal_to = 1;
+      heapinfo2[current_pair->block2].busy_block.equal_to = 1;
+    }
+  }
 
+}
 
index 5f13f65..e6f796d 100644 (file)
@@ -184,6 +184,7 @@ void *mmalloc(xbt_mheap_t mdp, size_t size)
       block = BLOCK(result);
       for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i) {
         mdp->heapinfo[block].busy_frag.frag_size[i] = 0;
+        mdp->heapinfo[block].busy_frag.equal_to[i] = -1;
         next = (struct list *) ((char *) result + (i << log));
         next->next = mdp->fraghead[log].next;
         next->prev = &mdp->fraghead[log];
@@ -240,8 +241,9 @@ void *mmalloc(xbt_mheap_t mdp, size_t size)
         memset(result, 0, requested_size);
 
         block = BLOCK(result);
-        for (it=0;it<blocks;it++)
+        for (it=0;it<blocks;it++){
           mdp->heapinfo[block+it].type = 0;
+        }
         mdp->heapinfo[block].busy_block.size = blocks;
         mdp->heapinfo[block].busy_block.busy_size = requested_size;
         mdp->heapinfo[block].busy_block.bt_size=xbt_backtrace_no_malloc(mdp->heapinfo[block].busy_block.bt,XBT_BACKTRACE_SIZE);
@@ -276,8 +278,9 @@ void *mmalloc(xbt_mheap_t mdp, size_t size)
         = mdp->heapindex = mdp->heapinfo[block].free_block.next;
     }
 
-    for (it=0;it<blocks;it++)
+    for (it=0;it<blocks;it++){
       mdp->heapinfo[block+it].type = 0;
+    }
     mdp->heapinfo[block].busy_block.size = blocks;
     mdp->heapinfo[block].busy_block.busy_size = requested_size;
     //mdp->heapinfo[block].busy_block.bt_size = 0;
index 34ce8ec..4f61135 100644 (file)
@@ -17,6 +17,7 @@
 #include "xbt/xbt_os_thread.h"
 #include "xbt/mmalloc.h"
 #include "xbt/ex.h"
+#include "xbt/dynar.h"
 #include <semaphore.h>
 #include <stdint.h>
 
@@ -129,13 +130,12 @@ struct mstats
  * The type field is consistently updated for every blocks, even within clusters of blocks.
  * You can crawl the array and rely on that value.
  *
- * TODO:
- *  - make room to store the backtrace of where the blocks and fragment were malloced, too.
  */
 typedef struct {
   int type; /*  0: busy large block
                 >0: busy fragmented (fragments of size 2^type bytes)
                 <0: free block */
+  
   union {
     /* Heap information for a busy block.  */
     struct {
@@ -143,12 +143,14 @@ typedef struct {
       size_t first;           /* First free fragment of the block.  */
       unsigned short frag_size[MAX_FRAGMENT_PER_BLOCK];
       void *bt[MAX_FRAGMENT_PER_BLOCK][XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
+      int equal_to[MAX_FRAGMENT_PER_BLOCK];
     } busy_frag;
     struct {
       size_t size; /* Size (in blocks) of a large cluster.  */
       size_t busy_size; /* Actually used space, in bytes */
       void *bt[XBT_BACKTRACE_SIZE]; /* Where it was malloced (or realloced lastly) */
       int bt_size;
+      int equal_to;
     } busy_block;
     /* Heap information for a free block (that may be the first of a free cluster).  */
     struct {
@@ -238,12 +240,6 @@ struct mdesc {
 
 };
 
-int mmalloc_compare_mdesc(struct mdesc *mdp1, struct mdesc *mdp2);
-
-int compare_area(void *area1, void *area2, size_t size);
-
-//void *get_end_addr_heap(void *s_heap);
-
 /* Bits to look at in the malloc descriptor flags word */
 
 #define MMALLOC_DEVZERO    (1 << 0)        /* Have mapped to /dev/zero */
index 57038c1..3c74fc7 100644 (file)
@@ -1,39 +1,43 @@
-/* file_appender - a dumb log appender which simply prints to stdout        */
+/* file_appender - a dumb log appender which simply prints to a file        */
 
-/* Copyright (c) 2007-2011. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2007-2012. 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 "xbt/sysdep.h"
 #include "xbt/log_private.h"
+#include "smpi/private.h" // to access bench_begin/end. Not ultraclean, I confess
 #include <stdio.h>
 
-/**
- * The root category's default logging function.
- */
-
-extern const char *xbt_log_priority_names[8];
-
+static void append_file(xbt_log_appender_t this_, char *str) {
+  fputs(str, (FILE *) this_->data);
+}
 
-static void append_file(xbt_log_appender_t this_appender, char *str)
-{
-  fputs(str, (FILE *) (this_appender->data));
+static void smpi_append_file(xbt_log_appender_t this_, char *str) {
+  fputs(str, (FILE *) this_->data);
 }
 
-static void free_(xbt_log_appender_t this_)
-{
+static void free_(xbt_log_appender_t this_) {
   if (this_->data != stderr)
     fclose(this_->data);
 }
 
+void __smpi_bench_dont (void); // Stupid prototype
+void __smpi_bench_dont (void) { /* I'm only a place-holder in case we link without SMPI */; }
+void smpi_bench_begin(void) __attribute__ ((weak, alias ("__smpi_bench_dont")));
+void smpi_bench_end(void)   __attribute__ ((weak, alias ("__smpi_bench_dont")));
 
 
-xbt_log_appender_t xbt_log_appender_file_new(char *arg)
-{
+XBT_LOG_EXTERNAL_CATEGORY(smpi); // To detect if SMPI is inited
+
+xbt_log_appender_t xbt_log_appender_file_new(char *arg) {
+
   xbt_log_appender_t res = xbt_new0(s_xbt_log_appender_t, 1);
-  res->do_append = append_file;
+  if (_XBT_LOGV(smpi).initialized) // HACK to detect if we run in SMPI mode. Relies on MAIN__ source disposition
+    res->do_append = smpi_append_file;
+  else
+    res->do_append = append_file;
   res->free_ = free_;
   if (arg)
     res->data = (void *) fopen(arg, "w");
index 2ca0ed6..030dd34 100644 (file)
@@ -23,6 +23,9 @@
 XBT_LOG_NEW_CATEGORY(xbt, "All XBT categories (simgrid toolbox)");
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(module, xbt, "module handling");
 
+XBT_LOG_NEW_CATEGORY(smpi, "All SMPI categories"); /* lives here even if that's a bit odd to solve linking issues: this is used in xbt_log_file_appender to detect whether SMPI is used (and thus whether we should unbench the writing to disk) */
+
+
 char *xbt_binary_name = NULL;   /* Mandatory to retrieve neat backtraces */
 int xbt_initialized = 0;
 
index dc72c91..0f17fcc 100644 (file)
@@ -86,11 +86,11 @@ void xbt_os_sleep(double sec)
 
 struct s_xbt_os_timer {
 #ifdef HAVE_POSIX_GETTIME
-  struct timespec start, stop;
+  struct timespec start, stop, elapse;
 #elif defined(HAVE_GETTIMEOFDAY)
-  struct timeval start, stop;
+  struct timeval start, stop, elapse;
 #else
-  unsigned long int start, stop;
+  unsigned long int start, stop, elapse;
 #endif
 };
 
@@ -104,13 +104,36 @@ void xbt_os_timer_free(xbt_os_timer_t timer)
   free(timer);
 }
 
+void xbt_os_timer_resume(xbt_os_timer_t timer)
+{
+#ifdef HAVE_POSIX_GETTIME
+  timer->elapse.tv_sec += timer->stop.tv_sec - timer->start.tv_sec;
+
+   timer->elapse.tv_nsec += timer->stop.tv_nsec - timer->start.tv_nsec;
+  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(timer->start));
+#elif defined(HAVE_GETTIMEOFDAY)
+  timer->elapse.tv_sec += timer->stop.tv_sec - timer->start.tv_sec;
+
+   timer->elapse.tv_usec += timer->stop.tv_usec - timer->start.tv_usec;
+  gettimeofday(&(timer->start), NULL);
+#else
+  timer->elapse = timer->stop - timer->start;
+  timer->start = (unsigned long int) (time(NULL));
+#endif
+}
+
 void xbt_os_timer_start(xbt_os_timer_t timer)
 {
 #ifdef HAVE_POSIX_GETTIME
+  timer->elapse.tv_sec = 0;
+  timer->elapse.tv_nsec = 0;
   clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(timer->start));
 #elif defined(HAVE_GETTIMEOFDAY)
+  timer->elapse.tv_sec = 0;
+  timer->elapse.tv_usec = 0;
   gettimeofday(&(timer->start), NULL);
 #else
+  timer->elapse = 0;
   timer->start = (unsigned long int) (time(NULL));
 #endif
 }
@@ -130,13 +153,16 @@ double xbt_os_timer_elapsed(xbt_os_timer_t timer)
 {
 #ifdef HAVE_POSIX_GETTIME
   return ((double) timer->stop.tv_sec) - ((double) timer->start.tv_sec) +
+                                          ((double) timer->elapse.tv_sec ) +
       ((((double) timer->stop.tv_nsec) -
-        ((double) timer->start.tv_nsec)) / 1e9);
+        ((double) timer->start.tv_nsec) + ((double) timer->elapse.tv_nsec )) / 1e9);
 #elif defined(HAVE_GETTIMEOFDAY)
-  return ((double) timer->stop.tv_sec) - ((double) timer->start.tv_sec) +
+  return ((double) timer->stop.tv_sec) - ((double) timer->start.tv_sec)
+    + ((double) timer->elapse.tv_sec ) +
       ((((double) timer->stop.tv_usec) -
-        ((double) timer->start.tv_usec)) / 1000000.0);
+        ((double) timer->start.tv_usec) + ((double) timer->elapse.tv_usec )) / 1000000.0);
 #else
-  return (double) timer->stop - (double) timer->start;
+  return (double) timer->stop - (double) timer->start + (double)
+    timer->elapse;
 #endif
 }
index 746092e..a8d06e7 100644 (file)
@@ -903,6 +903,28 @@ char *xbt_str_from_file(FILE * file)
   return res;
 }
 
+/* @brief Retrun 1 if string 'str' starts with string 'start'
+ *
+ * \param str a string
+ * \param start the string to search in str
+ *
+ * \return 1 if 'str' starts with 'start'
+ */
+int xbt_str_start_with(const char* str, const char* start)
+{
+  int i;
+  size_t l_str = strlen(str);
+  size_t l_start = strlen(start);
+
+  if(l_start > l_str) return 0;
+
+  for(i = 0; i< l_start; i++){
+    if(str[i] != start[i]) return 0;
+  }
+
+  return 1;
+}
+
 #ifdef SIMGRID_TEST
 #include "xbt/str.h"
 
index b51d24a..c01e31e 100644 (file)
@@ -79,6 +79,15 @@ int main(int argc, char **argv)
       }
       }
     }
+    if (!strcmp(argv[2], "PROP")) {
+      printf("SG_TEST_mem: %s\n",
+          SD_workstation_get_property_value(SD_workstation_get_by_name("host1"),
+          "SG_TEST_mem")
+          );
+      printf("Author: %s\n", SD_as_router_get_property_value("AS0", "author"));
+      printf("AS1: %s\n", SD_as_router_get_property_value("AS1", "name"));
+      printf("AS2: %s\n", SD_as_router_get_property_value("AS2", "name"));
+    }
   }
 
   SD_exit();
index ccdba5f..eb4bc87 100644 (file)
@@ -2,48 +2,64 @@
 <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
 <platform version="3">
 
-<random id="CustomBandwidth" generator="DRAND48"
-  min="1000000000" max="2000000000" mean="1600000000"
-  std_deviation="12" seed="2147483647" radical="0-1"/>
-  
-<random id="CustomPower" generator="DRAND48"
-  min="0900000000.00" max="1100000000.00" mean="1000000000.00"
-  std_deviation="12" seed="2147483647" radical="0-1"/>
-  
-<random id="RandomVALUE" generator="RNGSTREAM"
-  min="1000000000" max="2000000000" mean="1600000000"
-  std_deviation="12" seed="2147483647"/>
+<config id="General">
+  <prop id="rngstream/seed" value="12345;12345;12345;12345;12345;12345"></prop>
+</config>
+
+<random_law_type id="Core2010" type="discrete_explicite" value="1:0.1;2:0.4;23=0.00001"/>
+<random_law_type id="Core2012" type="discrete_explicite" value="1:0.01;2:0.8;23=0.00001"/>
+
+<random_law_type id="CustomBandwidth" type="uniform" min="1000" max="10000"/>
+<random_law_type id="CustomLatency" type="uniform" min="0.0001" max="0.0002"/>
+<random_law_type id="CustomAvail" type="uniform" min="0" max="1"/>
+
+<random_law_type id="expo01" type="exponential" rate="0.1"/>
+<random_law_type id="wei01" type="weibull" shape="1" scale=".4"/>
+
+<random_state_trace_type id="mystate" availa="expo01" unavail="wei01"/>
+<random_availability_trace_type id="mypow_avail" duration="expo01" value="CustomAvail"/>
+<random_availability_trace_type id="mybw" duration="expo01" value="CustomBandwidth"/>
+<random_availability_trace_type id="mylat" duration="expo01" value="CustomLatency"/>
+
+<random_law_type id="CustomPower" type="uniform" min="10000" max="400000"/>
+<random_law_type id="CustomBWval" type="uniform" min="1000" max="10000"/>
+
+<!--  tentative de description de variables linéairement corrélées. À revoir et confirmer... -->
+<random_law_type id="white" type="Gaussion" mean="1000" max="10000"/>
+<random_core_and_power_type 
+id_core="foo" 
+id_power="Core2010" 
+mode="linear" base="NBcore" linear_a="0.5" linear_b="1000" noise="white"/>
 
 <AS  id="AS0"  routing="Full">
-       
-       <cluster        id="bob_cluster"
-                               prefix="bob"
-                               suffix=".hamburger.edu"
-                               radical="0-1"
-                               power="CustomPower${radical}"
-                               bw="CustomBandwidth${radical}"
-                               lat="5e-5"
-                               bb_bw="2250000000.00"
-                               bb_lat="5e-4"
-                               />
-       
-       <cluster        id="alice_cluster"
-                               prefix="alice"
-                               suffix=".crepe.fr"
-                               radical="0-1"
-                               power="1000000000.00"
-                               bw="1600000000"
-                               lat="5e-5"
-                               bb_bw="2250000000.00"
-                               bb_lat="5e-4"/>
-                               
-       <link id="backbone" bandwidth="1250000000" latency="5E-4"/>  
-               
-       <ASroute src="bob_cluster" dst="alice_cluster" 
-        gw_src="bobbob_cluster_router.hamburger.edu" 
-        gw_dst="alicealice_cluster_router.crepe.fr"
-        symmetrical="YES">
-                       <link_ctn id="backbone"/>
-       </ASroute>   
+  <!-- Horizontal streams -->
+  <host id="foo" power="123121" state_trace="mystate" availability_trace="mypow_avail"/> 
+  <link id="bar" bandwidth=""   bandwidth_trace="mybw" latency_trace="mylat"/>
+  <cluster  id="bob_cluster"
+        prefix="bob"
+        suffix=".hamburger.edu"
+        radical="0-1"
+        power="100000"
+        bw=""
+        lat="5e-5"
+        bb_bw="2250000000.00"
+        bb_lat="5e-4"
+        bw_trace="mybw"
+        availability_trace="mywpow_avail"
+        state_trace="mystate"
+        />
+        
+  <!-- Vertical stream ? -->
+  <peer_set id="peer_home"
+        prefix="home"
+        suffix=".edu"
+        radical="1-10000"
+        power="CustomPower"
+        bw_in_trace="mybw"
+        bw_out="CustomBWval"
+        lat="5e-5"
+        />
+   <peer_set 
+     />
 </AS>  
 </platform>
index 1cd58ee..bdd5613 100644 (file)
@@ -46,49 +46,22 @@ char *warning = NULL;
 void s_process_free(void *process)
 {
   s_process_t *p = (s_process_t *) process;
-  int i;
-  for (i = 0; i < p->argc; i++)
-    free(p->argv[i]);
-  free(p->argv);
   free(p->host);
 }
 
 static s_process_t process;
 
-static void parse_process_init(void)
+static void parse_process(sg_platf_process_cbarg_t process_arg)
 {
-  xbt_dict_set(process_function_set, A_surfxml_process_function, NULL, NULL);
-  xbt_dict_set(machine_set, A_surfxml_process_host, NULL, NULL);
-  process.argc = 1;
-  process.argv = xbt_new(char *, 1);
-  process.argv[0] = xbt_strdup(A_surfxml_process_function);
-  process.host = strdup(A_surfxml_process_host);
+  xbt_dict_set(process_function_set, process_arg->function, NULL, NULL);
+  xbt_dict_set(machine_set, process_arg->host, NULL, NULL);
+  process.argc = process_arg->argc;
+  process.argv = (char**)(process_arg->argv);
+  process.host = strdup(process_arg->host);
   /*XBT_VERB("Function: %s",A_surfxml_process_function); */
-}
-
-static void parse_argument(void)
-{
-  process.argc++;
-  process.argv =
-      xbt_realloc(process.argv, (process.argc) * sizeof(char *));
-  process.argv[(process.argc) - 1] = xbt_strdup(A_surfxml_argument_value);
-}
-
-static void parse_process_finalize(void)
-{
   xbt_dynar_push(process_list, &process);
-  /*XBT_VERB("Function: %s",process.argv[0]); */
 }
 
-/*FIXME Defined in surfxml_parse.c*/
-#ifndef WIN32
-void surfxml_add_callback(xbt_dynar_t cb_list, void_f_void_t function)
-{
-  xbt_dynar_push(cb_list, &function);
-}
-#endif
-
-
 int main(int argc, char *argv[])
 {
   char *project_name = NULL;
@@ -131,11 +104,7 @@ int main(int argc, char *argv[])
   project_name = argv[1];
 
   surf_parse_reset_callbacks();
-  XBT_DEBUG("%p %p", parse_process_init, &parse_process_init);
-  surfxml_add_callback(STag_surfxml_process_cb_list, &parse_process_init);
-  surfxml_add_callback(ETag_surfxml_argument_cb_list, &parse_argument);
-  surfxml_add_callback(ETag_surfxml_process_cb_list,
-                       &parse_process_finalize);
+  sg_platf_process_add_cb(parse_process);
 
   for (i = 2; i < argc; i++) {
     deployment_file = argv[i];
@@ -178,6 +147,9 @@ int main(int argc, char *argv[])
 
   free(warning);
 
+
+  xbt_free(process.argv);
+
   xbt_dict_free(&process_function_set);
   xbt_dynar_free(&process_list);
   xbt_dict_free(&machine_set);
diff --git a/tools/simgrid2vite.sed b/tools/simgrid2vite.sed
new file mode 100644 (file)
index 0000000..a25793b
--- /dev/null
@@ -0,0 +1,6 @@
+/0 1 0 MPI/i \0 ROOT 0 ROOT
+s/0 1 0 MPI/0 1 ROOT MPI/
+s/4 3 0 1 1 MPI_LINK/4 3 ROOT 1 1 MPI_LINK/
+s/1 0 \"/1 root \"/g
+/6 0 1 1/i \6 0 root ROOT 0 "root"
+s/0 PTP/root PTP/g