From 6d4ddba08c200370db936f4c40b41fba6df199ae Mon Sep 17 00:00:00 2001 From: Nikita Kulikov Date: Thu, 5 Oct 2023 02:06:29 -0700 Subject: [PATCH] One commit to rule them all --- .../dal/backend/interop/data_conversion.hpp | 50 +-- .../dal/backend/interop/table_conversion.hpp | 291 +--------------- cpp/oneapi/dal/detail/error_messages.cpp | 1 + cpp/oneapi/dal/detail/error_messages.hpp | 1 + .../table/backend/interop/buffer_adapter.cpp | 107 ++++++ .../table/backend/interop/buffer_adapter.hpp | 39 +++ .../dal/table/backend/interop/common.cpp | 110 ++++++ .../dal/table/backend/interop/common.hpp | 50 ++- .../host_heterogen_to_soa_table_adapter.cpp | 232 +++++++++++++ .../host_heterogen_to_soa_table_adapter.hpp | 138 ++++++++ .../host_homogen_to_soa_table_adapter.cpp | 244 ++++++++++++++ .../host_homogen_to_soa_table_adapter.hpp | 120 +++++++ .../interop/host_soa_table_adapter.cpp | 244 ++------------ .../interop/host_soa_table_adapter.hpp | 105 +----- .../host_soa_to_heterogen_table_adapter.cpp | 79 +++++ .../host_soa_to_heterogen_table_adapter.hpp | 32 ++ .../backend/interop/table_conversion.cpp | 318 ++++++++++++++++++ .../backend/interop/table_conversion.hpp | 112 ++++++ .../interop/table_conversion_common.hpp | 36 ++ .../backend/interop/table_conversion_dpc.cpp | 0 .../backend/interop/table_conversion_dpc.hpp | 71 ++++ .../dal/table/detail/metadata_utils.hpp | 18 + cpp/oneapi/dal/table/heterogen.hpp | 2 +- cpp/oneapi/dal/table/test/heterogen.cpp | 2 + cpp/oneapi/dal/table/test/table_adapter.cpp | 25 ++ 25 files changed, 1789 insertions(+), 638 deletions(-) create mode 100644 cpp/oneapi/dal/table/backend/interop/buffer_adapter.cpp create mode 100644 cpp/oneapi/dal/table/backend/interop/buffer_adapter.hpp create mode 100644 cpp/oneapi/dal/table/backend/interop/common.cpp mode change 100755 => 100644 cpp/oneapi/dal/table/backend/interop/common.hpp create mode 100644 cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.cpp create mode 100644 cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp create mode 100755 cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.cpp create mode 100755 cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.hpp mode change 100755 => 100644 cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.cpp mode change 100755 => 100644 cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp create mode 100644 cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.cpp create mode 100644 cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.hpp create mode 100644 cpp/oneapi/dal/table/backend/interop/table_conversion.cpp create mode 100644 cpp/oneapi/dal/table/backend/interop/table_conversion.hpp create mode 100644 cpp/oneapi/dal/table/backend/interop/table_conversion_common.hpp create mode 100644 cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.cpp create mode 100644 cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.hpp diff --git a/cpp/oneapi/dal/backend/interop/data_conversion.hpp b/cpp/oneapi/dal/backend/interop/data_conversion.hpp index 99ac74aa9cd..25bf09eb530 100644 --- a/cpp/oneapi/dal/backend/interop/data_conversion.hpp +++ b/cpp/oneapi/dal/backend/interop/data_conversion.hpp @@ -24,7 +24,7 @@ namespace oneapi::dal::backend::interop { // TODO: Remove using namespace using namespace daal::data_management; -features::IndexNumType getIndexNumType(data_type t) { +inline features::IndexNumType getIndexNumType(data_type t) { switch (t) { case data_type::int32: return features::DAAL_INT32_S; case data_type::int64: return features::DAAL_INT64_S; @@ -36,7 +36,19 @@ features::IndexNumType getIndexNumType(data_type t) { } } -internal::ConversionDataType getConversionDataType(data_type t) { +inline data_type get_dal_data_type(features::IndexNumType t) { + switch (t) { + case features::DAAL_INT32_S: return data_type::int32; + case features::DAAL_INT64_S: return data_type::int64; + case features::DAAL_INT32_U: return data_type::uint32; + case features::DAAL_INT64_U: return data_type::uint64; + case features::DAAL_FLOAT32: return data_type::float32; + case features::DAAL_FLOAT64: return data_type::float64; + default: return data_type::float32; + } +} + +inline internal::ConversionDataType getConversionDataType(data_type t) { switch (t) { case data_type::int32: return internal::DAAL_INT32; case data_type::float32: return internal::DAAL_SINGLE; @@ -46,11 +58,11 @@ internal::ConversionDataType getConversionDataType(data_type t) { } template -void daal_convert_dispatcher(data_type src_type, - data_type dst_type, - DownCast&& dcast, - UpCast&& ucast, - Args&&... args) { +inline void daal_convert_dispatcher(data_type src_type, + data_type dst_type, + DownCast&& dcast, + UpCast&& ucast, + Args&&... args) { auto from_type = getIndexNumType(src_type); auto to_type = getConversionDataType(dst_type); @@ -74,11 +86,11 @@ void daal_convert_dispatcher(data_type src_type, } } -void daal_convert(const void* src, - void* dst, - data_type src_type, - data_type dst_type, - std::int64_t element_count) { +inline void daal_convert(const void* src, + void* dst, + data_type src_type, + data_type dst_type, + std::int64_t element_count) { daal_convert_dispatcher(src_type, dst_type, internal::getVectorDownCast, @@ -88,13 +100,13 @@ void daal_convert(const void* src, dst); } -void daal_convert(const void* src, - void* dst, - data_type src_type, - data_type dst_type, - std::int64_t src_stride, - std::int64_t dst_stride, - std::int64_t element_count) { +inline void daal_convert(const void* src, + void* dst, + data_type src_type, + data_type dst_type, + std::int64_t src_stride, + std::int64_t dst_stride, + std::int64_t element_count) { daal_convert_dispatcher(src_type, dst_type, internal::getVectorStrideDownCast, diff --git a/cpp/oneapi/dal/backend/interop/table_conversion.hpp b/cpp/oneapi/dal/backend/interop/table_conversion.hpp index b1fca83cd3c..0303ede56b0 100644 --- a/cpp/oneapi/dal/backend/interop/table_conversion.hpp +++ b/cpp/oneapi/dal/backend/interop/table_conversion.hpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2020 Intel Corporation +* Copyright 2021 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,291 +14,4 @@ * limitations under the License. *******************************************************************************/ -#pragma once - -#ifdef ONEDAL_DATA_PARALLEL -#include -#endif - -#include "oneapi/dal/backend/memory.hpp" -#include "oneapi/dal/table/detail/table_builder.hpp" -#include "oneapi/dal/table/backend/interop/sycl_table_adapter.hpp" -#include "oneapi/dal/table/backend/interop/host_homogen_table_adapter.hpp" -#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" -#include "oneapi/dal/table/backend/interop/host_csr_table_adapter.hpp" -#include "oneapi/dal/backend/interop/csr_block_owner.hpp" - -namespace oneapi::dal::backend::interop { - -template -inline auto allocate_daal_homogen_table(std::int64_t row_count, std::int64_t column_count) { - return daal::data_management::HomogenNumericTable::create( - dal::detail::integral_cast(column_count), - dal::detail::integral_cast(row_count), - daal::data_management::NumericTable::doAllocate); -} - -template -inline auto empty_daal_homogen_table(std::int64_t column_count) { - return daal::data_management::HomogenNumericTable::create( - dal::detail::integral_cast(column_count), - dal::detail::integral_cast(0), - daal::data_management::NumericTable::notAllocate); -} - -template -inline auto convert_to_daal_homogen_table(array& data, - std::int64_t row_count, - std::int64_t column_count, - bool allow_copy = false) { - if (!data.get_count()) { - return daal::services::SharedPtr>(); - } - - if (allow_copy) { - data.need_mutable_data(); - } - - ONEDAL_ASSERT(data.has_mutable_data()); - const auto daal_data = - daal::services::SharedPtr(data.get_mutable_data(), daal_object_owner{ data }); - - return daal::data_management::HomogenNumericTable::create( - daal_data, - dal::detail::integral_cast(column_count), - dal::detail::integral_cast(row_count)); -} - -template -inline daal::data_management::NumericTablePtr copy_to_daal_homogen_table(const table& table) { - // TODO: Preserve information about features - const bool allow_copy = true; - auto rows = row_accessor{ table }.pull(); - return convert_to_daal_homogen_table(rows, - table.get_row_count(), - table.get_column_count(), - allow_copy); -} - -template -inline table convert_from_daal_homogen_table(const daal::data_management::NumericTablePtr& nt) { - if (nt->getNumberOfRows() == 0) { - return table{}; - } - daal::data_management::BlockDescriptor block; - const std::int64_t row_count = dal::detail::integral_cast(nt->getNumberOfRows()); - const std::int64_t column_count = - dal::detail::integral_cast(nt->getNumberOfColumns()); - - nt->getBlockOfRows(0, row_count, daal::data_management::readOnly, block); - Data* data = block.getBlockPtr(); - array arr(data, row_count * column_count, [nt, block](Data* p) mutable { - nt->releaseBlockOfRows(block); - }); - return detail::homogen_table_builder{}.reset(arr, row_count, column_count).build(); -} - -inline daal::data_management::NumericTablePtr wrap_by_host_homogen_adapter( - const homogen_table& table) { - const auto& dtype = table.get_metadata().get_data_type(0); - - switch (dtype) { - case data_type::float32: return host_homogen_table_adapter::create(table); - case data_type::float64: return host_homogen_table_adapter::create(table); - case data_type::int32: return host_homogen_table_adapter::create(table); - default: return daal::data_management::NumericTablePtr(); - } -} - -inline daal::data_management::NumericTablePtr wrap_by_host_soa_adapter(const homogen_table& table) { - const auto& dtype = table.get_metadata().get_data_type(0); - - switch (dtype) { - case data_type::float32: return host_soa_table_adapter::create(table); - case data_type::float64: return host_soa_table_adapter::create(table); - case data_type::int32: return host_soa_table_adapter::create(table); - default: return daal::data_management::NumericTablePtr(); - } -} - -template -inline daal::data_management::NumericTablePtr convert_to_daal_table(const homogen_table& table) { - if (table.get_data_layout() == data_layout::row_major) { - if (auto wrapper = wrap_by_host_homogen_adapter(table)) { - return wrapper; - } - } - else if (table.get_data_layout() == data_layout::column_major) { - if (auto wrapper = wrap_by_host_soa_adapter(table)) { - return wrapper; - } - } - return copy_to_daal_homogen_table(table); -} - -template -inline auto convert_to_daal_csr_table(array& data, - array& column_indices, - array& row_indices, - std::int64_t row_count, - std::int64_t column_count, - bool allow_copy = false) { - ONEDAL_ASSERT(data.get_count() == column_indices.get_count()); - ONEDAL_ASSERT(row_indices.get_count() == row_count + 1); - - if (!data.get_count() || !column_indices.get_count() || !row_indices.get_count()) { - return daal::services::SharedPtr(); - } - - if (allow_copy) { - data.need_mutable_data(); - column_indices.need_mutable_data(); - row_indices.need_mutable_data(); - } - - ONEDAL_ASSERT(data.has_mutable_data()); - ONEDAL_ASSERT(column_indices.has_mutable_data()); - ONEDAL_ASSERT(row_indices.has_mutable_data()); - - const auto daal_data = - daal::services::SharedPtr(data.get_mutable_data(), daal_object_owner{ data }); - ONEDAL_ASSERT(sizeof(std::size_t) == sizeof(std::int64_t)); - const auto daal_column_indices = daal::services::SharedPtr( - reinterpret_cast(column_indices.get_mutable_data()), - daal_object_owner{ column_indices }); - const auto daal_row_indices = daal::services::SharedPtr( - reinterpret_cast(row_indices.get_mutable_data()), - daal_object_owner{ row_indices }); - - return daal::data_management::CSRNumericTable::create( - daal_data, - daal_column_indices, - daal_row_indices, - dal::detail::integral_cast(column_count), - dal::detail::integral_cast(row_count)); -} - -template -inline daal::data_management::CSRNumericTablePtr copy_to_daal_csr_table(const csr_table& table) { - const bool allow_copy = true; - auto [data, column_indices, row_offsets] = csr_accessor{ table }.pull(); - return convert_to_daal_csr_table(data, - column_indices, - row_offsets, - table.get_row_count(), - table.get_column_count(), - allow_copy); -} - -template -inline table convert_from_daal_csr_table(const daal::data_management::NumericTablePtr& nt) { - auto block_owner = std::make_shared>(csr_block_owner{ nt }); - - ONEDAL_ASSERT(sizeof(std::size_t) == sizeof(std::int64_t)); - - return csr_table{ - array{ block_owner->get_data(), - block_owner->get_element_count(), - [block_owner](const T* p) {} }, - array{ reinterpret_cast(block_owner->get_column_indices()), - block_owner->get_element_count(), - [block_owner](const std::int64_t* p) {} }, - array{ reinterpret_cast(block_owner->get_row_indices()), - block_owner->get_row_count() + 1, - [block_owner](const std::int64_t* p) {} }, - block_owner->get_column_count() - }; -} - -inline daal::data_management::CSRNumericTablePtr wrap_by_host_csr_adapter(const csr_table& table) { - const auto& dtype = table.get_metadata().get_data_type(0); - - switch (dtype) { - case data_type::float32: return host_csr_table_adapter::create(table); - case data_type::float64: return host_csr_table_adapter::create(table); - case data_type::int32: return host_csr_table_adapter::create(table); - default: return daal::data_management::CSRNumericTablePtr(); - } -} - -template -inline daal::data_management::CSRNumericTablePtr convert_to_daal_table(const csr_table& table) { - auto wrapper = wrap_by_host_csr_adapter(table); - if (!wrapper) { - return copy_to_daal_csr_table(table); - } - else { - return wrapper; - } -} - -template -inline daal::data_management::NumericTablePtr convert_to_daal_table(const table& table) { - if (table.get_kind() == homogen_table::kind()) { - const auto& homogen = static_cast(table); - return convert_to_daal_table(homogen); - } - else if (table.get_kind() == csr_table::kind()) { - const auto& csr = static_cast(table); - return convert_to_daal_table(csr); - } - else { - return copy_to_daal_homogen_table(table); - } -} - -template -inline table convert_from_daal_table(const daal::data_management::NumericTablePtr& nt) { - if (nt->getDataLayout() == daal::data_management::NumericTableIface::StorageLayout::csrArray) { - return convert_from_daal_csr_table(nt); - } - else { - return convert_from_daal_homogen_table(nt); - } -} - -#ifdef ONEDAL_DATA_PARALLEL -inline daal::data_management::NumericTablePtr convert_to_daal_table(const sycl::queue& queue, - const table& table) { - if (!table.has_data()) { - return daal::data_management::NumericTablePtr{}; - } - return interop::sycl_table_adapter::create(queue, table); -} - -template -inline daal::data_management::NumericTablePtr convert_to_daal_table(const sycl::queue& queue, - const array& data, - std::int64_t row_count, - std::int64_t column_count) { - using daal::services::Status; - using daal::services::SharedPtr; - using daal::services::internal::Buffer; - using daal::data_management::internal::SyclHomogenNumericTable; - using dal::detail::integral_cast; - - ONEDAL_ASSERT(data.get_count() == row_count * column_count); - ONEDAL_ASSERT(data.has_mutable_data()); - ONEDAL_ASSERT(is_same_context(queue, data)); - - const SharedPtr data_shared{ data.get_mutable_data(), daal_object_owner{ data } }; - - Status status; - const Buffer buffer{ data_shared, - integral_cast(data.get_count()), - queue, - status }; - status_to_exception(status); - - const auto table = - SyclHomogenNumericTable::create(buffer, - integral_cast(column_count), - integral_cast(row_count), - &status); - status_to_exception(status); - - return table; -} -#endif - -} // namespace oneapi::dal::backend::interop +#include "oneapi/dal/table/backend/interop/table_conversion.hpp" diff --git a/cpp/oneapi/dal/detail/error_messages.cpp b/cpp/oneapi/dal/detail/error_messages.cpp index 74cada68dbf..836212735c6 100644 --- a/cpp/oneapi/dal/detail/error_messages.cpp +++ b/cpp/oneapi/dal/detail/error_messages.cpp @@ -116,6 +116,7 @@ MSG(object_does_not_provide_read_access_to_csr, "Given object does not provide read access to the block of CSR format") MSG(pull_column_interface_is_not_implemented, "Pull column interface is planned but not implemented yet") +MSG(unsupported_table_conversion, "Unsupported table conversion") /* Ranges */ MSG(invalid_range_of_rows, "Invalid range of rows") diff --git a/cpp/oneapi/dal/detail/error_messages.hpp b/cpp/oneapi/dal/detail/error_messages.hpp index aa8bfb6377c..80406760c32 100644 --- a/cpp/oneapi/dal/detail/error_messages.hpp +++ b/cpp/oneapi/dal/detail/error_messages.hpp @@ -134,6 +134,7 @@ class ONEDAL_EXPORT error_messages { MSG(zero_based_indexing_is_not_supported); MSG(object_does_not_provide_read_access_to_csr); MSG(pull_column_interface_is_not_implemented); + MSG(unsupported_table_conversion); /* Ranges */ MSG(invalid_range_of_rows); diff --git a/cpp/oneapi/dal/table/backend/interop/buffer_adapter.cpp b/cpp/oneapi/dal/table/backend/interop/buffer_adapter.cpp new file mode 100644 index 00000000000..aced6800f7b --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/buffer_adapter.cpp @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "oneapi/dal/detail/common.hpp" + +#include "oneapi/dal/backend/interop/error_converter.hpp" + +#include "oneapi/dal/table/backend/interop/buffer_adapter.hpp" + +namespace oneapi::dal::backend::interop { + +template +struct array_deleter { + using data_t = DataType; + + array_deleter() = delete; + array_deleter(array_deleter&&) = default; + array_deleter(const array_deleter&) = default; + + array_deleter(std::shared_ptr inp) : ptr(std::move(inp)) {} + + void operator()(const void* del_ptr) { + return ptr.reset(); + } + + std::shared_ptr ptr; +}; + +template +auto convert(std::shared_ptr inp) { + using daal::services::SharedPtr; + using data_t = std::remove_const_t; + + auto del = array_deleter(inp); + DataType* const raw_ptr = inp.get(); + return SharedPtr(raw_ptr, del); +} + +template +auto to_daal_shared(const detail::array_impl& arr_impl) { + using daal::services::SharedPtr; + + SharedPtr curr_ptr; + if (arr_impl.has_mutable_data()) { + auto raw = arr_impl.get_shared(); + curr_ptr = convert(std::move(raw)); + } + else if (arr_impl.has_data()) { + auto raw = arr_impl.get_cshared(); + curr_ptr = convert(std::move(raw)); + } + else { + ONEDAL_ASSERT(!"An empty array"); + } + + return curr_ptr; +} + +template +auto convert_with_status(const dal::array& array) + -> std::pair, daal::services::Status> { + using dal::detail::integral_cast; + using daal::services::internal::Buffer; + + const auto count = array.get_count(); + auto& arr_impl = detail::get_impl(array); + ONEDAL_ASSERT(count == arr_impl.get_count()); + auto ccount = integral_cast(count); + + daal::services::Status st; + auto shared = to_daal_shared(arr_impl); + auto buf = Buffer(shared, ccount, st); + + return std::make_pair(buf, st); +} + +template +auto convert(const dal::array& array) -> buffer_t { + auto [buffer, status] = convert_with_status(array); + interop::status_to_exception(status); + return buffer; +} + +#define INSTANTIATE(TYPE) \ + template auto convert(const dal::array&)->buffer_t; \ + template auto convert_with_status(const dal::array&) \ + ->std::pair, daal::services::Status>; + +INSTANTIATE(int) +INSTANTIATE(long) +INSTANTIATE(float) +INSTANTIATE(double) + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/buffer_adapter.hpp b/cpp/oneapi/dal/table/backend/interop/buffer_adapter.hpp new file mode 100644 index 00000000000..9b47fd7896f --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/buffer_adapter.hpp @@ -0,0 +1,39 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include + +#include "oneapi/dal/array.hpp" +#include "oneapi/dal/common.hpp" + +#include +#include + +namespace oneapi::dal::backend::interop { + +template +using buffer_t = daal::services::internal::Buffer; + +template +ONEDAL_EXPORT buffer_t convert(const dal::array& array); + +template +ONEDAL_EXPORT auto convert_with_status(const dal::array& array) + -> std::pair, daal::services::Status>; + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/common.cpp b/cpp/oneapi/dal/table/backend/interop/common.cpp new file mode 100644 index 00000000000..617546e8647 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/common.cpp @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include + +#include "oneapi/dal/table/common.hpp" + +#include "oneapi/dal/backend/interop/common.hpp" +#include "oneapi/dal/backend/interop/error_converter.hpp" +#include "oneapi/dal/backend/interop/data_conversion.hpp" + +namespace oneapi::dal::backend::interop { + +namespace daal_dm = daal::data_management; + +daal_dm::features::FeatureType get_daal_feature_type(feature_type t) { + switch (t) { + case feature_type::nominal: return daal_dm::features::DAAL_CATEGORICAL; + case feature_type::ordinal: return daal_dm::features::DAAL_ORDINAL; + case feature_type::interval: return daal_dm::features::DAAL_CONTINUOUS; + case feature_type::ratio: return daal_dm::features::DAAL_CONTINUOUS; + default: throw dal::internal_error(detail::error_messages::unsupported_feature_type()); + } +} + +feature_type get_dal_feature_type(daal_dm::features::FeatureType t) { + switch (t) { + case daal_dm::features::DAAL_ORDINAL: return feature_type::ordinal; + case daal_dm::features::DAAL_CONTINUOUS: return feature_type::ratio; + case daal_dm::features::DAAL_CATEGORICAL: return feature_type::nominal; + default: throw dal::internal_error(detail::error_messages::unsupported_feature_type()); + } +} + +void convert_feature_information_to_daal(const table_metadata& src, + daal_dm::NumericTableDictionary& dst) { + const auto feature_count = src.get_feature_count(); + [[maybe_unused]] const std::size_t casted_count = // + dal::detail::integral_cast(feature_count); + ONEDAL_ASSERT(casted_count == dst.getNumberOfFeatures()); + + for (std::int64_t i = 0l; i < feature_count; ++i) { + const auto dtype = src.get_data_type(i); + const auto ftype = src.get_feature_type(i); + dst[i].indexType = getIndexNumType(dtype); + dst[i].featureType = get_daal_feature_type(ftype); + } + + interop::status_to_exception(dst.checkDictionary()); +} + +void convert_feature_information_from_daal(daal_dm::NumericTableDictionary& src, + table_metadata& dst) { + using detail::integral_cast; + const auto f_number = src.getNumberOfFeatures(); + const auto f_count = integral_cast(f_number); + + auto dtypes = dal::array::empty(f_count); + auto ftypes = dal::array::empty(f_count); + + data_type* const d_ptr = dtypes.get_mutable_data(); + feature_type* const f_ptr = ftypes.get_mutable_data(); + + for (std::int64_t i = 0l; i < f_count; ++i) { + const auto idx = integral_cast(i); + const daal_dm::NumericTableFeature& feature = src[idx]; + + d_ptr[idx] = get_dal_data_type(feature.indexType); + f_ptr[idx] = get_dal_feature_type(feature.featureType); + } + + dst = table_metadata{ dtypes, ftypes }; +} + +daal_dm::NumericTableDictionaryPtr convert(const table_metadata& src) { + using daal_dm::NumericTableDictionary; + using features_equal = daal_dm::DictionaryIface::FeaturesEqual; + + daal::services::Status status; + const auto not_equal = features_equal::notEqual; + const std::int64_t f_count = src.get_feature_count(); + const auto c_count = detail::integral_cast(f_count); + auto dict_ptr = NumericTableDictionary::create(c_count, not_equal, &status); + interop::status_to_exception(status); + + convert_feature_information_to_daal(src, *dict_ptr); + + return dict_ptr; +} + +table_metadata convert(const daal_dm::NumericTableDictionaryPtr& src) { + table_metadata result{}; + convert_feature_information_from_daal(*src, result); + return result; +} + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/common.hpp b/cpp/oneapi/dal/table/backend/interop/common.hpp old mode 100755 new mode 100644 index 85596ea5968..5e0a846a1ae --- a/cpp/oneapi/dal/table/backend/interop/common.hpp +++ b/cpp/oneapi/dal/table/backend/interop/common.hpp @@ -14,13 +14,32 @@ * limitations under the License. *******************************************************************************/ +#pragma once + #include -#include "oneapi/dal/table/homogen.hpp" +#include +#include +#include + +#include "oneapi/dal/table/common.hpp" namespace oneapi::dal::backend::interop { namespace daal_dm = daal::data_management; +template +using shared_t = daal::services::SharedPtr; + +using soa_table_t = daal_dm::SOANumericTable; +using csr_table_t = daal_dm::CSRNumericTable; +template +using homogen_table_t = daal_dm::CSRNumericTable; + +using soa_table_ptr_t = shared_t; +using csr_table_ptr_t = shared_t; +template +using homogen_table_ptr_t = shared_t>; + template static daal::services::Status convert_exception_to_status(Body&& body) { try { @@ -37,23 +56,18 @@ static daal::services::Status convert_exception_to_status(Body&& body) { } } -static daal_dm::features::FeatureType get_daal_feature_type(feature_type t) { - switch (t) { - case feature_type::nominal: return daal_dm::features::DAAL_CATEGORICAL; - case feature_type::ordinal: return daal_dm::features::DAAL_ORDINAL; - case feature_type::interval: return daal_dm::features::DAAL_CONTINUOUS; - case feature_type::ratio: return daal_dm::features::DAAL_CONTINUOUS; - default: throw dal::internal_error(detail::error_messages::unsupported_feature_type()); - } -} +ONEDAL_EXPORT daal_dm::features::FeatureType get_daal_feature_type(feature_type t); -static void convert_feature_information_to_daal(const table_metadata& src, - daal_dm::NumericTableDictionary& dst) { - ONEDAL_ASSERT(std::size_t(src.get_feature_count()) == dst.getNumberOfFeatures()); - for (std::int64_t i = 0; i < src.get_feature_count(); i++) { - auto& daal_feature = dst[i]; - daal_feature.featureType = get_daal_feature_type(src.get_feature_type(i)); - } -} +ONEDAL_EXPORT feature_type get_daal_feature_type(daal_dm::features::FeatureType t); + +ONEDAL_EXPORT void convert_feature_information_to_daal(const table_metadata& src, + daal_dm::NumericTableDictionary& dst); + +ONEDAL_EXPORT void convert_feature_information_from_daal(const daal_dm::NumericTableDictionary& src, + table_metadata& dst); + +ONEDAL_EXPORT daal_dm::NumericTableDictionaryPtr convert(const table_metadata& src); + +ONEDAL_EXPORT table_metadata convert(const daal_dm::NumericTableDictionaryPtr& src); } // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.cpp b/cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.cpp new file mode 100644 index 00000000000..1a727e70db0 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.cpp @@ -0,0 +1,232 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "oneapi/dal/table/row_accessor.hpp" +#include "oneapi/dal/table/column_accessor.hpp" +#include "oneapi/dal/table/backend/interop/common.hpp" +#include "oneapi/dal/backend/interop/error_converter.hpp" +#include "oneapi/dal/table/backend/interop/buffer_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp" + +namespace oneapi::dal::backend::interop { + +namespace daal_dm = daal::data_management; + +auto host_heterogen_table_adapter::create(const heterogen_table& table) -> ptr_t { + status_t status; + auto* raw = new host_heterogen_table_adapter(table, status); + interop::status_to_exception(status); + return ptr_t{ raw }; +} + +template +inline auto to_size_t(Integral integral) { + using dal::detail::integral_cast; + return integral_cast(integral); +} + +host_heterogen_table_adapter::host_heterogen_table_adapter(const heterogen_table& table, + status_t& status) + : base_t{ convert(table.get_metadata()), to_size_t(table.get_row_count()) }, + original_table_(table) {} + +auto host_heterogen_table_adapter::getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() -> status_t { + return read_rows_impl(vector_idx, vector_num, rwflag, block); + }); +} + +auto host_heterogen_table_adapter::getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() -> status_t { + return read_rows_impl(vector_idx, vector_num, rwflag, block); + }); +} + +auto host_heterogen_table_adapter::getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() -> status_t { + return read_rows_impl(vector_idx, vector_num, rwflag, block); + }); +} + +auto host_heterogen_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() -> status_t { + return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); + }); +} + +auto host_heterogen_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() -> status_t { + return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); + }); +} + +auto host_heterogen_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() -> status_t { + return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); + }); +} + +auto host_heterogen_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_heterogen_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_heterogen_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_heterogen_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) + -> status_t { + block.reset(); + return status_t(); +} + +auto host_heterogen_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) + -> status_t { + block.reset(); + return status_t(); +} + +auto host_heterogen_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) + -> status_t { + block.reset(); + return status_t(); +} + +auto host_heterogen_table_adapter::assign(float) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_heterogen_table_adapter::assign(double) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_heterogen_table_adapter::assign(int) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_heterogen_table_adapter::allocateDataMemoryImpl(daal::MemType) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_heterogen_table_adapter::setNumberOfColumnsImpl(std::size_t) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +int host_heterogen_table_adapter::getSerializationTag() const { + ONEDAL_ASSERT(!"host_soa_table_adapter: getSerializationTag() is not implemented"); + return -1; +} + +auto host_heterogen_table_adapter::serializeImpl(daal_dm::InputDataArchive* arch) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_heterogen_table_adapter::deserializeImpl(const daal_dm::OutputDataArchive* arch) + -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +void host_heterogen_table_adapter::freeDataMemoryImpl() { + base_t::freeDataMemoryImpl(); + original_table_ = heterogen_table{}; +} + +template +auto host_heterogen_table_adapter::read_rows_impl(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + if (rwflag != daal_dm::readOnly) { + ONEDAL_ASSERT(!"Data is accessible in read-only mode by design"); + return daal::services::ErrorMethodNotImplemented; + } + + using dal::detail::integral_cast; + using dal::detail::check_sum_overflow; + + const auto column_count = original_table_.get_column_count(); + const auto col_count = integral_cast(column_count); + + const auto row_count = integral_cast(vector_num); + const auto first = integral_cast(vector_idx); + const auto last = check_sum_overflow(first, row_count); + + row_accessor accessor{ original_table_ }; + dal::array data = accessor.pull({ first, last }); + auto [buffer, status] = convert_with_status(data); + + block.setBuffer(buffer, col_count, vector_num); + + return status; +} + +template +auto host_heterogen_table_adapter::read_column_values_impl(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + if (rwflag != daal_dm::readOnly) { + ONEDAL_ASSERT(!"Data is accessible in read-only mode by design"); + return daal::services::ErrorMethodNotImplemented; + } + + using dal::detail::integral_cast; + using dal::detail::check_sum_overflow; + + const auto column_idx = integral_cast(feature_idx); + const auto row_count = integral_cast(value_num); + const auto first = integral_cast(vector_idx); + const auto last = check_sum_overflow(first, row_count); + + column_accessor accessor{ original_table_ }; + auto data = accessor.pull(column_idx, { first, last }); + auto [buffer, status] = convert_with_status(data); + + block.setBuffer(buffer, 1ul, value_num); + + return status; +} + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp b/cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp new file mode 100644 index 00000000000..f52d526e8f6 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp @@ -0,0 +1,138 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include + +#include "oneapi/dal/table/heterogen.hpp" +#include "oneapi/dal/backend/interop/error_converter.hpp" +#include "oneapi/dal/backend/interop/daal_object_owner.hpp" +#include "oneapi/dal/table/backend/interop/block_info.hpp" + +namespace oneapi::dal::backend::interop { + +// This class shall be used only to represent immutable data on DAAL side. Any +// attempts to change the data inside objects of that class lead to undefined +// behavior. +class host_heterogen_table_adapter : public daal::data_management::SOANumericTable { + using status_t = daal::services::Status; + using base_t = daal::data_management::SOANumericTable; + using rw_mode_t = daal::data_management::ReadWriteMode; + using ptr_t = daal::services::SharedPtr; + + template + using block_desc_t = daal::data_management::BlockDescriptor; + +public: + static ptr_t create(const heterogen_table& table); + +protected: + explicit host_heterogen_table_adapter(const heterogen_table& table, status_t& stat); + + status_t getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + template + status_t get_block_of_rows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block); + + status_t getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + //template + //status_t get_block_of_column_values(std::size_t feature_idx, + // std::size_t vector_idx, + // std::size_t value_num, + // rw_mode_t rwflag, + // block_desc_t& block) override; + + status_t releaseBlockOfRows(block_desc_t& block) override; + status_t releaseBlockOfRows(block_desc_t& block) override; + status_t releaseBlockOfRows(block_desc_t& block) override; + + //template + //status_t release_block_of_rows(block_desc_t& block) override; + + status_t releaseBlockOfColumnValues(block_desc_t& block) override; + status_t releaseBlockOfColumnValues(block_desc_t& block) override; + status_t releaseBlockOfColumnValues(block_desc_t& block) override; + + //template + //status_t release_block_of_column_values(block_desc_t& block) override; + + template + status_t read_rows_impl(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block); + + template + status_t read_column_values_impl(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block); + + status_t assign(float value) override; + status_t assign(double value) override; + status_t assign(int value) override; + + template + status_t assign(Type value); + + int getSerializationTag() const override; + status_t serializeImpl(daal::data_management::InputDataArchive* arch) override; + status_t deserializeImpl(const daal::data_management::OutputDataArchive* arch) override; + + status_t allocateDataMemoryImpl(daal::MemType) override; + status_t setNumberOfColumnsImpl(std::size_t) override; + void freeDataMemoryImpl() override; + +private: + heterogen_table original_table_; +}; + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.cpp b/cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.cpp new file mode 100755 index 00000000000..e4c52e1c8b8 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.cpp @@ -0,0 +1,244 @@ +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/common.hpp" + +namespace oneapi::dal::backend::interop { + +namespace daal_dm = daal::data_management; + +template +auto host_soa_table_adapter::create(const homogen_table& table) -> ptr_t { + status_t internal_stat; + auto result = ptr_t{ new host_soa_table_adapter(table, internal_stat, Data{}) }; + status_to_exception(internal_stat); + return result; +} + +// TODO: change 'equal' flags across this constructor after implemeting the method +// of features equality defining for table_metadata class. +template +host_soa_table_adapter::host_soa_table_adapter(const homogen_table& table, + status_t& stat, + Data dummy) + : base(dal::detail::integral_cast(table.get_column_count()), + dal::detail::integral_cast(table.get_row_count()), + daal_dm::DictionaryIface::equal), + original_table_(table) { + if (!stat.ok()) { + return; + } + else if (!table.has_data()) { + stat.add(daal::services::ErrorIncorrectParameter); + return; + } + + if (table.get_data_layout() != data_layout::column_major) { + stat.add(daal::services::ErrorMethodNotImplemented); + return; + } + + // The following const_cast is safe only when this class is used for read-only + // operations. Use on write leads to undefined behaviour. + const auto original_data = const_cast(table.get_data()); + + const std::size_t column_count = + dal::detail::integral_cast(table.get_column_count()); + const std::size_t row_count = dal::detail::integral_cast(table.get_row_count()); + + for (std::size_t i = 0; i < column_count; i++) { + stat |= base::setArray(&original_data[i * row_count], i); + + if (!stat.ok()) { + return; + } + } + + this->_memStatus = daal_dm::NumericTableIface::userAllocated; + this->_layout = daal_dm::NumericTableIface::soa; + + convert_feature_information_to_daal(original_table_.get_metadata(), + *this->getDictionarySharedPtr()); +} + +auto host_soa_table_adapter::getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() { + return read_rows_impl(vector_idx, vector_num, rwflag, block); + }); +} + +auto host_soa_table_adapter::getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() { + return read_rows_impl(vector_idx, vector_num, rwflag, block); + }); +} + +auto host_soa_table_adapter::getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() { + return read_rows_impl(vector_idx, vector_num, rwflag, block); + }); +} + +auto host_soa_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() { + return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); + }); +} + +auto host_soa_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() { + return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); + }); +} + +auto host_soa_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + return convert_exception_to_status([&]() { + return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); + }); +} + +auto host_soa_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_soa_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_soa_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_soa_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_soa_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_soa_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) -> status_t { + block.reset(); + return status_t(); +} + +auto host_soa_table_adapter::assign(float) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_soa_table_adapter::assign(double) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_soa_table_adapter::assign(int) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_soa_table_adapter::allocateDataMemoryImpl(daal::MemType) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_soa_table_adapter::setNumberOfColumnsImpl(std::size_t) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +int host_soa_table_adapter::getSerializationTag() const { + ONEDAL_ASSERT(!"host_soa_table_adapter: getSerializationTag() is not implemented"); + return -1; +} + +auto host_soa_table_adapter::serializeImpl(daal_dm::InputDataArchive* arch) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +auto host_soa_table_adapter::deserializeImpl(const daal_dm::OutputDataArchive* arch) -> status_t { + return daal::services::ErrorMethodNotImplemented; +} + +void host_soa_table_adapter::freeDataMemoryImpl() { + base::freeDataMemoryImpl(); + original_table_ = homogen_table{}; +} + +template +auto host_soa_table_adapter::read_rows_impl(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + if (rwflag != daal_dm::readOnly) { + ONEDAL_ASSERT(!"Data is accessible in read-only mode by design"); + return daal::services::ErrorMethodNotImplemented; + } + + return base::getBlockOfRows(vector_idx, vector_num, rwflag, block); +} + +template +auto host_soa_table_adapter::read_column_values_impl(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) -> status_t { + if (rwflag != daal_dm::readOnly) { + ONEDAL_ASSERT(!"Data is accessible in read-only mode by design"); + return daal::services::ErrorMethodNotImplemented; + } + + return base::getBlockOfColumnValues(feature_idx, vector_idx, value_num, rwflag, block); +} + +bool host_soa_table_adapter::check_row_indexes_in_range(const block_info& info) const { + const std::int64_t row_count = original_table_.get_row_count(); + return info.row_begin_index < row_count && info.row_end_index <= row_count; +} + +bool host_soa_table_adapter::check_column_index_in_range(const block_info& info) const { + const std::int64_t column_count = original_table_.get_column_count(); + return info.single_column_requested && info.column_index < column_count; +} + +template auto host_soa_table_adapter::create(const homogen_table&) -> ptr_t; +template auto host_soa_table_adapter::create(const homogen_table&) -> ptr_t; +template auto host_soa_table_adapter::create(const homogen_table&) -> ptr_t; + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.hpp b/cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.hpp new file mode 100755 index 00000000000..a6cde837efd --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.hpp @@ -0,0 +1,120 @@ +/******************************************************************************* +* Copyright 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include + +#include "oneapi/dal/table/homogen.hpp" +#include "oneapi/dal/backend/interop/error_converter.hpp" +#include "oneapi/dal/backend/interop/daal_object_owner.hpp" +#include "oneapi/dal/table/backend/interop/block_info.hpp" + +namespace oneapi::dal::backend::interop { + +// This class shall be used only to represent immutable data on DAAL side. Any +// attempts to change the data inside objects of that class lead to undefined +// behavior. +class host_soa_table_adapter : public daal::data_management::SOANumericTable { + using base = daal::data_management::SOANumericTable; + using status_t = daal::services::Status; + using rw_mode_t = daal::data_management::ReadWriteMode; + using ptr_t = daal::services::SharedPtr; + + template + using block_desc_t = daal::data_management::BlockDescriptor; + +public: + template + static ptr_t create(const homogen_table& table); + +private: + template + explicit host_soa_table_adapter(const homogen_table& table, status_t& stat, Data dummy); + + status_t getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfRows(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t getBlockOfColumnValues(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block) override; + + status_t releaseBlockOfRows(block_desc_t& block) override; + status_t releaseBlockOfRows(block_desc_t& block) override; + status_t releaseBlockOfRows(block_desc_t& block) override; + + status_t releaseBlockOfColumnValues(block_desc_t& block) override; + status_t releaseBlockOfColumnValues(block_desc_t& block) override; + status_t releaseBlockOfColumnValues(block_desc_t& block) override; + + status_t assign(float value) override; + status_t assign(double value) override; + status_t assign(int value) override; + + int getSerializationTag() const override; + status_t serializeImpl(daal::data_management::InputDataArchive* arch) override; + status_t deserializeImpl(const daal::data_management::OutputDataArchive* arch) override; + + status_t allocateDataMemoryImpl(daal::MemType) override; + status_t setNumberOfColumnsImpl(std::size_t) override; + void freeDataMemoryImpl() override; + + template + status_t read_rows_impl(std::size_t vector_idx, + std::size_t vector_num, + rw_mode_t rwflag, + block_desc_t& block); + + template + status_t read_column_values_impl(std::size_t feature_idx, + std::size_t vector_idx, + std::size_t value_num, + rw_mode_t rwflag, + block_desc_t& block); + + bool check_row_indexes_in_range(const block_info& info) const; + bool check_column_index_in_range(const block_info& info) const; + + homogen_table original_table_; +}; + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.cpp b/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.cpp old mode 100755 new mode 100644 index e4c52e1c8b8..04a13831da0 --- a/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.cpp +++ b/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2023 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,231 +14,45 @@ * limitations under the License. *******************************************************************************/ -#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" -#include "oneapi/dal/table/backend/interop/common.hpp" - -namespace oneapi::dal::backend::interop { +#include -namespace daal_dm = daal::data_management; - -template -auto host_soa_table_adapter::create(const homogen_table& table) -> ptr_t { - status_t internal_stat; - auto result = ptr_t{ new host_soa_table_adapter(table, internal_stat, Data{}) }; - status_to_exception(internal_stat); - return result; -} - -// TODO: change 'equal' flags across this constructor after implemeting the method -// of features equality defining for table_metadata class. -template -host_soa_table_adapter::host_soa_table_adapter(const homogen_table& table, - status_t& stat, - Data dummy) - : base(dal::detail::integral_cast(table.get_column_count()), - dal::detail::integral_cast(table.get_row_count()), - daal_dm::DictionaryIface::equal), - original_table_(table) { - if (!stat.ok()) { - return; - } - else if (!table.has_data()) { - stat.add(daal::services::ErrorIncorrectParameter); - return; - } +#include "oneapi/dal/common.hpp" +#include "oneapi/dal/detail/error_messages.hpp" - if (table.get_data_layout() != data_layout::column_major) { - stat.add(daal::services::ErrorMethodNotImplemented); - return; - } - - // The following const_cast is safe only when this class is used for read-only - // operations. Use on write leads to undefined behaviour. - const auto original_data = const_cast(table.get_data()); +#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp" - const std::size_t column_count = - dal::detail::integral_cast(table.get_column_count()); - const std::size_t row_count = dal::detail::integral_cast(table.get_row_count()); +namespace oneapi::dal::backend::interop { - for (std::size_t i = 0; i < column_count; i++) { - stat |= base::setArray(&original_data[i * row_count], i); +template +soa_table_ptr_t convert_to_soa(const table& t, DefaultType type_tag) { + soa_table_ptr_t result; + const auto kind = t.get_kind(); - if (!stat.ok()) { - return; - } + if (kind == heterogen_table::kind()) { + const auto& raw = reinterpret_cast(t); + auto ptr = host_soa_table_adapter::create(raw); + result = soa_table_ptr_t{ ptr }; } - - this->_memStatus = daal_dm::NumericTableIface::userAllocated; - this->_layout = daal_dm::NumericTableIface::soa; - - convert_feature_information_to_daal(original_table_.get_metadata(), - *this->getDictionarySharedPtr()); -} - -auto host_soa_table_adapter::getBlockOfRows(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - return convert_exception_to_status([&]() { - return read_rows_impl(vector_idx, vector_num, rwflag, block); - }); -} - -auto host_soa_table_adapter::getBlockOfRows(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - return convert_exception_to_status([&]() { - return read_rows_impl(vector_idx, vector_num, rwflag, block); - }); -} - -auto host_soa_table_adapter::getBlockOfRows(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - return convert_exception_to_status([&]() { - return read_rows_impl(vector_idx, vector_num, rwflag, block); - }); -} - -auto host_soa_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - return convert_exception_to_status([&]() { - return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); - }); -} - -auto host_soa_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - return convert_exception_to_status([&]() { - return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); - }); -} - -auto host_soa_table_adapter::getBlockOfColumnValues(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - return convert_exception_to_status([&]() { - return read_column_values_impl(feature_idx, vector_idx, value_num, rwflag, block); - }); -} - -auto host_soa_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { - block.reset(); - return status_t(); -} - -auto host_soa_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { - block.reset(); - return status_t(); -} - -auto host_soa_table_adapter::releaseBlockOfRows(block_desc_t& block) -> status_t { - block.reset(); - return status_t(); -} - -auto host_soa_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) -> status_t { - block.reset(); - return status_t(); -} - -auto host_soa_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) -> status_t { - block.reset(); - return status_t(); -} - -auto host_soa_table_adapter::releaseBlockOfColumnValues(block_desc_t& block) -> status_t { - block.reset(); - return status_t(); -} - -auto host_soa_table_adapter::assign(float) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -auto host_soa_table_adapter::assign(double) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -auto host_soa_table_adapter::assign(int) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -auto host_soa_table_adapter::allocateDataMemoryImpl(daal::MemType) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -auto host_soa_table_adapter::setNumberOfColumnsImpl(std::size_t) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -int host_soa_table_adapter::getSerializationTag() const { - ONEDAL_ASSERT(!"host_soa_table_adapter: getSerializationTag() is not implemented"); - return -1; -} - -auto host_soa_table_adapter::serializeImpl(daal_dm::InputDataArchive* arch) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -auto host_soa_table_adapter::deserializeImpl(const daal_dm::OutputDataArchive* arch) -> status_t { - return daal::services::ErrorMethodNotImplemented; -} - -void host_soa_table_adapter::freeDataMemoryImpl() { - base::freeDataMemoryImpl(); - original_table_ = homogen_table{}; -} - -template -auto host_soa_table_adapter::read_rows_impl(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - if (rwflag != daal_dm::readOnly) { - ONEDAL_ASSERT(!"Data is accessible in read-only mode by design"); - return daal::services::ErrorMethodNotImplemented; + else if (kind == homogen_table::kind()) { + const auto& raw = reinterpret_cast(t); + auto ptr = host_heterogen_table_adapter::create(raw); + result = soa_table_ptr_t{ ptr }; } - - return base::getBlockOfRows(vector_idx, vector_num, rwflag, block); -} - -template -auto host_soa_table_adapter::read_column_values_impl(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) -> status_t { - if (rwflag != daal_dm::readOnly) { - ONEDAL_ASSERT(!"Data is accessible in read-only mode by design"); - return daal::services::ErrorMethodNotImplemented; + else { + using msg = dal::detail::error_messages; + throw invalid_argument(msg::unsupported_table_conversion()); } - return base::getBlockOfColumnValues(feature_idx, vector_idx, value_num, rwflag, block); -} - -bool host_soa_table_adapter::check_row_indexes_in_range(const block_info& info) const { - const std::int64_t row_count = original_table_.get_row_count(); - return info.row_begin_index < row_count && info.row_end_index <= row_count; + return result; } -bool host_soa_table_adapter::check_column_index_in_range(const block_info& info) const { - const std::int64_t column_count = original_table_.get_column_count(); - return info.single_column_requested && info.column_index < column_count; -} +#define INSTANTIATE(TYPE) \ + template ONEDAL_EXPORT soa_table_ptr_t convert_to_soa(const table&, TYPE); -template auto host_soa_table_adapter::create(const homogen_table&) -> ptr_t; -template auto host_soa_table_adapter::create(const homogen_table&) -> ptr_t; -template auto host_soa_table_adapter::create(const homogen_table&) -> ptr_t; +INSTANTIATE(int) +INSTANTIATE(float) +INSTANTIATE(double) } // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp b/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp old mode 100755 new mode 100644 index a6cde837efd..cc962de496f --- a/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp +++ b/cpp/oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2023 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,103 +18,16 @@ #include -#include "oneapi/dal/table/homogen.hpp" -#include "oneapi/dal/backend/interop/error_converter.hpp" -#include "oneapi/dal/backend/interop/daal_object_owner.hpp" -#include "oneapi/dal/table/backend/interop/block_info.hpp" +#include "oneapi/dal/table/backend/interop/common.hpp" +#include "oneapi/dal/table/backend/interop/host_homogen_to_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_heterogen_to_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.hpp" namespace oneapi::dal::backend::interop { -// This class shall be used only to represent immutable data on DAAL side. Any -// attempts to change the data inside objects of that class lead to undefined -// behavior. -class host_soa_table_adapter : public daal::data_management::SOANumericTable { - using base = daal::data_management::SOANumericTable; - using status_t = daal::services::Status; - using rw_mode_t = daal::data_management::ReadWriteMode; - using ptr_t = daal::services::SharedPtr; +ONEDAL_EXPORT table convert_from_soa(const soa_table_ptr_t& table); - template - using block_desc_t = daal::data_management::BlockDescriptor; +template +ONEDAL_EXPORT soa_table_ptr_t convert_to_soa(const table& t, DefaultType type_tag = {}); -public: - template - static ptr_t create(const homogen_table& table); - -private: - template - explicit host_soa_table_adapter(const homogen_table& table, status_t& stat, Data dummy); - - status_t getBlockOfRows(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) override; - - status_t getBlockOfRows(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) override; - - status_t getBlockOfRows(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block) override; - - status_t getBlockOfColumnValues(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) override; - - status_t getBlockOfColumnValues(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) override; - - status_t getBlockOfColumnValues(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block) override; - - status_t releaseBlockOfRows(block_desc_t& block) override; - status_t releaseBlockOfRows(block_desc_t& block) override; - status_t releaseBlockOfRows(block_desc_t& block) override; - - status_t releaseBlockOfColumnValues(block_desc_t& block) override; - status_t releaseBlockOfColumnValues(block_desc_t& block) override; - status_t releaseBlockOfColumnValues(block_desc_t& block) override; - - status_t assign(float value) override; - status_t assign(double value) override; - status_t assign(int value) override; - - int getSerializationTag() const override; - status_t serializeImpl(daal::data_management::InputDataArchive* arch) override; - status_t deserializeImpl(const daal::data_management::OutputDataArchive* arch) override; - - status_t allocateDataMemoryImpl(daal::MemType) override; - status_t setNumberOfColumnsImpl(std::size_t) override; - void freeDataMemoryImpl() override; - - template - status_t read_rows_impl(std::size_t vector_idx, - std::size_t vector_num, - rw_mode_t rwflag, - block_desc_t& block); - - template - status_t read_column_values_impl(std::size_t feature_idx, - std::size_t vector_idx, - std::size_t value_num, - rw_mode_t rwflag, - block_desc_t& block); - - bool check_row_indexes_in_range(const block_info& info) const; - bool check_column_index_in_range(const block_info& info) const; - - homogen_table original_table_; -}; - -} // namespace oneapi::dal::backend::interop +} // namespace oneapi::dal::backend::interop \ No newline at end of file diff --git a/cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.cpp b/cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.cpp new file mode 100644 index 00000000000..d7cf909a887 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.cpp @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "oneapi/dal/table/backend/interop/table_conversion_common.hpp" +#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/common.hpp" + +#include "oneapi/dal/detail/error_messages.hpp" + +namespace oneapi::dal::backend::interop { + +heterogen_table convert_to_heterogen(const soa_table_ptr_t& t) { + return convert_to_heterogen(*t); +} + +heterogen_table convert_to_heterogen(soa_table_t& t) { + constexpr std::size_t zero = 0; + using dal::detail::integral_cast; + using dal::detail::check_mul_overflow; + using dal::detail::check_sum_overflow; + + const auto raw_row_count = t.getNumberOfRows(); + const auto raw_col_count = t.getNumberOfColumns(); + + const auto row_count = integral_cast(raw_row_count); + const auto col_count = integral_cast(raw_col_count); + + const auto daal_meta = t.getDictionarySharedPtr(); + const table_metadata dal_meta = convert(daal_meta); + + auto table = heterogen_table::empty(dal_meta); + for (std::int64_t col = 0l; col < col_count; ++col) { + const auto dal_dtype = dal_meta.get_data_type(col); + + dispatch_by_table_type( + [&](auto type_tag) -> void { + using type_t = std::decay_t; + + daal_dm::BlockDescriptor column_block; + auto s = t.getBlockOfColumnValues(col, + zero, + raw_col_count, + daal_dm::ReadWriteMode::readOnly, + column_block); + interop::status_to_exception(s); + + auto shared_ptr = column_block.getBlockSharedPtr(); + const type_t* const raw_ptr = shared_ptr.get(); + + auto deleter = [shared_ptr, t](const type_t*) {}; + dal::array column(raw_ptr, row_count, deleter); + + table.set_column(col, std::move(column)); + }, + [](auto dummy) -> void { + using msg = detail::error_messages; + auto str = msg::unsupported_table_conversion(); + throw dal::unimplemented(str); + }, + dal_dtype); + } + + return table; +} + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.hpp b/cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.hpp new file mode 100644 index 00000000000..2e5a8f6f2f7 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/host_soa_to_heterogen_table_adapter.hpp @@ -0,0 +1,32 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include + +#include "oneapi/dal/table/heterogen.hpp" +#include "oneapi/dal/table/detail/metadata_utils.hpp" +#include "oneapi/dal/backend/interop/error_converter.hpp" +#include "oneapi/dal/backend/interop/daal_object_owner.hpp" +#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" + +namespace oneapi::dal::backend::interop { + +ONEDAL_EXPORT heterogen_table convert_to_heterogen(const soa_table_t& t); +ONEDAL_EXPORT heterogen_table convert_to_heterogen(const soa_table_ptr_t& t); + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/table_conversion.cpp b/cpp/oneapi/dal/table/backend/interop/table_conversion.cpp new file mode 100644 index 00000000000..8d18fda8fcf --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/table_conversion.cpp @@ -0,0 +1,318 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#include "oneapi/dal/table/backend/interop/common.hpp" +#include "oneapi/dal/table/backend/interop/table_conversion.hpp" +#include "oneapi/dal/table/backend/interop/table_conversion_common.hpp" + +namespace oneapi::dal::backend::interop { + +template +homogen_table_ptr empty_daal_homogen_table(std::int64_t column_count) { + return daal::data_management::HomogenNumericTable::create( + dal::detail::integral_cast(column_count), + dal::detail::integral_cast(0), + daal::data_management::NumericTable::notAllocate); +} + +template +homogen_table_ptr allocate_daal_homogen_table(std::int64_t row_count, + std::int64_t column_count) { + return daal::data_management::HomogenNumericTable::create( + dal::detail::integral_cast(column_count), + dal::detail::integral_cast(row_count), + daal::data_management::NumericTable::doAllocate); +} + +template +homogen_table_ptr convert_to_daal_homogen_table(array& data, + std::int64_t row_count, + std::int64_t column_count, + bool allow_copy) { + if (!data.get_count()) { + return empty_daal_homogen_table(column_count); + } + + if (allow_copy) { + data.need_mutable_data(); + } + + ONEDAL_ASSERT(data.has_mutable_data()); + const auto daal_data = daal_shared_t( // + data.get_mutable_data(), + daal_object_owner{ data }); + + return daal_homogen_t::create(daal_data, + dal::detail::integral_cast(column_count), + dal::detail::integral_cast(row_count)); +} + +template +homogen_table_ptr copy_to_daal_homogen_table(const table& table) { + // TODO: Preserve information about features + constexpr bool allow_copy = true; + auto rows = row_accessor{ table }.pull(); + return convert_to_daal_homogen_table(rows, + table.get_row_count(), + table.get_column_count(), + allow_copy); +} + +template +homogen_table convert_from_daal_homogen_table(const numeric_table_ptr& nt) { + if (nt->getNumberOfRows() == 0) { + return homogen_table{}; + } + daal::data_management::BlockDescriptor block; + const std::int64_t row_count = dal::detail::integral_cast(nt->getNumberOfRows()); + const std::int64_t column_count = + dal::detail::integral_cast(nt->getNumberOfColumns()); + + nt->getBlockOfRows(0, row_count, daal::data_management::readOnly, block); + Data* data = block.getBlockPtr(); + array arr(data, row_count * column_count, [nt, block](Data* p) mutable { + nt->releaseBlockOfRows(block); + }); + + return detail::homogen_table_builder{}.reset(arr, row_count, column_count).build(); +} + +numeric_table_ptr wrap_by_host_homogen_adapter(const homogen_table& table) { + const auto dtype = table.get_metadata().get_data_type(0); + + const auto to_homogen = [&table](auto type_tag) -> numeric_table_ptr { + using type_t = std::decay_t; + return host_homogen_table_adapter::create(table); + }; + + const auto to_empty = [](auto dummy) -> numeric_table_ptr { + return numeric_table_ptr{}; + }; + + return dispatch_by_table_type(to_homogen, to_empty, dtype); +} + +template +numeric_table_ptr convert_to_daal_table(const homogen_table& table) { + if (table.get_data_layout() == data_layout::column_major) { + if (auto wrapper = wrap_by_host_soa_adapter(table)) { + return wrapper; + } + } + else if (table.get_data_layout() == data_layout::row_major) { + if (auto wrapper = wrap_by_host_homogen_adapter(table)) { + return wrapper; + } + } + return copy_to_daal_homogen_table(table); +} + +template +csr_table_ptr convert_to_daal_csr_table(array& data, + array& column_indices, + array& row_indices, + std::int64_t row_count, + std::int64_t column_count, + bool allow_copy) { + ONEDAL_ASSERT(data.get_count() == column_indices.get_count()); + ONEDAL_ASSERT(row_indices.get_count() == row_count + 1); + + if (!data.get_count() || !column_indices.get_count() || !row_indices.get_count()) { + return csr_table_ptr(); + } + + if (allow_copy) { + data.need_mutable_data(); + column_indices.need_mutable_data(); + row_indices.need_mutable_data(); + } + + ONEDAL_ASSERT(data.has_mutable_data()); + ONEDAL_ASSERT(column_indices.has_mutable_data()); + ONEDAL_ASSERT(row_indices.has_mutable_data()); + + const auto daal_data = + daal::services::SharedPtr(data.get_mutable_data(), daal_object_owner{ data }); + ONEDAL_ASSERT(sizeof(std::size_t) == sizeof(std::int64_t)); + const auto daal_column_indices = daal::services::SharedPtr( + reinterpret_cast(column_indices.get_mutable_data()), + daal_object_owner{ column_indices }); + const auto daal_row_indices = daal::services::SharedPtr( + reinterpret_cast(row_indices.get_mutable_data()), + daal_object_owner{ row_indices }); + + return daal_csr_t::create(daal_data, + daal_column_indices, + daal_row_indices, + dal::detail::integral_cast(column_count), + dal::detail::integral_cast(row_count)); +} + +template +csr_table_ptr copy_to_daal_csr_table(const csr_table& table) { + constexpr bool allow_copy = true; + auto [data, column_indices, row_offsets] = csr_accessor{ table }.pull(); + return convert_to_daal_csr_table(data, + column_indices, + row_offsets, + table.get_row_count(), + table.get_column_count(), + allow_copy); +} + +csr_table_ptr wrap_by_host_csr_adapter(const csr_table& table) { + const auto dtype = table.get_metadata().get_data_type(0); + + const auto to_csr = [&table](auto type_tag) -> csr_table_ptr { + using type_t = std::decay_t; + return host_csr_table_adapter::create(table); + }; + + const auto to_empty = [](auto dummy) -> csr_table_ptr { + return csr_table_ptr{}; + }; + + return dispatch_by_table_type(to_csr, to_empty, dtype); +} + +template +csr_table_ptr convert_to_daal_table(const csr_table& table) { + if (auto wrapper = wrap_by_host_csr_adapter(table)) { + return wrapper; + } + else { + return copy_to_daal_csr_table(table); + } +} + +template +csr_table convert_from_daal_csr_table(const numeric_table_ptr& nt) { + auto block_owner = std::make_shared>(csr_block_owner{ nt }); + + ONEDAL_ASSERT(sizeof(std::size_t) == sizeof(std::int64_t)); + + return csr_table{ + array{ block_owner->get_data(), + block_owner->get_element_count(), + [block_owner](const Data* p) {} }, + array{ reinterpret_cast(block_owner->get_column_indices()), + block_owner->get_element_count(), + [block_owner](const std::int64_t* p) {} }, + array{ reinterpret_cast(block_owner->get_row_indices()), + block_owner->get_row_count() + 1, + [block_owner](const std::int64_t* p) {} }, + block_owner->get_column_count() + }; +} + +soa_table_ptr wrap_by_host_soa_adapter(const homogen_table& table) { + const auto dtype = table.get_metadata().get_data_type(0); + + const auto to_soa = [&table](auto type_tag) -> soa_table_ptr { + using type_t = std::decay_t; + return host_soa_table_adapter::create(table); + }; + + const auto to_empty = [](auto dummy) -> soa_table_ptr { + return soa_table_ptr{}; + }; + + return dispatch_by_table_type(to_soa, to_empty, dtype); +} + +soa_table_ptr wrap_by_host_soa_adapter(const heterogen_table& table) { + if (table.has_data()) { + return host_heterogen_table_adapter::create(table); + } + else { + return soa_table_ptr{}; + } +} + +template +numeric_table_ptr convert_to_daal_table(const heterogen_table& table) { + if (auto wrapper = wrap_by_host_soa_adapter(table)) { + return wrapper; + } + return copy_to_daal_homogen_table(table); +} + +heterogen_table convert_from_daal_table(const numeric_table_ptr& table) { + auto& raw = static_cast(*table); + return convert_to_heterogen(raw); +} + +template +table convert_from_daal_table(const numeric_table_ptr& nt) { + using StorageLayout = dm::NumericTableIface::StorageLayout; + if (nt->getDataLayout() == StorageLayout::csrArray) { + return convert_from_daal_csr_table(nt); + } + else if (nt->getDataLayout() == StorageLayout::aos) { + return convert_from_daal_homogen_table(nt); + } + else if (nt->getDataLayout() == StorageLayout::soa) { + return convert_from_daal_heterogen_table(nt); + } + else { + return table{}; + } +} + +template +numeric_table_ptr convert_to_daal_table(const table& table) { + if (table.get_kind() == homogen_table::kind()) { + const auto& homogen = static_cast(table); + return convert_to_daal_table(homogen); + } + else if (table.get_kind() == heterogen_table::kind()) { + const auto& heterogen = static_cast(table); + return convert_to_daal_table(heterogen); + } + else if (table.get_kind() == csr_table::kind()) { + const auto& csr = static_cast(table); + return convert_to_daal_table(csr); + } + else { + return copy_to_daal_homogen_table(table); + } +} + +#define INSTANTIATE(TYPE) \ + template ONEDAL_EXPORT numeric_table_ptr convert_to_daal_table(const homogen_table&); \ + template ONEDAL_EXPORT homogen_table_ptr copy_to_daal_homogen_table(const table&); \ + template ONEDAL_EXPORT homogen_table_ptr convert_to_daal_homogen_table(array&, \ + std::int64_t, \ + std::int64_t, \ + bool); \ + template ONEDAL_EXPORT csr_table_ptr convert_to_daal_csr_table(array&, \ + array&, \ + array&, \ + std::int64_t, \ + std::int64_t, \ + bool); \ + template ONEDAL_EXPORT csr_table_ptr copy_to_daal_csr_table(const csr_table&); \ + template ONEDAL_EXPORT csr_table_ptr convert_to_daal_table(const csr_table&); \ + template ONEDAL_EXPORT csr_table convert_from_daal_csr_table(const numeric_table_ptr&); \ + template ONEDAL_EXPORT numeric_table_ptr convert_to_daal_table(const heterogen_table&); \ + template ONEDAL_EXPORT table convert_from_daal_table(const numeric_table_ptr&); \ + template ONEDAL_EXPORT numeric_table_ptr convert_to_daal_table(const table& table); + +INSTANTIATE(std::int32_t) +INSTANTIATE(double) +INSTANTIATE(float) + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/table_conversion.hpp b/cpp/oneapi/dal/table/backend/interop/table_conversion.hpp new file mode 100644 index 00000000000..7e559cec80c --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/table_conversion.hpp @@ -0,0 +1,112 @@ +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include "oneapi/dal/backend/memory.hpp" +#include "oneapi/dal/table/detail/table_builder.hpp" +#include "oneapi/dal/table/backend/interop/sycl_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_homogen_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_soa_table_adapter.hpp" +#include "oneapi/dal/table/backend/interop/host_csr_table_adapter.hpp" +#include "oneapi/dal/backend/interop/csr_block_owner.hpp" + +#ifdef ONEDAL_DATA_PARALLEL +#include "oneapi/dal/table/backend/interop/table_conversion_dpc.hpp" +#endif + +namespace oneapi::dal::backend::interop { + +namespace dm = daal::data_management; + +using daal_csr_t = dm::CSRNumericTable; + +using daal_soa_t = dm::SOANumericTable; + +template +using daal_homogen_t = dm::HomogenNumericTable; + +template +using daal_shared_t = daal::services::SharedPtr; + +using numeric_table_ptr = dm::NumericTablePtr; + +using csr_table_ptr = daal_shared_t; + +using soa_table_ptr = daal_shared_t; +template +using homogen_table_ptr = daal_shared_t>; + +template +homogen_table_ptr allocate_daal_homogen_table(std::int64_t row_count, + std::int64_t column_count); + +template +homogen_table_ptr empty_daal_homogen_table(std::int64_t column_count); + +template +ONEDAL_EXPORT homogen_table_ptr convert_to_daal_homogen_table(array& data, + std::int64_t row_count, + std::int64_t column_count, + bool allow_copy = false); +template +ONEDAL_EXPORT homogen_table_ptr copy_to_daal_homogen_table(const table& table); + +template +ONEDAL_EXPORT homogen_table convert_from_daal_homogen_table(const numeric_table_ptr& nt); + +ONEDAL_EXPORT numeric_table_ptr wrap_by_host_homogen_adapter(const homogen_table& table); + +ONEDAL_EXPORT soa_table_ptr wrap_by_host_soa_adapter(const homogen_table& table); + +ONEDAL_EXPORT soa_table_ptr wrap_by_host_soa_adapter(const heterogen_table& table); + +template +ONEDAL_EXPORT numeric_table_ptr convert_to_daal_table(const homogen_table& table); + +template +ONEDAL_EXPORT csr_table_ptr convert_to_daal_csr_table(array& data, + array& column_indices, + array& row_indices, + std::int64_t row_count, + std::int64_t column_count, + bool allow_copy = false); + +template +ONEDAL_EXPORT csr_table_ptr copy_to_daal_csr_table(const csr_table& table); + +template +ONEDAL_EXPORT csr_table convert_from_daal_csr_table(const numeric_table_ptr& nt); + +ONEDAL_EXPORT csr_table_ptr wrap_by_host_csr_adapter(const csr_table& table); + +ONEDAL_EXPORT soa_table_ptr wrap_by_host_soa_adapter(const heterogen_table& table); + +template +ONEDAL_EXPORT numeric_table_ptr convert_to_daal_table(const heterogen_table& table); + +ONEDAL_EXPORT heterogen_table convert_from_daal_heterogen_table(const numeric_table_ptr& nt); + +template +ONEDAL_EXPORT csr_table_ptr convert_to_daal_table(const csr_table& table); + +template +ONEDAL_EXPORT numeric_table_ptr convert_to_daal_table(const table& table); + +template +ONEDAL_EXPORT table convert_from_daal_table(const numeric_table_ptr& nt); + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/table_conversion_common.hpp b/cpp/oneapi/dal/table/backend/interop/table_conversion_common.hpp new file mode 100644 index 00000000000..acec80bf8c0 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/table_conversion_common.hpp @@ -0,0 +1,36 @@ +/******************************************************************************* +* Copyright 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#include "oneapi/dal/common.hpp" +#include "oneapi/dal/detail/common.hpp" +#include "oneapi/dal/backend/common.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" + +namespace oneapi::dal::backend::interop { + +template +constexpr auto inline dispatch_by_table_type(Op&& op, OnUnknown&& on_unknown, data_type dtype) { + switch (dtype) { + case data_type::int32: return op(std::int32_t{}); + case data_type::float64: return op(double{}); + case data_type::float32: return op(float{}); + default: return on_unknown(dtype); + } +} + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.cpp b/cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.cpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.hpp b/cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.hpp new file mode 100644 index 00000000000..0c06003fa49 --- /dev/null +++ b/cpp/oneapi/dal/table/backend/interop/table_conversion_dpc.hpp @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#pragma once + +#ifdef ONEDAL_DATA_PARALLEL +#include +#endif + +#include "oneapi/dal/table/backend/interop/sycl_table_adapter.hpp" + +namespace oneapi::dal::backend::interop { + +#ifdef ONEDAL_DATA_PARALLEL +inline daal::data_management::NumericTablePtr convert_to_daal_table(const sycl::queue& queue, + const table& table) { + if (!table.has_data()) { + return daal::data_management::NumericTablePtr{}; + } + return interop::sycl_table_adapter::create(queue, table); +} + +template +inline daal::data_management::NumericTablePtr convert_to_daal_table(const sycl::queue& queue, + const array& data, + std::int64_t row_count, + std::int64_t column_count) { + using daal::services::Status; + using daal::services::SharedPtr; + using daal::services::internal::Buffer; + using daal::data_management::internal::SyclHomogenNumericTable; + using dal::detail::integral_cast; + + ONEDAL_ASSERT(data.get_count() == row_count * column_count); + ONEDAL_ASSERT(data.has_mutable_data()); + ONEDAL_ASSERT(is_same_context(queue, data)); + + const SharedPtr data_shared{ data.get_mutable_data(), daal_object_owner{ data } }; + + Status status; + const Buffer buffer{ data_shared, + integral_cast(data.get_count()), + queue, + status }; + status_to_exception(status); + + const auto table = + SyclHomogenNumericTable::create(buffer, + integral_cast(column_count), + integral_cast(row_count), + &status); + status_to_exception(status); + + return table; +} +#endif + +} // namespace oneapi::dal::backend::interop diff --git a/cpp/oneapi/dal/table/detail/metadata_utils.hpp b/cpp/oneapi/dal/table/detail/metadata_utils.hpp index 01800216b21..8db08b88528 100644 --- a/cpp/oneapi/dal/table/detail/metadata_utils.hpp +++ b/cpp/oneapi/dal/table/detail/metadata_utils.hpp @@ -111,11 +111,29 @@ inline table_metadata make_default_metadata_from_arrays() { return make_default_metadata_from_arrays_impl(reinterpret_cast(0ul)); } +inline bool is_homogen_metadata(const table_metadata& meta) { + const auto f_count = meta.get_feature_count(); + if (std::int64_t{ 0l } < f_count) { + const auto first_dtype = meta.get_data_type(0l); + const auto first_ftype = meta.get_feature_type(0l); + for (std::int64_t col = 1l; col < f_count; ++col) { + const auto is_same_dtype = first_dtype == meta.get_data_type(col); + const auto is_same_ftype = first_ftype == meta.get_feature_type(col); + if ((!is_same_dtype) || (!is_same_ftype)) { + return false; + } + } + } + return true; +} + } // namespace v1 using v1::find_array_dtypes; using v1::find_array_ftypes; +using v1::is_homogen_metadata; + using v1::make_default_metadata; using v1::make_default_metadata_from_arrays; diff --git a/cpp/oneapi/dal/table/heterogen.hpp b/cpp/oneapi/dal/table/heterogen.hpp index 5ec8d5faffe..3d41f42c35f 100644 --- a/cpp/oneapi/dal/table/heterogen.hpp +++ b/cpp/oneapi/dal/table/heterogen.hpp @@ -81,7 +81,7 @@ class ONEDAL_EXPORT heterogen_table : public table { heterogen_table& set_column(std::int64_t column, array arr) { const auto as_chunked = chunked_array{ std::move(arr) }; const auto dt = this->get_metadata().get_data_type(column); - this->set_column(column, dt, std::move(as_chunked)); + this->set_column_impl(column, dt, std::move(as_chunked)); return *this; } diff --git a/cpp/oneapi/dal/table/test/heterogen.cpp b/cpp/oneapi/dal/table/test/heterogen.cpp index 73370b69cb5..33407b7d7ff 100644 --- a/cpp/oneapi/dal/table/test/heterogen.cpp +++ b/cpp/oneapi/dal/table/test/heterogen.cpp @@ -14,6 +14,8 @@ * limitations under the License. *******************************************************************************/ +#include "oneapi/dal/detail/debug.hpp" + #include "oneapi/dal/array.hpp" #include "oneapi/dal/chunked_array.hpp" diff --git a/cpp/oneapi/dal/table/test/table_adapter.cpp b/cpp/oneapi/dal/table/test/table_adapter.cpp index 2468d94cf50..4e5ef0cf27c 100644 --- a/cpp/oneapi/dal/table/test/table_adapter.cpp +++ b/cpp/oneapi/dal/table/test/table_adapter.cpp @@ -38,6 +38,31 @@ TEST("SOA adapter is used") { REQUIRE(dynamic_cast(dt.get()) != nullptr); } +TEST("Can create SOA table adapter") { + constexpr float src1[] = { 1.f, 2.f }; + constexpr float src2[] = { 3.f, 4.f, 5.f }; + + auto arr1 = array::wrap(src1, 2l); + auto arr2 = array::wrap(src2, 3l); + + chunked_array chunked1(2); + chunked1.set_chunk(0l, arr1); + chunked1.set_chunk(1l, arr2); + ONEDAL_ASSERT(chunked1.get_count() == 5l); + + chunked_array chunked2(2); + chunked2.set_chunk(0l, arr2); + chunked2.set_chunk(1l, arr1); + ONEDAL_ASSERT(chunked2.get_count() == 5l); + + auto table = heterogen_table::wrap( // + chunked1, + chunked2); + + auto dt = backend::interop::convert_to_daal_table(table); + REQUIRE(dynamic_cast(dt.get()) != nullptr); +} + TEST("CSR adapter is used, one-based indexing") { const float data[] = { 1.0f, 2.0f, 3.0f, 4.0f, 1.0f, 11.0f, 8.0f }; const std::int64_t column_indices[] = { 1, 2, 4, 3, 2, 4, 2 };