From: jean-noel quintin Date: Thu, 4 Oct 2012 15:09:16 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/master' X-Git-Tag: v3_8~143 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/ad5734ab76c2c430832004e0e3af55a0378e1c5d?hp=d5fb5a821d7fc68f1327118928ba6861bfe8cc59 Merge remote-tracking branch 'origin/master' --- diff --git a/buildtools/Cmake/AddTests.cmake b/buildtools/Cmake/AddTests.cmake index 9170626088..498e647685 100644 --- a/buildtools/Cmake/AddTests.cmake +++ b/buildtools/Cmake/AddTests.cmake @@ -372,6 +372,7 @@ if(NOT enable_memcheck) 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 bindir=${CMAKE_BINARY_DIR}/examples/simdag --cd ${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 ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv bindir=${CMAKE_HOME_DIRECTORY}/examples/simdag/dax --cd ${CMAKE_BINARY_DIR}/examples/simdag/dax ${CMAKE_HOME_DIRECTORY}/examples/simdag/dax/smalldax.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) ADD_TEST(simdag-test-minmin-scheduling ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --setenv bindir=${CMAKE_BINARY_DIR}/examples/simdag/scheduling --cd ${CMAKE_HOME_DIRECTORY}/examples/simdag/scheduling test_minmin.tesh) diff --git a/buildtools/Cmake/memcheck_tests.cmake b/buildtools/Cmake/memcheck_tests.cmake index e4bb71a930..2dd183153d 100644 --- a/buildtools/Cmake/memcheck_tests.cmake +++ b/buildtools/Cmake/memcheck_tests.cmake @@ -475,6 +475,9 @@ ADD_TEST(memcheck-simdag-test-seq-access-0 ${CMAKE_BINARY_DIR}/examples/simdag/s 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-fail-0 ${CMAKE_BINARY_DIR}/examples/simdag/sd_fail --cd ${CMAKE_HOME_DIRECTORY}/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-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/smalldax.xml --cd ${CMAKE_BINARY_DIR}/examples/simdag/dax/) +ADD_TEST(memcheck-simdag-test-dax-1 cat ./smalldax.trace --cd ${CMAKE_BINARY_DIR}/examples/simdag/dax/) +ADD_TEST(memcheck-simdag-test-dax-2 $ cmake -E remove -f ${srcdir:=.}/smalldax.trace --cd ${CMAKE_BINARY_DIR}/examples/simdag/dax/) 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/) diff --git a/examples/simdag/dax/dax_test.c b/examples/simdag/dax/dax_test.c index 2a873d1288..f27ba96651 100644 --- a/examples/simdag/dax/dax_test.c +++ b/examples/simdag/dax/dax_test.c @@ -58,9 +58,12 @@ int main(int argc, char **argv) SD_create_environment(argv[1]); /* load the DAX file */ - if (!(dax = SD_daxload(argv[2]))){ + dax = SD_daxload(argv[2]); + if (!dax){ + XBT_ERROR("A problem occurred during DAX parsing (cycle or syntax). Do not continue this test"); free(tracefilename); - xbt_die("A problem occurred during parsing. The simulation can't continue."); + SD_exit(); + return -1; } /* Display all the tasks */ diff --git a/examples/simdag/dax/simple_dax_with_cycle.tesh b/examples/simdag/dax/simple_dax_with_cycle.tesh index 7b0e42aea8..5722440d19 100644 --- a/examples/simdag/dax/simple_dax_with_cycle.tesh +++ b/examples/simdag/dax/simple_dax_with_cycle.tesh @@ -1,7 +1,7 @@ #! ./tesh p Test the DAX loader with a DAX comprising a cycle. -! expect signal SIGABRT +! expect return 255 $ $SG_TEST_EXENV ./dax_test --log=no_loc ${srcdir:=.}/../2clusters.xml ${srcdir:=.}/simple_dax_with_cycle.xml > [0.000000] [surf_workstation/INFO] surf_workstation_model_init_ptask_L07 > [0.000000] [sd_daxparse/WARNING] the task root is not marked @@ -9,4 +9,4 @@ $ $SG_TEST_EXENV ./dax_test --log=no_loc ${srcdir:=.}/../2clusters.xml ${srcdir: > [0.000000] [sd_daxparse/WARNING] the task 2@task2 is in a cycle > [0.000000] [sd_daxparse/WARNING] the task 3@task3 is in a cycle > [0.000000] [sd_daxparse/ERROR] The DAX described in simple_dax_with_cycle.xml is not a DAG. It contains a cycle. -> [0.000000] [xbt/CRITICAL] A problem occurred during parsing. The simulation can't continue. +> [0.000000] [test/ERROR] A problem occurred during DAX parsing (cycle or syntax). Do not continue this test diff --git a/examples/simdag/dax/smalldax.tesh b/examples/simdag/dax/smalldax.tesh new file mode 100644 index 0000000000..e3ff1c140c --- /dev/null +++ b/examples/simdag/dax/smalldax.tesh @@ -0,0 +1,123 @@ +#! ./tesh +p Test the DAX loader on a small DAX instance + +$ $SG_TEST_EXENV ${bindir:=.}/dax_test --log=no_loc ${srcdir:=.}/../2clusters.xml ${srcdir:=.}/smalldax.xml +> [0.000000] [surf_workstation/INFO] surf_workstation_model_init_ptask_L07 +> [0.000000] [sd_daxparse/WARNING] Ignoring file o1 size redefinition from 1000000 to 304 +> [0.000000] [sd_daxparse/WARNING] Ignoring file o2 size redefinition from 1000000 to 304 +> [0.000000] [test/INFO] ------------------- Display all tasks of the loaded DAG --------------------------- +> [0.000000] [sd_task/INFO] Displaying task root +> [0.000000] [sd_task/INFO] - state: schedulable not runnable +> [0.000000] [sd_task/INFO] - kind: sequential computation +> [0.000000] [sd_task/INFO] - amount: 0 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 0 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] root_i2_2@task2 +> [0.000000] [sd_task/INFO] root_i1_1@task1 +> [0.000000] [sd_task/INFO] Displaying task 1@task1 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: sequential computation +> [0.000000] [sd_task/INFO] - amount: 42000000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] root_i1_1@task1 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 3@task1 +> [0.000000] [sd_task/INFO] 1@task1_o1_3@task1 +> [0.000000] [sd_task/INFO] Displaying task 2@task2 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: sequential computation +> [0.000000] [sd_task/INFO] - amount: 42000000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] root_i2_2@task2 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 3@task1 +> [0.000000] [sd_task/INFO] 2@task2_o2_3@task1 +> [0.000000] [sd_task/INFO] Displaying task 3@task1 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: sequential computation +> [0.000000] [sd_task/INFO] - amount: 42000000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 4 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] 1@task1 +> [0.000000] [sd_task/INFO] 2@task2 +> [0.000000] [sd_task/INFO] 1@task1_o1_3@task1 +> [0.000000] [sd_task/INFO] 2@task2_o2_3@task1 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 3@task1_o3_end +> [0.000000] [sd_task/INFO] Displaying task root_i2_2@task2 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: end-to-end communication +> [0.000000] [sd_task/INFO] - amount: 1000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] root +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 2@task2 +> [0.000000] [sd_task/INFO] Displaying task 1@task1_o1_3@task1 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: end-to-end communication +> [0.000000] [sd_task/INFO] - amount: 1000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] 1@task1 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 3@task1 +> [0.000000] [sd_task/INFO] Displaying task 2@task2_o2_3@task1 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: end-to-end communication +> [0.000000] [sd_task/INFO] - amount: 1000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] 2@task2 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 3@task1 +> [0.000000] [sd_task/INFO] Displaying task 3@task1_o3_end +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: end-to-end communication +> [0.000000] [sd_task/INFO] - amount: 4167312 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] 3@task1 +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] end +> [0.000000] [sd_task/INFO] Displaying task root_i1_1@task1 +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: end-to-end communication +> [0.000000] [sd_task/INFO] - amount: 1000000 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] root +> [0.000000] [sd_task/INFO] - post-dependencies: +> [0.000000] [sd_task/INFO] 1@task1 +> [0.000000] [sd_task/INFO] Displaying task end +> [0.000000] [sd_task/INFO] - state: not runnable +> [0.000000] [sd_task/INFO] - kind: sequential computation +> [0.000000] [sd_task/INFO] - amount: 0 +> [0.000000] [sd_task/INFO] - Dependencies to satisfy: 1 +> [0.000000] [sd_task/INFO] - pre-dependencies: +> [0.000000] [sd_task/INFO] 3@task1_o3_end +> [0.000000] [test/INFO] ------------------- Schedule tasks --------------------------- +> [0.000000] [test/INFO] ------------------- Run the schedule --------------------------- +> [84.185919] [test/INFO] ------------------- Produce the trace file--------------------------- +> [84.185919] [test/INFO] Producing the trace of the run into ./smalldax.trace + +$ cat ./smalldax.trace +> [0.000000] C1-00 compute 0.000000 # root +> [0.030300] C1-01 compute 42000000000.000000 # 1@task1 +> [0.030300] C1-02 compute 42000000000.000000 # 2@task2 +> [42.060600] C1-03 compute 42000000000.000000 # 3@task1 +> [0.000000] C1-00 send C1-02 1000000.000000 # root_i2_2@task2 +> [0.030300] C1-02 recv C1-00 1000000.000000 # root_i2_2@task2 +> [42.030300] C1-01 send C1-03 1000000.000000 # 1@task1_o1_3@task1 +> [42.060600] C1-03 recv C1-01 1000000.000000 # 1@task1_o1_3@task1 +> [42.030300] C1-02 send C1-03 1000000.000000 # 2@task2_o2_3@task1 +> [42.060600] C1-03 recv C1-02 1000000.000000 # 2@task2_o2_3@task1 +> [84.060600] C1-03 send C1-00 4167312.000000 # 3@task1_o3_end +> [84.185919] C1-00 recv C1-03 4167312.000000 # 3@task1_o3_end +> [0.000000] C1-00 send C1-01 1000000.000000 # root_i1_1@task1 +> [0.030300] C1-01 recv C1-00 1000000.000000 # root_i1_1@task1 +> [84.185919] C1-00 compute 0.000000 # end + +$ cmake -E remove -f ${srcdir:=.}/smalldax.trace diff --git a/examples/simdag/dax/smalldax.xml b/examples/simdag/dax/smalldax.xml new file mode 100644 index 0000000000..3829b9165d --- /dev/null +++ b/examples/simdag/dax/smalldax.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/smpi/CMakeLists.txt b/examples/smpi/CMakeLists.txt index 7abef72ed9..3bf1d3a35a 100644 --- a/examples/smpi/CMakeLists.txt +++ b/examples/smpi/CMakeLists.txt @@ -27,6 +27,9 @@ if(enable_smpi) add_executable(smpi_traced_simple tracing/smpi_traced_simple.c) add_executable(ttest01 ttest01.c) add_executable(vector_test vector_test.c) + add_executable(hvector_test hvector_test.c) + add_executable(indexed_test indexed_test.c) + add_executable(struct_test struct_test.c) add_executable(mc_bugged1 mc_bugged1.c) add_executable(mc_bugged2 mc_bugged2.c) add_executable(smpi_replay replay/replay.c) @@ -51,6 +54,9 @@ if(enable_smpi) target_link_libraries(smpi_traced_simple m simgrid smpi ) target_link_libraries(ttest01 m simgrid smpi ) target_link_libraries(vector_test m simgrid smpi ) + target_link_libraries(hvector_test m simgrid smpi ) + target_link_libraries(indexed_test m simgrid smpi ) + target_link_libraries(struct_test m simgrid smpi ) target_link_libraries(mc_bugged1 m simgrid smpi ) target_link_libraries(mc_bugged2 m simgrid smpi ) target_link_libraries(smpi_replay m simgrid smpi ) @@ -94,6 +100,9 @@ set(examples_src ${CMAKE_CURRENT_SOURCE_DIR}/barrier.c ${CMAKE_CURRENT_SOURCE_DIR}/bcbench.c ${CMAKE_CURRENT_SOURCE_DIR}/vector_test.c + ${CMAKE_CURRENT_SOURCE_DIR}/hvector_test.c + ${CMAKE_CURRENT_SOURCE_DIR}/indexed_test.c + ${CMAKE_CURRENT_SOURCE_DIR}/struct_test.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 diff --git a/examples/smpi/hvector_test.c b/examples/smpi/hvector_test.c new file mode 100644 index 0000000000..86d1a403d3 --- /dev/null +++ b/examples/smpi/hvector_test.c @@ -0,0 +1,42 @@ +#include +#include "mpi.h" +#define SIZE 4 + +int main(int argc, char **argv) { + + int rank, i, j; + double a[SIZE][SIZE]; + + MPI_Datatype columntype; + + MPI_Init(&argc,&argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Type_hvector(SIZE, 1, SIZE*sizeof(double), MPI_DOUBLE, &columntype); + MPI_Type_commit(&columntype); + + + if (rank == 0) { + for(i=0; i + +int main(int argc, char *argv[]) +{ + int rank, size, i; + MPI_Datatype type, type2; + int blocklen[3] = { 2, 3, 1 }; + int displacement[3] = { 0, 3, 8 }; + int buffer[27]; + MPI_Status status; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &size); + if (size < 2) + { + printf("Please run with 2 processes.\n"); + MPI_Finalize(); + return 1; + } + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Type_contiguous(3, MPI_INT, &type2); + MPI_Type_commit(&type2); + MPI_Type_indexed(3, blocklen, displacement, type2, &type); + MPI_Type_commit(&type); + + if (rank == 0) + { + for (i=0; i<27; i++) + buffer[i] = i; + MPI_Send(buffer, 1, type, 1, 123, MPI_COMM_WORLD); + } + + if (rank == 1) + { + for (i=0; i<27; i++) + buffer[i] = -1; + MPI_Recv(buffer, 1, type, 0, 123, MPI_COMM_WORLD, &status); + for (i=0; i<27; i++) + printf("buffer[%d] = %d\n", i, buffer[i]); + fflush(stdout); + } + + MPI_Finalize(); + return 0; +} + diff --git a/examples/smpi/replay/smpi_replay.tesh b/examples/smpi/replay/smpi_replay.tesh index 79e5092d3a..7c4ac38027 100644 --- a/examples/smpi/replay/smpi_replay.tesh +++ b/examples/smpi/replay/smpi_replay.tesh @@ -192,17 +192,16 @@ $ cat ./simgrid.trace > 12 157.673709 2 1 6 > 13 222.850244 2 3 > 12 222.850244 2 3 4 -> 13 222.850244 2 3 -> 7 222.850244 1 3 +> 13 222.850245 2 3 +> 7 222.850245 1 3 > 13 231.413469 2 2 > 12 231.413469 2 2 4 -> 13 231.413469 2 2 -> 7 231.413469 1 2 > 13 231.413469 2 1 > 12 231.413469 2 1 4 -> 13 231.413469 2 1 -> 7 231.413469 1 1 - +> 13 231.413470 2 1 +> 7 231.413470 1 1 +> 13 231.413470 2 2 +> 7 231.413470 1 2 $ rm -f ./simgrid.trace diff --git a/examples/smpi/struct_test.c b/examples/smpi/struct_test.c new file mode 100644 index 0000000000..5c73e385f3 --- /dev/null +++ b/examples/smpi/struct_test.c @@ -0,0 +1,67 @@ +#include +#include "mpi.h" + +int main( argc, argv ) +int argc; +char **argv; +{ + int rank; + struct { int a;int c; double b;int tab[2][3];} value; + MPI_Datatype mystruct; + int blocklens[3]; + MPI_Aint indices[3]; + MPI_Datatype old_types[3], type2; + int i,j; + + MPI_Init( &argc, &argv ); + + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + + int tab[2][3]={{1*rank,2*rank,3*rank},{7*rank,8*rank,9*rank}}; + MPI_Type_contiguous(3, MPI_INT, &type2); + MPI_Type_commit(&type2); + + /* One value of each type, and two for the contiguous one */ + blocklens[0] = 1; + blocklens[1] = 1; + blocklens[2] = 2; + /* The base types */ + old_types[0] = MPI_INT; + old_types[1] = MPI_DOUBLE; + old_types[2] = type2; + /* The locations of each element */ + MPI_Address( &value.a, &indices[0] ); + MPI_Address( &value.b, &indices[1] ); + MPI_Address( &tab, &indices[2] ); + /* Make relative */ + indices[2] = indices[2] - indices[0]; + indices[1] = indices[1] - indices[0]; + indices[0] = 0; + + MPI_Type_struct( 3, blocklens, indices, old_types, &mystruct ); + MPI_Type_commit( &mystruct ); + + if (rank == 0){ + value.a=-2; + value.b=8.0; + }else{ + value.a=10000; + value.b=5.0; + } + + MPI_Bcast( &value, 1, mystruct, 0, MPI_COMM_WORLD ); + + printf( "Process %d got %d (-2?) and %lf (8.0?), tab (should be all 0): ", rank, value.a, value.b ); + + for(j=0; j<2;j++ ) + for(i=0; i<3;i++ ) + printf("%d ", tab[j][i]); + + printf("\n"); + + + /* Clean up the type */ + MPI_Type_free( &mystruct ); + MPI_Finalize( ); + return 0; +} diff --git a/src/smpi/private.h b/src/smpi/private.h index b969e6b9a1..e9227f544a 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -24,8 +24,6 @@ typedef struct s_smpi_process_data *smpi_process_data_t; #define RECV 0x8 -//***************************************************************************************** - // this struct is here to handle the problem of non-contignous data // for each such structure these function should be implemented (vector // index hvector hindex struct) @@ -34,16 +32,6 @@ typedef struct s_smpi_subtype{ void (*unserialize)(const void * input, void *output, size_t count, void* subtype); } s_smpi_subtype_t; -/*one exemple of implementation for the vector is already here*/ -typedef struct s_smpi_mpi_vector{ - s_smpi_subtype_t base; - size_t block_stride; - size_t block_length; - size_t block_count; - MPI_Datatype old_type; - size_t size_oldtype; -} s_smpi_mpi_vector_t; - typedef struct s_smpi_mpi_datatype{ size_t size; /* this let us know if a serialization is required*/ @@ -55,7 +43,6 @@ typedef struct s_smpi_mpi_datatype{ void *substruct; } s_smpi_mpi_datatype_t; - //***************************************************************************************** typedef struct s_smpi_mpi_request { @@ -130,23 +117,6 @@ void smpi_datatype_create(MPI_Datatype* new_type, int size, int has_subtype, voi void smpi_datatype_free(MPI_Datatype* type); void smpi_datatype_commit(MPI_Datatype* datatype); -void unserialize_vector( const void *contiguous_vector, - void *noncontiguous_vector, - size_t count, - void *type); - -void serialize_vector( const void *noncontiguous_vector, - void *contiguous_vector, - size_t count, - void *type); - -s_smpi_mpi_vector_t* smpi_datatype_vector_create( int block_stride, - int block_length, - int block_count, - MPI_Datatype old_type, - int size_oldtype); - - void smpi_empty_status(MPI_Status * status); MPI_Op smpi_op_new(MPI_User_function * function, int commute); void smpi_op_destroy(MPI_Op op); diff --git a/src/smpi/smpi_mpi_dt.c b/src/smpi/smpi_mpi_dt.c index 255e5ca379..b3320611dd 100644 --- a/src/smpi/smpi_mpi_dt.c +++ b/src/smpi/smpi_mpi_dt.c @@ -305,7 +305,7 @@ int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_t }else{ /* in this situation the data are contignous thus it's not * required to serialize and unserialize it*/ - smpi_datatype_create(new_type, count * (blocklen) * + smpi_datatype_create(new_type, count * blocklen * smpi_datatype_size(old_type), 0, NULL, @@ -316,6 +316,91 @@ int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_t return retval; } + + +/* +Hvector Implementation - Vector with stride in bytes +*/ + + +/* + * Copies noncontiguous data into contiguous memory. + * @param contiguous_hvector - output hvector + * @param noncontiguous_hvector - input hvector + * @param type - pointer contening : + * - stride - stride of between noncontiguous data, in bytes + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void serialize_hvector( const void *noncontiguous_hvector, + void *contiguous_hvector, + size_t count, + void *type) +{ + s_smpi_mpi_hvector_t* type_c = (s_smpi_mpi_hvector_t*)type; + int i; + char* contiguous_vector_char = (char*)contiguous_hvector; + char* noncontiguous_vector_char = (char*)noncontiguous_hvector; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(contiguous_vector_char, + noncontiguous_vector_char, type_c->block_length * type_c->size_oldtype); + + contiguous_vector_char += type_c->block_length*type_c->size_oldtype; + noncontiguous_vector_char += type_c->block_stride; + } +} +/* + * Copies contiguous data into noncontiguous memory. + * @param noncontiguous_vector - output hvector + * @param contiguous_vector - input hvector + * @param type - pointer contening : + * - stride - stride of between noncontiguous data, in bytes + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void unserialize_hvector( const void *contiguous_vector, + void *noncontiguous_vector, + size_t count, + void *type) +{ + s_smpi_mpi_hvector_t* type_c = (s_smpi_mpi_hvector_t*)type; + int i; + + char* contiguous_vector_char = (char*)contiguous_vector; + char* noncontiguous_vector_char = (char*)noncontiguous_vector; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(noncontiguous_vector_char, + contiguous_vector_char, type_c->block_length * type_c->size_oldtype); + + contiguous_vector_char += type_c->block_length*type_c->size_oldtype; + noncontiguous_vector_char += type_c->block_stride; + } +} + +/* + * Create a Sub type vector to be able to serialize and unserialize it + * the structre s_smpi_mpi_vector_t is derived from s_smpi_subtype which + * required the functions unserialize and serialize + * + */ +s_smpi_mpi_hvector_t* smpi_datatype_hvector_create( MPI_Aint block_stride, + int block_length, + int block_count, + MPI_Datatype old_type, + int size_oldtype){ + s_smpi_mpi_hvector_t *new_t= xbt_new(s_smpi_mpi_hvector_t,1); + new_t->base.serialize = &serialize_hvector; + new_t->base.unserialize = &unserialize_hvector; + new_t->block_stride = block_stride; + new_t->block_length = block_length; + new_t->block_count = block_count; + new_t->old_type = old_type; + new_t->size_oldtype = size_oldtype; + return new_t; +} + int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) { int retval; @@ -323,20 +408,115 @@ int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) { retval = MPI_ERR_TYPE; } else { - /*FIXME: as for the vector the data should be serialized and - * unserialized moreover a structure derived from s_smpi_subtype should - * be created*/ - smpi_datatype_create(new_type, count * ((blocklen * - smpi_datatype_size(old_type))+stride), - 0, - NULL, - DT_FLAG_VECTOR); - retval=MPI_SUCCESS; + if(stride != blocklen*smpi_datatype_size(old_type)){ + s_smpi_mpi_hvector_t* subtype = smpi_datatype_hvector_create( stride, + blocklen, + count, + old_type, + smpi_datatype_size(old_type)); + + smpi_datatype_create(new_type, count * blocklen * + smpi_datatype_size(old_type), + 1, + subtype, + DT_FLAG_VECTOR); + retval=MPI_SUCCESS; + }else{ + smpi_datatype_create(new_type, count * blocklen * + smpi_datatype_size(old_type), + 0, + NULL, + DT_FLAG_VECTOR); + retval=MPI_SUCCESS; + } } return retval; } +/* +Indexed Implementation +*/ + +/* + * Copies noncontiguous data into contiguous memory. + * @param contiguous_indexed - output indexed + * @param noncontiguous_indexed - input indexed + * @param type - pointer contening : + * - stride - stride of between noncontiguous data + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void serialize_indexed( const void *noncontiguous_indexed, + void *contiguous_indexed, + size_t count, + void *type) +{ + s_smpi_mpi_indexed_t* type_c = (s_smpi_mpi_indexed_t*)type; + int i; + char* contiguous_indexed_char = (char*)contiguous_indexed; + char* noncontiguous_indexed_char = (char*)noncontiguous_indexed; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(contiguous_indexed_char, + noncontiguous_indexed_char, type_c->block_lengths[i] * type_c->size_oldtype); + + contiguous_indexed_char += type_c->block_lengths[i]*type_c->size_oldtype; + noncontiguous_indexed_char = (char*)noncontiguous_indexed + type_c->block_indices[i+1]*type_c->size_oldtype; + } +} +/* + * Copies contiguous data into noncontiguous memory. + * @param noncontiguous_indexed - output indexed + * @param contiguous_indexed - input indexed + * @param type - pointer contening : + * - stride - stride of between noncontiguous data + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void unserialize_indexed( const void *contiguous_indexed, + void *noncontiguous_indexed, + size_t count, + void *type) +{ + s_smpi_mpi_indexed_t* type_c = (s_smpi_mpi_indexed_t*)type; + int i; + + char* contiguous_indexed_char = (char*)contiguous_indexed; + char* noncontiguous_indexed_char = (char*)noncontiguous_indexed; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(noncontiguous_indexed_char, + contiguous_indexed_char, type_c->block_lengths[i] * type_c->size_oldtype); + + contiguous_indexed_char += type_c->block_lengths[i]*type_c->size_oldtype; + noncontiguous_indexed_char = (char*)noncontiguous_indexed + type_c->block_indices[i+1]*type_c->size_oldtype; + } +} + +/* + * Create a Sub type indexed to be able to serialize and unserialize it + * the structre s_smpi_mpi_indexed_t is derived from s_smpi_subtype which + * required the functions unserialize and serialize + */ +s_smpi_mpi_indexed_t* smpi_datatype_indexed_create( int* block_lengths, + int* block_indices, + int block_count, + MPI_Datatype old_type, + int size_oldtype){ + s_smpi_mpi_indexed_t *new_t= xbt_new(s_smpi_mpi_indexed_t,1); + new_t->base.serialize = &serialize_indexed; + new_t->base.unserialize = &unserialize_indexed; + //FIXME : copy those or assume they won't be freed ? + new_t->block_lengths = block_lengths; + new_t->block_indices = block_indices; + new_t->block_count = block_count; + new_t->old_type = old_type; + new_t->size_oldtype = size_oldtype; + return new_t; +} + + int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) { int i; @@ -350,16 +530,103 @@ int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) { retval = MPI_ERR_TYPE; } else { - /*FIXME: as for the vector the data should be serialized and - * unserialized moreover a structure derived from s_smpi_subtype should - * be created*/ - smpi_datatype_create(new_type, (size) * - smpi_datatype_size(old_type),0, NULL, DT_FLAG_DATA); + s_smpi_mpi_indexed_t* subtype = smpi_datatype_indexed_create( blocklens, + indices, + count, + old_type, + smpi_datatype_size(old_type)); + + smpi_datatype_create(new_type, size * + smpi_datatype_size(old_type),1, subtype, DT_FLAG_DATA); retval=MPI_SUCCESS; } return retval; } + +/* +Hindexed Implementation - Indexed with indices in bytes +*/ + +/* + * Copies noncontiguous data into contiguous memory. + * @param contiguous_hindexed - output hindexed + * @param noncontiguous_hindexed - input hindexed + * @param type - pointer contening : + * - stride - stride of between noncontiguous data + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void serialize_hindexed( const void *noncontiguous_hindexed, + void *contiguous_hindexed, + size_t count, + void *type) +{ + s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type; + int i; + char* contiguous_hindexed_char = (char*)contiguous_hindexed; + char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(contiguous_hindexed_char, + noncontiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype); + + contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype; + noncontiguous_hindexed_char = (char*)noncontiguous_hindexed + type_c->block_indices[i+1]; + } +} +/* + * Copies contiguous data into noncontiguous memory. + * @param noncontiguous_hindexed - output hindexed + * @param contiguous_hindexed - input hindexed + * @param type - pointer contening : + * - stride - stride of between noncontiguous data + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void unserialize_hindexed( const void *contiguous_hindexed, + void *noncontiguous_hindexed, + size_t count, + void *type) +{ + s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type; + int i; + + char* contiguous_hindexed_char = (char*)contiguous_hindexed; + char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(noncontiguous_hindexed_char, + contiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype); + + contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype; + noncontiguous_hindexed_char = (char*)noncontiguous_hindexed + type_c->block_indices[i+1]; + } +} + +/* + * Create a Sub type hindexed to be able to serialize and unserialize it + * the structre s_smpi_mpi_hindexed_t is derived from s_smpi_subtype which + * required the functions unserialize and serialize + */ +s_smpi_mpi_hindexed_t* smpi_datatype_hindexed_create( int* block_lengths, + MPI_Aint* block_indices, + int block_count, + MPI_Datatype old_type, + int size_oldtype){ + s_smpi_mpi_hindexed_t *new_t= xbt_new(s_smpi_mpi_hindexed_t,1); + new_t->base.serialize = &serialize_hindexed; + new_t->base.unserialize = &unserialize_hindexed; + //FIXME : copy those or assume they won't be freed ? + new_t->block_lengths = block_lengths; + new_t->block_indices = block_indices; + new_t->block_count = block_count; + new_t->old_type = old_type; + new_t->size_oldtype = size_oldtype; + return new_t; +} + + int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) { int i; @@ -373,15 +640,99 @@ int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Dat if ((old_type->flags & DT_FLAG_COMMITED) != DT_FLAG_COMMITED) { retval = MPI_ERR_TYPE; } else { - /*FIXME: as for the vector the data should be serialized and - * unserialized moreover a structure derived from s_smpi_subtype should - * be created*/ - smpi_datatype_create(new_type,(size * smpi_datatype_size(old_type)), 0,NULL, DT_FLAG_DATA); + s_smpi_mpi_hindexed_t* subtype = smpi_datatype_hindexed_create( blocklens, + indices, + count, + old_type, + smpi_datatype_size(old_type)); + + smpi_datatype_create(new_type, size * + smpi_datatype_size(old_type),1, subtype, DT_FLAG_DATA); retval=MPI_SUCCESS; } return retval; } + +/* +struct Implementation - Indexed with indices in bytes +*/ + +/* + * Copies noncontiguous data into contiguous memory. + * @param contiguous_struct - output struct + * @param noncontiguous_struct - input struct + * @param type - pointer contening : + * - stride - stride of between noncontiguous data + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void serialize_struct( const void *noncontiguous_struct, + void *contiguous_struct, + size_t count, + void *type) +{ + s_smpi_mpi_struct_t* type_c = (s_smpi_mpi_struct_t*)type; + int i; + char* contiguous_struct_char = (char*)contiguous_struct; + char* noncontiguous_struct_char = (char*)noncontiguous_struct; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(contiguous_struct_char, + noncontiguous_struct_char, type_c->block_lengths[i] * smpi_datatype_size(type_c->old_types[i])); + contiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_size(type_c->old_types[i]); + noncontiguous_struct_char = (char*)noncontiguous_struct + type_c->block_indices[i+1]; + } +} +/* + * Copies contiguous data into noncontiguous memory. + * @param noncontiguous_struct - output struct + * @param contiguous_struct - input struct + * @param type - pointer contening : + * - stride - stride of between noncontiguous data + * - block_length - the width or height of blocked matrix + * - count - the number of rows of matrix + */ +void unserialize_struct( const void *contiguous_struct, + void *noncontiguous_struct, + size_t count, + void *type) +{ + s_smpi_mpi_struct_t* type_c = (s_smpi_mpi_struct_t*)type; + int i; + + char* contiguous_struct_char = (char*)contiguous_struct; + char* noncontiguous_struct_char = (char*)noncontiguous_struct; + + for (i = 0; i < type_c->block_count * count; i++) { + memcpy(noncontiguous_struct_char, + contiguous_struct_char, type_c->block_lengths[i] * smpi_datatype_size(type_c->old_types[i])); + contiguous_struct_char += type_c->block_lengths[i]*smpi_datatype_size(type_c->old_types[i]); + noncontiguous_struct_char = (char*)noncontiguous_struct + type_c->block_indices[i+1]; + } +} + +/* + * Create a Sub type struct to be able to serialize and unserialize it + * the structre s_smpi_mpi_struct_t is derived from s_smpi_subtype which + * required the functions unserialize and serialize + */ +s_smpi_mpi_struct_t* smpi_datatype_struct_create( int* block_lengths, + MPI_Aint* block_indices, + int block_count, + MPI_Datatype* old_types){ + s_smpi_mpi_struct_t *new_t= xbt_new(s_smpi_mpi_struct_t,1); + new_t->base.serialize = &serialize_struct; + new_t->base.unserialize = &unserialize_struct; + //FIXME : copy those or assume they won't be freed ? + new_t->block_lengths = block_lengths; + new_t->block_indices = block_indices; + new_t->block_count = block_count; + new_t->old_types = old_types; + return new_t; +} + + int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) { int i; @@ -393,12 +744,15 @@ int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datat return MPI_ERR_TYPE; size += blocklens[i]*smpi_datatype_size(old_types[i]); } - /*FIXME: as for the vector the data should be serialized and - * unserialized moreover a structure derived from s_smpi_subtype should - * be created*/ - smpi_datatype_create(new_type, size, - 0, NULL, - DT_FLAG_DATA); + + + s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create( blocklens, + indices, + count, + old_types); + + smpi_datatype_create(new_type, size ,1, subtype, DT_FLAG_DATA); + return MPI_SUCCESS; } diff --git a/src/smpi/smpi_mpi_dt_private.h b/src/smpi/smpi_mpi_dt_private.h index 374f8f8bc5..89fcd659eb 100644 --- a/src/smpi/smpi_mpi_dt_private.h +++ b/src/smpi/smpi_mpi_dt_private.h @@ -32,4 +32,141 @@ extern MPI_Datatype MPI_PTR; + +//***************************************************************************************** + +/* + These are the structures that handle complex data type information, + used for serialization/unserialization of messages +*/ + +typedef struct s_smpi_mpi_vector{ + s_smpi_subtype_t base; + size_t block_stride; + size_t block_length; + size_t block_count; + MPI_Datatype old_type; + size_t size_oldtype; +} s_smpi_mpi_vector_t; + +typedef struct s_smpi_mpi_hvector{ + s_smpi_subtype_t base; + MPI_Aint block_stride; + size_t block_length; + size_t block_count; + MPI_Datatype old_type; + size_t size_oldtype; +} s_smpi_mpi_hvector_t; + +typedef struct s_smpi_mpi_indexed{ + s_smpi_subtype_t base; + int* block_lengths; + int* block_indices; + size_t block_count; + MPI_Datatype old_type; + size_t size_oldtype; +} s_smpi_mpi_indexed_t; + +typedef struct s_smpi_mpi_hindexed{ + s_smpi_subtype_t base; + int* block_lengths; + MPI_Aint* block_indices; + size_t block_count; + MPI_Datatype old_type; + size_t size_oldtype; +} s_smpi_mpi_hindexed_t; + +typedef struct s_smpi_mpi_struct{ + s_smpi_subtype_t base; + int* block_lengths; + MPI_Aint* block_indices; + size_t block_count; + MPI_Datatype* old_types; +} s_smpi_mpi_struct_t; + +/* + Functions to handle serialization/unserialization of messages, 3 for each type of MPI_Type + One for creating the substructure to handle, one for serialization, one for unserialization +*/ + +void unserialize_vector( const void *contiguous_vector, + void *noncontiguous_vector, + size_t count, + void *type); + +void serialize_vector( const void *noncontiguous_vector, + void *contiguous_vector, + size_t count, + void *type); + +s_smpi_mpi_vector_t* smpi_datatype_vector_create( int block_stride, + int block_length, + int block_count, + MPI_Datatype old_type, + int size_oldtype); + +void unserialize_hvector( const void *contiguous_vector, + void *noncontiguous_vector, + size_t count, + void *type); + +void serialize_hvector( const void *noncontiguous_vector, + void *contiguous_vector, + size_t count, + void *type); + +s_smpi_mpi_hvector_t* smpi_datatype_hvector_create( MPI_Aint block_stride, + int block_length, + int block_count, + MPI_Datatype old_type, + int size_oldtype); + + +void unserialize_indexed( const void *contiguous_indexed, + void *noncontiguous_indexed, + size_t count, + void *type); + +void serialize_indexed( const void *noncontiguous_vector, + void *contiguous_vector, + size_t count, + void *type); + +s_smpi_mpi_indexed_t* smpi_datatype_indexed_create(int* block_lengths, + int* block_indices, + int block_count, + MPI_Datatype old_type, + int size_oldtype); + +void unserialize_hindexed( const void *contiguous_indexed, + void *noncontiguous_indexed, + size_t count, + void *type); + +void serialize_hindexed( const void *noncontiguous_vector, + void *contiguous_vector, + size_t count, + void *type); + +s_smpi_mpi_hindexed_t* smpi_datatype_hindexed_create(int* block_lengths, + MPI_Aint* block_indices, + int block_count, + MPI_Datatype old_type, + int size_oldtype); + +void unserialize_struct( const void *contiguous_indexed, + void *noncontiguous_indexed, + size_t count, + void *type); + +void serialize_struct( const void *noncontiguous_vector, + void *contiguous_vector, + size_t count, + void *type); + +s_smpi_mpi_struct_t* smpi_datatype_struct_create(int* block_lengths, + MPI_Aint* block_indices, + int block_count, + MPI_Datatype* old_types); + #endif