From 509c6991cdc6e9ea5ebb5dd6d1ca07b9298608a6 Mon Sep 17 00:00:00 2001 From: "H. Joe Lee" Date: Wed, 18 Sep 2024 09:44:21 -0500 Subject: [PATCH] ci: sync upstream --- adapter/filesystem/filesystem.h | 232 -- adapter/filesystem/filesystem_mdm.h | 116 - adapter/kvstore/kvstore.h | 178 -- adapter/mpiio/mpiio_io_client.h | 115 - adapter/posix/posix_fs_api.h | 114 - adapter/posix/posix_io_client.h | 109 - adapter/real_api.h | 70 - adapter/stdio/stdio_fs_api.h | 104 - adapter/stdio/stdio_io_client.h | 108 - adapter/test/adapter_test_utils.h | 62 - adapter/test/mpiio/mpiio_adapter_test.cpp | 685 ------ .../test/posix/posix_adapter_basic_test.cpp | 1479 ------------ adapter/test/posix/posix_adapter_mpi_test.cpp | 411 ---- adapter/test/posix/posix_adapter_test.cpp | 333 --- .../test/stdio/stdio_adapter_basic_test.cpp | 1308 ---------- .../test/stdio/stdio_adapter_mapper_test.cpp | 209 -- .../test/stdio/stdio_adapter_mode_test.cpp | 363 --- adapter/test/stdio/stdio_adapter_mpi_test.cpp | 362 --- adapter/test/stdio/stdio_adapter_test.cpp | 294 --- data_stager/data_stager.h | 71 - data_stager/stagers/posix_stager.h | 40 - data_stager/test/CMakeLists.txt | 4 - data_stager/test/stage_dir.sh | 95 - hermes_adapters/adapter_types.h | 17 +- hermes_adapters/filesystem/filesystem.h | 136 +- .../filesystem/filesystem_io_client.h | 139 +- hermes_adapters/mapper/abstract_mapper.h | 6 +- hermes_adapters/mpiio/mpiio_api.h | 139 +- hermes_adapters/mpiio/mpiio_fs_api.h | 145 +- hermes_adapters/posix/fs_api.cc | 97 - hermes_adapters/posix/posix.cc | 337 --- hermes_adapters/posix/posix_api.h | 70 +- hermes_adapters/posix/posix_fs_api.h | 93 +- hermes_adapters/posix/real_api.h | 218 -- hermes_adapters/real_api.h | 54 +- hermes_adapters/stdio/fs_api.cc | 102 - hermes_adapters/stdio/real_api.h | 304 --- hermes_adapters/stdio/stdio_api.h | 61 +- hermes_adapters/stdio/stdio_fs_api.h | 110 +- hermes_adapters/vfd/H5FDhermes.c | 1154 --------- hermes_adapters/vfd/H5FDhermes_err.h | 199 -- hermes_shm/benchmark/allocator/test_init.h | 45 - .../benchmark/data_structure/test_init.h | 175 -- .../data_structure_singleton_macros.h | 38 - .../include/hermes_shm/constants/macros.h | 66 - .../data_structures/containers/charbuf.h | 248 -- .../data_structures/containers/converters.h | 58 - .../data_structures/containers/functional.h | 31 - .../data_structures/containers/tuple_base.h | 223 -- .../data_structures/data_structure.h | 26 - .../data_structures/internal/shm_archive.h | 105 - .../internal/shm_archive_or_t.h | 231 -- .../internal/shm_container_extend_macro.h | 233 -- .../internal/shm_container_macro.h | 347 --- .../internal/shm_deserialize.h | 84 - .../data_structures/internal/shm_macros.h | 72 - .../data_structures/internal/shm_ref.h | 167 -- .../data_structures/internal/shm_smart_ptr.h | 136 -- .../template/shm_container_base_example.h | 383 --- .../template/shm_container_base_template.h | 320 --- .../template/shm_container_extend_example.h | 280 --- .../template/shm_container_extend_template.h | 218 -- .../hermes_shm/data_structures/ipc/_queue.h | 52 - .../ipc/internal/shm_archive.h | 126 - .../ipc/internal/shm_container.h | 78 - .../ipc/internal/shm_container_macro.h | 69 - .../ipc/internal/shm_internal.h | 22 - .../data_structures/ipc/internal/shm_macros.h | 31 - .../ipc/internal/shm_null_container.h | 115 - .../ipc/internal/shm_smart_ptr.h | 56 - .../template/shm_container_base_example.h | 127 - .../template/shm_container_base_template.h | 61 - .../hermes_shm/data_structures/ipc/iqueue.h | 339 --- .../hermes_shm/data_structures/ipc/list.h | 466 ---- .../hermes_shm/data_structures/ipc/pair.h | 201 -- .../hermes_shm/data_structures/ipc/slist.h | 487 ---- .../data_structures/ipc/spsc_queue.h | 208 -- .../hermes_shm/data_structures/ipc/string.h | 340 --- .../data_structures/ipc/unordered_map.h | 518 ---- .../hermes_shm/data_structures/ipc/vector.h | 667 ------ .../data_structures/numa_aware/numa_list.h | 152 -- .../include/hermes_shm/data_structures/pair.h | 182 -- .../serialization/shm_serialize.h | 103 - .../data_structures/serialization/thallium.h | 223 -- .../data_structures/smart_ptr/manual_ptr.h | 106 - .../smart_ptr/smart_ptr_base.h | 288 --- .../hermes_shm/data_structures/string.h | 273 --- .../thread_unsafe/unordered_map.h | 529 ---- .../data_structures/thread_unsafe/vector.h | 763 ------ .../hermes_shm/introspect/system_info.h | 44 - .../hermes_shm/memory/allocator/allocator.h | 519 ---- .../memory/allocator/allocator_factory.h | 88 - .../memory/allocator/malloc_allocator.h | 93 - .../hermes_shm/memory/allocator/mp_page.h | 36 - .../allocator/scalable_page_allocator.h | 196 -- .../memory/allocator/stack_allocator.h | 98 - .../hermes_shm/memory/backend/array_backend.h | 65 - .../memory/backend/memory_backend.h | 80 - .../memory/backend/memory_backend_factory.h | 105 - .../hermes_shm/memory/backend/null_backend.h | 73 - .../hermes_shm/memory/backend/posix_mmap.h | 111 - .../memory/backend/posix_shm_mmap.h | 135 -- hermes_shm/include/hermes_shm/memory/memory.h | 374 --- .../hermes_shm/memory/memory_manager.h | 202 -- .../hermes_shm/memory/memory_registry.h | 129 - .../hermes_shm/thread/ipc_call_manager.h | 128 - .../include/hermes_shm/thread/lock/mutex.h | 64 - .../include/hermes_shm/thread/lock/rwlock.h | 120 - .../hermes_shm/thread/thread_model/argobots.h | 53 - .../thread/thread_model/thread_model.h | 48 - .../thread_model/thread_model_factory.h | 52 - .../hermes_shm/thread/thread_model_manager.h | 85 - hermes_shm/include/hermes_shm/types/argpack.h | 252 -- hermes_shm/include/hermes_shm/types/atomic.h | 244 -- .../include/hermes_shm/types/bitfield.h | 155 -- .../include/hermes_shm/types/real_number.h | 93 - .../include/hermes_shm/util/auto_trace.h | 83 - .../include/hermes_shm/util/config_parse.h | 243 -- hermes_shm/include/hermes_shm/util/error.h | 61 - hermes_shm/include/hermes_shm/util/errors.h | 66 - .../include/hermes_shm/util/formatter.h | 87 - hermes_shm/include/hermes_shm/util/logging.h | 209 -- .../include/hermes_shm/util/singleton.h | 150 -- hermes_shm/include/hermes_shm/util/timer.h | 86 - .../include/hermes_shm/util/type_switch.h | 48 - hermes_shm/test/unit/allocators/test_init.h | 53 - .../unit/data_structures/containers/iqueue.h | 108 - .../unit/data_structures/containers/list.h | 187 -- .../data_structures/containers/smart_ptr.h | 84 - .../data_structures/containers/test_init.h | 49 - .../containers_mpi/test_init.h | 38 - .../data_structures/serialize/shm/test_init.h | 35 - .../serialize/thallium/test_init.h | 84 - hrun/include/hrun/api/hrun_client.h | 327 +-- hrun/include/hrun/api/hrun_runtime.h | 2 +- hrun/include/hrun/api/hrun_runtime_.h | 10 +- hrun/include/hrun/api/manager.h | 13 +- hrun/include/hrun/config/config.h | 8 +- .../hrun/config/config_client_default.h | 3 +- .../hrun/config/config_server_default.h | 141 +- hrun/include/hrun/work_orchestrator/debug.h | 78 - src/api/bucket.h | 224 -- src/api/hermes.h | 269 --- src/api/vbucket.cc | 400 ---- src/api/vbucket.h | 262 -- src/binlog.h | 145 -- src/borg_io_clients/borg_posix_client.h | 83 - src/borg_io_clients/borg_ram_client.h | 62 - src/buffer_organizer.h | 279 --- src/buffer_pool.h | 299 --- src/config_client.h | 128 - src/config_client_default.h | 14 - src/config_parser.cc | 562 ----- src/config_server.h | 304 --- src/dpe/minimize_io_time.h | 33 - src/hermes_types.h | 532 ---- src/metadata_manager.h | 524 ---- src/metadata_types.h | 387 --- src/prefetcher.h | 58 - src/prefetcher/apriori_prefetcher.h | 54 - src/prefetcher_factory.h | 50 - src/rpc.h | 190 -- src/rpc_thallium.h | 170 -- src/rpc_thallium_serialization.h | 166 -- src/statuses.h | 54 - src/stb_ds.h | 2130 ----------------- src/thread_manager.h | 63 - src/trait_manager.h | 202 -- test/test_utils.h | 43 - test/trait_order.cc | 166 -- test/unit/boost/pthread.h | 96 - test/unit/hermes_adapters/posix/simple_io.cc | 128 - traits/example/example_trait.cc | 25 - traits/example/example_trait.h | 49 - traits/prefetcher/prefetcher_header.h | 35 - traits/prefetcher/prefetcher_trait.h | 39 - wrapper/c/c_wrapper.h | 36 - wrapper/hermes_wrapper.cpp | 126 - wrapper/hermes_wrapper.h | 58 - .../java/src/hermes/cpp/hermes_java_wrapper.h | 162 -- wrapper/java/src/hermes/cpp/src_main_Blob.h | 21 - wrapper/java/src/hermes/cpp/src_main_Bucket.h | 90 - wrapper/java/src/hermes/cpp/src_main_Hermes.h | 28 - wrapper/python/cpp/py_hermes.cpp | 20 +- 184 files changed, 752 insertions(+), 34220 deletions(-) delete mode 100644 adapter/filesystem/filesystem.h delete mode 100644 adapter/filesystem/filesystem_mdm.h delete mode 100644 adapter/kvstore/kvstore.h delete mode 100644 adapter/mpiio/mpiio_io_client.h delete mode 100644 adapter/posix/posix_fs_api.h delete mode 100644 adapter/posix/posix_io_client.h delete mode 100644 adapter/real_api.h delete mode 100644 adapter/stdio/stdio_fs_api.h delete mode 100644 adapter/stdio/stdio_io_client.h delete mode 100644 adapter/test/adapter_test_utils.h delete mode 100644 adapter/test/mpiio/mpiio_adapter_test.cpp delete mode 100644 adapter/test/posix/posix_adapter_basic_test.cpp delete mode 100644 adapter/test/posix/posix_adapter_mpi_test.cpp delete mode 100644 adapter/test/posix/posix_adapter_test.cpp delete mode 100644 adapter/test/stdio/stdio_adapter_basic_test.cpp delete mode 100644 adapter/test/stdio/stdio_adapter_mapper_test.cpp delete mode 100644 adapter/test/stdio/stdio_adapter_mode_test.cpp delete mode 100644 adapter/test/stdio/stdio_adapter_mpi_test.cpp delete mode 100644 adapter/test/stdio/stdio_adapter_test.cpp delete mode 100644 data_stager/data_stager.h delete mode 100644 data_stager/stagers/posix_stager.h delete mode 100644 data_stager/test/CMakeLists.txt delete mode 100755 data_stager/test/stage_dir.sh delete mode 100644 hermes_adapters/posix/fs_api.cc delete mode 100644 hermes_adapters/posix/posix.cc delete mode 100644 hermes_adapters/posix/real_api.h delete mode 100644 hermes_adapters/stdio/fs_api.cc delete mode 100644 hermes_adapters/stdio/real_api.h delete mode 100644 hermes_adapters/vfd/H5FDhermes.c delete mode 100644 hermes_adapters/vfd/H5FDhermes_err.h delete mode 100644 hermes_shm/benchmark/allocator/test_init.h delete mode 100644 hermes_shm/benchmark/data_structure/test_init.h delete mode 100644 hermes_shm/include/hermes_shm/constants/data_structure_singleton_macros.h delete mode 100644 hermes_shm/include/hermes_shm/constants/macros.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/containers/charbuf.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/containers/converters.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/containers/functional.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/containers/tuple_base.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/data_structure.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_archive.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_archive_or_t.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_container_extend_macro.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_container_macro.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_deserialize.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_macros.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_ref.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/shm_smart_ptr.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/template/shm_container_base_example.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/template/shm_container_base_template.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/template/shm_container_extend_example.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/internal/template/shm_container_extend_template.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/_queue.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_archive.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_container.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_container_macro.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_internal.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_macros.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_null_container.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/shm_smart_ptr.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/template/shm_container_base_example.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/internal/template/shm_container_base_template.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/iqueue.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/list.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/pair.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/slist.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/spsc_queue.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/string.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/unordered_map.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/ipc/vector.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/numa_aware/numa_list.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/pair.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/serialization/shm_serialize.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/serialization/thallium.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/smart_ptr/manual_ptr.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/smart_ptr/smart_ptr_base.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/string.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/thread_unsafe/unordered_map.h delete mode 100644 hermes_shm/include/hermes_shm/data_structures/thread_unsafe/vector.h delete mode 100644 hermes_shm/include/hermes_shm/introspect/system_info.h delete mode 100644 hermes_shm/include/hermes_shm/memory/allocator/allocator.h delete mode 100644 hermes_shm/include/hermes_shm/memory/allocator/allocator_factory.h delete mode 100644 hermes_shm/include/hermes_shm/memory/allocator/malloc_allocator.h delete mode 100644 hermes_shm/include/hermes_shm/memory/allocator/mp_page.h delete mode 100644 hermes_shm/include/hermes_shm/memory/allocator/scalable_page_allocator.h delete mode 100644 hermes_shm/include/hermes_shm/memory/allocator/stack_allocator.h delete mode 100644 hermes_shm/include/hermes_shm/memory/backend/array_backend.h delete mode 100644 hermes_shm/include/hermes_shm/memory/backend/memory_backend.h delete mode 100644 hermes_shm/include/hermes_shm/memory/backend/memory_backend_factory.h delete mode 100644 hermes_shm/include/hermes_shm/memory/backend/null_backend.h delete mode 100644 hermes_shm/include/hermes_shm/memory/backend/posix_mmap.h delete mode 100644 hermes_shm/include/hermes_shm/memory/backend/posix_shm_mmap.h delete mode 100644 hermes_shm/include/hermes_shm/memory/memory.h delete mode 100644 hermes_shm/include/hermes_shm/memory/memory_manager.h delete mode 100644 hermes_shm/include/hermes_shm/memory/memory_registry.h delete mode 100644 hermes_shm/include/hermes_shm/thread/ipc_call_manager.h delete mode 100644 hermes_shm/include/hermes_shm/thread/lock/mutex.h delete mode 100644 hermes_shm/include/hermes_shm/thread/lock/rwlock.h delete mode 100644 hermes_shm/include/hermes_shm/thread/thread_model/argobots.h delete mode 100644 hermes_shm/include/hermes_shm/thread/thread_model/thread_model.h delete mode 100644 hermes_shm/include/hermes_shm/thread/thread_model/thread_model_factory.h delete mode 100644 hermes_shm/include/hermes_shm/thread/thread_model_manager.h delete mode 100644 hermes_shm/include/hermes_shm/types/argpack.h delete mode 100644 hermes_shm/include/hermes_shm/types/atomic.h delete mode 100644 hermes_shm/include/hermes_shm/types/bitfield.h delete mode 100644 hermes_shm/include/hermes_shm/types/real_number.h delete mode 100644 hermes_shm/include/hermes_shm/util/auto_trace.h delete mode 100644 hermes_shm/include/hermes_shm/util/config_parse.h delete mode 100644 hermes_shm/include/hermes_shm/util/error.h delete mode 100644 hermes_shm/include/hermes_shm/util/errors.h delete mode 100644 hermes_shm/include/hermes_shm/util/formatter.h delete mode 100644 hermes_shm/include/hermes_shm/util/logging.h delete mode 100644 hermes_shm/include/hermes_shm/util/singleton.h delete mode 100644 hermes_shm/include/hermes_shm/util/timer.h delete mode 100644 hermes_shm/include/hermes_shm/util/type_switch.h delete mode 100644 hermes_shm/test/unit/allocators/test_init.h delete mode 100644 hermes_shm/test/unit/data_structures/containers/iqueue.h delete mode 100644 hermes_shm/test/unit/data_structures/containers/list.h delete mode 100644 hermes_shm/test/unit/data_structures/containers/smart_ptr.h delete mode 100644 hermes_shm/test/unit/data_structures/containers/test_init.h delete mode 100644 hermes_shm/test/unit/data_structures/containers_mpi/test_init.h delete mode 100644 hermes_shm/test/unit/data_structures/serialize/shm/test_init.h delete mode 100644 hermes_shm/test/unit/data_structures/serialize/thallium/test_init.h delete mode 100644 hrun/include/hrun/work_orchestrator/debug.h delete mode 100644 src/api/bucket.h delete mode 100644 src/api/hermes.h delete mode 100644 src/api/vbucket.cc delete mode 100644 src/api/vbucket.h delete mode 100644 src/binlog.h delete mode 100644 src/borg_io_clients/borg_posix_client.h delete mode 100644 src/borg_io_clients/borg_ram_client.h delete mode 100644 src/buffer_organizer.h delete mode 100644 src/buffer_pool.h delete mode 100644 src/config_client.h delete mode 100644 src/config_client_default.h delete mode 100644 src/config_parser.cc delete mode 100644 src/config_server.h delete mode 100644 src/dpe/minimize_io_time.h delete mode 100644 src/hermes_types.h delete mode 100644 src/metadata_manager.h delete mode 100644 src/metadata_types.h delete mode 100644 src/prefetcher.h delete mode 100644 src/prefetcher/apriori_prefetcher.h delete mode 100644 src/prefetcher_factory.h delete mode 100644 src/rpc.h delete mode 100644 src/rpc_thallium.h delete mode 100644 src/rpc_thallium_serialization.h delete mode 100644 src/statuses.h delete mode 100644 src/stb_ds.h delete mode 100644 src/thread_manager.h delete mode 100644 src/trait_manager.h delete mode 100644 test/test_utils.h delete mode 100644 test/trait_order.cc delete mode 100644 test/unit/boost/pthread.h delete mode 100644 test/unit/hermes_adapters/posix/simple_io.cc delete mode 100644 traits/example/example_trait.cc delete mode 100644 traits/example/example_trait.h delete mode 100644 traits/prefetcher/prefetcher_header.h delete mode 100644 traits/prefetcher/prefetcher_trait.h delete mode 100644 wrapper/c/c_wrapper.h delete mode 100644 wrapper/hermes_wrapper.cpp delete mode 100644 wrapper/hermes_wrapper.h delete mode 100644 wrapper/java/src/hermes/cpp/hermes_java_wrapper.h delete mode 100644 wrapper/java/src/hermes/cpp/src_main_Blob.h delete mode 100644 wrapper/java/src/hermes/cpp/src_main_Bucket.h delete mode 100644 wrapper/java/src/hermes/cpp/src_main_Hermes.h diff --git a/adapter/filesystem/filesystem.h b/adapter/filesystem/filesystem.h deleted file mode 100644 index 72776ba3c..000000000 --- a/adapter/filesystem/filesystem.h +++ /dev/null @@ -1,232 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_H_ -#define HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_H_ - -#ifndef O_TMPFILE -#define O_TMPFILE 0x0 -#endif - -#include -#include - -#include -#include -#include -#include - -#include "bucket.h" -#include "filesystem_io_client.h" -#include "hermes.h" - -namespace hapi = hermes::api; - -namespace hermes::adapter::fs { - -/** The maximum length of a posix path */ -static inline const int kMaxPathLen = 4096; - -/** The type of seek to perform */ -enum class SeekMode { - kNone = -1, - kSet = SEEK_SET, - kCurrent = SEEK_CUR, - kEnd = SEEK_END -}; - -/** A class to represent file system */ -class Filesystem { - public: - FilesystemIoClient *io_client_; - AdapterType type_; - - public: - /** Constructor */ - explicit Filesystem(FilesystemIoClient *io_client, AdapterType type) - : io_client_(io_client), type_(type) {} - - /** open \a path */ - File Open(AdapterStat &stat, const std::string &path); - - /** open \a f File in \a path*/ - void Open(AdapterStat &stat, File &f, const std::string &path); - - /** - * Put \a blob_name Blob into the bucket. Load the blob from the - * I/O backend if it does not exist or is not fully loaded. - * - * @param bkt the bucket to use for the partial operation - * @param blob_name the semantic name of the blob - * @param blob the buffer to put final data in - * @param blob_off the offset within the blob to begin the Put - * @param page_size the page size of the adapter - * @param blob_id [out] the blob id corresponding to blob_name - * @param io_ctx information required to perform I/O to the backend - * @param opts specific configuration of the I/O to perform - * @param ctx any additional information - * */ - Status PartialPutOrCreate(hapi::Bucket &bkt, const std::string &blob_name, - const Blob &blob, size_t blob_off, size_t page_size, - BlobId &blob_id, IoStatus &status, - const FsIoOptions &opts, Context &ctx); - - /** write */ - size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t off, - size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); - - /** - * Load \a blob_name Blob from the bucket. Load the blob from the - * I/O backend if it does not exist or is not fully loaded. - * - * @param bkt the bucket to use for the partial operation - * @param blob_name the semantic name of the blob - * @param blob the buffer to put final data in - * @param blob_off the offset within the blob to begin the Put - * @param page_size the page size of the adapter - * @param blob_id [out] the blob id corresponding to blob_name - * @param io_ctx information required to perform I/O to the backend - * @param opts specific configuration of the I/O to perform - * @param ctx any additional information - * */ - Status PartialGetOrCreate(hapi::Bucket &bkt, const std::string &blob_name, - Blob &blob, size_t blob_off, size_t blob_size, - size_t page_size, BlobId &blob_id, IoStatus &status, - const FsIoOptions &opts, Context &ctx); - - /** read */ - size_t Read(File &f, AdapterStat &stat, void *ptr, size_t off, - size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); - - /** write asynchronously */ - HermesRequest *AWrite(File &f, AdapterStat &stat, const void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); - /** read asynchronously */ - HermesRequest *ARead(File &f, AdapterStat &stat, void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); - /** wait for \a req_id request ID */ - size_t Wait(uint64_t req_id); - /** wait for request IDs in \a req_id vector */ - void Wait(std::vector &req_id, std::vector &ret); - /** seek */ - off_t Seek(File &f, AdapterStat &stat, SeekMode whence, off64_t offset); - /** file size */ - size_t GetSize(File &f, AdapterStat &stat); - /** tell */ - off_t Tell(File &f, AdapterStat &stat); - /** sync */ - int Sync(File &f, AdapterStat &stat); - /** truncate */ - int Truncate(File &f, AdapterStat &stat, size_t new_size); - /** close */ - int Close(File &f, AdapterStat &stat); - /** remove */ - int Remove(const std::string &pathname); - - /* - * I/O APIs which seek based on the internal AdapterStat st_ptr, - * instead of taking an offset as input. - */ - - public: - /** write */ - size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts); - /** read */ - size_t Read(File &f, AdapterStat &stat, void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts); - /** write asynchronously */ - HermesRequest *AWrite(File &f, AdapterStat &stat, const void *ptr, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); - /** read asynchronously */ - HermesRequest *ARead(File &f, AdapterStat &stat, void *ptr, size_t total_size, - size_t req_id, IoStatus &io_status, FsIoOptions opts); - - /* - * Locates the AdapterStat data structure internally, and - * call the underlying APIs which take AdapterStat as input. - */ - - public: - /** write */ - size_t Write(File &f, bool &stat_exists, const void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts = FsIoOptions()); - /** read */ - size_t Read(File &f, bool &stat_exists, void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts = FsIoOptions()); - /** write \a off offset */ - size_t Write(File &f, bool &stat_exists, const void *ptr, size_t off, - size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); - /** read \a off offset */ - size_t Read(File &f, bool &stat_exists, void *ptr, size_t off, - size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); - /** write asynchronously */ - HermesRequest *AWrite(File &f, bool &stat_exists, const void *ptr, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); - /** read asynchronously */ - HermesRequest *ARead(File &f, bool &stat_exists, void *ptr, size_t total_size, - size_t req_id, IoStatus &io_status, FsIoOptions opts); - /** write \a off offset asynchronously */ - HermesRequest *AWrite(File &f, bool &stat_exists, const void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); - /** read \a off offset asynchronously */ - HermesRequest *ARead(File &f, bool &stat_exists, void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); - /** seek */ - off_t Seek(File &f, bool &stat_exists, SeekMode whence, off_t offset); - /** file sizes */ - size_t GetSize(File &f, bool &stat_exists); - /** tell */ - off_t Tell(File &f, bool &stat_exists); - /** sync */ - int Sync(File &f, bool &stat_exists); - /** truncate */ - int Truncate(File &f, bool &stat_exists, size_t new_size); - /** close */ - int Close(File &f, bool &stat_exists); - - public: - /** Whether or not \a path PATH is tracked by Hermes */ - static bool IsPathTracked(const std::string &path) { - if (!HERMES->IsInitialized()) { - return false; - } - std::string abs_path = stdfs::absolute(path).string(); - auto &paths = HERMES->client_config_.path_list_; - // Check if path is included or excluded - for (config::UserPathInfo &pth : paths) { - if (abs_path.rfind(pth.path_) != std::string::npos) { - if (abs_path == pth.path_ && pth.is_directory_) { - // Do not include if path is a tracked directory - return false; - } - return pth.include_; - } - } - // Assume it is excluded - return false; - } -}; - -} // namespace hermes::adapter::fs - -#endif // HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_H_ diff --git a/adapter/filesystem/filesystem_mdm.h b/adapter/filesystem/filesystem_mdm.h deleted file mode 100644 index 4dad8f9be..000000000 --- a/adapter/filesystem/filesystem_mdm.h +++ /dev/null @@ -1,116 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_METADATA_MANAGER_H -#define HERMES_ADAPTER_METADATA_MANAGER_H - -#include -#include - -#include "filesystem.h" -#include "filesystem_io_client.h" -#include "thread_pool.h" - -namespace hermes::adapter::fs { - -/** - * Metadata manager for POSIX adapter - */ -class MetadataManager { - private: - std::unordered_map> - path_to_hermes_file_; /**< Map to determine if path is buffered. */ - std::unordered_map> - hermes_file_to_stat_; /**< Map for metadata */ - RwLock lock_; /**< Lock to synchronize MD updates*/ - - public: - /** map for Hermes request */ - std::unordered_map request_map; - FsIoClientMetadata fs_mdm_; /**< Context needed for I/O clients */ - - /** Constructor */ - MetadataManager() = default; - - /** Get the current adapter mode */ - AdapterMode GetBaseAdapterMode() { - ScopedRwReadLock md_lock(lock_, kFS_GetBaseAdapterMode); - return HERMES->client_config_.GetBaseAdapterMode(); - } - - /** Get the adapter mode for a particular file */ - AdapterMode GetAdapterMode(const std::string& path) { - ScopedRwReadLock md_lock(lock_, kFS_GetAdapterMode); - return HERMES->client_config_.GetAdapterConfig(path).mode_; - } - - /** Get the adapter page size for a particular file */ - size_t GetAdapterPageSize(const std::string& path) { - ScopedRwReadLock md_lock(lock_, kFS_GetAdapterPageSize); - return HERMES->client_config_.GetAdapterConfig(path).page_size_; - } - - /** - * Create a metadata entry for filesystem adapters given File handler. - * @param f original file handler of the file on the destination - * filesystem. - * @param stat POSIX Adapter version of Stat data structure. - * @return true, if operation was successful. - * false, if operation was unsuccessful. - */ - bool Create(const File& f, std::shared_ptr& stat); - - /** - * Update existing metadata entry for filesystem adapters. - * @param f original file handler of the file on the destination. - * @param stat POSIX Adapter version of Stat data structure. - * @return true, if operation was successful. - * false, if operation was unsuccessful or entry doesn't exist. - */ - bool Update(const File& f, const AdapterStat& stat); - - /** - * Delete existing metadata entry for for filesystem adapters. - * @param f original file handler of the file on the destination. - * @return true, if operation was successful. - * false, if operation was unsuccessful. - */ - bool Delete(const std::string& path, const File& f); - - /** - * Find the hermes file relating to a path. - * @param path the path being checked - * @return The hermes file. - * */ - std::list* Find(const std::string& path); - - /** - * Find existing metadata entry for filesystem adapters. - * @param f original file handler of the file on the destination. - * @return The metadata entry if exist. - * The bool in pair indicated whether metadata entry exists. - */ - std::shared_ptr Find(const File& f); -}; -} // namespace hermes::adapter::fs - -// Singleton macros -#include "hermes_shm/util/singleton.h" - -#define HERMES_FS_METADATA_MANAGER \ - hshm::Singleton::GetInstance() -#define HERMES_FS_METADATA_MANAGER_T hermes::adapter::fs::MetadataManager* - -#define HERMES_FS_THREAD_POOL \ - hshm::EasySingleton::GetInstance() - -#endif // HERMES_ADAPTER_METADATA_MANAGER_H diff --git a/adapter/kvstore/kvstore.h b/adapter/kvstore/kvstore.h deleted file mode 100644 index cfbf43173..000000000 --- a/adapter/kvstore/kvstore.h +++ /dev/null @@ -1,178 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_KVSTORE_KVSTORE_H_ -#define HERMES_ADAPTER_KVSTORE_KVSTORE_H_ - -#include -#include - -#include "hermes.h" - -namespace hermes::adapter { - -/** Denotes the set of fields for a record */ -typedef std::unordered_set KVFieldSet; - -/** Measure the serialized size */ -struct BlobSerializeCounter { - size_t size_; - - /** Constructor */ - BlobSerializeCounter() : size_(0) {} - - /** Serialize std::string into blob */ - BlobSerializeCounter &operator<<(const std::string &data) { - (*this) << data.size(); - size_ += data.size(); - return *this; - } - - /** Serialize blob into blob */ - BlobSerializeCounter &operator<<(const hapi::Blob &data) { - (*this) << data.size(); - size_ += data.size(); - return *this; - } - - /** Serialize size_t into blob */ - BlobSerializeCounter &operator<<(const size_t &data) { - size_ += sizeof(size_t); - return *this; - } -}; - -/** Serialize data into and out of blob */ -struct BlobSerializer { - hapi::Blob &blob_; - size_t off_; - - /** Constructor */ - explicit BlobSerializer(hapi::Blob &blob) : blob_(blob), off_(0) {} - - /** Serialize a string type */ - template - void SerializeString(const StringT &data) { - (*this) << data.size(); - memcpy(blob_.data() + off_, data.data(), data.size()); - off_ += data.size(); - } - - /** Deserialize a string type */ - template - void DeserializeString(StringT &data) { - size_t size; - (*this) >> size; - data.resize(size); - memcpy(data.data(), blob_.data() + off_, data.size()); - off_ += data.size(); - } - - /** Serialize std::string into blob */ - BlobSerializer &operator<<(const std::string &data) { - SerializeString(data); - return *this; - } - - /** Deserialize std::string from blob */ - BlobSerializer &operator>>(std::string &data) { - DeserializeString(data); - return *this; - } - - /** Serialize blob into blob */ - BlobSerializer &operator<<(const hapi::Blob &data) { - SerializeString(data); - return *this; - } - - /** Deserialize blob from blob */ - BlobSerializer &operator>>(hapi::Blob &data) { - DeserializeString(data); - return *this; - } - - /** Serialize size_t into blob */ - BlobSerializer &operator<<(const size_t &data) { - memcpy(blob_.data() + off_, &data, sizeof(size_t)); - off_ += sizeof(size_t); - return *this; - } - - /** Deserialize size_t from blob */ - BlobSerializer &operator>>(size_t &data) { - memcpy(&data, blob_.data() + off_, sizeof(size_t)); - off_ += sizeof(size_t); - return *this; - } -}; - -/** Denotes a record to place in a table */ -struct KVRecord { - std::unordered_map record_; - - /** Default constructor */ - KVRecord() = default; - - /** Convert the record from a single array of bytes */ - explicit KVRecord(hapi::Blob &blob); - - /** Convert the record into a single array of bytes */ - hapi::Blob value(); -}; - -/** Denotes a set of records */ -class KVTable { - public: - hapi::Bucket bkt_; - - /** Emplace Constructor */ - explicit KVTable(const hapi::Bucket &bkt) : bkt_(bkt) {} - - /** - * Create or insert a record into the table - * - * @param key the record key - * @param val the values to update in the record - * @return None - * */ - void Update(const std::string &key, KVRecord &val); - - /** - * Get a subset of fields from a record - * - * @param key the record key - * @param field the field in the record to update - * @return The blob containing only the field's data - * */ - KVRecord Read(const std::string &key, const KVFieldSet &field); - - /** Delete a record */ - void Erase(const std::string &key); - - /** Destroy this table */ - void Destroy(); -}; - -/** The key-value store instance */ -class KVStore { - public: - /** Connect to Hermes */ - void Connect(); - - /** Get or create a table */ - KVTable GetTable(const std::string table_name); -}; - -} // namespace hermes::adapter - -#endif // HERMES_ADAPTER_KVSTORE_KVSTORE_H_ diff --git a/adapter/mpiio/mpiio_io_client.h b/adapter/mpiio/mpiio_io_client.h deleted file mode 100644 index 5a999d70e..000000000 --- a/adapter/mpiio/mpiio_io_client.h +++ /dev/null @@ -1,115 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_MPIIO_MPIIO_IO_CLIENT_H_ -#define HERMES_ADAPTER_MPIIO_MPIIO_IO_CLIENT_H_ - -#include - -#include "adapter/filesystem/filesystem_io_client.h" -#include "mpiio_api.h" - -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::FsIoOptions; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::MpiioApi; - -namespace hermes::adapter::fs { - -/** State for the MPI I/O trait */ -struct MpiioIoClientHeader : public TraitHeader { - explicit MpiioIoClientHeader(const std::string &trait_uuid, - const std::string &trait_name) - : TraitHeader(trait_uuid, trait_name, HERMES_TRAIT_FLUSH) {} -}; - -/** A class to represent STDIO IO file system */ -class MpiioIoClient : public hermes::adapter::fs::FilesystemIoClient { - public: - HERMES_TRAIT_H(MpiioIoClient, "mpiio_io_client") - - private: - HERMES_MPIIO_API_T real_api; /**< pointer to real APIs */ - - public: - /** Default constructor */ - MpiioIoClient() { - real_api = HERMES_MPIIO_API; - CreateHeader("mpiio_io_client_", trait_name_); - } - - /** Trait deserialization constructor */ - explicit MpiioIoClient(hshm::charbuf ¶ms) { - (void)params; - real_api = HERMES_MPIIO_API; - CreateHeader("mpiio_io_client_", trait_name_); - } - - /** Virtual destructor */ - virtual ~MpiioIoClient() = default; - - public: - /** Allocate an fd for the file f */ - void RealOpen(File &f, AdapterStat &stat, const std::string &path) override; - - /** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as STDIO file - * descriptor and STDIO file handler. - * */ - void HermesOpen(File &f, const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Synchronize \a file FILE f */ - int RealSync(const File &f, const AdapterStat &stat) override; - - /** Close \a file FILE f */ - int RealClose(const File &f, AdapterStat &stat) override; - - /** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ - void HermesClose(File &f, const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Remove \a file FILE f */ - int RealRemove(const std::string &path) override; - - /** Get initial statistics from the backend */ - size_t GetSize(const hipc::charbuf &bkt_name) override; - - /** Initialize I/O context using count + datatype */ - static size_t IoSizeFromCount(int count, MPI_Datatype datatype, - FsIoOptions &opts); - - /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override; - - /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override; - - /** Update the I/O status after a ReadBlob or WriteBlob */ - void UpdateIoStatus(size_t count, IoStatus &status); -}; - -} // namespace hermes::adapter::fs - -/** Simplify access to the stateless StdioIoClient Singleton */ -#define HERMES_MPIIO_IO_CLIENT \ - hshm::EasySingleton::GetInstance() -#define HERMES_MPIIO_IO_CLIENT_T hermes::adapter::fs::MpiioIoClient * - -#endif // HERMES_ADAPTER_MPIIO_MPIIO_IO_CLIENT_H_ diff --git a/adapter/posix/posix_fs_api.h b/adapter/posix/posix_fs_api.h deleted file mode 100644 index 0a4536b2a..000000000 --- a/adapter/posix/posix_fs_api.h +++ /dev/null @@ -1,114 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_POSIX_NATIVE_H_ -#define HERMES_ADAPTER_POSIX_NATIVE_H_ - -#include - -#include "adapter/filesystem/filesystem.h" -#include "adapter/filesystem/filesystem_mdm.h" -#include "posix_api.h" -#include "posix_io_client.h" - -namespace hermes::adapter::fs { - -/** A class to represent POSIX IO file system */ -class PosixFs : public hermes::adapter::fs::Filesystem { - public: - PosixFs() - : hermes::adapter::fs::Filesystem(HERMES_POSIX_IO_CLIENT, - AdapterType::kPosix) {} - - template - int Stat(File &f, StatT *buf) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto existing = mdm->Find(f); - if (existing) { - AdapterStat &astat = *existing; - /*memset(buf, 0, sizeof(StatT)); - buf->st_dev = 0; - buf->st_ino = 0;*/ - buf->st_mode = 0100644; - /*buf->st_nlink = 1;*/ - buf->st_uid = HERMES_SYSTEM_INFO->uid_; - buf->st_gid = HERMES_SYSTEM_INFO->gid_; - // buf->st_rdev = 0; - buf->st_size = GetSize(f, astat); - /*buf->st_blksize = 0; - buf->st_blocks = 0;*/ - buf->st_atime = astat.st_atim_.tv_sec; - buf->st_mtime = astat.st_mtim_.tv_sec; - buf->st_ctime = astat.st_ctim_.tv_sec; - errno = 0; - return 0; - } else { - errno = EBADF; - HELOG(kError, "File with descriptor {} does not exist in Hermes", - f.hermes_fd_) - return -1; - } - } - - template - int Stat(const char *__filename, StatT *buf) { - bool stat_exists; - AdapterStat stat; - stat.flags_ = O_RDONLY; - stat.st_mode_ = 0; - File f = Open(stat, __filename); - if (!f.status_) { - // HILOG(kInfo, "Failed to stat the file {}", __filename); - memset(buf, 0, sizeof(StatT)); - return -1; - } - int result = Stat(f, buf); - Close(f, stat_exists); - return result; - } - - /** Whether or not \a fd FILE DESCRIPTOR was generated by Hermes */ - static bool IsFdTracked(int fd, std::shared_ptr &stat) { - if (!HERMES->IsInitialized() || fd < 8192) { - return false; - } - hermes::adapter::fs::File f; - f.hermes_fd_ = fd; - stat = HERMES_FS_METADATA_MANAGER->Find(f); - return stat != nullptr; - } - - /** Whether or not \a fd FILE DESCRIPTOR was generated by Hermes */ - static bool IsFdTracked(int fd) { - std::shared_ptr stat; - return IsFdTracked(fd, stat); - } - - /** get the file name from \a fd file descriptor */ - std::string GetFilenameFromFD(int fd) { - std::vector proclnk(kMaxPathLen); - std::vector filename(kMaxPathLen); - snprintf(proclnk.data(), kMaxPathLen - 1, "/proc/self/fd/%d", fd); - size_t r = readlink(proclnk.data(), filename.data(), kMaxPathLen); - filename[r] = '\0'; - return std::string(filename.data(), filename.size()); - } -}; - -/** Simplify access to the stateless PosixFs Singleton */ -#define HERMES_POSIX_FS \ - hshm::EasySingleton::GetInstance() -#define HERMES_POSIX_FS_T hermes::adapter::fs::PosixFs * - -} // namespace hermes::adapter::fs - -#endif // HERMES_ADAPTER_POSIX_NATIVE_H_ diff --git a/adapter/posix/posix_io_client.h b/adapter/posix/posix_io_client.h deleted file mode 100644 index fc294eafc..000000000 --- a/adapter/posix/posix_io_client.h +++ /dev/null @@ -1,109 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_POSIX_POSIX_IO_CLIENT_H_ -#define HERMES_ADAPTER_POSIX_POSIX_IO_CLIENT_H_ - -#include - -#include "adapter/filesystem/filesystem_io_client.h" -#include "posix_api.h" - -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::FsIoOptions; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::PosixApi; -using hshm::Singleton; - -namespace hermes::adapter::fs { - -/** State for the POSIX I/O trait */ -struct PosixIoClientHeader : public TraitHeader { - explicit PosixIoClientHeader(const std::string &trait_uuid, - const std::string &trait_name) - : TraitHeader(trait_uuid, trait_name, HERMES_TRAIT_FLUSH) {} -}; - -/** A class to represent POSIX IO file system */ -class PosixIoClient : public hermes::adapter::fs::FilesystemIoClient { - public: - HERMES_TRAIT_H(PosixIoClient, "posix_io_client") - - private: - HERMES_POSIX_API_T real_api; /**< pointer to real APIs */ - - public: - /** Default constructor */ - PosixIoClient() { - real_api = HERMES_POSIX_API; - CreateHeader("posix_io_client_", trait_name_); - } - - /** Trait deserialization constructor */ - explicit PosixIoClient(hshm::charbuf ¶ms) { - (void)params; - real_api = HERMES_POSIX_API; - CreateHeader("posix_io_client_", trait_name_); - } - - /** Virtual destructor */ - virtual ~PosixIoClient() = default; - - public: - /** Allocate an fd for the file f */ - void RealOpen(File &f, AdapterStat &stat, const std::string &path) override; - - /** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as POSIX file - * descriptor and STDIO file handler. - * */ - void HermesOpen(File &f, const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Synchronize \a file FILE f */ - int RealSync(const File &f, const AdapterStat &stat) override; - - /** Close \a file FILE f */ - int RealClose(const File &f, AdapterStat &stat) override; - - /** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ - void HermesClose(File &f, const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Remove \a file FILE f */ - int RealRemove(const std::string &path) override; - - /** Get initial statistics from the backend */ - size_t GetSize(const hipc::charbuf &bkt_name) override; - - /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override; - - /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override; -}; - -} // namespace hermes::adapter::fs - -/** Simplify access to the stateless PosixIoClient Singleton */ -#define HERMES_POSIX_IO_CLIENT \ - hshm::EasySingleton::GetInstance() -#define HERMES_POSIX_IO_CLIENT_T hermes::adapter::fs::PosixIoClient * - -#endif // HERMES_ADAPTER_POSIX_POSIX_IO_CLIENT_H_ diff --git a/adapter/real_api.h b/adapter/real_api.h deleted file mode 100644 index 68d18c8e2..000000000 --- a/adapter/real_api.h +++ /dev/null @@ -1,70 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_API_H -#define HERMES_ADAPTER_API_H - -#include -#include - -#define REQUIRE_API(api_name) \ - if (!(api_name)) { \ - HELOG(kFatal, "HERMES Adapter failed to map symbol: {}", #api_name); \ - } - -namespace hermes::adapter { - -struct RealApiIter { - const char *symbol_name_; - const char *is_intercepted_; - const char *lib_path_; - - RealApiIter(const char *symbol_name, const char *is_intercepted) - : symbol_name_(symbol_name), - is_intercepted_(is_intercepted), - lib_path_(nullptr) {} -}; - -struct RealApi { - void *real_lib_next_; /**< TODO(llogan): remove */ - void *real_lib_default_; /**< TODO(llogan): remove */ - void *real_lib_; - bool is_intercepted_; - - static int callback(struct dl_phdr_info *info, size_t size, void *data) { - auto iter = (RealApiIter *)data; - auto lib = dlopen(info->dlpi_name, RTLD_GLOBAL | RTLD_NOW); - auto exists = dlsym(lib, iter->symbol_name_); - void *is_intercepted = (void *)dlsym(lib, iter->is_intercepted_); - if (!is_intercepted && exists) { - iter->lib_path_ = info->dlpi_name; - } - return 0; - } - - RealApi(const char *symbol_name, const char *is_intercepted) - : real_lib_next_(nullptr), real_lib_default_(nullptr) { - RealApiIter iter(symbol_name, is_intercepted); - dl_iterate_phdr(callback, (void *)&iter); - if (iter.lib_path_) { - real_lib_ = dlopen(iter.lib_path_, RTLD_GLOBAL | RTLD_NOW); - real_lib_next_ = real_lib_; - real_lib_default_ = real_lib_; - } - void *is_intercepted_ptr = (void *)dlsym(RTLD_DEFAULT, is_intercepted); - is_intercepted_ = is_intercepted_ptr != nullptr; - } -}; - -} // namespace hermes::adapter - -#endif // HERMES_ADAPTER_API_H diff --git a/adapter/stdio/stdio_fs_api.h b/adapter/stdio/stdio_fs_api.h deleted file mode 100644 index 75895ddd8..000000000 --- a/adapter/stdio/stdio_fs_api.h +++ /dev/null @@ -1,104 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_STDIO_NATIVE_H_ -#define HERMES_ADAPTER_STDIO_NATIVE_H_ - -#include - -#include "adapter/filesystem/filesystem.h" -#include "adapter/filesystem/filesystem_mdm.h" -#include "adapter/posix/posix_fs_api.h" -#include "stdio_api.h" -#include "stdio_io_client.h" - -namespace hermes::adapter::fs { - -/** A class to represent POSIX IO file system */ -class StdioFs : public hermes::adapter::fs::Filesystem { - public: - StdioFs() - : hermes::adapter::fs::Filesystem(HERMES_STDIO_IO_CLIENT, - AdapterType::kStdio) {} - - /** Close an existing stream and then open with new path */ - FILE *Reopen(const std::string &user_path, const char *mode, - AdapterStat &stat) { - auto real_api = HERMES_STDIO_API; - FILE *ret; - ret = real_api->freopen(user_path.c_str(), mode, stat.fh_); - if (!ret) { - return ret; - } - stat.fh_ = ret; - HILOG(kDebug, "Reopen file for filename: {} in mode {}", user_path, mode) - stat.UpdateTime(); - return (FILE *)&stat; - } - - /** fdopen */ - FILE *FdOpen(const std::string &mode, std::shared_ptr &stat) { - auto real_api = HERMES_STDIO_API; - auto mdm = HERMES_FS_METADATA_MANAGER; - stat->fh_ = real_api->fdopen(stat->fd_, mode.c_str()); - stat->mode_str_ = mode; - File f; - f.hermes_fh_ = (FILE *)stat.get(); - mdm->Create(f, stat); - return f.hermes_fh_; - } - - /** Whether or not \a fd FILE DESCRIPTOR is tracked */ - static bool IsFdTracked(int fd, std::shared_ptr &stat) { - return PosixFs::IsFdTracked(fd, stat); - } - - /** Whether or not \a fd FILE DESCRIPTOR is tracked */ - static bool IsFdTracked(int fd) { return PosixFs::IsFdTracked(fd); } - - /** Whether or not \a fp FILE was generated by Hermes */ - static bool IsFpTracked(FILE *fp, std::shared_ptr &stat) { - if (!fp || !HERMES->IsInitialized()) { - return false; - } - hermes::adapter::fs::File f; - f.hermes_fh_ = fp; - stat = HERMES_FS_METADATA_MANAGER->Find(f); - return stat != nullptr; - } - - /** Whether or not \a fp FILE was generated by Hermes */ - static bool IsFpTracked(FILE *fp) { - std::shared_ptr stat; - return IsFpTracked(fp, stat); - } - - /** get the file name from \a fp file pointer */ - static std::string GetFilenameFromFP(FILE *fp) { - char proclnk[kMaxPathLen]; - char filename[kMaxPathLen]; - int fno = fileno(fp); - snprintf(proclnk, kMaxPathLen, "/proc/self/fd/%d", fno); - size_t r = readlink(proclnk, filename, kMaxPathLen); - filename[r] = '\0'; - return filename; - } -}; - -/** Simplify access to the stateless StdioFs Singleton */ -#define HERMES_STDIO_FS \ - hshm::EasySingleton::GetInstance() -#define HERMES_STDIO_FS_T hermes::adapter::fs::StdioFs * - -} // namespace hermes::adapter::fs - -#endif // HERMES_ADAPTER_STDIO_NATIVE_H_ diff --git a/adapter/stdio/stdio_io_client.h b/adapter/stdio/stdio_io_client.h deleted file mode 100644 index 7402cc8e7..000000000 --- a/adapter/stdio/stdio_io_client.h +++ /dev/null @@ -1,108 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_STDIO_STDIO_IO_CLIENT_H_ -#define HERMES_ADAPTER_STDIO_STDIO_IO_CLIENT_H_ - -#include - -#include "adapter/filesystem/filesystem_io_client.h" -#include "stdio_api.h" - -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::FsIoOptions; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::StdioApi; - -namespace hermes::adapter::fs { - -/** State for the STDIO I/O trait */ -struct StdioIoClientHeader : public TraitHeader { - explicit StdioIoClientHeader(const std::string &trait_uuid, - const std::string &trait_name) - : TraitHeader(trait_uuid, trait_name, HERMES_TRAIT_FLUSH) {} -}; - -/** A class to represent STDIO IO file system */ -class StdioIoClient : public hermes::adapter::fs::FilesystemIoClient { - public: - HERMES_TRAIT_H(StdioIoClient, "stdio_io_client") - - private: - HERMES_STDIO_API_T real_api; /**< pointer to real APIs */ - - public: - /** Default constructor */ - StdioIoClient() { - real_api = HERMES_STDIO_API; - CreateHeader(trait_name_, trait_name_); - } - - /** Trait deserialization constructor */ - explicit StdioIoClient(hshm::charbuf ¶ms) { - (void)params; - real_api = HERMES_STDIO_API; - CreateHeader(trait_name_, trait_name_); - } - - /** Virtual destructor */ - virtual ~StdioIoClient() = default; - - public: - /** Allocate an fd for the file f */ - void RealOpen(File &f, AdapterStat &stat, const std::string &path) override; - - /** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as STDIO file - * descriptor and STDIO file handler. - * */ - void HermesOpen(File &f, const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Synchronize \a file FILE f */ - int RealSync(const File &f, const AdapterStat &stat) override; - - /** Close \a file FILE f */ - int RealClose(const File &f, AdapterStat &stat) override; - - /** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ - void HermesClose(File &f, const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Remove \a file FILE f */ - int RealRemove(const std::string &path) override; - - /** Get initial statistics from the backend */ - size_t GetSize(const hipc::charbuf &bkt_name) override; - - /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override; - - /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override; -}; - -} // namespace hermes::adapter::fs - -/** Simplify access to the stateless StdioIoClient Singleton */ -#define HERMES_STDIO_IO_CLIENT \ - hshm::EasySingleton::GetInstance() -#define HERMES_STDIO_IO_CLIENT_T hermes::adapter::fs::StdioIoClient * - -#endif // HERMES_ADAPTER_STDIO_STDIO_IO_CLIENT_H_ diff --git a/adapter/test/adapter_test_utils.h b/adapter/test/adapter_test_utils.h deleted file mode 100644 index 18b7f2e6d..000000000 --- a/adapter/test/adapter_test_utils.h +++ /dev/null @@ -1,62 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_TEST_UTILS_H -#define HERMES_ADAPTER_TEST_UTILS_H -#include - -#include -#include -#include - -bool FilesystemSupportsTmpfile() { - bool result = false; - -#if O_TMPFILE - // NOTE(chogan): Even if O_TMPFILE is defined, the underlying filesystem might - // not support it. - int tmp_fd = open("/tmp", O_WRONLY | O_TMPFILE, 0600); - if (tmp_fd > 0) { - result = true; - close(tmp_fd); - } -#endif - - return result; -} - -size_t GetRandomOffset(size_t i, unsigned int offset_seed, size_t stride, - size_t total_size) { - return abs((int)(((i * rand_r(&offset_seed)) % stride) % total_size)); -} - -std::string GenRandom(const int len) { - std::string tmp_s; - static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - - srand(100); - - tmp_s.reserve(len); - - for (int i = 0; i < len; ++i) { - tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)]; - } - - tmp_s[len - 1] = '\n'; - - return tmp_s; -} - -#endif // HERMES_ADAPTER_TEST_UTILS_H diff --git a/adapter/test/mpiio/mpiio_adapter_test.cpp b/adapter/test/mpiio/mpiio_adapter_test.cpp deleted file mode 100644 index e4140b954..000000000 --- a/adapter/test/mpiio/mpiio_adapter_test.cpp +++ /dev/null @@ -1,685 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include - -#include -#include - -#include "adapter_test_utils.h" -#include "catch_config.h" -#if HERMES_INTERCEPT == 1 -#include "filesystem/filesystem.h" -#endif - -#include "adapter_test_utils.h" - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::mpiio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - bool debug = false; - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string shared_new_file; - std::string shared_existing_file; - std::string new_file_cmp; - std::string existing_file_cmp; - std::string shared_new_file_cmp; - std::string shared_existing_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; - size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::mpiio::test -hermes::adapter::mpiio::test::Arguments args; -hermes::adapter::mpiio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - info.write_data = GenRandom(args.request_size); - info.read_data = std::string(args.request_size, 'r'); - MPI_Comm_rank(MPI_COMM_WORLD, &info.rank); - MPI_Comm_size(MPI_COMM_WORLD, &info.comm_size); - if (info.debug && info.rank == 0) { - printf("ready for attach\n"); - fflush(stdout); - sleep(30); - } - MPI_Barrier(MPI_COMM_WORLD); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -const char* kUser = "USER"; - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename + "_" + std::string(getenv(kUser)); - info.new_file = fullpath.string() + "_new_" + std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext_" + std::to_string(getpid()); - info.new_file_cmp = - fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - info.shared_new_file = - fullpath.string() + "_shared_new_" + std::to_string(info.comm_size); - info.shared_existing_file = - fullpath.string() + "_shared_ext_" + std::to_string(info.comm_size); - info.shared_new_file_cmp = - fullpath.string() + "_shared_new_cmp_" + std::to_string(info.comm_size); - info.shared_existing_file_cmp = - fullpath.string() + "_shared_ext_cmp_" + std::to_string(info.comm_size); - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + info.existing_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - } - MPI_Barrier(MPI_COMM_WORLD); - if (!stdfs::exists(info.existing_file_cmp)) { - std::string cmd = "cp " + info.existing_file + " " + info.existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - } - MPI_Barrier(MPI_COMM_WORLD); - if (info.rank == 0) { - if (stdfs::exists(info.shared_new_file)) - stdfs::remove(info.shared_new_file); - if (stdfs::exists(info.shared_existing_file)) - stdfs::remove(info.shared_existing_file); - if (!stdfs::exists(info.shared_existing_file)) { - std::string cmd = - "cp " + info.existing_file + " " + info.shared_existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.shared_existing_file) == - args.request_size * info.num_iterations); - } - if (stdfs::exists(info.shared_new_file_cmp)) - stdfs::remove(info.shared_new_file_cmp); - if (stdfs::exists(info.shared_existing_file_cmp)) - stdfs::remove(info.shared_existing_file_cmp); - if (!stdfs::exists(info.shared_existing_file_cmp)) { - std::string cmd = - "cp " + info.existing_file + " " + info.shared_existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.shared_existing_file_cmp) == - args.request_size * info.num_iterations); - } - } - MPI_Barrier(MPI_COMM_WORLD); - REQUIRE(info.total_size > 0); -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.shared_new_file_cmp, - false); - HERMES->client_config_.SetAdapterPathTracking(info.shared_existing_file_cmp, - false); -#endif - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest(bool compare_data = true) { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); -#endif - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - Clear(); - -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, true); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, true); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, true); -#endif - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -MPI_File fh_orig; -MPI_File fh_cmp; -int status_orig; -int size_read_orig; -int size_written_orig; - -void test_read_data(size_t size_read, size_t count, int type_size, - char* read_data, char* ptr) { - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < count * type_size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} - -void test_open(const char* path, int mode, MPI_Comm comm) { - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else if (strcmp(path, info.existing_file.c_str()) == 0) { - cmp_path = info.existing_file_cmp; - } else if (strcmp(path, info.shared_new_file.c_str()) == 0) { - cmp_path = info.shared_new_file_cmp; - } else { - cmp_path = info.shared_existing_file_cmp; - } - status_orig = MPI_File_open(comm, path, mode, MPI_INFO_NULL, &fh_orig); - auto status_cmp = - MPI_File_open(comm, cmp_path.c_str(), mode, MPI_INFO_NULL, &fh_cmp); - bool is_same = (status_orig != MPI_SUCCESS && status_cmp != MPI_SUCCESS) || - (status_orig == MPI_SUCCESS && status_cmp == MPI_SUCCESS); - REQUIRE(is_same); -} -void test_close() { - status_orig = MPI_File_close(&fh_orig); - int status = MPI_File_close(&fh_cmp); - REQUIRE(status == status_orig); -} - -void test_preallocate(MPI_Offset size) { - status_orig = MPI_File_preallocate(fh_orig, size); - int status = MPI_File_preallocate(fh_cmp, size); - REQUIRE(status == status_orig); -} - -void test_write(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_write(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = MPI_File_write(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = MPI_File_iwrite(fh_orig, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = MPI_File_iwrite(fh_cmp, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_shared(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_shared(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = MPI_File_write_shared(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_shared(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iwrite_shared(fh_orig, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = - MPI_File_iwrite_shared(fh_cmp, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_all(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_write_all(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = MPI_File_write_all(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_all(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iwrite_all(fh_orig, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = MPI_File_iwrite_all(fh_cmp, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_at(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_at(fh_orig, offset, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = - MPI_File_write_at(fh_cmp, offset, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_at(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iwrite_at(fh_orig, offset, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = - MPI_File_iwrite_at(fh_cmp, offset, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[0], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_at_all(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_at_all(fh_orig, offset, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = - MPI_File_write_at_all(fh_cmp, offset, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_at_all(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = MPI_File_iwrite_at_all(fh_orig, offset, ptr, count, datatype, - &request[0]); - int size_written; - auto ret_cmp = - MPI_File_iwrite_at_all(fh_cmp, offset, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_ordered(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_ordered(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = - MPI_File_write_ordered(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_read(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_read(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = - MPI_File_read(fh_cmp, read_data.data(), count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = MPI_File_iread(fh_orig, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = - MPI_File_iread(fh_cmp, read_data.data(), count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_shared(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_shared(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_shared(fh_cmp, read_data.data(), count, datatype, - &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_shared(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_shared(fh_orig, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_shared(fh_cmp, read_data.data(), count, - datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_all(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_read_all(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = - MPI_File_read_all(fh_cmp, read_data.data(), count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_all(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_all(fh_orig, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_all(fh_cmp, read_data.data(), count, datatype, - &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_ordered(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_ordered(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_ordered(fh_cmp, read_data.data(), count, - datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_at(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_at(fh_orig, offset, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_at(fh_cmp, offset, read_data.data(), count, - datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_at(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_at(fh_orig, offset, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_at(fh_cmp, offset, read_data.data(), count, - datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_at_all(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_at_all(fh_orig, offset, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_at_all(fh_cmp, offset, read_data.data(), count, - datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_at_all(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_at_all(fh_orig, offset, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_at_all(fh_cmp, offset, read_data.data(), count, - datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_seek(MPI_Offset offset, int whence) { - status_orig = MPI_File_seek(fh_orig, offset, whence); - int status = MPI_File_seek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} - -void test_seek_shared(MPI_Offset offset, int whence) { - status_orig = MPI_File_seek_shared(fh_orig, offset, whence); - int status = MPI_File_seek_shared(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -#include "mpiio_adapter_basic_test.cpp" diff --git a/adapter/test/posix/posix_adapter_basic_test.cpp b/adapter/test/posix/posix_adapter_basic_test.cpp deleted file mode 100644 index 6bca7d0e3..000000000 --- a/adapter/test/posix/posix_adapter_basic_test.cpp +++ /dev/null @@ -1,1479 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include - -TEST_CASE("Open", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_open]" - "[repetition=1][file=1]") { - pretest(); - SECTION("open non-existant file") { - test::test_open(info.new_file.c_str(), O_WRONLY); - REQUIRE(test::fh_orig == -1); - test::test_open(info.new_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig == -1); - test::test_open(info.new_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig == -1); - } - - SECTION("truncate existing file and write-only") { - test::test_open(info.existing_file.c_str(), O_WRONLY | O_TRUNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("truncate existing file and read/write") { - test::test_open(info.existing_file.c_str(), O_RDWR | O_TRUNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("open existing file") { - test::test_open(info.existing_file.c_str(), O_WRONLY); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("append write existing file") { - test::test_open(info.existing_file.c_str(), O_APPEND); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("create a new file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - stdfs::remove(info.new_file); - - test::test_open(info.new_file.c_str(), O_RDONLY | O_CREAT, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - stdfs::remove(info.new_file); - - test::test_open(info.new_file.c_str(), O_RDWR | O_CREAT, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("create a existing file") { - test::test_open(info.existing_file.c_str(), O_WRONLY | O_CREAT, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_CREAT, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_CREAT, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - - test::test_open(info.existing_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, - 0600); - REQUIRE(test::fh_orig == -1); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_CREAT | O_EXCL, - 0600); - REQUIRE(test::fh_orig == -1); - test::test_open(info.existing_file.c_str(), O_RDWR | O_CREAT | O_EXCL, - 0600); - REQUIRE(test::fh_orig == -1); - } - SECTION("Async I/O") { - test::test_open(info.existing_file.c_str(), O_WRONLY | O_ASYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_ASYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_ASYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_APPEND | O_ASYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - - test::test_open(info.existing_file.c_str(), O_WRONLY | O_NONBLOCK); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_NONBLOCK); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_NONBLOCK); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_APPEND | O_NONBLOCK); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - - test::test_open(info.existing_file.c_str(), O_WRONLY | O_NDELAY); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_NDELAY); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_NDELAY); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_APPEND | O_NDELAY); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("Async I/O") { - test::test_open(info.existing_file.c_str(), O_WRONLY | O_DIRECT); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_DIRECT); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_DIRECT); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_APPEND | O_DIRECT); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("Write Synchronize") { - /* File synchronicity */ - test::test_open(info.existing_file.c_str(), O_WRONLY | O_DSYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_DSYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_DSYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_APPEND | O_DSYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - - /* Write synchronicity */ - test::test_open(info.existing_file.c_str(), O_WRONLY | O_SYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_SYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_RDWR | O_SYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.existing_file.c_str(), O_APPEND | O_SYNC); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("Temporary file") { - if (info.supports_tmpfile) { - test::test_open("/tmp", O_WRONLY | O_TMPFILE, 0600); - REQUIRE(test::fh_orig != -1); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.new_file.c_str(), O_RDONLY | O_TMPFILE, 0600); - REQUIRE(test::fh_orig == -1); - test::test_open(info.new_file.c_str(), O_RDWR | O_TMPFILE, 0600); - REQUIRE(test::fh_orig == -1); - test::test_open(info.new_file.c_str(), O_APPEND | O_TMPFILE, 0600); - REQUIRE(test::fh_orig == -1); - - test::test_open(info.existing_file.c_str(), O_WRONLY | O_TMPFILE, 0600); - REQUIRE(test::fh_orig == -1); - test::test_open(info.existing_file.c_str(), O_RDONLY | O_TMPFILE, 0600); - REQUIRE(test::fh_orig == -1); - test::test_open(info.existing_file.c_str(), O_RDWR | O_TMPFILE, 0600); - REQUIRE(test::fh_orig == -1); - } - } - posttest(); -} - -TEST_CASE("SingleWrite", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("write to new file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == test::size_written_orig); - } - - SECTION("write to existing file with truncate") { - test::test_open(info.existing_file.c_str(), O_WRONLY | O_TRUNC); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.existing_file) == test::size_written_orig); - } - - SECTION("write to existing file at the end") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - test::test_seek(0, SEEK_END); - REQUIRE(((size_t)test::status_orig) == - args.request_size * info.num_iterations); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.existing_file) == - test::size_written_orig + args.request_size * info.num_iterations); - } - - SECTION("append to existing file") { - auto existing_size = stdfs::file_size(info.existing_file); - test::test_open(info.existing_file.c_str(), O_RDWR | O_APPEND); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.existing_file) == - existing_size + test::size_written_orig); - } - - SECTION("append to new file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == test::size_written_orig); - } - posttest(); -} - -TEST_CASE("SingleRead", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read from non-existing file") { - test::test_open(info.new_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig == -1); - } - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig != -1); - test::test_seek(0, SEEK_CUR); - REQUIRE(test::status_orig == 0); - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("read at the end of existing file") { - test::test_open(info.existing_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig != -1); - test::test_seek(0, SEEK_END); - REQUIRE(((size_t)test::status_orig) == - args.request_size * info.num_iterations); - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == 0); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedWriteSequential", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - SECTION("write to existing file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == args.request_size); - } - - SECTION("write to new file always at start") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedReadSequential", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < 1; ++i) { - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::is_scase_ = true; - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadRandom", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed]" - "[repetition=" + - std::to_string(info.num_iterations) + - "][pattern=random][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateRandom", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=random][file=1]") { - pretest(); - SECTION("update into existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size - 1); - test::test_seek(offset, SEEK_SET); // 630978 - REQUIRE(((size_t)test::status_orig) == offset); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - fsync(test::fh_orig); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = (i * info.stride_size) % info.total_size; - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = (i * info.stride_size) % info.total_size; - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideDynamic", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideDynamic", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedWriteRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - - SECTION("write to new file always at the start") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - size_t biggest_size_written = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.offset_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - if (biggest_size_written < request_size) - biggest_size_written = request_size; - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == biggest_size_written); - } - - SECTION("write to new file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - size_t total_size_written = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = - args.request_size + (rand_r(&info.offset_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - total_size_written += test::size_written_orig; - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == total_size_written); - } - posttest(); -} - -TEST_CASE("BatchedReadSequentialRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - size_t current_offset = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = (args.request_size + - (rand_r(&info.offset_seed) % args.request_size)) % - (info.total_size - current_offset); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - current_offset += test::size_read_orig; - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_open(info.existing_file.c_str(), O_RDONLY); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.offset_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadRandomRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable]" - "[repetition=" + - std::to_string(info.num_iterations) + - "][pattern=random][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateRandomRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=random][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideFixedRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = (i * info.stride_size) % info.total_size; - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideFixedRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = (i * info.stride_size) % info.total_size; - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideDynamicRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideDynamicRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideNegative", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - size_t prev_offset = info.total_size + 1; - for (size_t i = 0; i < info.num_iterations; ++i) { - auto stride_offset = info.total_size - i * info.stride_size; - REQUIRE(prev_offset > stride_offset); - prev_offset = stride_offset; - size_t offset = (stride_offset) % (info.total_size - args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideNegative", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = - info.total_size - ((i * info.stride_size) % info.total_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_write(data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideNegativeRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = (info.total_size - i * info.stride_size) % - (info.total_size - 2 * args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideNegativeRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - - SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t offset = - info.total_size - ((i * info.stride_size) % info.total_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStride2D", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStride2D", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - test::test_write(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStride2DRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - 2 * args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_read(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStride2DRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - 2 * args.request_size); - test::test_seek(offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == offset); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_write(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -/** - * Temporal Fixed - */ - -TEST_CASE("BatchedWriteTemporalFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=fixed]") { - pretest(); - - SECTION("write to existing file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == args.request_size); - } - - SECTION("write to new file always at start") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedReadSequentialTemporalFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=fixed]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_open(info.existing_file.c_str(), O_WRONLY); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedWriteTemporalVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=variable]") { - pretest(); - - SECTION("write to existing file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == args.request_size); - } - - SECTION("write to new file always at start") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedReadSequentialTemporalVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=variable]") { - pretest(); - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_read(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_open(info.existing_file.c_str(), O_WRONLY); - REQUIRE(test::fh_orig != -1); - - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedMixedSequential", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_mixed]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - SECTION("read after write on new file") { - test::test_open(info.new_file.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - size_t last_offset = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_seek(last_offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == last_offset); - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - last_offset += args.request_size; - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - SECTION("write and read alternative existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - if (i % 2 == 0) { - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } else { - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("update after read existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - size_t last_offset = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_seek(last_offset, SEEK_SET); - REQUIRE(((size_t)test::status_orig) == last_offset); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - last_offset += args.request_size; - } - - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("read all after write all on new file in single open") { - test::test_open(info.new_file.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("read all after write all on new file in different open") { - test::test_open(info.new_file.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.new_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("SingleMixed", "[process=" + std::to_string(info.comm_size) + - "][operation=single_mixed]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read after write from new file") { - test::test_open(info.new_file.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("update after read from existing file") { - test::test_open(info.existing_file.c_str(), O_RDWR); - REQUIRE(test::fh_orig != -1); - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_seek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - - test::test_close(); - REQUIRE(test::status_orig == 0); - } - SECTION("read after write from new file different opens") { - test::test_open(info.new_file.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - test::test_open(info.new_file.c_str(), O_RDWR); - test::test_read(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("fstat") { - pretest(); - - SECTION("fstat on new file") { - test::test_open(info.new_file.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(test::fh_orig != -1); - test::test_write(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - - struct stat buf = {}; - int result = fstat(test::fh_orig, &buf); - REQUIRE(result == 0); - REQUIRE(buf.st_size == (off_t)test::size_written_orig); - - test::test_close(); - REQUIRE(test::status_orig == 0); - } - - posttest(); -} diff --git a/adapter/test/posix/posix_adapter_mpi_test.cpp b/adapter/test/posix/posix_adapter_mpi_test.cpp deleted file mode 100644 index f0f3a77db..000000000 --- a/adapter/test/posix/posix_adapter_mpi_test.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include - -#include -#include - -#include "adapter_test_utils.h" -#include "catch_config.h" - -#if HERMES_INTERCEPT == 1 -#include "adapter/posix/posix_api.h" -#include "adapter/posix/posix_fs_api.h" -#endif - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::fs::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - bool debug = false; - bool supports_tmpfile; - int rank = 0; - int comm_size = 1; - std::vector write_data; - std::vector read_data; - std::string new_file; - std::string existing_file; - std::string shared_new_file; - std::string existing_shared_file; - std::string new_file_cmp; - std::string existing_file_cmp; - std::string existing_shared_file_cmp; - std::string shared_new_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 1; - size_t total_size; - size_t stride_size = 4 * 1024; - unsigned int temporal_interval_ms = 5; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 512 * 1024; - size_t large_min = 512 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::fs::test - -hermes::adapter::fs::test::Arguments args; -hermes::adapter::fs::test::Info info; -std::vector gen_random(const int len) { - std::vector tmp_s(len); - static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - - srand((unsigned)time(NULL) * getpid()); - - tmp_s.reserve(len); - - for (int i = 0; i < len; ++i) - tmp_s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; - - return tmp_s; -} - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - info.write_data = gen_random(args.request_size); - info.read_data = std::vector(args.request_size, 'r'); - info.supports_tmpfile = FilesystemSupportsTmpfile(); - MPI_Comm_rank(MPI_COMM_WORLD, &info.rank); - MPI_Comm_size(MPI_COMM_WORLD, &info.comm_size); - if (info.debug && info.rank == 0) { - printf("%d ready for attach\n", info.comm_size); - fflush(stdout); - sleep(30); - } - MPI_Barrier(MPI_COMM_WORLD); - return 0; -} - -int finalize() { - MPI_Finalize(); - return 0; -} - -int pretest() { - REQUIRE(info.comm_size > 1); - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - info.new_file = fullpath.string() + "_new_" + std::to_string(info.rank) + - "_of_" + std::to_string(info.comm_size) + "_" + - std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext_" + std::to_string(info.rank) + - "_of_" + std::to_string(info.comm_size) + "_" + - std::to_string(getpid()); - info.new_file_cmp = - fullpath.string() + "_new_cmp_" + std::to_string(info.rank) + "_of_" + - std::to_string(info.comm_size) + "_" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp_" + std::to_string(info.rank) + "_of_" + - std::to_string(info.comm_size) + "_" + std::to_string(getpid()); - info.existing_shared_file = - fullpath.string() + "_shared_ext_" + std::to_string(info.comm_size); - info.existing_shared_file_cmp = - fullpath.string() + "_shared_ext_cmp_" + std::to_string(info.comm_size); - info.shared_new_file = - fullpath.string() + "_shared_new_" + std::to_string(info.comm_size); - info.shared_new_file_cmp = - fullpath.string() + "_shared_new_cmp_" + std::to_string(info.comm_size); - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - if (stdfs::exists(info.existing_shared_file)) - stdfs::remove(info.existing_shared_file); - if (stdfs::exists(info.existing_shared_file_cmp)) - stdfs::remove(info.existing_shared_file_cmp); - if (stdfs::exists(info.shared_new_file)) stdfs::remove(info.shared_new_file); - if (stdfs::exists(info.shared_new_file_cmp)) - stdfs::remove(info.shared_new_file_cmp); - stdfs::path temp_fullpath = "/tmp"; - temp_fullpath /= args.filename; - std::string temp_ext_file = - temp_fullpath.string() + "_temp_" + std::to_string(info.rank) + "_of_" + - std::to_string(info.comm_size) + "_" + std::to_string(getpid()); - if (stdfs::exists(temp_ext_file)) stdfs::remove(temp_ext_file); - if (!stdfs::exists(temp_ext_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + temp_ext_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(temp_ext_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(temp_ext_file); - } - if (info.rank == 0 && !stdfs::exists(info.existing_shared_file)) { - std::string cmd = "cp " + temp_ext_file + " " + info.existing_shared_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_shared_file) == - args.request_size * info.num_iterations); - } - if (info.rank == 0 && !stdfs::exists(info.existing_shared_file_cmp)) { - std::string cmd = - "cp " + temp_ext_file + " " + info.existing_shared_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_shared_file_cmp) == - args.request_size * info.num_iterations); - } - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "cp " + temp_ext_file + " " + info.existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - } - if (!stdfs::exists(info.existing_file_cmp)) { - std::string cmd = "cp " + info.existing_file + " " + info.existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - } - if (stdfs::exists(temp_ext_file)) stdfs::remove(temp_ext_file); - REQUIRE(info.total_size > 0); - MPI_Barrier(MPI_COMM_WORLD); -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file_cmp, - false); -#endif - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest(bool compare_data = true) { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file, - false); -#endif - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_shared_file) && - stdfs::exists(info.existing_shared_file_cmp)) { - size_t size = stdfs::file_size(info.existing_shared_file); - if (size != stdfs::file_size(info.existing_shared_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_shared_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_shared_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_shared_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - MPI_Barrier(MPI_COMM_WORLD); - if (info.rank == 0) { - if (stdfs::exists(info.existing_shared_file)) - stdfs::remove(info.existing_shared_file); - if (stdfs::exists(info.existing_shared_file_cmp)) - stdfs::remove(info.existing_shared_file_cmp); - } - Clear(); - -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, true); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, true); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file, - true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file_cmp, - true); -#endif - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -int fh_orig; -int fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -bool is_scase_ = false; -void test_open(const char* path, int flags, ...) { - int mode = 0; - if (flags & O_CREAT || flags & O_TMPFILE) { - va_list arg; - va_start(arg, flags); - mode = va_arg(arg, int); - va_end(arg); - } - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else if (strcmp(path, info.shared_new_file.c_str()) == 0) { - cmp_path = info.shared_new_file_cmp; - } else if (strcmp(path, "/tmp") == 0) { - cmp_path = "/tmp"; - } else { - cmp_path = info.existing_file_cmp; - } - if (flags & O_CREAT || flags & O_TMPFILE) { - fh_orig = open(path, flags, mode); - fh_cmp = open(cmp_path.c_str(), flags, mode); - } else { - fh_orig = open(path, flags); - fh_cmp = open(cmp_path.c_str(), flags); - } - bool is_same = - (fh_cmp != -1 && fh_orig != -1) || (fh_cmp == -1 && fh_orig == -1); - REQUIRE(is_same); -} -void test_close() { - status_orig = close(fh_orig); - int status = close(fh_cmp); - REQUIRE(status == status_orig); -} -void test_write(const void* ptr, size_t size) { - size_written_orig = write(fh_orig, ptr, size); - size_t size_written = write(fh_cmp, ptr, size); - REQUIRE(size_written == size_written_orig); -} -void test_read(char* ptr, size_t size) { - size_read_orig = read(fh_orig, ptr, size); - std::vector read_data(size, 'r'); - size_t size_read = read(fh_cmp, read_data.data(), size); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} -void test_seek(long offset, int whence) { - status_orig = lseek(fh_orig, offset, whence); - int status = lseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -#include "posix_adapter_basic_test.cpp" -#include "posix_adapter_rs_test.cpp" -// TODO(chogan): Disabling until issue #302 is fixed -// #include "posix_adapter_shared_test.cpp" diff --git a/adapter/test/posix/posix_adapter_test.cpp b/adapter/test/posix/posix_adapter_test.cpp deleted file mode 100644 index b8be03d64..000000000 --- a/adapter/test/posix/posix_adapter_test.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include -#include - -#include -#include - -#include "adapter/posix/posix_api.h" -#include "catch_config.h" -#include "hermes.h" - -#if HERMES_INTERCEPT == 1 -#include "adapter/posix/posix_fs_api.h" -#endif - -#include "adapter_test_utils.h" - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::fs::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - int rank = 0; - int comm_size = 1; - bool supports_tmpfile; - std::vector write_data; - std::vector read_data; - std::string new_file; // Tracked by Hermes - std::string existing_file; // Tracked by Hermes - std::string new_file_cmp; // NOT tracked by Hermes - std::string existing_file_cmp; // NOT tracekd by Hermes - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; // The size of the EXISTING file - size_t stride_size = 1024; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::fs::test -hermes::adapter::fs::test::Arguments args; -hermes::adapter::fs::test::Info info; -std::vector gen_random(const int len) { - auto tmp_s = std::vector(len); - static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - - srand(100); - for (int i = 0; i < len; ++i) - tmp_s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; - return tmp_s; -} - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - info.write_data = gen_random(args.request_size); - info.read_data = std::vector(args.request_size, 'r'); - info.supports_tmpfile = FilesystemSupportsTmpfile(); - return 0; -} - -int finalize() { - MPI_Finalize(); - return 0; -} - -void IgnoreAllFiles() { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); -#endif -} - -void TrackFiles() { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.new_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, true); -#endif -} - -void RemoveFile(const std::string& path) { - stdfs::remove(path); - if (stdfs::exists(path)) { - HELOG(kFatal, "Failed to remove: {}", path) - } -} - -void RemoveFiles() { - RemoveFile(info.new_file); - RemoveFile(info.new_file_cmp); - RemoveFile(info.existing_file); - RemoveFile(info.existing_file_cmp); -} - -int pretest() { - // Initialize path names - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - info.new_file = fullpath.string() + "_new_" + std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext_" + std::to_string(getpid()); - info.new_file_cmp = - fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - - // Ignore all files - IgnoreAllFiles(); - - // Remove existing files from the FS - RemoveFiles(); - - // Create the file which is untracked by Hermes - if (true) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + info.existing_file_cmp + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file_cmp); - } - - // Create the file that is being tracks by Hermes - if (true) { - std::string cmd = "cp " + info.existing_file_cmp + " " + info.existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - auto check = stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations; - if (!check) { - HELOG(kFatal, "File sizes weren't equivalent after copy") - } - REQUIRE(check); - } - REQUIRE(info.total_size > 0); - - // Begin tracking the Hermes files - TrackFiles(); - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest(bool compare_data = true) { - IgnoreAllFiles(); - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - // Verify the NEW file is the same in Hermes + the backend - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, 'r'); - std::vector d2(size, 'w'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), sizeof(unsigned char), size, fh1); - REQUIRE(read_d1 == size); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), sizeof(unsigned char), size, fh2); - REQUIRE(read_d2 == size); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) { - char_mismatch = pos; - break; - } - } - if (char_mismatch != 0) { - std::cout << "The files " << info.existing_file << " and " - << info.existing_file_cmp << " had mismatched characters" - << std::endl; - } - REQUIRE(char_mismatch == 0); - } - } - /* Delete the files from both Hermes and the backend. */ - TrackFiles(); - RemoveFiles(); - Clear(); - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -int fh_orig; -int fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -bool is_scase_ = false; -void test_open(const char* path, int flags, ...) { - int mode = 0; - if (flags & O_CREAT || flags & O_TMPFILE) { - va_list arg; - va_start(arg, flags); - mode = va_arg(arg, int); - va_end(arg); - } - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else if (strcmp(path, "/tmp") == 0) { - cmp_path = "/tmp"; - } else { - cmp_path = info.existing_file_cmp; - } - if (flags & O_CREAT || flags & O_TMPFILE) { - fh_orig = open(path, flags, mode); - fh_cmp = open(cmp_path.c_str(), flags, mode); - } else { - fh_orig = open(path, flags); - fh_cmp = open(cmp_path.c_str(), flags); - } - bool is_same = - (fh_cmp != -1 && fh_orig != -1) || (fh_cmp == -1 && fh_orig == -1); - REQUIRE(is_same); -} -void test_close() { - status_orig = close(fh_orig); - int status = close(fh_cmp); - REQUIRE(status == status_orig); -} -void test_write(const void* ptr, size_t size) { - size_written_orig = write(fh_orig, ptr, size); - size_t size_written = write(fh_cmp, ptr, size); - REQUIRE(size_written == size_written_orig); -} -void test_read(char* ptr, size_t size) { - size_read_orig = read(fh_orig, ptr, size); - std::vector read_data(size, 'r'); - size_t size_read = read(fh_cmp, read_data.data(), size); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - if (unmatching_chars != 0) { - std::cerr << "There were unmatching chars" << std::endl; - } - REQUIRE(unmatching_chars == 0); - } -} -void test_seek(long offset, int whence) { - status_orig = lseek(fh_orig, offset, whence); - int status = lseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -#include "posix_adapter_basic_test.cpp" -#include "posix_adapter_rs_test.cpp" diff --git a/adapter/test/stdio/stdio_adapter_basic_test.cpp b/adapter/test/stdio/stdio_adapter_basic_test.cpp deleted file mode 100644 index 6bdb20836..000000000 --- a/adapter/test/stdio/stdio_adapter_basic_test.cpp +++ /dev/null @@ -1,1308 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -TEST_CASE("Open", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_open]" - "[repetition=1][file=1]") { - pretest(); - SECTION("open non-existant file") { - test::test_fopen(info.new_file.c_str(), "r"); - REQUIRE(test::fh_orig == nullptr); - test::test_fopen(info.new_file.c_str(), "r+"); - REQUIRE(test::fh_orig == nullptr); - } - - SECTION("truncate existing file and write-only") { - test::test_fopen(info.existing_file.c_str(), "w"); - REQUIRE(test::fh_orig != nullptr); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("truncate existing file and read/write") { - test::test_fopen(info.existing_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("open existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - test::test_fopen(info.existing_file.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("append write existing file") { - test::test_fopen(info.existing_file.c_str(), "a"); - REQUIRE(test::fh_orig != nullptr); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("append write and read existing file") { - test::test_fopen(info.existing_file.c_str(), "a+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("SingleWrite", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("write to existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("write to new file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == test::size_written_orig); - } - - SECTION("write to existing file with truncate") { - test::test_fopen(info.existing_file.c_str(), "w"); - REQUIRE(test::fh_orig != nullptr); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.existing_file) == test::size_written_orig); - } - - SECTION("write to existing file at the end") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fseek(0, SEEK_END); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == args.request_size * info.num_iterations); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.existing_file) == - test::size_written_orig + offset); - } - - SECTION("append to existing file") { - auto existing_size = stdfs::file_size(info.existing_file); - test::test_fopen(info.existing_file.c_str(), "a+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.existing_file) == - existing_size + test::size_written_orig); - } - - SECTION("append to new file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == test::size_written_orig); - } - posttest(); -} - -TEST_CASE("SingleRead", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read from non-existing file") { - test::test_fopen(info.new_file.c_str(), "r"); - REQUIRE(test::fh_orig == nullptr); - } - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("read at the end of existing file") { - test::test_fopen(info.existing_file.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - test::test_fseek(0, SEEK_END); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == args.request_size * info.num_iterations); - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == 0); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedWriteSequential", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - SECTION("write to new file always at beginning") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == args.request_size); - } - - SECTION("write to new file sequentially") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedReadSequential", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_fopen(info.existing_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadRandom", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed]" - "[repetition=" + - std::to_string(info.num_iterations) + - "][pattern=random][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateRandom", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=random][file=1]") { - pretest(); - SECTION("update into existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - fflush(test::fh_orig); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = (i * info.stride_size) % info.total_size; - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("update from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = (i * info.stride_size) % info.total_size; - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideDynamic", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideDynamic", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - SECTION("update from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedWriteRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - - SECTION("write to new file always at the start") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - size_t biggest_written = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - size_t request_size = - args.request_size + (rand_r(&info.offset_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - if (biggest_written < request_size) biggest_written = request_size; - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == biggest_written); - } - - SECTION("write to new file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - size_t total_test_written = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = - args.request_size + (rand_r(&info.offset_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - total_test_written += test::size_written_orig; - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == total_test_written); - } - posttest(); -} - -TEST_CASE("BatchedReadSequentialRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - size_t current_offset = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = (args.request_size + - (rand_r(&info.offset_seed) % args.request_size)) % - (info.total_size - current_offset); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - current_offset += test::size_read_orig; - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_fopen(info.existing_file.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - size_t request_size = - args.request_size + (rand_r(&info.offset_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadRandomRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable]" - "[repetition=" + - std::to_string(info.num_iterations) + - "][pattern=random][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateRandomRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=random][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = - rand_r(&info.offset_seed) % (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideFixedRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = (i * info.stride_size) % info.total_size; - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideFixedRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_fixed][file=1]") { - pretest(); - - SECTION("write to existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = (i * info.stride_size) % info.total_size; - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideDynamicRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideDynamicRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_dynamic][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = GetRandomOffset(i, info.offset_seed, info.stride_size, - info.total_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideNegative", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - size_t prev_offset = info.total_size + 1; - for (size_t i = 0; i < info.num_iterations; ++i) { - auto stride_offset = info.total_size - i * info.stride_size; - REQUIRE(prev_offset > stride_offset); - prev_offset = stride_offset; - auto offset = (stride_offset) % (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideNegative", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = info.total_size - args.request_size - - ((i * info.stride_size) % info.total_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStrideNegativeRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = (info.total_size - i * info.stride_size) % - (info.total_size - 2 * args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStrideNegativeRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_negative][file=1]") { - pretest(); - - SECTION("write to existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - auto offset = - info.total_size - ((i * info.stride_size) % info.total_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStride2D", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStride2D", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedReadStride2DRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "" - "[operation=batched_read]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - 2 * args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - (args.request_size + (rand_r(&info.rs_seed) % args.request_size)) % - (info.total_size - offset); - std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedUpdateStride2DRSVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_update]" - "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=stride_2d][file=1]") { - pretest(); - size_t rows = sqrt(info.total_size); - size_t cols = rows; - REQUIRE(rows * cols == info.total_size); - size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / info.num_iterations; - SECTION("write to existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t current_cell_col = (prev_cell_col + cell_stride) % cols; - size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; - prev_cell_row = current_cell_row; - auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (info.total_size - 2 * args.request_size); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t request_size = - args.request_size + (rand_r(&info.rs_seed) % args.request_size); - std::string data(request_size, '1'); - test::test_fwrite(data.c_str(), request_size); - REQUIRE(test::size_written_orig == request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -/** - * Temporal Fixed - */ - -TEST_CASE("BatchedWriteTemporalFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=fixed]") { - pretest(); - - SECTION("write to existing file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == args.request_size); - } - - SECTION("write to new file always at start") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedReadSequentialTemporalFixed", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=fixed]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_fopen(info.existing_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedWriteTemporalVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=variable]") { - pretest(); - - SECTION("write to existing file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == args.request_size); - } - - SECTION("write to new file always at start") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedReadSequentialTemporalVariable", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1][temporal=variable]") { - pretest(); - - SECTION("read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(args.request_size, '1'); - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_fread(data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("read from existing file always at start") { - test::test_fopen(info.existing_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - info.temporal_interval_ms = - rand_r(&info.temporal_interval_seed) % info.temporal_interval_ms + 1; - usleep(info.temporal_interval_ms * 1000); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("BatchedMixedSequential", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_mixed]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - pretest(); - SECTION("read after write on new file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - size_t last_offset = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fseek(last_offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - last_offset += args.request_size; - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - - SECTION("write and read alternative existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - if (i % 2 == 0) { - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } else { - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("update after read existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - size_t last_offset = 0; - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_fseek(last_offset, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - last_offset += args.request_size; - } - - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("read all after write all on new file in single open") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("read all after write all on new file in different open") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - test::test_fopen(info.new_file.c_str(), "r"); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} - -TEST_CASE("SingleMixed", "[process=" + std::to_string(info.comm_size) + - "][operation=single_mixed]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read after write from new file") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("update after read from existing file") { - test::test_fopen(info.existing_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - SECTION("read after write from new file different opens") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - size_t offset = ftell(test::fh_orig); - REQUIRE(offset == 0); - test::test_fwrite(info.write_data.data(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - test::test_fopen(info.new_file.c_str(), "r+"); - test::test_fread(info.read_data.data(), args.request_size); - REQUIRE(test::size_read_orig == args.request_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - } - posttest(); -} diff --git a/adapter/test/stdio/stdio_adapter_mapper_test.cpp b/adapter/test/stdio/stdio_adapter_mapper_test.cpp deleted file mode 100644 index ab4885e1f..000000000 --- a/adapter/test/stdio/stdio_adapter_mapper_test.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include - -#include "adapter/stdio/stdio_fs_api.h" -#include "adapter_constants.h" -#include "catch_config.h" -#include "mapper/mapper_factory.h" -#include "src/hermes_types.h" - -using hermes::adapter::BlobPlacements; -using hermes::adapter::kMapperType; -using hermes::adapter::MapperFactory; -using hermes::adapter::MapperType; -using hermes::adapter::fs::MetadataManager; - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; - size_t num_iterations = 1024; -}; -struct Info { - int rank = 0; - int comm_size = 1; - std::string new_file; - std::string existing_file; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - size_t total_size; - size_t stride_size = 1024; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 4 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - - return 0; -} -int finalize() { - MPI_Finalize(); - - return 0; -} - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - info.new_file = fullpath.string() + "_new"; - info.existing_file = fullpath.string() + "_ext"; - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "dd if=/dev/zero of=" + info.existing_file + - " bs=1 count=0 seek=" + - std::to_string(args.request_size * args.num_iterations) + - " > /dev/null 2>&1"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * args.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - } - REQUIRE(info.total_size > 0); - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest() { - Clear(); - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O") | - cl::Opt(args.num_iterations, "iterations")["-n"]["--iterations"]( - "Number of iterations of requests"); -} - -TEST_CASE("SingleWrite", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[request_size=type-fixed][repetition=1]" - "[pattern=sequential][file=1]") { - pretest(); - const size_t kPageSize = MEGABYTES(1); - SECTION("Map a one request") { - auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = args.request_size; - FILE* fp = fopen(info.new_file.c_str(), "w+"); - REQUIRE(fp != nullptr); - size_t offset = 0; - REQUIRE(kPageSize > total_size + offset); - BlobPlacements mapping; - mapper->map(offset, total_size, kPageSize, mapping); - REQUIRE(mapping.size() == 1); - REQUIRE(mapping[0].bucket_off_ == offset); - REQUIRE(mapping[0].blob_size_ == total_size); - REQUIRE(mapping[0].blob_off_ == offset); - int status = fclose(fp); - REQUIRE(status == 0); - } - SECTION("Map a one big request") { - auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = args.request_size * args.num_iterations; - FILE* fp = fopen(info.new_file.c_str(), "w+"); - REQUIRE(fp != nullptr); - size_t offset = 0; - BlobPlacements mapping; - mapper->map(offset, total_size, kPageSize, mapping); - REQUIRE(mapping.size() == ceil((double)total_size / kPageSize)); - for (const auto& item : mapping) { - size_t mapped_size = - total_size - offset > kPageSize ? kPageSize : total_size - offset; - REQUIRE(item.bucket_off_ == offset); - REQUIRE(item.blob_size_ == mapped_size); - REQUIRE(item.blob_off_ == offset % kPageSize); - offset += mapped_size; - } - int status = fclose(fp); - REQUIRE(status == 0); - } - SECTION("Map a one large unaligned request") { - auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = args.request_size * args.num_iterations; - FILE* fp = fopen(info.new_file.c_str(), "w+"); - REQUIRE(fp != nullptr); - size_t offset = 1; - BlobPlacements mapping; - mapper->map(offset, total_size, kPageSize, mapping); - bool has_rem = (total_size + offset) % kPageSize != 0; - if (has_rem) { - REQUIRE(mapping.size() == ceil((double)total_size / kPageSize) + 1); - } else { - REQUIRE(mapping.size() == ceil((double)total_size / kPageSize)); - } - - size_t i = 0; - size_t current_offset = offset; - for (const auto& item : mapping) { - size_t mapped_size = 0; - if (i == 0) { - mapped_size = kPageSize - offset; - } else if (i == mapping.size() - 1) { - mapped_size = offset; - } else { - mapped_size = kPageSize; - } - REQUIRE(item.bucket_off_ == current_offset); - REQUIRE(item.blob_size_ == mapped_size); - REQUIRE(item.blob_off_ == current_offset % kPageSize); - current_offset += mapped_size; - i++; - } - int status = fclose(fp); - REQUIRE(status == 0); - } - SECTION("Map a one small unaligned request") { - auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = args.request_size; - FILE* fp = fopen(info.new_file.c_str(), "w+"); - REQUIRE(fp != nullptr); - size_t offset = 1; - REQUIRE(kPageSize > total_size + offset); - BlobPlacements mapping; - mapper->map(offset, total_size, kPageSize, mapping); - REQUIRE(mapping.size() == 1); - REQUIRE(mapping[0].bucket_off_ == offset); - REQUIRE(mapping[0].blob_size_ == total_size); - REQUIRE(mapping[0].blob_off_ == 1); - int status = fclose(fp); - REQUIRE(status == 0); - } - posttest(); -} diff --git a/adapter/test/stdio/stdio_adapter_mode_test.cpp b/adapter/test/stdio/stdio_adapter_mode_test.cpp deleted file mode 100644 index 67c784a2b..000000000 --- a/adapter/test/stdio/stdio_adapter_mode_test.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include -#include - -#include -#include - -#if HERMES_INTERCEPT == 1 -#include "adapter/stdio/stdio_api.h" -#endif - -#include "adapter_test_utils.h" -#include "adapter_types.h" -#include "hermes.h" - -namespace stdfs = std::filesystem; -using hermes::adapter::AdapterMode; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string new_file_cmp; - std::string existing_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; - size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - info.new_file = fullpath.string() + "_new" + std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext" + std::to_string(getpid()); - info.new_file_cmp = fullpath.string() + "_new_cmp" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp" + std::to_string(getpid()); - char* set_path = getenv("SET_PATH"); - if (set_path && strcmp(set_path, "1") == 0) { - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); - } - MPI_Init(argc, argv); - info.write_data = GenRandom(args.request_size); - info.read_data = std::string(args.request_size, 'r'); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -void IgnoreAllFiles() { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); -#endif -} - -void TrackFiles() { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.new_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, true); -#endif -} - -void RemoveFile(const std::string& path) { - stdfs::remove(path); - if (stdfs::exists(path)) { - HELOG(kFatal, "Failed to remove: {}", path) - } -} - -void RemoveFiles() { - RemoveFile(info.new_file); - RemoveFile(info.new_file_cmp); - RemoveFile(info.existing_file); - RemoveFile(info.existing_file_cmp); -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int pretest() { - IgnoreAllFiles(); - RemoveFiles(); - - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + info.existing_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - } - if (!stdfs::exists(info.existing_file_cmp)) { - std::string cmd = "cp " + info.existing_file + " " + info.existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - } - REQUIRE(info.total_size > 0); - - TrackFiles(); - return 0; -} - -int posttest(bool compare_data = true) { - IgnoreAllFiles(); - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - TrackFiles(); - RemoveFiles(); - Clear(); - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -FILE* fh_orig; -FILE* fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -void test_fopen(const char* path, const char* mode) { - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else { - cmp_path = info.existing_file_cmp; - } - fh_orig = fopen(path, mode); - fh_cmp = fopen(cmp_path.c_str(), mode); - bool is_same = (fh_cmp != nullptr && fh_orig != nullptr) || - (fh_cmp == nullptr && fh_orig == nullptr); - REQUIRE(is_same); -} -void test_fclose() { - status_orig = fclose(fh_orig); - int status = fclose(fh_cmp); - REQUIRE(status == status_orig); -} -void test_fwrite(const void* ptr, size_t size) { - size_written_orig = fwrite(ptr, sizeof(char), size, fh_orig); - size_t size_written = fwrite(ptr, sizeof(char), size, fh_cmp); - REQUIRE(size_written == size_written_orig); -} -void test_fread(char* ptr, size_t size) { - size_read_orig = fread(ptr, sizeof(char), size, fh_orig); - std::vector read_data(size, 'r'); - size_t size_read = fread(read_data.data(), sizeof(char), size, fh_cmp); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} -void test_fseek(long offset, int whence) { - status_orig = fseek(fh_orig, offset, whence); - int status = fseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -TEST_CASE("BatchedWriteSequentialPersistent", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[hermes_mode=persistent]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - HERMES->client_config_.SetBaseAdapterMode(AdapterMode::kDefault); - REQUIRE(HERMES->client_config_.GetBaseAdapterMode() == AdapterMode::kDefault); - pretest(); - SECTION("write to new file always at end") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedWriteSequentialBypass", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[hermes_mode=bypass]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - HERMES->client_config_.SetBaseAdapterMode(AdapterMode::kBypass); - REQUIRE(HERMES->client_config_.GetBaseAdapterMode() == AdapterMode::kBypass); - pretest(); - SECTION("write to new file always at end") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(info.new_file) == - info.num_iterations * args.request_size); - } - posttest(); -} - -TEST_CASE("BatchedWriteSequentialScratch", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[hermes_mode=scratch]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=sequential][file=1]") { - HERMES->client_config_.SetBaseAdapterMode(AdapterMode::kScratch); - REQUIRE(HERMES->client_config_.GetBaseAdapterMode() == AdapterMode::kScratch); - pretest(); - SECTION("write to new file always at end") { - test::test_fopen(info.new_file.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - - for (size_t i = 0; i < info.num_iterations; ++i) { - test::test_fwrite(info.write_data.c_str(), args.request_size); - REQUIRE(test::size_written_orig == args.request_size); - } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - IgnoreAllFiles(); - REQUIRE(stdfs::exists(info.new_file) == 0); - TrackFiles(); - } - posttest(false); -} diff --git a/adapter/test/stdio/stdio_adapter_mpi_test.cpp b/adapter/test/stdio/stdio_adapter_mpi_test.cpp deleted file mode 100644 index 1280980dc..000000000 --- a/adapter/test/stdio/stdio_adapter_mpi_test.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include -#include -#include - -#include -#include -#if HERMES_INTERCEPT == 1 -#include "adapter/stdio/stdio_api.h" -#include "adapter/stdio/stdio_fs_api.h" -#endif - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - bool debug = false; - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string existing_shared_file; - std::string new_file_cmp; - std::string existing_file_cmp; - std::string existing_shared_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 1; - size_t total_size; - size_t stride_size = 4 * 1024; - unsigned int temporal_interval_ms = 5; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 512 * 1024; - size_t large_min = 512 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test - -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - info.write_data = GenRandom(args.request_size); - info.read_data = std::string(args.request_size, 'r'); - MPI_Comm_rank(MPI_COMM_WORLD, &info.rank); - MPI_Comm_size(MPI_COMM_WORLD, &info.comm_size); - if (info.debug && info.rank == 0) { - printf("%d ready for attach\n", info.comm_size); - fflush(stdout); - sleep(30); - } - MPI_Barrier(MPI_COMM_WORLD); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -namespace test { -FILE* fh_orig; -FILE* fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -void test_fopen(const char* path, const char* mode) { - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else if (strcmp(path, info.existing_file.c_str()) == 0) { - cmp_path = info.existing_file_cmp; - } else { - cmp_path = info.existing_shared_file_cmp; - } - fh_orig = fopen(path, mode); - fh_cmp = fopen(cmp_path.c_str(), mode); - bool is_same = (fh_cmp != nullptr && fh_orig != nullptr) || - (fh_cmp == nullptr && fh_orig == nullptr); - REQUIRE(is_same); -} -void test_fclose() { - status_orig = fclose(fh_orig); - int status = fclose(fh_cmp); - REQUIRE(status == status_orig); -} -void test_fwrite(const void* ptr, size_t size) { - size_written_orig = fwrite(ptr, sizeof(char), size, fh_orig); - size_t size_written = fwrite(ptr, sizeof(char), size, fh_cmp); - REQUIRE(size_written == size_written_orig); -} -void test_fread(char* ptr, size_t size) { - size_read_orig = fread(ptr, sizeof(char), size, fh_orig); - std::vector read_data(size, 'r'); - size_t size_read = fread(read_data.data(), sizeof(char), size, fh_cmp); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) unmatching_chars++; - } - REQUIRE(unmatching_chars == 0); - } -} -void test_fseek(long offset, int whence) { - status_orig = fseek(fh_orig, offset, whence); - int status = fseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - info.new_file = fullpath.string() + "_new_" + std::to_string(info.rank) + - "_of_" + std::to_string(info.comm_size) + "_" + - std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext_" + std::to_string(info.rank) + - "_of_" + std::to_string(info.comm_size) + "_" + - std::to_string(getpid()); - info.new_file_cmp = - fullpath.string() + "_new_cmp_" + std::to_string(info.rank) + "_of_" + - std::to_string(info.comm_size) + "_" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp_" + std::to_string(info.rank) + "_of_" + - std::to_string(info.comm_size) + "_" + std::to_string(getpid()); - info.existing_shared_file = - fullpath.string() + "_ext_" + std::to_string(info.comm_size); - info.existing_shared_file_cmp = - fullpath.string() + "_ext_cmp_" + std::to_string(info.comm_size); - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - if (stdfs::exists(info.existing_shared_file)) - stdfs::remove(info.existing_shared_file); - if (stdfs::exists(info.existing_shared_file_cmp)) - stdfs::remove(info.existing_shared_file_cmp); - stdfs::path temp_fullpath = "/tmp"; - temp_fullpath /= args.filename; - std::string temp_ext_file = - temp_fullpath.string() + "_temp_" + std::to_string(info.rank) + "_of_" + - std::to_string(info.comm_size) + "_" + std::to_string(getpid()); - if (stdfs::exists(temp_ext_file)) stdfs::remove(temp_ext_file); - if (!stdfs::exists(temp_ext_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + temp_ext_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(temp_ext_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(temp_ext_file); - } - if (info.rank == 0 && !stdfs::exists(info.existing_shared_file)) { - std::string cmd = "cp " + temp_ext_file + " " + info.existing_shared_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_shared_file) == - args.request_size * info.num_iterations); - } - if (info.rank == 0 && !stdfs::exists(info.existing_shared_file_cmp)) { - std::string cmd = - "cp " + temp_ext_file + " " + info.existing_shared_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_shared_file_cmp) == - args.request_size * info.num_iterations); - } - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "cp " + temp_ext_file + " " + info.existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - } - if (!stdfs::exists(info.existing_file_cmp)) { - std::string cmd = "cp " + info.existing_file + " " + info.existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - } - if (stdfs::exists(temp_ext_file)) stdfs::remove(temp_ext_file); - REQUIRE(info.total_size > 0); - MPI_Barrier(MPI_COMM_WORLD); -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file_cmp, - false); -#endif - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest(bool compare_data = true) { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file, - false); -#endif - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_shared_file) && - stdfs::exists(info.existing_shared_file_cmp)) { - size_t size = stdfs::file_size(info.existing_shared_file); - if (size != stdfs::file_size(info.existing_shared_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_shared_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_shared_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_shared_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - MPI_Barrier(MPI_COMM_WORLD); - if (info.rank == 0) { - if (stdfs::exists(info.existing_shared_file)) - stdfs::remove(info.existing_shared_file); - if (stdfs::exists(info.existing_shared_file_cmp)) - stdfs::remove(info.existing_shared_file_cmp); - } - Clear(); - -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, true); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, true); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file, - true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_shared_file_cmp, - true); -#endif - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -#include "stdio_adapter_basic_test.cpp" -#include "stdio_adapter_func_test.cpp" -#include "stdio_adapter_rs_test.cpp" -// #include "stdio_adapter_shared_test.cpp" diff --git a/adapter/test/stdio/stdio_adapter_test.cpp b/adapter/test/stdio/stdio_adapter_test.cpp deleted file mode 100644 index cf7b722b8..000000000 --- a/adapter/test/stdio/stdio_adapter_test.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include - -#include -#include - -#include "adapter/stdio/stdio_api.h" -#include "adapter_test_utils.h" -#include "catch_config.h" -#if HERMES_INTERCEPT == 1 -#include "adapter/stdio/stdio_fs_api.h" -#endif - -#include "adapter_test_utils.h" -#include "hermes_shm/util/logging.h" - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string new_file_cmp; - std::string existing_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; - size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test - -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES->client_config_.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - info.write_data = GenRandom(args.request_size); - info.read_data = std::string(args.request_size, 'r'); - return 0; -} - -int finalize() { - MPI_Finalize(); - return 0; -} - -void IgnoreAllFiles() { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES->client_config_.SetAdapterPathTracking(info.new_file, false); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, false); -#endif -} - -void TrackFiles() { -#if HERMES_INTERCEPT == 1 - HERMES->client_config_.SetAdapterPathTracking(info.new_file, true); - HERMES->client_config_.SetAdapterPathTracking(info.existing_file, true); -#endif -} - -void RemoveFile(const std::string& path) { - stdfs::remove(path); - if (stdfs::exists(path)) { - HELOG(kFatal, "Failed to remove: {}", path) - } -} - -void RemoveFiles() { - RemoveFile(info.new_file); - RemoveFile(info.new_file_cmp); - RemoveFile(info.existing_file); - RemoveFile(info.existing_file_cmp); -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int pretest() { - // Create path names - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - info.new_file = fullpath.string() + "_new_" + std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext_" + std::to_string(getpid()); - info.new_file_cmp = - fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - - // Temporarily ignore all files - IgnoreAllFiles(); - - // Remove all files - RemoveFiles(); - - // Create the file NOT buffered by Hermes - if (!stdfs::exists(info.existing_file_cmp)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + info.existing_file_cmp + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file_cmp); - } - - // Create the file that IS buffered by Hermes - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "cp " + info.existing_file_cmp + " " + info.existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations); - } - - REQUIRE(info.total_size > 0); - - // Begin interception - TrackFiles(); - return 0; -} - -int posttest(bool compare_data = true) { - IgnoreAllFiles(); - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) { - char_mismatch++; - } - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) { - char_mismatch++; - } - } - REQUIRE(char_mismatch == 0); - } - } - /* Delete the files from both Hermes and the backend. */ - TrackFiles(); - RemoveFiles(); - Clear(); - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -FILE* fh_orig; -FILE* fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -void test_fopen(const char* path, const char* mode) { - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else { - cmp_path = info.existing_file_cmp; - } - fh_orig = fopen(path, mode); - fh_cmp = fopen(cmp_path.c_str(), mode); - bool is_same = (fh_cmp != nullptr && fh_orig != nullptr) || - (fh_cmp == nullptr && fh_orig == nullptr); - REQUIRE(is_same); -} -void test_fclose() { - status_orig = fclose(fh_orig); - int status = fclose(fh_cmp); - REQUIRE(status == status_orig); -} -void test_fwrite(const void* ptr, size_t size) { - size_written_orig = fwrite(ptr, sizeof(char), size, fh_orig); - size_t size_written = fwrite(ptr, sizeof(char), size, fh_cmp); - REQUIRE(size_written == size_written_orig); -} -void test_fread(char* ptr, size_t size) { - size_read_orig = fread(ptr, sizeof(char), size, fh_orig); - std::vector read_data(size, 'r'); - size_t size_read = fread(read_data.data(), sizeof(char), size, fh_cmp); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} -void test_fseek(long offset, int whence) { - status_orig = fseek(fh_orig, offset, whence); - int status = fseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -#include "stdio_adapter_basic_test.cpp" -#include "stdio_adapter_func_test.cpp" -#include "stdio_adapter_rs_test.cpp" diff --git a/data_stager/data_stager.h b/data_stager/data_stager.h deleted file mode 100644 index b594622bc..000000000 --- a/data_stager/data_stager.h +++ /dev/null @@ -1,71 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_DATA_STAGER_STAGE_IN_H_ -#define HERMES_DATA_STAGER_STAGE_IN_H_ - -#include -#include - -#include "hermes_types.h" -#include "posix/posix_io_client.h" - -namespace hermes { - -enum class DataStagerType { kPosix, kHdf5 }; - -class DataStagerTypeConv { - public: - static DataStagerType from_url(const std::string &url) { - if (url.rfind("h5::", 0) != std::string::npos) { - return DataStagerType::kHdf5; - } else { - return DataStagerType::kPosix; - } - } -}; - -class DataStager { - public: - virtual void StageIn(std::string url, hapi::PlacementPolicy dpe) = 0; - virtual void StageIn(std::string url, off_t off, size_t size, - hapi::PlacementPolicy dpe) = 0; - virtual void StageOut(std::string url) = 0; - - protected: - void DivideRange(off_t off, size_t size, off_t &new_off, size_t &new_size) { - int nprocs = 1; - int rank = 0; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - int ranks_for_io = nprocs; - - // Ensure that all ranks perform at least 32MB of I/O - size_t min_io_per_rank = MEGABYTES(32); - if (size < nprocs * min_io_per_rank) { - ranks_for_io = size / min_io_per_rank; - if (size % min_io_per_rank) { - ranks_for_io += 1; - } - } - - new_size = size / ranks_for_io; - new_off = off + new_size * rank; - if (rank == ranks_for_io - 1) { - new_size += size % ranks_for_io; - } - } -}; - -} // namespace hermes - -#endif // HERMES_DATA_STAGER_STAGE_IN_H_ diff --git a/data_stager/stagers/posix_stager.h b/data_stager/stagers/posix_stager.h deleted file mode 100644 index 70675d27a..000000000 --- a/data_stager/stagers/posix_stager.h +++ /dev/null @@ -1,40 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_DATA_STAGER_STAGERS_POSIX_STAGE_H -#define HERMES_DATA_STAGER_STAGERS_POSIX_STAGE_H - -#include "../data_stager.h" -#include "posix/posix_api.h" -#include "posix/posix_fs_api.h" - -namespace hermes { - -class PosixStager : public DataStager { - public: - void StageIn(std::string url, hapi::PlacementPolicy dpe) override; - void FileStageIn(std::string path, hapi::PlacementPolicy dpe); - void DirectoryStageIn(std::string path, hapi::PlacementPolicy dpe); - - void StageIn(std::string url, off_t off, size_t size, - hapi::PlacementPolicy dpe) override; - void FileStageIn(std::string path, off_t off, size_t size, - hapi::PlacementPolicy dpe); - - void StageOut(std::string url) override; - void FileStageOut(std::string path); - void DirectoryStageOut(std::string path); -}; - -} // namespace hermes - -#endif // HERMES_DATA_STAGER_STAGERS_POSIX_STAGE_H diff --git a/data_stager/test/CMakeLists.txt b/data_stager/test/CMakeLists.txt deleted file mode 100644 index 2b0116e81..000000000 --- a/data_stager/test/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -pytest(data_stager test_data_stager_posix_large_aligned) -pytest(data_stager test_data_stager_posix_large_unaligned) -pytest(data_stager test_data_stager_posix_small_misaligned) -pytest(data_stager test_data_stager_directory) diff --git a/data_stager/test/stage_dir.sh b/data_stager/test/stage_dir.sh deleted file mode 100755 index 44bf512bd..000000000 --- a/data_stager/test/stage_dir.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -MPI_EXEC=$1 -HERMES_ROOT=$2 -HERMES_BUILD=$3 -HERMES_CONF=$4 -N_STAGE=$5 -STAGE_OFFSET_BLOCKS=$6 - -BLOCK_SIZE=1048576 -BLOCK_SIZE_KB=1024 -STAGE_OFFSET=$((${STAGE_OFFSET_BLOCKS}*${BLOCK_SIZE})) -ITER=10 - -echo "START" -echo "${MPI_EXEC}" -echo "${HERMES_ROOT}" -echo "${HERMES_BUILD}" -echo "${HERMES_CONF}" - -rm -rf /tmp/staging -rm -rf hermes_dir - -mkdir -p /tmp/staging -mkdir hermes_dir - -if ! command -v ior &> /dev/null -then - echo "ior could not be found" - exit 1 -fi - -# Create files using IOR. -# -# -F option is for file per process. -# -w for write-only -# -k to keep file -# -m multiple file -# -i iteration -# -# https://ior.readthedocs.io/en/latest/userDoc/options.html -echo "CREATE FILE" -${MPI_EXEC} -n ${N_STAGE} ior -F2 -w -k -m -i2 -o /tmp/staging/test -if [ $? != 0 ]; then - exit ${RET} -fi - -# Start daemon. -${MPI_EXEC} -n 1 \ --genv HERMES_CONF "${HERMES_CONF}" \ --genv LD_LIBRARY_PATH "${HERMES_BUILD}:$LD_LIBRARY_PATH" \ -"${HERMES_BUILD}/hermes_daemon" & -if [ $? != 0 ]; then - exit ${RET} -fi - -sleep 1 - -# Stage file. -echo "STAGE IN" -${MPI_EXEC} -n "${N_STAGE}" \ --genv HERMES_CONF "${HERMES_CONF}" \ --genv LD_LIBRARY_PATH "${HERMES_BUILD}:$LD_LIBRARY_PATH" \ --genv LSAN_OPTIONS=suppressions="${HERMES_ROOT}/test/data/asan.supp" \ --genv SET_PATH=0 \ --genv HERMES_CLIENT 1 \ -"${HERMES_BUILD}/stage_in" /tmp/staging/ "${STAGE_OFFSET}" 0 kMinimizeIoTime -if [ $? != 0 ]; then - exit ${RET} -fi - -# Read with hermes. -echo "READ STAGE IN" -${MPI_EXEC} -n ${N_STAGE} \ --genv HERMES_CONF "${HERMES_CONF}" \ --genv LD_PRELOAD "${HERMES_BUILD}/libhermes_posix.so" \ --genv HERMES_STOP_DAEMON 0 \ --genv ADAPTER_MODE WORKFLOW \ --genv HERMES_CLIENT 1 \ --genv HERMES_PAGE_SIZE 1048576 \ -ior -F2 -r -m -o /tmp/staging/test -if [ $? != 0 ]; then - exit ${RET} -fi - - -# Finalize hermes daemon. -echo "FINALIZE" -${MPI_EXEC} -n 1 "${HERMES_BUILD}/finalize_hermes" -if [ $? != 0 ]; then - exit ${RET} -fi - -rm -rf /tmp/staging -rm -rf hermes_dir - diff --git a/hermes_adapters/adapter_types.h b/hermes_adapters/adapter_types.h index 05b002bdd..2bc971455 100644 --- a/hermes_adapters/adapter_types.h +++ b/hermes_adapters/adapter_types.h @@ -18,10 +18,23 @@ namespace hermes::adapter { /** Adapter types */ -enum class AdapterType { kNone, kPosix, kStdio, kMpiio, kPubsub, kVfd }; +enum class AdapterType { + kNone, + kPosix, + kStdio, + kMpiio, + kPubsub, + kVfd +}; /** Adapter modes */ -enum class AdapterMode { kNone, kDefault, kBypass, kScratch, kWorkflow }; +enum class AdapterMode { + kNone, + kDefault, + kBypass, + kScratch, + kWorkflow +}; /** * Per-Object Adapter Settings. diff --git a/hermes_adapters/filesystem/filesystem.h b/hermes_adapters/filesystem/filesystem.h index 9ba99662f..a0eea9e7d 100644 --- a/hermes_adapters/filesystem/filesystem.h +++ b/hermes_adapters/filesystem/filesystem.h @@ -19,18 +19,19 @@ #include #include - -#include #include #include #include -#include "data_stager/factory/binary_stager.h" -#include "filesystem_io_client.h" -#include "filesystem_mdm.h" #include "hermes/bucket.h" #include "hermes/hermes.h" + +#include "filesystem_mdm.h" +#include "filesystem_io_client.h" #include "hermes_adapters/mapper/mapper_factory.h" +#include "data_stager/factory/binary_stager.h" +#include + namespace hermes::adapter { @@ -52,7 +53,8 @@ class Filesystem : public FilesystemIoClient { public: /** Constructor */ - explicit Filesystem(AdapterType type) : type_(type) {} + explicit Filesystem(AdapterType type) + : type_(type) {} /** open \a path */ File Open(AdapterStat &stat, const std::string &path) { @@ -95,23 +97,18 @@ class Filesystem : public FilesystemIoClient { // Update page size stat.page_size_ = mdm->GetAdapterPageSize(path); // Bucket parameters - ctx.bkt_params_ = - hermes::data_stager::BinaryFileStager::BuildFileParams( - stat.page_size_); + ctx.bkt_params_ = hermes::data_stager::BinaryFileStager::BuildFileParams(stat.page_size_); // Get or create the bucket if (stat.hflags_.Any(HERMES_FS_TRUNC)) { // The file was opened with TRUNCATION - stat.bkt_id_ = - HERMES->GetBucket(stat.path_, ctx, 0, HERMES_SHOULD_STAGE); + stat.bkt_id_ = HERMES->GetBucket(stat.path_, ctx, 0, HERMES_SHOULD_STAGE); stat.bkt_id_.Clear(); } else { // The file was opened regularly stat.file_size_ = GetBackendSize(*path_shm); - stat.bkt_id_ = HERMES->GetBucket(stat.path_, ctx, stat.file_size_, - HERMES_SHOULD_STAGE); + stat.bkt_id_ = HERMES->GetBucket(stat.path_, ctx, stat.file_size_, HERMES_SHOULD_STAGE); } - HILOG(kDebug, "BKT vs file size: {} {}", stat.bkt_id_.GetSize(), - stat.file_size_); + HILOG(kDebug, "BKT vs file size: {} {}", stat.bkt_id_.GetSize(), stat.file_size_); // Update file position pointer if (stat.hflags_.Any(HERMES_FS_APPEND)) { stat.st_ptr_ = std::numeric_limits::max(); @@ -120,7 +117,7 @@ class Filesystem : public FilesystemIoClient { } // Allocate internal hermes data auto stat_ptr = std::make_shared(stat); - FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *)stat_ptr.get()); + FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *) stat_ptr.get()); HermesOpen(f, stat, fs_ctx); mdm->Create(f, stat_ptr); } else { @@ -137,24 +134,23 @@ class Filesystem : public FilesystemIoClient { size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t off, size_t total_size, IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { - (void)f; + (void) f; hapi::Bucket &bkt = stat.bkt_id_; std::string filename = bkt.GetName(); bool is_append = stat.st_ptr_ == std::numeric_limits::max(); - HILOG(kDebug, - "Write called for filename: {}" - " on offset: {}" - " from position: {}" - " and size: {}" - " and adapter mode: {}", + HILOG(kDebug, "Write called for filename: {}" + " on offset: {}" + " from position: {}" + " and size: {}" + " and adapter mode: {}", filename, off, stat.st_ptr_, total_size, AdapterModeConv::str(stat.adapter_mode_)) if (stat.adapter_mode_ == AdapterMode::kBypass) { // Bypass mode is handled differently opts.backend_size_ = total_size; opts.backend_off_ = off; - Blob blob_wrap((char *)ptr, total_size); + Blob blob_wrap((char*)ptr, total_size); WriteBlob(bkt.GetName(), blob_wrap, opts, io_status); if (!io_status.success_) { HILOG(kDebug, "Failed to write blob of size {} to backend", @@ -171,7 +167,7 @@ class Filesystem : public FilesystemIoClient { if (is_append) { // Perform append - const Blob page((const char *)ptr, total_size); + const Blob page((const char*)ptr, total_size); bkt.Append(page, stat.page_size_, ctx); } else { // Fragment I/O request into pages @@ -182,7 +178,7 @@ class Filesystem : public FilesystemIoClient { // Perform a PartialPut for each page for (const BlobPlacement &p : mapping) { - const Blob page((const char *)ptr + data_offset, p.blob_size_); + const Blob page((const char*)ptr + data_offset, p.blob_size_); std::string blob_name(p.CreateBlobName().str()); bkt.AsyncPartialPut(blob_name, page, p.blob_off_, ctx); data_offset += p.blob_size_; @@ -195,25 +191,24 @@ class Filesystem : public FilesystemIoClient { io_status.size_ = total_size; UpdateIoStatus(opts, io_status); - HILOG(kDebug, "The size of file after write: {}", GetSize(f, stat)) + HILOG(kDebug, "The size of file after write: {}", + GetSize(f, stat)) return total_size; } /** base read function */ - template - size_t BaseRead( - File &f, AdapterStat &stat, void *ptr, size_t off, size_t total_size, - size_t req_id, - std::vector>> &tasks, - IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { - (void)f; + template + size_t BaseRead(File &f, AdapterStat &stat, void *ptr, size_t off, + size_t total_size, size_t req_id, + std::vector>> &tasks, + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { + (void) f; hapi::Bucket &bkt = stat.bkt_id_; - HILOG(kDebug, - "Read called for filename: {}" - " on offset: {}" - " from position: {}" - " and size: {}", + HILOG(kDebug, "Read called for filename: {}" + " on offset: {}" + " from position: {}" + " and size: {}", stat.path_, off, stat.st_ptr_, total_size) // SEEK_END is not a valid read position @@ -235,7 +230,7 @@ class Filesystem : public FilesystemIoClient { // Bypass mode is handled differently opts.backend_size_ = total_size; opts.backend_off_ = off; - Blob blob_wrap((char *)ptr, total_size); + Blob blob_wrap((char *) ptr, total_size); ReadBlob(bkt.GetName(), blob_wrap, opts, io_status); if (!io_status.success_) { HILOG(kDebug, "Failed to read blob of size {} from backend", @@ -259,7 +254,7 @@ class Filesystem : public FilesystemIoClient { Context ctx; ctx.flags_.SetBits(HERMES_SHOULD_STAGE); for (const BlobPlacement &p : mapping) { - Blob page((const char *)ptr + data_offset, p.blob_size_); + Blob page((const char*)ptr + data_offset, p.blob_size_); std::string blob_name(p.CreateBlobName().str()); if constexpr (ASYNC) { LPointer> task = @@ -283,16 +278,15 @@ class Filesystem : public FilesystemIoClient { } /** read */ - size_t Read(File &f, AdapterStat &stat, void *ptr, size_t off, - size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()) { + size_t Read(File &f, AdapterStat &stat, void *ptr, + size_t off, size_t total_size, + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { std::vector>> tasks; - return BaseRead(f, stat, ptr, off, total_size, 0, tasks, io_status, - opts); + return BaseRead(f, stat, ptr, off, total_size, 0, tasks, io_status, opts); } /** write asynchronously */ - FsAsyncTask *AWrite(File &f, AdapterStat &stat, const void *ptr, size_t off, + FsAsyncTask* AWrite(File &f, AdapterStat &stat, const void *ptr, size_t off, size_t total_size, size_t req_id, IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { // Writes are completely async at this time @@ -304,12 +298,11 @@ class Filesystem : public FilesystemIoClient { } /** read asynchronously */ - FsAsyncTask *ARead(File &f, AdapterStat &stat, void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()) { + FsAsyncTask* ARead(File &f, AdapterStat &stat, void *ptr, size_t off, + size_t total_size, size_t req_id, + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { FsAsyncTask *fstask = new FsAsyncTask(); - BaseRead(f, stat, ptr, off, total_size, req_id, fstask->get_tasks_, - io_status, opts); + BaseRead(f, stat, ptr, off, total_size, req_id, fstask->get_tasks_, io_status, opts); fstask->io_status_ = io_status; fstask->opts_ = opts; return fstask; @@ -317,8 +310,7 @@ class Filesystem : public FilesystemIoClient { /** wait for \a req_id request ID */ size_t Wait(FsAsyncTask *fstask) { - for (LPointer> &push_task : - fstask->put_tasks_) { + for (LPointer> &push_task : fstask->put_tasks_) { push_task->Wait(); HRUN_CLIENT->DelTask(push_task); } @@ -326,8 +318,7 @@ class Filesystem : public FilesystemIoClient { // Update I/O status for gets if (!fstask->get_tasks_.empty()) { size_t get_size = 0; - for (LPointer> &push_task : - fstask->get_tasks_) { + for (LPointer> &push_task : fstask->get_tasks_) { push_task->Wait(); GetBlobTask *task = push_task->get(); get_size += task->data_size_; @@ -340,7 +331,7 @@ class Filesystem : public FilesystemIoClient { } /** wait for request IDs in \a req_id vector */ - void Wait(std::vector &req_ids, std::vector &ret) { + void Wait(std::vector &req_ids, std::vector &ret) { for (auto &req_id : req_ids) { ret.emplace_back(Wait(req_id)); } @@ -385,7 +376,7 @@ class Filesystem : public FilesystemIoClient { /** file size */ size_t GetSize(File &f, AdapterStat &stat) { - (void)stat; + (void) stat; if (stat.adapter_mode_ != AdapterMode::kBypass) { return stat.bkt_id_.GetSize(); } else { @@ -395,7 +386,7 @@ class Filesystem : public FilesystemIoClient { /** tell */ size_t Tell(File &f, AdapterStat &stat) { - (void)f; + (void) f; if (stat.st_ptr_ != std::numeric_limits::max()) { return stat.st_ptr_; } else { @@ -424,7 +415,7 @@ class Filesystem : public FilesystemIoClient { int Close(File &f, AdapterStat &stat) { Sync(f, stat); auto mdm = HERMES_FS_METADATA_MANAGER; - FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *)&stat); + FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void*)&stat); HermesClose(f, stat, fs_ctx); RealClose(f, stat); mdm->Delete(stat.path_, f); @@ -457,10 +448,8 @@ class Filesystem : public FilesystemIoClient { std::list files = *filesp; for (File &f : files) { std::shared_ptr stat = mdm->Find(f); - if (stat == nullptr) { - continue; - } - FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *)&stat); + if (stat == nullptr) { continue; } + FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *) &stat); HermesClose(f, *stat, fs_ctx); RealClose(f, *stat); mdm->Delete(stat->path_, f); @@ -496,7 +485,7 @@ class Filesystem : public FilesystemIoClient { } /** write asynchronously */ - FsAsyncTask *AWrite(File &f, AdapterStat &stat, const void *ptr, + FsAsyncTask* AWrite(File &f, AdapterStat &stat, const void *ptr, size_t total_size, size_t req_id, IoStatus &io_status, FsIoOptions opts) { size_t off = stat.st_ptr_; @@ -504,8 +493,9 @@ class Filesystem : public FilesystemIoClient { } /** read asynchronously */ - FsAsyncTask *ARead(File &f, AdapterStat &stat, void *ptr, size_t total_size, - size_t req_id, IoStatus &io_status, FsIoOptions opts) { + FsAsyncTask* ARead(File &f, AdapterStat &stat, void *ptr, size_t total_size, + size_t req_id, + IoStatus &io_status, FsIoOptions opts) { size_t off = stat.st_ptr_; return ARead(f, stat, ptr, off, total_size, req_id, io_status, opts); } @@ -573,10 +563,10 @@ class Filesystem : public FilesystemIoClient { } /** write asynchronously */ - FsAsyncTask *AWrite(File &f, bool &stat_exists, const void *ptr, + FsAsyncTask* AWrite(File &f, bool &stat_exists, const void *ptr, size_t total_size, size_t req_id, - std::vector &tasks, IoStatus &io_status, - FsIoOptions opts) { + std::vector &tasks, + IoStatus &io_status, FsIoOptions opts) { auto mdm = HERMES_FS_METADATA_MANAGER; auto stat = mdm->Find(f); if (!stat) { @@ -588,7 +578,7 @@ class Filesystem : public FilesystemIoClient { } /** read asynchronously */ - FsAsyncTask *ARead(File &f, bool &stat_exists, void *ptr, size_t total_size, + FsAsyncTask* ARead(File &f, bool &stat_exists, void *ptr, size_t total_size, size_t req_id, IoStatus &io_status, FsIoOptions opts) { auto mdm = HERMES_FS_METADATA_MANAGER; auto stat = mdm->Find(f); @@ -601,7 +591,7 @@ class Filesystem : public FilesystemIoClient { } /** write \a off offset asynchronously */ - FsAsyncTask *AWrite(File &f, bool &stat_exists, const void *ptr, size_t off, + FsAsyncTask* AWrite(File &f, bool &stat_exists, const void *ptr, size_t off, size_t total_size, size_t req_id, IoStatus &io_status, FsIoOptions opts) { auto mdm = HERMES_FS_METADATA_MANAGER; @@ -616,7 +606,7 @@ class Filesystem : public FilesystemIoClient { } /** read \a off offset asynchronously */ - FsAsyncTask *ARead(File &f, bool &stat_exists, void *ptr, size_t off, + FsAsyncTask* ARead(File &f, bool &stat_exists, void *ptr, size_t off, size_t total_size, size_t req_id, IoStatus &io_status, FsIoOptions opts) { auto mdm = HERMES_FS_METADATA_MANAGER; diff --git a/hermes_adapters/filesystem/filesystem_io_client.h b/hermes_adapters/filesystem/filesystem_io_client.h index 40dfa02c7..8e504501e 100644 --- a/hermes_adapters/filesystem/filesystem_io_client.h +++ b/hermes_adapters/filesystem/filesystem_io_client.h @@ -13,15 +13,13 @@ #ifndef HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_IO_CLIENT_H_ #define HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_IO_CLIENT_H_ -#include - +#include "hermes_adapters/mapper/balanced_mapper.h" +#include "hermes/hermes.h" +#include "hermes/bucket.h" #include -#include #include - -#include "hermes/bucket.h" -#include "hermes/hermes.h" -#include "hermes_adapters/mapper/balanced_mapper.h" +#include +#include namespace stdfs = std::filesystem; @@ -44,18 +42,17 @@ namespace hermes::adapter { /** A structure to represent IO status */ struct IoStatus { - size_t size_; /**< POSIX/STDIO return value */ + size_t size_; /**< POSIX/STDIO return value */ int mpi_ret_; /**< MPI return value */ MPI_Status mpi_status_; /**< MPI status */ MPI_Status *mpi_status_ptr_; /**< MPI status pointer */ bool success_; /**< Whether the I/O succeeded */ /** Default constructor */ - IoStatus() - : size_(0), - mpi_ret_(MPI_SUCCESS), - mpi_status_ptr_(&mpi_status_), - success_(true) {} + IoStatus() : size_(0), + mpi_ret_(MPI_SUCCESS), + mpi_status_ptr_(&mpi_status_), + success_(true) {} /** Copy constructor */ void Copy(const IoStatus &other) { @@ -76,46 +73,53 @@ struct IoStatus { * For now, nothing additional than the typical FsIoOptions. * */ struct FsIoOptions { - bitfield32_t flags_; /**< various I/O flags */ - MPI_Datatype mpi_type_; /**< MPI data type */ - int mpi_count_; /**< The number of types */ - int type_size_; /**< The size of type */ - size_t backend_off_; /**< Offset in the backend to begin I/O */ - size_t backend_size_; /**< Size of I/O to perform at backend */ + bitfield32_t flags_; /**< various I/O flags */ + MPI_Datatype mpi_type_; /**< MPI data type */ + int mpi_count_; /**< The number of types */ + int type_size_; /**< The size of type */ + size_t backend_off_; /**< Offset in the backend to begin I/O */ + size_t backend_size_; /**< Size of I/O to perform at backend */ /** Default constructor */ - FsIoOptions() - : flags_(), - mpi_type_(MPI_CHAR), - mpi_count_(0), - type_size_(1), - backend_off_(0), - backend_size_(0) { + FsIoOptions() : flags_(), + mpi_type_(MPI_CHAR), + mpi_count_(0), + type_size_(1), + backend_off_(0), + backend_size_(0) { SetSeek(); } /** Enable seek for this I/O */ - void SetSeek() { flags_.SetBits(HERMES_FS_SEEK); } + void SetSeek() { + flags_.SetBits(HERMES_FS_SEEK); + } /** Disable seek for this I/O */ - void UnsetSeek() { flags_.UnsetBits(HERMES_FS_SEEK); } + void UnsetSeek() { + flags_.UnsetBits(HERMES_FS_SEEK); + } /** Whether or not to perform seek in FS adapter */ - bool DoSeek() const { return flags_.Any(HERMES_FS_SEEK); } + bool DoSeek() const { + return flags_.Any(HERMES_FS_SEEK); + } /** Marks the file as truncated */ - void MarkTruncated() { flags_.SetBits(HERMES_FS_TRUNC); } + void MarkTruncated() { + flags_.SetBits(HERMES_FS_TRUNC); + } /** Whether a file is marked truncated */ - bool IsTruncated() const { return flags_.Any(HERMES_FS_TRUNC); } + bool IsTruncated() const { + return flags_.Any(HERMES_FS_TRUNC); + } /** return IO options with \a mpi_type MPI data type */ static FsIoOptions DataType(MPI_Datatype mpi_type, bool seek = true) { FsIoOptions opts; opts.mpi_type_ = mpi_type; - if (!seek) { - opts.UnsetSeek(); - } + if (!seek) { opts.UnsetSeek(); } return opts; } }; @@ -131,7 +135,7 @@ struct FsAsyncTask { /** Represents an object in the I/O client (e.g., a file) */ struct File { AdapterType type_; /**< Client to forward I/O request to */ - std::string filename_; /**< Filename to read from */ + std::string filename_; /**< Filename to read from */ int hermes_fd_; /**< fake file descriptor (SCRATCH MODE) */ FILE *hermes_fh_; /**< fake file handler (SCRATCH MODE) */ @@ -179,8 +183,8 @@ struct File { std::size_t hash() const { std::size_t result; std::size_t h1 = std::hash{}(hermes_fd_); - std::size_t h2 = std::hash{}(hermes_fh_); - std::size_t h3 = std::hash{}(hermes_mpi_fh_); + std::size_t h2 = std::hash{}(hermes_fh_); + std::size_t h3 = std::hash{}(hermes_mpi_fh_); result = h1 ^ h2 ^ h3; return result; } @@ -188,19 +192,19 @@ struct File { /** Any relevant statistics from the I/O client */ struct AdapterStat { - std::string path_; /**< The URL of this file */ - int flags_; /**< open() flags for POSIX */ - bitfield32_t hflags_; /**< Flags used by FS adapter */ - mode_t st_mode_; /**< protection */ - uid_t st_uid_; /**< user ID of owner */ - gid_t st_gid_; /**< group ID of owner */ - size_t st_ptr_; /**< current ptr of FILE */ - size_t file_size_; /**< Size of file at backend at time of open */ - timespec st_atim_; /**< time of last access */ - timespec st_mtim_; /**< time of last modification */ - timespec st_ctim_; /**< time of last status change */ - std::string mode_str_; /**< mode used for fopen() */ - AdapterMode adapter_mode_; /**< Mode used for adapter */ + std::string path_; /**< The URL of this file */ + int flags_; /**< open() flags for POSIX */ + bitfield32_t hflags_; /**< Flags used by FS adapter */ + mode_t st_mode_; /**< protection */ + uid_t st_uid_; /**< user ID of owner */ + gid_t st_gid_; /**< group ID of owner */ + size_t st_ptr_; /**< current ptr of FILE */ + size_t file_size_; /**< Size of file at backend at time of open */ + timespec st_atim_; /**< time of last access */ + timespec st_mtim_; /**< time of last modification */ + timespec st_ctim_; /**< time of last status change */ + std::string mode_str_; /**< mode used for fopen() */ + AdapterMode adapter_mode_; /**< Mode used for adapter */ int fd_; /**< real file descriptor */ FILE *fh_; /**< real STDIO file handler */ @@ -251,8 +255,8 @@ struct AdapterStat { * Metadta required by Filesystem I/O clients to perform a HermesOpen * */ struct FsIoClientMetadata { - int hermes_fd_min_, hermes_fd_max_; /**< Min and max fd values (inclusive)*/ - std::atomic hermes_fd_cur_; /**< Current fd */ + int hermes_fd_min_, hermes_fd_max_; /**< Min and max fd values (inclusive)*/ + std::atomic hermes_fd_cur_; /**< Current fd */ /** Default constructor */ FsIoClientMetadata() { @@ -270,7 +274,7 @@ struct FsIoClientMetadata { /** Release a Hermes FD */ void ReleaseFd(int hermes_fd) { // TODO(llogan): recycle instead of ignore - (void)hermes_fd; + (void) hermes_fd; } }; @@ -291,7 +295,7 @@ struct FilesystemIoClientState { /** Default constructor */ FilesystemIoClientState(FsIoClientMetadata *mdm, void *stat) - : mdm_(mdm), stat_(stat) {} + : mdm_(mdm), stat_(stat) {} }; /** @@ -307,15 +311,20 @@ class FilesystemIoClient { virtual size_t GetBackendSize(const hipc::charbuf &bkt_name) = 0; /** Write blob to backend */ - virtual void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) = 0; + virtual void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) = 0; /** Read blob from the backend */ - virtual void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) = 0; + virtual void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) = 0; /** real open */ - virtual void RealOpen(File &f, AdapterStat &stat, + virtual void RealOpen(File &f, + AdapterStat &stat, const std::string &path) = 0; /** @@ -324,14 +333,17 @@ class FilesystemIoClient { * and hermes file handler. These are not the same as POSIX file * descriptor and STDIO file handler. * */ - virtual void HermesOpen(File &f, const AdapterStat &stat, + virtual void HermesOpen(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) = 0; /** real sync */ - virtual int RealSync(const File &f, const AdapterStat &stat) = 0; + virtual int RealSync(const File &f, + const AdapterStat &stat) = 0; /** real close */ - virtual int RealClose(const File &f, AdapterStat &stat) = 0; + virtual int RealClose(const File &f, + AdapterStat &stat) = 0; /** real remove */ virtual int RealRemove(const std::string &path) = 0; @@ -340,7 +352,8 @@ class FilesystemIoClient { * Called before RealClose. Releases information provisioned during * the allocation phase. * */ - virtual void HermesClose(File &f, const AdapterStat &stat, + virtual void HermesClose(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) = 0; /** Updates I/O status after read/write operations */ diff --git a/hermes_adapters/mapper/abstract_mapper.h b/hermes_adapters/mapper/abstract_mapper.h index b28fc8ff9..30c904f6f 100644 --- a/hermes_adapters/mapper/abstract_mapper.h +++ b/hermes_adapters/mapper/abstract_mapper.h @@ -21,7 +21,9 @@ namespace hermes::adapter { * Define different types of mappers supported by POSIX Adapter. * Also define its construction in the MapperFactory. */ -enum class MapperType { kBalancedMapper }; +enum class MapperType { + kBalancedMapper +}; /** A structure to represent BLOB placement @@ -49,7 +51,7 @@ struct BlobPlacement { } /** decode \a blob_name BLOB name to index. */ - template + template void DecodeBlobName(const StringT &blob_name, size_t page_size) { hrun::LocalDeserialize srl(blob_name); srl >> page_; diff --git a/hermes_adapters/mpiio/mpiio_api.h b/hermes_adapters/mpiio/mpiio_api.h index 75512eee8..283050e21 100644 --- a/hermes_adapters/mpiio/mpiio_api.h +++ b/hermes_adapters/mpiio/mpiio_api.h @@ -12,13 +12,11 @@ #ifndef HERMES_ADAPTER_MPIIO_H #define HERMES_ADAPTER_MPIIO_H +#include #include -#include - #include -#include - #include "hermes_shm/util/logging.h" +#include #ifdef HERMES_MPICH #include #endif @@ -29,67 +27,33 @@ #endif extern "C" { -typedef int (*MPI_Init_t)(int* argc, char*** argv); -typedef int (*MPI_Finalize_t)(void); -typedef int (*MPI_Wait_t)(MPI_Request* req, MPI_Status* status); -typedef int (*MPI_Waitall_t)(int count, MPI_Request* req, MPI_Status* status); -typedef int (*MPI_File_open_t)(MPI_Comm comm, const char* filename, int amode, - MPI_Info info, MPI_File* fh); -typedef int (*MPI_File_close_t)(MPI_File* fh); -typedef int (*MPI_File_seek_shared_t)(MPI_File fh, MPI_Offset offset, - int whence); +typedef int (*MPI_Init_t)(int * argc, char *** argv); +typedef int (*MPI_Finalize_t)( void); +typedef int (*MPI_Wait_t)(MPI_Request * req, MPI_Status * status); +typedef int (*MPI_Waitall_t)(int count, MPI_Request * req, MPI_Status * status); +typedef int (*MPI_File_open_t)(MPI_Comm comm, const char * filename, int amode, MPI_Info info, MPI_File * fh); +typedef int (*MPI_File_close_t)(MPI_File * fh); +typedef int (*MPI_File_seek_shared_t)(MPI_File fh, MPI_Offset offset, int whence); typedef int (*MPI_File_seek_t)(MPI_File fh, MPI_Offset offset, int whence); -typedef int (*MPI_File_get_position_t)(MPI_File fh, MPI_Offset* offset); -typedef int (*MPI_File_read_all_t)(MPI_File fh, void* buf, int count, - MPI_Datatype datatype, MPI_Status* status); -typedef int (*MPI_File_read_at_all_t)(MPI_File fh, MPI_Offset offset, void* buf, - int count, MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_read_at_t)(MPI_File fh, MPI_Offset offset, void* buf, - int count, MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_read_t)(MPI_File fh, void* buf, int count, - MPI_Datatype datatype, MPI_Status* status); -typedef int (*MPI_File_read_ordered_t)(MPI_File fh, void* buf, int count, - MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_read_shared_t)(MPI_File fh, void* buf, int count, - MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_write_all_t)(MPI_File fh, const void* buf, int count, - MPI_Datatype datatype, MPI_Status* status); -typedef int (*MPI_File_write_at_all_t)(MPI_File fh, MPI_Offset offset, - const void* buf, int count, - MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_write_at_t)(MPI_File fh, MPI_Offset offset, - const void* buf, int count, - MPI_Datatype datatype, MPI_Status* status); -typedef int (*MPI_File_write_t)(MPI_File fh, const void* buf, int count, - MPI_Datatype datatype, MPI_Status* status); -typedef int (*MPI_File_write_ordered_t)(MPI_File fh, const void* buf, int count, - MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_write_shared_t)(MPI_File fh, const void* buf, int count, - MPI_Datatype datatype, - MPI_Status* status); -typedef int (*MPI_File_iread_at_t)(MPI_File fh, MPI_Offset offset, void* buf, - int count, MPI_Datatype datatype, - MPI_Request* request); -typedef int (*MPI_File_iread_t)(MPI_File fh, void* buf, int count, - MPI_Datatype datatype, MPI_Request* request); -typedef int (*MPI_File_iread_shared_t)(MPI_File fh, void* buf, int count, - MPI_Datatype datatype, - MPI_Request* request); -typedef int (*MPI_File_iwrite_at_t)(MPI_File fh, MPI_Offset offset, - const void* buf, int count, - MPI_Datatype datatype, - MPI_Request* request); -typedef int (*MPI_File_iwrite_t)(MPI_File fh, const void* buf, int count, - MPI_Datatype datatype, MPI_Request* request); -typedef int (*MPI_File_iwrite_shared_t)(MPI_File fh, const void* buf, int count, - MPI_Datatype datatype, - MPI_Request* request); +typedef int (*MPI_File_get_position_t)(MPI_File fh, MPI_Offset * offset); +typedef int (*MPI_File_read_all_t)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_read_at_all_t)(MPI_File fh, MPI_Offset offset, void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_read_at_t)(MPI_File fh, MPI_Offset offset, void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_read_t)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_read_ordered_t)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_read_shared_t)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_write_all_t)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_write_at_all_t)(MPI_File fh, MPI_Offset offset, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_write_at_t)(MPI_File fh, MPI_Offset offset, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_write_t)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_write_ordered_t)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_write_shared_t)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status); +typedef int (*MPI_File_iread_at_t)(MPI_File fh, MPI_Offset offset, void * buf, int count, MPI_Datatype datatype, MPI_Request * request); +typedef int (*MPI_File_iread_t)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Request * request); +typedef int (*MPI_File_iread_shared_t)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Request * request); +typedef int (*MPI_File_iwrite_at_t)(MPI_File fh, MPI_Offset offset, const void * buf, int count, MPI_Datatype datatype, MPI_Request * request); +typedef int (*MPI_File_iwrite_t)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Request * request); +typedef int (*MPI_File_iwrite_shared_t)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Request * request); typedef int (*MPI_File_sync_t)(MPI_File fh); } @@ -168,68 +132,53 @@ class MpiioApi : public RealApi { REQUIRE_API(MPI_File_open) MPI_File_close = (MPI_File_close_t)dlsym(real_lib_, "MPI_File_close"); REQUIRE_API(MPI_File_close) - MPI_File_seek_shared = - (MPI_File_seek_shared_t)dlsym(real_lib_, "MPI_File_seek_shared"); + MPI_File_seek_shared = (MPI_File_seek_shared_t)dlsym(real_lib_, "MPI_File_seek_shared"); REQUIRE_API(MPI_File_seek_shared) MPI_File_seek = (MPI_File_seek_t)dlsym(real_lib_, "MPI_File_seek"); REQUIRE_API(MPI_File_seek) - MPI_File_get_position = - (MPI_File_get_position_t)dlsym(real_lib_, "MPI_File_get_position"); + MPI_File_get_position = (MPI_File_get_position_t)dlsym(real_lib_, "MPI_File_get_position"); REQUIRE_API(MPI_File_get_position) - MPI_File_read_all = - (MPI_File_read_all_t)dlsym(real_lib_, "MPI_File_read_all"); + MPI_File_read_all = (MPI_File_read_all_t)dlsym(real_lib_, "MPI_File_read_all"); REQUIRE_API(MPI_File_read_all) - MPI_File_read_at_all = - (MPI_File_read_at_all_t)dlsym(real_lib_, "MPI_File_read_at_all"); + MPI_File_read_at_all = (MPI_File_read_at_all_t)dlsym(real_lib_, "MPI_File_read_at_all"); REQUIRE_API(MPI_File_read_at_all) MPI_File_read_at = (MPI_File_read_at_t)dlsym(real_lib_, "MPI_File_read_at"); REQUIRE_API(MPI_File_read_at) MPI_File_read = (MPI_File_read_t)dlsym(real_lib_, "MPI_File_read"); REQUIRE_API(MPI_File_read) - MPI_File_read_ordered = - (MPI_File_read_ordered_t)dlsym(real_lib_, "MPI_File_read_ordered"); + MPI_File_read_ordered = (MPI_File_read_ordered_t)dlsym(real_lib_, "MPI_File_read_ordered"); REQUIRE_API(MPI_File_read_ordered) - MPI_File_read_shared = - (MPI_File_read_shared_t)dlsym(real_lib_, "MPI_File_read_shared"); + MPI_File_read_shared = (MPI_File_read_shared_t)dlsym(real_lib_, "MPI_File_read_shared"); REQUIRE_API(MPI_File_read_shared) - MPI_File_write_all = - (MPI_File_write_all_t)dlsym(real_lib_, "MPI_File_write_all"); + MPI_File_write_all = (MPI_File_write_all_t)dlsym(real_lib_, "MPI_File_write_all"); REQUIRE_API(MPI_File_write_all) - MPI_File_write_at_all = - (MPI_File_write_at_all_t)dlsym(real_lib_, "MPI_File_write_at_all"); + MPI_File_write_at_all = (MPI_File_write_at_all_t)dlsym(real_lib_, "MPI_File_write_at_all"); REQUIRE_API(MPI_File_write_at_all) - MPI_File_write_at = - (MPI_File_write_at_t)dlsym(real_lib_, "MPI_File_write_at"); + MPI_File_write_at = (MPI_File_write_at_t)dlsym(real_lib_, "MPI_File_write_at"); REQUIRE_API(MPI_File_write_at) MPI_File_write = (MPI_File_write_t)dlsym(real_lib_, "MPI_File_write"); REQUIRE_API(MPI_File_write) - MPI_File_write_ordered = - (MPI_File_write_ordered_t)dlsym(real_lib_, "MPI_File_write_ordered"); + MPI_File_write_ordered = (MPI_File_write_ordered_t)dlsym(real_lib_, "MPI_File_write_ordered"); REQUIRE_API(MPI_File_write_ordered) - MPI_File_write_shared = - (MPI_File_write_shared_t)dlsym(real_lib_, "MPI_File_write_shared"); + MPI_File_write_shared = (MPI_File_write_shared_t)dlsym(real_lib_, "MPI_File_write_shared"); REQUIRE_API(MPI_File_write_shared) - MPI_File_iread_at = - (MPI_File_iread_at_t)dlsym(real_lib_, "MPI_File_iread_at"); + MPI_File_iread_at = (MPI_File_iread_at_t)dlsym(real_lib_, "MPI_File_iread_at"); REQUIRE_API(MPI_File_iread_at) MPI_File_iread = (MPI_File_iread_t)dlsym(real_lib_, "MPI_File_iread"); REQUIRE_API(MPI_File_iread) - MPI_File_iread_shared = - (MPI_File_iread_shared_t)dlsym(real_lib_, "MPI_File_iread_shared"); + MPI_File_iread_shared = (MPI_File_iread_shared_t)dlsym(real_lib_, "MPI_File_iread_shared"); REQUIRE_API(MPI_File_iread_shared) - MPI_File_iwrite_at = - (MPI_File_iwrite_at_t)dlsym(real_lib_, "MPI_File_iwrite_at"); + MPI_File_iwrite_at = (MPI_File_iwrite_at_t)dlsym(real_lib_, "MPI_File_iwrite_at"); REQUIRE_API(MPI_File_iwrite_at) MPI_File_iwrite = (MPI_File_iwrite_t)dlsym(real_lib_, "MPI_File_iwrite"); REQUIRE_API(MPI_File_iwrite) - MPI_File_iwrite_shared = - (MPI_File_iwrite_shared_t)dlsym(real_lib_, "MPI_File_iwrite_shared"); + MPI_File_iwrite_shared = (MPI_File_iwrite_shared_t)dlsym(real_lib_, "MPI_File_iwrite_shared"); REQUIRE_API(MPI_File_iwrite_shared) MPI_File_sync = (MPI_File_sync_t)dlsym(real_lib_, "MPI_File_sync"); REQUIRE_API(MPI_File_sync) } }; -} // namespace hermes::adapter +} // namespace hermes::adapter::mpiio #include "hermes_shm/util/singleton.h" diff --git a/hermes_adapters/mpiio/mpiio_fs_api.h b/hermes_adapters/mpiio/mpiio_fs_api.h index 187db4193..a9b79bfe0 100644 --- a/hermes_adapters/mpiio/mpiio_fs_api.h +++ b/hermes_adapters/mpiio/mpiio_fs_api.h @@ -43,11 +43,14 @@ class MpiioSeekModeConv { class MpiioFs : public Filesystem { public: HERMES_MPIIO_API_T real_api_; /**< pointer to real APIs */ - - MpiioFs() : Filesystem(AdapterType::kMpiio) { real_api_ = HERMES_MPIIO_API; } + + MpiioFs() : Filesystem(AdapterType::kMpiio) { + real_api_ = HERMES_MPIIO_API; + } /** Initialize I/O opts using count + datatype */ - static size_t IoSizeFromCount(int count, MPI_Datatype datatype, + static size_t IoSizeFromCount(int count, + MPI_Datatype datatype, FsIoOptions &opts) { opts.mpi_type_ = datatype; opts.mpi_count_ = count; @@ -57,11 +60,8 @@ class MpiioFs : public Filesystem { inline bool IsMpiFpTracked(MPI_File *fh, std::shared_ptr &stat) { auto mdm = HERMES_FS_METADATA_MANAGER; - if (fh == nullptr) { - return false; - } - File f; - f.hermes_mpi_fh_ = (*fh); + if (fh == nullptr) { return false; } + File f; f.hermes_mpi_fh_ = (*fh); stat = mdm->Find(f); return stat != nullptr; } @@ -85,9 +85,8 @@ class MpiioFs : public Filesystem { auto mdm = HERMES_FS_METADATA_MANAGER; IoStatus io_status; size_t total_size = IoSizeFromCount(count, datatype, opts); - FsAsyncTask *fstask = - Filesystem::ARead(f, stat, ptr, offset, total_size, - reinterpret_cast(request), io_status, opts); + FsAsyncTask *fstask = Filesystem::ARead(f, stat, ptr, offset, total_size, + reinterpret_cast(request), io_status, opts); mdm->EmplaceTask(reinterpret_cast(request), fstask); return io_status.mpi_ret_; } @@ -128,18 +127,17 @@ class MpiioFs : public Filesystem { auto mdm = HERMES_FS_METADATA_MANAGER; IoStatus io_status; size_t total_size = IoSizeFromCount(count, datatype, opts); - FsAsyncTask *fstask = - Filesystem::AWrite(f, stat, ptr, offset, total_size, - reinterpret_cast(request), io_status, opts); + FsAsyncTask *fstask = Filesystem::AWrite(f, stat, ptr, offset, total_size, + reinterpret_cast(request), io_status, opts); mdm->EmplaceTask(reinterpret_cast(request), fstask); return io_status.mpi_ret_; } - template + template int BaseWriteAll(File &f, AdapterStat &stat, const void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Status *status, MPI_Request *request, FsIoOptions opts) { - if constexpr (!ASYNC) { + if constexpr(!ASYNC) { MPI_Barrier(stat.comm_); int ret = Write(f, stat, ptr, offset, count, datatype, status, opts); MPI_Barrier(stat.comm_); @@ -157,20 +155,20 @@ class MpiioFs : public Filesystem { } int AWriteAll(File &f, AdapterStat &stat, const void *ptr, size_t offset, - int count, MPI_Datatype datatype, MPI_Request *request, - FsIoOptions opts) { + int count, MPI_Datatype datatype, MPI_Request *request, + FsIoOptions opts) { return BaseWriteAll(f, stat, ptr, offset, count, datatype, nullptr, request, opts); } - template + template int BaseWriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, MPI_Datatype datatype, MPI_Status *status, MPI_Request *request, FsIoOptions opts) { int total; MPI_Scan(&count, &total, 1, MPI_INT, MPI_SUM, stat.comm_); MPI_Offset my_offset = total - count; - if constexpr (!ASYNC) { + if constexpr(!ASYNC) { size_t ret = WriteAll(f, stat, ptr, my_offset, count, datatype, status, opts); return ret; @@ -180,8 +178,8 @@ class MpiioFs : public Filesystem { } int WriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, - MPI_Datatype datatype, MPI_Status *status, - FsIoOptions opts) { + MPI_Datatype datatype, + MPI_Status *status, FsIoOptions opts) { return BaseWriteOrdered(f, stat, ptr, count, datatype, status, nullptr, opts); } @@ -232,13 +230,11 @@ class MpiioFs : public Filesystem { stat.comm_); MPI_Allreduce(&whence, &sum_whence, 1, MPI_INT, MPI_SUM, stat.comm_); if (sum_offset / comm_participators != offset) { - HELOG(kError, - "Same offset should be passed " + HELOG(kError, "Same offset should be passed " "across the opened file communicator.") } if (sum_whence / comm_participators != whence) { - HELOG(kError, - "Same whence should be passed " + HELOG(kError, "Same whence should be passed " "across the opened file communicator.") } Seek(f, stat, offset, whence); @@ -502,7 +498,9 @@ class MpiioFs : public Filesystem { public: /** Allocate an fd for the file f */ - void RealOpen(File &f, AdapterStat &stat, const std::string &path) override { + void RealOpen(File &f, + AdapterStat &stat, + const std::string &path) override { if (stat.amode_ & MPI_MODE_CREATE) { stat.hflags_.SetBits(HERMES_FS_CREATE); stat.hflags_.SetBits(HERMES_FS_TRUNC); @@ -544,19 +542,22 @@ class MpiioFs : public Filesystem { * and hermes file handler. These are not the same as STDIO file * descriptor and STDIO file handler. * */ - void HermesOpen(File &f, const AdapterStat &stat, + void HermesOpen(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) override { // f.hermes_mpi_fh_ = (MPI_File)fs_mdm.stat_; f.hermes_mpi_fh_ = stat.mpi_fh_; } /** Synchronize \a file FILE f */ - int RealSync(const File &f, const AdapterStat &stat) override { + int RealSync(const File &f, + const AdapterStat &stat) override { return real_api_->MPI_File_sync(stat.mpi_fh_); } /** Close \a file FILE f */ - int RealClose(const File &f, AdapterStat &stat) override { + int RealClose(const File &f, + AdapterStat &stat) override { return real_api_->MPI_File_close(&stat.mpi_fh_); } @@ -564,11 +565,10 @@ class MpiioFs : public Filesystem { * Called before RealClose. Releases information provisioned during * the allocation phase. * */ - void HermesClose(File &f, const AdapterStat &stat, + void HermesClose(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) override { - (void)f; - (void)stat; - (void)fs_mdm; + (void) f; (void) stat; (void) fs_mdm; } /** Remove \a file FILE f */ @@ -581,22 +581,22 @@ class MpiioFs : public Filesystem { size_t true_size = 0; std::string filename = bkt_name.str(); int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - return 0; - } + if (fd < 0) { return 0; } struct stat buf; fstat(fd, &buf); true_size = buf.st_size; close(fd); - HILOG(kDebug, "The size of the file {} on disk is {} bytes", filename, - true_size) + HILOG(kDebug, "The size of the file {} on disk is {} bytes", + filename, true_size) return true_size; } /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override { + void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { status.success_ = true; HILOG(kDebug, "Write called for: {}" @@ -605,38 +605,44 @@ class MpiioFs : public Filesystem { bkt_name, opts.backend_off_, full_blob.size()) MPI_File fh; int write_count = 0; - status.mpi_ret_ = real_api_->MPI_File_open( - MPI_COMM_SELF, bkt_name.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + status.mpi_ret_ = real_api_->MPI_File_open(MPI_COMM_SELF, bkt_name.c_str(), + MPI_MODE_RDONLY, + MPI_INFO_NULL, &fh); if (status.mpi_ret_ != MPI_SUCCESS) { status.success_ = false; return; } - status.mpi_ret_ = - real_api_->MPI_File_seek(fh, opts.backend_off_, MPI_SEEK_SET); + status.mpi_ret_ = real_api_->MPI_File_seek(fh, opts.backend_off_, + MPI_SEEK_SET); if (status.mpi_ret_ != MPI_SUCCESS) { status.success_ = false; goto ERROR; } - status.mpi_ret_ = - real_api_->MPI_File_write(fh, full_blob.data(), opts.mpi_count_, - opts.mpi_type_, status.mpi_status_ptr_); - MPI_Get_count(status.mpi_status_ptr_, opts.mpi_type_, &write_count); + status.mpi_ret_ = real_api_->MPI_File_write(fh, + full_blob.data(), + opts.mpi_count_, + opts.mpi_type_, + status.mpi_status_ptr_); + MPI_Get_count(status.mpi_status_ptr_, + opts.mpi_type_, &write_count); if (write_count != opts.mpi_count_) { status.success_ = false; - HELOG(kError, "writing failed: wrote {} / {}", write_count, - opts.mpi_count_) + HELOG(kError, "writing failed: wrote {} / {}", + write_count, opts.mpi_count_) } - ERROR: + ERROR: real_api_->MPI_File_close(&fh); status.size_ = full_blob.size(); UpdateIoStatus(opts, status); } /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override { + void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { status.success_ = true; HILOG(kDebug, "Reading from: {}" @@ -645,29 +651,34 @@ class MpiioFs : public Filesystem { bkt_name, opts.backend_off_, full_blob.size()) MPI_File fh; int read_count = 0; - status.mpi_ret_ = real_api_->MPI_File_open( - MPI_COMM_SELF, bkt_name.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + status.mpi_ret_ = real_api_->MPI_File_open(MPI_COMM_SELF, bkt_name.c_str(), + MPI_MODE_RDONLY, MPI_INFO_NULL, + &fh); if (status.mpi_ret_ != MPI_SUCCESS) { status.success_ = false; return; } - status.mpi_ret_ = - real_api_->MPI_File_seek(fh, opts.backend_off_, MPI_SEEK_SET); + status.mpi_ret_ = real_api_->MPI_File_seek(fh, opts.backend_off_, + MPI_SEEK_SET); if (status.mpi_ret_ != MPI_SUCCESS) { status.success_ = false; goto ERROR; } - status.mpi_ret_ = - real_api_->MPI_File_read(fh, full_blob.data(), opts.mpi_count_, - opts.mpi_type_, status.mpi_status_ptr_); - MPI_Get_count(status.mpi_status_ptr_, opts.mpi_type_, &read_count); + status.mpi_ret_ = real_api_->MPI_File_read(fh, + full_blob.data(), + opts.mpi_count_, + opts.mpi_type_, + status.mpi_status_ptr_); + MPI_Get_count(status.mpi_status_ptr_, + opts.mpi_type_, &read_count); if (read_count != opts.mpi_count_) { status.success_ = false; - HELOG(kError, "reading failed: read {} / {}", read_count, opts.mpi_count_) + HELOG(kError, "reading failed: read {} / {}", + read_count, opts.mpi_count_) } - ERROR: + ERROR: real_api_->MPI_File_close(&fh); status.size_ = full_blob.size(); UpdateIoStatus(opts, status); @@ -677,10 +688,10 @@ class MpiioFs : public Filesystem { void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) override { #ifdef HERMES_OPENMPI status.mpi_status_ptr_->_cancelled = 0; - status.mpi_status_ptr_->_ucount = (int)(status.size_ / opts.type_size_); + status.mpi_status_ptr_->_ucount = (int) (status.size_ / opts.type_size_); #elif defined(HERMES_MPICH) status.mpi_status_ptr_->count_hi_and_cancelled = 0; - status.mpi_status_ptr_->count_lo = (int)(status.size_ / opts.type_size_); + status.mpi_status_ptr_->count_lo = (int) (status.size_ / opts.type_size_); #else #error "No MPI implementation specified for MPIIO adapter" #endif @@ -692,6 +703,6 @@ class MpiioFs : public Filesystem { /** Simplify access to the stateless StdioFs Singleton */ #define HERMES_MPIIO_FS \ hshm::EasySingleton<::hermes::adapter::MpiioFs>::GetInstance() -#define HERMES_STDIO_FS_T hermes::adapter::MpiioFs * +#define HERMES_STDIO_FS_T hermes::adapter::MpiioFs* #endif // HERMES_ADAPTER_MPIIO_MPIIO_FS_API_H_ diff --git a/hermes_adapters/posix/fs_api.cc b/hermes_adapters/posix/fs_api.cc deleted file mode 100644 index 7f4aa457c..000000000 --- a/hermes_adapters/posix/fs_api.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Distributed under BSD 3-Clause license. * -* Copyright by The HDF Group. * -* Copyright by the Illinois Institute of Technology. * -* All rights reserved. * -* * -* This file is part of Hermes. The full Hermes copyright notice, including * -* terms governing use, modification, and redistribution, is contained in * -* the COPYING file, which can be found at the top directory. If you do not * -* have access to the file, you may request a copy from help@hdfgroup.org. * -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include "fs_api.h" -#include "real_api.h" - -#include "filesystem/metadata_manager.cc" -#include "filesystem/filesystem.cc" - -namespace hermes::adapter::posix { - -File PosixFS::_RealOpen(AdapterStat &stat, const std::string &path) { - File f; - if (stat.flags & O_CREAT || stat.flags & O_TMPFILE) { - f.fd_ = real_api->open(path.c_str(), stat.flags, stat.st_mode); - } else { - f.fd_ = real_api->open(path.c_str(), stat.flags); - } - if (f.fd_ < 0) { - f.status_ = false; - } - _InitFile(f); - return f; -} - -void PosixFS::_InitFile(File &f) { - struct stat st; - real_api->fstat(f.fd_, &st); - f.st_dev = st.st_dev; - f.st_ino = st.st_ino; -} - -void PosixFS::_OpenInitStats(File &f, AdapterStat &stat) { - struct stat st; - real_api->fstat(f.fd_, &st); - stat.st_mode = st.st_mode; - stat.st_uid = st.st_uid; - stat.st_gid = st.st_gid; - stat.st_size = st.st_size; - stat.st_blksize = st.st_blksize; - stat.st_atim = st.st_atim; - stat.st_mtim = st.st_mtim; - stat.st_ctim = st.st_ctim; - if (stat.flags & O_APPEND) { - stat.is_append = true; - } -} - -size_t PosixFS::_RealWrite(const std::string &filename, off_t offset, - size_t size, const u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) { - (void) opts; (void) io_status; - LOG(INFO) << "Writing to file: " << filename - << " offset: " << offset - << " size:" << size << "." - << " file_size:" << stdfs::file_size(filename) << std::endl; - int fd = real_api->open(filename.c_str(), O_RDWR | O_CREAT); - if (fd < 0) { return 0; } - size_t write_size = real_api->pwrite(fd, data_ptr, size, offset); - real_api->close(fd); - return write_size; -} - -size_t PosixFS::_RealRead(const std::string &filename, off_t offset, - size_t size, u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) { - (void) opts; (void) io_status; - LOG(INFO) << "Read called for filename from destination: " << filename - << " on offset: " << offset - << " and size: " << size << "." - << " file_size:" << stdfs::file_size(filename) << std::endl; - int fd = real_api->open(filename.c_str(), O_RDONLY); - if (fd < 0) { return 0; } - size_t read_size = real_api->pread(fd, data_ptr, size, offset); - real_api->close(fd); - return read_size; -} - -int PosixFS::_RealSync(File &f) { - return real_api->fsync(f.fd_); -} - -int PosixFS::_RealClose(File &f) { - return real_api->close(f.fd_); -} - -} // namespace hermes::adapter::posix diff --git a/hermes_adapters/posix/posix.cc b/hermes_adapters/posix/posix.cc deleted file mode 100644 index fbbbd85b5..000000000 --- a/hermes_adapters/posix/posix.cc +++ /dev/null @@ -1,337 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -// Dynamically checked to see which are the real APIs and which are intercepted -bool posix_intercepted = true; - -#include -#include -#include -#include - -#include "interceptor.cc" - -#include "interceptor.h" -#include "singleton.h" - -#include "posix/real_api.h" -#include "posix/fs_api.h" - -#ifndef O_TMPFILE -#define O_TMPFILE 0 -#endif - -using hermes::adapter::WeaklyCanonical; -using hermes::adapter::posix::API; -using hermes::adapter::posix::PosixFS; -using hermes::Singleton; -using hermes::adapter::fs::MetadataManager; -using hermes::adapter::fs::SeekMode; - -namespace hapi = hermes::api; -namespace stdfs = std::experimental::filesystem; -using hermes::u8; - -extern "C" { - -/** - * MPI - */ -int HERMES_DECL(MPI_Init)(int *argc, char ***argv) { - auto real_api = Singleton::GetInstance(); - int status = real_api->MPI_Init(argc, argv); - if (status == 0) { - LOG(INFO) << "MPI Init intercepted." << std::endl; - auto mdm = hermes::Singleton::GetInstance(); - mdm->InitializeHermes(true); - } - return status; -} - -int HERMES_DECL(MPI_Finalize)(void) { - auto real_api = Singleton::GetInstance(); - LOG(INFO) << "MPI Finalize intercepted." << std::endl; - auto mdm = hermes::Singleton::GetInstance(); - mdm->FinalizeHermes(); - int status = real_api->MPI_Finalize(); - return status; -} - -/** - * POSIX - */ -int HERMES_DECL(open)(const char *path, int flags, ...) { - int mode = 0; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (flags & O_CREAT || flags & O_TMPFILE) { - va_list arg; - va_start(arg, flags); - mode = va_arg(arg, int); - va_end(arg); - } - if (hermes::adapter::IsTracked(path)) { - LOG(INFO) << "Intercept open for filename: " << path - << " and mode: " << flags << " is tracked." << std::endl; - AdapterStat stat; - stat.flags = flags; - stat.st_mode = mode; - return fs_api->Open(stat, path).fd_; - } - if (flags & O_CREAT || flags & O_TMPFILE) { - return real_api->open(path, flags, mode); - } - return real_api->open(path, flags); -} - -int HERMES_DECL(open64)(const char *path, int flags, ...) { - int mode = 0; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (flags & O_CREAT) { - va_list arg; - va_start(arg, flags); - mode = va_arg(arg, int); - va_end(arg); - } - if (hermes::adapter::IsTracked(path)) { - LOG(INFO) << "Intercept open64 for filename: " << path - << " and mode: " << flags << " is tracked." << std::endl; - AdapterStat stat; - stat.flags = flags; - stat.st_mode = mode; - return fs_api->Open(stat, path).fd_; - } - if (flags & O_CREAT) { - return real_api->open64(path, flags, mode); - } - return real_api->open64(path, flags); -} - -int HERMES_DECL(__open_2)(const char *path, int oflag) { - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(path)) { - LOG(INFO) << "Intercept __open_2 for filename: " << path - << " and mode: " << oflag << " is tracked." << std::endl; - AdapterStat stat; - stat.flags = oflag; - stat.st_mode = 0; - return fs_api->Open(stat, path).fd_; - } - return real_api->__open_2(path, oflag); -} - -int HERMES_DECL(creat)(const char *path, mode_t mode) { - std::string path_str(path); - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(path)) { - LOG(INFO) << "Intercept creat for filename: " << path - << " and mode: " << mode << " is tracked." << std::endl; - AdapterStat stat; - stat.flags = O_CREAT; - stat.st_mode = mode; - return fs_api->Open(stat, path).fd_; - } - return real_api->creat(path, mode); -} - -int HERMES_DECL(creat64)(const char *path, mode_t mode) { - std::string path_str(path); - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(path)) { - LOG(INFO) << "Intercept creat64 for filename: " << path - << " and mode: " << mode << " is tracked." << std::endl; - AdapterStat stat; - stat.flags = O_CREAT; - stat.st_mode = mode; - return fs_api->Open(stat, path).fd_; - } - return real_api->creat64(path, mode); -} - -ssize_t HERMES_DECL(read)(int fd, void *buf, size_t count) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - LOG(INFO) << "Intercept read." << std::endl; - File f; f.fd_ = fd; fs_api->_InitFile(f); IoStatus io_status; - size_t ret = fs_api->Read(f, stat_exists, buf, count, io_status); - if (stat_exists) return ret; - } - return real_api->read(fd, buf, count); -} - -ssize_t HERMES_DECL(write)(int fd, const void *buf, size_t count) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - LOG(INFO) << "Intercept write." << std::endl; - File f; f.fd_ = fd; fs_api->_InitFile(f); IoStatus io_status; - size_t ret = fs_api->Write(f, stat_exists, buf, count, io_status); - if (stat_exists) return ret; - } - return real_api->write(fd, buf, count); -} - -ssize_t HERMES_DECL(pread)(int fd, void *buf, size_t count, off_t offset) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - LOG(INFO) << "Intercept pread." << std::endl; - File f; f.fd_ = fd; fs_api->_InitFile(f); IoStatus io_status; - size_t ret = fs_api->Read(f, stat_exists, buf, offset, count, io_status); - if (stat_exists) return ret; - } - return real_api->pread(fd, buf, count, offset); -} - -ssize_t HERMES_DECL(pwrite)(int fd, const void *buf, size_t count, - off_t offset) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); IoStatus io_status; - LOG(INFO) << "Intercept pwrite." << std::endl; - size_t ret = fs_api->Write(f, stat_exists, buf, offset, count, io_status); - if (stat_exists) return ret; - } - return real_api->pwrite(fd, buf, count, offset); -} - -ssize_t HERMES_DECL(pread64)(int fd, void *buf, size_t count, off64_t offset) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); IoStatus io_status; - LOG(INFO) << "Intercept pread64." << std::endl; - size_t ret = fs_api->Read(f, stat_exists, buf, offset, count, io_status); - if (stat_exists) return ret; - } - return real_api->pread64(fd, buf, count, offset); -} - -ssize_t HERMES_DECL(pwrite64)(int fd, const void *buf, size_t count, - off64_t offset) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); IoStatus io_status; - LOG(INFO) << "Intercept pwrite." << std::endl; - size_t ret = fs_api->Write(f, stat_exists, buf, offset, count, io_status); - if (stat_exists) return ret; - } - return real_api->pwrite64(fd, buf, count, offset); -} - -off_t HERMES_DECL(lseek)(int fd, off_t offset, int whence) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); - LOG(INFO) << "Intercept lseek offset:" << offset << " whence:" << whence - << "." << std::endl; - return fs_api->Seek(f, stat_exists, - static_cast(whence), offset); - } - return real_api->lseek(fd, offset, whence); -} - -off64_t HERMES_DECL(lseek64)(int fd, off64_t offset, int whence) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); - LOG(INFO) << "Intercept lseek64 offset:" << offset << " whence:" << whence - << "." << std::endl; - return fs_api->Seek(f, stat_exists, - static_cast(whence), offset); - } - return real_api->lseek64(fd, offset, whence); -} - -int HERMES_DECL(fstat)(int fd, struct stat *buf) { - int result = 0; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); - LOG(INFO) << "Intercepted fstat." << std::endl; - auto mdm = hermes::Singleton::GetInstance(); - auto existing = mdm->Find(f); - if (existing.second) { - AdapterStat &astat = existing.first; - // TODO(chogan): st_dev and st_ino need to be assigned by us, but - // currently we get them by calling the real fstat on open. - buf->st_dev = 0; - buf->st_ino = 0; - buf->st_mode = astat.st_mode; - buf->st_nlink = 0; - buf->st_uid = astat.st_uid; - buf->st_gid = astat.st_gid; - buf->st_rdev = 0; - buf->st_size = astat.st_size; - buf->st_blksize = astat.st_blksize; - buf->st_blocks = 0; - buf->st_atime = astat.st_atime; - buf->st_mtime = astat.st_mtime; - buf->st_ctime = astat.st_ctime; - } else { - result = -1; - errno = EBADF; - LOG(ERROR) << "File with descriptor " << fd - << " does not exist in Hermes\n"; - } - } else { - result = real_api->fstat(fd, buf); - } - return result; -} - -int HERMES_DECL(fsync)(int fd) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - File f; f.fd_ = fd; fs_api->_InitFile(f); - LOG(INFO) << "Intercept fsync." << std::endl; - return fs_api->Sync(f, stat_exists); - } - return real_api->fsync(fd); -} - -int HERMES_DECL(close)(int fd) { - bool stat_exists; - auto real_api = Singleton::GetInstance(); - auto fs_api = Singleton::GetInstance(); - if (hermes::adapter::IsTracked(fd)) { - LOG(INFO) << "Intercept close(" << std::to_string(fd) << ")"; - DLOG(INFO) << " -> " << hermes::adapter::GetFilenameFromFD(fd); - LOG(INFO) << std::endl; - - File f; f.fd_ = fd; fs_api->_InitFile(f); - return fs_api->Close(f, stat_exists); - } - return real_api->close(fd); -} - -} // extern C diff --git a/hermes_adapters/posix/posix_api.h b/hermes_adapters/posix/posix_api.h index af9fe62a6..89a032603 100644 --- a/hermes_adapters/posix/posix_api.h +++ b/hermes_adapters/posix/posix_api.h @@ -12,16 +12,14 @@ #ifndef HERMES_ADAPTER_POSIX_H #define HERMES_ADAPTER_POSIX_H -#include -#include +#include +#include +#include "hermes_shm/util/logging.h" #include +#include #include - -#include -#include - +#include #include "hermes_adapters/real_api.h" -#include "hermes_shm/util/logging.h" #ifndef O_TMPFILE #define O_TMPFILE 0 @@ -32,43 +30,41 @@ #endif extern "C" { -typedef int (*open_t)(const char *path, int flags, ...); -typedef int (*open64_t)(const char *path, int flags, ...); -typedef int (*__open_2_t)(const char *path, int oflag); -typedef int (*creat_t)(const char *path, mode_t mode); -typedef int (*creat64_t)(const char *path, mode_t mode); -typedef ssize_t (*read_t)(int fd, void *buf, size_t count); -typedef ssize_t (*write_t)(int fd, const void *buf, size_t count); -typedef ssize_t (*pread_t)(int fd, void *buf, size_t count, off_t offset); -typedef ssize_t (*pwrite_t)(int fd, const void *buf, size_t count, - off_t offset); -typedef ssize_t (*pread64_t)(int fd, void *buf, size_t count, off64_t offset); -typedef ssize_t (*pwrite64_t)(int fd, const void *buf, size_t count, - off64_t offset); +typedef int (*open_t)(const char * path, int flags, ...); +typedef int (*open64_t)(const char * path, int flags, ...); +typedef int (*__open_2_t)(const char * path, int oflag); +typedef int (*creat_t)(const char * path, mode_t mode); +typedef int (*creat64_t)(const char * path, mode_t mode); +typedef ssize_t (*read_t)(int fd, void * buf, size_t count); +typedef ssize_t (*write_t)(int fd, const void * buf, size_t count); +typedef ssize_t (*pread_t)(int fd, void * buf, size_t count, off_t offset); +typedef ssize_t (*pwrite_t)(int fd, const void * buf, size_t count, off_t offset); +typedef ssize_t (*pread64_t)(int fd, void * buf, size_t count, off64_t offset); +typedef ssize_t (*pwrite64_t)(int fd, const void * buf, size_t count, off64_t offset); typedef off_t (*lseek_t)(int fd, off_t offset, int whence); typedef off64_t (*lseek64_t)(int fd, off64_t offset, int whence); // stat functions -typedef int (*__fxstat_t)(int __ver, int __filedesc, struct stat *__stat_buf); +typedef int (*__fxstat_t)(int __ver, int __filedesc, struct stat * __stat_buf); typedef int (*__xstat_t)(int __ver, const char *__filename, struct stat *__stat_buf); typedef int (*__lxstat_t)(int __ver, const char *__filename, struct stat *__stat_buf); typedef int (*__fxstatat_t)(int __ver, int __fildes, const char *__filename, struct stat *__stat_buf, int __flag); -typedef int (*stat_t)(const char *pathname, struct stat *__stat_buf); -typedef int (*fstat_t)(int __filedesc, struct stat *__stat_buf); +typedef int (*stat_t)(const char * pathname, struct stat * __stat_buf); +typedef int (*fstat_t)(int __filedesc, struct stat * __stat_buf); // fxstat functions typedef int (*__fxstat64_t)(int __ver, int __fildes, struct stat64 *__stat_buf); typedef int (*__xstat64_t)(int __ver, const char *__filename, - struct stat64 *__stat_buf); + struct stat64 *__stat_buf); typedef int (*__lxstat64_t)(int __ver, const char *__filename, - struct stat64 *__stat_buf); + struct stat64 *__stat_buf); typedef int (*__fxstatat64_t)(int __ver, int __fildes, const char *__filename, - struct stat64 *__stat_buf, int __flag); -typedef int (*stat64_t)(const char *pathname, struct stat64 *__stat_buf); -typedef int (*fstat64_t)(int __filedesc, struct stat64 *__stat_buf); + struct stat64 *__stat_buf, int __flag); +typedef int (*stat64_t)(const char * pathname, struct stat64 * __stat_buf); +typedef int (*fstat64_t)(int __filedesc, struct stat64 * __stat_buf); typedef int (*fsync_t)(int fd); typedef int (*close_t)(int fd); @@ -77,16 +73,17 @@ typedef int (*fchdir_t)(int fd); typedef int (*fchmod_t)(int fd, mode_t mode); typedef int (*fchmod_t)(int fd, mode_t mode); typedef int (*fchown_t)(int fd, uid_t owner, gid_t group); -typedef int (*fchownat_t)(int dirfd, const char *pathname, uid_t owner, - gid_t group, int flags); +typedef int (*fchownat_t)(int dirfd, const char *pathname, + uid_t owner, gid_t group, int flags); typedef int (*close_range_t)(unsigned int first, unsigned int last, unsigned int flags); -typedef ssize_t (*copy_file_range_t)(int fd_in, off64_t *off_in, int fd_out, - off64_t *off_out, size_t len, - unsigned int flags); +typedef ssize_t (*copy_file_range_t)(int fd_in, off64_t *off_in, + int fd_out, off64_t *off_out, + size_t len, unsigned int flags); // TODO(llogan): fadvise -typedef int (*posix_fadvise_t)(int fd, off_t offset, off_t len, int advice); +typedef int (*posix_fadvise_t)(int fd, off_t offset, + off_t len, int advice); typedef int (*flock_t)(int fd, int operation); typedef int (*remove_t)(const char *pathname); typedef int (*unlink_t)(const char *pathname); @@ -95,7 +92,7 @@ typedef int (*unlink_t)(const char *pathname); namespace hermes::adapter { /** Used for compatability with older kernel versions */ -static int fxstat_to_fstat(int fd, struct stat *stbuf); +static int fxstat_to_fstat(int fd, struct stat * stbuf); /** Pointers to the real posix API */ class PosixApi : public RealApi { @@ -246,7 +243,8 @@ class PosixApi : public RealApi { #define HERMES_POSIX_API \ hshm::EasySingleton<::hermes::adapter::PosixApi>::GetInstance() -#define HERMES_POSIX_API_T hermes::adapter::PosixApi * +#define HERMES_POSIX_API_T hermes::adapter::PosixApi* + namespace hermes::adapter { /** Used for compatability with older kernel versions */ diff --git a/hermes_adapters/posix/posix_fs_api.h b/hermes_adapters/posix/posix_fs_api.h index 3a887be66..89f20d1db 100644 --- a/hermes_adapters/posix/posix_fs_api.h +++ b/hermes_adapters/posix/posix_fs_api.h @@ -25,11 +25,13 @@ namespace hermes::adapter { class PosixFs : public hermes::adapter::Filesystem { public: HERMES_POSIX_API_T real_api_; /**< pointer to real APIs */ - + public: - PosixFs() : Filesystem(AdapterType::kPosix) { real_api_ = HERMES_POSIX_API; } + PosixFs() : Filesystem(AdapterType::kPosix) { + real_api_ = HERMES_POSIX_API; + } - template + template int Stat(File &f, StatT *buf) { auto mdm = HERMES_FS_METADATA_MANAGER; auto existing = mdm->Find(f); @@ -59,7 +61,7 @@ class PosixFs : public hermes::adapter::Filesystem { } } - template + template int Stat(const char *__filename, StatT *buf) { bool stat_exists; AdapterStat stat; @@ -101,10 +103,12 @@ class PosixFs : public hermes::adapter::Filesystem { size_t r = readlink(proclnk.data(), filename.data(), kMaxPathLen); return std::string(filename.data(), r); } - + public: /** Allocate an fd for the file f */ - void RealOpen(File &f, AdapterStat &stat, const std::string &path) override { + void RealOpen(File &f, + AdapterStat &stat, + const std::string &path) override { if (stat.flags_ & O_APPEND) { stat.hflags_.SetBits(HERMES_FS_APPEND); } @@ -137,24 +141,29 @@ class PosixFs : public hermes::adapter::Filesystem { * and hermes file handler. These are not the same as POSIX file * descriptor and STDIO file handler. * */ - void HermesOpen(File &f, const AdapterStat &stat, + void HermesOpen(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) override { f.hermes_fd_ = fs_mdm.mdm_->AllocateFd(); } /** Synchronize \a file FILE f */ - int RealSync(const File &f, const AdapterStat &stat) override { - (void)f; - if (stat.adapter_mode_ == AdapterMode::kScratch && stat.fd_ == -1) { + int RealSync(const File &f, + const AdapterStat &stat) override { + (void) f; + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fd_ == -1) { return 0; } return real_api_->fsync(stat.fd_); } /** Close \a file FILE f */ - int RealClose(const File &f, AdapterStat &stat) override { - (void)f; - if (stat.adapter_mode_ == AdapterMode::kScratch && stat.fd_ == -1) { + int RealClose(const File &f, + AdapterStat &stat) override { + (void) f; + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fd_ == -1) { return 0; } return real_api_->close(stat.fd_); @@ -164,7 +173,8 @@ class PosixFs : public hermes::adapter::Filesystem { * Called before RealClose. Releases information provisioned during * the allocation phase. * */ - void HermesClose(File &f, const AdapterStat &stat, + void HermesClose(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) override { fs_mdm.mdm_->ReleaseFd(f.hermes_fd_); } @@ -179,27 +189,27 @@ class PosixFs : public hermes::adapter::Filesystem { size_t true_size = 0; std::string filename = bkt_name.str(); int fd = real_api_->open(filename.c_str(), O_RDONLY); - if (fd < 0) { - return 0; - } + if (fd < 0) { return 0; } struct stat buf; real_api_->fstat(fd, &buf); true_size = buf.st_size; real_api_->close(fd); - HILOG(kDebug, "The size of the file {} on disk is {}", filename, true_size) + HILOG(kDebug, "The size of the file {} on disk is {}", + filename, true_size) return true_size; } /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override { - (void)opts; + void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + (void) opts; status.success_ = true; - HILOG(kDebug, - "Writing to file: {}" - " offset: {}" - " size: {}", + HILOG(kDebug, "Writing to file: {}" + " offset: {}" + " size: {}", bkt_name, opts.backend_off_, full_blob.size()) int fd = real_api_->open(bkt_name.c_str(), O_RDWR | O_CREAT); if (fd < 0) { @@ -207,8 +217,10 @@ class PosixFs : public hermes::adapter::Filesystem { status.success_ = false; return; } - status.size_ = real_api_->pwrite(fd, full_blob.data(), full_blob.size(), - opts.backend_off_); + status.size_ = real_api_->pwrite(fd, + full_blob.data(), + full_blob.size(), + opts.backend_off_); if (status.size_ != full_blob.size()) { status.success_ = false; } @@ -216,14 +228,15 @@ class PosixFs : public hermes::adapter::Filesystem { } /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override { - (void)opts; + void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + (void) opts; status.success_ = true; - HILOG(kDebug, - "Reading from file: {}" - " offset: {}" - " size: {}", + HILOG(kDebug, "Reading from file: {}" + " offset: {}" + " size: {}", bkt_name, opts.backend_off_, full_blob.size()) int fd = real_api_->open(bkt_name.c_str(), O_RDONLY); if (fd < 0) { @@ -231,8 +244,10 @@ class PosixFs : public hermes::adapter::Filesystem { status.success_ = false; return; } - status.size_ = real_api_->pread(fd, full_blob.data(), full_blob.size(), - opts.backend_off_); + status.size_ = real_api_->pread(fd, + full_blob.data(), + full_blob.size(), + opts.backend_off_); if (status.size_ != full_blob.size()) { status.success_ = false; } @@ -240,15 +255,15 @@ class PosixFs : public hermes::adapter::Filesystem { } void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) override { - (void)opts; - (void)status; + (void) opts; + (void) status; } }; /** Simplify access to the stateless PosixFs Singleton */ #define HERMES_POSIX_FS \ hshm::EasySingleton<::hermes::adapter::PosixFs>::GetInstance() -#define HERMES_POSIX_FS_T hermes::adapter::PosixFs * +#define HERMES_POSIX_FS_T hermes::adapter::PosixFs* } // namespace hermes::adapter diff --git a/hermes_adapters/posix/real_api.h b/hermes_adapters/posix/real_api.h deleted file mode 100644 index 5982ca545..000000000 --- a/hermes_adapters/posix/real_api.h +++ /dev/null @@ -1,218 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_POSIX_H -#define HERMES_ADAPTER_POSIX_H -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "filesystem/filesystem.h" -#include "filesystem/metadata_manager.h" -#include "interceptor.h" - -#define REQUIRE_API(api_name) \ - if (api_name == nullptr) { \ - LOG(FATAL) << "HERMES Adapter failed to map symbol: " #api_name \ - << std::endl; \ - std::exit(1); \ - } - -extern "C" { -typedef int (*MPI_Init_t)(int *argc, char ***argv); -typedef int (*MPI_Finalize_t)(void); -typedef int (*open_t)(const char *path, int flags, ...); -typedef int (*open64_t)(const char *path, int flags, ...); -typedef int (*__open_2_t)(const char *path, int oflag); -typedef int (*creat_t)(const char *path, mode_t mode); -typedef int (*creat64_t)(const char *path, mode_t mode); -typedef ssize_t (*read_t)(int fd, void *buf, size_t count); -typedef ssize_t (*write_t)(int fd, const void *buf, size_t count); -typedef ssize_t (*pread_t)(int fd, void *buf, size_t count, off_t offset); -typedef ssize_t (*pwrite_t)(int fd, const void *buf, size_t count, - off_t offset); -typedef ssize_t (*pread64_t)(int fd, void *buf, size_t count, off64_t offset); -typedef ssize_t (*pwrite64_t)(int fd, const void *buf, size_t count, - off64_t offset); -typedef off_t (*lseek_t)(int fd, off_t offset, int whence); -typedef off64_t (*lseek64_t)(int fd, off64_t offset, int whence); -typedef int (*fstat_t)(int __filedesc, struct stat *__stat_buf); -typedef int (*fsync_t)(int fd); -typedef int (*close_t)(int fd); -} - -namespace hermes::adapter::posix { - -/** Pointers to the real posix API */ -class API { - public: - /** MPI_Init */ - MPI_Init_t MPI_Init = nullptr; - /** MPI_Finalize */ - MPI_Finalize_t MPI_Finalize = nullptr; - /** open */ - open_t open = nullptr; - /** open64 */ - open64_t open64 = nullptr; - /** __open_2 */ - __open_2_t __open_2 = nullptr; - /** creat */ - creat_t creat = nullptr; - /** creat64 */ - creat64_t creat64 = nullptr; - /** read */ - read_t read = nullptr; - /** write */ - write_t write = nullptr; - /** pread */ - pread_t pread = nullptr; - /** pwrite */ - pwrite_t pwrite = nullptr; - /** pread64 */ - pread64_t pread64 = nullptr; - /** pwrite64 */ - pwrite64_t pwrite64 = nullptr; - /** lseek */ - lseek_t lseek = nullptr; - /** lseek64 */ - lseek64_t lseek64 = nullptr; - /** fstat */ - fstat_t fstat = nullptr; - /** fsync */ - fsync_t fsync = nullptr; - /** close */ - close_t close = nullptr; - - /** API constructor that intercepts POSIX API calls */ - API() { - void *is_intercepted = (void *)dlsym(RTLD_DEFAULT, "posix_intercepted"); - if (is_intercepted) { - MPI_Init = (MPI_Init_t)dlsym(RTLD_NEXT, "MPI_Init"); - } else { - MPI_Init = (MPI_Init_t)dlsym(RTLD_DEFAULT, "MPI_Init"); - } - REQUIRE_API(MPI_Init) - if (is_intercepted) { - MPI_Finalize = (MPI_Finalize_t)dlsym(RTLD_NEXT, "MPI_Finalize"); - } else { - MPI_Finalize = (MPI_Finalize_t)dlsym(RTLD_DEFAULT, "MPI_Finalize"); - } - REQUIRE_API(MPI_Finalize) - if (is_intercepted) { - open = (open_t)dlsym(RTLD_NEXT, "open"); - } else { - open = (open_t)dlsym(RTLD_DEFAULT, "open"); - } - REQUIRE_API(open) - if (is_intercepted) { - open64 = (open64_t)dlsym(RTLD_NEXT, "open64"); - } else { - open64 = (open64_t)dlsym(RTLD_DEFAULT, "open64"); - } - REQUIRE_API(open64) - if (is_intercepted) { - __open_2 = (__open_2_t)dlsym(RTLD_NEXT, "__open_2"); - } else { - __open_2 = (__open_2_t)dlsym(RTLD_DEFAULT, "__open_2"); - } - REQUIRE_API(__open_2) - if (is_intercepted) { - creat = (creat_t)dlsym(RTLD_NEXT, "creat"); - } else { - creat = (creat_t)dlsym(RTLD_DEFAULT, "creat"); - } - REQUIRE_API(creat) - if (is_intercepted) { - creat64 = (creat64_t)dlsym(RTLD_NEXT, "creat64"); - } else { - creat64 = (creat64_t)dlsym(RTLD_DEFAULT, "creat64"); - } - REQUIRE_API(creat64) - if (is_intercepted) { - read = (read_t)dlsym(RTLD_NEXT, "read"); - } else { - read = (read_t)dlsym(RTLD_DEFAULT, "read"); - } - REQUIRE_API(read) - if (is_intercepted) { - write = (write_t)dlsym(RTLD_NEXT, "write"); - } else { - write = (write_t)dlsym(RTLD_DEFAULT, "write"); - } - REQUIRE_API(write) - if (is_intercepted) { - pread = (pread_t)dlsym(RTLD_NEXT, "pread"); - } else { - pread = (pread_t)dlsym(RTLD_DEFAULT, "pread"); - } - REQUIRE_API(pread) - if (is_intercepted) { - pwrite = (pwrite_t)dlsym(RTLD_NEXT, "pwrite"); - } else { - pwrite = (pwrite_t)dlsym(RTLD_DEFAULT, "pwrite"); - } - REQUIRE_API(pwrite) - if (is_intercepted) { - pread64 = (pread64_t)dlsym(RTLD_NEXT, "pread64"); - } else { - pread64 = (pread64_t)dlsym(RTLD_DEFAULT, "pread64"); - } - REQUIRE_API(pread64) - if (is_intercepted) { - pwrite64 = (pwrite64_t)dlsym(RTLD_NEXT, "pwrite64"); - } else { - pwrite64 = (pwrite64_t)dlsym(RTLD_DEFAULT, "pwrite64"); - } - REQUIRE_API(pwrite64) - if (is_intercepted) { - lseek = (lseek_t)dlsym(RTLD_NEXT, "lseek"); - } else { - lseek = (lseek_t)dlsym(RTLD_DEFAULT, "lseek"); - } - REQUIRE_API(lseek) - if (is_intercepted) { - lseek64 = (lseek64_t)dlsym(RTLD_NEXT, "lseek64"); - } else { - lseek64 = (lseek64_t)dlsym(RTLD_DEFAULT, "lseek64"); - } - REQUIRE_API(lseek64) - if (is_intercepted) { - fstat = (fstat_t)dlsym(RTLD_NEXT, "fstat"); - } else { - fstat = (fstat_t)dlsym(RTLD_DEFAULT, "fstat"); - } - REQUIRE_API(fstat) - if (is_intercepted) { - fsync = (fsync_t)dlsym(RTLD_NEXT, "fsync"); - } else { - fsync = (fsync_t)dlsym(RTLD_DEFAULT, "fsync"); - } - REQUIRE_API(fsync) - if (is_intercepted) { - close = (close_t)dlsym(RTLD_NEXT, "close"); - } else { - close = (close_t)dlsym(RTLD_DEFAULT, "close"); - } - REQUIRE_API(close) - } -}; -} // namespace hermes::adapter::posix - -#undef REQUIRE_API - -#endif // HERMES_ADAPTER_POSIX_H diff --git a/hermes_adapters/real_api.h b/hermes_adapters/real_api.h index 524c7f914..6146348cb 100644 --- a/hermes_adapters/real_api.h +++ b/hermes_adapters/real_api.h @@ -1,14 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +* Distributed under BSD 3-Clause license. * +* Copyright by The HDF Group. * +* Copyright by the Illinois Institute of Technology. * +* All rights reserved. * +* * +* This file is part of Hermes. The full Hermes copyright notice, including * +* terms governing use, modification, and redistribution, is contained in * +* the COPYING file, which can be found at the top directory. If you do not * +* have access to the file, you may request a copy from help@hdfgroup.org. * +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HERMES_ADAPTER_API_H #define HERMES_ADAPTER_API_H @@ -20,12 +20,13 @@ // #include #include + namespace stdfs = std::filesystem; #define HERMES_DECL(F) F -#define REQUIRE_API(api_name) \ - if (!(api_name)) { \ +#define REQUIRE_API(api_name) \ + if (!(api_name)) { \ HELOG(kFatal, "HERMES Adapter failed to map symbol: {}", #api_name); \ } @@ -37,8 +38,7 @@ struct RealApiIter { const char *lib_path_; RealApiIter(const char *symbol_name, const char *is_intercepted) - : symbol_name_(symbol_name), - is_intercepted_(is_intercepted), + : symbol_name_(symbol_name), is_intercepted_(is_intercepted), lib_path_(nullptr) {} }; @@ -47,24 +47,27 @@ struct RealApi { bool is_intercepted_; static int callback(struct dl_phdr_info *info, size_t size, void *data) { - auto iter = (RealApiIter *)data; + auto iter = (RealApiIter*)data; auto lib = dlopen(info->dlpi_name, RTLD_GLOBAL | RTLD_NOW); // auto lib = dlopen(info->dlpi_name, RTLD_NOLOAD | RTLD_NOW); auto exists = dlsym(lib, iter->symbol_name_); - void *is_intercepted = (void *)dlsym(lib, iter->is_intercepted_); + void *is_intercepted = + (void*)dlsym(lib, iter->is_intercepted_); if (!is_intercepted && exists && !iter->lib_path_) { iter->lib_path_ = info->dlpi_name; } return 0; } - RealApi(const char *symbol_name, const char *is_intercepted) { + RealApi(const char *symbol_name, + const char *is_intercepted) { RealApiIter iter(symbol_name, is_intercepted); - dl_iterate_phdr(callback, (void *)&iter); + dl_iterate_phdr(callback, (void*)&iter); if (iter.lib_path_) { real_lib_ = dlopen(iter.lib_path_, RTLD_GLOBAL | RTLD_NOW); } - void *is_intercepted_ptr = (void *)dlsym(RTLD_DEFAULT, is_intercepted); + void *is_intercepted_ptr = (void*)dlsym(RTLD_DEFAULT, + is_intercepted); is_intercepted_ = is_intercepted_ptr != nullptr; /* if (is_intercepted_) { real_lib_ = RTLD_NEXT; @@ -74,7 +77,7 @@ struct RealApi { } }; -template +template struct InterceptorApi { PosixT *posix_; std::string lib_path_; @@ -83,11 +86,12 @@ struct InterceptorApi { Elf *lib_elf_ = nullptr; static int callback(struct dl_phdr_info *info, size_t size, void *data) { - auto iter = (RealApiIter *)data; + auto iter = (RealApiIter*)data; auto lib = dlopen(info->dlpi_name, RTLD_GLOBAL | RTLD_NOW); // auto lib = dlopen(info->dlpi_name, RTLD_NOLOAD | RTLD_NOW); auto exists = dlsym(lib, iter->symbol_name_); - void *is_intercepted = (void *)dlsym(lib, iter->is_intercepted_); + void *is_intercepted = + (void*)dlsym(lib, iter->is_intercepted_); if (is_intercepted && exists && !iter->lib_path_) { iter->lib_path_ = info->dlpi_name; if (iter->lib_path_ == nullptr || strlen(iter->lib_path_) == 0) { @@ -173,13 +177,13 @@ struct InterceptorApi { } } - InterceptorApi(const char *symbol_name, const char *is_intercepted) - : is_loaded_(false) { + InterceptorApi(const char *symbol_name, + const char *is_intercepted) : is_loaded_(false) { is_loaded_ = true; return; posix_ = hshm::EasySingleton::GetInstance(); RealApiIter iter(symbol_name, is_intercepted); - dl_iterate_phdr(callback, (void *)&iter); + dl_iterate_phdr(callback, (void*)&iter); if (iter.lib_path_) { lib_path_ = iter.lib_path_; is_loaded_ = IsLoaded(iter.lib_path_); diff --git a/hermes_adapters/stdio/fs_api.cc b/hermes_adapters/stdio/fs_api.cc deleted file mode 100644 index 09c0462b4..000000000 --- a/hermes_adapters/stdio/fs_api.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* Distributed under BSD 3-Clause license. * -* Copyright by The HDF Group. * -* Copyright by the Illinois Institute of Technology. * -* All rights reserved. * -* * -* This file is part of Hermes. The full Hermes copyright notice, including * -* terms governing use, modification, and redistribution, is contained in * -* the COPYING file, which can be found at the top directory. If you do not * -* have access to the file, you may request a copy from help@hdfgroup.org. * -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include "real_api.h" -#include "fs_api.h" -#include - -namespace hermes::adapter::stdio { - -File StdioFS::_RealOpen(AdapterStat &stat, const std::string &path) { - File f; - f.fh_ = real_api->fopen(path.c_str(), stat.mode_str.c_str()); - if (f.fh_ == nullptr) { - f.status_ = false; - } - _InitFile(f); - return f; -} - -void StdioFS::_InitFile(File &f) { - struct stat st; - if (f.fh_ == nullptr) { - f.fd_ = -1; - return; - } - f.fd_ = fileno(f.fh_); - posix_api->fstat(f.fd_, &st); - f.st_dev = st.st_dev; - f.st_ino = st.st_ino; -} - -void StdioFS::_OpenInitStats(File &f, AdapterStat &stat) { - struct stat st; - posix_api->fstat(f.fd_, &st); - stat.st_mode = st.st_mode; - stat.st_uid = st.st_uid; - stat.st_gid = st.st_gid; - stat.st_size = st.st_size; - stat.st_blksize = st.st_blksize; - stat.st_atim = st.st_atim; - stat.st_mtim = st.st_mtim; - stat.st_ctim = st.st_ctim; - if (stat.mode_str.find('a') != std::string::npos) { - stat.is_append = true; - } -} - -size_t StdioFS::_RealWrite(const std::string &filename, off_t offset, - size_t size, const u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) { - (void) opts; (void) io_status; - LOG(INFO) << "Writing to file: " << filename - << " offset: " << offset - << " size:" << size << "." - << " file_size:" << stdfs::file_size(filename) << std::endl; - FILE *fh = real_api->fopen(filename.c_str(), "r+"); - if (fh == nullptr) { return 0; } - real_api->fseek(fh, offset, SEEK_SET); - flock(fileno(fh), LOCK_EX); - size_t write_size = real_api->fwrite(data_ptr, sizeof(char), size, fh); - flock(fileno(fh), LOCK_UN); - real_api->fclose(fh); - return write_size; -} - -size_t StdioFS::_RealRead(const std::string &filename, off_t offset, - size_t size, u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) { - (void) opts; (void) io_status; - LOG(INFO) << "Read called for filename from destination: " << filename - << " on offset: " << offset - << " and size: " << size << "." - << " file_size:" << stdfs::file_size(filename) << std::endl; - FILE *fh = real_api->fopen(filename.c_str(), "r"); - if (fh == nullptr) { return 0; } - real_api->fseek(fh, offset, SEEK_SET); - flock(fileno(fh), LOCK_SH); - size_t read_size = real_api->fread(data_ptr, sizeof(char), size, fh); - flock(fileno(fh), LOCK_UN); - real_api->fclose(fh); - return read_size; -} - -int StdioFS::_RealSync(File &f) { - return real_api->fflush(f.fh_); -} - -int StdioFS::_RealClose(File &f) { - return real_api->fclose(f.fh_); -} - -} // namespace hermes::adapter::stdio diff --git a/hermes_adapters/stdio/real_api.h b/hermes_adapters/stdio/real_api.h deleted file mode 100644 index bcfed421b..000000000 --- a/hermes_adapters/stdio/real_api.h +++ /dev/null @@ -1,304 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_STDIO_H -#define HERMES_ADAPTER_STDIO_H -#include -#include - -#include -#include -#include - -#include "filesystem/filesystem.h" -#include "filesystem/metadata_manager.h" -#include "interceptor.h" - -#define REQUIRE_API(api_name) \ - if (api_name == nullptr) { \ - LOG(FATAL) << "HERMES Adapter failed to map symbol: " #api_name \ - << std::endl; \ - std::exit(1); \ - } - -extern "C" { -typedef int (*MPI_Init_t)(int *argc, char ***argv); -typedef int (*MPI_Finalize_t)(void); -typedef FILE *(*fopen_t)(const char *path, const char *mode); -typedef FILE *(*fopen64_t)(const char *path, const char *mode); -typedef FILE *(*fdopen_t)(int fd, const char *mode); -typedef FILE *(*freopen_t)(const char *path, const char *mode, FILE *stream); -typedef FILE *(*freopen64_t)(const char *path, const char *mode, FILE *stream); -typedef int (*fflush_t)(FILE *fp); -typedef int (*fclose_t)(FILE *fp); -typedef size_t (*fwrite_t)(const void *ptr, size_t size, size_t nmemb, - FILE *fp); -typedef int (*fputc_t)(int c, FILE *fp); -typedef int (*fgetpos_t)(FILE *fp, fpos_t *pos); -typedef int (*fgetpos64_t)(FILE *fp, fpos64_t *pos); -typedef int (*putc_t)(int c, FILE *fp); -typedef int (*putw_t)(int w, FILE *fp); -typedef int (*fputs_t)(const char *s, FILE *stream); -typedef size_t (*fread_t)(void *ptr, size_t size, size_t nmemb, FILE *stream); -typedef int (*fgetc_t)(FILE *stream); -typedef int (*getc_t)(FILE *stream); -typedef int (*getw_t)(FILE *stream); -typedef char *(*fgets_t)(char *s, int size, FILE *stream); -typedef void (*rewind_t)(FILE *stream); -typedef int (*fseek_t)(FILE *stream, long offset, int whence); -typedef int (*fseeko_t)(FILE *stream, off_t offset, int whence); -typedef int (*fseeko64_t)(FILE *stream, off64_t offset, int whence); -typedef int (*fsetpos_t)(FILE *stream, const fpos_t *pos); -typedef int (*fsetpos64_t)(FILE *stream, const fpos64_t *pos); -typedef long int (*ftell_t)(FILE *fp); -} - -namespace hermes::adapter::stdio { - -/** Pointers to the real stdio API */ -class API { - public: - /** MPI_Init */ - MPI_Init_t MPI_Init = nullptr; - /** MPI_Finalize */ - MPI_Finalize_t MPI_Finalize = nullptr; - /** fopen */ - fopen_t fopen = nullptr; - /** fopen64 */ - fopen64_t fopen64 = nullptr; - /** fdopen */ - fdopen_t fdopen = nullptr; - /** freopen */ - freopen_t freopen = nullptr; - /** freopen64 */ - freopen64_t freopen64 = nullptr; - /** fflush */ - fflush_t fflush = nullptr; - /** fclose */ - fclose_t fclose = nullptr; - /** fwrite */ - fwrite_t fwrite = nullptr; - /** fputc */ - fputc_t fputc = nullptr; - /** fgetpos */ - fgetpos_t fgetpos = nullptr; - /** fgetpos64 */ - fgetpos64_t fgetpos64 = nullptr; - /** putc */ - putc_t putc = nullptr; - /** putw */ - putw_t putw = nullptr; - /** fputs */ - fputs_t fputs = nullptr; - /** fread */ - fread_t fread = nullptr; - /** fgetc */ - fgetc_t fgetc = nullptr; - /** getc */ - getc_t getc = nullptr; - /** getw */ - getw_t getw = nullptr; - /** fgets */ - fgets_t fgets = nullptr; - /** rewind */ - rewind_t rewind = nullptr; - /** fseek */ - fseek_t fseek = nullptr; - /** fseeko */ - fseeko_t fseeko = nullptr; - /** fseeko64 */ - fseeko64_t fseeko64 = nullptr; - /** fsetpos */ - fsetpos_t fsetpos = nullptr; - /** fsetpos64 */ - fsetpos64_t fsetpos64 = nullptr; - /** ftell */ - ftell_t ftell = nullptr; - - /** API constructor that intercepts STDIO API calls */ - API() { - void *is_intercepted = (void *)dlsym(RTLD_DEFAULT, "stdio_intercepted"); - if (is_intercepted) { - MPI_Init = (MPI_Init_t)dlsym(RTLD_NEXT, "MPI_Init"); - } else { - MPI_Init = (MPI_Init_t)dlsym(RTLD_DEFAULT, "MPI_Init"); - } - REQUIRE_API(MPI_Init) - if (is_intercepted) { - MPI_Finalize = (MPI_Finalize_t)dlsym(RTLD_NEXT, "MPI_Finalize"); - } else { - MPI_Finalize = (MPI_Finalize_t)dlsym(RTLD_DEFAULT, "MPI_Finalize"); - } - REQUIRE_API(MPI_Finalize) - if (is_intercepted) { - fopen = (fopen_t)dlsym(RTLD_NEXT, "fopen"); - } else { - fopen = (fopen_t)dlsym(RTLD_DEFAULT, "fopen"); - } - REQUIRE_API(fopen) - if (is_intercepted) { - fopen64 = (fopen64_t)dlsym(RTLD_NEXT, "fopen64"); - } else { - fopen64 = (fopen64_t)dlsym(RTLD_DEFAULT, "fopen64"); - } - REQUIRE_API(fopen64) - if (is_intercepted) { - fdopen = (fdopen_t)dlsym(RTLD_NEXT, "fdopen"); - } else { - fdopen = (fdopen_t)dlsym(RTLD_DEFAULT, "fdopen"); - } - REQUIRE_API(fdopen) - if (is_intercepted) { - freopen = (freopen_t)dlsym(RTLD_NEXT, "freopen"); - } else { - freopen = (freopen_t)dlsym(RTLD_DEFAULT, "freopen"); - } - REQUIRE_API(freopen) - if (is_intercepted) { - freopen64 = (freopen64_t)dlsym(RTLD_NEXT, "freopen64"); - } else { - freopen64 = (freopen64_t)dlsym(RTLD_DEFAULT, "freopen64"); - } - REQUIRE_API(freopen64) - if (is_intercepted) { - fflush = (fflush_t)dlsym(RTLD_NEXT, "fflush"); - } else { - fflush = (fflush_t)dlsym(RTLD_DEFAULT, "fflush"); - } - REQUIRE_API(fflush) - if (is_intercepted) { - fclose = (fclose_t)dlsym(RTLD_NEXT, "fclose"); - } else { - fclose = (fclose_t)dlsym(RTLD_DEFAULT, "fclose"); - } - REQUIRE_API(fclose) - if (is_intercepted) { - fwrite = (fwrite_t)dlsym(RTLD_NEXT, "fwrite"); - } else { - fwrite = (fwrite_t)dlsym(RTLD_DEFAULT, "fwrite"); - } - REQUIRE_API(fwrite) - if (is_intercepted) { - fputc = (fputc_t)dlsym(RTLD_NEXT, "fputc"); - } else { - fputc = (fputc_t)dlsym(RTLD_DEFAULT, "fputc"); - } - REQUIRE_API(fputc) - if (is_intercepted) { - fgetpos = (fgetpos_t)dlsym(RTLD_NEXT, "fgetpos"); - } else { - fgetpos = (fgetpos_t)dlsym(RTLD_DEFAULT, "fgetpos"); - } - REQUIRE_API(fgetpos) - if (is_intercepted) { - fgetpos64 = (fgetpos64_t)dlsym(RTLD_NEXT, "fgetpos64"); - } else { - fgetpos64 = (fgetpos64_t)dlsym(RTLD_DEFAULT, "fgetpos64"); - } - REQUIRE_API(fgetpos64) - if (is_intercepted) { - putc = (putc_t)dlsym(RTLD_NEXT, "putc"); - } else { - putc = (putc_t)dlsym(RTLD_DEFAULT, "putc"); - } - REQUIRE_API(putc) - if (is_intercepted) { - putw = (putw_t)dlsym(RTLD_NEXT, "putw"); - } else { - putw = (putw_t)dlsym(RTLD_DEFAULT, "putw"); - } - REQUIRE_API(putw) - if (is_intercepted) { - fputs = (fputs_t)dlsym(RTLD_NEXT, "fputs"); - } else { - fputs = (fputs_t)dlsym(RTLD_DEFAULT, "fputs"); - } - REQUIRE_API(fputs) - if (is_intercepted) { - fread = (fread_t)dlsym(RTLD_NEXT, "fread"); - } else { - fread = (fread_t)dlsym(RTLD_DEFAULT, "fread"); - } - REQUIRE_API(fread) - if (is_intercepted) { - fgetc = (fgetc_t)dlsym(RTLD_NEXT, "fgetc"); - } else { - fgetc = (fgetc_t)dlsym(RTLD_DEFAULT, "fgetc"); - } - REQUIRE_API(fgetc) - if (is_intercepted) { - getc = (getc_t)dlsym(RTLD_NEXT, "getc"); - } else { - getc = (getc_t)dlsym(RTLD_DEFAULT, "getc"); - } - REQUIRE_API(getc) - if (is_intercepted) { - getw = (getw_t)dlsym(RTLD_NEXT, "getw"); - } else { - getw = (getw_t)dlsym(RTLD_DEFAULT, "getw"); - } - REQUIRE_API(getw) - if (is_intercepted) { - fgets = (fgets_t)dlsym(RTLD_NEXT, "fgets"); - } else { - fgets = (fgets_t)dlsym(RTLD_DEFAULT, "fgets"); - } - REQUIRE_API(fgets) - if (is_intercepted) { - rewind = (rewind_t)dlsym(RTLD_NEXT, "rewind"); - } else { - rewind = (rewind_t)dlsym(RTLD_DEFAULT, "rewind"); - } - REQUIRE_API(rewind) - if (is_intercepted) { - fseek = (fseek_t)dlsym(RTLD_NEXT, "fseek"); - } else { - fseek = (fseek_t)dlsym(RTLD_DEFAULT, "fseek"); - } - REQUIRE_API(fseek) - if (is_intercepted) { - fseeko = (fseeko_t)dlsym(RTLD_NEXT, "fseeko"); - } else { - fseeko = (fseeko_t)dlsym(RTLD_DEFAULT, "fseeko"); - } - REQUIRE_API(fseeko) - if (is_intercepted) { - fseeko64 = (fseeko64_t)dlsym(RTLD_NEXT, "fseeko64"); - } else { - fseeko64 = (fseeko64_t)dlsym(RTLD_DEFAULT, "fseeko64"); - } - REQUIRE_API(fseeko64) - if (is_intercepted) { - fsetpos = (fsetpos_t)dlsym(RTLD_NEXT, "fsetpos"); - } else { - fsetpos = (fsetpos_t)dlsym(RTLD_DEFAULT, "fsetpos"); - } - REQUIRE_API(fsetpos) - if (is_intercepted) { - fsetpos64 = (fsetpos64_t)dlsym(RTLD_NEXT, "fsetpos64"); - } else { - fsetpos64 = (fsetpos64_t)dlsym(RTLD_DEFAULT, "fsetpos64"); - } - REQUIRE_API(fsetpos64) - if (is_intercepted) { - ftell = (ftell_t)dlsym(RTLD_NEXT, "ftell"); - } else { - ftell = (ftell_t)dlsym(RTLD_DEFAULT, "ftell"); - } - REQUIRE_API(ftell) - } -}; -} // namespace hermes::adapter::stdio - -#undef REQUIRE_API - -#endif // HERMES_ADAPTER_STDIO_H diff --git a/hermes_adapters/stdio/stdio_api.h b/hermes_adapters/stdio/stdio_api.h index 8bc3401ac..92c914675 100644 --- a/hermes_adapters/stdio/stdio_api.h +++ b/hermes_adapters/stdio/stdio_api.h @@ -12,43 +12,40 @@ #ifndef HERMES_ADAPTER_STDIO_H #define HERMES_ADAPTER_STDIO_H +#include #include - -#include #include -#include - -#include "hermes_adapters/real_api.h" #include "hermes_shm/util/logging.h" +#include +#include "hermes_adapters/real_api.h" extern "C" { -typedef FILE* (*fopen_t)(const char* path, const char* mode); -typedef FILE* (*fopen64_t)(const char* path, const char* mode); -typedef FILE* (*fdopen_t)(int fd, const char* mode); -typedef FILE* (*freopen_t)(const char* path, const char* mode, FILE* stream); -typedef FILE* (*freopen64_t)(const char* path, const char* mode, FILE* stream); -typedef int (*fflush_t)(FILE* fp); -typedef int (*fclose_t)(FILE* fp); -typedef size_t (*fwrite_t)(const void* ptr, size_t size, size_t nmemb, - FILE* fp); -typedef int (*fputc_t)(int c, FILE* fp); -typedef int (*fgetpos_t)(FILE* fp, fpos_t* pos); -typedef int (*fgetpos64_t)(FILE* fp, fpos64_t* pos); -typedef int (*putc_t)(int c, FILE* fp); -typedef int (*putw_t)(int w, FILE* fp); -typedef int (*fputs_t)(const char* s, FILE* stream); -typedef size_t (*fread_t)(void* ptr, size_t size, size_t nmemb, FILE* stream); -typedef int (*fgetc_t)(FILE* stream); -typedef int (*getc_t)(FILE* stream); -typedef int (*getw_t)(FILE* stream); -typedef char* (*fgets_t)(char* s, int size, FILE* stream); -typedef void (*rewind_t)(FILE* stream); -typedef int (*fseek_t)(FILE* stream, long offset, int whence); -typedef int (*fseeko_t)(FILE* stream, off_t offset, int whence); -typedef int (*fseeko64_t)(FILE* stream, off64_t offset, int whence); -typedef int (*fsetpos_t)(FILE* stream, const fpos_t* pos); -typedef int (*fsetpos64_t)(FILE* stream, const fpos64_t* pos); -typedef long int (*ftell_t)(FILE* fp); +typedef FILE * (*fopen_t)(const char * path, const char * mode); +typedef FILE * (*fopen64_t)(const char * path, const char * mode); +typedef FILE * (*fdopen_t)(int fd, const char * mode); +typedef FILE * (*freopen_t)(const char * path, const char * mode, FILE * stream); +typedef FILE * (*freopen64_t)(const char * path, const char * mode, FILE * stream); +typedef int (*fflush_t)(FILE * fp); +typedef int (*fclose_t)(FILE * fp); +typedef size_t (*fwrite_t)(const void * ptr, size_t size, size_t nmemb, FILE * fp); +typedef int (*fputc_t)(int c, FILE * fp); +typedef int (*fgetpos_t)(FILE * fp, fpos_t * pos); +typedef int (*fgetpos64_t)(FILE * fp, fpos64_t * pos); +typedef int (*putc_t)(int c, FILE * fp); +typedef int (*putw_t)(int w, FILE * fp); +typedef int (*fputs_t)(const char * s, FILE * stream); +typedef size_t (*fread_t)(void * ptr, size_t size, size_t nmemb, FILE * stream); +typedef int (*fgetc_t)(FILE * stream); +typedef int (*getc_t)(FILE * stream); +typedef int (*getw_t)(FILE * stream); +typedef char * (*fgets_t)(char * s, int size, FILE * stream); +typedef void (*rewind_t)(FILE * stream); +typedef int (*fseek_t)(FILE * stream, long offset, int whence); +typedef int (*fseeko_t)(FILE * stream, off_t offset, int whence); +typedef int (*fseeko64_t)(FILE * stream, off64_t offset, int whence); +typedef int (*fsetpos_t)(FILE * stream, const fpos_t * pos); +typedef int (*fsetpos64_t)(FILE * stream, const fpos64_t * pos); +typedef long int (*ftell_t)(FILE * fp); } namespace hermes::adapter { diff --git a/hermes_adapters/stdio/stdio_fs_api.h b/hermes_adapters/stdio/stdio_fs_api.h index a3ce420a2..3d2c9b4fb 100644 --- a/hermes_adapters/stdio/stdio_fs_api.h +++ b/hermes_adapters/stdio/stdio_fs_api.h @@ -25,13 +25,15 @@ namespace hermes::adapter { /** A class to represent POSIX IO file system */ class StdioFs : public hermes::adapter::Filesystem { public: - HERMES_STDIO_API_T real_api_; /**< pointer to real APIs */ + HERMES_STDIO_API_T real_api_; /**< pointer to real APIs */ public: - StdioFs() : Filesystem(AdapterType::kStdio) { real_api_ = HERMES_STDIO_API; } + StdioFs() : Filesystem(AdapterType::kStdio) { + real_api_ = HERMES_STDIO_API; + } /** Close an existing stream and then open with new path */ - FILE *Reopen(const std::string &user_path, const char *mode, + FILE* Reopen(const std::string &user_path, const char *mode, AdapterStat &stat) { auto real_api_ = HERMES_STDIO_API; FILE *ret; @@ -40,19 +42,20 @@ class StdioFs : public hermes::adapter::Filesystem { return ret; } stat.fh_ = ret; - HILOG(kDebug, "Reopen file for filename: {} in mode {}", user_path, mode) + HILOG(kDebug, "Reopen file for filename: {} in mode {}", + user_path, mode) stat.UpdateTime(); - return (FILE *)&stat; + return (FILE*)&stat; } /** fdopen */ - FILE *FdOpen(const std::string &mode, std::shared_ptr &stat) { + FILE* FdOpen(const std::string &mode, + std::shared_ptr &stat) { auto real_api_ = HERMES_STDIO_API; auto mdm = HERMES_FS_METADATA_MANAGER; stat->fh_ = real_api_->fdopen(stat->fd_, mode.c_str()); stat->mode_str_ = mode; - File f; - f.hermes_fh_ = (FILE *)stat.get(); + File f; f.hermes_fh_ = (FILE*)stat.get(); mdm->Create(f, stat); return f.hermes_fh_; } @@ -63,10 +66,12 @@ class StdioFs : public hermes::adapter::Filesystem { } /** Whether or not \a fd FILE DESCRIPTOR is tracked */ - static bool IsFdTracked(int fd) { return PosixFs::IsFdTracked(fd); } + static bool IsFdTracked(int fd) { + return PosixFs::IsFdTracked(fd); + } /** Whether or not \a fp FILE was generated by Hermes */ - static bool IsFpTracked(FILE *fp, std::shared_ptr &stat) { + static bool IsFpTracked(FILE* fp, std::shared_ptr &stat) { if (!fp || !HERMES->IsInitialized()) { return false; } @@ -77,13 +82,13 @@ class StdioFs : public hermes::adapter::Filesystem { } /** Whether or not \a fp FILE was generated by Hermes */ - static bool IsFpTracked(FILE *fp) { + static bool IsFpTracked(FILE* fp) { std::shared_ptr stat; return IsFpTracked(fp, stat); } /** get the file name from \a fp file pointer */ - static std::string GetFilenameFromFP(FILE *fp) { + static std::string GetFilenameFromFP(FILE* fp) { char proclnk[kMaxPathLen]; char filename[kMaxPathLen]; int fno = fileno(fp); @@ -95,7 +100,9 @@ class StdioFs : public hermes::adapter::Filesystem { public: /** Allocate an fd for the file f */ - void RealOpen(File &f, AdapterStat &stat, const std::string &path) override { + void RealOpen(File &f, + AdapterStat &stat, + const std::string &path) override { if (stat.mode_str_.find('w') != std::string::npos) { stat.hflags_.SetBits(HERMES_FS_TRUNC); stat.hflags_.SetBits(HERMES_FS_CREATE); @@ -127,23 +134,28 @@ class StdioFs : public hermes::adapter::Filesystem { * and hermes file handler. These are not the same as STDIO file * descriptor and STDIO file handler. * */ - void HermesOpen(File &f, const AdapterStat &stat, + void HermesOpen(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) override { - f.hermes_fh_ = (FILE *)fs_mdm.stat_; + f.hermes_fh_ = (FILE*)fs_mdm.stat_; } /** Synchronize \a file FILE f */ - int RealSync(const File &f, const AdapterStat &stat) override { - (void)f; - if (stat.adapter_mode_ == AdapterMode::kScratch && stat.fh_ == nullptr) { + int RealSync(const File &f, + const AdapterStat &stat) override { + (void) f; + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fh_ == nullptr) { return 0; } return real_api_->fflush(stat.fh_); } /** Close \a file FILE f */ - int RealClose(const File &f, AdapterStat &stat) override { - if (stat.adapter_mode_ == AdapterMode::kScratch && stat.fh_ == nullptr) { + int RealClose(const File &f, + AdapterStat &stat) override { + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fh_ == nullptr) { return 0; } return real_api_->fclose(stat.fh_); @@ -153,11 +165,10 @@ class StdioFs : public hermes::adapter::Filesystem { * Called before RealClose. Releases information provisioned during * the allocation phase. * */ - void HermesClose(File &f, const AdapterStat &stat, + void HermesClose(File &f, + const AdapterStat &stat, FilesystemIoClientState &fs_mdm) override { - (void)f; - (void)stat; - (void)fs_mdm; + (void) f; (void) stat; (void) fs_mdm; } /** Remove \a file FILE f */ @@ -170,26 +181,26 @@ class StdioFs : public hermes::adapter::Filesystem { size_t true_size = 0; std::string filename = bkt_name.str(); int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { - return 0; - } + if (fd < 0) { return 0; } struct stat buf; fstat(fd, &buf); true_size = buf.st_size; close(fd); - HILOG(kDebug, "The size of the file {} on disk is {}", filename, true_size) + HILOG(kDebug, "The size of the file {} on disk is {}", + filename, true_size) return true_size; } /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, const Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override { + void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { status.success_ = true; - HILOG(kDebug, - "Writing to file: {}" - " offset: {}" - " size: {}", + HILOG(kDebug, "Writing to file: {}" + " offset: {}" + " size: {}", bkt_name, opts.backend_off_, full_blob.size()) FILE *fh = real_api_->fopen(bkt_name.c_str(), "r+"); if (fh == nullptr) { @@ -198,8 +209,10 @@ class StdioFs : public hermes::adapter::Filesystem { return; } real_api_->fseek(fh, opts.backend_off_, SEEK_SET); - status.size_ = - real_api_->fwrite(full_blob.data(), sizeof(char), full_blob.size(), fh); + status.size_ = real_api_->fwrite(full_blob.data(), + sizeof(char), + full_blob.size(), + fh); if (status.size_ != full_blob.size()) { status.success_ = false; } @@ -207,13 +220,14 @@ class StdioFs : public hermes::adapter::Filesystem { } /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, Blob &full_blob, - const FsIoOptions &opts, IoStatus &status) override { + void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { status.success_ = true; - HILOG(kDebug, - "Reading from file: {}" - " offset: {}" - " size: {}", + HILOG(kDebug, "Reading from file: {}" + " offset: {}" + " size: {}", bkt_name, opts.backend_off_, full_blob.size()) FILE *fh = real_api_->fopen(bkt_name.c_str(), "r"); if (fh == nullptr) { @@ -222,8 +236,10 @@ class StdioFs : public hermes::adapter::Filesystem { return; } real_api_->fseek(fh, opts.backend_off_, SEEK_SET); - status.size_ = - real_api_->fread(full_blob.data(), sizeof(char), full_blob.size(), fh); + status.size_ = real_api_->fread(full_blob.data(), + sizeof(char), + full_blob.size(), + fh); if (status.size_ != full_blob.size()) { status.success_ = false; } @@ -231,15 +247,15 @@ class StdioFs : public hermes::adapter::Filesystem { } void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) override { - (void)opts; - (void)status; + (void) opts; + (void) status; } }; /** Simplify access to the stateless StdioFs Singleton */ #define HERMES_STDIO_FS \ hshm::EasySingleton<::hermes::adapter::StdioFs>::GetInstance() -#define HERMES_STDIO_FS_T hermes::adapter::StdioFs * +#define HERMES_STDIO_FS_T hermes::adapter::StdioFs* } // namespace hermes::adapter diff --git a/hermes_adapters/vfd/H5FDhermes.c b/hermes_adapters/vfd/H5FDhermes.c deleted file mode 100644 index 4f128f8ac..000000000 --- a/hermes_adapters/vfd/H5FDhermes.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Programmer: Kimmy Mu - * March 2021 - * - * Purpose: The hermes file driver using only the HDF5 public API - * and buffer datasets in Hermes buffering systems with - * multiple storage tiers. - */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* HDF5 header for dynamic plugin loading */ -#include "H5FDhermes.h" /* Hermes file driver */ -#include "H5FDhermes_err.h" /* error handling */ -#include "H5PLextern.h" - -/* Necessary hermes headers */ -#include "hermes_wrapper.h" - -#define H5FD_HERMES (H5FD_hermes_init()) - -/* HDF5 doesn't currently have a driver init callback. Use - * macro to initialize driver if loaded as a plugin. - */ -#define H5FD_HERMES_INIT \ - do { \ - if (H5FD_HERMES_g < 0) H5FD_HERMES_g = H5FD_HERMES; \ - } while (0) - -/* The driver identification number, initialized at runtime */ -static hid_t H5FD_HERMES_g = H5I_INVALID_HID; - -/* Identifiers for HDF5's error API */ -hid_t H5FDhermes_err_stack_g = H5I_INVALID_HID; -hid_t H5FDhermes_err_class_g = H5I_INVALID_HID; - -/* Whether Hermes is initialized */ -static htri_t hermes_initialized = FAIL; -static hbool_t mpi_is_initialized = FALSE; - -/* File operations */ -#define OP_UNKNOWN 0 -#define OP_READ 1 -#define OP_WRITE 2 - -/* POSIX I/O mode used as the third parameter to open/_open - * when creating a new file (O_CREAT is set). */ -#if defined(H5_HAVE_WIN32_API) -#define H5FD_HERMES_POSIX_CREATE_MODE_RW (_S_IREAD | _S_IWRITE) -#else -#define H5FD_HERMES_POSIX_CREATE_MODE_RW 0666 -#endif - -/* Define length of blob name, which is converted from page index */ -#define LEN_BLOB_NAME 10 - -#define BIT_SIZE_OF_UNSIGNED (sizeof(uint) * 8) - -/* kHermesConf env variable is used to define path to kHermesConf in adapters. - * This is used for initialization of Hermes. */ -const char *kHermesConf = "HERMES_CONF"; - -/* The description of bit representation of blobs in Hermes buffering system. */ -typedef struct bitv_t { - uint *blobs; - size_t capacity; - size_t end_pos; -} bitv_t; - -/* The description of a file/bucket belonging to this driver. */ -typedef struct H5FD_hermes_t { - H5FD_t pub; /* public stuff, must be first */ - haddr_t eoa; /* end of allocated region */ - haddr_t eof; /* end of file; current file size */ - haddr_t pos; /* current file I/O position */ - int op; /* last operation */ - hbool_t persistence; /* write to file name on close */ - int fd; /* the filesystem file descriptor */ - size_t buf_size; - char *bktname; /* Copy of file name from open operation */ - BucketClass *bkt_handle; - int ref_count; - unsigned char *page_buf; - bitv_t blob_in_bucket; - unsigned flags; /* The flags passed from H5Fcreate/H5Fopen */ -} H5FD_hermes_t; - -/* Driver-specific file access properties */ -typedef struct H5FD_hermes_fapl_t { - hbool_t persistence; /* write to file name on flush */ - size_t page_size; /* page size */ -} H5FD_hermes_fapl_t; - -/* - * These macros check for overflow of various quantities. These macros - * assume that HDoff_t is signed and haddr_t and size_t are unsigned. - * - * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' - * is too large to be represented by the second argument - * of the file seek function. - * - * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too - * large to be represented by the `size_t' type. - * - * REGION_OVERFLOW: Checks whether an address and size pair describe data - * which can be addressed entirely by the second - * argument of the file seek function. - */ -#define MAXADDR (((haddr_t)1 << (8 * sizeof(off_t) - 1)) - 1) -#define ADDR_OVERFLOW(A) (HADDR_UNDEF == (A) || ((A) & ~(haddr_t)MAXADDR)) -#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) -#define REGION_OVERFLOW(A, Z) \ - (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || HADDR_UNDEF == (A) + (Z) || \ - (off_t)((A) + (Z)) < (off_t)(A)) - -/* Prototypes */ -static herr_t H5FD__hermes_term(void); -static herr_t H5FD__hermes_fapl_free(void *_fa); -static H5FD_t *H5FD__hermes_open(const char *name, unsigned flags, - hid_t fapl_id, haddr_t maxaddr); -static herr_t H5FD__hermes_close(H5FD_t *_file); -static int H5FD__hermes_cmp(const H5FD_t *_f1, const H5FD_t *_f2); -static herr_t H5FD__hermes_query(const H5FD_t *_f1, unsigned long *flags); -static haddr_t H5FD__hermes_get_eoa(const H5FD_t *_file, H5FD_mem_t type); -static herr_t H5FD__hermes_set_eoa(H5FD_t *_file, H5FD_mem_t type, - haddr_t addr); -static haddr_t H5FD__hermes_get_eof(const H5FD_t *_file, H5FD_mem_t type); -static herr_t H5FD__hermes_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, - haddr_t addr, size_t size, void *buf); -static herr_t H5FD__hermes_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, - haddr_t addr, size_t size, const void *buf); - -static const H5FD_class_t H5FD_hermes_g = { - H5FD_CLASS_VERSION, - H5FD_HERMES_VALUE, /* value */ - H5FD_HERMES_NAME, /* name */ - MAXADDR, /* maxaddr */ - H5F_CLOSE_STRONG, /* fc_degree */ - H5FD__hermes_term, /* terminate */ - NULL, /* sb_size */ - NULL, /* sb_encode */ - NULL, /* sb_decode */ - sizeof(H5FD_hermes_fapl_t), /* fapl_size */ - NULL, /* fapl_get */ - NULL, /* fapl_copy */ - H5FD__hermes_fapl_free, /* fapl_free */ - 0, /* dxpl_size */ - NULL, /* dxpl_copy */ - NULL, /* dxpl_free */ - H5FD__hermes_open, /* open */ - H5FD__hermes_close, /* close */ - H5FD__hermes_cmp, /* cmp */ - H5FD__hermes_query, /* query */ - NULL, /* get_type_map */ - NULL, /* alloc */ - NULL, /* free */ - H5FD__hermes_get_eoa, /* get_eoa */ - H5FD__hermes_set_eoa, /* set_eoa */ - H5FD__hermes_get_eof, /* get_eof */ - NULL, /* get_handle */ - H5FD__hermes_read, /* read */ - H5FD__hermes_write, /* write */ - NULL, /* flush */ - NULL, /* truncate */ - NULL, /* lock */ - NULL, /* unlock */ - NULL, /* del */ - NULL, /* ctl */ - H5FD_FLMAP_DICHOTOMY /* fl_map */ -}; - -/* Check if the blob at POS is set */ -static bool check_blob(bitv_t *bits, size_t bit_pos) { - bool result = false; - - if (bit_pos >= bits->capacity) return false; - - size_t unit_pos = bit_pos / BIT_SIZE_OF_UNSIGNED; - size_t blob_pos_in_unit = bit_pos % BIT_SIZE_OF_UNSIGNED; - result = bits->blobs[unit_pos] & (1 << blob_pos_in_unit); - - return result; -} - -/* Set the bit at POS and reallocate 2*capacity for blobs as needed */ -static void set_blob(bitv_t *bits, size_t bit_pos) { - if (bit_pos >= bits->capacity) { - size_t current_units = bits->capacity / BIT_SIZE_OF_UNSIGNED; - size_t need_units = bit_pos / BIT_SIZE_OF_UNSIGNED + 1; - bits->capacity = need_units * BIT_SIZE_OF_UNSIGNED * 2; - bits->blobs = realloc(bits->blobs, bits->capacity); - memset(&bits->blobs[current_units], 0, - sizeof(uint) * (need_units * 2 - current_units + 1)); - } - - size_t unit_pos = bit_pos / BIT_SIZE_OF_UNSIGNED; - size_t blob_pos_in_unit = bit_pos % BIT_SIZE_OF_UNSIGNED; - bits->blobs[unit_pos] |= 1 << blob_pos_in_unit; - if (bit_pos > bits->end_pos) bits->end_pos = bit_pos; -} - -/** Returns true if @p page_index is the last page in the file. */ -bool H5FD__hermes_is_last_page(H5FD_hermes_t *file, size_t page_index) { - size_t total_pages = (size_t)ceil(file->eof / (float)file->buf_size); - size_t last_page_index = total_pages > 0 ? total_pages - 1 : 0; - bool ret_value = page_index == last_page_index; - - return ret_value; -} - -/** Returns the size of page @page_index. This is only different from - * H5FD_hermes_t::buf_size if it's the last page in the file. */ -size_t H5FD__hermes_get_gap_size(H5FD_hermes_t *file, size_t page_index) { - size_t ret_value = file->buf_size; - if (H5FD__hermes_is_last_page(file, page_index)) { - ret_value = file->eof - (page_index * file->buf_size); - } - - return ret_value; -} - -/** - * If the Hermes VFD recieves a partial page update to an existing file, we - * first need to fill the page with exising data from the file with a read - * before the Blob can be buffered. We refer to these partial pages as "gaps." - */ -herr_t H5FD__hermes_read_gap(H5FD_hermes_t *file, size_t seek_offset, - unsigned char *read_ptr, size_t read_size) { - herr_t ret_value = SUCCEED; - - if (!(file->flags & H5F_ACC_CREAT || file->flags & H5F_ACC_TRUNC || - file->flags & H5F_ACC_EXCL)) { - if (file->fd > -1) { - if (flock(file->fd, LOCK_SH) == -1) { - H5FD_HERMES_SYS_GOTO_ERROR(H5E_IO, H5E_CANTLOCKFILE, FAIL, - file->bktname); - } - - ssize_t bytes_read = pread(file->fd, read_ptr, read_size, seek_offset); - if (bytes_read == -1 || - ((size_t)bytes_read != read_size && bytes_read != 0)) { - H5FD_HERMES_SYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, file->bktname); - } - - if (flock(file->fd, LOCK_UN) == -1) { - H5FD_HERMES_SYS_GOTO_ERROR(H5E_IO, H5E_CANTUNLOCKFILE, FAIL, - file->bktname); - } - } - } - -done: - H5FD_HERMES_FUNC_LEAVE; -} - -/*------------------------------------------------------------------------- - * Function: H5FD_hermes_init - * - * Purpose: Initialize this driver by registering the driver with the - * library. - * - * Return: Success: The driver ID for the hermes driver - * Failure: H5I_INVALID_HID - * - *------------------------------------------------------------------------- - */ -hid_t H5FD_hermes_init(void) { - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - /* Initialize error reporting */ - if ((H5FDhermes_err_stack_g = H5Ecreate_stack()) < 0) - H5FD_HERMES_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't create HDF5 error stack"); - if ((H5FDhermes_err_class_g = - H5Eregister_class(H5FD_HERMES_ERR_CLS_NAME, H5FD_HERMES_ERR_LIB_NAME, - H5FD_HERMES_ERR_VER)) < 0) - H5FD_HERMES_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't register error class with HDF5 error API"); - - if (H5I_VFL != H5Iget_type(H5FD_HERMES_g)) - H5FD_HERMES_g = H5FDregister(&H5FD_hermes_g); - - /* Set return value */ - ret_value = H5FD_HERMES_g; - -done: - H5FD_HERMES_FUNC_LEAVE; -} /* end H5FD_hermes_init() */ - -/*--------------------------------------------------------------------------- - * Function: H5FD__hermes_term - * - * Purpose: Shut down the VFD - * - * Returns: SUCCEED (Can't fail) - * - *--------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_term(void) { - herr_t ret_value = SUCCEED; - - /* Unregister from HDF5 error API */ - if (H5FDhermes_err_class_g >= 0) { - if (H5Eunregister_class(H5FDhermes_err_class_g) < 0) - H5FD_HERMES_GOTO_ERROR( - H5E_VFL, H5E_CLOSEERROR, FAIL, - "can't unregister error class from HDF5 error API"); - - /* Print the current error stack before destroying it */ - PRINT_ERROR_STACK; - - /* Destroy the error stack */ - if (H5Eclose_stack(H5FDhermes_err_stack_g) < 0) { - H5FD_HERMES_GOTO_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, - "can't close HDF5 error stack"); - PRINT_ERROR_STACK; - } /* end if */ - - H5FDhermes_err_stack_g = H5I_INVALID_HID; - H5FDhermes_err_class_g = H5I_INVALID_HID; - } - - /* Reset VFL ID */ - H5FD_HERMES_g = H5I_INVALID_HID; - -done: - H5FD_HERMES_FUNC_LEAVE_API; -} /* end H5FD__hermes_term() */ - -/*------------------------------------------------------------------------- - * Function: H5Pset_fapl_hermes - * - * Purpose: Modify the file access property list to use the H5FD_HERMES - * driver defined in this source file. There are no driver - * specific properties. - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t H5Pset_fapl_hermes(hid_t fapl_id, hbool_t persistence, - size_t page_size) { - H5FD_hermes_fapl_t fa; /* Hermes VFD info */ - herr_t ret_value = SUCCEED; /* Return value */ - - /* Check argument */ - if (H5I_GENPROP_LST != H5Iget_type(fapl_id) || - TRUE != H5Pisa_class(fapl_id, H5P_FILE_ACCESS)) { - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - - /* Set VFD info values */ - memset(&fa, 0, sizeof(H5FD_hermes_fapl_t)); - fa.persistence = persistence; - fa.page_size = page_size; - - /* Set the property values & the driver for the FAPL */ - if (H5Pset_driver(fapl_id, H5FD_HERMES, &fa) < 0) { - H5FD_HERMES_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't set Hermes VFD as driver"); - } - -done: - H5FD_HERMES_FUNC_LEAVE_API; -} /* end H5Pset_fapl_hermes() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_fapl_free - * - * Purpose: Frees the family-specific file access properties. - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_fapl_free(void *_fa) { - H5FD_hermes_fapl_t *fa = (H5FD_hermes_fapl_t *)_fa; - herr_t ret_value = SUCCEED; /* Return value */ - - free(fa); - - H5FD_HERMES_FUNC_LEAVE; -} - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_open - * - * Purpose: Create and/or opens a bucket in Hermes. - * - * Return: Success: A pointer to a new bucket data structure. - * Failure: NULL - * - *------------------------------------------------------------------------- - */ -static H5FD_t *H5FD__hermes_open(const char *name, unsigned flags, - hid_t fapl_id, haddr_t maxaddr) { - H5FD_hermes_t *file = NULL; /* hermes VFD info */ - int fd = -1; /* File descriptor */ - int o_flags = 0; /* Flags for open() call */ - struct stat sb = {0}; - const H5FD_hermes_fapl_t *fa = NULL; - H5FD_hermes_fapl_t new_fa = {0}; - char *hermes_config = NULL; - H5FD_t *ret_value = NULL; /* Return value */ - - /* Sanity check on file offsets */ - assert(sizeof(off_t) >= sizeof(size_t)); - - H5FD_HERMES_INIT; - - /* Check arguments */ - if (!name || !*name) - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); - if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); - if (ADDR_OVERFLOW(maxaddr)) - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); - - /* Get the driver specific information */ - H5E_BEGIN_TRY { fa = H5Pget_driver_info(fapl_id); } - H5E_END_TRY; - if (!fa || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { - ssize_t config_str_len = 0; - char config_str_buf[128]; - if ((config_str_len = - H5Pget_driver_config_str(fapl_id, config_str_buf, 128)) < 0) { - printf("H5Pget_driver_config_str() error\n"); - } - char *saveptr = NULL; - char *token = strtok_r(config_str_buf, " ", &saveptr); - if (!strcmp(token, "true") || !strcmp(token, "TRUE") || - !strcmp(token, "True")) { - new_fa.persistence = true; - } - token = strtok_r(0, " ", &saveptr); - sscanf(token, "%zu", &(new_fa.page_size)); - fa = &new_fa; - } - - /* Initialize Hermes */ - if ((H5OPEN hermes_initialized) == FAIL) { - hermes_config = getenv(kHermesConf); - if (HermesInitHermes(hermes_config) < 0) { - H5FD_HERMES_GOTO_ERROR(H5E_SYM, H5E_UNINITIALIZED, NULL, - "Hermes initialization failed"); - } else { - hermes_initialized = TRUE; - } - } - - bool creating_file = false; - - /* Build the open flags */ - o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; - if (H5F_ACC_TRUNC & flags) { - o_flags |= O_TRUNC; - } - if (H5F_ACC_CREAT & flags) { - o_flags |= O_CREAT; - creating_file = true; - } - if (H5F_ACC_EXCL & flags) { - o_flags |= O_EXCL; - } - - if (fa->persistence || !creating_file) { - // NOTE(chogan): We're either in persistent mode, or we're in scratch mode - // and dealing with an existing file. - if ((fd = open(name, o_flags, H5FD_HERMES_POSIX_CREATE_MODE_RW)) < 0) { - int myerrno = errno; - H5FD_HERMES_GOTO_ERROR( - H5E_FILE, H5E_CANTOPENFILE, NULL, - "unable to open file: name = '%s', errno = %d, error message = '%s'," - "flags = %x, o_flags = %x", - name, myerrno, strerror(myerrno), flags, (unsigned)o_flags); - } - - if (fstat(fd, &sb) < 0) { - H5FD_HERMES_SYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, - "unable to fstat file"); - } - } - - /* Create the new file struct */ - if (NULL == (file = calloc(1, sizeof(H5FD_hermes_t)))) { - H5FD_HERMES_GOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, - "unable to allocate file struct"); - } - - if (name && *name) { - file->bktname = strdup(name); - } - - file->persistence = fa->persistence; - file->fd = fd; - file->bkt_handle = HermesBucketCreate(name); - file->page_buf = malloc(fa->page_size); - file->buf_size = fa->page_size; - file->ref_count = 1; - file->op = OP_UNKNOWN; - file->blob_in_bucket.capacity = BIT_SIZE_OF_UNSIGNED; - file->blob_in_bucket.blobs = (uint *)calloc(1, sizeof(uint)); - file->blob_in_bucket.end_pos = 0; - file->flags = flags; - file->eof = (haddr_t)sb.st_size; - - /* Set return value */ - ret_value = (H5FD_t *)file; - -done: - if (NULL == ret_value) { - if (fd >= 0) close(fd); - if (file) { - if (file->bkt_handle) { - HermesBucketDestroy(file->bkt_handle); - } - free(file->blob_in_bucket.blobs); - free(file->bktname); - free(file->page_buf); - free(file); - } - } /* end if */ - - H5FD_HERMES_FUNC_LEAVE_API; -} /* end H5FD__hermes_open() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_close - * - * Purpose: Closes an HDF5 file. - * - * Return: Success: SUCCEED - * Failure: FAIL, file not closed. - * - *------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_close(H5FD_t *_file) { - H5FD_hermes_t *file = (H5FD_hermes_t *)_file; - size_t blob_size = file->buf_size; - size_t i; - herr_t ret_value = SUCCEED; /* Return value */ - - /* Sanity check */ - assert(file); - - if (file->persistence) { - if (file->op == OP_WRITE) { - /* TODO: if there is user blobk, the logic is not working, - including offset, but not 0 */ - for (i = 0; i <= file->blob_in_bucket.end_pos; i++) { - /* Check if this blob exists */ - bool blob_exists = check_blob(&file->blob_in_bucket, i); - if (!blob_exists) continue; - - char i_blob[LEN_BLOB_NAME]; - snprintf(i_blob, sizeof(i_blob), "%zu\n", i); - HermesBucketGet(file->bkt_handle, i_blob, blob_size, file->page_buf); - - bool is_last_page = H5FD__hermes_is_last_page(file, i); - size_t bytes_to_write = blob_size; - - if (is_last_page) { - size_t bytes_in_last_page = file->eof - (i * blob_size); - bytes_to_write = bytes_in_last_page; - } - - ssize_t bytes_written = - pwrite(file->fd, file->page_buf, bytes_to_write, i * blob_size); - assert(bytes_written == bytes_to_write); - } - } - if (close(file->fd) < 0) - H5FD_HERMES_SYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, - "unable to close file"); - } - - if (file->ref_count == 1) { - HermesBucketDestroy(file->bkt_handle); - } else { - HermesBucketClose(file->bkt_handle); - } - - /* Release the file info */ - free(file->blob_in_bucket.blobs); - free(file->page_buf); - free(file->bktname); - free(file); - -done: - H5FD_HERMES_FUNC_LEAVE_API; -} /* end H5FD__hermes_close() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_cmp - * - * Purpose: Compares two buckets belonging to this driver using an - * arbitrary (but consistent) ordering. - * - * Return: Success: A value like strcmp() - * Failure: never fails (arguments were checked by the - * caller). - * - *------------------------------------------------------------------------- - */ -static int H5FD__hermes_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_hermes_t *f1 = (const H5FD_hermes_t *)_f1; - const H5FD_hermes_t *f2 = (const H5FD_hermes_t *)_f2; - int ret_value = 0; - - ret_value = strcmp(f1->bktname, f2->bktname); - - H5FD_HERMES_FUNC_LEAVE; -} /* end H5FD__hermes_cmp() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_query - * - * Purpose: Set the flags that this VFL driver is capable of supporting. - * (listed in H5FDpublic.h) - * - * Return: SUCCEED (Can't fail) - * - *------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_query(const H5FD_t *_file, - unsigned long *flags /* out */) { - /* Set the VFL feature flags that this driver supports */ - /* Notice: the Mirror VFD Writer currently uses only the hermes driver as - * the underying driver -- as such, the Mirror VFD implementation copies - * these feature flags as its own. Any modifications made here must be - * reflected in H5FDmirror.c - * -- JOS 2020-01-13 - */ - herr_t ret_value = SUCCEED; - - if (flags) { - *flags = 0; - } /* end if */ - - H5FD_HERMES_FUNC_LEAVE; -} /* end H5FD__hermes_query() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_get_eoa - * - * Purpose: Gets the end-of-address marker for the file. The EOA marker - * is the first address past the last byte allocated in the - * format address space. - * - * Return: The end-of-address marker. - * - *------------------------------------------------------------------------- - */ -static haddr_t H5FD__hermes_get_eoa(const H5FD_t *_file, - H5FD_mem_t H5_ATTR_UNUSED type) { - haddr_t ret_value = HADDR_UNDEF; - - const H5FD_hermes_t *file = (const H5FD_hermes_t *)_file; - - ret_value = file->eoa; - - H5FD_HERMES_FUNC_LEAVE; -} /* end H5FD__hermes_get_eoa() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_set_eoa - * - * Purpose: Set the end-of-address marker for the file. This function is - * called shortly after an existing HDF5 file is opened in order - * to tell the driver where the end of the HDF5 data is located. - * - * Return: SUCCEED (Can't fail) - * - *------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_set_eoa(H5FD_t *_file, - H5FD_mem_t H5_ATTR_UNUSED type, - haddr_t addr) { - herr_t ret_value = SUCCEED; - - H5FD_hermes_t *file = (H5FD_hermes_t *)_file; - - file->eoa = addr; - - H5FD_HERMES_FUNC_LEAVE; -} /* end H5FD__hermes_set_eoa() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_get_eof - * - * Purpose: Returns the end-of-file marker, which is the greater of - * either the filesystem end-of-file or the HDF5 end-of-address - * markers. - * - * Return: End of file address, the first address past the end of the - * "file", either the filesystem file or the HDF5 file. - * - *------------------------------------------------------------------------- - */ -static haddr_t H5FD__hermes_get_eof(const H5FD_t *_file, - H5FD_mem_t H5_ATTR_UNUSED type) { - haddr_t ret_value = HADDR_UNDEF; - - const H5FD_hermes_t *file = (const H5FD_hermes_t *)_file; - - ret_value = file->eof; - - H5FD_HERMES_FUNC_LEAVE; -} /* end H5FD__hermes_get_eof() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_read - * - * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in - * DXPL_ID. Determine the number of file pages affected by this - * call from ADDR and SIZE. Utilize transfer buffer PAGE_BUF to - * read the data from Blobs. Exercise care for the first and last - * pages to prevent overwriting existing data. - * - * Return: Success: SUCCEED. Result is stored in caller-supplied - * buffer BUF. - * Failure: FAIL, Contents of buffer BUF are undefined. - * - *------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, - hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, - size_t size, void *buf /*out*/) { - H5FD_hermes_t *file = (H5FD_hermes_t *)_file; - size_t num_pages; /* Number of pages of transfer buffer */ - size_t start_page_index; /* First page index of tranfer buffer */ - size_t end_page_index; /* End page index of tranfer buffer */ - size_t transfer_size = 0; - size_t blob_size = file->buf_size; - size_t k; - haddr_t addr_end = addr + size - 1; - herr_t ret_value = SUCCEED; /* Return value */ - - assert(file && file->pub.cls); - assert(buf); - - /* Check for overflow conditions */ - if (HADDR_UNDEF == addr) { - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "addr undefined, addr = %llu", - (unsigned long long)addr); - } - if (REGION_OVERFLOW(addr, size)) { - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, - "addr overflow, addr = %llu", - (unsigned long long)addr); - } - if (NULL == file->page_buf) { - H5FD_HERMES_GOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, FAIL, - "transfer buffer not initialized"); - } - - /* Check easy cases */ - if (0 == size) return 0; - if ((haddr_t)addr >= file->eof) { - memset(buf, 0, size); - return 0; - } - - start_page_index = addr / blob_size; - end_page_index = addr_end / blob_size; - num_pages = end_page_index - start_page_index + 1; - - for (k = start_page_index; k <= end_page_index; ++k) { - size_t bytes_in; - char k_blob[LEN_BLOB_NAME]; - snprintf(k_blob, sizeof(k_blob), "%zu\n", k); - /* Check if this blob exists */ - bool blob_exists = check_blob(&file->blob_in_bucket, k); - - /* Check if addr is in the range of (k*blob_size, (k+1)*blob_size) */ - /* NOTE: The range does NOT include the start address of page k, - but includes the end address of page k */ - if (addr > k * blob_size && addr < (k + 1) * blob_size) { - /* Calculate the starting address of transfer buffer update within page - * k */ - size_t offset = addr - k * blob_size; - assert(offset > 0); - - if (addr_end <= (k + 1) * blob_size - 1) - bytes_in = size; - else - bytes_in = (k + 1) * blob_size - addr; - - if (!blob_exists) { - size_t bytes_copy; - if (file->eof < (k + 1) * blob_size - 1) - bytes_copy = file->eof - k * blob_size; - else - bytes_copy = blob_size; - - size_t bytes_read = - pread(file->fd, file->page_buf, bytes_copy, k * blob_size); - if (bytes_read != bytes_copy) - H5FD_HERMES_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "pread failed"); - memcpy(buf, file->page_buf + offset, bytes_in); - - /* Write Blob k to Hermes buffering system */ - HermesBucketPut(file->bkt_handle, k_blob, file->page_buf, blob_size); - set_blob(&file->blob_in_bucket, k); - } else { - /* Read blob back to transfer buffer */ - HermesBucketGet(file->bkt_handle, k_blob, blob_size, file->page_buf); - - memcpy(buf, file->page_buf + offset, bytes_in); - } - transfer_size += bytes_in; - /* Check if addr_end is in the range of [k*blob_size, - * (k+1)*blob_size-1) */ - /* NOTE: The range includes the start address of page k, - but does NOT include the end address of page k */ - } else if (addr_end >= k * blob_size && - addr_end < (k + 1) * blob_size - 1) { - bytes_in = addr_end - k * blob_size + 1; - if (!blob_exists) { - size_t bytes_copy; - if (file->eof < (k + 1) * blob_size - 1) - bytes_copy = file->eof - k * blob_size; - else - bytes_copy = blob_size; - - ssize_t bytes_read = - pread(file->fd, file->page_buf, bytes_copy, k * blob_size); - if (bytes_read != bytes_copy) - H5FD_HERMES_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "pread failed"); - - memcpy((char *)buf + transfer_size, file->page_buf, bytes_in); - - /* Write Blob k to Hermes buffering system */ - HermesBucketPut(file->bkt_handle, k_blob, file->page_buf, blob_size); - set_blob(&file->blob_in_bucket, k); - } else { - /* Read blob back to transfer buffer */ - HermesBucketGet(file->bkt_handle, k_blob, blob_size, file->page_buf); - - /* Update transfer buffer */ - memcpy((char *)buf + transfer_size, file->page_buf, bytes_in); - } - transfer_size += bytes_in; - /* Page/Blob k is within the range of (addr, addr+size) */ - /* addr <= k*blob_size && addr_end >= (k+1)*blob_size-1 */ - } else { - if (!blob_exists) { - ssize_t bytes_read = pread(file->fd, (char *)buf + transfer_size, - blob_size, addr + transfer_size); - if (bytes_read != blob_size) - H5FD_HERMES_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "pread failed"); - - /* Write Blob k to Hermes buffering system */ - HermesBucketPut(file->bkt_handle, k_blob, (char *)buf + transfer_size, - blob_size); - set_blob(&file->blob_in_bucket, k); - } else { - /* Read blob back directly */ - HermesBucketGet(file->bkt_handle, k_blob, blob_size, - (char *)buf + transfer_size); - } - transfer_size += blob_size; - } - } - - /* Update current position */ - file->pos = addr + size; - file->op = OP_READ; - -done: - if (ret_value < 0) { - /* Reset last file I/O information */ - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - } /* end if */ - - H5FD_HERMES_FUNC_LEAVE_API; -} /* end H5FD__hermes_read() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__hermes_write - * - * Purpose: Writes SIZE bytes of data contained in buffer BUF to Hermes - * buffering system according to data transfer properties in - * DXPL_ID. Determine the number of file pages affected by this - * call from ADDR and SIZE. Utilize transfer buffer PAGE_BUF to - * put the data into Blobs. Exercise care for the first and last - * pages to prevent overwriting existing data. - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -static herr_t H5FD__hermes_write(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, - hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, - size_t size, const void *buf) { - H5FD_hermes_t *file = (H5FD_hermes_t *)_file; - size_t start_page_index; /* First page index of tranfer buffer */ - size_t end_page_index; /* End page index of tranfer buffer */ - size_t transfer_size = 0; - size_t blob_size = file->buf_size; - size_t k; - haddr_t addr_end = addr + size - 1; - herr_t ret_value = SUCCEED; /* Return value */ - - assert(file && file->pub.cls); - assert(buf); - - /* Check for overflow conditions */ - if (HADDR_UNDEF == addr) { - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "addr undefined, addr = %llu", - (unsigned long long)addr); - } - if (REGION_OVERFLOW(addr, size)) { - H5FD_HERMES_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, - "addr overflow, addr = %llu, size = %llu", - (unsigned long long)addr, (unsigned long long)size); - } - if (NULL == file->page_buf) { - H5FD_HERMES_GOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, FAIL, - "transfer buffer not initialized"); - } - start_page_index = addr / blob_size; - end_page_index = addr_end / blob_size; - - for (k = start_page_index; k <= end_page_index; ++k) { - char k_blob[LEN_BLOB_NAME]; - snprintf(k_blob, sizeof(k_blob), "%zu\n", k); - bool blob_exists = check_blob(&file->blob_in_bucket, k); - size_t page_start = k * blob_size; - size_t next_page_start = (k + 1) * blob_size; - - /* Check if addr is in the range of (page_start, next_page_start) */ - /* NOTE: The range does NOT include the start address of page k, - but includes the end address of page k */ - if (addr > page_start && addr < next_page_start) { - size_t page_offset = addr - page_start; - size_t page_write_size; - - if (addr_end < next_page_start) { - /* addr + size is within the same page (only one page) */ - page_write_size = size; - } else { - /* More than one page. Only copy until the end of this page. */ - page_write_size = next_page_start - addr; - } - - /* Fill transfer buffer with existing data, if any. */ - if (blob_exists) { - HermesBucketGet(file->bkt_handle, k_blob, blob_size, file->page_buf); - } else { - /* Populate this page from the original file */ - size_t gap_size = H5FD__hermes_get_gap_size(file, k); - herr_t status = - H5FD__hermes_read_gap(file, page_start, file->page_buf, gap_size); - if (status != SUCCEED) { - H5FD_HERMES_GOTO_DONE(FAIL); - } - } - - memcpy(file->page_buf + page_offset, (char *)buf + transfer_size, - page_write_size); - transfer_size += page_write_size; - - /* Write Blob k to Hermes. */ - HermesBucketPut(file->bkt_handle, k_blob, file->page_buf, blob_size); - set_blob(&file->blob_in_bucket, k); - } else if (addr_end >= page_start && addr_end < next_page_start - 1) { - /* NOTE: The range includes the start address of page k, but does NOT - include the end address of page k */ - - /* Read blob back */ - if (blob_exists) { - HermesBucketGet(file->bkt_handle, k_blob, blob_size, file->page_buf); - } else { - /* Populate this page from the original file */ - size_t gap_size = H5FD__hermes_get_gap_size(file, k); - herr_t status = - H5FD__hermes_read_gap(file, page_start, file->page_buf, gap_size); - if (status != SUCCEED) { - H5FD_HERMES_GOTO_DONE(FAIL); - } - } - - /* Update transfer buffer */ - memcpy(file->page_buf, (char *)buf + transfer_size, - addr_end - page_start + 1); - transfer_size += addr_end - page_start + 1; - /* Write Blob k to Hermes. */ - HermesBucketPut(file->bkt_handle, k_blob, file->page_buf, blob_size); - set_blob(&file->blob_in_bucket, k); - } else if (addr <= page_start && addr_end >= next_page_start - 1) { - /* The write spans this page entirely */ - /* Write Blob k to Hermes buffering system */ - HermesBucketPut(file->bkt_handle, k_blob, (char *)buf + transfer_size, - blob_size); - set_blob(&(file->blob_in_bucket), k); - transfer_size += blob_size; - } - } - - /* Update current position and eof */ - file->pos = addr + size; - file->op = OP_WRITE; - if (file->pos > file->eof) file->eof = file->pos; - -done: - if (ret_value < 0) { - /* Reset last file I/O information */ - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - } /* end if */ - - H5FD_HERMES_FUNC_LEAVE_API; -} /* end H5FD__hermes_write() */ - -/* - * Stub routines for dynamic plugin loading - */ -H5PL_type_t H5PLget_plugin_type(void) { return H5PL_TYPE_VFD; } - -const void *H5PLget_plugin_info(void) { return &H5FD_hermes_g; } - -/* NOTE(chogan): Question: Why do we intercept initialization and termination of - * HDF5 and MPI? Answer: We have to handle several possible cases in order to - * get the initialization and finalization order of Hermes correct. First, the - * HDF5 application using the Hermes VFD can be either an MPI application or a - * serial application. If it's a serial application, we simply initialize Hermes - * before initializing the HDF5 library by intercepting H5_init_library. See - * https://github.com/HDFGroup/hermes/issues/385 for an explanation of why we - * need to initialize Hermes before HDF5. - * - * If we're dealing with an MPI application, then there are two possibilities: - * the app called MPI_Init before any HDF5 calls, or it made at least one HDF5 - * call before calling MPI_Init. If HDF5 was called first, then we have to - * initialize MPI ourselves and then intercept the app's call to MPI_Init to - * ensure MPI_Init is not called twice. - * - * For finalization, there are two cases to handle: 1) The application called - * MPI_Finalize(). In this case we need to intercept MPI_Finalize and shut down - * Hermes before MPI is finalized because Hermes finalization requires MPI. 2) - * If the app is serial, we need to call MPI_Finalize ourselves, so we intercept - * H5_term_library().*/ - -herr_t H5_init_library() { - herr_t ret_value = SUCCEED; - - if (mpi_is_initialized == FALSE) { - int status = PMPI_Init(NULL, NULL); - if (status != MPI_SUCCESS) { - // NOTE(chogan): We can't use the HDF5 error reporting functions here - // because HDF5 isn't initialized yet. - fprintf(stderr, "Hermes VFD: can't initialize MPI\n"); - ret_value = FAIL; - } else { - mpi_is_initialized = TRUE; - } - } - - if (ret_value == SUCCEED) { - if (hermes_initialized == FAIL) { - char *hermes_config = getenv(kHermesConf); - int status = HermesInitHermes(hermes_config); - if (status == 0) { - hermes_initialized = TRUE; - } else { - fprintf(stderr, "Hermes VFD: can't initialize Hermes\n"); - ret_value = FAIL; - } - } - - if (hermes_initialized == TRUE) { - MAP_OR_FAIL(H5_init_library); - ret_value = real_H5_init_library_(); - } - } - - return ret_value; -} - -herr_t H5_term_library() { - MAP_OR_FAIL(H5_term_library); - herr_t ret_value = real_H5_term_library_(); - - if (hermes_initialized == TRUE) { - HermesFinalize(); - hermes_initialized = FALSE; - } - - if (mpi_is_initialized) { - MPI_Finalize(); - mpi_is_initialized = FALSE; - } - - return ret_value; -} - -/** Only Initialize MPI if it hasn't already been initialized. */ -int MPI_Init(int *argc, char ***argv) { - int status = MPI_SUCCESS; - if (mpi_is_initialized == FALSE) { - int status = PMPI_Init(argc, argv); - if (status == MPI_SUCCESS) { - mpi_is_initialized = TRUE; - } - } - - return status; -} - -int MPI_Finalize() { - MAP_OR_FAIL(H5_term_library); - real_H5_term_library_(); - - if (hermes_initialized == TRUE) { - HermesFinalize(); - hermes_initialized = FALSE; - } - - int status = PMPI_Finalize(); - if (status == MPI_SUCCESS) { - mpi_is_initialized = FALSE; - } - - return status; -} diff --git a/hermes_adapters/vfd/H5FDhermes_err.h b/hermes_adapters/vfd/H5FDhermes_err.h deleted file mode 100644 index 024bc7041..000000000 --- a/hermes_adapters/vfd/H5FDhermes_err.h +++ /dev/null @@ -1,199 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of the HDF5 HERMES Virtual File Driver. The full * - * copyright notice, including terms governing use, modification, and * - * redistribution, is contained in the COPYING file, which can be found at * - * the root of the source code distribution tree. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Error handling for the HERMES VFD - */ - -#ifndef H5FDhermes_err_h -#define H5FDhermes_err_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include "H5Epublic.h" - -extern hid_t H5FDhermes_err_stack_g; -extern hid_t H5FDhermes_err_class_g; - -#define H5FD_HERMES_ERR_CLS_NAME "HDF5 HERMES VFD" -#define H5FD_HERMES_ERR_LIB_NAME "HDF5 HERMES VFD" -#define H5FD_HERMES_ERR_VER "0.1.0" - -#define SUCCEED 0 -#define FAIL (-1) - -#ifndef FALSE -#define FALSE false -#endif -#ifndef TRUE -#define TRUE true -#endif - -#define H5_ATTR_UNUSED __attribute__((unused)) - -/* Error macros */ - -/* - * Macro to push the current function to the current error stack - * and then goto the "done" label, which should appear inside the - * function. (compatible with v1 and v2 errors) - */ -#define H5FD_HERMES_GOTO_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) { \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - } else { \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - } \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || \ - (!is_v2_err && err_func.err_func_v1)) { \ - if (H5FDhermes_err_stack_g >= 0 && H5FDhermes_err_class_g >= 0) { \ - H5Epush2(H5FDhermes_err_stack_g, __FILE__, __func__, __LINE__, \ - H5FDhermes_err_class_g, err_major, err_minor, __VA_ARGS__); \ - } else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to push the current function to the current error stack - * without calling goto. This is used for handling the case where - * an error occurs during cleanup past the "done" label inside a - * function so that an infinite loop does not occur where goto - * continually branches back to the label. (compatible with v1 - * and v2 errors) - */ -#define H5FD_HERMES_DONE_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) { \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - } else { \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - } \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || \ - (!is_v2_err && err_func.err_func_v1)) { \ - if (H5FDhermes_err_stack_g >= 0 && H5FDhermes_err_class_g >= 0) { \ - H5Epush2(H5FDhermes_err_stack_g, __FILE__, __func__, __LINE__, \ - H5FDhermes_err_class_g, err_major, err_minor, __VA_ARGS__); \ - } else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - } while (0) - -/* - * Macro to print out the current error stack and then clear it - * for future use. (compatible with v1 and v2 errors) - */ -#define PRINT_ERROR_STACK \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) { \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - } else { \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - } \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || \ - (!is_v2_err && err_func.err_func_v1)) { \ - if ((H5FDhermes_err_stack_g >= 0) && \ - (H5Eget_num(H5FDhermes_err_stack_g) > 0)) { \ - H5Eprint2(H5FDhermes_err_stack_g, NULL); \ - H5Eclear2(H5FDhermes_err_stack_g); \ - } \ - } \ - } while (0) - -#define H5FD_HERMES_SYS_GOTO_ERROR(err_major, err_minor, ret_val, str) \ - do { \ - int myerrno = errno; \ - H5FD_HERMES_GOTO_ERROR(err_major, err_minor, ret_val, \ - "%s, errno = %d, error message = '%s'", str, \ - myerrno, strerror(myerrno)); \ - } while (0) - -/* - * Macro to simply jump to the "done" label inside the function, - * setting ret_value to the given value. This is often used for - * short circuiting in functions when certain conditions arise. - */ -#define H5FD_HERMES_GOTO_DONE(ret_val) \ - do { \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to return from a top-level API function, printing - * out the error stack on the way out. - * It should be ensured that this macro is only called once - * per HDF5 operation. If it is called multiple times per - * operation (e.g. due to calling top-level API functions - * internally), the error stack will be inconsistent/incoherent. - */ -#define H5FD_HERMES_FUNC_LEAVE_API \ - do { \ - PRINT_ERROR_STACK; \ - return ret_value; \ - } while (0) - -/* - * Macro to return from internal functions. - */ -#define H5FD_HERMES_FUNC_LEAVE \ - do { \ - return ret_value; \ - } while (0) - -#ifdef __cplusplus -} -#endif - -#endif /* H5FDhermes_err_h */ diff --git a/hermes_shm/benchmark/allocator/test_init.h b/hermes_shm/benchmark/allocator/test_init.h deleted file mode 100644 index 7a15ca33b..000000000 --- a/hermes_shm/benchmark/allocator/test_init.h +++ /dev/null @@ -1,45 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_BENCHMARK_DATA_STRUCTURE_TEST_INIT_H_ -#define HERMES_BENCHMARK_DATA_STRUCTURE_TEST_INIT_H_ - -#include - -#include -#include -#include -#include -#include - -#include "hermes_shm/data_structures/data_structure.h" - -using hshm::ipc::Allocator; -using hshm::ipc::allocator_id_t; -using hshm::ipc::AllocatorType; -using hshm::ipc::MemoryBackend; -using hshm::ipc::MemoryBackendType; -using hshm::ipc::Pointer; - -using hshm::ipc::Allocator; -using hshm::ipc::allocator_id_t; -using hshm::ipc::AllocatorType; -using hshm::ipc::MemoryBackend; -using hshm::ipc::MemoryBackendType; -using hshm::ipc::MemoryManager; -using hshm::ipc::Pointer; - -using Timer = hshm::HighResMonotonicTimer; - -extern const std::string shm_url; - -#endif // HERMES_BENCHMARK_DATA_STRUCTURE_TEST_INIT_H_ diff --git a/hermes_shm/benchmark/data_structure/test_init.h b/hermes_shm/benchmark/data_structure/test_init.h deleted file mode 100644 index 68a39a85d..000000000 --- a/hermes_shm/benchmark/data_structure/test_init.h +++ /dev/null @@ -1,175 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_BENCHMARK_DATA_STRUCTURE_TEST_INIT_H_ -#define HERMES_BENCHMARK_DATA_STRUCTURE_TEST_INIT_H_ - -#include -#include - -#include -#include -#include -#include -#include - -#include "hermes_shm/data_structures/data_structure.h" - -using hshm::ipc::Allocator; -using hshm::ipc::allocator_id_t; -using hshm::ipc::AllocatorType; -using hshm::ipc::MemoryBackend; -using hshm::ipc::MemoryBackendType; -using hshm::ipc::Pointer; - -using hshm::ipc::Allocator; -using hshm::ipc::allocator_id_t; -using hshm::ipc::AllocatorType; -using hshm::ipc::MemoryBackend; -using hshm::ipc::MemoryBackendType; -using hshm::ipc::MemoryManager; -using hshm::ipc::Pointer; - -namespace bipc = boost::interprocess; - -/** Shared memory segment (a large contiguous region) */ -typedef bipc::managed_shared_memory::segment_manager segment_manager_t; - -/** Create boost segment singleton */ -struct BoostSegment { - std::unique_ptr segment_; - - BoostSegment() { - bipc::shared_memory_object::remove("HermesBoostBench"); - segment_ = std::make_unique( - bipc::create_only, "HermesBoostBench", GIGABYTES(4)); - } -}; -#define BOOST_SEGMENT \ - hshm::EasySingleton::GetInstance()->segment_.get() - -/** Create boost allocator singleton */ -template -struct BoostAllocator { - typedef bipc::allocator alloc_t; - alloc_t alloc_; - - BoostAllocator() : alloc_(BOOST_SEGMENT->get_segment_manager()) {} -}; -#define BOOST_ALLOCATOR(T) \ - hshm::EasySingleton>::GetInstance()->alloc_ - -/** A generic string using allocator */ -typedef boost::interprocess::basic_string< - char, std::char_traits, typename BoostAllocator::alloc_t> - bipc_string; - -/** Instance of the segment */ -extern std::unique_ptr segment_g; - -/** - * Converts an arbitrary type to std::string or int - * */ -template -struct StringOrInt { - typedef typename hshm::type_switch< - T, size_t, size_t, size_t, std::string, std::string, hipc::string, - hipc::uptr, bipc_string, bipc_string*>::type internal_t; - internal_t internal_; - - /** Convert from int to internal_t */ - StringOrInt(size_t num) { - if constexpr (std::is_same_v) { - internal_ = num; - } else if constexpr (std::is_same_v) { - internal_ = std::to_string(num); - } else if constexpr (std::is_same_v) { - internal_ = hipc::make_uptr(std::to_string(num)); - } else if constexpr (std::is_same_v) { - internal_ = BOOST_SEGMENT->find_or_construct("MyString")( - BOOST_ALLOCATOR(bipc_string)); - } - } - - /** Get the internal type */ - T& Get() { - if constexpr (std::is_same_v) { - return internal_; - } else if constexpr (std::is_same_v) { - return internal_; - } else if constexpr (std::is_same_v) { - return *internal_; - } else if constexpr (std::is_same_v) { - return *internal_; - } - } - - /** Convert internal_t to int */ - size_t ToInt() { - if constexpr (std::is_same_v) { - return internal_; - } else { - size_t num; - std::stringstream(ToString(internal_)) >> num; - return num; - } - } - - /** Convert internal_t to std::string */ - std::string ToString() { - if constexpr (std::is_same_v) { - return std::to_string(internal_); - } else if constexpr (std::is_same_v) { - return internal_; - } else if constexpr (std::is_same_v) { - return internal_->str(); - } else if constexpr (std::is_same_v) { - return std::string(internal_->c_str(), internal_->length()); - } - } - - /** Destructor */ - ~StringOrInt() { - if constexpr (std::is_same_v) { - } else if constexpr (std::is_same_v) { - } else if constexpr (std::is_same_v) { - } else if constexpr (std::is_same_v) { - BOOST_SEGMENT->destroy("MyString"); - } - } -}; - -/** - * Gets the semantic name of a type - * */ -template -struct InternalTypeName { - static std::string Get() { - if constexpr (std::is_same_v) { - return "hipc::string"; - } else if constexpr (std::is_same_v) { - return "std::string"; - } else if constexpr (std::is_same_v) { - return "bipc::string"; - } else if constexpr (std::is_same_v) { - return "int"; - } - } -}; - -/** Timer */ -using Timer = hshm::HighResMonotonicTimer; - -/** Avoid compiler warning */ -#define USE(var) ptr_ = (void*)&(var); - -#endif // HERMES_BENCHMARK_DATA_STRUCTURE_TEST_INIT_H_ diff --git a/hermes_shm/include/hermes_shm/constants/data_structure_singleton_macros.h b/hermes_shm/include/hermes_shm/constants/data_structure_singleton_macros.h deleted file mode 100644 index 074b202a3..000000000 --- a/hermes_shm/include/hermes_shm/constants/data_structure_singleton_macros.h +++ /dev/null @@ -1,38 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_INCLUDE_HERMES_CONSTANTS_DATA_STRUCTURE_SINGLETON_MACROS_H_H -#define HERMES_INCLUDE_HERMES_CONSTANTS_DATA_STRUCTURE_SINGLETON_MACROS_H_H - -#include - -#define HERMES_SYSTEM_INFO \ - hshm::GlobalSingleton::GetInstance() -#define HERMES_SYSTEM_INFO_T hshm::SystemInfo* - -#define HERMES_MEMORY_REGISTRY \ - hshm::GlobalSingleton::GetInstance() -#define HERMES_MEMORY_REGISTRY_REF \ - hshm::GlobalSingleton::GetRef() -#define HERMES_MEMORY_REGISTRY_T hshm::ipc::MemoryRegistry* - -#define HERMES_MEMORY_MANAGER \ - hshm::GlobalSingleton::GetInstance() -#define HERMES_MEMORY_MANAGER_REF \ - hshm::GlobalSingleton::GetRef() -#define HERMES_MEMORY_MANAGER_T hshm::ipc::MemoryManager* - -#define HERMES_THREAD_MODEL \ - hshm::GlobalSingleton::GetInstance() -#define HERMES_THREAD_MODEL_T hshm::ThreadModelManager* - -#endif // HERMES_INCLUDE_HERMES_CONSTANTS_DATA_STRUCTURE_SINGLETON_MACROS_H_H diff --git a/hermes_shm/include/hermes_shm/constants/macros.h b/hermes_shm/include/hermes_shm/constants/macros.h deleted file mode 100644 index b93c074d6..000000000 --- a/hermes_shm/include/hermes_shm/constants/macros.h +++ /dev/null @@ -1,66 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_MACROS_H -#define HERMES_MACROS_H - -/** Bytes -> Bytes */ -#ifndef BYTES -#define BYTES(n) (size_t)((n) * (((size_t)1) << 0)) -#endif - -/** KILOBYTES -> Bytes */ -#ifndef KILOBYTES -#define KILOBYTES(n) (size_t)((n) * (((size_t)1) << 10)) -#endif - -/** MEGABYTES -> Bytes */ -#ifndef MEGABYTES -#define MEGABYTES(n) (size_t)((n) * (((size_t)1) << 20)) -#endif - -/** GIGABYTES -> Bytes */ -#ifndef GIGABYTES -#define GIGABYTES(n) (size_t)((n) * (((size_t)1) << 30)) -#endif - -/** TERABYTES -> Bytes */ -#ifndef TERABYTES -#define TERABYTES(n) (size_t)((n) * (((size_t)1) << 40)) -#endif - -/** PETABYTES -> Bytes */ -#ifndef PETABYTES -#define PETABYTES(n) (size_t)((n) * (((size_t)1) << 50)) -#endif - -/** - * Remove parenthesis surrounding "X" if it has parenthesis - * Used for helper macros which take templated types as parameters - * E.g., let's say we have: - * - * #define HELPER_MACRO(T) TYPE_UNWRAP(T) - * HELPER_MACRO( (std::vector>) ) - * will return std::vector> without the parenthesis - * */ -#define TYPE_UNWRAP(X) ESC(ISH X) -#define ISH(...) ISH __VA_ARGS__ -#define ESC(...) ESC_(__VA_ARGS__) -#define ESC_(...) VAN##__VA_ARGS__ -#define VANISH - -/** - * Ensure that the compiler ALWAYS inlines a particular function. - * */ -#define HSHM_ALWAYS_INLINE __attribute__((always_inline)) - -#endif // HERMES_MACROS_H diff --git a/hermes_shm/include/hermes_shm/data_structures/containers/charbuf.h b/hermes_shm/include/hermes_shm/data_structures/containers/charbuf.h deleted file mode 100644 index 3536da57c..000000000 --- a/hermes_shm/include/hermes_shm/data_structures/containers/charbuf.h +++ /dev/null @@ -1,248 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_INCLUDE_HERMES_TYPES_CHARBUF_H_ -#define HERMES_INCLUDE_HERMES_TYPES_CHARBUF_H_ - -#include - -#include "hermes_shm/memory/memory_registry.h" -#include "hermes_shm/types/real_number.h" - -namespace hshm { - -/** An uninterpreted array of bytes */ -struct charbuf { - /**==================================== - * Variables & Types - * ===================================*/ - - hipc::Allocator *alloc_; /**< The allocator used to allocate data */ - char *data_; /**< The pointer to data */ - size_t size_; /**< The size of data */ - bool destructable_; /**< Whether or not this container owns data */ - - /**==================================== - * Default Constructor - * ===================================*/ - - /** Default constructor */ - charbuf() : alloc_(nullptr), data_(nullptr), size_(0), destructable_(false) {} - - /**==================================== - * Destructor - * ===================================*/ - - /** Destructor */ - ~charbuf() { Free(); } - - /**==================================== - * Emplace Constructors - * ===================================*/ - - /** Size-based constructor */ - explicit charbuf(size_t size) { - Allocate(HERMES_MEMORY_REGISTRY->GetDefaultAllocator(), size); - } - - /** Allocator + Size-based constructor */ - explicit charbuf(hipc::Allocator *alloc, size_t size) { - Allocate(alloc, size); - } - - /**==================================== - * Reference Constructors - * ===================================*/ - - /** Reference constructor. From char* + size */ - explicit charbuf(char *data, size_t size) - : alloc_(nullptr), data_(data), size_(size), destructable_(false) {} - - /** - * Reference constructor. From const char* - * We assume that the data will not be modified by the user, but - * we must cast away the const anyway. - * */ - explicit charbuf(const char *data, size_t size) - : alloc_(nullptr), - data_(const_cast(data)), - size_(size), - destructable_(false) {} - - /**==================================== - * Copy Constructors - * ===================================*/ - - /** Copy constructor. From std::string. */ - explicit charbuf(const std::string &data) { - Allocate(HERMES_MEMORY_REGISTRY->GetDefaultAllocator(), data.size()); - memcpy(data_, data.data(), data.size()); - } - - /** Copy constructor. From charbuf. */ - charbuf(const charbuf &other) { - if (!Allocate(HERMES_MEMORY_REGISTRY->GetDefaultAllocator(), - other.size())) { - return; - } - memcpy(data_, other.data(), size()); - } - - /** Copy assignment operator */ - charbuf &operator=(const charbuf &other) { - if (this != &other) { - Free(); - if (!Allocate(HERMES_MEMORY_REGISTRY->GetDefaultAllocator(), - other.size())) { - return *this; - } - memcpy(data_, other.data(), size()); - } - return *this; - } - - /**==================================== - * Move Constructors - * ===================================*/ - - /** Move constructor */ - charbuf(charbuf &&other) { - alloc_ = other.alloc_; - data_ = other.data_; - size_ = other.size_; - destructable_ = other.destructable_; - other.size_ = 0; - other.destructable_ = false; - } - - /** Move assignment operator */ - charbuf &operator=(charbuf &&other) { - if (this != &other) { - Free(); - alloc_ = other.alloc_; - data_ = other.data_; - size_ = other.size_; - destructable_ = other.destructable_; - other.size_ = 0; - other.destructable_ = false; - } - return *this; - } - - /**==================================== - * Methods - * ===================================*/ - - /** Destroy and resize */ - void resize(size_t new_size) { - if (new_size <= size()) { - size_ = new_size; - return; - } - if (alloc_ == nullptr) { - alloc_ = HERMES_MEMORY_REGISTRY->GetDefaultAllocator(); - } - if (destructable_) { - data_ = alloc_->ReallocatePtr(data_, new_size); - } else { - data_ = alloc_->AllocatePtr(new_size); - } - destructable_ = true; - size_ = new_size; - } - - /** Reference data */ - char *data() { return data_; } - - /** Reference data */ - char *data() const { return data_; } - - /** Reference size */ - size_t size() const { return size_; } - - /** Get allocator */ - hipc::Allocator *GetAllocator() { return alloc_; } - - /** Convert to std::string */ - std::string str() { return std::string(data(), size()); } - - /**==================================== - * Comparison Operators - * ===================================*/ - - int _strncmp(const char *a, size_t len_a, const char *b, size_t len_b) const { - if (len_a != len_b) { - return int((int64_t)len_a - (int64_t)len_b); - } - for (size_t i = 0; i < len_a; ++i) { - if (a[i] != b[i]) { - return a[i] - b[i]; - } - } - return 0; - } - -#define HERMES_STR_CMP_OPERATOR(op) \ - bool operator TYPE_UNWRAP(op)(const char *other) const { \ - return _strncmp(data(), size(), other, strlen(other)) op 0; \ - } \ - bool operator op(const std::string &other) const { \ - return _strncmp(data(), size(), other.data(), other.size()) op 0; \ - } \ - bool operator op(const charbuf &other) const { \ - return _strncmp(data(), size(), other.data(), other.size()) op 0; \ - } - - HERMES_STR_CMP_OPERATOR(==) // NOLINT - HERMES_STR_CMP_OPERATOR(!=) // NOLINT - HERMES_STR_CMP_OPERATOR(<) // NOLINT - HERMES_STR_CMP_OPERATOR(>) // NOLINT - HERMES_STR_CMP_OPERATOR(<=) // NOLINT - HERMES_STR_CMP_OPERATOR(>=) // NOLINT - -#undef HERMES_STR_CMP_OPERATOR - - private: - /**==================================== - * Internal functions - * ===================================*/ - - /** Allocate charbuf */ - bool Allocate(hipc::Allocator *alloc, size_t size) { - hipc::OffsetPointer p; - if (size == 0) { - alloc_ = nullptr; - data_ = nullptr; - size_ = 0; - destructable_ = false; - return false; - } - alloc_ = alloc; - data_ = alloc->AllocatePtr(size, p); - size_ = size; - destructable_ = true; - return true; - } - - /** Explicitly free the charbuf */ - void Free() { - if (destructable_ && data_ && size_) { - alloc_->FreePtr(data_); - } - } -}; - -typedef charbuf string; - -} // namespace hshm - -#endif // HERMES_INCLUDE_HERMES_TYPES_CHARBUF_H_ diff --git a/hermes_shm/include/hermes_shm/data_structures/containers/converters.h b/hermes_shm/include/hermes_shm/data_structures/containers/converters.h deleted file mode 100644 index 8309d54bf..000000000 --- a/hermes_shm/include/hermes_shm/data_structures/containers/converters.h +++ /dev/null @@ -1,58 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_SHM_INCLUDE_HERMES_SHM_DATA_STRUCTURES_IPC_CONVERTERS_H_ -#define HERMES_SHM_INCLUDE_HERMES_SHM_DATA_STRUCTURES_IPC_CONVERTERS_H_ - -#include -#include - -#include "hermes_shm/data_structures/data_structure.h" - -namespace hshm { - -/** Convert an iterable object into a vector */ -template -std::vector to_stl_vector(const SharedT &other) { - std::vector vec; - vec.reserve(other.size()); - auto end = other.cend(); - for (auto iter = other.cbegin(); iter != end; ++iter) { - T &obj = (*iter); - vec.emplace_back(obj); - } - return vec; -} - -/** Convert an iterable object into a list */ -template -std::list to_stl_list(const SharedT &other) { - std::list vec; - auto end = other.cend(); - for (auto iter = other.cbegin(); iter != end; ++iter) { - T &obj = (*iter); - vec.emplace_back(obj); - } - return vec; -} - -/** Convert a string to an hshm::charbuf */ -template -hshm::charbuf to_charbuf(StringT &other) { - hshm::charbuf text(other.size()); - memcpy(text.data(), other.data(), other.size()); - return text; -} - -} // namespace hshm - -#endif // HERMES_SHM_INCLUDE_HERMES_SHM_DATA_STRUCTURES_IPC_CONVERTERS_H_ diff --git a/hermes_shm/include/hermes_shm/data_structures/containers/functional.h b/hermes_shm/include/hermes_shm/data_structures/containers/functional.h deleted file mode 100644 index 7d3c7b9db..000000000 --- a/hermes_shm/include/hermes_shm/data_structures/containers/functional.h +++ /dev/null @@ -1,31 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_SHM_SHM_DATA_STRUCTURES_CONTAINERS_FUNCTIONAL_H_ -#define HERMES_SHM_SHM_DATA_STRUCTURES_CONTAINERS_FUNCTIONAL_H_ - -namespace hshm { - -template -IteratorT find(IteratorT start, const IteratorT &end, T &val) { - for (; start != end; ++start) { - T &ref = *start; - if (ref == val) { - return start; - } - } - return end; -} - -} // namespace hshm - -#endif // HERMES_SHM_SHM_DATA_STRUCTURES_CONTAINERS_FUNCTIONAL_H_ diff --git a/hermes_shm/include/hermes_shm/data_structures/containers/tuple_base.h b/hermes_shm/include/hermes_shm/data_structures/containers/tuple_base.h deleted file mode 100644 index 9fdfa4bd2..000000000 --- a/hermes_shm/include/hermes_shm/data_structures/containers/tuple_base.h +++ /dev/null @@ -1,223 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_INCLUDE_HERMES_DATA_STRUCTURES_TupleBase_H_ -#define HERMES_INCLUDE_HERMES_DATA_STRUCTURES_TupleBase_H_ - -#include - -#include "hermes_shm/types/argpack.h" -#include "hermes_shm/types/real_number.h" - -namespace hshm { - -/** The null container wrapper */ -template -using NullWrap = T; - -/** Recurrence used to create argument pack */ -template