From 02388ff0ed03563cd83068d9e2cbbf49e84f3d20 Mon Sep 17 00:00:00 2001 From: Houjun Tang Date: Wed, 22 Mar 2023 13:46:47 -1000 Subject: [PATCH] Sync from Develop (#72) * Committing clang-format changes * region partition arguments * Committing clang-format changes * Update vpicio_batch.c * Committing clang-format changes * Update vpicio_batch.c * Committing clang-format changes * Additional server timing and PDCflush_obj * Committing clang-format changes * flush all RPCs for PDC cache * Committing clang-format changes * Add flush all to vpicio_batch * Committing clang-format changes * Update vpicio_batch.c * Update vpicio_batch.c * change API name and place flush lock * Committing clang-format changes * Update pdc_obj.c * fix restart timing bug * Committing clang-format changes * flush for vpicio_batch * Committing clang-format changes * Update vpicio_batch.c * remove barriers * Committing clang-format changes * barrier back * Fix HOST_NAME_MAX undefined issue on MacOS * Fix HOST_NAME_MAX undefined issue on MacOS * Dynamic region partition Implementation of dynamic region partitioning. A metadata server dynamically assigns regions to data server depending on the workload. * Committing clang-format changes * Add posix timing * Committing clang-format changes * Rename pdc timing variables * Committing clang-format changes * Update pdc_region_cache.c * Update pdc_timing.c * Committing clang-format changes * Update pdc_timing.c * Update pdc_server.c * Update pdc_server_data.c * Committing clang-format changes * Add region local implementation * Committing clang-format changes * Update pdc_region_transfer.c * fix issues * Committing clang-format changes * Update pdc_region_transfer_metadata_query.c * Committing clang-format changes * Fix bugs * Committing clang-format changes * Update pdc_region_transfer.c * Committing clang-format changes * Mixed region partition type fix * Update pdc_timing.h * Update pdc_timing.h * Update pdc_region_transfer_metadata_query.c * Committing clang-format changes * Fix a dynamic partition bug * Committing clang-format changes * Update CMakeLists.txt * Update CMakeLists.txt * Sort out PDC timing * Update pdc.h * update timer link * Committing clang-format changes * sync with test folder * remove warnings * Update pdc.h * attribute unused. * Committing clang-format changes * Update CMakeLists.txt * Update pdc_client_server_common.c * Committing clang-format changes * Change path * Update CMakeLists.txt * test * Update pdc_timing.h * Metadata separate checkpoint and finalize * Committing clang-format changes * change the cmake layout * Committing clang-format changes * separating implementations into independent files * Committing clang-format changes * missing file * Update CMakeLists.txt * Update CMakeLists.txt * Update CMakeLists.txt * Update CMakeLists.txt * Update pdc_timing.h * Update pdc_region_transfer_metadata_query.c * Fix a dynamic allocation bug * Committing clang-format changes * Update pdc_region_transfer_metadata_query.c * Timing values * obj reset dimension implementation * Committing clang-format changes * solve compile errors * Committing clang-format changes * Update pdc_obj.c * Committing clang-format changes * Fix a bug * Committing clang-format changes * Rename files for consistency * Committing clang-format changes * Fix some conflicts * Cmake changes * Update CMakeLists.txt * Update CMakeLists.txt * Add a new API to set consistency semantics (#56) * Add consistency constants Signed-off-by: Chen Wang * Committing clang-format changes * Ignore install directory Signed-off-by: Chen Wang * Add a new API to set consistency semantics Signed-off-by: Chen Wang * Committing clang-format changes * Copy consistency at transfer creation time Signed-off-by: Chen Wang * Committing clang-format changes * Insert wait calls at transfer/close time depends on the consistency requirement Signed-off-by: Chen Wang * Committing clang-format changes * Use the new semantics setting api in haccio Signed-off-by: Chen Wang * Add a unit test for consistency semantics Signed-off-by: Chen Wang Co-authored-by: github-actions * Update pdc_region_transfer.c * Committing clang-format changes * Update pdc_region_transfer.c * Set dims test * Committing clang-format changes * Fix issues at server cache * Committing clang-format changes * server cache cleanups * Update pdc_server_region_cache.c * Committing clang-format changes * Update pdc_server_region_cache.c * Committing clang-format changes * 2D set dims case * Committing clang-format changes * Update region_transfer_set_dims_2D.c * Fix dimension check bug * error code when error * 3D case for set dims * Update region_transfer_set_dims_3D.c * Update pdc_server_region_cache.c * Committing clang-format changes * Rename PDC folders * Update CMakeLists.txt * Update CMakeLists.txt * Update CMakeLists.txt * change for path * Update CMakeLists.txt * Update pdc_client_server_common.c * Update pdc_client_server_common.c * Committing clang-format changes * reset path * Fix a consistency bug, server metadata structure has to be modified along with local property * Committing clang-format changes * Server files reordering * Update CMakeLists.txt * Update README.md * Update pdc_server_region_cache.h * Update pdc_server_region_cache.c * Fix a metadata ID bug * Committing clang-format changes * Update vpicio_batch.c * Code comments and examples in C++ * Committing clang-format changes * Upload documentation to developer note section. Fixed a bug in vpicio_batch.c * Fix Cmake issues * Committing clang-format changes * Add PDC server cache to cmake * Cori scripts and results * Adding descriptions for running vpicio_batch.c on Cori * Update script_cori_shared.sh * Upload figures used by developer's note * Update readme.md * Include all figures to developer's note * Shrink font size * Update container_hashtable_checkpoint.png * Update documentations to include new APIs * Update struct type documentations with latest implementation * Committing clang-format changes * Add PDC future work * Update readme.md * Fix a couple of issues with MPI and cmake checkpoint * Update CMakeLists.txt * add local partition result * Add vpicio results * Fixed some typos * Add binary to Cmake install directory contents in bin are pdc_server.exe and close_server * Bring develop branch to current branch. * Create CMakeLists.txt * add missing file * Update CMakeLists.txt * Update github CI script * Update github CI script * Update github CI script * Add PDC Tools (#63) * update vol documentation * add tools * update pdc_ls and documentation * remove extraneous files in tools * add cjson * update pdc_ls and tools documentation * update tools documentation * fix undefined behavior * update pdc_import * update pdc tools * fix formatting * Committing clang-format changes * Fix a bug with packing local region buffer * Fix a bug with packing local region buffer * Partially fixed issues with data query * Committing clang-format changes * Remove unnecessary header * Fix compile error * Update linux.yml * Update linux.yml * Fix compile issues * Disable the skewed tests for now * Disable the skewed tests for now * Fix the issue with vpic scaling * Committing clang-format changes * Add multi-step VPIC * Committing clang-format changes * Update documentation for Perlmutter (#69) * Update getting_started.rst * Update getting_started.rst * Add fcommon flag * Change default client lookup to local server only, remove query test * Committing clang-format changes * Update server automatic flush cache to storage mechnism, minor updates to test code * Committing clang-format changes * Change default consistency to eventual * update Cori CI * update Cori CI * temporarily disable test in CI * update tests for parallel CI * update CI dependecy * set distinct directory for each test * include Perlmutter in the CI * fix path for multiple CIs * update compilation for Perlmutter * fix Perlmutter CI * update Perlmutter CI policy * change scheduler parameters * fix to enable Perlmutter CI * fix to enable Perlmutter CI * fix to enable both Cori and Perlmutter CI * further split CI * Update README.md * Update getting_started.rst * remove unnecessary install block from CMakeLists.txt (#73) * Update Readme for better readability (#74) * update the doc * update readme * update readme with `libibverb` instruction * resolve review comments * improve the readability further * review comments * Fix kvtag tests * Committing clang-format changes * Update CMakelist --------- Co-authored-by: github-actions Co-authored-by: Qiao Kang Co-authored-by: Chen Wang Co-authored-by: Qiao Kang Co-authored-by: Qiao Kang Co-authored-by: Jonathan Luo <45892670+JLaoo@users.noreply.github.com> Co-authored-by: Jean Luca Bez Co-authored-by: Zhang Wei --- .github/workflows/linux.yml | 4 +- .gitignore | 3 +- .gitlab-ci.yml | 282 +- {src/CMake => CMake}/FindDRC.cmake | 0 .../pdc-config-version.cmake.in | 0 .../CMake => CMake}/pdc-config.cmake.build.in | 0 .../pdc-config.cmake.install.in | 0 src/CMakeLists.txt => CMakeLists.txt | 66 +- src/CTestConfig.cmake => CTestConfig.cmake | 0 README.md | 249 +- docs/container_hashtable_checkpoint.png | Bin 0 -> 26662 bytes docs/data_hashtable_checkpoint.png | Bin 0 -> 205118 bytes docs/data_server_checkpoint.png | Bin 0 -> 57827 bytes docs/pdc_metadata_flow.png | Bin 0 -> 110183 bytes docs/pdc_plots.pptx | Bin 0 -> 53807 bytes docs/pdc_region_transfer_request_flow.png | Bin 0 -> 177075 bytes docs/readme.md | 612 ++-- docs/source/getting_started.rst | 18 +- docs/source/hdf5vol.rst | 92 +- docs/source/tools.rst | 235 ++ examples/C_plus_plus_example/H5Timing.cc | 223 ++ examples/C_plus_plus_example/H5Timing.h | 80 + examples/C_plus_plus_example/Makefile | 21 + .../multidataset_plugin.cc | 449 +++ .../C_plus_plus_example/multidataset_plugin.h | 47 + .../region_transfer_1D_append.cc | 86 + examples/README.md | 14 +- examples/bdcats.c | 4 +- examples/bdcats_batch.c | 505 +-- examples/bdcats_old.c | 3 - examples/haccio.c | 19 +- examples/haccio_v2.c | 7 +- examples/read_write_col_perf.c | 10 +- examples/read_write_perf.c | 10 +- examples/script_cori_shared.sh | 70 + examples/tileio.c | 14 +- examples/tileio_v2.c | 4 +- examples/vpicio.c | 4 +- examples/vpicio_batch.c | 546 ++-- examples/vpicio_batch_results.png | Bin 0 -> 61654 bytes examples/vpicio_dynamic_partition_4.txt | 69 + examples/vpicio_local_partition_4.txt | 73 + examples/vpicio_object_partition_4.txt | 73 + examples/vpicio_old.c | 8 - examples/vpicio_static_partition_4.txt | 73 + src/api/pdc_config.h.in => pdc_config.h.in | 4 +- ...c_config.h.cmake => pdc_config_sys.h.cmake | 7 +- ...naming_policy.txt => pdc_naming_policy.txt | 0 src/pdc_start => pdc_start | 7 +- src/api/CMakeLists.txt | 113 +- src/api/close_server.c | 60 + src/api/{ => include}/pdc.h | 2 + src/api/{ => include}/pdc_client_connect.h | 112 +- src/api/{ => include}/pdc_public.h | 0 .../{ => pdc_analysis/include}/pdc_analysis.h | 0 .../pdc_analysis_and_transforms_common.h | 0 .../include}/pdc_analysis_pkg.h | 0 .../{ => pdc_analysis/include}/pdc_hist_pkg.h | 0 src/api/{ => pdc_analysis}/pdc_analysis.c | 2 +- .../pdc_analysis_and_transforms_connect.c | 0 .../{ => pdc_analysis}/pdc_analysis_common.c | 2 +- src/api/{ => pdc_analysis}/pdc_hist_pkg.c | 0 src/api/pdc_client_connect.c | 1284 +++++--- src/api/{ => pdc_obj/include}/pdc_cont.h | 0 src/api/{ => pdc_obj/include}/pdc_cont_pkg.h | 0 src/api/{ => pdc_obj/include}/pdc_dt_conv.h | 0 src/api/{ => pdc_obj/include}/pdc_mpi.h | 0 src/api/{ => pdc_obj/include}/pdc_obj.h | 113 +- src/api/{ => pdc_obj/include}/pdc_obj_pkg.h | 20 +- src/api/{ => pdc_obj/include}/pdc_prop.h | 11 +- src/api/{ => pdc_obj/include}/pdc_prop_pkg.h | 0 src/api/{ => pdc_obj}/pdc_cont.c | 0 src/api/{ => pdc_obj}/pdc_dt_conv.c | 0 src/api/{ => pdc_obj}/pdc_mpi.c | 6 +- src/api/{ => pdc_obj}/pdc_obj.c | 268 +- src/api/{ => pdc_obj}/pdc_prop.c | 39 +- src/api/{ => pdc_query/include}/pdc_query.h | 0 src/api/{ => pdc_query}/pdc_query.c | 0 src/api/{ => pdc_region/include}/pdc_region.h | 45 +- .../{ => pdc_region/include}/pdc_region_pkg.h | 0 src/api/{ => pdc_region}/pdc_region.c | 245 +- src/api/pdc_region/pdc_region_transfer.c | 1996 ++++++++++++ src/api/pdc_timing.h | 146 - .../include}/pdc_transform.h | 0 .../include}/pdc_transforms_common.h | 0 .../include}/pdc_transforms_pkg.h | 0 src/api/{ => pdc_transform}/pdc_transform.c | 2 +- .../pdc_transforms_common.c | 0 src/api/profiling/CMakeLists.txt | 37 +- src/api/profiling/{ => include}/pdc_hashtab.h | 0 .../profiling/{ => include}/pdc_stack_ops.h | 0 src/server/CMakeLists.txt | 51 +- .../include}/pdc_client_server_common.h | 512 ++- src/server/{ => include}/pdc_hash-table.h | 0 src/server/{ => include}/pdc_server.h | 0 src/server/{ => include}/pdc_server_common.h | 0 .../{ => include}/pdc_server_metadata.h | 0 src/server/{ => include}/pdc_utlist.h | 0 .../pdc_client_server_common.c | 1489 ++------- src/server/pdc_server.c | 210 +- .../include}/pdc_server_analysis.h | 0 .../pdc_server_analysis.c | 0 src/server/pdc_server_metadata.c | 21 +- .../include}/pdc_server_data.h | 5 + .../include/pdc_server_region_cache.h} | 26 +- .../include/pdc_server_region_transfer.h | 83 + ...dc_server_region_transfer_metadata_query.h | 6 + .../{ => pdc_server_region}/pdc_server_data.c | 792 +++-- .../pdc_server_region_cache.c} | 403 ++- .../pdc_server_region_request_handler.h | 918 ++++++ .../pdc_server_region_transfer.c | 491 +++ ...dc_server_region_transfer_metadata_query.c | 570 ++++ src/tests/CMakeLists.txt | 347 +- src/tests/bdcats.c | 7 +- src/tests/bdcats_old.c | 3 - src/tests/consistency_semantics.c | 256 ++ src/tests/kvtag_add_get.c | 33 +- src/tests/kvtag_add_get_scale.c | 24 +- src/tests/mpi_test.sh | 5 +- src/tests/obj_round_robin_io_all.c | 463 +++ src/tests/open_existing_obj.c | 107 + src/tests/query_data.c | 3 +- src/tests/region_transfer.c | 1 + src/tests/region_transfer_2D.c | 6 +- src/tests/region_transfer_all.c | 168 +- src/tests/region_transfer_all_2D.c | 160 +- src/tests/region_transfer_all_3D.c | 144 +- src/tests/region_transfer_all_append.c | 509 ++- src/tests/region_transfer_all_append_2D.c | 501 ++- src/tests/region_transfer_all_append_3D.c | 520 ++- src/tests/region_transfer_all_fold.c | 238 ++ src/tests/region_transfer_all_split_wait.c | 349 ++ src/tests/region_transfer_all_test.c | 272 ++ src/tests/region_transfer_query.c | 243 ++ src/tests/region_transfer_set_dims.c | 746 +++++ src/tests/region_transfer_set_dims_2D.c | 756 +++++ src/tests/region_transfer_set_dims_3D.c | 772 +++++ src/tests/region_transfer_skewed.c | 6 +- src/tests/region_transfer_status.c | 4 +- src/tests/run_test.sh | 1 - src/tests/vpicio.c | 112 +- src/tests/vpicio_mts.c | 635 ++++ src/tests/vpicio_old.c | 8 - src/{api => utils/include}/pdc_id_pkg.h | 0 src/{api => utils/include}/pdc_interface.h | 0 src/{api => utils/include}/pdc_linkedlist.h | 0 src/{api => utils/include}/pdc_malloc.h | 0 src/{api => utils/include}/pdc_private.h | 0 src/utils/include/pdc_timing.h | 193 ++ src/{api => utils}/pdc_interface.c | 0 src/{api => utils}/pdc_malloc.c | 0 src/utils/pdc_region_utils.c | 165 + src/utils/pdc_timing.c | 537 ++++ tools/.gitignore | 6 + tools/CMakeLists.txt | 68 + tools/cjson/cJSON.c | 2847 +++++++++++++++++ tools/cjson/cJSON.h | 321 ++ tools/pdc_export.c | 788 +++++ tools/pdc_import.c | 888 +++++ tools/pdc_ls.c | 861 +++++ 160 files changed, 24394 insertions(+), 3750 deletions(-) rename {src/CMake => CMake}/FindDRC.cmake (100%) rename {src/CMake => CMake}/pdc-config-version.cmake.in (100%) rename {src/CMake => CMake}/pdc-config.cmake.build.in (100%) rename {src/CMake => CMake}/pdc-config.cmake.install.in (100%) rename src/CMakeLists.txt => CMakeLists.txt (92%) rename src/CTestConfig.cmake => CTestConfig.cmake (100%) create mode 100644 docs/container_hashtable_checkpoint.png create mode 100644 docs/data_hashtable_checkpoint.png create mode 100644 docs/data_server_checkpoint.png create mode 100644 docs/pdc_metadata_flow.png create mode 100644 docs/pdc_plots.pptx create mode 100644 docs/pdc_region_transfer_request_flow.png create mode 100644 docs/source/tools.rst create mode 100644 examples/C_plus_plus_example/H5Timing.cc create mode 100644 examples/C_plus_plus_example/H5Timing.h create mode 100644 examples/C_plus_plus_example/Makefile create mode 100644 examples/C_plus_plus_example/multidataset_plugin.cc create mode 100644 examples/C_plus_plus_example/multidataset_plugin.h create mode 100644 examples/C_plus_plus_example/region_transfer_1D_append.cc create mode 100755 examples/script_cori_shared.sh create mode 100644 examples/vpicio_batch_results.png create mode 100644 examples/vpicio_dynamic_partition_4.txt create mode 100644 examples/vpicio_local_partition_4.txt create mode 100644 examples/vpicio_object_partition_4.txt create mode 100644 examples/vpicio_static_partition_4.txt rename src/api/pdc_config.h.in => pdc_config.h.in (95%) rename src/pdc_config.h.cmake => pdc_config_sys.h.cmake (92%) rename src/pdc_naming_policy.txt => pdc_naming_policy.txt (100%) rename src/pdc_start => pdc_start (79%) create mode 100644 src/api/close_server.c rename src/api/{ => include}/pdc.h (97%) rename src/api/{ => include}/pdc_client_connect.h (88%) rename src/api/{ => include}/pdc_public.h (100%) rename src/api/{ => pdc_analysis/include}/pdc_analysis.h (100%) rename src/api/{ => pdc_analysis/include}/pdc_analysis_and_transforms_common.h (100%) rename src/api/{ => pdc_analysis/include}/pdc_analysis_pkg.h (100%) rename src/api/{ => pdc_analysis/include}/pdc_hist_pkg.h (100%) rename src/api/{ => pdc_analysis}/pdc_analysis.c (99%) rename src/api/{ => pdc_analysis}/pdc_analysis_and_transforms_connect.c (100%) rename src/api/{ => pdc_analysis}/pdc_analysis_common.c (99%) rename src/api/{ => pdc_analysis}/pdc_hist_pkg.c (100%) rename src/api/{ => pdc_obj/include}/pdc_cont.h (100%) rename src/api/{ => pdc_obj/include}/pdc_cont_pkg.h (100%) rename src/api/{ => pdc_obj/include}/pdc_dt_conv.h (100%) rename src/api/{ => pdc_obj/include}/pdc_mpi.h (100%) rename src/api/{ => pdc_obj/include}/pdc_obj.h (74%) rename src/api/{ => pdc_obj/include}/pdc_obj_pkg.h (83%) rename src/api/{ => pdc_obj/include}/pdc_prop.h (94%) rename src/api/{ => pdc_obj/include}/pdc_prop_pkg.h (100%) rename src/api/{ => pdc_obj}/pdc_cont.c (100%) rename src/api/{ => pdc_obj}/pdc_dt_conv.c (100%) rename src/api/{ => pdc_obj}/pdc_mpi.c (89%) rename src/api/{ => pdc_obj}/pdc_obj.c (79%) rename src/api/{ => pdc_obj}/pdc_prop.c (89%) rename src/api/{ => pdc_query/include}/pdc_query.h (100%) rename src/api/{ => pdc_query}/pdc_query.c (100%) rename src/api/{ => pdc_region/include}/pdc_region.h (86%) rename src/api/{ => pdc_region/include}/pdc_region_pkg.h (100%) rename src/api/{ => pdc_region}/pdc_region.c (53%) create mode 100644 src/api/pdc_region/pdc_region_transfer.c delete mode 100644 src/api/pdc_timing.h rename src/api/{ => pdc_transform/include}/pdc_transform.h (100%) rename src/api/{ => pdc_transform/include}/pdc_transforms_common.h (100%) rename src/api/{ => pdc_transform/include}/pdc_transforms_pkg.h (100%) rename src/api/{ => pdc_transform}/pdc_transform.c (99%) rename src/api/{ => pdc_transform}/pdc_transforms_common.c (100%) rename src/api/profiling/{ => include}/pdc_hashtab.h (100%) rename src/api/profiling/{ => include}/pdc_stack_ops.h (100%) rename src/{api => server/include}/pdc_client_server_common.h (89%) rename src/server/{ => include}/pdc_hash-table.h (100%) rename src/server/{ => include}/pdc_server.h (100%) rename src/server/{ => include}/pdc_server_common.h (100%) rename src/server/{ => include}/pdc_server_metadata.h (100%) rename src/server/{ => include}/pdc_utlist.h (100%) rename src/{api => server}/pdc_client_server_common.c (83%) rename src/server/{ => pdc_server_analysis/include}/pdc_server_analysis.h (100%) rename src/server/{ => pdc_server_analysis}/pdc_server_analysis.c (100%) rename src/server/{ => pdc_server_region/include}/pdc_server_data.h (99%) rename src/{api/pdc_region_cache.h => server/pdc_server_region/include/pdc_server_region_cache.h} (69%) create mode 100644 src/server/pdc_server_region/include/pdc_server_region_transfer.h create mode 100644 src/server/pdc_server_region/include/pdc_server_region_transfer_metadata_query.h rename src/server/{ => pdc_server_region}/pdc_server_data.c (92%) rename src/{api/pdc_region_cache.c => server/pdc_server_region/pdc_server_region_cache.c} (63%) create mode 100644 src/server/pdc_server_region/pdc_server_region_request_handler.h create mode 100644 src/server/pdc_server_region/pdc_server_region_transfer.c create mode 100644 src/server/pdc_server_region/pdc_server_region_transfer_metadata_query.c create mode 100644 src/tests/consistency_semantics.c create mode 100644 src/tests/obj_round_robin_io_all.c create mode 100644 src/tests/open_existing_obj.c create mode 100644 src/tests/region_transfer_all_fold.c create mode 100644 src/tests/region_transfer_all_split_wait.c create mode 100644 src/tests/region_transfer_all_test.c create mode 100644 src/tests/region_transfer_query.c create mode 100644 src/tests/region_transfer_set_dims.c create mode 100644 src/tests/region_transfer_set_dims_2D.c create mode 100644 src/tests/region_transfer_set_dims_3D.c create mode 100644 src/tests/vpicio_mts.c rename src/{api => utils/include}/pdc_id_pkg.h (100%) rename src/{api => utils/include}/pdc_interface.h (100%) rename src/{api => utils/include}/pdc_linkedlist.h (100%) rename src/{api => utils/include}/pdc_malloc.h (100%) rename src/{api => utils/include}/pdc_private.h (100%) create mode 100644 src/utils/include/pdc_timing.h rename src/{api => utils}/pdc_interface.c (100%) rename src/{api => utils}/pdc_malloc.c (100%) create mode 100644 src/utils/pdc_region_utils.c create mode 100644 src/utils/pdc_timing.c create mode 100644 tools/.gitignore create mode 100644 tools/CMakeLists.txt create mode 100644 tools/cjson/cJSON.c create mode 100644 tools/cjson/cJSON.h create mode 100644 tools/pdc_export.c create mode 100644 tools/pdc_import.c create mode 100644 tools/pdc_ls.c diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index a7cbf5074..afcad8d50 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -21,7 +21,7 @@ jobs: run: .github/workflows/dependencies-linux.sh - name: Build PDC - working-directory: ./src + # working-directory: ./src run: | mkdir build && cd build cmake ../ -DBUILD_MPI_TESTING=ON -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DPDC_ENABLE_MPI=ON -DCMAKE_C_COMPILER=mpicc @@ -36,5 +36,5 @@ jobs: # mpirun -n 1 ./close_server - name: Test PDC - working-directory: ./src/build + working-directory: build run: ctest -L serial diff --git a/.gitignore b/.gitignore index cfdb5de9c..f706f8e1b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,10 @@ *.swp # build dir -*build* # exes *.exe *.pdf + +src/install diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9b155fabd..0f63b78d5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,30 +1,274 @@ -# This is a global variable variables: - LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" - MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_BUILD_PATH: "${CI_PROJECT_DIR}/build" + PDC_INSTALL_PATH: "${CI_PROJECT_DIR}/install" stages: - build + - test -# This stage uses the global SCHEDULER_PARAMETERS variable -build: +cori-build: stage: build tags: - - cori + - cori variables: SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" - # SCHEDULER_PARAMETERS: "--clusters=escori -N 1 --qos=compile -t 00:30:00" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" script: - - echo "Build PDC" - # - pwd - - module list - - cd src && mkdir build && cd build - - cmake ../ -DBUILD_MPI_TESTING=ON -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DPDC_ENABLE_MPI=ON -DPDC_ENABLE_TIMING=ON -DMERCURY_DIR=$MERCURY_DIR -DCMAKE_C_COMPILER=cc -DCMAKE_C_FLAGS=-dynamic -DMPI_RUN_CMD=srun -DPDC_ENABLE_LUSTRE=ON -DPDC_DISABLE_CHECKPOINT=ON - - make -j - - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" - - echo $LD_LIBRARY_PATH - # - echo "Run Serial Tests" - # - ctest -L serial - - echo "Run Parallel Tests" - - ctest -L parallel + - module list + - mkdir -p ${PDC_BUILD_PATH}/cori + - cd ${PDC_BUILD_PATH}/cori + - cmake ../.. -DBUILD_MPI_TESTING=ON -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DPDC_ENABLE_MPI=ON -DPDC_ENABLE_TIMING=ON -DMERCURY_DIR=$MERCURY_DIR -DCMAKE_C_COMPILER=cc -DCMAKE_C_FLAGS=-dynamic -DMPI_RUN_CMD=srun -DPDC_ENABLE_LUSTRE=ON -DPDC_DISABLE_CHECKPOINT=ON -DCMAKE_INSTALL_PREFIX=${PDC_INSTALL_PATH}/cori + - make -j + - make install + artifacts: + paths: + - ${PDC_BUILD_PATH}/cori + - ${PDC_INSTALL_PATH}/cori +perlmutter-build: + stage: build + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + script: + - module load libfabric/1.15.2.0 + - module list + - mkdir -p ${PDC_BUILD_PATH}/perlmutter + - cd ${PDC_BUILD_PATH}/perlmutter + - cmake ../.. -DBUILD_MPI_TESTING=ON -DBUILD_SHARED_LIBS=ON -DPDC_SERVER_CACHE=ON -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX=$PDC_DIR -DPDC_ENABLE_MPI=ON -DMERCURY_DIR=$MERCURY_DIR -DCMAKE_C_COMPILER=mpicc -DMPI_RUN_CMD="srun -A m2621 --qos=debug --constraint=cpu --tasks-per-node=64" -DCMAKE_INSTALL_PREFIX=${PDC_INSTALL_PATH}/perlmutter + - make -j + - make install + artifacts: + paths: + - ${PDC_BUILD_PATH}/perlmutter + - ${PDC_INSTALL_PATH}/perlmutter + +cori-parallel-pdc: + stage: test + needs: + - cori-build + tags: + - cori + variables: + SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-pdc" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-pdc" + script: + - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/cori + - ctest -L parallel_pdc + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +cori-parallel-obj: + stage: test + needs: + - cori-build + - cori-parallel-pdc + tags: + - cori + variables: + SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-obj" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-obj" + script: + - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/cori + - ctest -L parallel_obj + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +cori-parallel-cont: + stage: test + needs: + - cori-build + - cori-parallel-pdc + tags: + - cori + variables: + SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-cont" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-cont" + script: + - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/cori + - ctest -L parallel_cont + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +cori-parallel-prop: + stage: test + needs: + - cori-build + - cori-parallel-pdc + tags: + - cori + variables: + SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-prop" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-prop" + script: + - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/cori + - ctest -L parallel_prop + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +cori-parallel-region: + stage: test + needs: + - cori-build + - cori-parallel-pdc + tags: + - cori + variables: + SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-region" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-region" + script: + - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/cori + - ctest -L parallel_region_transfer + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +cori-parallel-region-all: + stage: test + needs: + - cori-build + - cori-parallel-pdc + tags: + - cori + variables: + SCHEDULER_PARAMETERS: "-C haswell --qos=debug -N 1 -t 00:30:00 --gres=craynetwork:3" + LIBFABRIC_DIR: "/global/cfs/cdirs/m1248/pdc/libfabric-1.12.1/install" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc/mercury-2.0.0/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-region-all" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-region-all" + script: + - export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/cori + - ctest -L parallel_region_transfer_all + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +perlmutter-parallel-pdc: + stage: test + needs: + - perlmutter-build + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-pdc" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-pdc" + script: + - export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/perlmutter + - ctest -L parallel_pdc + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +perlmutter-parallel-obj: + stage: test + needs: + - perlmutter-build + - perlmutter-parallel-pdc + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-obj" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-obj" + script: + - export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/perlmutter + - ctest -L parallel_obj + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +perlmutter-parallel-cont: + stage: test + needs: + - perlmutter-build + - perlmutter-parallel-pdc + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-cont" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-cont" + script: + - export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/perlmutter + - ctest -L parallel_cont + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +perlmutter-parallel-prop: + stage: test + needs: + - perlmutter-build + - perlmutter-parallel-pdc + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-prop" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-prop" + script: + - export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/perlmutter + - ctest -L parallel_prop + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +perlmutter-parallel-region: + stage: test + needs: + - perlmutter-build + - perlmutter-parallel-pdc + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-region" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-region" + script: + - export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/perlmutter + - ctest -L parallel_region_transfer + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} + +perlmutter-parallel-region-all: + stage: test + needs: + - perlmutter-build + - perlmutter-parallel-pdc + tags: + - perlmutter + variables: + SCHEDULER_PARAMETERS: "-A m1248 --qos=debug --constraint=cpu --tasks-per-node=64 -N 1 -t 00:30:00" + SUPERCOMPUTER: "perlmutter" + MERCURY_DIR: "/global/cfs/cdirs/m1248/pdc-perlmutter/mercury/install" + PDC_TMPDIR: "${PDC_BUILD_PATH}/pdc-tmp-paralell-region-all" + PDC_DATA_LOC: "${PDC_BUILD_PATH}/pdc-data-paralell-region-all" + script: + - export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" + - cd ${PDC_BUILD_PATH}/perlmutter + - ctest -L parallel_region_transfer_all + - rm -rf ${PDC_TMPDIR} ${PDC_DATA_LOC} diff --git a/src/CMake/FindDRC.cmake b/CMake/FindDRC.cmake similarity index 100% rename from src/CMake/FindDRC.cmake rename to CMake/FindDRC.cmake diff --git a/src/CMake/pdc-config-version.cmake.in b/CMake/pdc-config-version.cmake.in similarity index 100% rename from src/CMake/pdc-config-version.cmake.in rename to CMake/pdc-config-version.cmake.in diff --git a/src/CMake/pdc-config.cmake.build.in b/CMake/pdc-config.cmake.build.in similarity index 100% rename from src/CMake/pdc-config.cmake.build.in rename to CMake/pdc-config.cmake.build.in diff --git a/src/CMake/pdc-config.cmake.install.in b/CMake/pdc-config.cmake.install.in similarity index 100% rename from src/CMake/pdc-config.cmake.install.in rename to CMake/pdc-config.cmake.install.in diff --git a/src/CMakeLists.txt b/CMakeLists.txt similarity index 92% rename from src/CMakeLists.txt rename to CMakeLists.txt index f0d24d249..447ef9924 100644 --- a/src/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,9 @@ endif() project(PDC C) -include_directories(${PROJECT_BINARY_DIR}) +include_directories( + ${PROJECT_SOURCE_DIR} +) #------------------------------------------------------------------------------ # Version information @@ -48,6 +50,9 @@ endif() #------------------------------------------------------------------------------ # Setup install and output Directories #------------------------------------------------------------------------------ +if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}) +endif() if(NOT PDC_INSTALL_BIN_DIR) set(PDC_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/bin) endif() @@ -136,7 +141,7 @@ endif() if(NOT CMAKE_C_FLAGS AND CMAKE_COMPILER_IS_GNUCC) message(STATUS "GCC detected, setting additional flags") - set(CMAKE_C_FLAGS "-Wall -Wextra -Winline -Wcast-qual -std=gnu99 -Wshadow -Wimplicit-fallthrough=3" CACHE STRING "Flags used by the compiler during all build types." FORCE) + set(CMAKE_C_FLAGS "-Wall -Wextra -Winline -Wcast-qual -std=gnu99 -Wshadow -fcommon" CACHE STRING "Flags used by the compiler during all build types." FORCE) endif() #----------------------------------------------------------------------------- @@ -234,7 +239,7 @@ endif() #----------------------------------------------------------------------------- # MPI option #----------------------------------------------------------------------------- -option(PDC_ENABLE_MPI "Enable MPI." OFF) +option(PDC_ENABLE_MPI "Enable MPI." ON) if(PDC_ENABLE_MPI) find_package(MPI) if(MPI_FOUND) @@ -254,17 +259,26 @@ endif() #----------------------------------------------------------------------------- # TIMING option #----------------------------------------------------------------------------- -option(PDC_ENABLE_TIMING "Enable timing." OFF) -if(PDC_ENABLE_TIMING) +option(PDC_TIMING "Enable timing." OFF) +if(PDC_TIMING) set(PDC_TIMING 1) endif() +#----------------------------------------------------------------------------- +# SERVER CACHE option +#----------------------------------------------------------------------------- +option(PDC_SERVER_CACHE "Enable timing." OFF) +if(PDC_SERVER_CACHE) + set(PDC_SERVER_CACHE 1) +endif() + + #----------------------------------------------------------------------------- # CHECKPOINT option #----------------------------------------------------------------------------- -option(PDC_DISABLE_CHECKPOINT "Disable checkpointing." OFF) -if(PDC_DISABLE_CHECKPOINT) - set(DISABLE_CHECKPOINT 1) +option(PDC_ENABLE_CHECKPOINT "Enable checkpointing." ON) +if(PDC_ENABLE_CHECKPOINT) + set(PDC_ENABLE_CHECKPOINT 1) endif() #----------------------------------------------------------------------------- @@ -354,15 +368,20 @@ check_type_size("unsigned long long" VAR_SIZE_ULLINT) check_type_size("int64_t" VAR_SIZE_64INT) check_type_size("uint64_t" VAR_SIZE_U64INT) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pdc_config.h.cmake ${PROJECT_BINARY_DIR}/pdc_config.h) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pdc_config_sys.h.cmake ${PROJECT_BINARY_DIR}/pdc_config_sys.h) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/pdc_config.h.in + ${PROJECT_BINARY_DIR}/pdc_config.h +) #---------------------- end of generating config.h --------------------------- #----------------------------------------------------------------------------- # Source #----------------------------------------------------------------------------- -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/api) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/server) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/api) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/server) #----------------------------------------------------------------------------- # Testing @@ -372,7 +391,7 @@ option(BUILD_MPI_TESTING "Build MPI testing." OFF) if(NOT PDC_EXTERNALLY_CONFIGURED AND BUILD_TESTING) enable_testing() include(CTest) - add_subdirectory(tests) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/tests) endif() #----------------------------------------------------------------------------- @@ -424,18 +443,19 @@ install( install( DIRECTORY ${PDC_BINARY_DIR}/bin + DESTINATION ${PDC_INSTALL_DATA_DIR}/test ) -install( - FILES - ${PDC_BINARY_DIR}/bin/pdc_server.exe - ${PDC_BINARY_DIR}/bin/close_server - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - DESTINATION - ${CMAKE_INSTALL_PREFIX}/bin -) + +#install( +# FILES +# ${PDC_BINARY_DIR}/bin/pdc_server.exe +# ${PDC_BINARY_DIR}/bin/close_server +# DESTINATION +# ${CMAKE_INSTALL_PREFIX}/bin +#) #----------------------------------------------------------------------------- # CPack @@ -457,9 +477,9 @@ endif() add_custom_target(format COMMAND find - ${PDC_SOURCE_DIR}/api - ${PDC_SOURCE_DIR}/server - ${PDC_SOURCE_DIR}/tests + ${PDC_SOURCE_DIR}/src/api + ${PDC_SOURCE_DIR}/src/server + ${PDC_SOURCE_DIR}/src/tests -type f ( -name "*.c" diff --git a/src/CTestConfig.cmake b/CTestConfig.cmake similarity index 100% rename from src/CTestConfig.cmake rename to CTestConfig.cmake diff --git a/README.md b/README.md index 29f6f6f51..54ab218f6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ [![linux](https://github.com/hpc-io/pdc/actions/workflows/linux.yml/badge.svg?branch=stable)](https://github.com/hpc-io/pdc/actions/workflows/linux.yml) -## Proactive Data Containers (PDC) +# Proactive Data Containers (PDC) Proactive Data Containers (PDC) software provides an object-centric API and a runtime system with a set of data object management services. These services allow placing data in the memory and storage hierarchy, performing data movement asynchronously, and providing scalable metadata operations to find data objects. PDC revolutionizes how data is stored and accessed by using object-centric abstractions to represent data that moves in the high-performance computing (HPC) memory and storage subsystems. PDC manages extensive metadata to describe data objects to find desired data efficiently as well as to store information in the data objects. PDC API, data types, and developer notes are available in docs/readme.md. More information and publications of PDC is available at https://sdm.lbl.gov/pdc -## Installation +# Installation + The following instructions are for installing PDC on Linux and Cray machines. GCC version 7 or newer and a version of MPI are needed to install PDC. @@ -14,110 +15,216 @@ Current PDC tests have been verified with MPICH. To install MPICH, follow the do PDC also depends on libfabric and Mercury. We provide detailed instructions for installing libfabric, Mercury, and PDC below. Make sure to record the environmental variables (lines that contains the "export" commands). They are needed for running PDC and to use the libraries again. -# Install libfabric + +## Preparing for Installation + +PDC relies on [`libfabric`](https://github.com/ofiwg/libfabric/) as well as [`mercury`](https://github.com/mercury-hpc/mercury). Therefore, let's **prepare the dependencies**. +### Preparing Work Space + +Before installing the dependencies and downloading the code repository, we assume there is a directory created for your installation already, e.g. `$WORK_SPACE` and now you are in `$WORK_SPACE`. + +```bash +export WORK_SPACE=/path/to/your/work/space +mkdir -p $WORK_SPACE/source +mkdir -p $WORK_SPACE/install +``` + +### Download Necessary Source Repository + +Now, let's download [`libfabric`](https://github.com/ofiwg/libfabric/), [`mercury`](https://github.com/mercury-hpc/mercury) and [`pdc`](https://github.com/hpc-io/pdc/tree/develop) into our `source` directory. + +```bash +cd $WORK_SPACE/source +git clone git@github.com:ofiwg/libfabric.git +git clone git@github.com:mercury-hpc/mercury.git +git clone git@github.com:hpc-io/pdc.git +``` + +### Prepare Directories for Artifact Installation +```bash +export LIBFABRIC_SRC_DIR=$WORK_SPACE/source/libfabric +export MERCURY_SRC_DIR=$WORK_SPACE/source/mercury +export PDC_SRC_DIR=$WORK_SPACE/source/pdc + +export LIBFABRIC_DIR=$WORK_SPACE/install/libfabric +export MERCURY_DIR=$WORK_SPACE/install/mercury +export PDC_DIR=$WORK_SPACE/install/pdc + +mkdir -p $LIBFABRIC_SRC_DIR +mkdir -p $MERCURY_SRC_DIR +mkdir -p $PDC_SRC_DIR + +mkdir -p $LIBFABRIC_DIR +mkdir -p $MERCURY_DIR +mkdir -p $PDC_DIR + +echo "export LIBFABRIC_SRC_DIR=$LIBFABRIC_SRC_DIR" > $WORK_SPACE/pdc_env.sh +echo "export MERCURY_SRC_DIR=$MERCURY_SRC_DIR" >> $WORK_SPACE/pdc_env.sh +echo "export PDC_SRC_DIR=$PDC_SRC_DIR" >> $WORK_SPACE/pdc_env.sh + +echo "export LIBFABRIC_DIR=$LIBFABRIC_DIR" >> $WORK_SPACE/pdc_env.sh +echo "export MERCURY_DIR=$MERCURY_DIR" >> $WORK_SPACE/pdc_env.sh +echo "export PDC_DIR=$PDC_DIR" >> $WORK_SPACE/pdc_env.sh ``` -wget https://github.com/ofiwg/libfabric/archive/v1.11.2.tar.gz -tar xvzf v1.11.2.tar.gz -cd libfabric-1.11.2 -mkdir install -export LIBFABRIC_DIR=$(pwd)/install +Remember, from now on, at any time, you can simply run the following to set the above environment variables so that you can run any of the following command for your installation. + +```bash +export WORK_SPACE=/path/to/your/work/space +source $WORK_SPACE/pdc_env.sh +``` + +### Compile and Install`libfabric` + +Check out tag `v1.11.2` for `libfabric`: + +```bash +cd $LIBFABRIC_SRC_DIR +git checkout tags/v1.11.2 +``` + +Configure, compile and install: + +```bash ./autogen.sh -./configure --prefix=$LIBFABRIC_DIR CC=gcc CFLAG="-O2" -make -j8 +./configure --prefix=$LIBFABRIC_DIR CC=cc CFLAG="-O2" + +make -j 32 make install export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$LD_LIBRARY_PATH" export PATH="$LIBFABRIC_DIR/include:$LIBFABRIC_DIR/lib:$PATH" -``` -# Install Mercury -Make sure the ctest passes. PDC may not work without passing all the tests of Mercury. -Step 2 in the following is not required. It is a stable commit that has been used to test when these these instructions were written (mercury-2.0.1 release commit). One may skip it to use the current master branch of Mercury. +echo 'export LD_LIBRARY_PATH=$LIBFABRIC_DIR/lib:$LD_LIBRARY_PATH' >> $WORK_SPACE/pdc_env.sh +echo 'export PATH=$LIBFABRIC_DIR/include:$LIBFABRIC_DIR/lib:$PATH' >> $WORK_SPACE/pdc_env.sh ``` -git clone https://github.com/mercury-hpc/mercury.git -cd mercury -git checkout cabb83758f9e07842dc34b0443d0873301fbdf91 + +Note: On NERSC supercomputers, e.g. Cori and Perlmutter, we should add `--disable-efa --disable-sockets` to the `./configure` command during the compilation on login nodes. + +### Compile and Install `mercury` + +Now, you may check out a specific tag version of `mercury`, for example, `v2.2.0`: + +```bash +cd $MERCURY_SRC_DIR +mkdir build +git checkout tags/v2.2.0 git submodule update --init -export MERCURY_DIR=$(pwd)/install -mkdir install -cd install +``` -cmake ../ -DCMAKE_INSTALL_PREFIX=$MERCURY_DIR -DCMAKE_C_COMPILER=gcc -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DNA_USE_OFI=ON -DNA_USE_SM=OFF -make -make install +Configure, compile, test and install: + +```bash +cd build +cmake ../ -DCMAKE_INSTALL_PREFIX=$MERCURY_DIR -DCMAKE_C_COMPILER=cc -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DNA_USE_OFI=ON -DNA_USE_SM=OFF -DNA_OFI_TESTING_PROTOCOL=tcp +make -j 32 && make install ctest export LD_LIBRARY_PATH="$MERCURY_DIR/lib:$LD_LIBRARY_PATH" export PATH="$MERCURY_DIR/include:$MERCURY_DIR/lib:$PATH" + +echo 'export LD_LIBRARY_PATH=$MERCURY_DIR/lib:$LD_LIBRARY_PATH' >> $WORK_SPACE/pdc_env.sh +echo 'export PATH=$MERCURY_DIR/include:$MERCURY_DIR/lib:$PATH' >> $WORK_SPACE/pdc_env.sh +``` + +## Compile and Install PDC +Now, it's time to compile and install PDC. + +* One can replace `mpicc` to other available MPI compilers. For example, on Cori, `cc` can be used to replace `mpicc`. +* `ctest` contains both sequential and MPI tests for the PDC settings. These can be used to perform regression tests. + +```bash +cd $PDC_SRC_DIR +git checkout develop +mkdir build +cd build +cmake ../ -DBUILD_MPI_TESTING=ON -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX=$PDC_DIR -DPDC_ENABLE_MPI=ON -DMERCURY_DIR=$MERCURY_DIR -DCMAKE_C_COMPILER=cc -DMPI_RUN_CMD=srun +make -j 32 && make install +``` + +Let's run `ctest` now on a compute node: + +### On Cori +```bash +salloc --nodes 1 --qos interactive --time 01:00:00 --constraint haswell ``` -# Install PDC -One can replace mpicc to other available MPI compilers. -DCMAKE_C_FLAGS="-dynamic" is sometimes required for Cori. For example, on Cori, cc can be used to replace mpicc. -ctest contains both sequential and MPI tests for the PDC settings. These can be used to perform regression tests. +### On Perlmutter + +```bash +salloc --nodes 1 --qos interactive --time 01:00:00 --constraint cpu --account=mxxxx ``` -git clone https://github.com/hpc-io/pdc.git -cd pdc -git checkout stable -cd src -mkdir install -cd install -export PDC_DIR=$(pwd) -cmake ../ -DBUILD_MPI_TESTING=ON -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX=$PDC_DIR -DPDC_ENABLE_MPI=ON -DMERCURY_DIR=$MERCURY_DIR -DCMAKE_C_COMPILER=mpicc -make -j8 +Once you are on the compute node, you can run `ctest`. +```bash ctest +``` +Note: On Cori, if you happen to see failures regarding `libibverb` validation, login to one of the compute nodes by running an interactive job and re-compile all PDC's dependencies and PDC itself. Then problem will be solved. + +If all the tests pass, you can now specify the environment variables. + +```bash export LD_LIBRARY_PATH="$PDC_DIR/lib:$LD_LIBRARY_PATH" export PATH="$PDC_DIR/include:$PDC_DIR/lib:$PATH" -``` -# Environmental variables -During installation, we have set some environmental variables. These variables may disappear after the close the current session ends. -We recommend adding the following lines to ~/.bashrc. (One may also execute them manually after logging in). -The MERCURY_DIR and LIBFABRIC_DIR variables should be identical to the values that were set during the installation of Mercury and libfabric. -The install path is the path containing bin and lib directory, instead of the one containing the source code. +echo 'export LD_LIBRARY_PATH=$PDC_DIR/lib:$LD_LIBRARY_PATH' >> $WORK_SPACE/pdc_env.sh +echo 'export PATH=$PDC_DIR/include:$PDC_DIR/lib:$PATH' >> $WORK_SPACE/pdc_env.sh ``` -export PDC_DIR="where/you/installed/your/pdc" -export MERCURY_DIR="where/you/installed/your/mercury" -export LIBFABRIC_DIR="where/you/installed/your/libfabric" -export LD_LIBRARY_PATH="$LIBFABRIC_DIR/lib:$MERCURY_DIR/lib:$LD_LIBRARY_PATH" -export PATH="$PDC_DIR/include:$PDC_DIR/lib:LIBFABRIC_DIR/include:$LIBFABRIC_DIR/lib:$MERCURY_DIR/include:$MERCURY_DIR/lib:$PATH" + +## About Spack + +One can also install `PDC` with [`Spack`](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/pdc/package.py), with which the dependencies of `PDC` can be easily managed and installed. + +```bash +git clone -c feature.manyFiles=true https://github.com/spack/spack.git +cd spack/bin +./spack install pdc ``` -One can also manage the path with Spack, which is a lot more easier to load and unload these libraries. + ## Running PDC -The ctest under PDC install folder runs PDC examples using PDC APIs. -PDC needs to run at least two applications. The PDC servers need to be started first. -The client programs that send I/O request to servers as Mercury RPCs are started next. -We provide a convenient function (mpi_text.sh) to start MPI tests. -One needs to change the MPI launching function (mpiexec) with the relevant launcher on a system. -On Cori at NERSC, the mpiexec argument needs to be changed to srun. On Theta, it is aprun. On Summit, it is jsrun. -``` +Essentially, PDC is a typical client-server application. +To run `PDC`, one needs to start the server processes first, and then the clients can be started to issue RPC requests handled by the `Mercury` RPC framework. + +We provide [`mpi_test.sh` utility](https://github.com/hpc-io/pdc/blob/develop/examples/mpi_test.sh) for running MPI tests. For example, on a regular Linux machine, you may run the following: + +```bash +export JOB_RUNNER=mpiexec cd $PDC_DIR/bin -./mpi_test.sh ./pdc_init mpiexec 2 4 +./mpi_test.sh ./pdc_init $JOB_RUNNER 2 4 ``` -This is test will start 2 processes for PDC servers. The client program ./pdc_init will start 4 processes. Similarly, one can run any of the client examples in ctest. + +This is test will start 2 processes for PDC servers. The client program ./pdc_init will start 4 processes. Similarly, one can run any of the client examples in `ctest`. + +Depending on the specific HPC environment where you run `PDC` , the value of `$JOB_RUNNER` variable can be changed to `srun` (for NERSC), `aprun` (for Theta), or `jsrun` for `Summit`, accordingly. + These source code will provide some knowledge of how to use PDC. For more reference, one may check the documentation folder in this repository. -# PDC on Cori. -Installation on Cori is not very different from a regular linux machine. Simply replacing all gcc/mpicc with the default cc compiler on Cori would work. "-DMPI_RUN_CMD=srun" is needed for ctest command later. In some instances and on some systems, unload darshan before installation may be needed. -For job allocation on Cori it is recommended to add "--gres=craynetwork:2" to the command: -```sh -salloc -C haswell -N 4 -t 01:00:00 -q interactive --gres=craynetwork:2 -``` -And to launch the PDC server and the client, add "--gres=craynetwork:1" before the executables: +# PDC on Cori -* Run 4 server processes, each on one node in background: -```sh -srun -N 4 -n 4 -c 2 --mem=25600 --cpu_bind=cores --gres=craynetwork:1 --overlap ./bin/pdc_server.exe & -``` +If you are running `PDC` on Cori supercomputer, here are some tips you would need to follow: -* Run 64 client processes that concurrently create 1000 objects in total: -```sh -srun -N 4 -n 64 -c 2 --mem=25600 --cpu_bind=cores --gres=craynetwork:1 --overlap ./bin/create_obj_scale -r 1000 -``` +* On Cori, it is recommended to use `cc` as the default compiler when compiling PDC and its dependencies. +* When preparing compilation for `PDC` using `CMake`, it is suggested to append console argument `-DMPI_RUN_CMD=srun` so that `ctest` can be executed on Cori. +* Sometimes, it might be helpful to unload `darshan` module before the installation. + +* For opening an interactive job session on Cori, it is recommended to add `--gres=craynetwork:2` option to the `salloc` command: + ```bash + salloc -C haswell -N 4 -t 01:00:00 -q interactive --gres=craynetwork:2 + ``` +* To launch the PDC server and the client, add `--gres=craynetwork:1` before the executables, for example: + + * Run 4 server processes, each on one node in background: + ```bash + srun -N 4 -n 4 -c 2 --mem=25600 --cpu_bind=cores --gres=craynetwork:1 --overlap ./bin/pdc_server.exe & + ``` + + * Run 64 client processes that concurrently create 1000 objects in total: + ```bash + srun -N 4 -n 64 -c 2 --mem=25600 --cpu_bind=cores --gres=craynetwork:1 --overlap ./bin/create_obj_scale -r 1000 + ``` diff --git a/docs/container_hashtable_checkpoint.png b/docs/container_hashtable_checkpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..784a9a5e4f26030644ec184c06a1c65add7b6a5d GIT binary patch literal 26662 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 literal 0 HcmV?d00001 diff --git a/docs/data_hashtable_checkpoint.png b/docs/data_hashtable_checkpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..60cda6851bbeb619b6a01c7319c07951c4752bb1 GIT binary patch literal 205118 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