diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 92460cc99a7b6735818951d335b65ed7a3ee2cef..81604dcee5f3c5987bee3b6c3eb84f1f2e94cb29 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -49,3 +49,8 @@ add_library(common::network::rpc_server ALIAS _rpc_server) target_include_directories(_rpc_types INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::network::rpc_types ALIAS _rpc_types) + +add_subdirectory(api) +target_include_directories(_api_types INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}) +add_library(common::api::types ALIAS _api_types) diff --git a/src/common/api/CMakeLists.txt b/src/common/api/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d81fa158c7e803ce5e83c0f8042bea9f393f62ab --- /dev/null +++ b/src/common/api/CMakeLists.txt @@ -0,0 +1,40 @@ +################################################################################ +# Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain # +# # +# This software was partially supported by the EuroHPC-funded project ADMIRE # +# (Project ID: 956748, https://www.admire-eurohpc.eu). # +# # +# This file is part of scord. # +# # +# scord is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# scord is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with scord. If not, see . # +# # +# SPDX-License-Identifier: GPL-3.0-or-later # +################################################################################ + +add_library(_api_types STATIC) + +target_sources(_api_types PUBLIC admire_types.h admire_types.hpp PRIVATE + types.cpp convert.hpp convert.cpp) + +target_include_directories(_api_types PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(_api_types PRIVATE + Margo::Margo common::logger PUBLIC fmt::fmt) + +set_property(TARGET _api_types PROPERTY POSITION_INDEPENDENT_CODE ON) + +install( + FILES admire_types.h admire_types.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/src/lib/admire_types.h b/src/common/api/admire_types.h similarity index 100% rename from src/lib/admire_types.h rename to src/common/api/admire_types.h diff --git a/src/lib/admire_types.hpp b/src/common/api/admire_types.hpp similarity index 76% rename from src/lib/admire_types.hpp rename to src/common/api/admire_types.hpp index 16b9525e8a3767af61943cf4a33906334434d01c..232433dc8536d424f839e9f1767f2aa61623aa37 100644 --- a/src/lib/admire_types.hpp +++ b/src/common/api/admire_types.hpp @@ -252,177 +252,9 @@ private: std::unique_ptr m_pimpl; }; -template -struct managed_rpc_type; - -template -struct unmanaged_rpc_type; - } // namespace admire -//////////////////////////////////////////////////////////////////////////////// -// Specializations for conversion types -//////////////////////////////////////////////////////////////////////////////// - -template <> -struct admire::managed_rpc_type { - - template - using managed_ptr = scord::utils::ctype_ptr; - - explicit managed_rpc_type(const admire::adhoc_storage::ctx& ctx) - : m_adhoc_context(ADM_adhoc_context_create( - static_cast(ctx.exec_mode()), - static_cast(ctx.access_type()), - ctx.nodes(), ctx.walltime(), ctx.should_flush())) {} - - ADM_adhoc_context_t - get() const { - return m_adhoc_context.get(); - } - - managed_ptr m_adhoc_context; -}; - - -template <> -struct admire::managed_rpc_type { - - template - using rpc_storage_ptr = scord::utils::ctype_ptr; - - template - using managed_ptr = scord::utils::ctype_ptr; - - explicit managed_rpc_type(const admire::adhoc_storage& st) - : m_adhoc_context(*std::static_pointer_cast( - st.context())), - m_storage(ADM_storage_create( - st.id().c_str(), static_cast(st.type()), - m_adhoc_context.get())) {} - - ADM_storage_t - get() const { - return m_storage.get(); - } - - managed_rpc_type m_adhoc_context; - rpc_storage_ptr m_storage; -}; - -template <> -struct admire::managed_rpc_type> { - - template - using managed_ptr_vector = scord::utils::ctype_ptr_vector; - - explicit managed_rpc_type(const std::vector& datasets) { - m_datasets.reserve(datasets.size()); - - for(const auto& d : datasets) { - m_datasets.emplace_back(ADM_dataset_create(d.id().c_str())); - } - } - - const ADM_dataset_t* - data() const { - return m_datasets.data(); - } - - ADM_dataset_t* - data() { - return m_datasets.data(); - } - - std::size_t - size() const { - return m_datasets.size(); - } - - managed_ptr_vector m_datasets; -}; - -template <> -struct admire::managed_rpc_type { - - template - using rpc_requirements_ptr = scord::utils::ctype_ptr; - - explicit managed_rpc_type(const admire::job_requirements& reqs) - : m_inputs(reqs.inputs()), m_outputs(reqs.outputs()), - m_storage(*std::dynamic_pointer_cast( - reqs.storage())), - m_reqs(ADM_job_requirements_create(m_inputs.data(), m_inputs.size(), - m_outputs.data(), m_outputs.size(), - m_storage.get())) {} - - ADM_job_requirements_t - get() const { - return m_reqs.get(); - } - - managed_rpc_type> m_inputs; - managed_rpc_type> m_outputs; - managed_rpc_type m_storage; - rpc_requirements_ptr - m_reqs; -}; - -// forward declarations -ADM_job_t -ADM_job_create(uint64_t id); -ADM_return_t -ADM_job_destroy(ADM_job_t job); - -template <> -struct admire::managed_rpc_type { - - template - using rpc_job_ptr = scord::utils::ctype_ptr; - - explicit managed_rpc_type(const admire::job& j) - : m_job(ADM_job_create(j.id())) {} - - ADM_job_t - get() const { - return m_job.get(); - } - - rpc_job_ptr m_job; -}; - -template <> -struct admire::managed_rpc_type { - - template - using rpc_job_ptr = scord::utils::ctype_ptr; - - explicit managed_rpc_type(ADM_job_t job) : m_job(job) {} - - admire::job - get() const { - return admire::job(m_job.get()); - } - - rpc_job_ptr m_job; -}; - -template <> -struct admire::unmanaged_rpc_type { - - explicit unmanaged_rpc_type(const admire::job& j) - : m_job(ADM_job_create(j.id())) {} - - ADM_job_t - get() const { - return m_job; - } - - ADM_job_t m_job; -}; - - //////////////////////////////////////////////////////////////////////////////// // Formatting functions //////////////////////////////////////////////////////////////////////////////// diff --git a/src/common/api/convert.cpp b/src/common/api/convert.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6d05b3b6a0ef89d6fedcb40e123a5bceb725a4c --- /dev/null +++ b/src/common/api/convert.cpp @@ -0,0 +1,100 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#include +#include "convert.hpp" + +// forward declarations +ADM_job_t +ADM_job_create(uint64_t id); + +namespace admire::api { + +managed_ctype +convert(const adhoc_storage::ctx& ctx) { + return managed_ctype{ADM_adhoc_context_create( + static_cast(ctx.exec_mode()), + static_cast(ctx.access_type()), ctx.nodes(), + ctx.walltime(), ctx.should_flush())}; +} + +managed_ctype +convert(const admire::adhoc_storage& st) { + + auto managed_ctx = + convert(*std::static_pointer_cast( + st.context())); + + ADM_storage_t c_st = ADM_storage_create( + st.id().c_str(), static_cast(st.type()), + managed_ctx.get()); + + return managed_ctype{c_st, std::move(managed_ctx)}; +} + +managed_ctype_array +convert(const std::vector& datasets) { + + std::vector tmp; + + std::transform(datasets.cbegin(), datasets.cend(), std::back_inserter(tmp), + [](const admire::dataset& d) { + return ADM_dataset_create(d.id().c_str()); + }); + + return managed_ctype_array{std::move(tmp)}; +} + +managed_ctype +convert(const admire::job_requirements& reqs) { + + const auto& adhoc_storage = + *std::dynamic_pointer_cast(reqs.storage()); + + auto managed_storage = convert(adhoc_storage); + auto managed_inputs = convert(reqs.inputs()); + auto managed_outputs = convert(reqs.outputs()); + + ADM_job_requirements_t c_reqs = ADM_job_requirements_create( + managed_inputs.data(), managed_inputs.size(), + managed_outputs.data(), managed_outputs.size(), + managed_storage.get()); + + return managed_ctype{ + c_reqs, std::move(managed_inputs), std::move(managed_outputs), + std::move(managed_storage)}; +} + + +managed_ctype +convert(const job& j) { + return managed_ctype(ADM_job_create(j.id())); +} + +job +convert(ADM_job_t j) { + return admire::job{j}; +} + +} // namespace admire::api diff --git a/src/common/api/convert.hpp b/src/common/api/convert.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8ac73ca100dc07c734f73de661f82b84e158cf84 --- /dev/null +++ b/src/common/api/convert.hpp @@ -0,0 +1,193 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#ifndef SCORD_CONVERT_HPP +#define SCORD_CONVERT_HPP + +#include "admire_types.h" +#include "admire_types.hpp" + +namespace admire::api { + +// convenience types for managing the types from the C API in a RAII fashion +template +struct managed_ctype; + +template +struct managed_ctype_array; + +// conversion functions between C API and CXX API types + +managed_ctype +convert(const adhoc_storage::ctx& ctx); + +managed_ctype +convert(const admire::adhoc_storage& st); + +managed_ctype_array +convert(const std::vector& datasets); + +managed_ctype +convert(const admire::job_requirements& reqs); + +managed_ctype +convert(const job& j); + +job +convert(ADM_job_t j); + + +} // namespace admire::api + + +//////////////////////////////////////////////////////////////////////////////// +// Specializations for conversion types +//////////////////////////////////////////////////////////////////////////////// + +template <> +struct admire::api::managed_ctype { + + explicit managed_ctype(ADM_adhoc_context_t ctx) : m_adhoc_context(ctx) {} + + ADM_adhoc_context_t + get() const { + return m_adhoc_context.get(); + } + + ADM_adhoc_context_t + release() { + return m_adhoc_context.release(); + } + + scord::utils::ctype_ptr + m_adhoc_context; +}; + +template <> +struct admire::api::managed_ctype { + + explicit managed_ctype(ADM_storage_t st, + managed_ctype&& ctx) + : m_storage(st), m_ctx(std::move(ctx)) {} + + ADM_storage_t + get() const { + return m_storage.get(); + } + + ADM_storage_t + release() { + return m_storage.release(); + } + + scord::utils::ctype_ptr m_storage; + managed_ctype m_ctx; +}; + +template <> +struct admire::api::managed_ctype_array { + + explicit managed_ctype_array(ADM_dataset_t* data, size_t size) + : m_datasets(data, size) {} + + explicit managed_ctype_array(std::vector&& v) + : m_datasets(v.data(), v.size()) {} + + constexpr size_t + size() const { + return m_datasets.size(); + } + + constexpr const ADM_dataset_t* + data() const noexcept { + return m_datasets.data(); + } + + constexpr ADM_dataset_t* + data() noexcept { + return m_datasets.data(); + } + + constexpr ADM_dataset_t* + release() noexcept { + return m_datasets.release(); + } + + scord::utils::ctype_ptr_vector + m_datasets; +}; + +template <> +struct admire::api::managed_ctype { + + explicit managed_ctype(ADM_job_requirements_t reqs, + managed_ctype_array&& inputs, + managed_ctype_array&& outputs, + managed_ctype&& storage) + : m_reqs(reqs), m_inputs(std::move(inputs)), + m_outputs(std::move(outputs)), m_storage(std::move(storage)) {} + + ADM_job_requirements_t + get() const { + return m_reqs.get(); + } + + ADM_job_requirements_t + release() { + return m_reqs.release(); + } + + + scord::utils::ctype_ptr + m_reqs; + managed_ctype_array m_inputs; + managed_ctype_array m_outputs; + managed_ctype m_storage; +}; + + +// forward declarations +ADM_return_t +ADM_job_destroy(ADM_job_t job); + +template <> +struct admire::api::managed_ctype { + + explicit managed_ctype(ADM_job_t job) : m_job(job) {} + + ADM_job_t + get() const { + return m_job.get(); + } + + ADM_job_t + release() { + return m_job.release(); + } + + scord::utils::ctype_ptr m_job; +}; + +#endif // SCORD_CONVERT_HPP diff --git a/src/lib/types.cpp b/src/common/api/types.cpp similarity index 99% rename from src/lib/types.cpp rename to src/common/api/types.cpp index 9be36b09e1f53ee7ea0c62663578206f20af0803..17ea8d468a12cc4a909276949c3178db7c2e0203 100644 --- a/src/lib/types.cpp +++ b/src/common/api/types.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "admire_types.hpp" /******************************************************************************/ diff --git a/src/common/net/proto/CMakeLists.txt b/src/common/net/proto/CMakeLists.txt index f7697d3ed03b0c64490266843970a5d3b52691dc..10702cb0e6b872b04e3175b6841f2a63886700b4 100644 --- a/src/common/net/proto/CMakeLists.txt +++ b/src/common/net/proto/CMakeLists.txt @@ -30,7 +30,7 @@ target_include_directories(_rpc_types PUBLIC ${CMAKE_SOURCE_DIR}/src/lib) target_sources( _rpc_types PRIVATE rpc_types.h rpc_types.c ${CMAKE_SOURCE_DIR}/src/lib/admire.h - ${CMAKE_SOURCE_DIR}/src/lib/admire_types.h ) -target_link_libraries(_rpc_types PRIVATE Mercury::Mercury Margo::Margo) +target_link_libraries(_rpc_types PRIVATE common::api::types Mercury::Mercury + Margo::Margo) diff --git a/src/common/net/proto/rpc_types.h b/src/common/net/proto/rpc_types.h index 2e1139f01591aeb2db9c48aa7f58be370e5d6296..5dc1c1595df16547a29f4e00bacdc9dba1f15e23 100644 --- a/src/common/net/proto/rpc_types.h +++ b/src/common/net/proto/rpc_types.h @@ -28,7 +28,7 @@ #include // NOLINT #include #include -#include +#include #ifdef __cplusplus extern "C" { diff --git a/src/common/utils/ctype_ptr.hpp b/src/common/utils/ctype_ptr.hpp index 830e6da80767840de569ed09a9e88be1cc5c4190..a0752d77edc2aa170f2d3f59ef313703659eb357 100644 --- a/src/common/utils/ctype_ptr.hpp +++ b/src/common/utils/ctype_ptr.hpp @@ -57,6 +57,20 @@ struct ctype_ptr_vector { ctype_ptr_vector() = default; + ctype_ptr_vector(T* const data, size_t size) { + reserve(size); + + for(size_t i = 0; i < size; ++i) { + emplace_back(data[i]); + } + } + + ctype_ptr_vector(ctype_ptr_vector&& rhs) noexcept + : m_data(std::move(rhs.m_data)), m_addrs(std::move(rhs.m_addrs)) {} + + ctype_ptr_vector& + operator=(ctype_ptr_vector&&) noexcept = default; + ~ctype_ptr_vector() = default; constexpr void @@ -87,6 +101,20 @@ struct ctype_ptr_vector { return m_data.size(); } + constexpr T* + release() noexcept { + + auto* data = (T*) calloc(m_data.size(), sizeof(T)); + + for(size_t i = 0; i < m_data.size(); ++i) { + data[i] = m_data[i].release(); + m_addrs[i] = nullptr; + } + + return data; + } + + std::vector> m_data{}; std::vector m_addrs{}; }; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index a80305100d8405ca280d3be2d913f42254f059bb..bc1f58d3e8224712bbff4ac7774397702f5a21c4 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -22,32 +22,23 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -add_library(admire_types STATIC) - -target_sources(admire_types PUBLIC admire_types.h admire_types.hpp PRIVATE - types.cpp) - -target_link_libraries(admire_types PRIVATE common::network::rpc_types - Margo::Margo common::logger) - -set_target_properties(admire_types PROPERTIES POSITION_INDEPENDENT_CODE ON) - -# the client library implementing the actual API add_library(adm_iosched SHARED) target_sources(adm_iosched - PUBLIC admire.h admire_types.h admire.hpp admire_types.hpp - PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c types.cpp) + PUBLIC admire.h admire.hpp + PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c) + +set_target_properties(adm_iosched PROPERTIES PUBLIC_HEADER "admire.h;admire.hpp") target_include_directories(adm_iosched PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(adm_iosched PRIVATE common::network::engine - common::network::rpc_types admire_types PUBLIC - tl::expected) + common::network::rpc_types PUBLIC + tl::expected common::api::types) install( TARGETS adm_iosched LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/adm_iosched + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index d0cdacf36766ef310929cdb7378695a94f812b42..f150358b3665f2918f47675b4810a14c25427694 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -27,8 +27,9 @@ #include #include #include -#include "admire_types.hpp" -#include "admire_types.h" +#include +#include +#include #include "detail/impl.hpp" @@ -54,7 +55,7 @@ ADM_register_job(ADM_server_t server, ADM_job_requirements_t reqs, return rv.error(); } - *job = admire::unmanaged_rpc_type{*rv}.get(); + *job = admire::api::convert(*rv).release(); return ADM_SUCCESS; } diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 85dbd05691f1136820fd88b901619e87147f3e6f..e8092a471e3bac46423346c4f301f22f1a83bb98 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "impl.hpp" @@ -179,7 +180,7 @@ register_job(const admire::server& srv, const admire::job_requirements& reqs) { LOGGER_INFO("RPC (ADM_{}) => {{job_requirements: {{{}}}}}", __FUNCTION__, reqs); - auto rpc_reqs = managed_rpc_type{reqs}; + auto rpc_reqs = api::convert(reqs); ADM_register_job_in_t in{*rpc_reqs.get()}; ADM_register_job_out_t out; @@ -191,8 +192,7 @@ register_job(const admire::server& srv, const admire::job_requirements& reqs) { return tl::make_unexpected(static_cast(out.retval)); } - const auto rpc_job = managed_rpc_type{out.job}; - const admire::job job = rpc_job.get(); + const admire::job job = api::convert(out.job); LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}, job: {{{}}}}}", __FUNCTION__, ADM_SUCCESS, job.id()); @@ -210,8 +210,8 @@ update_job(const server& srv, const job& job, const job_requirements& reqs) { LOGGER_INFO("RPC ({}): {{job: {{{}}}, job_requirements: {{{}}}}}", "ADM_update_job", job, reqs); - const auto rpc_job = managed_rpc_type{job}; - const auto rpc_reqs = managed_rpc_type{reqs}; + const auto rpc_job = api::convert(job); + const auto rpc_reqs = api::convert(reqs); ADM_update_job_in_t in{rpc_job.get(), *rpc_reqs.get()}; ADM_update_job_out_t out; @@ -238,7 +238,7 @@ remove_job(const server& srv, const job& job) { LOGGER_INFO("RPC (ADM_{}) => {{job: {}}}", __FUNCTION__, job); - const auto rpc_job = managed_rpc_type{job}; + const auto rpc_job = api::convert(job); ADM_remove_job_in_t in{rpc_job.get()}; ADM_remove_job_out_t out; diff --git a/src/scord-ctl/CMakeLists.txt b/src/scord-ctl/CMakeLists.txt index 6d7c474b0f085fce8c0342f56dbd6ddd2e07c387..66315a8e1a7ef9a8f1eafb7398bddc53b580ca41 100644 --- a/src/scord-ctl/CMakeLists.txt +++ b/src/scord-ctl/CMakeLists.txt @@ -35,7 +35,7 @@ target_include_directories( target_link_libraries( scord-ctl PRIVATE common::config common::logger common::network::rpc_server - common::network::rpc_types admire_types fmt::fmt Boost::program_options + common::network::rpc_types common::api::types fmt::fmt Boost::program_options ) install(TARGETS scord DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/scord/CMakeLists.txt b/src/scord/CMakeLists.txt index e842d425012bba75ea627c3929a6f8bd67de74ec..1cd70863cc863425699de80e9a2e03061065584a 100644 --- a/src/scord/CMakeLists.txt +++ b/src/scord/CMakeLists.txt @@ -39,7 +39,7 @@ target_link_libraries( common::logger common::network::rpc_server common::network::rpc_types - admire_types + common::api::types fmt::fmt Boost::program_options RedisPlusPlus::RedisPlusPlus diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index 68677cc805cdaf7478ab19bccb27458b4987ff53..af3f157e1193cbe906de1cfdb888124fa7e1e24c 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "rpc_handlers.hpp" struct remote_procedure { @@ -71,11 +72,10 @@ ADM_register_job(hg_handle_t h) { const auto job = admire::job{42}; - const auto rpc_job = admire::unmanaged_rpc_type{job}; admire::error_code rv = ADM_SUCCESS; out.retval = rv; - out.job = rpc_job.get(); + out.job = admire::api::convert(job).get(); LOGGER_INFO("RPC ID {} ({}) => {{retval: {}, job: {{{}}}}}", id, __FUNCTION__, rv, job);