diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8cf6802..e298a57 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,23 +39,23 @@ jobs: if: matrix.os == 'macos-latest' run: brew update-reset && brew install boost - - name: Configure CMake - run: > - cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=${{ matrix.release }} -DENABLE_TESTING=ON -DENABLE_EXAMPLES=ON + # - name: Configure CMake + # run: > + # cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=${{ matrix.release }} -DENABLE_TESTING=ON -DENABLE_EXAMPLES=ON - - name: Build - run: cmake --build build --config ${{ matrix.release }} - - - name: Install - if: matrix.os != 'windows-latest' - run: sudo cmake --install build --config ${{ matrix.release }} + # - name: Build + # run: cmake --build build --config ${{ matrix.release }} # - name: Install - # if: matrix.os == 'windows-latest' - # run: cmake --install build --config ${{ matrix.release }} + # if: matrix.os != 'windows-latest' + # run: sudo cmake --install build --config ${{ matrix.release }} + + # # - name: Install + # # if: matrix.os == 'windows-latest' + # # run: cmake --install build --config ${{ matrix.release }} - - name: Test - run: ctest --test-dir build --output-on-failure + # - name: Test + # run: ctest --test-dir build --output-on-failure - - name: Examples - run: ./build/libtokamap/examples/simple_mapper/simple_mapper + # - name: Examples + # run: ./build/libtokamap/examples/simple_mapper/simple_mapper diff --git a/CMakeLists.txt b/CMakeLists.txt index abd43dc..7fedc31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ list( ) # Specify C++ standard for all targets -set( CMAKE_CXX_STANDARD 17 ) +set( CMAKE_CXX_STANDARD 20 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) set( CMAKE_CXX_EXTENSIONS OFF ) @@ -42,24 +42,32 @@ if( POLICY CMP0167 ) endif() # Set project options -include( StandardSettings ) include( StaticAnalyzers ) include( Utils ) +option( ENABLE_TESTING "Enable unit tests for the project (from the `test` subfolder)." OFF ) +option( ENABLE_PROFILING "Enable profiling for the project." OFF ) +option( FETCH_LIBTOKAMAP "Fetch libtokamap as a dependency." OFF ) + # add_clang_format_target() if( ENABLE_TESTING ) enable_testing() endif() -include( FetchContent ) -FetchContent_Declare( - libtokamap - GIT_REPOSITORY git@github.com:jholloc/libtokamap.git - GIT_TAG main -) +if( FETCH_LIBTOKAMAP ) + include( FetchContent ) + FetchContent_Declare( + libtokamap + GIT_REPOSITORY https://github.com/ukaea/libtokamap.git + GIT_TAG develop + CMAKE_ARGS -DENABLE_TESTS=OFF -DENABLE_PROFILING=${ENABLE_PROFILING} + ) -FetchContent_MakeAvailable( libtokamap ) + FetchContent_MakeAvailable( libtokamap ) +else() + add_clang_format_target() +endif() find_package( UDA REQUIRED ) add_subdirectory( mapping_plugin ) diff --git a/cmake/StandardSettings.cmake b/cmake/StandardSettings.cmake deleted file mode 100644 index f3f25a9..0000000 --- a/cmake/StandardSettings.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# Compiler options -option( - ${PROJECT_NAME}_WARNINGS_AS_ERRORS - "Treat compiler warnings as errors." ON -) - -# Unit testing -option( - ${PROJECT_NAME}_ENABLE_TESTING - "Enable unit tests for the projects (from the `test` subfolder)." OFF -) -option( - ${PROJECT_NAME}_ENABLE_CODE_COVERAGE - "Enable code coverage for unit tests." OFF -) - -# Static analyzers -# Currently supporting: Clang-Tidy, Cppcheck. -option( - ${PROJECT_NAME}_ENABLE_CLANG_TIDY - "Enable static analysis with Clang-Tidy." OFF -) -option( - ${PROJECT_NAME}_ENABLE_CPPCHECK - "Enable static analysis with Cppcheck." OFF -) - -# Miscellaneous options -# Generate compile_commands.json for clang based tools -set( CMAKE_EXPORT_COMPILE_COMMANDS ON ) - -option( - ${PROJECT_NAME}_VERBOSE_OUTPUT - "Enable verbose output, allowing\ - for a better understanding of each step taken." ON -) - -option( - ${PROJECT_NAME}_ENABLE_CCACHE - "Enable the usage of Ccache, in order to speed up rebuild times." OFF -) - -find_program( CCACHE_FOUND ccache ) -if( CCACHE_FOUND ) - set_property( GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache ) - set_property( GLOBAL PROPERTY RULE_LAUNCH_LINK ccache ) -endif() - -option( - ${PROJECT_NAME}_ENABLE_ASAN - "Enable Address Sanitize to detect memory error." OFF -) -if( ${PROJECT_NAME}_ENABLE_ASAN ) - add_compile_options(-fsanitize=address) - add_link_options(-fsanitize=address) -endif() diff --git a/cmake/plugins.cmake b/cmake/plugins.cmake index 723cb81..4b1cee5 100644 --- a/cmake/plugins.cmake +++ b/cmake/plugins.cmake @@ -28,7 +28,7 @@ macro( uda_plugin ) "${ARGN}" ) - set( BUILT_PLUGINS ${BUILT_PLUGINS} "${PLUGIN_NAME}" PARENT_SCOPE ) + set( BUILT_PLUGINS ${BUILT_PLUGINS} "${PLUGIN_NAME}" ) if( NOT PLUGIN_VERSION ) set( PLUGIN_VERSION "0.0.0" ) diff --git a/mapping_plugin/CMakeLists.txt b/mapping_plugin/CMakeLists.txt index 4ece78f..5255a9a 100644 --- a/mapping_plugin/CMakeLists.txt +++ b/mapping_plugin/CMakeLists.txt @@ -7,11 +7,7 @@ find_package( UDA 2.7.0 REQUIRED ) find_package( Boost REQUIRED ) - -# Specify C++ standard for all targets -set( CMAKE_CXX_STANDARD 17 ) -set( CMAKE_CXX_STANDARD_REQUIRED ON ) -set( CMAKE_CXX_EXTENSIONS OFF ) +find_package( libtokamap REQUIRED ) set( SOURCES src/uda_data_source.cpp @@ -31,11 +27,13 @@ add_library( libtokamap_uda_extension ${SOURCES} ) target_include_directories( libtokamap_uda_extension PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src ${CMAKE_CURRENT_LIST_DIR}/ext_include - ${CMAKE_SOURCE_DIR}/libtokamap/src ) target_link_libraries( libtokamap_uda_extension PRIVATE Boost::boost LibTokaMap::libtokamap ) -find_package( Boost REQUIRED ) +set( EXTRA_DEFINITIONS ) +if( ENABLE_PROFILING ) + list( APPEND EXTRA_DEFINITIONS -DENABLE_PROFILING ) +endif() include( plugins ) uda_plugin( @@ -58,6 +56,8 @@ uda_plugin( LibTokaMap::libtokamap libtokamap_uda_extension uda_client + EXTRA_DEFINITIONS + ${EXTRA_DEFINITIONS} ) # Unit testing setup @@ -98,6 +98,7 @@ install( ) # Generate scripts +list( GET UDA_DIR 0 UDA_HOME ) string( REGEX REPLACE ";" " " PLUGINS "${BUILT_PLUGINS}" ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/scripts/activate-plugins.sh.in diff --git a/mapping_plugin/config/json_mapping.cfg.in b/mapping_plugin/config/json_mapping.cfg.in index e2d6dea..354cbe5 100644 --- a/mapping_plugin/config/json_mapping.cfg.in +++ b/mapping_plugin/config/json_mapping.cfg.in @@ -1,3 +1,4 @@ # Needed at runtime to find the installed mappings locations on the server side machine # Environmental Variables are available on server after install export UDA_MAPPING_CONFIG_PATH=@CMAKE_INSTALL_PREFIX@/etc/plugins.d/libtokamap_config.json +export UDA_MAPPING_PROFILE_FILE=@CMAKE_INSTALL_PREFIX@/etc/profile.json diff --git a/mapping_plugin/config/libtokamap_config.json.in b/mapping_plugin/config/libtokamap_config.json.in index c6b0d09..d8921ad 100644 --- a/mapping_plugin/config/libtokamap_config.json.in +++ b/mapping_plugin/config/libtokamap_config.json.in @@ -1,8 +1,6 @@ { "mapping_directory": "@CMAKE_INSTALL_PREFIX@/etc/JSON_mappings", - "globals_schema": "@CMAKE_BINARY_DIR@/_deps/libtokamap-src/schemas/mappings.schema.json", - "mapping_schema": "@CMAKE_BINARY_DIR@/_deps/libtokamap-src/schemas/globals.schema.json", - "mapping_config_schema": "@CMAKE_BINARY_DIR@/_deps/libtokamap-src/schemas/mappings.cfg.schema.json", + "schemas_directory": "@CMAKE_BINARY_DIR@/_deps/libtokamap-src/schemas", "cache_enabled": false, "cache_size": 100 } diff --git a/mapping_plugin/mapping_plugin.cpp b/mapping_plugin/mapping_plugin.cpp index d8c0f2f..ce823fb 100644 --- a/mapping_plugin/mapping_plugin.cpp +++ b/mapping_plugin/mapping_plugin.cpp @@ -17,8 +17,7 @@ #include // LibTokaMap includes -#include -#include +#include // UDA includes #include @@ -33,6 +32,7 @@ #include "uda_data_source.hpp" #include "uda_plugin_helpers.hpp" +#include "utils/profiler.hpp" namespace { @@ -99,6 +99,13 @@ class JSONMappingPlugin public: int entry_handle(IDAM_PLUGIN_INTERFACE* plugin_interface); + ~JSONMappingPlugin() + { + if (m_init) { + reset(nullptr); + } + } + private: int execute(IDAM_PLUGIN_INTERFACE* plugin_interface); int init(IDAM_PLUGIN_INTERFACE* plugin_interface); @@ -133,6 +140,10 @@ int JSONMappingPlugin::init(IDAM_PLUGIN_INTERFACE* plugin_interface) return 0; } +#if ENABLE_PROFILING + libtokamap::Profiler::init(); +#endif + const char* config_path = getenv("UDA_MAPPING_CONFIG_PATH"); if (config_path != nullptr) { m_mapping_handler.init(std::filesystem::path{config_path}); @@ -143,10 +154,12 @@ int JSONMappingPlugin::init(IDAM_PLUGIN_INTERFACE* plugin_interface) auto data_source = std::make_unique("UDA", "get", plugin_interface->pluginList, false); m_mapping_handler.register_data_source("UDA", std::move(data_source)); - auto mastu_data_source = std::make_unique("CUSTOM_MASTU", "get", plugin_interface->pluginList, false); + auto mastu_data_source = + std::make_unique("CUSTOM_MASTU", "get", plugin_interface->pluginList, false); m_mapping_handler.register_data_source("CUSTOM_MASTU", std::move(mastu_data_source)); - auto geom_data_source = std::make_unique("GEOMETRY", "get", plugin_interface->pluginList, false); + auto geom_data_source = + std::make_unique("GEOMETRY", "get", plugin_interface->pluginList, false); m_mapping_handler.register_data_source("GEOMETRY", std::move(geom_data_source)); m_init = true; @@ -164,6 +177,13 @@ int JSONMappingPlugin::init(IDAM_PLUGIN_INTERFACE* plugin_interface) int JSONMappingPlugin::reset(IDAM_PLUGIN_INTERFACE* /*plugin_interface*/) // silence unused warning { if (m_init) { +#if ENABLE_PROFILING + const char* profile_file = getenv("UDA_MAPPING_PROFILE_FILE"); + if (profile_file != nullptr) { + libtokamap::Profiler::write(profile_file); + } +#endif + // Free Heap & reset counters if initialised m_mapping_handler.unregister_data_source("UDA"); m_mapping_handler.unregister_data_source("CUSTOM_MASTU"); @@ -235,6 +255,9 @@ int JSONMappingPlugin::get(IDAM_PLUGIN_INTERFACE* plugin_interface) auto type_index = std::type_index{typeid(void)}; switch (datatype) { + case UDA_TYPE_SHORT: + type_index = std::type_index{typeid(short)}; + break; case UDA_TYPE_INT: type_index = std::type_index{typeid(int)}; break; @@ -247,6 +270,33 @@ int JSONMappingPlugin::get(IDAM_PLUGIN_INTERFACE* plugin_interface) case UDA_TYPE_STRING: type_index = std::type_index{typeid(char)}; break; + case UDA_TYPE_UNSIGNED_LONG64: + type_index = std::type_index{typeid(uint64_t)}; + break; + case UDA_TYPE_UNSIGNED_INT: + type_index = std::type_index{typeid(unsigned int)}; + break; + case UDA_TYPE_LONG: + type_index = std::type_index{typeid(long)}; + break; + case UDA_TYPE_UNSIGNED_CHAR: + type_index = std::type_index{typeid(unsigned char)}; + break; + case UDA_TYPE_UNSIGNED_SHORT: + type_index = std::type_index{typeid(unsigned short)}; + break; + case UDA_TYPE_UNSIGNED_LONG: + type_index = std::type_index{typeid(unsigned long)}; + break; + case UDA_TYPE_LONG64: + type_index = std::type_index{typeid(int64_t)}; + break; + case UDA_TYPE_COMPLEX: + type_index = std::type_index{typeid(COMPLEX)}; + break; + case UDA_TYPE_DCOMPLEX: + type_index = std::type_index{typeid(DCOMPLEX)}; + break; default: break; } diff --git a/mapping_plugin/src/uda_data_source.cpp b/mapping_plugin/src/uda_data_source.cpp index 0c82eec..077d1c8 100644 --- a/mapping_plugin/src/uda_data_source.cpp +++ b/mapping_plugin/src/uda_data_source.cpp @@ -13,6 +13,7 @@ // UDA includes #include +#include #include #include #include @@ -26,8 +27,9 @@ #include "map_types/data_source_mapping.hpp" #include "map_types/map_arguments.hpp" -#include "uda_ram_cache.hpp" -#include "utils/ram_cache.hpp" +// #include "uda_ram_cache.hpp" +// #include "utils/ram_cache.hpp" +#include "utils/typed_data_array.hpp" // TODO: // - handle compressed dims @@ -48,7 +50,15 @@ std::string json_plugin::UDADataSource::get_request_str(const libtokamap::DataSo const libtokamap::MapArguments& arguments) const { std::stringstream string_stream; - string_stream << m_plugin_name << "::" << m_function.value_or("get") << "("; + // string_stream << m_plugin_name << "::" << m_function.value_or("get") << "("; + string_stream << m_plugin_name << "::"; + + if (data_source_args.count("function") != 0) { + string_stream << data_source_args.at("function").get(); + } else { + string_stream << m_function.value_or("get"); + } + string_stream << "("; // m_map_args 'field' currently nlohmann json // parse to string/bool @@ -89,94 +99,195 @@ int json_plugin::UDADataSource::call_plugins(DATA_BLOCK* data_block, const libto return err; } // Return 1 if no request receieved - /* - * - * generate subset info then remove subset syntax from - * request string - * - */ - REQUEST_DATA request = {0}; strcpy(request.signal, request_str.c_str()); ENVIRONMENT* environment = getIdamClientEnvironment(); makeRequestData(&request, *m_plugin_list, environment); - // if (m_cache_enabled) { - // std::string key_found = ram_cache->has_entry(request_str) ? "True" : "False"; - // ram_cache->log(libtokamap:LogLevel::DEBUG, "key, \"" + request_str + "\" in cache? " + key_found); - // } - - /* - * - * CACHING GOES HERE - * - */ - - // check cache for request string and only get data if it's not already there - // currently copies whole datablock (data, error, and dims) - // if (m_cache_enabled) { - // ram_cache->log(libtokamap::LogLevel::DEBUG, "caching disabled"); - // } - - bool cache_hit = false; - if (m_cache_enabled && ram_cache != nullptr) { - cache_hit = json_plugin::copy_from_cache(*ram_cache, request_str, data_block); - } - if (cache_hit) { - // ram_cache->log(libtokamap:LogLevel::INFO, "Adding cached datablock onto plugin_interface"); - // ram_cache->log(libtokamap:LogLevel::INFO, - // "data on plugin_interface (data_n): " + std::to_string(data_block->data_n)); - err = 0; - } else { - IDAM_PLUGIN_INTERFACE interface = {0}; - CLIENT_BLOCK client_block; - DATA_SOURCE data_source; - SIGNAL_DESC signal_desc; - initClientBlock(&client_block, 0, ""); - initDataSource(&data_source); - initSignalDesc(&signal_desc); - - interface.request_data = &request; - interface.pluginList = m_plugin_list; - interface.data_block = data_block; - interface.environment = environment; - interface.client_block = &client_block; - interface.data_source = &data_source; - interface.signal_desc = &signal_desc; - - err = callPlugin(m_plugin_list, request_str.c_str(), &interface); - - if (err != 0) { - // add check of int udaNumErrors() and if more than one, don't wipe - // 220 situation when UDA tries to get data and cannot find it - if (err == 220) { - closeUdaError(); - } - return err; - } // return code if failure, no need to proceed + IDAM_PLUGIN_INTERFACE interface = {0}; + CLIENT_BLOCK client_block; + DATA_SOURCE data_source; + SIGNAL_DESC signal_desc; + initClientBlock(&client_block, 0, ""); + initDataSource(&data_source); + initSignalDesc(&signal_desc); - // Add retrieved datablock to cache. data is copied from datablock into a new libtokamap:data_entry. original - // data remains on block (on plugin_interface structure) for return. - if (m_cache_enabled && ram_cache != nullptr) { - json_plugin::copy_to_cache(*ram_cache, request_str, data_block); + interface.request_data = &request; + interface.pluginList = m_plugin_list; + interface.data_block = data_block; + interface.environment = environment; + interface.client_block = &client_block; + interface.data_source = &data_source; + interface.signal_desc = &signal_desc; + + err = callPlugin(m_plugin_list, request_str.c_str(), &interface); + + if (err != 0) { + // add check of int udaNumErrors() and if more than one, don't wipe + // 220 situation when UDA tries to get data and cannot find it + if (err == 220) { + closeUdaError(); } - } + return err; + } // return code if failure, no need to proceed return err; } namespace { -template -libtokamap::TypedDataArray set_return_data(DataBlock& data_block, size_t size, std::vector&& shape, bool is_time) +class ArrayBuilder { - auto ptr = is_time ? data_block.dims[data_block.order].dim : data_block.data; - auto array = libtokamap::TypedDataArray{reinterpret_cast(ptr), size, std::move(shape), false}; - // we set the data_block.data to nullptr to avoid double deletion - data_block.data = nullptr; - return array; -} + private: + const char* m_data = nullptr; + size_t m_size = {}; + std::vector m_shape; + int m_data_type = UDA_TYPE_UNKNOWN; + bool m_owning = true; + bool m_ownership_locked = false; + bool m_buildable = false; + bool m_free_data_required = false; + + public: + ArrayBuilder() = default; + ~ArrayBuilder() + { + if (m_free_data_required and m_data != nullptr) { + free(const_cast(m_data)); + } + } + + ArrayBuilder(const ArrayBuilder&) = delete; + ArrayBuilder& operator=(const ArrayBuilder&) = delete; + ArrayBuilder(ArrayBuilder&& other) = delete; + ArrayBuilder& operator=(ArrayBuilder&& other) = delete; + + enum class OwnershipPolicy { VIEW, COPY }; + + void set_ownership(OwnershipPolicy policy) + { + bool is_owning = (policy == OwnershipPolicy::COPY); + if (m_ownership_locked and m_owning != is_owning) { + throw std::runtime_error("Ownership policy already enforced by a previous option"); + } + m_owning = is_owning; + } + ArrayBuilder& ownership(OwnershipPolicy policy) + { + set_ownership(policy); + return *this; + } + + void set_data(const DATA_BLOCK& db) + { + m_data = db.data; + m_size = db.data_n; + m_shape.reserve(db.rank); + for (int i = 0; i < db.rank; ++i) { + m_shape.push_back(db.dims[i].dim_n); + } + m_data_type = db.data_type; + m_buildable = true; + } + ArrayBuilder& data(const DATA_BLOCK& db) + { + set_data(db); + return *this; + } + + void set_dimension_data(const DIMS& dim) + { + if (dim.compressed > 0) { + DIMS tmp_dim = dim; + + uncompressDim(&tmp_dim); + tmp_dim.compressed = 0; + tmp_dim.method = 0; + + m_data = tmp_dim.dim; + tmp_dim.dim = nullptr; + m_free_data_required = true; + + m_owning = true; + m_ownership_locked = true; // cannot guarantee sufficient object lifetime? + } else { + m_data = dim.dim; + } + m_size = dim.dim_n; + m_shape = {m_size}; + m_data_type = dim.data_type; + m_buildable = true; + } + ArrayBuilder& dimension(const DIMS& dim) + { + set_dimension_data(dim); + return *this; + } + + void set_time_data(const DATA_BLOCK& db) + { + auto index = db.order; + if (index < 0 or index > db.rank or db.rank < 1) { + throw std::runtime_error("No time data available for this signal"); + } + set_dimension_data(db.dims[index]); + } + ArrayBuilder& time(const DATA_BLOCK& db) + { + set_time_data(db); + return *this; + } + + private: + template libtokamap::TypedDataArray _array_factory() + { + return libtokamap::TypedDataArray(reinterpret_cast(const_cast(m_data)), m_size, std::move(m_shape), + m_owning); + } + template <> libtokamap::TypedDataArray _array_factory() + { + return libtokamap::TypedDataArray(const_cast(m_data), m_size, std::move(m_shape), m_owning); + } + + public: + libtokamap::TypedDataArray build() + { + switch (m_data_type) { + case UDA_TYPE_SHORT: + return _array_factory(); + case UDA_TYPE_INT: + return _array_factory(); + case UDA_TYPE_UNSIGNED_INT: + return _array_factory(); + case UDA_TYPE_LONG: + return _array_factory(); + case UDA_TYPE_LONG64: + return _array_factory(); + case UDA_TYPE_FLOAT: + return _array_factory(); + case UDA_TYPE_DOUBLE: + return _array_factory(); + case UDA_TYPE_UNSIGNED_CHAR: + return _array_factory(); + case UDA_TYPE_UNSIGNED_SHORT: + return _array_factory(); + case UDA_TYPE_UNSIGNED_LONG: + return _array_factory(); + case UDA_TYPE_UNSIGNED_LONG64: + return _array_factory(); + case UDA_TYPE_CHAR: + case UDA_TYPE_STRING: + return _array_factory(); + case UDA_TYPE_COMPLEX: + return _array_factory(); + case UDA_TYPE_DCOMPLEX: + return _array_factory(); + default: + throw std::runtime_error{"unknown data type"}; + } + } +}; } // namespace libtokamap::TypedDataArray json_plugin::UDADataSource::get(const libtokamap::DataSourceArgs& data_source_args, @@ -190,28 +301,8 @@ libtokamap::TypedDataArray json_plugin::UDADataSource::get(const libtokamap::Dat return {}; } - // temporary solution to the slice functionality returning arrays of 1 element - if (data_block.rank == 1 && data_block.data_n == 1) { - data_block.rank = 0; - } - - size_t size = data_block.data_n; - std::vector shape(data_block.rank); - for (int i = 0; i < data_block.rank; ++i) { - shape[i] = data_block.dims[i].dim_n; - } - bool is_time = data_source_args.count("time") != 0 && data_source_args.at("time").get(); - - switch (data_block.data_type) { - case UDA_TYPE_INT: - return set_return_data(data_block, size, std::move(shape), is_time); - case UDA_TYPE_FLOAT: - return set_return_data(data_block, size, std::move(shape), is_time); - case UDA_TYPE_DOUBLE: - return set_return_data(data_block, size, std::move(shape), is_time); - case UDA_TYPE_STRING: - return set_return_data(data_block, size, std::move(shape), is_time); - default: - throw std::runtime_error{"unknown data type"}; + if (data_source_args.count("time") != 0 && data_source_args.at("time").get()) { + return ArrayBuilder().ownership(ArrayBuilder::OwnershipPolicy::COPY).time(data_block).build(); } + return ArrayBuilder().ownership(ArrayBuilder::OwnershipPolicy::COPY).data(data_block).build(); } diff --git a/mapping_plugin/src/uda_plugin_helpers.cpp b/mapping_plugin/src/uda_plugin_helpers.cpp index 482e646..4b11f1f 100644 --- a/mapping_plugin/src/uda_plugin_helpers.cpp +++ b/mapping_plugin/src/uda_plugin_helpers.cpp @@ -1,28 +1,35 @@ #include "uda_plugin_helpers.hpp" #include +#include +#include +#include #include #include #include #include -#include -#include #include #include #include -#include "map_types/map_arguments.hpp" - std::unordered_map json_plugin::uda_type_map() { static std::unordered_map type_map; if (type_map.empty()) { type_map = {{typeid(unsigned int).name(), UDA_TYPE_UNSIGNED_INT}, + {typeid(unsigned char).name(), UDA_TYPE_UNSIGNED_CHAR}, + {typeid(unsigned short).name(), UDA_TYPE_UNSIGNED_SHORT}, + {typeid(unsigned long).name(), UDA_TYPE_UNSIGNED_LONG}, + {typeid(uint64_t).name(), UDA_TYPE_UNSIGNED_LONG64}, + {typeid(short).name(), UDA_TYPE_SHORT}, {typeid(int).name(), UDA_TYPE_INT}, + {typeid(long).name(), UDA_TYPE_LONG}, {typeid(float).name(), UDA_TYPE_FLOAT}, {typeid(double).name(), UDA_TYPE_DOUBLE}, {typeid(char).name(), UDA_TYPE_STRING}, + {typeid(COMPLEX).name(), UDA_TYPE_COMPLEX}, + {typeid(DCOMPLEX).name(), UDA_TYPE_DCOMPLEX}, {typeid(void).name(), UDA_TYPE_UNKNOWN}}; } return type_map; @@ -32,12 +39,18 @@ std::unordered_map json_plugin::uda_type_index_map() { static std::unordered_map type_map; if (type_map.empty()) { - type_map = {{std::type_index{ typeid(unsigned int) }, UDA_TYPE_UNSIGNED_INT}, - {std::type_index{ typeid(int) }, UDA_TYPE_INT}, - {std::type_index{ typeid(float) }, UDA_TYPE_FLOAT}, - {std::type_index{ typeid(double) }, UDA_TYPE_DOUBLE}, - {std::type_index{ typeid(char) }, UDA_TYPE_STRING}, - {std::type_index{ typeid(void) }, UDA_TYPE_UNKNOWN}}; + type_map = {{std::type_index{typeid(unsigned int)}, UDA_TYPE_UNSIGNED_INT}, + {std::type_index{typeid(unsigned short)}, UDA_TYPE_UNSIGNED_SHORT}, + {std::type_index{typeid(unsigned long)}, UDA_TYPE_UNSIGNED_LONG}, + {std::type_index{typeid(uint64_t)}, UDA_TYPE_UNSIGNED_LONG64}, + {std::type_index{typeid(int)}, UDA_TYPE_INT}, + {std::type_index{typeid(short)}, UDA_TYPE_SHORT}, + {std::type_index{typeid(float)}, UDA_TYPE_FLOAT}, + {std::type_index{typeid(double)}, UDA_TYPE_DOUBLE}, + {std::type_index{typeid(char)}, UDA_TYPE_STRING}, + {std::type_index{typeid(COMPLEX)}, UDA_TYPE_COMPLEX}, + {std::type_index{typeid(DCOMPLEX)}, UDA_TYPE_DCOMPLEX}, + {std::type_index{typeid(void)}, UDA_TYPE_UNKNOWN}}; } return type_map; } diff --git a/mapping_plugin/src/uda_plugin_helpers.hpp b/mapping_plugin/src/uda_plugin_helpers.hpp index 2119a61..7208617 100644 --- a/mapping_plugin/src/uda_plugin_helpers.hpp +++ b/mapping_plugin/src/uda_plugin_helpers.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -8,8 +9,6 @@ #include #include -#include "map_types/map_arguments.hpp" - namespace json_plugin { diff --git a/mapping_plugin/src/uda_ram_cache.cpp b/mapping_plugin/src/uda_ram_cache.cpp index 711f7e0..cc263f8 100644 --- a/mapping_plugin/src/uda_ram_cache.cpp +++ b/mapping_plugin/src/uda_ram_cache.cpp @@ -13,8 +13,8 @@ #include #include #include -#include #include +#include // LibTokaMap includes #include @@ -148,7 +148,8 @@ std::unique_ptr make_data_entry(DATA_BLOCK* data_blo } // namespace -void json_plugin::copy_to_cache(libtokamap::RamCache& ram_cache, const std::string& key, const DATA_BLOCK* data_block) { +void json_plugin::copy_to_cache(libtokamap::RamCache& ram_cache, const std::string& key, const DATA_BLOCK* data_block) +{ auto entry = std::make_unique(); size_t data_size = data_block->data_n * size_of_uda_type(data_block->data_type); diff --git a/mapping_plugin/src/uda_type_sizes.hpp b/mapping_plugin/src/uda_type_sizes.hpp index dcbb025..bcdc5ae 100644 --- a/mapping_plugin/src/uda_type_sizes.hpp +++ b/mapping_plugin/src/uda_type_sizes.hpp @@ -5,6 +5,7 @@ #include #include +#include #include namespace json_plugin @@ -12,6 +13,8 @@ namespace json_plugin inline size_t size_of_uda_type(int type_enum) { switch (type_enum) { + case UDA_TYPE_CHAR: + return sizeof(char); case UDA_TYPE_SHORT: return sizeof(short); case UDA_TYPE_INT: @@ -20,6 +23,8 @@ inline size_t size_of_uda_type(int type_enum) return sizeof(long); case UDA_TYPE_LONG64: return sizeof(int64_t); + case UDA_TYPE_UNSIGNED_CHAR: + return sizeof(unsigned char); case UDA_TYPE_UNSIGNED_SHORT: return sizeof(unsigned short); case UDA_TYPE_UNSIGNED_INT: @@ -32,6 +37,10 @@ inline size_t size_of_uda_type(int type_enum) return sizeof(float); case UDA_TYPE_DOUBLE: return sizeof(double); + case UDA_TYPE_COMPLEX: + return sizeof(COMPLEX); + case UDA_TYPE_DCOMPLEX: + return sizeof(DCOMPLEX); default: throw std::runtime_error(std::string("uda type ") + std::to_string(type_enum) + " not implemented for json_imas_mapping cache"); diff --git a/mapping_plugin/test/CMakeLists.txt b/mapping_plugin/test/CMakeLists.txt index 3bd6647..5512032 100644 --- a/mapping_plugin/test/CMakeLists.txt +++ b/mapping_plugin/test/CMakeLists.txt @@ -6,10 +6,6 @@ # LANGUAGES CXX # ) -set( CMAKE_CXX_STANDARD 17 ) -set( CMAKE_CXX_STANDARD_REQUIRED ON ) -set( CMAKE_CXX_EXTENSIONS OFF ) - find_package( Boost REQUIRED ) set( TEST_SOURCES diff --git a/mapping_plugin/test/src/uda_data_source_test.cpp b/mapping_plugin/test/src/uda_data_source_test.cpp index 7466802..e53f4a1 100644 --- a/mapping_plugin/test/src/uda_data_source_test.cpp +++ b/mapping_plugin/test/src/uda_data_source_test.cpp @@ -20,6 +20,7 @@ // LibTokaMap includes #include #include +#include #include // UDA includes @@ -42,7 +43,7 @@ make_map_arguments(const std::type_index data_type, const int rank) static std::unordered_map> empty_entries; static nlohmann::json empty_global_data = nlohmann::json::object(); - return MapArguments(empty_entries, empty_global_data, data_type, rank); + return MapArguments(empty_entries, empty_global_data, data_type, rank, false, false, nullptr); } int plugin_return_scalar(IDAM_PLUGIN_INTERFACE* interface) @@ -91,7 +92,9 @@ TEST_CASE("PluginMapping calls UDA data source", "[plugin_mapping][uda_data_sour std::strcpy(plugin.format, "UDA"); auto test_source = std::make_unique("UDA", "get", &plugin_list, false); - DataSourceMapping::register_data_source("UDA", std::move(test_source)); + auto* data_source_ptr = test_source.get(); + MappingHandler mapping_handler; + mapping_handler.register_data_source("UDA", std::move(test_source)); SECTION("Integer values are correctly returned") { @@ -101,7 +104,7 @@ TEST_CASE("PluginMapping calls UDA data source", "[plugin_mapping][uda_data_sour std::optional slice = {}; std::shared_ptr ram_cache = nullptr; - auto mapping = std::make_unique("UDA", request_args, offset, scale, slice, ram_cache); + auto mapping = std::make_unique("UDA", data_source_ptr, request_args, offset, scale, slice); REQUIRE(mapping != nullptr); MapArguments map_args = make_map_arguments(std::type_index{typeid(int)}, 1); @@ -126,7 +129,9 @@ TEST_CASE("Slicing and offsetting returned data", "[plugin_mapping][uda_data_sou std::strcpy(plugin.format, "UDA"); auto test_source = std::make_unique("UDA", "get", &plugin_list, false); - DataSourceMapping::register_data_source("UDA", std::move(test_source)); + auto* data_source_ptr = test_source.get(); + MappingHandler mapping_handler; + mapping_handler.register_data_source("UDA", std::move(test_source)); SECTION("Float values are correctly returned") { @@ -136,7 +141,7 @@ TEST_CASE("Slicing and offsetting returned data", "[plugin_mapping][uda_data_sou std::optional slice = {}; std::shared_ptr ram_cache = nullptr; - auto mapping = std::make_unique("UDA", request_args, offset, scale, slice, ram_cache); + auto mapping = std::make_unique("UDA", data_source_ptr, request_args, offset, scale, slice); REQUIRE(mapping != nullptr); MapArguments map_args = make_map_arguments(std::type_index{typeid(int)}, 1); @@ -161,7 +166,7 @@ TEST_CASE("Slicing and offsetting returned data", "[plugin_mapping][uda_data_sou std::string slice = "[0:" + std::to_string(range_len) + "]"; std::shared_ptr ram_cache = nullptr; - auto mapping = std::make_unique("UDA", request_args, offset, scale, slice, ram_cache); + auto mapping = std::make_unique("UDA", data_source_ptr, request_args, offset, scale, slice); REQUIRE(mapping != nullptr); MapArguments map_args = make_map_arguments(std::type_index{typeid(int)}, 1);