From daf0359a4c4833f014394c6ceec9056c8b339f69 Mon Sep 17 00:00:00 2001 From: Hyo-Kyung Lee Date: Wed, 2 Nov 2022 10:27:30 -0500 Subject: [PATCH] Remove Doxygen warnings. (#270) --- adapter/adapter_utils.cc | 23 +- adapter/adapter_utils.h | 1 - adapter/constants.h | 4 +- adapter/enumerations.h | 6 +- adapter/filesystem/filesystem.cc | 2 +- adapter/filesystem/filesystem.h | 374 ++- adapter/filesystem/metadata_manager.h | 46 +- adapter/interceptor.cc | 19 + adapter/interceptor.h | 34 +- adapter/mapper/abstract_mapper.h | 38 +- adapter/mapper/balanced_mapper.cc | 34 +- adapter/mapper/balanced_mapper.h | 3 +- adapter/mapper/mapper_factory.h | 11 +- adapter/metadata_manager.h | 43 +- adapter/mpiio/fs_api.h | 297 +- adapter/mpiio/real_api.h | 320 ++- adapter/posix/fs_api.h | 43 +- adapter/posix/real_api.h | 116 +- adapter/pubsub/datastructures.h | 12 +- adapter/pubsub/metadata_manager.h | 50 +- adapter/pubsub/pubsub.h | 7 +- adapter/stdio/fs_api.h | 45 +- adapter/stdio/real_api.h | 166 +- adapter/test/adapter_test_utils.h | 6 +- adapter/test/catch_config.h | 27 +- .../test/mpiio/mpiio_adapter_basic_test.cpp | 21 +- adapter/test/mpiio/mpiio_adapter_test.cpp | 20 +- adapter/test/posix/posix_adapter_mpi_test.cpp | 19 +- adapter/test/posix/posix_adapter_test.cpp | 18 +- .../stdio_adapter_low_buffer_space_test.cpp | 20 +- .../test/stdio/stdio_adapter_mapper_test.cpp | 4 +- .../test/stdio/stdio_adapter_mode_test.cpp | 21 +- adapter/test/stdio/stdio_adapter_mpi_test.cpp | 18 +- adapter/test/stdio/stdio_adapter_test.cpp | 22 +- adapter/test/vfd/hermes_vfd_test.cc | 109 +- ci/install_docs.sh | 16 +- data_stager/data_stager.h | 37 +- data_stager/data_stager_factory.h | 20 +- data_stager/stagers/unix_stager.h | 30 +- doc/Doxyfile.in | 2393 ++++++++++++++++- src/api/bucket.h | 105 +- src/api/hermes.cc | 5 + src/api/hermes.h | 30 +- src/api/traits.cc | 2 - src/api/traits.h | 31 +- src/api/vbucket.h | 35 +- src/buffer_organizer.cc | 21 +- src/buffer_organizer.h | 67 +- src/buffer_pool.cc | 164 +- src/buffer_pool.h | 114 +- src/buffer_pool_internal.h | 4 +- .../buffer_pool_visualizer.cc | 50 +- src/communication.h | 16 +- src/communication_mpi.cc | 38 +- src/config_parser.cc | 20 + src/config_parser.h | 8 +- src/data_placement_engine.cc | 3 + src/data_placement_engine.h | 32 +- src/data_placement_engine_factory.h | 33 +- src/debug_state.h | 24 +- src/dpe/linprog.h | 111 +- src/dpe/minimize_io_time.h | 33 +- src/dpe/random.h | 33 +- src/dpe/round_robin.h | 33 +- src/hermes_status.h | 116 +- src/hermes_types.h | 138 +- src/memory_management.cc | 81 + src/memory_management.h | 97 +- src/metadata_management.cc | 116 +- src/metadata_management.h | 203 +- src/metadata_management_internal.h | 13 +- src/metadata_storage_stb_ds.cc | 76 +- src/rpc.h | 36 +- src/rpc_thallium.cc | 22 + src/rpc_thallium.h | 139 +- src/singleton.h | 3 + src/thread_pool.h | 17 +- src/utils.cc | 4 +- src/utils.h | 46 +- test/test_utils.h | 27 +- 80 files changed, 5079 insertions(+), 1562 deletions(-) diff --git a/adapter/adapter_utils.cc b/adapter/adapter_utils.cc index c00e28674..4afc84634 100644 --- a/adapter/adapter_utils.cc +++ b/adapter/adapter_utils.cc @@ -34,9 +34,12 @@ inline bool is_dotdot(const stdfs::path& path) { namespace hermes { namespace adapter { - -// NOTE(chogan): Back port of the C++17 standard fileystem implementation from -// gcc 9.1 to support gcc 7 +/** + * normalize \a path + * + * \note (chogan): Back port of the C++17 standard fileystem implementation + * from gcc 9.1 to support gcc 7 +*/ stdfs::path LexicallyNormal(stdfs::path &path) { /* C++17 [fs.path.generic] p6 @@ -124,7 +127,10 @@ stdfs::path LexicallyNormal(stdfs::path &path) { return ret; } -// NOTE(chogan): Backported from GCC 9 +/** + convert path \a p to a canonical absolute path + \note (chogan): Backported from GCC 9 +*/ stdfs::path WeaklyCanonical(const stdfs::path& p) { stdfs::path result; if (stdfs::exists(stdfs::status(p))) { @@ -155,7 +161,10 @@ stdfs::path WeaklyCanonical(const stdfs::path& p) { return LexicallyNormal(result); } -// NOTE(chogan): Backported from GCC 9 +/** + convert path \a p to a canonical absolute path with \a ec error code + \note (chogan): Backported from GCC 9 +*/ stdfs::path WeaklyCanonical(const stdfs::path& p, std::error_code& ec) { stdfs::path result; stdfs::file_status st = stdfs::status(p, ec); @@ -201,6 +210,9 @@ stdfs::path WeaklyCanonical(const stdfs::path& p, std::error_code& ec) { return result; } +/** + Read gap from the original file when BLOB has a gap in write. + */ void ReadGap(const std::string &filename, size_t seek_offset, u8 *read_ptr, size_t read_size, size_t file_bounds) { if (stdfs::exists(filename) && @@ -231,6 +243,5 @@ void ReadGap(const std::string &filename, size_t seek_offset, u8 *read_ptr, INTERCEPTOR_LIST->hermes_flush_exclusion.erase(filename); } } - } // namespace adapter } // namespace hermes diff --git a/adapter/adapter_utils.h b/adapter/adapter_utils.h index 81025278d..ed35d3dce 100644 --- a/adapter/adapter_utils.h +++ b/adapter/adapter_utils.h @@ -20,4 +20,3 @@ stdfs::path WeaklyCanonical(const stdfs::path& p); stdfs::path WeaklyCanonical(const stdfs::path& p, std::error_code& ec); } // namespace hermes::adapter - diff --git a/adapter/constants.h b/adapter/constants.h index a2a021d98..9a4a363b6 100644 --- a/adapter/constants.h +++ b/adapter/constants.h @@ -102,11 +102,11 @@ const char* kStopDaemon = "HERMES_STOP_DAEMON"; * it's important to align the page size to your workload. */ const size_t kPageSize = []() { - const char *kPageSizeVar = "HERMES_PAGE_SIZE"; + const char* kPageSizeVar = "HERMES_PAGE_SIZE"; const size_t kDefaultPageSize = 1 * 1024 * 1024; size_t result = kDefaultPageSize; - char *page_size = getenv(kPageSizeVar); + char* page_size = getenv(kPageSizeVar); if (page_size) { result = (size_t)std::strtoull(page_size, NULL, 0); diff --git a/adapter/enumerations.h b/adapter/enumerations.h index 9ff606fe7..e1a506040 100644 --- a/adapter/enumerations.h +++ b/adapter/enumerations.h @@ -14,12 +14,12 @@ #define HERMES_ADAPTER_ENUMERATIONS_H enum class AdapterMode { kDefault = 0, /**< All/given files are stored on file close or flush. */ - kBypass = 1, /**< All/given files are not buffered. */ - kScratch = 2 /**< All/given files are ignored on file close or flush. */ + kBypass = 1, /**< All/given files are not buffered. */ + kScratch = 2 /**< All/given files are ignored on file close or flush. */ }; enum class FlushingMode { - kSynchronous, /**< Flush persistent Blobs synchronously on fclose. */ + kSynchronous, /**< Flush persistent Blobs synchronously on fclose. */ kAsynchronous, /**< Flush persistent Blobs asynchronously on fwrite. */ }; diff --git a/adapter/filesystem/filesystem.cc b/adapter/filesystem/filesystem.cc index d05dd10e6..f5366470b 100644 --- a/adapter/filesystem/filesystem.cc +++ b/adapter/filesystem/filesystem.cc @@ -538,7 +538,7 @@ HermesRequest* Filesystem::ARead(File &f, AdapterStat &stat, void *ptr, return hreq; } -size_t Filesystem::Wait(size_t req_id) { +size_t Filesystem::Wait(uint64_t req_id) { auto mdm = Singleton::GetInstance(); auto req_iter = mdm->request_map.find(req_id); if (req_iter == mdm->request_map.end()) { diff --git a/adapter/filesystem/filesystem.h b/adapter/filesystem/filesystem.h index f5f6e9b8a..ad46e6999 100644 --- a/adapter/filesystem/filesystem.h +++ b/adapter/filesystem/filesystem.h @@ -1,29 +1,31 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_FILESYSTEM_FILESYSTEM_H_ #define HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_H_ -#include "enumerations.h" -#include -#include #include -#include #include +#include #include -#include -#include "mapper/mapper_factory.h" #include +#include +#include + #include +#include + +#include "enumerations.h" +#include "mapper/mapper_factory.h" namespace hapi = hermes::api; @@ -41,8 +43,11 @@ enum class SeekMode { kEnd = SEEK_END }; +/** + A structure to represent adapter stat. +*/ struct AdapterStat { - std::shared_ptr st_bkid; /* bucket associated with the file */ + std::shared_ptr st_bkid; /**< bucket associated with the file */ /** VBucket for persisting data asynchronously. */ std::shared_ptr st_vbkt; /** Blob for locking when coordination is needed. */ @@ -50,25 +55,25 @@ struct AdapterStat { /** Used for async flushing. */ std::shared_ptr st_persist; std::set - st_blobs; /* Blobs access in the bucket */ - i32 ref_count; /* # of time process opens a file */ - int flags; /* open() flags for POSIX */ - mode_t st_mode; /* protection */ - uid_t st_uid; /* user ID of owner */ - gid_t st_gid; /* group ID of owner */ - size_t st_size; /* total size, in bytes */ - off_t st_ptr; /* Current ptr of FILE */ - blksize_t st_blksize; /* blocksize for blob within bucket */ - 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() */ - - bool is_append; /* File is in append mode */ - int amode; /* access mode */ - MPI_Info info; /* Info object (handle) */ - MPI_Comm comm; /* Communicator for the file.*/ - bool atomicity; /* Consistency semantics for data-access */ + st_blobs; /**< Blobs access in the bucket */ + i32 ref_count; /**< # of time process opens a file */ + int flags; /**< open() flags for POSIX */ + mode_t st_mode; /**< protection */ + uid_t st_uid; /**< user ID of owner */ + gid_t st_gid; /**< group ID of owner */ + size_t st_size; /**< total size, in bytes */ + off_t st_ptr; /**< Current ptr of FILE */ + blksize_t st_blksize; /**< blocksize for blob within bucket */ + 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() */ + + bool is_append; /**< File is in append mode */ + int amode; /**< access mode */ + MPI_Info info; /**< Info object (handle) */ + MPI_Comm comm; /**< Communicator for the file.*/ + bool atomicity; /**< Consistency semantics for data-access */ AdapterStat() : st_bkid(), @@ -88,39 +93,45 @@ struct AdapterStat { amode(0), comm(MPI_COMM_SELF), atomicity(false) {} - + /** compare \a a BLOB and \a b BLOB.*/ static bool CompareBlobs(const std::string &a, const std::string &b) { return std::stol(a) < std::stol(b); } }; +/** + A structure to represent file +*/ struct File { - int fd_; - FILE *fh_; - MPI_File mpi_fh_; - - dev_t st_dev; - ino_t st_ino; - bool status_; - int mpi_status_; - - File() : fd_(-1), - fh_(nullptr), - mpi_fh_(nullptr), - st_dev(-1), - st_ino(-1), - status_(true), - mpi_status_(MPI_SUCCESS) {} - - File(const File &old) { - Copy(old); - } - + int fd_; /**< file descriptor */ + FILE *fh_; /**< file handler */ + MPI_File mpi_fh_; /**< MPI file handler */ + + dev_t st_dev; /**< device */ + ino_t st_ino; /**< inode */ + bool status_; /**< status */ + int mpi_status_; /**< MPI status */ + + /** default file constructor */ + File() + : fd_(-1), + fh_(nullptr), + mpi_fh_(nullptr), + st_dev(-1), + st_ino(-1), + status_(true), + mpi_status_(MPI_SUCCESS) {} + + /** file constructor that copies \a old file */ + File(const File &old) { Copy(old); } + + /** file assignment operator that copies \a old file */ File &operator=(const File &old) { Copy(old); return *this; } + /** copy \a old file */ void Copy(const File &old) { fd_ = old.fd_; fh_ = old.fh_; @@ -130,11 +141,13 @@ struct File { status_ = old.status_; } + /** file comparison operator */ bool operator==(const File &old) const { return (st_dev == old.st_dev) && (st_ino == old.st_ino) && (mpi_fh_ == old.mpi_fh_); } + /** return hash value of this class */ std::size_t hash() const { std::size_t result; std::size_t h1 = std::hash{}(st_dev); @@ -145,20 +158,25 @@ struct File { } }; +/** + A structure to represent IO options +*/ struct IoOptions { - PlacementPolicy dpe_; - bool coordinate_; - bool seek_; - bool with_fallback_; - MPI_Datatype mpi_type_; - int count_; - IoOptions() : - dpe_(PlacementPolicy::kNone), - coordinate_(true), - seek_(true), - with_fallback_(true), - mpi_type_(MPI_CHAR), count_(0) {} - + PlacementPolicy dpe_; /**< data placement policy */ + bool coordinate_; /**< use coordinate? */ + bool seek_; /**< use seek? */ + bool with_fallback_; /**< use fallback? */ + MPI_Datatype mpi_type_; /**< MPI data type */ + int count_; /**< option count */ + IoOptions() + : dpe_(PlacementPolicy::kNone), + coordinate_(true), + seek_(true), + with_fallback_(true), + mpi_type_(MPI_CHAR), + count_(0) {} + + /** return options with \a dpe parallel data placement engine */ static IoOptions WithParallelDpe(PlacementPolicy dpe) { IoOptions opts; opts.dpe_ = dpe; @@ -166,6 +184,7 @@ struct IoOptions { return opts; } + /** return direct IO options by setting placement policy to none */ static IoOptions DirectIo(IoOptions &cur_opts) { IoOptions opts(cur_opts); opts.seek_ = false; @@ -174,6 +193,7 @@ struct IoOptions { return opts; } + /** return IO options with \a mpi_type MPI data type */ static IoOptions DataType(MPI_Datatype mpi_type, bool seek = true) { IoOptions opts; opts.mpi_type_ = mpi_type; @@ -182,68 +202,97 @@ struct IoOptions { } }; +/** + A structure to represent IO status +*/ struct IoStatus { - int mpi_ret_; - MPI_Status mpi_status_; - MPI_Status *mpi_status_ptr_; + int mpi_ret_; /**< MPI return value */ + MPI_Status mpi_status_; /**< MPI status */ + MPI_Status *mpi_status_ptr_; /**< MPI status pointer */ IoStatus() : mpi_ret_(MPI_SUCCESS), mpi_status_ptr_(&mpi_status_) {} }; +/** + A structure to represent Hermes request +*/ struct HermesRequest { - std::future return_future; - IoStatus io_status; + std::future return_future; /**< future result of async op. */ + IoStatus io_status; /**< IO status */ }; +/** + A structure to represent BLOB placement iterator +*/ struct BlobPlacementIter { - File &f_; - AdapterStat &stat_; - const std::string &filename_; - const BlobPlacement &p_; - std::shared_ptr &bkt_; - IoStatus &io_status_; - IoOptions &opts_; - - std::string blob_name_; - u8 *mem_ptr_; - size_t blob_start_; - hapi::Context ctx_; - hapi::Blob blob_; - int rank_; - int nprocs_; - bool blob_exists_; - + File &f_; /**< file */ + AdapterStat &stat_; /**< adapter stat */ + const std::string &filename_; /**< file name */ + const BlobPlacement &p_; /**< BLOB placement */ + std::shared_ptr &bkt_; /**< bucket*/ + IoStatus &io_status_; /**< IO status */ + IoOptions &opts_; /**< IO options */ + + std::string blob_name_; /**< BLOB name */ + u8 *mem_ptr_; /**< pointer to memory */ + size_t blob_start_; /**< BLOB start */ + hapi::Context ctx_; /**< context */ + hapi::Blob blob_; /**< BLOB */ + int rank_; /**< MPI rank */ + int nprocs_; /**< number of processes */ + bool blob_exists_; /**< Does BLOB exist? */ + + /** iterate \a p BLOB placement */ explicit BlobPlacementIter(File &f, AdapterStat &stat, const std::string &filename, const BlobPlacement &p, std::shared_ptr &bkt, - IoStatus &io_status, - IoOptions &opts) : - f_(f), stat_(stat), filename_(filename), - p_(p), bkt_(bkt), io_status_(io_status), opts_(opts) {} + IoStatus &io_status, IoOptions &opts) + : f_(f), + stat_(stat), + filename_(filename), + p_(p), + bkt_(bkt), + io_status_(io_status), + opts_(opts) {} }; +/** + A class to represent file system +*/ class Filesystem { public: + /** 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); - size_t Write(File &f, AdapterStat &stat, const void *ptr, - size_t off, size_t total_size, IoStatus &io_status, + /** write */ + size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t off, + size_t total_size, IoStatus &io_status, IoOptions opts = IoOptions()); - size_t Read(File &f, AdapterStat &stat, void *ptr, - size_t off, size_t total_size, IoStatus &io_status, + /** read */ + size_t Read(File &f, AdapterStat &stat, void *ptr, size_t off, + size_t total_size, IoStatus &io_status, IoOptions opts = IoOptions()); - HermesRequest* AWrite(File &f, AdapterStat &stat, const void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts = IoOptions()); - HermesRequest* ARead(File &f, AdapterStat &stat, void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts = IoOptions()); + /** 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, + IoOptions opts = IoOptions()); + /** read asynchronously */ + HermesRequest *ARead(File &f, AdapterStat &stat, void *ptr, size_t off, + size_t total_size, size_t req_id, IoStatus &io_status, + IoOptions opts = IoOptions()); + /** 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, off_t offset); + /** tell */ off_t Tell(File &f, AdapterStat &stat); + /** sync */ int Sync(File &f, AdapterStat &stat); + /** close */ int Close(File &f, AdapterStat &stat, bool destroy = true); /* @@ -251,17 +300,27 @@ class Filesystem { * */ private: + /** coordinated put */ void _CoordinatedPut(BlobPlacementIter &wi); + /** uncoordinated put */ void _UncoordinatedPut(BlobPlacementIter &wi); + /** write to a new aligned buffer */ void _WriteToNewAligned(BlobPlacementIter &write_iter); + /** write to a new unaligned buffer */ void _WriteToNewUnaligned(BlobPlacementIter &write_iter); + /** write to an existing aligned buffer */ void _WriteToExistingAligned(BlobPlacementIter &write_iter); + /** write to an existing unaligned buffer */ void _WriteToExistingUnaligned(BlobPlacementIter &write_iter); + /** put with fallback */ void _PutWithFallback(AdapterStat &stat, const std::string &blob_name, const std::string &filename, u8 *data, size_t size, size_t offset, IoStatus &io_status_, IoOptions &opts); + /** read existing contained buffer */ size_t _ReadExistingContained(BlobPlacementIter &read_iter); + /** read existing partial buffer */ size_t _ReadExistingPartial(BlobPlacementIter &read_iter); + /** read new buffer */ size_t _ReadNew(BlobPlacementIter &read_iter); void _OpenInitStatsInternal(AdapterStat &stat, bool bucket_exists) { @@ -290,86 +349,109 @@ class Filesystem { /* * The APIs to overload - * */ + */ public: + /** initialize file */ virtual void _InitFile(File &f) = 0; private: + /** open initial status */ virtual void _OpenInitStats(File &f, AdapterStat &stat) = 0; + /** real open */ virtual File _RealOpen(AdapterStat &stat, const std::string &path) = 0; + /** real write */ virtual size_t _RealWrite(const std::string &filename, off_t offset, size_t size, const u8 *data_ptr, IoStatus &io_status, IoOptions &opts) = 0; + /** real read */ virtual size_t _RealRead(const std::string &filename, off_t offset, - size_t size, u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) = 0; + size_t size, u8 *data_ptr, IoStatus &io_status, + IoOptions &opts) = 0; + /** io status */ virtual void _IoStats(size_t count, IoStatus &io_status, IoOptions &opts) { - (void) count; (void) io_status; (void) opts; + (void)count; + (void)io_status; + (void)opts; } + /** real sync */ virtual int _RealSync(File &f) = 0; + /** real close */ virtual int _RealClose(File &f) = 0; /* * I/O APIs which seek based on the internal AdapterStat st_ptr, * instead of taking an offset as input. - * */ + */ public: - size_t Write(File &f, AdapterStat &stat, const void *ptr, - size_t total_size, IoStatus &io_status, IoOptions opts); - size_t Read(File &f, AdapterStat &stat, void *ptr, - size_t total_size, IoStatus &io_status, IoOptions opts); - HermesRequest* AWrite(File &f, AdapterStat &stat, const void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts); - HermesRequest* ARead(File &f, AdapterStat &stat, void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts); + /** write */ + size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t total_size, + IoStatus &io_status, IoOptions opts); + /** read */ + size_t Read(File &f, AdapterStat &stat, void *ptr, size_t total_size, + IoStatus &io_status, IoOptions opts); + /** write asynchronously */ + HermesRequest *AWrite(File &f, AdapterStat &stat, const void *ptr, + size_t total_size, size_t req_id, IoStatus &io_status, + IoOptions opts); + /** read asynchronously */ + HermesRequest *ARead(File &f, AdapterStat &stat, void *ptr, size_t total_size, + size_t req_id, IoStatus &io_status, IoOptions opts); /* * Locates the AdapterStat data structure internally, and * call the underlying APIs which take AdapterStat as input. - * */ + */ public: - size_t Write(File &f, bool &stat_exists, const void *ptr, + /** write */ + size_t Write(File &f, bool &stat_exists, const void *ptr, size_t total_size, + IoStatus &io_status, IoOptions opts = IoOptions()); + /** read */ + size_t Read(File &f, bool &stat_exists, void *ptr, size_t total_size, + IoStatus &io_status, IoOptions opts = IoOptions()); + /** 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, IoOptions opts = IoOptions()); - size_t Read(File &f, bool &stat_exists, void *ptr, + /** read \a off offset */ + size_t Read(File &f, bool &stat_exists, void *ptr, size_t off, size_t total_size, IoStatus &io_status, IoOptions opts = IoOptions()); - size_t Write(File &f, bool &stat_exists, const void *ptr, - size_t off, size_t total_size, IoStatus &io_status, - IoOptions opts = IoOptions()); - size_t Read(File &f, bool &stat_exists, void *ptr, - size_t off, size_t total_size, IoStatus &io_status, - IoOptions opts = IoOptions()); - - HermesRequest* AWrite(File &f, bool &stat_exists, const void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts); - HermesRequest* ARead(File &f, bool &stat_exists, void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts); - HermesRequest* AWrite(File &f, bool &stat_exists, const void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts); - HermesRequest* ARead(File &f, bool &stat_exists, void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, IoOptions opts); - + /** write asynchronously */ + HermesRequest *AWrite(File &f, bool &stat_exists, const void *ptr, + size_t total_size, size_t req_id, IoStatus &io_status, + IoOptions opts); + /** read asynchronously */ + HermesRequest *ARead(File &f, bool &stat_exists, void *ptr, size_t total_size, + size_t req_id, IoStatus &io_status, IoOptions 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, + IoOptions 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, + IoOptions opts); + /** seek */ off_t Seek(File &f, bool &stat_exists, SeekMode whence, off_t offset); + /** tell */ off_t Tell(File &f, bool &stat_exists); + /** sync */ int Sync(File &f, bool &stat_exists); + /** close */ int Close(File &f, bool &stat_exists, bool destroy = true); }; - } // namespace hermes::adapter::fs namespace std { +/** + A structure to represent hash +*/ template <> struct hash { + /** hash creator functor */ std::size_t operator()(const hermes::adapter::fs::File &key) const { return key.hash(); } diff --git a/adapter/filesystem/metadata_manager.h b/adapter/filesystem/metadata_manager.h index 10ec37bf4..f71030e03 100644 --- a/adapter/filesystem/metadata_manager.h +++ b/adapter/filesystem/metadata_manager.h @@ -14,15 +14,15 @@ #define HERMES_ADAPTER_METADATA_MANAGER_H #include +#include + #include #include -#include - #include "constants.h" #include "enumerations.h" -#include "interceptor.h" #include "filesystem.h" +#include "interceptor.h" namespace hermes::adapter::fs { /** @@ -30,34 +30,30 @@ namespace hermes::adapter::fs { */ class MetadataManager { private: - std::unordered_map metadata; - std::shared_ptr hermes; + std::unordered_map metadata; /**< map for metadata*/ + std::shared_ptr hermes; /**< pointers for hermes */ /** * references of how many times hermes was tried to initialize. */ std::atomic ref; public: + /** map for Hermes request */ std::unordered_map request_map; - bool is_mpi; - int rank; - int comm_size; + bool is_mpi; /**< flag for checking if MPI is used */ + int rank; /**< rank of MPI processor */ + int comm_size; /**< number of MPI processors */ /** * Constructor */ MetadataManager() - : metadata(), - ref(0), - is_mpi(false), - rank(0), - comm_size(1) {} + : metadata(), ref(0), is_mpi(false), rank(0), comm_size(1) {} /** * Get the instance of hermes. */ std::shared_ptr& GetHermes() { return hermes; } - /** * Initialize hermes. Get the kHermesConf from environment else get_env * returns NULL which is handled internally by hermes. Initialize hermes in @@ -102,7 +98,7 @@ class MetadataManager { if (ref == 1) { if (this->is_mpi) { MPI_Barrier(MPI_COMM_WORLD); - char *stop_daemon = getenv(kStopDaemon); + char* stop_daemon = getenv(kStopDaemon); bool shutdown_daemon = true; if (stop_daemon && stop_daemon[0] == '0') { shutdown_daemon = false; @@ -117,38 +113,38 @@ class MetadataManager { /** * Create a metadata entry for POSIX adapter for a given file handler. - * @param fh, int, original file handler of the file on the destination + * @param f original file handler of the file on the destination * filesystem. - * @param stat, AdapterStat, POSIX Adapter version of Stat data structure. + * @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, const AdapterStat& stat); + bool Create(const File& f, const AdapterStat& stat); /** * Update existing metadata entry for POSIX adapter for a given file handler. - * @param fh, int, original file handler of the file on the destination. - * @param stat, AdapterStat, POSIX Adapter version of Stat data structure. + * @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); + bool Update(const File& f, const AdapterStat& stat); /** * Delete existing metadata entry for POSIX adapter for a given file handler. - * @param fh, int, original file handler of the file on the destination. + * @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 File &f); + bool Delete(const File& f); /** * Find existing metadata entry for POSIX adapter for a given file handler. - * @param fh, int, original file handler of the file on the destination. + * @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::pair Find(const File &f); + std::pair Find(const File& f); }; } // namespace hermes::adapter::fs diff --git a/adapter/interceptor.cc b/adapter/interceptor.cc index ca477c476..8a845b413 100644 --- a/adapter/interceptor.cc +++ b/adapter/interceptor.cc @@ -32,10 +32,20 @@ namespace hermes::adapter { */ bool exit = false; +/** + * a flag for checking if buffering paths are populated or not + */ bool populated = false; +/** + populate buffering path +*/ void PopulateBufferingPath() { char* hermes_config = getenv(kHermesConf); + if (hermes_config == NULL) { + LOG(ERROR) << "HERMES_CONF is not set."; + return; + } if (stdfs::exists(hermes_config)) { std::string hermes_conf_abs_path = @@ -73,6 +83,9 @@ void PopulateBufferingPath() { populated = true; } +/** + check if \a path is being tracked +*/ bool IsTracked(const std::string& path) { if (hermes::adapter::exit) { return false; @@ -128,12 +141,18 @@ bool IsTracked(const std::string& path) { } } +/** + check if \a fh file handler is being tracked +*/ bool IsTracked(FILE* fh) { if (hermes::adapter::exit) return false; atexit(OnExit); return IsTracked(GetFilenameFromFP(fh)); } +/** + check if \a fd file descriptor is being tracked +*/ bool IsTracked(int fd) { if (hermes::adapter::exit) return false; atexit(OnExit); diff --git a/adapter/interceptor.h b/adapter/interceptor.h index bc68196a5..27fec48ad 100644 --- a/adapter/interceptor.h +++ b/adapter/interceptor.h @@ -17,16 +17,16 @@ #include #include +#include #include #include #include -#include +#include "adapter_utils.h" #include "buffer_pool_internal.h" #include "constants.h" #include "enumerations.h" #include "singleton.h" -#include "adapter_utils.h" /** * Define Interceptor list for adapter. @@ -34,8 +34,7 @@ #define INTERCEPTOR_LIST \ hermes::Singleton::GetInstance<>() -#define HERMES_CONF \ - hermes::Singleton::GetInstance() +#define HERMES_CONF hermes::Singleton::GetInstance() // Path lengths are up to 4096 bytes const int kMaxPathLen = 4096; @@ -55,15 +54,23 @@ inline std::vector StringSplit(const char* str, char delimiter) { } return v; } -inline std::string GetFilenameFromFP(FILE* fh) { + +/** + get the file name from \a fp file pointer +*/ +inline std::string GetFilenameFromFP(FILE* fp) { char proclnk[kMaxPathLen]; char filename[kMaxPathLen]; - int fno = fileno(fh); + int fno = fileno(fp); snprintf(proclnk, kMaxPathLen, "/proc/self/fd/%d", fno); size_t r = readlink(proclnk, filename, kMaxPathLen); filename[r] = '\0'; return filename; } + +/** + get the file name from \a fd file descriptor +*/ inline std::string GetFilenameFromFD(int fd) { char proclnk[kMaxPathLen]; char filename[kMaxPathLen]; @@ -108,6 +115,9 @@ struct InterceptorList { adapter_paths(), hermes_paths_exclusion(), hermes_flush_exclusion() {} + /** + set up adapter mode - default, bypass, or scratch + */ void SetupAdapterMode() { char* adapter_mode_str = getenv(kAdapterMode); if (adapter_mode_str == nullptr) { @@ -133,9 +143,19 @@ struct InterceptorList { adapter_paths = paths_local; } - bool Persists(FILE* fh) { return Persists(GetFilenameFromFP(fh)); } + /** + check if \a fp file pointer persists + */ + bool Persists(FILE* fp) { return Persists(GetFilenameFromFP(fp)); } + + /** + check if \a fd file descriptor persists + */ bool Persists(int fd) { return Persists(GetFilenameFromFD(fd)); } + /** + check if \a path file path persists + */ bool Persists(std::string path) { if (adapter_mode == AdapterMode::kDefault) { if (adapter_paths.empty()) { diff --git a/adapter/mapper/abstract_mapper.h b/adapter/mapper/abstract_mapper.h index fe29921f1..f7f5e764d 100644 --- a/adapter/mapper/abstract_mapper.h +++ b/adapter/mapper/abstract_mapper.h @@ -29,22 +29,26 @@ enum MapperType { BALANCED = 0 /* Balanced Mapping */ }; +/** + A structure to represent BLOB placement +*/ struct BlobPlacement { - int rank_; // The rank of the process producing the blob - size_t page_; // The index in the array placements - size_t bucket_off_; // Offset from file start (for FS) - size_t blob_off_; // Offset from blob start - size_t blob_size_; // Size after offset to read - int time_; // The order of the blob in a list of blobs + int rank_; /**< The rank of the process producing the BLOB */ + size_t page_; /**< The index in the array placements */ + size_t bucket_off_; /**< Offset from file start (for FS) */ + size_t blob_off_; /**< Offset from BLOB start */ + size_t blob_size_; /**< Size after offset to read */ + int time_; /**< The order of the blob in a list of blobs */ - std::string CreateBlobName() const { - return std::to_string(page_); - } + /** create a BLOB name from index. */ + std::string CreateBlobName() const { return std::to_string(page_); } + /** decode \a blob_name BLOB name to index. */ void DecodeBlobName(const std::string &blob_name) { std::stringstream(blob_name) >> page_; } + /** create a log entry for this BLOB using \a time. */ std::string CreateBlobNameLogEntry(int time) const { std::stringstream ss; ss << std::to_string(page_); @@ -55,9 +59,10 @@ struct BlobPlacement { return ss.str(); } + /** decode \a blob_name BLOB name by splitting it into index, offset, size, + and rank. */ void DecodeBlobNamePerProc(const std::string &blob_name) { - auto str_split = - hermes::adapter::StringSplit(blob_name.data(), '#'); + auto str_split = hermes::adapter::StringSplit(blob_name.data(), '#'); std::stringstream(str_split[0]) >> page_; std::stringstream(str_split[1]) >> blob_off_; std::stringstream(str_split[2]) >> blob_size_; @@ -68,13 +73,18 @@ struct BlobPlacement { typedef std::vector BlobPlacements; +/** + A class to represent abstract mapper +*/ class AbstractMapper { public: /** - * This method maps the current Operation to Hermes data structures. + * This method maps the current operation to Hermes data structures. + * + * @param off offset + * @param size size + * @param ps BLOB placement * - * @param file_op, FileStruct, operations for which we are mapping. - * @return a map of FileStruct to Hermes Struct */ virtual void map(size_t off, size_t size, BlobPlacements &ps) = 0; }; diff --git a/adapter/mapper/balanced_mapper.cc b/adapter/mapper/balanced_mapper.cc index 6784173b6..e79fe81ca 100644 --- a/adapter/mapper/balanced_mapper.cc +++ b/adapter/mapper/balanced_mapper.cc @@ -15,22 +15,26 @@ namespace hermes::adapter { -void BalancedMapper::map(size_t off, size_t size, BlobPlacements &ps) { - VLOG(1) << "Mapping File with offset:" << off << " and size:" << size << "." - << std::endl; + /** + * This method maps the current Operation to Hermes data structures. + */ + void BalancedMapper::map(size_t off, size_t size, BlobPlacements &ps) { + VLOG(1) << "Mapping File with offset:" << off << " and size:" << size << "." + << std::endl; - size_t size_mapped = 0; - while (size > size_mapped) { - BlobPlacement p; - p.bucket_off_ = off + size_mapped; - p.page_ = p.bucket_off_ / kPageSize; - p.blob_off_ = p.bucket_off_ % kPageSize; - auto left_size_page = kPageSize - p.blob_off_; - p.blob_size_ = left_size_page < size - size_mapped ? left_size_page - : size - size_mapped; - ps.emplace_back(p); - size_mapped += p.blob_size_; + size_t size_mapped = 0; + while (size > size_mapped) { + BlobPlacement p; + p.bucket_off_ = off + size_mapped; + p.page_ = p.bucket_off_ / kPageSize; + p.blob_off_ = p.bucket_off_ % kPageSize; + auto left_size_page = kPageSize - p.blob_off_; + p.blob_size_ = left_size_page < size - size_mapped ? left_size_page + : size - size_mapped; + ps.emplace_back(p); + size_mapped += p.blob_size_; + } } -} + } // namespace hermes::adapter diff --git a/adapter/mapper/balanced_mapper.h b/adapter/mapper/balanced_mapper.h index 60e45adbc..343efc50c 100644 --- a/adapter/mapper/balanced_mapper.h +++ b/adapter/mapper/balanced_mapper.h @@ -14,6 +14,7 @@ #define HERMES_BALANCED_MAPPER_H #include + #include "abstract_mapper.h" namespace hermes::adapter { @@ -25,8 +26,6 @@ class BalancedMapper : public AbstractMapper { /** * This method maps the current Operation to Hermes data structures. * - * @param file_op, FileStruct, operations for which we are mapping. - * @return a map of FileStruct to Hermes Struct */ void map(size_t off, size_t size, BlobPlacements &ps) override; }; diff --git a/adapter/mapper/mapper_factory.h b/adapter/mapper/mapper_factory.h index 1a90120f7..a2d8203dc 100644 --- a/adapter/mapper/mapper_factory.h +++ b/adapter/mapper/mapper_factory.h @@ -13,21 +13,24 @@ #ifndef HERMES_ADAPTER_FACTORY_H #define HERMES_ADAPTER_FACTORY_H -#include "singleton.h" #include "abstract_mapper.h" -#include "balanced_mapper.h" #include "balanced_mapper.cc" +#include "balanced_mapper.h" +#include "singleton.h" namespace hermes::adapter { +/** + A class to represent mapper factory pattern +*/ class MapperFactory { public: /** * Return the instance of mapper given a type. Uses factory pattern. * - * @param type, MapperType, type of mapper to be used by the POSIX adapter. + * @param[in] type type of mapper to be used by the POSIX adapter. * @return Instance of mapper given a type. */ - AbstractMapper* Get(const MapperType &type) { + AbstractMapper* Get(const MapperType& type) { switch (type) { case MapperType::BALANCED: { return hermes::Singleton::GetInstance(); diff --git a/adapter/metadata_manager.h b/adapter/metadata_manager.h index 3e1421af3..ff7a313b2 100644 --- a/adapter/metadata_manager.h +++ b/adapter/metadata_manager.h @@ -1,40 +1,45 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_METADATA_MANAGER_H_ #define HERMES_ADAPTER_METADATA_MANAGER_H_ +#include +#include +#include #include + #include "constants.h" #include "enumerations.h" #include "interceptor.h" -#include -#include -#include - namespace hapi = hermes::api; namespace hermes::adapter { +/** A variable for synchronous or asynchronous global flusing mode */ FlushingMode global_flushing_mode; +/** + A class to represent metadata manager +*/ class MetadataManager { protected: - int rank; - int comm_size; + int rank; /**< MPI communicator rank */ + int comm_size; /**< MPI communicator size */ + /** a reference of how many times Initialize is called */ std::atomic ref; - std::shared_ptr hermes; - bool is_mpi_; + std::shared_ptr hermes; /**< pointer to hermes instances */ + bool is_mpi_; /**< check whether MPI is being used or not */ public: /** @@ -75,7 +80,6 @@ class MetadataManager { ref++; } - /** * Finalize hermes and close rpc if reference is equal to one. Else just * decrement the ref counter. @@ -97,5 +101,4 @@ class MetadataManager { } // namespace hermes::adapter - #endif // HERMES_ADAPTER_METADATA_MANAGER_H_ diff --git a/adapter/mpiio/fs_api.h b/adapter/mpiio/fs_api.h index 5f8853535..f543b47da 100644 --- a/adapter/mpiio/fs_api.h +++ b/adapter/mpiio/fs_api.h @@ -1,63 +1,74 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_MPIIO_FS_API_H_ #define HERMES_ADAPTER_MPIIO_FS_API_H_ +#include +#include #include #include -#include - -#include #include #include + #include -#include +#include -#include "filesystem/filesystem.h" #include "filesystem/filesystem.cc" -#include "filesystem/metadata_manager.h" +#include "filesystem/filesystem.h" #include "filesystem/metadata_manager.cc" -#include "real_api.h" +#include "filesystem/metadata_manager.h" #include "posix/real_api.h" +#include "real_api.h" namespace hermes::adapter::mpiio { +using hermes::Singleton; using hermes::adapter::fs::AdapterStat; using hermes::adapter::fs::File; -using hermes::Singleton; -using hermes::adapter::mpiio::API; +using hermes::adapter::fs::HermesRequest; using hermes::adapter::fs::IoOptions; using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::HermesRequest; using hermes::adapter::fs::MetadataManager; using hermes::adapter::fs::SeekMode; +using hermes::adapter::mpiio::API; +/** + A class to represent MPI IO seek mode conversion +*/ class MpiioSeekModeConv { public: + /** normalize \a mpi_seek MPI seek mode */ static SeekMode Normalize(int mpi_seek) { switch (mpi_seek) { - case MPI_SEEK_SET: return SeekMode::kSet; - case MPI_SEEK_CUR: return SeekMode::kCurrent; - case MPI_SEEK_END: return SeekMode::kEnd; - default: return SeekMode::kNone; + case MPI_SEEK_SET: + return SeekMode::kSet; + case MPI_SEEK_CUR: + return SeekMode::kCurrent; + case MPI_SEEK_END: + return SeekMode::kEnd; + default: + return SeekMode::kNone; } } }; +/** + A class to represent MPI IO file system +*/ class MpiioFS : public hermes::adapter::fs::Filesystem { private: - API *real_api; - hermes::adapter::posix::API *posix_api; + API *real_api; /**< pointer to real APIs */ + hermes::adapter::posix::API *posix_api; /**< pointer to POSIX APIs */ public: MpiioFS() { @@ -68,8 +79,8 @@ class MpiioFS : public hermes::adapter::fs::Filesystem { void _InitFile(File &f) override; - public: + /** get file name from \a fh MPI file pointer */ static inline std::string GetFilenameFromFP(MPI_File *fh) { MPI_Info info; int status = MPI_File_get_info(*fh, &info); @@ -79,50 +90,52 @@ class MpiioFS : public hermes::adapter::fs::Filesystem { const int kMaxSize = 0xFFF; int flag; char filename[kMaxSize] = {0}; - MPI_Info_get(info, "filename", kMaxSize, - filename, &flag); + MPI_Info_get(info, "filename", kMaxSize, filename, &flag); return filename; } - - int Read(File &f, AdapterStat &stat, - void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status, IoOptions opts = IoOptions()); - int ARead(File &f, AdapterStat &stat, - void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Request *request, IoOptions opts = IoOptions()); - int ReadAll(File &f, AdapterStat &stat, - void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status, IoOptions opts = IoOptions()); - int ReadOrdered(File &f, AdapterStat &stat, - void *ptr, int count, - MPI_Datatype datatype, - MPI_Status *status, IoOptions opts = IoOptions()); - int Write(File &f, AdapterStat &stat, - const void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status, IoOptions opts = IoOptions()); - int AWrite(File &f, AdapterStat &stat, - const void *ptr, size_t offset, + /** Read */ + int Read(File &f, AdapterStat &stat, void *ptr, size_t offset, int count, + MPI_Datatype datatype, MPI_Status *status, + IoOptions opts = IoOptions()); + /** ARead */ + int ARead(File &f, AdapterStat &stat, void *ptr, size_t offset, int count, + MPI_Datatype datatype, MPI_Request *request, + IoOptions opts = IoOptions()); + /** ReadAll */ + int ReadAll(File &f, AdapterStat &stat, void *ptr, size_t offset, int count, + MPI_Datatype datatype, MPI_Status *status, + IoOptions opts = IoOptions()); + /** ReadOrdered */ + int ReadOrdered(File &f, AdapterStat &stat, void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status, + IoOptions opts = IoOptions()); + /** Write */ + int Write(File &f, AdapterStat &stat, const void *ptr, size_t offset, + int count, MPI_Datatype datatype, MPI_Status *status, + IoOptions opts = IoOptions()); + /** AWrite */ + int AWrite(File &f, AdapterStat &stat, const void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Request *request, IoOptions opts = IoOptions()); - int WriteAll(File &f, AdapterStat &stat, - const void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status, IoOptions opts = IoOptions()); - int WriteOrdered(File &f, AdapterStat &stat, - const void *ptr, int count, - MPI_Datatype datatype, - MPI_Status *status, IoOptions opts = IoOptions()); - int AWriteOrdered(File &f, AdapterStat &stat, - const void *ptr, int count, - MPI_Datatype datatype, - MPI_Request *request, IoOptions opts = IoOptions()); + /** WriteAll */ + int WriteAll(File &f, AdapterStat &stat, const void *ptr, size_t offset, + int count, MPI_Datatype datatype, MPI_Status *status, + IoOptions opts = IoOptions()); + /** WriteOrdered */ + int WriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status, + IoOptions opts = IoOptions()); + /** AWriteOrdered */ + int AWriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, MPI_Request *request, + IoOptions opts = IoOptions()); + /** Wait */ int Wait(MPI_Request *req, MPI_Status *status); + /** WaitAll */ int WaitAll(int count, MPI_Request *req, MPI_Status *status); + /** Seek */ int Seek(File &f, AdapterStat &stat, MPI_Offset offset, int whence); + /** SeekShared */ int SeekShared(File &f, AdapterStat &stat, MPI_Offset offset, int whence); /** @@ -130,105 +143,101 @@ class MpiioFS : public hermes::adapter::fs::Filesystem { */ public: - int Read(File &f, AdapterStat &stat, - void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - int ARead(File &f, AdapterStat &stat, - void *ptr, int count, MPI_Datatype datatype, - MPI_Request *request); - int ReadAll(File &f, AdapterStat &stat, - void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - - int Write(File &f, AdapterStat &stat, - const void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - int AWrite(File &f, AdapterStat &stat, - const void *ptr, int count, MPI_Datatype datatype, - MPI_Request *request); - int WriteAll(File &f, AdapterStat &stat, - const void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); + /** Read */ + int Read(File &f, AdapterStat &stat, void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** ARead */ + int ARead(File &f, AdapterStat &stat, void *ptr, int count, + MPI_Datatype datatype, MPI_Request *request); + /** ReadAll */ + int ReadAll(File &f, AdapterStat &stat, void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** Write */ + int Write(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** AWrite */ + int AWrite(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, MPI_Request *request); + /** WriteAll */ + int WriteAll(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); /** * Variants which retrieve the stat data structure internally - * */ + */ public: - int Read(File &f, bool &stat_exists, - void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status); - int ARead(File &f, bool &stat_exists, - void *ptr, size_t offset, - int count, MPI_Datatype datatype, MPI_Request *request); - int ReadAll(File &f, bool &stat_exists, - void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status); - int ReadOrdered(File &f, bool &stat_exists, - void *ptr, int count, - MPI_Datatype datatype, - MPI_Status *status); - - int Write(File &f, bool &stat_exists, - const void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status); - int AWrite(File &f, bool &stat_exists, - const void *ptr, size_t offset, + /** Read */ + int Read(File &f, bool &stat_exists, void *ptr, size_t offset, int count, + MPI_Datatype datatype, MPI_Status *status); + /** ARead */ + int ARead(File &f, bool &stat_exists, void *ptr, size_t offset, int count, + MPI_Datatype datatype, MPI_Request *request); + /** ReadAll */ + int ReadAll(File &f, bool &stat_exists, void *ptr, size_t offset, int count, + MPI_Datatype datatype, MPI_Status *status); + /** ReadOrdered */ + int ReadOrdered(File &f, bool &stat_exists, void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** Write */ + int Write(File &f, bool &stat_exists, const void *ptr, size_t offset, + int count, MPI_Datatype datatype, MPI_Status *status); + /** AWrite */ + int AWrite(File &f, bool &stat_exists, const void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Request *request); - int WriteAll(File &f, bool &stat_exists, - const void *ptr, size_t offset, - int count, MPI_Datatype datatype, - MPI_Status *status); - int WriteOrdered(File &f, bool &stat_exists, - const void *ptr, int count, - MPI_Datatype datatype, - MPI_Status *status); - int AWriteOrdered(File &f, bool &stat_exists, - const void *ptr, int count, - MPI_Datatype datatype, - MPI_Request *request); - - int Read(File &f, bool &stat_exists, - void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - int ARead(File &f, bool &stat_exists, - void *ptr, int count, MPI_Datatype datatype, MPI_Request *request); - int ReadAll(File &f, bool &stat_exists, - void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - - int Write(File &f, bool &stat_exists, - const void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - int AWrite(File &f, bool &stat_exists, - const void *ptr, int count, MPI_Datatype datatype, - MPI_Request *request); - int WriteAll(File &f, bool &stat_exists, - const void *ptr, int count, MPI_Datatype datatype, - MPI_Status *status); - + /** WriteAll */ + int WriteAll(File &f, bool &stat_exists, const void *ptr, size_t offset, + int count, MPI_Datatype datatype, MPI_Status *status); + /** WriteOrdered */ + int WriteOrdered(File &f, bool &stat_exists, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** AWriteOrdered */ + int AWriteOrdered(File &f, bool &stat_exists, const void *ptr, int count, + MPI_Datatype datatype, MPI_Request *request); + /** Read */ + int Read(File &f, bool &stat_exists, void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** ARead */ + int ARead(File &f, bool &stat_exists, void *ptr, int count, + MPI_Datatype datatype, MPI_Request *request); + /** ReadAll */ + int ReadAll(File &f, bool &stat_exists, void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** Write */ + int Write(File &f, bool &stat_exists, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** AWrite */ + int AWrite(File &f, bool &stat_exists, const void *ptr, int count, + MPI_Datatype datatype, MPI_Request *request); + /** WriteAll */ + int WriteAll(File &f, bool &stat_exists, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status); + /** Seek */ int Seek(File &f, bool &stat_exists, MPI_Offset offset, int whence); + /** SeekShared */ int SeekShared(File &f, bool &stat_exists, MPI_Offset offset, int whence); - /** * Internal overrides - * */ + */ private: + /** OpenInitStats */ void _OpenInitStats(File &f, AdapterStat &stat) override; + /** RealOpen */ File _RealOpen(AdapterStat &stat, const std::string &path) override; + /** RealWrite */ size_t _RealWrite(const std::string &filename, off_t offset, size_t size, - const u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) override; + const u8 *data_ptr, IoStatus &io_status, + IoOptions &opts) override; + /** RealRead */ size_t _RealRead(const std::string &filename, off_t offset, size_t size, - u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) override; + u8 *data_ptr, IoStatus &io_status, IoOptions &opts) override; + /** IoStats */ void _IoStats(size_t count, IoStatus &io_status, IoOptions &opts) override; + /** RealSync */ int _RealSync(File &f) override; + /** RealClose */ int _RealClose(File &f) override; }; diff --git a/adapter/mpiio/real_api.h b/adapter/mpiio/real_api.h index 58e21a15a..415b5322c 100644 --- a/adapter/mpiio/real_api.h +++ b/adapter/mpiio/real_api.h @@ -12,88 +12,187 @@ #ifndef HERMES_ADAPTER_MPIIO_H #define HERMES_ADAPTER_MPIIO_H -#include #include -#include #include #include #include -#include "interceptor.h" + +#include +#include + #include "filesystem/filesystem.h" #include "filesystem/metadata_manager.h" +#include "interceptor.h" -#define REQUIRE_API(api_name) \ - if (real_api->api_name == nullptr) { \ - LOG(FATAL) << "HERMES Adapter failed to map symbol: " \ - #api_name << std::endl; \ +#define REQUIRE_API(api_name) \ + if (real_api->api_name == nullptr) { \ + LOG(FATAL) << "HERMES Adapter failed to map symbol: " #api_name \ + << std::endl; \ exit(1); 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); } namespace hermes::adapter::mpiio { - +/** + A class to represent MPIIO API +*/ class API { public: - int (*MPI_Init)(int * argc, char *** argv) = nullptr; - int (*MPI_Finalize)( void) = nullptr; - int (*MPI_Wait)(MPI_Request * req, MPI_Status * status) = nullptr; - int (*MPI_Waitall)(int count, MPI_Request * req, MPI_Status * status) = nullptr; - int (*MPI_File_open)(MPI_Comm comm, const char * filename, int amode, MPI_Info info, MPI_File * fh) = nullptr; - int (*MPI_File_close)(MPI_File * fh) = nullptr; - int (*MPI_File_seek_shared)(MPI_File fh, MPI_Offset offset, int whence) = nullptr; + /** MPI_Init */ + int (*MPI_Init)(int *argc, char ***argv) = nullptr; + /** MPI_Finalize */ + int (*MPI_Finalize)(void) = nullptr; + /** MPI_Wait */ + int (*MPI_Wait)(MPI_Request *req, MPI_Status *status) = nullptr; + /** MPI_Waitall */ + int (*MPI_Waitall)(int count, MPI_Request *req, MPI_Status *status) = nullptr; + /** MPI_File_open */ + int (*MPI_File_open)(MPI_Comm comm, const char *filename, int amode, + MPI_Info info, MPI_File *fh) = nullptr; + /** MPI_File_close */ + int (*MPI_File_close)(MPI_File *fh) = nullptr; + /** MPI_File_seek_shared */ + int (*MPI_File_seek_shared)(MPI_File fh, MPI_Offset offset, + int whence) = nullptr; + /** MPI_File_seek */ int (*MPI_File_seek)(MPI_File fh, MPI_Offset offset, int whence) = nullptr; - int (*MPI_File_get_position)(MPI_File fh, MPI_Offset * offset) = nullptr; - int (*MPI_File_read_all)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_read_at_all)(MPI_File fh, MPI_Offset offset, void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_read_at)(MPI_File fh, MPI_Offset offset, void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_read)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_read_ordered)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_read_shared)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_write_all)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_write_at_all)(MPI_File fh, MPI_Offset offset, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_write_at)(MPI_File fh, MPI_Offset offset, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_write)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_write_ordered)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_write_shared)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status * status) = nullptr; - int (*MPI_File_iread_at)(MPI_File fh, MPI_Offset offset, void * buf, int count, MPI_Datatype datatype, MPI_Request * request) = nullptr; - int (*MPI_File_iread)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Request * request) = nullptr; - int (*MPI_File_iread_shared)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Request * request) = nullptr; - int (*MPI_File_iwrite_at)(MPI_File fh, MPI_Offset offset, const void * buf, int count, MPI_Datatype datatype, MPI_Request * request) = nullptr; - int (*MPI_File_iwrite)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Request * request) = nullptr; - int (*MPI_File_iwrite_shared)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Request * request) = nullptr; + /** MPI_File_get_position */ + int (*MPI_File_get_position)(MPI_File fh, MPI_Offset *offset) = nullptr; + /** MPI_File_read_all */ + int (*MPI_File_read_all)(MPI_File fh, void *buf, int count, + MPI_Datatype datatype, MPI_Status *status) = nullptr; + /** MPI_File_read_at_all */ + int (*MPI_File_read_at_all)(MPI_File fh, MPI_Offset offset, void *buf, + int count, MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_read_at */ + int (*MPI_File_read_at)(MPI_File fh, MPI_Offset offset, void *buf, int count, + MPI_Datatype datatype, MPI_Status *status) = nullptr; + /** MPI_File_read */ + int (*MPI_File_read)(MPI_File fh, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_read_ordered */ + int (*MPI_File_read_ordered)(MPI_File fh, void *buf, int count, + MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_read_shared */ + int (*MPI_File_read_shared)(MPI_File fh, void *buf, int count, + MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_write_all */ + int (*MPI_File_write_all)(MPI_File fh, const void *buf, int count, + MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_write_at_all */ + int (*MPI_File_write_at_all)(MPI_File fh, MPI_Offset offset, const void *buf, + int count, MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_write_at */ + int (*MPI_File_write_at)(MPI_File fh, MPI_Offset offset, const void *buf, + int count, MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_write */ + int (*MPI_File_write)(MPI_File fh, const void *buf, int count, + MPI_Datatype datatype, MPI_Status *status) = nullptr; + /** MPI_File_write_ordered */ + int (*MPI_File_write_ordered)(MPI_File fh, const void *buf, int count, + MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_write_shared */ + int (*MPI_File_write_shared)(MPI_File fh, const void *buf, int count, + MPI_Datatype datatype, + MPI_Status *status) = nullptr; + /** MPI_File_iread_at */ + int (*MPI_File_iread_at)(MPI_File fh, MPI_Offset offset, void *buf, int count, + MPI_Datatype datatype, + MPI_Request *request) = nullptr; + /** MPI_File_iread */ + int (*MPI_File_iread)(MPI_File fh, void *buf, int count, + MPI_Datatype datatype, MPI_Request *request) = nullptr; + /** MPI_File_iread_shared */ + int (*MPI_File_iread_shared)(MPI_File fh, void *buf, int count, + MPI_Datatype datatype, + MPI_Request *request) = nullptr; + /** MPI_File_iwrite_at */ + int (*MPI_File_iwrite_at)(MPI_File fh, MPI_Offset offset, const void *buf, + int count, MPI_Datatype datatype, + MPI_Request *request) = nullptr; + /** MPI_File_iwrite */ + int (*MPI_File_iwrite)(MPI_File fh, const void *buf, int count, + MPI_Datatype datatype, MPI_Request *request) = nullptr; + /** MPI_File_iwrite_shared */ + int (*MPI_File_iwrite_shared)(MPI_File fh, const void *buf, int count, + MPI_Datatype datatype, + MPI_Request *request) = nullptr; + /** MPI_File_sync */ int (*MPI_File_sync)(MPI_File fh) = nullptr; + /** API constructor that intercepts MPI API calls */ API() { - void *is_intercepted = (void*)dlsym(RTLD_DEFAULT, "mpiio_intercepted"); + void *is_intercepted = (void *)dlsym(RTLD_DEFAULT, "mpiio_intercepted"); if (is_intercepted) { MPI_Init = (MPI_Init_t)dlsym(RTLD_NEXT, "MPI_Init"); } else { @@ -125,9 +224,11 @@ class API { MPI_File_close = (MPI_File_close_t)dlsym(RTLD_DEFAULT, "MPI_File_close"); } if (is_intercepted) { - MPI_File_seek_shared = (MPI_File_seek_shared_t)dlsym(RTLD_NEXT, "MPI_File_seek_shared"); + MPI_File_seek_shared = + (MPI_File_seek_shared_t)dlsym(RTLD_NEXT, "MPI_File_seek_shared"); } else { - MPI_File_seek_shared = (MPI_File_seek_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_seek_shared"); + MPI_File_seek_shared = + (MPI_File_seek_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_seek_shared"); } if (is_intercepted) { MPI_File_seek = (MPI_File_seek_t)dlsym(RTLD_NEXT, "MPI_File_seek"); @@ -135,24 +236,32 @@ class API { MPI_File_seek = (MPI_File_seek_t)dlsym(RTLD_DEFAULT, "MPI_File_seek"); } if (is_intercepted) { - MPI_File_get_position = (MPI_File_get_position_t)dlsym(RTLD_NEXT, "MPI_File_get_position"); + MPI_File_get_position = + (MPI_File_get_position_t)dlsym(RTLD_NEXT, "MPI_File_get_position"); } else { - MPI_File_get_position = (MPI_File_get_position_t)dlsym(RTLD_DEFAULT, "MPI_File_get_position"); + MPI_File_get_position = + (MPI_File_get_position_t)dlsym(RTLD_DEFAULT, "MPI_File_get_position"); } if (is_intercepted) { - MPI_File_read_all = (MPI_File_read_all_t)dlsym(RTLD_NEXT, "MPI_File_read_all"); + MPI_File_read_all = + (MPI_File_read_all_t)dlsym(RTLD_NEXT, "MPI_File_read_all"); } else { - MPI_File_read_all = (MPI_File_read_all_t)dlsym(RTLD_DEFAULT, "MPI_File_read_all"); + MPI_File_read_all = + (MPI_File_read_all_t)dlsym(RTLD_DEFAULT, "MPI_File_read_all"); } if (is_intercepted) { - MPI_File_read_at_all = (MPI_File_read_at_all_t)dlsym(RTLD_NEXT, "MPI_File_read_at_all"); + MPI_File_read_at_all = + (MPI_File_read_at_all_t)dlsym(RTLD_NEXT, "MPI_File_read_at_all"); } else { - MPI_File_read_at_all = (MPI_File_read_at_all_t)dlsym(RTLD_DEFAULT, "MPI_File_read_at_all"); + MPI_File_read_at_all = + (MPI_File_read_at_all_t)dlsym(RTLD_DEFAULT, "MPI_File_read_at_all"); } if (is_intercepted) { - MPI_File_read_at = (MPI_File_read_at_t)dlsym(RTLD_NEXT, "MPI_File_read_at"); + MPI_File_read_at = + (MPI_File_read_at_t)dlsym(RTLD_NEXT, "MPI_File_read_at"); } else { - MPI_File_read_at = (MPI_File_read_at_t)dlsym(RTLD_DEFAULT, "MPI_File_read_at"); + MPI_File_read_at = + (MPI_File_read_at_t)dlsym(RTLD_DEFAULT, "MPI_File_read_at"); } if (is_intercepted) { MPI_File_read = (MPI_File_read_t)dlsym(RTLD_NEXT, "MPI_File_read"); @@ -160,29 +269,39 @@ class API { MPI_File_read = (MPI_File_read_t)dlsym(RTLD_DEFAULT, "MPI_File_read"); } if (is_intercepted) { - MPI_File_read_ordered = (MPI_File_read_ordered_t)dlsym(RTLD_NEXT, "MPI_File_read_ordered"); + MPI_File_read_ordered = + (MPI_File_read_ordered_t)dlsym(RTLD_NEXT, "MPI_File_read_ordered"); } else { - MPI_File_read_ordered = (MPI_File_read_ordered_t)dlsym(RTLD_DEFAULT, "MPI_File_read_ordered"); + MPI_File_read_ordered = + (MPI_File_read_ordered_t)dlsym(RTLD_DEFAULT, "MPI_File_read_ordered"); } if (is_intercepted) { - MPI_File_read_shared = (MPI_File_read_shared_t)dlsym(RTLD_NEXT, "MPI_File_read_shared"); + MPI_File_read_shared = + (MPI_File_read_shared_t)dlsym(RTLD_NEXT, "MPI_File_read_shared"); } else { - MPI_File_read_shared = (MPI_File_read_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_read_shared"); + MPI_File_read_shared = + (MPI_File_read_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_read_shared"); } if (is_intercepted) { - MPI_File_write_all = (MPI_File_write_all_t)dlsym(RTLD_NEXT, "MPI_File_write_all"); + MPI_File_write_all = + (MPI_File_write_all_t)dlsym(RTLD_NEXT, "MPI_File_write_all"); } else { - MPI_File_write_all = (MPI_File_write_all_t)dlsym(RTLD_DEFAULT, "MPI_File_write_all"); + MPI_File_write_all = + (MPI_File_write_all_t)dlsym(RTLD_DEFAULT, "MPI_File_write_all"); } if (is_intercepted) { - MPI_File_write_at_all = (MPI_File_write_at_all_t)dlsym(RTLD_NEXT, "MPI_File_write_at_all"); + MPI_File_write_at_all = + (MPI_File_write_at_all_t)dlsym(RTLD_NEXT, "MPI_File_write_at_all"); } else { - MPI_File_write_at_all = (MPI_File_write_at_all_t)dlsym(RTLD_DEFAULT, "MPI_File_write_at_all"); + MPI_File_write_at_all = + (MPI_File_write_at_all_t)dlsym(RTLD_DEFAULT, "MPI_File_write_at_all"); } if (is_intercepted) { - MPI_File_write_at = (MPI_File_write_at_t)dlsym(RTLD_NEXT, "MPI_File_write_at"); + MPI_File_write_at = + (MPI_File_write_at_t)dlsym(RTLD_NEXT, "MPI_File_write_at"); } else { - MPI_File_write_at = (MPI_File_write_at_t)dlsym(RTLD_DEFAULT, "MPI_File_write_at"); + MPI_File_write_at = + (MPI_File_write_at_t)dlsym(RTLD_DEFAULT, "MPI_File_write_at"); } if (is_intercepted) { MPI_File_write = (MPI_File_write_t)dlsym(RTLD_NEXT, "MPI_File_write"); @@ -190,19 +309,25 @@ class API { MPI_File_write = (MPI_File_write_t)dlsym(RTLD_DEFAULT, "MPI_File_write"); } if (is_intercepted) { - MPI_File_write_ordered = (MPI_File_write_ordered_t)dlsym(RTLD_NEXT, "MPI_File_write_ordered"); + MPI_File_write_ordered = + (MPI_File_write_ordered_t)dlsym(RTLD_NEXT, "MPI_File_write_ordered"); } else { - MPI_File_write_ordered = (MPI_File_write_ordered_t)dlsym(RTLD_DEFAULT, "MPI_File_write_ordered"); + MPI_File_write_ordered = (MPI_File_write_ordered_t)dlsym( + RTLD_DEFAULT, "MPI_File_write_ordered"); } if (is_intercepted) { - MPI_File_write_shared = (MPI_File_write_shared_t)dlsym(RTLD_NEXT, "MPI_File_write_shared"); + MPI_File_write_shared = + (MPI_File_write_shared_t)dlsym(RTLD_NEXT, "MPI_File_write_shared"); } else { - MPI_File_write_shared = (MPI_File_write_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_write_shared"); + MPI_File_write_shared = + (MPI_File_write_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_write_shared"); } if (is_intercepted) { - MPI_File_iread_at = (MPI_File_iread_at_t)dlsym(RTLD_NEXT, "MPI_File_iread_at"); + MPI_File_iread_at = + (MPI_File_iread_at_t)dlsym(RTLD_NEXT, "MPI_File_iread_at"); } else { - MPI_File_iread_at = (MPI_File_iread_at_t)dlsym(RTLD_DEFAULT, "MPI_File_iread_at"); + MPI_File_iread_at = + (MPI_File_iread_at_t)dlsym(RTLD_DEFAULT, "MPI_File_iread_at"); } if (is_intercepted) { MPI_File_iread = (MPI_File_iread_t)dlsym(RTLD_NEXT, "MPI_File_iread"); @@ -210,24 +335,31 @@ class API { MPI_File_iread = (MPI_File_iread_t)dlsym(RTLD_DEFAULT, "MPI_File_iread"); } if (is_intercepted) { - MPI_File_iread_shared = (MPI_File_iread_shared_t)dlsym(RTLD_NEXT, "MPI_File_iread_shared"); + MPI_File_iread_shared = + (MPI_File_iread_shared_t)dlsym(RTLD_NEXT, "MPI_File_iread_shared"); } else { - MPI_File_iread_shared = (MPI_File_iread_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_iread_shared"); + MPI_File_iread_shared = + (MPI_File_iread_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_iread_shared"); } if (is_intercepted) { - MPI_File_iwrite_at = (MPI_File_iwrite_at_t)dlsym(RTLD_NEXT, "MPI_File_iwrite_at"); + MPI_File_iwrite_at = + (MPI_File_iwrite_at_t)dlsym(RTLD_NEXT, "MPI_File_iwrite_at"); } else { - MPI_File_iwrite_at = (MPI_File_iwrite_at_t)dlsym(RTLD_DEFAULT, "MPI_File_iwrite_at"); + MPI_File_iwrite_at = + (MPI_File_iwrite_at_t)dlsym(RTLD_DEFAULT, "MPI_File_iwrite_at"); } if (is_intercepted) { MPI_File_iwrite = (MPI_File_iwrite_t)dlsym(RTLD_NEXT, "MPI_File_iwrite"); } else { - MPI_File_iwrite = (MPI_File_iwrite_t)dlsym(RTLD_DEFAULT, "MPI_File_iwrite"); + MPI_File_iwrite = + (MPI_File_iwrite_t)dlsym(RTLD_DEFAULT, "MPI_File_iwrite"); } if (is_intercepted) { - MPI_File_iwrite_shared = (MPI_File_iwrite_shared_t)dlsym(RTLD_NEXT, "MPI_File_iwrite_shared"); + MPI_File_iwrite_shared = + (MPI_File_iwrite_shared_t)dlsym(RTLD_NEXT, "MPI_File_iwrite_shared"); } else { - MPI_File_iwrite_shared = (MPI_File_iwrite_shared_t)dlsym(RTLD_DEFAULT, "MPI_File_iwrite_shared"); + MPI_File_iwrite_shared = (MPI_File_iwrite_shared_t)dlsym( + RTLD_DEFAULT, "MPI_File_iwrite_shared"); } if (is_intercepted) { MPI_File_sync = (MPI_File_sync_t)dlsym(RTLD_NEXT, "MPI_File_sync"); diff --git a/adapter/posix/fs_api.h b/adapter/posix/fs_api.h index 29d2e4be1..1d0ed7f09 100644 --- a/adapter/posix/fs_api.h +++ b/adapter/posix/fs_api.h @@ -1,39 +1,41 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_POSIX_NATIVE_H_ #define HERMES_ADAPTER_POSIX_NATIVE_H_ #include + #include "filesystem/filesystem.h" #include "filesystem/metadata_manager.h" #include "real_api.h" +using hermes::Singleton; using hermes::adapter::fs::AdapterStat; using hermes::adapter::fs::File; -using hermes::Singleton; -using hermes::adapter::posix::API; using hermes::adapter::fs::IoOptions; using hermes::adapter::fs::IoStatus; +using hermes::adapter::posix::API; namespace hermes::adapter::posix { - +/** + A class to represent POSIX IO file system +*/ class PosixFS : public hermes::adapter::fs::Filesystem { private: - API* real_api; + API *real_api; /**< pointer to real APIs */ + public: - PosixFS() { - real_api = Singleton::GetInstance(); - } + PosixFS() { real_api = Singleton::GetInstance(); } ~PosixFS() = default; void _InitFile(File &f) override; @@ -42,11 +44,10 @@ class PosixFS : public hermes::adapter::fs::Filesystem { void _OpenInitStats(File &f, AdapterStat &stat) override; File _RealOpen(AdapterStat &stat, const std::string &path) override; size_t _RealWrite(const std::string &filename, off_t offset, size_t size, - const u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) override; + const u8 *data_ptr, IoStatus &io_status, + IoOptions &opts) override; size_t _RealRead(const std::string &filename, off_t offset, size_t size, - u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) override; + u8 *data_ptr, IoStatus &io_status, IoOptions &opts) override; int _RealSync(File &f) override; int _RealClose(File &f) override; }; diff --git a/adapter/posix/real_api.h b/adapter/posix/real_api.h index ac2e64c3e..2de40c5be 100644 --- a/adapter/posix/real_api.h +++ b/adapter/posix/real_api.h @@ -12,86 +12,104 @@ #ifndef HERMES_ADAPTER_POSIX_H #define HERMES_ADAPTER_POSIX_H -#include #include -#include +#include #include #include -#include -#include "interceptor.h" + +#include +#include + #include "filesystem/filesystem.h" #include "filesystem/metadata_manager.h" +#include "interceptor.h" -#define REQUIRE_API(api_name) \ - if (real_api->api_name == nullptr) { \ - LOG(FATAL) << "HERMES Adapter failed to map symbol: " \ - #api_name << std::endl; \ +#define REQUIRE_API(api_name) \ + if (real_api->api_name == nullptr) { \ + LOG(FATAL) << "HERMES Adapter failed to map symbol: " #api_name \ + << std::endl; \ 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 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 (*__fxstat_t)(int version, int fd, struct stat * buf); +typedef int (*__fxstat_t)(int version, int fd, struct stat *buf); typedef int (*fsync_t)(int fd); typedef int (*close_t)(int fd); } namespace hermes::adapter::posix { - +/** + A class to represent POSIX API +*/ class API { public: - int (*MPI_Init)(int * argc, char *** argv) = nullptr; - int (*MPI_Finalize)( void) = nullptr; - int (*open)(const char * path, int flags, ...) = nullptr; - int (*open64)(const char * path, int flags, ...) = nullptr; - int (*__open_2)(const char * path, int oflag) = nullptr; - int (*creat)(const char * path, mode_t mode) = nullptr; - int (*creat64)(const char * path, mode_t mode) = nullptr; - ssize_t (*read)(int fd, void * buf, size_t count) = nullptr; - ssize_t (*write)(int fd, const void * buf, size_t count) = nullptr; - ssize_t (*pread)(int fd, void * buf, - size_t count, off_t offset) = nullptr; - ssize_t (*pwrite)(int fd, const void * buf, - size_t count, off_t offset) = nullptr; - ssize_t (*pread64)(int fd, void * buf, - size_t count, off64_t offset) = nullptr; - ssize_t (*pwrite64)(int fd, const void * buf, - size_t count, off64_t offset) = nullptr; + /** MPI_Init */ + int (*MPI_Init)(int *argc, char ***argv) = nullptr; + /** MPI_Finalize */ + int (*MPI_Finalize)(void) = nullptr; + /** open */ + int (*open)(const char *path, int flags, ...) = nullptr; + /** open64 */ + int (*open64)(const char *path, int flags, ...) = nullptr; + /** __open_2 */ + int (*__open_2)(const char *path, int oflag) = nullptr; + /** creat */ + int (*creat)(const char *path, mode_t mode) = nullptr; + /** creat64 */ + int (*creat64)(const char *path, mode_t mode) = nullptr; + /** read */ + ssize_t (*read)(int fd, void *buf, size_t count) = nullptr; + /** write */ + ssize_t (*write)(int fd, const void *buf, size_t count) = nullptr; + /** pread */ + ssize_t (*pread)(int fd, void *buf, size_t count, off_t offset) = nullptr; + /** pwrite */ + ssize_t (*pwrite)(int fd, const void *buf, size_t count, + off_t offset) = nullptr; + /** pread64 */ + ssize_t (*pread64)(int fd, void *buf, size_t count, off64_t offset) = nullptr; + /** pwrite64 */ + ssize_t (*pwrite64)(int fd, const void *buf, size_t count, + off64_t offset) = nullptr; + /** lseek */ off_t (*lseek)(int fd, off_t offset, int whence) = nullptr; + /** lseek64 */ off64_t (*lseek64)(int fd, off64_t offset, int whence) = nullptr; - int (*__fxstat)(int version, int fd, struct stat * buf) = nullptr; + /** __fxstat */ + int (*__fxstat)(int version, int fd, struct stat *buf) = nullptr; + /** fsync */ int (*fsync)(int fd) = nullptr; + /** close */ int (*close)(int fd) = nullptr; + /** API constructor that intercepts POSIX API calls */ API() { - void *is_intercepted = (void*)dlsym(RTLD_DEFAULT, - "posix_intercepted"); + 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"); } if (is_intercepted) { - MPI_Finalize = (MPI_Finalize_t)dlsym( - RTLD_NEXT, "MPI_Finalize"); + MPI_Finalize = (MPI_Finalize_t)dlsym(RTLD_NEXT, "MPI_Finalize"); } else { - MPI_Finalize = (MPI_Finalize_t)dlsym( - RTLD_DEFAULT, "MPI_Finalize"); + MPI_Finalize = (MPI_Finalize_t)dlsym(RTLD_DEFAULT, "MPI_Finalize"); } if (is_intercepted) { open = (open_t)dlsym(RTLD_NEXT, "open"); diff --git a/adapter/pubsub/datastructures.h b/adapter/pubsub/datastructures.h index e0d282964..1bbe8a226 100644 --- a/adapter/pubsub/datastructures.h +++ b/adapter/pubsub/datastructures.h @@ -36,12 +36,10 @@ namespace hermes::adapter::pubsub { * Struct that defines the metadata required for the pubsub adapter. */ struct ClientMetadata { - /** - * attributes - */ - std::shared_ptr st_bkid; /* bucket associated with the topic */ - u64 last_subscribed_blob; /* Current blob being used */ - timespec st_atim; /* time of last access */ + /** bucket associated with the topic */ + std::shared_ptr st_bkid; + u64 last_subscribed_blob; /**< Current blob being used */ + timespec st_atim; /**< time of last access */ /** * Constructor */ @@ -52,7 +50,7 @@ struct ClientMetadata { explicit ClientMetadata(const struct ClientMetadata &st) : st_bkid(st.st_bkid), last_subscribed_blob(st.last_subscribed_blob), - st_atim(st.st_atim) {} /* parameterized constructor */ + st_atim(st.st_atim) {} /**< parameterized constructor */ }; } // namespace hermes::adapter::pubsub diff --git a/adapter/pubsub/metadata_manager.h b/adapter/pubsub/metadata_manager.h index a8843fd5e..28eb1918f 100644 --- a/adapter/pubsub/metadata_manager.h +++ b/adapter/pubsub/metadata_manager.h @@ -16,9 +16,10 @@ /** * Standard headers */ -#include #include +#include + /** * Internal headers */ @@ -46,13 +47,11 @@ class MetadataManager { std::atomic ref; public: - int mpi_rank; + int mpi_rank; /**< rank of MPI processor */ /** * Constructor */ - explicit MetadataManager(bool is_mpi = true) - : metadata(), - ref(0) { + explicit MetadataManager(bool is_mpi = true) : metadata(), ref(0) { if (is_mpi) { MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); } else { @@ -65,11 +64,10 @@ class MetadataManager { */ std::shared_ptr& GetHermes() { return hermes; } - /** * Initialize hermes. */ - void InitializeHermes(const char *config_file) { + void InitializeHermes(const char* config_file) { if (ref == 0) { hermes = hapi::InitHermes(config_file, false, true); } @@ -87,42 +85,48 @@ class MetadataManager { ref--; } - bool isClient() { - return hermes->IsApplicationCore(); - } + /** + check if this application is client or core + */ + bool isClient() { return hermes->IsApplicationCore(); } /** * \brief Create a metadata entry for pubsub adapter for a given topic. - * \param topic, std::string&, name of the managed topic. - * \param stat, ClientMetadata&, current metadata of the topic. + * \param topic name of the managed topic. + * \param stat current metadata of the topic. * \return true, if operation was successful. * false, if operation was unsuccessful. */ bool Create(const std::string& topic, const ClientMetadata& stat); /** - * \brief Update existing metadata entry for pubsub adapter for a given file handler. - * \param topic, std::string&, name of the managed topic. - * \param stat, ClientMetadata&, current metadata of the topic to replace previous one. + * \brief Update existing metadata entry for pubsub adapter for a given file + * handler. + * \param topic name of the managed topic. + * \param stat current metadata of the topic to replace previous one. * \return true, if operation was successful. * false, if operation was unsuccessful or entry doesn't exist. - * \remark Update call will not degenerate into a create call if topic is not being tracked. + * \remark Update call will not degenerate into a create call + * if topic is not being tracked. */ bool Update(const std::string& topic, const ClientMetadata& stat); /** - * \brief Delete existing metadata entry for pubsub adapter for a given file handler. - * \param topic, std::string&, name of the managed topic. - * \return true, if operation was successful. - * false, if operation was unsuccessful. + * \brief Delete existing metadata entry for pubsub adapter for a given file + * handler. + * \param topic name of the managed topic. + * \return true, if operation was successful. + * false, if operation was unsuccessful. */ bool Delete(const std::string& topic); /** - * \brief Find existing metadata entry for pubsub adapter for a given file handler. - * \param topic, std::string&, name of the managed topic. + * \brief Find existing metadata entry for pubsub adapter for a given file + * handler. + * \param topic name of the managed topic. * \return The metadata entry if exist. - * The bool in pair indicated whether metadata entry exists. + * + * The bool in pair indicates whether metadata entry exists or not. */ std::pair Find(const std::string& topic); }; diff --git a/adapter/pubsub/pubsub.h b/adapter/pubsub/pubsub.h index c296e661f..8ee1e0106 100644 --- a/adapter/pubsub/pubsub.h +++ b/adapter/pubsub/pubsub.h @@ -29,8 +29,9 @@ */ #include #include -#include "metadata_manager.h" + #include "../constants.h" +#include "metadata_manager.h" #include "singleton.h" namespace hermes::pubsub { @@ -41,7 +42,7 @@ namespace hermes::pubsub { * \return The return code/status * */ -hapi::Status mpiInit(int argc, char **argv); +hapi::Status mpiInit(int argc, char** argv); /** * \brief Connects to the Hermes instance @@ -51,7 +52,7 @@ hapi::Status mpiInit(int argc, char **argv); * \return The return code/status * */ -hapi::Status connect(const std::string &config_file); +hapi::Status connect(const std::string& config_file); /** * \brief Connects to the Hermes instance diff --git a/adapter/stdio/fs_api.h b/adapter/stdio/fs_api.h index 3bf502b01..a10f3f418 100644 --- a/adapter/stdio/fs_api.h +++ b/adapter/stdio/fs_api.h @@ -1,39 +1,43 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_STDIO_NATIVE_H_ #define HERMES_ADAPTER_STDIO_NATIVE_H_ #include -#include "filesystem/filesystem.h" + #include "filesystem/filesystem.cc" -#include "filesystem/metadata_manager.h" +#include "filesystem/filesystem.h" #include "filesystem/metadata_manager.cc" +#include "filesystem/metadata_manager.h" #include "posix/real_api.h" #include "real_api.h" +using hermes::Singleton; using hermes::adapter::fs::AdapterStat; using hermes::adapter::fs::File; -using hermes::Singleton; -using hermes::adapter::stdio::API; using hermes::adapter::fs::IoOptions; using hermes::adapter::fs::IoStatus; +using hermes::adapter::stdio::API; namespace hermes::adapter::stdio { - +/** + A class to represent standard IO file system +*/ class StdioFS : public hermes::adapter::fs::Filesystem { private: - API* real_api; - hermes::adapter::posix::API* posix_api; + API *real_api; /**< pointer to real APIs */ + hermes::adapter::posix::API *posix_api; /**< pointer to POSIX APIs */ + public: StdioFS() { real_api = Singleton::GetInstance(); @@ -47,11 +51,10 @@ class StdioFS : public hermes::adapter::fs::Filesystem { void _OpenInitStats(File &f, AdapterStat &stat) override; File _RealOpen(AdapterStat &stat, const std::string &path) override; size_t _RealWrite(const std::string &filename, off_t offset, size_t size, - const u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) override; + const u8 *data_ptr, IoStatus &io_status, + IoOptions &opts) override; size_t _RealRead(const std::string &filename, off_t offset, size_t size, - u8 *data_ptr, - IoStatus &io_status, IoOptions &opts) override; + u8 *data_ptr, IoStatus &io_status, IoOptions &opts) override; int _RealSync(File &f) override; int _RealClose(File &f) override; }; diff --git a/adapter/stdio/real_api.h b/adapter/stdio/real_api.h index 4ff3ae343..51869521d 100644 --- a/adapter/stdio/real_api.h +++ b/adapter/stdio/real_api.h @@ -12,87 +12,123 @@ #ifndef HERMES_ADAPTER_STDIO_H #define HERMES_ADAPTER_STDIO_H -#include #include -#include #include + #include -#include "interceptor.h" +#include +#include + #include "filesystem/filesystem.h" #include "filesystem/metadata_manager.h" +#include "interceptor.h" -#define REQUIRE_API(api_name) \ - if (real_api->api_name == nullptr) { \ - LOG(FATAL) << "HERMES Adapter failed to map symbol: " \ - #api_name << std::endl; \ +#define REQUIRE_API(api_name) \ + if (real_api->api_name == nullptr) { \ + LOG(FATAL) << "HERMES Adapter failed to map symbol: " #api_name \ + << std::endl; \ 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); +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 { - +/** + A class to represent STDIO API +*/ class API { public: - int (*MPI_Init)(int * argc, char *** argv) = nullptr; - int (*MPI_Finalize)( void) = nullptr; - FILE * (*fopen)(const char * path, const char * mode) = nullptr; - FILE * (*fopen64)(const char * path, const char * mode) = nullptr; - FILE * (*fdopen)(int fd, const char * mode) = nullptr; - FILE * (*freopen)(const char * path, const char * mode, FILE * stream) = nullptr; - FILE * (*freopen64)(const char * path, const char * mode, FILE * stream) = nullptr; - int (*fflush)(FILE * fp) = nullptr; - int (*fclose)(FILE * fp) = nullptr; - size_t (*fwrite)(const void * ptr, size_t size, size_t nmemb, FILE * fp) = nullptr; - int (*fputc)(int c, FILE * fp) = nullptr; - int (*fgetpos)(FILE * fp, fpos_t * pos) = nullptr; - int (*fgetpos64)(FILE * fp, fpos64_t * pos) = nullptr; - int (*putc)(int c, FILE * fp) = nullptr; - int (*putw)(int w, FILE * fp) = nullptr; - int (*fputs)(const char * s, FILE * stream) = nullptr; - size_t (*fread)(void * ptr, size_t size, size_t nmemb, FILE * stream) = nullptr; - int (*fgetc)(FILE * stream) = nullptr; - int (*getc)(FILE * stream) = nullptr; - int (*getw)(FILE * stream) = nullptr; - char * (*fgets)(char * s, int size, FILE * stream) = nullptr; - void (*rewind)(FILE * stream) = nullptr; - int (*fseek)(FILE * stream, long offset, int whence) = nullptr; - int (*fseeko)(FILE * stream, off_t offset, int whence) = nullptr; - int (*fseeko64)(FILE * stream, off64_t offset, int whence) = nullptr; - int (*fsetpos)(FILE * stream, const fpos_t * pos) = nullptr; - int (*fsetpos64)(FILE * stream, const fpos64_t * pos) = nullptr; - long int (*ftell)(FILE * fp) = nullptr; + /** MPI_Init */ + int (*MPI_Init)(int *argc, char ***argv) = nullptr; + /** MPI_Finalize */ + int (*MPI_Finalize)(void) = nullptr; + /** fopen */ + FILE *(*fopen)(const char *path, const char *mode) = nullptr; + /** fopen64 */ + FILE *(*fopen64)(const char *path, const char *mode) = nullptr; + /** fdopen */ + FILE *(*fdopen)(int fd, const char *mode) = nullptr; + /** freopen */ + FILE *(*freopen)(const char *path, const char *mode, FILE *stream) = nullptr; + /** freopen64 */ + FILE *(*freopen64)(const char *path, const char *mode, + FILE *stream) = nullptr; + /** fflush */ + int (*fflush)(FILE *fp) = nullptr; + /** fclose */ + int (*fclose)(FILE *fp) = nullptr; + /** fwrite */ + size_t (*fwrite)(const void *ptr, size_t size, size_t nmemb, + FILE *fp) = nullptr; + /** fputc */ + int (*fputc)(int c, FILE *fp) = nullptr; + /** fgetpos */ + int (*fgetpos)(FILE *fp, fpos_t *pos) = nullptr; + /** fgetpos64 */ + int (*fgetpos64)(FILE *fp, fpos64_t *pos) = nullptr; + /** putc */ + int (*putc)(int c, FILE *fp) = nullptr; + /** putw */ + int (*putw)(int w, FILE *fp) = nullptr; + /** fputs */ + int (*fputs)(const char *s, FILE *stream) = nullptr; + /** fread */ + size_t (*fread)(void *ptr, size_t size, size_t nmemb, FILE *stream) = nullptr; + /** fgetc */ + int (*fgetc)(FILE *stream) = nullptr; + /** getc */ + int (*getc)(FILE *stream) = nullptr; + /** getw */ + int (*getw)(FILE *stream) = nullptr; + /** fgets */ + char *(*fgets)(char *s, int size, FILE *stream) = nullptr; + /** rewind */ + void (*rewind)(FILE *stream) = nullptr; + /** fseek */ + int (*fseek)(FILE *stream, long offset, int whence) = nullptr; + /** fseeko */ + int (*fseeko)(FILE *stream, off_t offset, int whence) = nullptr; + /** fseeko64 */ + int (*fseeko64)(FILE *stream, off64_t offset, int whence) = nullptr; + /** fsetpos */ + int (*fsetpos)(FILE *stream, const fpos_t *pos) = nullptr; + /** fsetpos64 */ + int (*fsetpos64)(FILE *stream, const fpos64_t *pos) = nullptr; + /** ftell */ + long int (*ftell)(FILE *fp) = nullptr; + /** API constructor that intercepts STDIO API calls */ API() { - void *is_intercepted = (void*)dlsym(RTLD_DEFAULT, "stdio_intercepted"); + void *is_intercepted = (void *)dlsym(RTLD_DEFAULT, "stdio_intercepted"); if (is_intercepted) { MPI_Init = (MPI_Init_t)dlsym(RTLD_NEXT, "MPI_Init"); } else { diff --git a/adapter/test/adapter_test_utils.h b/adapter/test/adapter_test_utils.h index a694bcfb4..e8d4ecb64 100644 --- a/adapter/test/adapter_test_utils.h +++ b/adapter/test/adapter_test_utils.h @@ -40,9 +40,9 @@ size_t GetRandomOffset(size_t i, unsigned int offset_seed, size_t stride, std::string GenRandom(const int len) { std::string tmp_s; static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; srand(100); diff --git a/adapter/test/catch_config.h b/adapter/test/catch_config.h index c694de46b..1317e1e50 100644 --- a/adapter/test/catch_config.h +++ b/adapter/test/catch_config.h @@ -14,28 +14,29 @@ #define HERMES_CATCH_CONFIG_H #define CATCH_CONFIG_RUNNER -#include #include +#include + namespace cl = Catch::Clara; cl::Parser define_options(); -int init(int *argc, char*** argv); +int init(int* argc, char*** argv); int finalize(); int main(int argc, char* argv[]) { - Catch::Session session; - auto cli = session.cli() | define_options(); - int returnCode = init(&argc, &argv); - if (returnCode != 0) return returnCode; - session.cli(cli); - returnCode = session.applyCommandLine(argc, argv); - if (returnCode != 0) return returnCode; - int test_return_code = session.run(); - returnCode = finalize(); - if (returnCode != 0) return returnCode; - return test_return_code; + Catch::Session session; + auto cli = session.cli() | define_options(); + int returnCode = init(&argc, &argv); + if (returnCode != 0) return returnCode; + session.cli(cli); + returnCode = session.applyCommandLine(argc, argv); + if (returnCode != 0) return returnCode; + int test_return_code = session.run(); + returnCode = finalize(); + if (returnCode != 0) return returnCode; + return test_return_code; } #endif diff --git a/adapter/test/mpiio/mpiio_adapter_basic_test.cpp b/adapter/test/mpiio/mpiio_adapter_basic_test.cpp index a339a9858..9035bd5d4 100644 --- a/adapter/test/mpiio/mpiio_adapter_basic_test.cpp +++ b/adapter/test/mpiio/mpiio_adapter_basic_test.cpp @@ -195,7 +195,7 @@ TEST_CASE("SingleWrite", "[process=" + std::to_string(info.comm_size) + pretest(); bool check_bytes = true; SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); + test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); REQUIRE(test::status_orig == MPI_SUCCESS); test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); REQUIRE(test::status_orig == 0); @@ -361,17 +361,17 @@ TEST_CASE("SingleWriteCollective", // https://github.com/HDFGroup/hermes/issues/209 SECTION("write to new file using shared ptr") { test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); REQUIRE(test::status_orig == MPI_SUCCESS); test::test_seek_shared(0, MPI_SEEK_SET); REQUIRE(test::status_orig == 0); test::test_write_shared(info.write_data.c_str(), args.request_size, - MPI_CHAR); + MPI_CHAR); REQUIRE((size_t)test::size_written_orig == args.request_size); test::test_close(); REQUIRE(test::status_orig == MPI_SUCCESS); REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); + (size_t)test::size_written_orig * info.comm_size); } SECTION("write to new file with allocate") { @@ -1003,13 +1003,13 @@ TEST_CASE("SingleAsyncReadCollective", pretest(); SECTION("read from non-existing file") { test::test_open(info.shared_new_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); + MPI_COMM_WORLD); REQUIRE(test::status_orig != MPI_SUCCESS); } SECTION("read from existing file") { test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); + MPI_COMM_WORLD); REQUIRE(test::status_orig == MPI_SUCCESS); test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); REQUIRE(test::status_orig == 0); @@ -1021,12 +1021,11 @@ TEST_CASE("SingleAsyncReadCollective", SECTION("read from existing file using shared ptr") { test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); + MPI_COMM_WORLD); REQUIRE(test::status_orig == MPI_SUCCESS); test::test_seek_shared(0, MPI_SEEK_SET); REQUIRE(test::status_orig == 0); - test::test_iread_shared(info.read_data.data(), args.request_size, - MPI_CHAR); + test::test_iread_shared(info.read_data.data(), args.request_size, MPI_CHAR); REQUIRE((size_t)test::size_read_orig == args.request_size); test::test_close(); REQUIRE(test::status_orig == MPI_SUCCESS); @@ -1035,8 +1034,8 @@ TEST_CASE("SingleAsyncReadCollective", SECTION("read_at_all from existing file") { test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iread_at_all(info.read_data.data(), args.request_size, - MPI_CHAR, info.rank * args.request_size); + test::test_iread_at_all(info.read_data.data(), args.request_size, MPI_CHAR, + info.rank * args.request_size); REQUIRE((size_t)test::size_read_orig == args.request_size); test::test_close(); REQUIRE(test::status_orig == MPI_SUCCESS); diff --git a/adapter/test/mpiio/mpiio_adapter_test.cpp b/adapter/test/mpiio/mpiio_adapter_test.cpp index 0a20a218c..70dc5c018 100644 --- a/adapter/test/mpiio/mpiio_adapter_test.cpp +++ b/adapter/test/mpiio/mpiio_adapter_test.cpp @@ -15,8 +15,8 @@ #include #include -#include "catch_config.h" #include "adapter_test_utils.h" +#include "catch_config.h" #if HERMES_INTERCEPT == 1 #include "filesystem/filesystem.h" #endif @@ -98,12 +98,9 @@ int pretest() { 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.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)) { @@ -227,12 +224,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); diff --git a/adapter/test/posix/posix_adapter_mpi_test.cpp b/adapter/test/posix/posix_adapter_mpi_test.cpp index e2201162e..2dbdeeec0 100644 --- a/adapter/test/posix/posix_adapter_mpi_test.cpp +++ b/adapter/test/posix/posix_adapter_mpi_test.cpp @@ -129,12 +129,9 @@ int pretest() { 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.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)) @@ -296,12 +293,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); @@ -338,6 +332,7 @@ int fh_cmp; int status_orig; size_t size_read_orig; size_t size_written_orig; + void test_open(const char* path, int flags, ...) { int mode = 0; if (flags & O_CREAT || flags & O_TMPFILE) { diff --git a/adapter/test/posix/posix_adapter_test.cpp b/adapter/test/posix/posix_adapter_test.cpp index 361c0fcf5..c57c0a402 100644 --- a/adapter/test/posix/posix_adapter_test.cpp +++ b/adapter/test/posix/posix_adapter_test.cpp @@ -95,12 +95,9 @@ int pretest() { fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); info.existing_file_cmp = fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - 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.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)) { @@ -195,12 +192,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); diff --git a/adapter/test/stdio/stdio_adapter_low_buffer_space_test.cpp b/adapter/test/stdio/stdio_adapter_low_buffer_space_test.cpp index c66b5fb2a..3f8903321 100644 --- a/adapter/test/stdio/stdio_adapter_low_buffer_space_test.cpp +++ b/adapter/test/stdio/stdio_adapter_low_buffer_space_test.cpp @@ -17,8 +17,8 @@ #include #include -#include "catch_config.h" #include "adapter_test_utils.h" +#include "catch_config.h" #if HERMES_INTERCEPT == 1 #include "stdio/real_api.h" #endif @@ -75,12 +75,9 @@ int pretest() { fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); info.existing_file_cmp = fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - 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.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)) { @@ -175,12 +172,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); diff --git a/adapter/test/stdio/stdio_adapter_mapper_test.cpp b/adapter/test/stdio/stdio_adapter_mapper_test.cpp index 1a7c31cea..1d5eb7ede 100644 --- a/adapter/test/stdio/stdio_adapter_mapper_test.cpp +++ b/adapter/test/stdio/stdio_adapter_mapper_test.cpp @@ -14,13 +14,13 @@ #include "catch_config.h" #include "constants.h" -#include "stdio/fs_api.h" #include "mapper/mapper_factory.h" +#include "stdio/fs_api.h" using hermes::adapter::BlobPlacements; using hermes::adapter::MapperFactory; -using hermes::adapter::fs::MetadataManager; using hermes::adapter::fs::kMapperType; +using hermes::adapter::fs::MetadataManager; namespace stdfs = std::experimental::filesystem; diff --git a/adapter/test/stdio/stdio_adapter_mode_test.cpp b/adapter/test/stdio/stdio_adapter_mode_test.cpp index 0859ca90a..d315c56e5 100644 --- a/adapter/test/stdio/stdio_adapter_mode_test.cpp +++ b/adapter/test/stdio/stdio_adapter_mode_test.cpp @@ -80,12 +80,9 @@ int finalize() { } int pretest() { - 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.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)) { @@ -177,12 +174,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); @@ -267,8 +261,7 @@ TEST_CASE("BatchedWriteSequentialPersistent", "[pattern=sequential][file=1]") { char* adapter_mode = getenv(kAdapterMode); REQUIRE(adapter_mode != nullptr); - bool is_same = - strcmp(kAdapterDefaultMode, adapter_mode) == 0; + bool is_same = strcmp(kAdapterDefaultMode, adapter_mode) == 0; REQUIRE(is_same); pretest(); SECTION("write to new file always at end") { diff --git a/adapter/test/stdio/stdio_adapter_mpi_test.cpp b/adapter/test/stdio/stdio_adapter_mpi_test.cpp index bb2870cf0..c279dd786 100644 --- a/adapter/test/stdio/stdio_adapter_mpi_test.cpp +++ b/adapter/test/stdio/stdio_adapter_mpi_test.cpp @@ -148,12 +148,9 @@ int pretest() { 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.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)) @@ -312,12 +309,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); diff --git a/adapter/test/stdio/stdio_adapter_test.cpp b/adapter/test/stdio/stdio_adapter_test.cpp index 37e337dc0..a88853f45 100644 --- a/adapter/test/stdio/stdio_adapter_test.cpp +++ b/adapter/test/stdio/stdio_adapter_test.cpp @@ -17,8 +17,8 @@ #include #include -#include "catch_config.h" #include "adapter_test_utils.h" +#include "catch_config.h" #if HERMES_INTERCEPT == 1 #include "stdio/real_api.h" #endif @@ -75,14 +75,13 @@ int pretest() { 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()); + info.new_file_cmp = + fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); + info.existing_file_cmp = + fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); 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)) stdfs::remove(info.existing_file); if (stdfs::exists(info.existing_file_cmp)) stdfs::remove(info.existing_file_cmp); if (!stdfs::exists(info.existing_file)) { @@ -176,12 +175,9 @@ int posttest(bool compare_data = true) { } } /* 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.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); diff --git a/adapter/test/vfd/hermes_vfd_test.cc b/adapter/test/vfd/hermes_vfd_test.cc index 796835879..e3458950e 100644 --- a/adapter/test/vfd/hermes_vfd_test.cc +++ b/adapter/test/vfd/hermes_vfd_test.cc @@ -32,39 +32,45 @@ using hermes::u32; namespace hermes::adapter::vfd::test { +/** + A structure to represent test arguments +*/ struct Arguments { - std::string filename = "test"; - std::string directory = "/tmp"; - size_t request_size = 65536; + std::string filename = "test"; /**< test file name */ + std::string directory = "/tmp"; /**< test directory name */ + size_t request_size = 65536; /**< test request size */ }; +/** + A structure to represent test information +*/ struct TestInfo { - static const int element_size = sizeof(f32); - - 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 new_file_cmp; - std::string existing_file_cmp; - std::string hdf5_extension = ".h5"; - size_t num_iterations = 64; - 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; - size_t small_max = KILOBYTES(4); - size_t medium_min = KILOBYTES(4) + 1; - size_t medium_max = KILOBYTES(256); - size_t large_min = KILOBYTES(256) + 1; - size_t large_max = MEGABYTES(3); - size_t nelems_per_dataset; - bool scratch_mode = false; + static const int element_size = sizeof(f32); /**< test element size */ + + // int rank = 0; + int comm_size = 1; /**< communicator size */ + std::vector write_data; /**< test data for writing */ + std::vector read_data; /**< test data for reading */ + std::string new_file; /**< new file name */ + std::string existing_file; /**< existing file name */ + std::string new_file_cmp; /**< new file name to compare */ + std::string existing_file_cmp; /**< existing file name to compare */ + std::string hdf5_extension = ".h5"; /**< HDF5 file extention to use */ + size_t num_iterations = 64; /**< number of iterations */ + // int offset_seed = 1; + // unsigned int rs_seed = 1; + // unsigned int temporal_interval_seed = 5; + size_t total_size; /**< total size */ + // size_t stride_size = 512; + unsigned int temporal_interval_ms = 1; /**< interval in milliseconds */ + // size_t small_min = 1; + // size_t small_max = KILOBYTES(4); + // size_t medium_min = KILOBYTES(4) + 1; + // size_t medium_max = KILOBYTES(256); + // size_t large_min = KILOBYTES(256) + 1; + // size_t large_max = MEGABYTES(3); + size_t nelems_per_dataset; /**< number of elements per dataset */ + bool scratch_mode = false; /**< flag for scratch mode */ }; /** @@ -74,8 +80,8 @@ struct TestInfo { * want to clutter the output with HDF5 error messages. */ class MuteHdf5Errors { - H5E_auto2_t old_func; - void *old_client_data; + H5E_auto2_t old_func; /**< error handler callback function */ + void *old_client_data; /**< pointer to client data for old_func */ public: MuteHdf5Errors() { @@ -96,9 +102,9 @@ class MuteHdf5Errors { * HDF5 identifiers required for reads and writes. */ struct RwIds { - hid_t dset_id; - hid_t dspace_id; - hid_t mspace_id; + hid_t dset_id; /**< dataset ID */ + hid_t dspace_id; /**< data space ID */ + hid_t mspace_id; /**< memory space ID */ }; /** @@ -211,7 +217,9 @@ struct Hdf5Api { RwCleanup(&ids); } - + /** + Create a 1-dimensional dataset using \a data vector. + */ void MakeDataset(hid_t hid, const std::string &dset_name, const std::vector &data, bool compact = false) { MakeDataset(hid, dset_name, data.data(), data.size(), compact); @@ -270,7 +278,9 @@ struct Hdf5Api { RwCleanup(&ids); } - + /** + Close HDF5 file. + */ herr_t Close(hid_t id) { herr_t result = H5Fclose(id); @@ -488,10 +498,12 @@ using hermes::adapter::vfd::test::Hdf5Api; */ namespace test { -hid_t hermes_hid; -hid_t sec2_hid; -herr_t hermes_herr; - +hid_t hermes_hid; /**< Hermes handle ID */ +hid_t sec2_hid; /**< POSIX driver handle ID */ +herr_t hermes_herr; /**< Hermes error return value */ +/** + Test creating and opening a new file. +*/ void TestOpen(const std::string &path, unsigned flags, bool create = false) { Hdf5Api api; @@ -515,7 +527,9 @@ void TestOpen(const std::string &path, unsigned flags, bool create = false) { REQUIRE(is_same); } - +/** + Test Close() calls. +*/ void TestClose() { Hdf5Api api; hermes_herr = api.Close(hermes_hid); @@ -523,6 +537,9 @@ void TestClose() { REQUIRE(status == hermes_herr); } +/** + Test writing partial 1-D dataset. +*/ void TestWritePartial1d(const std::string &dset_name, const f32 *data, hsize_t offset, hsize_t nelems) { Hdf5Api api; @@ -530,6 +547,9 @@ void TestWritePartial1d(const std::string &dset_name, const f32 *data, api.WritePartial1d(test::sec2_hid, dset_name, data, offset, nelems); } +/** + Test making dataset. +*/ void TestWriteDataset(const std::string &dset_name, const std::vector &data) { Hdf5Api api; @@ -537,6 +557,10 @@ void TestWriteDataset(const std::string &dset_name, api.MakeDataset(test::sec2_hid, dset_name, data); } + +/** + Test making compact dataset. +*/ void TestMakeCompactDataset(const std::string &dset_name, const std::vector &data) { Hdf5Api api; @@ -544,6 +568,9 @@ void TestMakeCompactDataset(const std::string &dset_name, api.MakeDataset(test::sec2_hid, dset_name, data, true); } +/** + Test reading dataset. +*/ void TestRead(const std::string &dset_name, std::vector &buf, hsize_t offset, hsize_t nelems) { Hdf5Api api; diff --git a/ci/install_docs.sh b/ci/install_docs.sh index 3b16abfb7..ada02aec8 100755 --- a/ci/install_docs.sh +++ b/ci/install_docs.sh @@ -1,8 +1,8 @@ #!/bin/bash -set -x -set -e -set -o pipefail +# set -x +# set -e +# set -o pipefail mkdir build pushd build @@ -33,8 +33,10 @@ cmake \ -DHERMES_ENABLE_VFD=ON \ -DBUILD_TESTING=ON \ .. -make dox -# cmake --build . -- -j4 -# ctest -VV - +make dox >& out.txt +# cat out.txt | grep warning | grep -v "ignoring unsupported tag" popd +rec="$( grep warning build/out.txt | grep -v "ignoring unsupported tag" | wc -l )" +echo $rec +exit $rec + diff --git a/data_stager/data_stager.h b/data_stager/data_stager.h index 759520bca..a16b2ce7f 100644 --- a/data_stager/data_stager.h +++ b/data_stager/data_stager.h @@ -1,28 +1,26 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_DATA_STAGER_STAGE_IN_H_ #define HERMES_DATA_STAGER_STAGE_IN_H_ -#include "posix/fs_api.h" -#include "hermes_types.h" #include +#include "hermes_types.h" +#include "posix/fs_api.h" + namespace hermes { -enum class DataStagerType { - kUnix, - kHdf5 -}; +enum class DataStagerType { kUnix, kHdf5 }; class DataStagerTypeConv { public: @@ -38,13 +36,12 @@ class DataStagerTypeConv { class DataStager { public: virtual void StageIn(std::string url, PlacementPolicy dpe) = 0; - virtual void StageIn(std::string url, - off_t off, size_t size, PlacementPolicy dpe) = 0; + virtual void StageIn(std::string url, off_t off, size_t size, + 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) { + void DivideRange(off_t off, size_t size, off_t &new_off, size_t &new_size) { auto mdm = Singleton::GetInstance(); int concurrency = 1; int rank = 0; diff --git a/data_stager/data_stager_factory.h b/data_stager/data_stager_factory.h index 22932e155..127cbb63f 100644 --- a/data_stager/data_stager_factory.h +++ b/data_stager/data_stager_factory.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_DATA_STAGER_STAGE_FACTORY_H_ #define HERMES_DATA_STAGER_STAGE_FACTORY_H_ diff --git a/data_stager/stagers/unix_stager.h b/data_stager/stagers/unix_stager.h index ab28c1d25..7d9556385 100644 --- a/data_stager/stagers/unix_stager.h +++ b/data_stager/stagers/unix_stager.h @@ -1,20 +1,20 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* 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_DATA_STAGER_STAGERS_UNIX_STAGE_H_ #define HERMES_DATA_STAGER_STAGERS_UNIX_STAGE_H_ -#include "posix/fs_api.h" #include "../data_stager.h" +#include "posix/fs_api.h" namespace hermes { @@ -24,10 +24,10 @@ class UnixStager : public DataStager { void FileStageIn(std::string path, PlacementPolicy dpe); void DirectoryStageIn(std::string path, PlacementPolicy dpe); - void StageIn(std::string url, - off_t off, size_t size, PlacementPolicy dpe) override; - void FileStageIn(std::string path, - off_t off, size_t size, PlacementPolicy dpe); + void StageIn(std::string url, off_t off, size_t size, + PlacementPolicy dpe) override; + void FileStageIn(std::string path, off_t off, size_t size, + PlacementPolicy dpe); void StageOut(std::string url) override; void FileStageOut(std::string path); diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index d47fb48b9..e351f448e 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1,17 +1,145 @@ -# Doxyfile 1.8.14 +# Doxyfile 1.9.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + PROJECT_NAME = Hermes + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + PROJECT_NUMBER = 0.8.0-beta + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + PROJECT_BRIEF = "Hierarchical Distributed I/O Buffering System" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# numer of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ @@ -23,300 +151,2535 @@ ABBREVIATE_BRIEF = "The $name class" \ a \ an \ the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + JAVADOC_AUTOBRIEF = NO + +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + TAB_SIZE = 4 -ALIASES += status="A Status object." -ALIASES += ctx{1}="ctx The Context for this \1." -ALIASES += bool{1}="true if \1, otherwise false." +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = "status=A Status object." \ + "ctx{1}=ctx The Context for this \1." \ + "bool{1}=true if \1, otherwise false." + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. -TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + EXTRACT_PRIVATE = YES + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + CITE_BIB_FILES = + #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + WARN_LOGFILE = + #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + INPUT = @PROJECT_SOURCE_DIR@/adapter \ @PROJECT_SOURCE_DIR@/gotcha_intercept \ @PROJECT_SOURCE_DIR@/src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. + FILE_PATTERNS = *.h \ *.cc + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + EXCLUDE = @PROJECT_SOURCE_DIR@/src/stb_ds.h + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + USE_MDFILE_AS_MAINPAGE = front_page.md + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + VERBATIM_HEADERS = YES + #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + IGNORE_PREFIX = + #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. Default setting AUTO_LIGHT +# enables light output unless the user preference is dark output. Other options +# are DARK to always use dark mode, LIGHT to always use light mode, AUTO_DARK to +# default to dark mode unless the user prefers light mode, and TOGGLE to let the +# user toggle between dark and light mode via a button. +# Possible values are: LIGHT Always generate light output., DARK Always generate +# dark output., AUTO_LIGHT Automatically set the mode according to the user +# preference, use light mode if no preference is set (the default)., AUTO_DARK +# Automatically set the mode according to the user preference, use dark mode if +# no preference is set. and TOGGLE Allow to user to switch between light and +# dark mode via a button.. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + GENERATE_TREEVIEW = YES + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + FORMULA_FONTSIZE = 10 -FORMULA_TRANSPARENT = YES + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /