From 776c9dfeea692f8beda5b4dfcb8a532a2d44eae2 Mon Sep 17 00:00:00 2001 From: antonio-decaro Date: Tue, 1 Jul 2025 19:56:16 +0000 Subject: [PATCH 01/69] feat: add bitset and frontier classes with atomic operations and tests --- cpp/oneapi/dal/backend/primitives/bitset.hpp | 1 + .../dal/backend/primitives/bitset/bitset.hpp | 112 ++++++++++++++++++ .../dal/backend/primitives/frontier.hpp | 1 + .../dal/backend/primitives/frontier/BUILD | 29 +++++ .../primitives/frontier/frontier_dpc.hpp | 105 ++++++++++++++++ .../frontier/test/basic_frontier_ops_dpc.cpp | 21 ++++ .../primitives/frontier/test/frontier.hpp | 43 +++++++ 7 files changed, 312 insertions(+) create mode 100644 cpp/oneapi/dal/backend/primitives/bitset.hpp create mode 100644 cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp create mode 100644 cpp/oneapi/dal/backend/primitives/frontier.hpp create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/BUILD create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp diff --git a/cpp/oneapi/dal/backend/primitives/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset.hpp new file mode 100644 index 00000000000..905603885cb --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/bitset.hpp @@ -0,0 +1 @@ +#include "oneapi/dal/backend/primitives/bitset/bitset.hpp" \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp new file mode 100644 index 00000000000..453fd35ec1e --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -0,0 +1,112 @@ +#include "oneapi/dal/backend/memory.hpp" + +namespace oneapi::dal::backend::primitives { + +/** + * @brief A bitset class that provides a set of operations on a bitset. + */ +template +class bitset { +public: + using element_t = ElementType; + static constexpr size_t element_bitsize = sizeof(element_t) * 8; // Number of bits in an element + + bitset(element_t* data) : _data(data) {} + + /// Sets the bit at the specified index to 1. + inline void set(std::uint32_t index) { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + _data[element_index] |= (element_t(1) << bit_index); + } + + /// Clears the bit at the specified index to 0. + inline void clear(std::uint32_t index) { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + _data[element_index] &= ~(element_t(1) << bit_index); + } + + /// Checks if the bit at the specified index is set. + inline bool test(std::uint32_t index) const { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + return (_data[element_index] & (element_t(1) << bit_index)) != 0; + } + + inline bool gas(std::uint32_t index) const { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + bool set = (_data[element_index] & (element_t(1) << bit_index)) != 0; + if (!set) { + _data[element_index] &= ~(element_t(1) << bit_index); // Clear + } + return set; + } + + /// Sets the bit at the specified index using atomic operations. + template + inline void atomic_set(std::uint32_t index) const { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + sycl::atomic_ref + atomic_element(_data[element_index]); + atomic_element.fetch_or(element_t(1) << bit_index); + } + + /// Clears the bit at the specified index using atomic operations. + template + inline void atomic_clear(std::uint32_t index) { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + sycl::atomic_ref + atomic_element(_data[element_index]); + atomic_element.fetch_and(~(element_t(1) << bit_index)); + } + + /// Checks if the bit at the specified index is set using atomic operations. + template + inline bool atomic_test(std::uint32_t index) const { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + sycl::atomic_ref + atomic_element(_data[element_index]); + return (atomic_element.load() & (element_t(1) << bit_index)) != 0; + } + + template + inline bool atomic_gas(std::uint32_t index) const { + const auto element_index = index / element_bitsize; + const auto bit_index = index % element_bitsize; + sycl::atomic_ref + atomic_element(_data[element_index]); + bool set = (atomic_element.load() & (element_t(1) << bit_index)) != 0; + if (!set) { + atomic_element.fetch_and(~(element_t(1) << bit_index)); // Clear + } + return set; + } + + /// Returns the pointer to the underlying data. + inline element_t* get_data() { + return _data; + } + + inline void set_data(element_t* data) { + _data = data; + } + + /// Returns the pointer to the underlying data (const version). + inline const element_t* get_data() const { + return _data; + } + +private: + element_t* _data; +}; + +} // namespace oneapi::dal::backend::primitives \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier.hpp new file mode 100644 index 00000000000..0ce734a968e --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier.hpp @@ -0,0 +1 @@ +#include "oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp" \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD new file mode 100644 index 00000000000..d39a3708bcb --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -0,0 +1,29 @@ +package(default_visibility = ["//visibility:public"]) +load("@onedal//dev/bazel:dal.bzl", + "dal_module", + "dal_test_suite", +) + +dal_module ( + name = "frontier", + auto = True +) + +dal_test_suite ( + name = "tests", + framework = "catch2", + compile_as = [ "dpc++" ], + private = True, + hdrs = glob([ + "test/*.hpp", + ]), + srcs = glob([ + "test/*_dpc.cpp", + ], exclude=[ + "test/*perf*.cpp", + ]), + dal_deps = [ + ":frontier", + "@onedal//cpp/oneapi/dal/backend/primitives:rng", + ], +) \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp new file mode 100644 index 00000000000..618e9328192 --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -0,0 +1,105 @@ +#pragma once + +#include "oneapi/dal/common.hpp" +#include "oneapi/dal/graph/detail/common.hpp" +#include "oneapi/dal/graph/detail/container.hpp" +#include "oneapi/dal/backend/primitives/bitset.hpp" +#include "oneapi/dal/backend/primitives/ndarray.hpp" + +namespace oneapi::dal::backend::primitives { + +template +struct frontier_view { + using bitmap_t = ElementType; + static constexpr std::size_t divide_factor = bitset::element_bitsize; + + frontier_view() = default; + frontier_view(bitmap_t* data_layer, + bitmap_t* mlb_layer, + std::uint32_t* offsets, + std::uint32_t* offsets_size, + size_t num_items) + : _num_items(num_items), + _data_layer(data_layer), + _mlb_layer(mlb_layer), + _offsets(offsets), + _offsets_size(offsets_size) {} + + inline void insert(std::uint32_t idx) const { + if (_mlb_layer.atomic_gas(static_cast(idx / divide_factor))) { + _data_layer.atomic_set(idx); + } + } + + inline void remove(std::uint32_t idx) const { + throw dal::domain_error("Frontier does not support remove operation"); + } + + inline bool check(std::uint32_t idx) const { + return _data_layer.atomic_test(idx); + } + + size_t _num_items; + + bitset _data_layer; + bitset _mlb_layer; + + std::uint32_t* _offsets; + std::uint32_t* _offsets_size; +}; + +template +class frontier { + using bitmap_t = ElementType; + +public: + frontier(sycl::queue& queue, std::size_t num_items) : _queue(queue) { + auto array_size = + (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; + auto mlb_size = (array_size + bitset::element_bitsize - 1) / + bitset::element_bitsize; + _data_layer = ndarray::empty(queue, + { static_cast(array_size) }, + sycl::usm::alloc::shared); + _mlb_layer = ndarray::empty(queue, + { static_cast(mlb_size) }, + sycl::usm::alloc::shared); + _offsets = ndarray::empty( + queue, + { static_cast(mlb_size + 1) }, + sycl::usm::alloc::shared); /// First offset is to keep the size of the frontier + } + + frontier_view get_device_view() { + return frontier_view(this->get_data_layer(), + this->get_mlb_layer(), + this->get_offsets(), + this->get_offsets_size(), + _data_layer.get_count()); + } + + bitmap_t* get_data_layer() { + return _data_layer.get_mutable_data(); + } + + bitmap_t* get_mlb_layer() { + return _mlb_layer.get_mutable_data(); + } + + std::uint32_t* get_offsets() { + return _offsets.get_mutable_data() + 1; + } + + std::uint32_t* get_offsets_size() { + return _offsets.get_mutable_data(); + } + +private: + sycl::queue& _queue; + + ndarray _data_layer; + ndarray _mlb_layer; + ndarray _offsets; +}; + +} // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp new file mode 100644 index 00000000000..9d5645d687f --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -0,0 +1,21 @@ +#include "oneapi/dal/backend/primitives/frontier.hpp" + +#include "oneapi/dal/test/engine/common.hpp" +#include "oneapi/dal/test/engine/fixtures.hpp" +#include "oneapi/dal/test/engine/dataframe.hpp" + +namespace oneapi::dal::backend::primitives::test { + +TEST("frontier can be created", "[frontier]") { + sycl::queue queue{ sycl::default_selector_v }; + + const std::size_t num_items = 100; + REQUIRE(num_items > 0); + // auto f = frontier(queue, num_items); + + // auto view = f.get_device_view(); + // view.insert(0); + +} // TEST + +} // namespace oneapi::dal::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp new file mode 100644 index 00000000000..3c6b3bed9bd --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp @@ -0,0 +1,43 @@ +#include "oneapi/dal/backend/primitives/frontier.hpp" + +#include "oneapi/dal/test/engine/common.hpp" +#include "oneapi/dal/test/engine/fixtures.hpp" +#include "oneapi/dal/test/engine/dataframe.hpp" + +namespace oneapi::dal::backend::primitives::test { + +template +class frontier_test + : public oneapi::dal::test::engine::float_algo_fixture> { +public: + using float_t = std::tuple_element_t<0, Param>; + + void generate_input(std::int64_t n = -1, std::int64_t p = -1) { + if (n == -1 || p == -1) { + this->n_ = GENERATE(7, 827, 13, 216); + this->p_ = GENERATE(4, 17, 41, 256); + } + else { + this->n_ = n; + this->p_ = p; + } + const auto dataframe = GENERATE_DATAFRAME( + oneapi::dal::test::engine::dataframe_builder{ n_, p_ }.fill_uniform(-0.5, 0.5)); + this->data_ = dataframe.get_table(this->get_homogen_table_id()); + } + + void measure_time() { + // Implement the performance measurement logic here + } +}; + +TEMPLATE_LIST_TEST_M(frontier_test, + "frontier test", + "[frontier]", + oneapi::dal::test::engine::float_types) { + SKIP_IF(this->not_float64_friendly()); + this->generate_input(); + this->measure_time(); +} + +} // namespace oneapi::dal::backend::primitives::test From cb957e8e17caf8e51de139b01fcacb304e30d165 Mon Sep 17 00:00:00 2001 From: antonio-decaro Date: Mon, 7 Jul 2025 12:39:38 +0000 Subject: [PATCH 02/69] feat: enhance frontier class with additional operations and tests; remove obsolete test header --- .../dal/backend/primitives/bitset/bitset.hpp | 32 +++---- .../dal/backend/primitives/frontier/BUILD | 6 +- .../primitives/frontier/frontier_dpc.hpp | 76 +++++++++++++--- .../frontier/test/basic_frontier_ops_dpc.cpp | 89 +++++++++++++++++-- .../primitives/frontier/test/frontier.hpp | 43 --------- 5 files changed, 165 insertions(+), 81 deletions(-) delete mode 100644 cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp index 453fd35ec1e..110bdaba70a 100644 --- a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -15,28 +15,28 @@ class bitset { /// Sets the bit at the specified index to 1. inline void set(std::uint32_t index) { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; _data[element_index] |= (element_t(1) << bit_index); } /// Clears the bit at the specified index to 0. inline void clear(std::uint32_t index) { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; _data[element_index] &= ~(element_t(1) << bit_index); } /// Checks if the bit at the specified index is set. inline bool test(std::uint32_t index) const { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; return (_data[element_index] & (element_t(1) << bit_index)) != 0; } inline bool gas(std::uint32_t index) const { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; bool set = (_data[element_index] & (element_t(1) << bit_index)) != 0; if (!set) { _data[element_index] &= ~(element_t(1) << bit_index); // Clear @@ -48,8 +48,8 @@ class bitset { template inline void atomic_set(std::uint32_t index) const { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; sycl::atomic_ref atomic_element(_data[element_index]); atomic_element.fetch_or(element_t(1) << bit_index); @@ -59,8 +59,8 @@ class bitset { template inline void atomic_clear(std::uint32_t index) { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; sycl::atomic_ref atomic_element(_data[element_index]); atomic_element.fetch_and(~(element_t(1) << bit_index)); @@ -70,8 +70,8 @@ class bitset { template inline bool atomic_test(std::uint32_t index) const { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; sycl::atomic_ref atomic_element(_data[element_index]); return (atomic_element.load() & (element_t(1) << bit_index)) != 0; @@ -80,8 +80,8 @@ class bitset { template inline bool atomic_gas(std::uint32_t index) const { - const auto element_index = index / element_bitsize; - const auto bit_index = index % element_bitsize; + element_t element_index = index / element_bitsize; + element_t bit_index = index % element_bitsize; sycl::atomic_ref atomic_element(_data[element_index]); bool set = (atomic_element.load() & (element_t(1) << bit_index)) != 0; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD index d39a3708bcb..394618090e5 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/BUILD +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -14,9 +14,9 @@ dal_test_suite ( framework = "catch2", compile_as = [ "dpc++" ], private = True, - hdrs = glob([ - "test/*.hpp", - ]), + # hdrs = glob([ + # "test/*.hpp", + # ]), srcs = glob([ "test/*_dpc.cpp", ], exclude=[ diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 618e9328192..7826f7a82d6 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -26,9 +26,12 @@ struct frontier_view { _offsets_size(offsets_size) {} inline void insert(std::uint32_t idx) const { - if (_mlb_layer.atomic_gas(static_cast(idx / divide_factor))) { + if (!_data_layer.test(idx)) { _data_layer.atomic_set(idx); } + if (!_mlb_layer.test(idx / divide_factor)) { + _mlb_layer.atomic_set(idx / divide_factor); + }; } inline void remove(std::uint32_t idx) const { @@ -48,7 +51,7 @@ struct frontier_view { std::uint32_t* _offsets_size; }; -template +template class frontier { using bitmap_t = ElementType; @@ -58,16 +61,23 @@ class frontier { (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; auto mlb_size = (array_size + bitset::element_bitsize - 1) / bitset::element_bitsize; - _data_layer = ndarray::empty(queue, - { static_cast(array_size) }, - sycl::usm::alloc::shared); - _mlb_layer = ndarray::empty(queue, - { static_cast(mlb_size) }, - sycl::usm::alloc::shared); - _offsets = ndarray::empty( + auto [data_layer, e1] = + ndarray::zeros(queue, { static_cast(array_size) }, Alloc); + auto [mlb_layer, e2] = + ndarray::zeros(queue, { static_cast(mlb_size) }, Alloc); + auto [offsets, e3] = ndarray::zeros( queue, { static_cast(mlb_size + 1) }, sycl::usm::alloc::shared); /// First offset is to keep the size of the frontier + _buffer = ndarray::empty(queue, { static_cast(10) }, Alloc); + + e1.wait_and_throw(); + e2.wait_and_throw(); + e3.wait_and_throw(); + + _data_layer = std::move(data_layer); + _mlb_layer = std::move(mlb_layer); + _offsets = std::move(offsets); } frontier_view get_device_view() { @@ -78,28 +88,68 @@ class frontier { _data_layer.get_count()); } - bitmap_t* get_data_layer() { + bitmap_t* get_data_layer() const { return _data_layer.get_mutable_data(); } - bitmap_t* get_mlb_layer() { + size_t get_data_layer_size() const { + return _data_layer.get_count(); + } + + size_t get_mlb_layer_size() const { + return _mlb_layer.get_count(); + } + + bitmap_t* get_mlb_layer() const { return _mlb_layer.get_mutable_data(); } - std::uint32_t* get_offsets() { + std::uint32_t* get_offsets() const { return _offsets.get_mutable_data() + 1; } - std::uint32_t* get_offsets_size() { + std::uint32_t* get_offsets_size() const { return _offsets.get_mutable_data(); } + bool empty() const { + auto empty_buff = _buffer.slice(0, 1); + fill(_queue, empty_buff, bitmap_t(0)).wait(); + auto empty_buff_ptr = empty_buff.get_mutable_data(); + + auto e = _queue.submit([&](sycl::handler& cgh) { + const auto range = make_range_1d(_mlb_layer.get_count()); + auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); + auto* f_ptr = this->get_mlb_layer(); + + cgh.parallel_for(range, sum_reduction, [=](sycl::id<1> idx, auto& sum_v) { + sum_v += f_ptr[idx]; + }); + }); + e.wait_and_throw(); + auto empty_sum = empty_buff.at_device(_queue, 0, { e }); + return empty_sum == 0; + } + + void insert(bitmap_t idx) { + if (idx >= _data_layer.get_count() * bitset::element_bitsize) { + throw dal::domain_error("Index is out of range"); + } + auto view = this->get_device_view(); + _queue + .single_task([=]() { + view.insert(idx); + }) + .wait(); + } + private: sycl::queue& _queue; ndarray _data_layer; ndarray _mlb_layer; ndarray _offsets; + ndarray _buffer; }; } // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp index 9d5645d687f..d5f900dcc19 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -4,18 +4,95 @@ #include "oneapi/dal/test/engine/fixtures.hpp" #include "oneapi/dal/test/engine/dataframe.hpp" +#include "oneapi/dal/test/engine/common.hpp" +#include "oneapi/dal/test/engine/fixtures.hpp" +#include "oneapi/dal/test/engine/dataframe.hpp" + namespace oneapi::dal::backend::primitives::test { -TEST("frontier can be created", "[frontier]") { +TEST("frontier basic operations", "[frontier]") { sycl::queue queue{ sycl::default_selector_v }; const std::size_t num_items = 100; - REQUIRE(num_items > 0); - // auto f = frontier(queue, num_items); + auto f = frontier(queue, num_items); + auto view = f.get_device_view(); + size_t expected_data_layer_size = (num_items + bitset::element_bitsize - 1) / + bitset::element_bitsize; + size_t expected_mlb_layer_size = + (expected_data_layer_size + bitset::element_bitsize - 1) / + bitset::element_bitsize; + + SECTION("frontier has correct data layer size", "[frontier]") { + REQUIRE(f.get_data_layer_size() == expected_data_layer_size); + + REQUIRE(f.get_mlb_layer_size() == expected_mlb_layer_size); + } + + SECTION("frontier can insert elements", "[frontier]") { + view.insert(0); + view.insert(2); + view.insert(bitset::element_bitsize); + + auto data_layer = f.get_data_layer(); + auto mlb_layer = f.get_mlb_layer(); + + std::cout << "Data layer size: " << data_layer[0] << std::endl; + std::cout << "MLB layer size: " << mlb_layer[0] << std::endl; + + REQUIRE(data_layer[0] == static_cast(5)); + REQUIRE(data_layer[1] == static_cast(1)); + REQUIRE(mlb_layer[0] == static_cast(3)); + } + + SECTION("frontier can check elements", "[frontier]") { + view.insert(0); + view.insert(2); + view.insert(32); + view.insert(64); + + REQUIRE(view.check(0) == true); + REQUIRE(view.check(1) == false); + REQUIRE(view.check(2) == true); + REQUIRE(view.check(3) == false); + REQUIRE(view.check(31) == false); + REQUIRE(view.check(32) == true); + REQUIRE(view.check(33) == false); + REQUIRE(view.check(63) == false); + REQUIRE(view.check(64) == true); + REQUIRE(view.check(65) == false); + } + +} // TEST "frontier basic operations" + +TEST("frontier queue operations", "[frontier]") { + sycl::queue queue{ sycl::default_selector_v }; + + const std::size_t num_items = 100; + auto f = frontier(queue, num_items); + + SECTION("empty function", "[frontier]") { + REQUIRE(f.empty() == true); + auto view = f.get_device_view(); + view.insert(0); + REQUIRE(f.empty() == false); + } + + SECTION("insert function", "[frontier]") { + f.insert(0); + f.insert(2); + f.insert(bitset::element_bitsize); + + auto data_layer = f.get_data_layer(); + auto mlb_layer = f.get_mlb_layer(); + + std::cout << "Data layer size: " << data_layer[0] << std::endl; + std::cout << "MLB layer size: " << mlb_layer[0] << std::endl; - // auto view = f.get_device_view(); - // view.insert(0); + REQUIRE(data_layer[0] == static_cast(5)); + REQUIRE(data_layer[1] == static_cast(1)); + REQUIRE(mlb_layer[0] == static_cast(3)); + } -} // TEST +} // TEST "frontier queue operations" } // namespace oneapi::dal::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp deleted file mode 100644 index 3c6b3bed9bd..00000000000 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "oneapi/dal/backend/primitives/frontier.hpp" - -#include "oneapi/dal/test/engine/common.hpp" -#include "oneapi/dal/test/engine/fixtures.hpp" -#include "oneapi/dal/test/engine/dataframe.hpp" - -namespace oneapi::dal::backend::primitives::test { - -template -class frontier_test - : public oneapi::dal::test::engine::float_algo_fixture> { -public: - using float_t = std::tuple_element_t<0, Param>; - - void generate_input(std::int64_t n = -1, std::int64_t p = -1) { - if (n == -1 || p == -1) { - this->n_ = GENERATE(7, 827, 13, 216); - this->p_ = GENERATE(4, 17, 41, 256); - } - else { - this->n_ = n; - this->p_ = p; - } - const auto dataframe = GENERATE_DATAFRAME( - oneapi::dal::test::engine::dataframe_builder{ n_, p_ }.fill_uniform(-0.5, 0.5)); - this->data_ = dataframe.get_table(this->get_homogen_table_id()); - } - - void measure_time() { - // Implement the performance measurement logic here - } -}; - -TEMPLATE_LIST_TEST_M(frontier_test, - "frontier test", - "[frontier]", - oneapi::dal::test::engine::float_types) { - SKIP_IF(this->not_float64_friendly()); - this->generate_input(); - this->measure_time(); -} - -} // namespace oneapi::dal::backend::primitives::test From 10d8a3db7b6683e33752a9d76ac51d4c8ad5e3cc Mon Sep 17 00:00:00 2001 From: antonio-decaro Date: Mon, 7 Jul 2025 13:03:06 +0000 Subject: [PATCH 03/69] feat: enhance frontier class with additional methods and tests for check and clear operations --- .../primitives/frontier/frontier_dpc.hpp | 64 ++++++++++++++----- .../frontier/test/basic_frontier_ops_dpc.cpp | 20 ++++-- 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 7826f7a82d6..8708b859b66 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -54,9 +54,10 @@ struct frontier_view { template class frontier { using bitmap_t = ElementType; + using buffer_t = std::uint32_t; public: - frontier(sycl::queue& queue, std::size_t num_items) : _queue(queue) { + frontier(sycl::queue& queue, std::size_t num_items) : _queue(queue), _num_items(num_items) { auto array_size = (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; auto mlb_size = (array_size + bitset::element_bitsize - 1) / @@ -80,11 +81,14 @@ class frontier { _offsets = std::move(offsets); } - frontier_view get_device_view() { + frontier_view get_device_view() const { + auto offsets_size_pointer = _offsets.get_mutable_data(); + auto offsets_pointer = _offsets.get_mutable_data() + 1; + return frontier_view(this->get_data_layer(), this->get_mlb_layer(), - this->get_offsets(), - this->get_offsets_size(), + offsets_pointer, + offsets_size_pointer, _data_layer.get_count()); } @@ -92,6 +96,14 @@ class frontier { return _data_layer.get_mutable_data(); } + bitmap_t* get_mlb_layer() const { + return _mlb_layer.get_mutable_data(); + } + + std::uint32_t* get_offsets() const { + return _offsets.get_mutable_data() + 1; + } + size_t get_data_layer_size() const { return _data_layer.get_count(); } @@ -100,21 +112,17 @@ class frontier { return _mlb_layer.get_count(); } - bitmap_t* get_mlb_layer() const { - return _mlb_layer.get_mutable_data(); - } - - std::uint32_t* get_offsets() const { - return _offsets.get_mutable_data() + 1; + size_t get_offsets_size() const { + return _offsets.get_count() - 1; } - std::uint32_t* get_offsets_size() const { - return _offsets.get_mutable_data(); + size_t get_num_items() const { + return _num_items; } bool empty() const { auto empty_buff = _buffer.slice(0, 1); - fill(_queue, empty_buff, bitmap_t(0)).wait(); + fill(_queue, empty_buff, buffer_t(0)).wait(); auto empty_buff_ptr = empty_buff.get_mutable_data(); auto e = _queue.submit([&](sycl::handler& cgh) { @@ -140,16 +148,42 @@ class frontier { .single_task([=]() { view.insert(idx); }) - .wait(); + .wait_and_throw(); + } + + bool check(bitmap_t idx) const { + auto check_buff = _buffer.slice(0, 1); + fill(_queue, check_buff, buffer_t(0)).wait(); + auto check_buff_ptr = check_buff.get_mutable_data(); + + auto e = _queue.submit([&](sycl::handler& cgh) { + auto view = this->get_device_view(); + + cgh.single_task([=]() { + check_buff_ptr[0] = view.check(idx) ? buffer_t(1) : buffer_t(0); + }); + }); + auto check_res = check_buff.at_device(_queue, 0, { e }); + return check_res == buffer_t(1); + } + + void clear() { + auto e = fill(_queue, _data_layer, bitmap_t(0)); + auto e1 = fill(_queue, _mlb_layer, bitmap_t(0)); + auto e2 = fill(_queue, _offsets, buffer_t(0)); + e.wait_and_throw(); + e1.wait_and_throw(); + e2.wait_and_throw(); } private: sycl::queue& _queue; + size_t _num_items; ndarray _data_layer; ndarray _mlb_layer; ndarray _offsets; - ndarray _buffer; + ndarray _buffer; }; } // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp index d5f900dcc19..6439a67ad9f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -36,9 +36,6 @@ TEST("frontier basic operations", "[frontier]") { auto data_layer = f.get_data_layer(); auto mlb_layer = f.get_mlb_layer(); - std::cout << "Data layer size: " << data_layer[0] << std::endl; - std::cout << "MLB layer size: " << mlb_layer[0] << std::endl; - REQUIRE(data_layer[0] == static_cast(5)); REQUIRE(data_layer[1] == static_cast(1)); REQUIRE(mlb_layer[0] == static_cast(3)); @@ -64,7 +61,7 @@ TEST("frontier basic operations", "[frontier]") { } // TEST "frontier basic operations" -TEST("frontier queue operations", "[frontier]") { +TEST("frontier queue basic operations", "[frontier]") { sycl::queue queue{ sycl::default_selector_v }; const std::size_t num_items = 100; @@ -93,6 +90,21 @@ TEST("frontier queue operations", "[frontier]") { REQUIRE(mlb_layer[0] == static_cast(3)); } + SECTION("check function", "[frontier]") { + f.insert(0); + REQUIRE(f.check(0) == true); + REQUIRE(f.check(1) == false); + } + + SECTION("clear function", "[frontier]") { + f.insert(0); + f.insert(2); + f.insert(bitset::element_bitsize); + REQUIRE(f.empty() == false); + f.clear(); + REQUIRE(f.empty() == true); + } + } // TEST "frontier queue operations" } // namespace oneapi::dal::backend::primitives::test From 05152471999798405070fe96d34e119168cef36e Mon Sep 17 00:00:00 2001 From: antonio-decaro Date: Tue, 8 Jul 2025 14:04:53 +0000 Subject: [PATCH 04/69] insert compunte active kernel --- .../dal/backend/primitives/bitset/bitset.hpp | 5 + .../primitives/frontier/frontier_dpc.hpp | 127 +++++++++++++++--- .../frontier/test/basic_frontier_ops_dpc.cpp | 36 +++-- 3 files changed, 141 insertions(+), 27 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp index 110bdaba70a..96d252ab674 100644 --- a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -105,6 +105,11 @@ class bitset { return _data; } + /// override operator [] + inline element_t& operator[](std::size_t index) { + return _data[index]; + } + private: element_t* _data; }; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 8708b859b66..e18890fd6dd 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -68,7 +68,7 @@ class frontier { ndarray::zeros(queue, { static_cast(mlb_size) }, Alloc); auto [offsets, e3] = ndarray::zeros( queue, - { static_cast(mlb_size + 1) }, + { static_cast(array_size + 1) }, sycl::usm::alloc::shared); /// First offset is to keep the size of the frontier _buffer = ndarray::empty(queue, { static_cast(10) }, Alloc); @@ -85,39 +85,35 @@ class frontier { auto offsets_size_pointer = _offsets.get_mutable_data(); auto offsets_pointer = _offsets.get_mutable_data() + 1; - return frontier_view(this->get_data_layer(), - this->get_mlb_layer(), + return frontier_view(this->get_data_ptr(), + this->get_mlb_ptr(), offsets_pointer, offsets_size_pointer, _data_layer.get_count()); } - bitmap_t* get_data_layer() const { + inline bitmap_t* get_data_ptr() const { return _data_layer.get_mutable_data(); } - bitmap_t* get_mlb_layer() const { + inline bitmap_t* get_mlb_ptr() const { return _mlb_layer.get_mutable_data(); } - std::uint32_t* get_offsets() const { - return _offsets.get_mutable_data() + 1; + inline std::uint32_t* get_offsets_ptr() const { + return &_offsets.get_mutable_data()[1]; } - size_t get_data_layer_size() const { - return _data_layer.get_count(); + inline std::uint32_t* get_offsets_size_ptr() const { + return _offsets.get_mutable_data(); } - size_t get_mlb_layer_size() const { - return _mlb_layer.get_count(); - } - - size_t get_offsets_size() const { - return _offsets.get_count() - 1; + inline size_t get_data_size() const { + return _data_layer.get_count(); } - size_t get_num_items() const { - return _num_items; + inline size_t get_mlb_size() const { + return _mlb_layer.get_count(); } bool empty() const { @@ -128,7 +124,7 @@ class frontier { auto e = _queue.submit([&](sycl::handler& cgh) { const auto range = make_range_1d(_mlb_layer.get_count()); auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); - auto* f_ptr = this->get_mlb_layer(); + auto* f_ptr = this->get_mlb_ptr(); cgh.parallel_for(range, sum_reduction, [=](sycl::id<1> idx, auto& sum_v) { sum_v += f_ptr[idx]; @@ -176,6 +172,101 @@ class frontier { e2.wait_and_throw(); } + sycl::event compute_active_frontier() const { + auto bitmap = this->get_device_view(); + + uint32_t range = decltype(bitmap._mlb_layer)::element_bitsize; + size_t local_range = 1024; // Adjust as needed + size_t global_range = + _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); + + bool use_local_mem = + device_local_mem_size(this->_queue) >= (local_range * range * sizeof(uint32_t)); + + auto e = this->_queue.submit([&](sycl::handler& cgh) { + sycl::local_accessor local_offsets(local_range * range, cgh); + sycl::local_accessor local_size(1, cgh); + + if (use_local_mem) { + cgh.parallel_for( + make_multiple_nd_range_1d(global_range, local_range), + [=, + offsets = this->get_offsets_ptr(), + offsets_size = this->get_offsets_size_ptr(), + data_layer = this->get_mlb_ptr(), + size = this->_num_items](sycl::nd_item<1> item) { + if (offsets_size[0] > 0) { + return; + } + + auto group = item.get_group(); + sycl::atomic_ref + local_size_ref{ local_size[0] }; + sycl::atomic_ref + offsets_size_ref{ offsets_size[0] }; + + if (group.leader()) { + local_size_ref.store(0); + } + sycl::group_barrier(group); + for (uint32_t gid = item.get_global_linear_id(); gid < size; + gid += local_range) { + bitmap_t data = data_layer[gid]; + for (size_t i = 0; i < range; i++) { + if (data & (static_cast(1) << i)) { + local_offsets[local_size_ref++] = i + gid * range; + } + } + } + + sycl::group_barrier(group); + + size_t data_offset = 0; + if (group.leader()) { + data_offset = offsets_size_ref.fetch_add(local_size_ref.load()); + } + data_offset = sycl::group_broadcast(group, data_offset, 0); + for (size_t i = item.get_local_linear_id(); i < local_size_ref.load(); + i += item.get_local_range(0)) { + offsets[data_offset + i] = local_offsets[i]; + } + }); + } + else { + cgh.parallel_for(make_multiple_nd_range_1d(global_range, 256), + [=, + offsets = this->get_offsets_ptr(), + offsets_size = this->get_offsets_size_ptr(), + data_layer = this->get_mlb_ptr(), + size = this->_num_items](sycl::nd_item<1> item) { + if (offsets_size[0] > 0) { + return; + } + + sycl::atomic_ref + offsets_size_ref{ offsets_size[0] }; + auto gid = item.get_global_linear_id(); + if (gid >= size) + return; + + bitmap_t data = data_layer[gid]; + for (size_t i = 0; i < range; i++) { + if (data & (static_cast(1) << i)) { + offsets[offsets_size_ref++] = i + gid * range; + } + } + }); + } + }); + return e; + } + private: sycl::queue& _queue; size_t _num_items; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp index 6439a67ad9f..026f6bcf728 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -23,9 +23,9 @@ TEST("frontier basic operations", "[frontier]") { bitset::element_bitsize; SECTION("frontier has correct data layer size", "[frontier]") { - REQUIRE(f.get_data_layer_size() == expected_data_layer_size); + REQUIRE(f.get_data_size() == expected_data_layer_size); - REQUIRE(f.get_mlb_layer_size() == expected_mlb_layer_size); + REQUIRE(f.get_mlb_size() == expected_mlb_layer_size); } SECTION("frontier can insert elements", "[frontier]") { @@ -33,8 +33,8 @@ TEST("frontier basic operations", "[frontier]") { view.insert(2); view.insert(bitset::element_bitsize); - auto data_layer = f.get_data_layer(); - auto mlb_layer = f.get_mlb_layer(); + auto data_layer = f.get_data_ptr(); + auto mlb_layer = f.get_mlb_ptr(); REQUIRE(data_layer[0] == static_cast(5)); REQUIRE(data_layer[1] == static_cast(1)); @@ -79,11 +79,8 @@ TEST("frontier queue basic operations", "[frontier]") { f.insert(2); f.insert(bitset::element_bitsize); - auto data_layer = f.get_data_layer(); - auto mlb_layer = f.get_mlb_layer(); - - std::cout << "Data layer size: " << data_layer[0] << std::endl; - std::cout << "MLB layer size: " << mlb_layer[0] << std::endl; + auto data_layer = f.get_data_ptr(); + auto mlb_layer = f.get_mlb_ptr(); REQUIRE(data_layer[0] == static_cast(5)); REQUIRE(data_layer[1] == static_cast(1)); @@ -107,4 +104,25 @@ TEST("frontier queue basic operations", "[frontier]") { } // TEST "frontier queue operations" +TEST("compute active frontier", "[frontier]") { + sycl::queue queue{ sycl::default_selector_v }; + + const std::size_t num_items = 100000; + auto f = frontier(queue, num_items); + auto view = f.get_device_view(); + + view.insert(0); + view.insert(2); + view.insert(32); + view.insert(1024); + + auto e = f.compute_active_frontier(); + e.wait(); + + // auto offsets = f.get_offsets_ptr(); + auto offsets_size = f.get_offsets_size_ptr(); + + REQUIRE(offsets_size[0] == 2); +} // TEST "compute active frontier" + } // namespace oneapi::dal::backend::primitives::test From c4149fef01459b534665e721e860e19ba0d3b5a4 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 9 Jul 2025 14:18:46 +0200 Subject: [PATCH 05/69] add compute active frontier operation --- .../primitives/frontier/frontier_dpc.hpp | 133 ++++++++++-------- .../frontier/test/basic_frontier_ops_dpc.cpp | 15 +- 2 files changed, 84 insertions(+), 64 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index e18890fd6dd..403a11267fa 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -42,6 +42,18 @@ struct frontier_view { return _data_layer.atomic_test(idx); } + inline size_t get_element_bitsize() const { + return bitset::element_bitsize; + } + + inline std::uint32_t* get_offsets() const { + return _offsets_size; + } + + inline std::uint32_t* get_offsets_size() const { + return _offsets; + } + size_t _num_items; bitset _data_layer; @@ -66,10 +78,8 @@ class frontier { ndarray::zeros(queue, { static_cast(array_size) }, Alloc); auto [mlb_layer, e2] = ndarray::zeros(queue, { static_cast(mlb_size) }, Alloc); - auto [offsets, e3] = ndarray::zeros( - queue, - { static_cast(array_size + 1) }, - sycl::usm::alloc::shared); /// First offset is to keep the size of the frontier + auto [offsets, e3] = + ndarray::zeros(queue, { static_cast(array_size + 1) }, Alloc); /// First offset is to keep the size of the frontier _buffer = ndarray::empty(queue, { static_cast(10) }, Alloc); e1.wait_and_throw(); @@ -101,7 +111,7 @@ class frontier { } inline std::uint32_t* get_offsets_ptr() const { - return &_offsets.get_mutable_data()[1]; + return &(_offsets.get_mutable_data()[1]); } inline std::uint32_t* get_offsets_size_ptr() const { @@ -175,96 +185,101 @@ class frontier { sycl::event compute_active_frontier() const { auto bitmap = this->get_device_view(); - uint32_t range = decltype(bitmap._mlb_layer)::element_bitsize; + uint32_t element_bitsize = decltype(bitmap._mlb_layer)::element_bitsize; size_t local_range = 1024; // Adjust as needed size_t global_range = _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); bool use_local_mem = - device_local_mem_size(this->_queue) >= (local_range * range * sizeof(uint32_t)); + device_local_mem_size(this->_queue) >= (local_range * element_bitsize * sizeof(uint32_t)); - auto e = this->_queue.submit([&](sycl::handler& cgh) { - sycl::local_accessor local_offsets(local_range * range, cgh); - sycl::local_accessor local_size(1, cgh); + auto e0 = _queue.submit([&](sycl::handler& cgh) { + cgh.single_task([=, offsets_size = this->get_offsets_size_ptr(), buffer_ptr = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG]() { + buffer_ptr[CAF_FLAG] = offsets_size[0] == 0 ? 1 : 0; + }); + }); - if (use_local_mem) { - cgh.parallel_for( - make_multiple_nd_range_1d(global_range, local_range), + auto e1 = this->_queue.submit([&](sycl::handler& cgh) { + cgh.depends_on(e0); + + if (!use_local_mem || true) { // Force to use global memory for simplicity + cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), [=, - offsets = this->get_offsets_ptr(), - offsets_size = this->get_offsets_size_ptr(), - data_layer = this->get_mlb_ptr(), - size = this->_num_items](sycl::nd_item<1> item) { - if (offsets_size[0] > 0) { - return; + offsets = this->get_offsets_ptr(), + offsets_size = this->get_offsets_size_ptr(), + data_layer = this->get_mlb_ptr(), + buffer = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG](sycl::id<1> idx) { + + if (!buffer[CAF_FLAG]) return; + + sycl::atomic_ref + offsets_size_ref{ offsets_size[0] }; + + bitmap_t data = data_layer[idx]; + for (size_t i = 0; i < element_bitsize; i++) { + if (data & (static_cast(1) << i)) { + offsets[offsets_size_ref++] = i + idx * element_bitsize; + } } + }); + } else { + sycl::local_accessor local_offsets(local_range * element_bitsize, cgh); + sycl::local_accessor local_size(1, cgh); + cgh.parallel_for( + make_multiple_nd_range_1d(global_range, local_range), + [=, + offsets = this->get_offsets_ptr(), + offsets_size = this->get_offsets_size_ptr(), + data_layer = this->get_mlb_ptr(), + size = this->_num_items, + buffer = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { + if (!buffer[CAF_FLAG]) return; + auto group = item.get_group(); sycl::atomic_ref + sycl::memory_order::relaxed, + sycl::memory_scope::work_group> local_size_ref{ local_size[0] }; sycl::atomic_ref + sycl::memory_order::relaxed, + sycl::memory_scope::device> offsets_size_ref{ offsets_size[0] }; - + if (group.leader()) { local_size_ref.store(0); } sycl::group_barrier(group); for (uint32_t gid = item.get_global_linear_id(); gid < size; - gid += local_range) { + gid += local_range) { bitmap_t data = data_layer[gid]; - for (size_t i = 0; i < range; i++) { + for (size_t i = 0; i < element_bitsize; i++) { if (data & (static_cast(1) << i)) { - local_offsets[local_size_ref++] = i + gid * range; + local_offsets[local_size_ref++] = i + gid * element_bitsize; } } } - + sycl::group_barrier(group); - + size_t data_offset = 0; if (group.leader()) { data_offset = offsets_size_ref.fetch_add(local_size_ref.load()); } data_offset = sycl::group_broadcast(group, data_offset, 0); for (size_t i = item.get_local_linear_id(); i < local_size_ref.load(); - i += item.get_local_range(0)) { + i += item.get_local_range(0)) { offsets[data_offset + i] = local_offsets[i]; } }); } - else { - cgh.parallel_for(make_multiple_nd_range_1d(global_range, 256), - [=, - offsets = this->get_offsets_ptr(), - offsets_size = this->get_offsets_size_ptr(), - data_layer = this->get_mlb_ptr(), - size = this->_num_items](sycl::nd_item<1> item) { - if (offsets_size[0] > 0) { - return; - } - - sycl::atomic_ref - offsets_size_ref{ offsets_size[0] }; - auto gid = item.get_global_linear_id(); - if (gid >= size) - return; - - bitmap_t data = data_layer[gid]; - for (size_t i = 0; i < range; i++) { - if (data & (static_cast(1) << i)) { - offsets[offsets_size_ref++] = i + gid * range; - } - } - }); - } + }); - return e; + return e1; } private: @@ -275,6 +290,8 @@ class frontier { ndarray _mlb_layer; ndarray _offsets; ndarray _buffer; + const size_t _TMP_VAR = 0; + const size_t _CAF_FLAG = 0; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) }; } // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp index 026f6bcf728..97c99e8b41a 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -11,7 +11,7 @@ namespace oneapi::dal::backend::primitives::test { TEST("frontier basic operations", "[frontier]") { - sycl::queue queue{ sycl::default_selector_v }; + sycl::queue queue{ sycl::cpu_selector_v }; const std::size_t num_items = 100; auto f = frontier(queue, num_items); @@ -62,7 +62,7 @@ TEST("frontier basic operations", "[frontier]") { } // TEST "frontier basic operations" TEST("frontier queue basic operations", "[frontier]") { - sycl::queue queue{ sycl::default_selector_v }; + sycl::queue queue{ sycl::gpu_selector_v }; const std::size_t num_items = 100; auto f = frontier(queue, num_items); @@ -105,7 +105,7 @@ TEST("frontier queue basic operations", "[frontier]") { } // TEST "frontier queue operations" TEST("compute active frontier", "[frontier]") { - sycl::queue queue{ sycl::default_selector_v }; + sycl::queue queue{ sycl::gpu_selector_v }; const std::size_t num_items = 100000; auto f = frontier(queue, num_items); @@ -114,15 +114,18 @@ TEST("compute active frontier", "[frontier]") { view.insert(0); view.insert(2); view.insert(32); - view.insert(1024); + view.insert(33); + view.insert(64); + view.insert(65); + view.insert(95); auto e = f.compute_active_frontier(); e.wait(); - // auto offsets = f.get_offsets_ptr(); auto offsets_size = f.get_offsets_size_ptr(); - REQUIRE(offsets_size[0] == 2); + REQUIRE(offsets_size[0] == 3); + f.clear(); } // TEST "compute active frontier" } // namespace oneapi::dal::backend::primitives::test From 7a12f2c420ea202f9e7fe5b1c1150a377b24708d Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 16 Jul 2025 14:48:53 +0200 Subject: [PATCH 06/69] bug fix --- .../dal/backend/primitives/bitset/bitset.hpp | 4 +- .../primitives/frontier/advance_dpc.hpp | 242 ++++++++++++++++++ .../primitives/frontier/frontier_dpc.hpp | 12 +- .../dal/backend/primitives/frontier/graph.hpp | 0 .../frontier/test/basic_frontier_ops_dpc.cpp | 74 ++++-- 5 files changed, 305 insertions(+), 27 deletions(-) create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/graph.hpp diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp index 96d252ab674..847d1021cbc 100644 --- a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -14,14 +14,14 @@ class bitset { bitset(element_t* data) : _data(data) {} /// Sets the bit at the specified index to 1. - inline void set(std::uint32_t index) { + inline void set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; _data[element_index] |= (element_t(1) << bit_index); } /// Clears the bit at the specified index to 0. - inline void clear(std::uint32_t index) { + inline void clear(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; _data[element_index] &= ~(element_t(1) << bit_index); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp new file mode 100644 index 00000000000..da78687dcb0 --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -0,0 +1,242 @@ +#pragma once + +#include "oneapi/dal/backend/primitives/frontier.hpp" + + +namespace oneapi::dal::backend::primitives { + +struct ContextState { + size_t group_offset; + const uint16_t coarsening_factor; + const uint32_t offsets_size; + const sycl::nd_item<1> item; +}; + +template +struct Context { + size_t limit; + InFrontierDevT in_dev_frontier; + OutFrontierDevT out_dev_frontier; + + Context(size_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) + : limit(limit), in_dev_frontier(in_dev_frontier), out_dev_frontier(out_dev_frontier) {} + + inline ContextState init(sycl::nd_item<1>& item) const { + return { + item.get_group_linear_id(), + static_cast(item.get_local_range(0) / in_dev_frontier.get_element_bitsize()), + in_dev_frontier.get_offsets_size()[0], + item, + }; + } + + inline bool need_to_process(ContextState& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } + + inline void complete_iteration(ContextState& state) const { state.group_offset += state.item.get_group_range(0); } + + inline size_t get_assigned_element(const ContextState& state) const { + const uint16_t bitmap_range = in_dev_frontier.getBitmapRange(); + const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / bitmap_range); + const int* bitmap_offsets = in_dev_frontier.get_offsets(); + // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); + const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * bitmap_range) + (state.item.get_local_linear_id() % bitmap_range); + return assigned_vertex; + } + + inline bool check(const ContextState& state, size_t vertex) const { + return vertex < limit && in_dev_frontier.check(vertex); + + } + + inline void insert(const ContextState& state, size_t vertex) const { + out_dev_frontier.insert(vertex); + } +}; + +template +struct BitmapKernel { + void operator()(sycl::nd_item<1> item) const { + // 0. retrieve global and local ids + const size_t gid = item.get_global_linear_id(); + const size_t lid = item.get_local_linear_id(); + const auto wgroup = item.get_group(); + const auto wgroup_id = item.get_group_linear_id(); + const size_t wgroup_size = wgroup.get_local_range(0); + const auto sgroup = item.get_sub_group(); + const auto sgroup_id = sgroup.get_group_id(); + const size_t sgroup_size = sgroup.get_local_range()[0]; + const size_t llid = sgroup.get_local_linear_id(); + + auto state = context.init(item); + + + while (context.need_to_process(state)) { + const auto assigned_vertex = context.get_assigned_element(state); + + // 1. load number of edges in local memory + if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; } + if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } + + sycl::atomic_ref sg_tail{subgroup_reduce_tail[sgroup_id]}; + sycl::atomic_ref wg_tail{workgroup_reduce_tail[0]}; + + const uint32_t offset = sgroup_id * sgroup_size; + if (context.check(state, assigned_vertex)) { + uint32_t n_edges = graph_dev.getDegree(assigned_vertex); // GRAPH degree of the vertex + if (n_edges >= wgroup_size * wgroup_size) { // assign to the workgroup + uint32_t loc = wg_tail.fetch_add(static_cast(1)); + n_edges_wg[loc] = n_edges; + workgroup_reduce[loc] = assigned_vertex; + workgroup_ids[loc] = lid; + } else if (n_edges >= sgroup_size) { // assign to the subgroup + uint32_t loc = sg_tail.fetch_add(static_cast(1)); + n_edges_sg[offset + loc] = n_edges; + subgroup_reduce[offset + loc] = assigned_vertex; + subgroup_ids[offset + loc] = lid; + } + visited[lid] = false; + } else { + visited[lid] = true; + } + + sycl::group_barrier(wgroup); + for (size_t i = 0; i < wg_tail.load(); i++) { + auto vertex = workgroup_reduce[i]; + size_t n_edges = n_edges_wg[i]; + auto start = graph_dev.begin(vertex); // GRAPH edge iterator + + for (auto j = lid; j < n_edges; j += wgroup_size) { + auto n = start + j; + auto edge = n.getIndex(); // GRAPH edge index + auto weight = graph_dev.getEdgeWeight(edge); // GRAPH edge weight + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } + } + + if (wgroup.leader()) { visited[workgroup_ids[i]] = true; } + } + + sycl::group_barrier(sgroup); + + for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size + size_t vertex_id = offset + i; + auto vertex = subgroup_reduce[vertex_id]; + size_t n_edges = n_edges_sg[vertex_id]; + + auto start = graph_dev.begin(vertex); // GRAPH edge iterator + + for (auto j = llid; j < n_edges; j += sgroup_size) { + auto n = start + j; + auto edge = n.getIndex(); // GRAPH edge index + auto weight = graph_dev.getEdgeWeight(edge); // GRAPH edge weight + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } + } + + if (sgroup.leader()) { visited[subgroup_ids[vertex_id]] = true; } + } + sycl::group_barrier(sgroup); + + if (!visited[lid]) { + auto vertex = assigned_vertex; + auto start = graph_dev.begin(vertex); // GRAPH edge iterator + auto end = graph_dev.end(vertex); // GRAPH edge iterator + + for (auto n = start; n != end; ++n) { + auto edge = n.getIndex(); // GRAPH edge index + auto weight = graph_dev.getEdgeWeight(edge); // GRAPH edge weight + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } + } + } + context.complete_iteration(state); + } + } + + const ContextT context; + const GraphDevT graph_dev; + const sycl::local_accessor n_edges_wg; + const sycl::local_accessor n_edges_sg; + const sycl::local_accessor visited; + const sycl::local_accessor subgroup_reduce; + const sycl::local_accessor subgroup_reduce_tail; + const sycl::local_accessor subgroup_ids; + const sycl::local_accessor workgroup_reduce; + const sycl::local_accessor workgroup_reduce_tail; + const sycl::local_accessor workgroup_ids; + const LambdaT functor; +}; + +template +sygraph::Event launchBitmapKernel(GraphT& graph, const InFrontierT& in, const OutFrontierT& out, LambdaT&& functor, size_t expected_size) { + sycl::queue& q = graph.getQueue(); + + size_t num_nodes = graph.getVertexCount(); + + using element_t = std::conditional_t; + + auto in_dev_frontier = in.get_device_view(); + auto out_dev_frontier = out.get_device_view(); + auto graph_dev = graph.getDeviceGraph(); // GRAPH device view + + size_t coarsening_factor = types::detail::COMPUTE_UNIT_SIZE / 16; // sygraph::detail::device::getSubgroupSize(q); + + sycl::event to_wait; + sycl::range<1> local_range; + size_t global_size; + size_t bitmap_range = in.get_element_bitsize(); + to_wait = in.compute_active_frontier(); + local_range = {bitmap_range * coarsening_factor}; + if (expected_size > 0) { + global_size = {expected_size + (local_range[0] - (expected_size % local_range[0]))}; + } else { + global_size = {local_range[0] * (sygraph::detail::device::getMaxComputeUints(q) * 8)}; + } + + sycl::range<1> global_range{global_size > local_range[0] ? global_size + (local_range[0] - (global_size % local_range[0])) : local_range[0]}; + + Context context{num_nodes, in_dev_frontier, out_dev_frontier}; + using bitmap_kernel_t = BitmapKernel; + + const uint32_t max_num_subgroups = sygraph::detail::device::getMaxNumSubgroups(q); + + auto e = q.submit([&](sycl::handler& cgh) { + cgh.depends_on(to_wait); + sycl::local_accessor n_edges_wg{local_range, cgh}; + sycl::local_accessor n_edges_sg{local_range, cgh}; + sycl::local_accessor visited{local_range, cgh}; + sycl::local_accessor subgroup_reduce{local_range, cgh}; + sycl::local_accessor subgroup_reduce_tail{max_num_subgroups, cgh}; + sycl::local_accessor subgroup_ids{local_range, cgh}; + sycl::local_accessor workgroup_reduce{local_range, cgh}; + sycl::local_accessor workgroup_reduce_tail{1, cgh}; + sycl::local_accessor workgroup_ids{local_range, cgh}; + sycl::local_accessor individual_reduce{local_range, cgh}; + sycl::local_accessor individual_reduce_tail{1, cgh}; + + + cgh.parallel_for>(sycl::nd_range<1>{global_range, local_range}, + bitmap_kernel_t{context, + graph_dev, + n_edges_wg, + n_edges_sg, + visited, + subgroup_reduce, + subgroup_reduce_tail, + subgroup_ids, + workgroup_reduce, + workgroup_reduce_tail, + workgroup_ids, + std::forward(functor)}); + }); + return {e}; +} + +} // namespace oneapi::dal::backend::primitives \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 403a11267fa..41f608e06f9 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -63,6 +63,8 @@ struct frontier_view { std::uint32_t* _offsets_size; }; +#ifdef ONEDAL_DATA_PARALLEL + template class frontier { using bitmap_t = ElementType; @@ -127,11 +129,12 @@ class frontier { } bool empty() const { - auto empty_buff = _buffer.slice(0, 1); - fill(_queue, empty_buff, buffer_t(0)).wait(); - auto empty_buff_ptr = empty_buff.get_mutable_data(); + ndview empty_buff = _buffer.slice(0, 1); + auto copy_e = fill(_queue, empty_buff, buffer_t(0)); + auto* const empty_buff_ptr = empty_buff.get_mutable_data(); auto e = _queue.submit([&](sycl::handler& cgh) { + cgh.depends_on(copy_e); const auto range = make_range_1d(_mlb_layer.get_count()); auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); auto* f_ptr = this->get_mlb_ptr(); @@ -140,7 +143,6 @@ class frontier { sum_v += f_ptr[idx]; }); }); - e.wait_and_throw(); auto empty_sum = empty_buff.at_device(_queue, 0, { e }); return empty_sum == 0; } @@ -294,4 +296,6 @@ class frontier { const size_t _CAF_FLAG = 0; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) }; +#endif + } // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp index 97c99e8b41a..fa05bd1f9e7 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -10,8 +10,26 @@ namespace oneapi::dal::backend::primitives::test { +void print_device_name(sycl::queue& queue) { + const auto device = queue.get_device(); + const auto device_name = device.get_info(); + std::cout << "Running on device: " << device_name << std::endl; +} + +template +void print_frontier(const T* data, size_t num_items) { + size_t element_bitsize = sizeof(T) * 8; + for (size_t i = 0; i < num_items; ++i) { + size_t offset = num_items / element_bitsize; + size_t bit = i % element_bitsize; + std::cout << ((data[offset] & (static_cast(1) << bit)) ? "1" : "0"); + } +} + TEST("frontier basic operations", "[frontier]") { - sycl::queue queue{ sycl::cpu_selector_v }; + DECLARE_TEST_POLICY(policy); + auto& queue = policy.get_queue(); + print_device_name(queue); const std::size_t num_items = 100; auto f = frontier(queue, num_items); @@ -62,15 +80,20 @@ TEST("frontier basic operations", "[frontier]") { } // TEST "frontier basic operations" TEST("frontier queue basic operations", "[frontier]") { - sycl::queue queue{ sycl::gpu_selector_v }; + DECLARE_TEST_POLICY(policy); + auto& queue = policy.get_queue(); + print_device_name(queue); const std::size_t num_items = 100; - auto f = frontier(queue, num_items); + auto f = frontier(queue, num_items); SECTION("empty function", "[frontier]") { REQUIRE(f.empty() == true); - auto view = f.get_device_view(); - view.insert(0); + queue.single_task([=, view = f.get_device_view()]() { + view.insert(0); + }).wait_and_throw(); + std::cout << (f.check(0) ? "Frontier is not empty" : "Frontier is empty") << std::endl; + std::vector data_layer_cpy(f.get_data_size()); REQUIRE(f.empty() == false); } @@ -79,12 +102,19 @@ TEST("frontier queue basic operations", "[frontier]") { f.insert(2); f.insert(bitset::element_bitsize); - auto data_layer = f.get_data_ptr(); - auto mlb_layer = f.get_mlb_ptr(); - - REQUIRE(data_layer[0] == static_cast(5)); - REQUIRE(data_layer[1] == static_cast(1)); - REQUIRE(mlb_layer[0] == static_cast(3)); + auto* data_layer = f.get_data_ptr(); + auto* mlb_layer = f.get_mlb_ptr(); + + bool* check = sycl::malloc_device(1, queue); + queue.single_task([=, view = f.get_device_view()]() { + check[0] = data_layer[0] == static_cast(5); + check[0] &= data_layer[1] == static_cast(1); + check[0] &= mlb_layer[0] == static_cast(3); + }).wait_and_throw(); + bool tmp_check; + queue.copy(check, &tmp_check, 1).wait_and_throw(); + REQUIRE(tmp_check == true); + sycl::free(check, queue); } SECTION("check function", "[frontier]") { @@ -105,19 +135,21 @@ TEST("frontier queue basic operations", "[frontier]") { } // TEST "frontier queue operations" TEST("compute active frontier", "[frontier]") { - sycl::queue queue{ sycl::gpu_selector_v }; + DECLARE_TEST_POLICY(policy); + auto& queue = policy.get_queue(); const std::size_t num_items = 100000; - auto f = frontier(queue, num_items); - auto view = f.get_device_view(); + auto f = frontier(queue, num_items); - view.insert(0); - view.insert(2); - view.insert(32); - view.insert(33); - view.insert(64); - view.insert(65); - view.insert(95); + queue.single_task([=, view = f.get_device_view()]() { + view.insert(0); + view.insert(2); + view.insert(32); + view.insert(33); + view.insert(64); + view.insert(65); + view.insert(95); + }).wait_and_throw(); auto e = f.compute_active_frontier(); e.wait(); From 74459af83b4d4224028f670832dd54debf0d4404 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Thu, 17 Jul 2025 01:56:28 +0200 Subject: [PATCH 07/69] refactor: rename clear and gas methods to unset and atomic_unset for consistency; update related functionality; fixed bug for SIGSEGV --- .../dal/backend/primitives/bitset/bitset.hpp | 38 +--- .../primitives/frontier/frontier_dpc.hpp | 120 ++++++------- .../frontier/test/basic_frontier_ops_dpc.cpp | 162 ++++-------------- 3 files changed, 92 insertions(+), 228 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp index 847d1021cbc..63d728c5cc0 100644 --- a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -21,7 +21,7 @@ class bitset { } /// Clears the bit at the specified index to 0. - inline void clear(std::uint32_t index) const { + inline void unset(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; _data[element_index] &= ~(element_t(1) << bit_index); @@ -34,36 +34,26 @@ class bitset { return (_data[element_index] & (element_t(1) << bit_index)) != 0; } - inline bool gas(std::uint32_t index) const { - element_t element_index = index / element_bitsize; - element_t bit_index = index % element_bitsize; - bool set = (_data[element_index] & (element_t(1) << bit_index)) != 0; - if (!set) { - _data[element_index] &= ~(element_t(1) << bit_index); // Clear - } - return set; - } - /// Sets the bit at the specified index using atomic operations. template inline void atomic_set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; - sycl::atomic_ref + sycl::atomic_ref atomic_element(_data[element_index]); - atomic_element.fetch_or(element_t(1) << bit_index); + atomic_element.store(atomic_element.load() | (element_t(1) << bit_index)); } /// Clears the bit at the specified index using atomic operations. template - inline void atomic_clear(std::uint32_t index) { + inline void atomic_unset(std::uint32_t index) { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; - sycl::atomic_ref + sycl::atomic_ref atomic_element(_data[element_index]); - atomic_element.fetch_and(~(element_t(1) << bit_index)); + atomic_element.store(atomic_element.load() & ~(element_t(1) << bit_index)); } /// Checks if the bit at the specified index is set using atomic operations. @@ -72,25 +62,11 @@ class bitset { inline bool atomic_test(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; - sycl::atomic_ref + sycl::atomic_ref atomic_element(_data[element_index]); return (atomic_element.load() & (element_t(1) << bit_index)) != 0; } - template - inline bool atomic_gas(std::uint32_t index) const { - element_t element_index = index / element_bitsize; - element_t bit_index = index % element_bitsize; - sycl::atomic_ref - atomic_element(_data[element_index]); - bool set = (atomic_element.load() & (element_t(1) << bit_index)) != 0; - if (!set) { - atomic_element.fetch_and(~(element_t(1) << bit_index)); // Clear - } - return set; - } - /// Returns the pointer to the underlying data. inline element_t* get_data() { return _data; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 41f608e06f9..ce2747c4c39 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -20,8 +20,8 @@ struct frontier_view { std::uint32_t* offsets_size, size_t num_items) : _num_items(num_items), - _data_layer(data_layer), - _mlb_layer(mlb_layer), + _data_layer(bitset{data_layer}), + _mlb_layer(bitset{mlb_layer}), _offsets(offsets), _offsets_size(offsets_size) {} @@ -31,7 +31,7 @@ struct frontier_view { } if (!_mlb_layer.test(idx / divide_factor)) { _mlb_layer.atomic_set(idx / divide_factor); - }; + } } inline void remove(std::uint32_t idx) const { @@ -65,67 +65,60 @@ struct frontier_view { #ifdef ONEDAL_DATA_PARALLEL -template +template class frontier { using bitmap_t = ElementType; using buffer_t = std::uint32_t; public: - frontier(sycl::queue& queue, std::size_t num_items) : _queue(queue), _num_items(num_items) { - auto array_size = + frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc = sycl::usm::alloc::shared) : _queue(queue), _num_items(num_items) { + std::int64_t array_size = (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; - auto mlb_size = (array_size + bitset::element_bitsize - 1) / + std::int64_t mlb_size = (array_size + bitset::element_bitsize - 1) / bitset::element_bitsize; - auto [data_layer, e1] = - ndarray::zeros(queue, { static_cast(array_size) }, Alloc); - auto [mlb_layer, e2] = - ndarray::zeros(queue, { static_cast(mlb_size) }, Alloc); - auto [offsets, e3] = - ndarray::zeros(queue, { static_cast(array_size + 1) }, Alloc); /// First offset is to keep the size of the frontier - _buffer = ndarray::empty(queue, { static_cast(10) }, Alloc); + _data_layer = + ndarray::empty(_queue, { array_size }, alloc); + _mlb_layer = + ndarray::empty(_queue, { mlb_size }, alloc); + _offsets = + ndarray::empty(_queue, { array_size + 1 }, alloc); /// First offset is to keep the size of the frontier + _buffer = ndarray::empty(_queue, { 10 }, alloc); + + sycl::event e1, e2, e3; + e1 = _data_layer.fill(_queue, bitmap_t(0)); + e2 = _mlb_layer.fill(_queue, bitmap_t(0)); + e3 = _offsets.fill(_queue, buffer_t(0)); e1.wait_and_throw(); e2.wait_and_throw(); e3.wait_and_throw(); - - _data_layer = std::move(data_layer); - _mlb_layer = std::move(mlb_layer); - _offsets = std::move(offsets); } - frontier_view get_device_view() const { + const frontier_view get_device_view() const { auto offsets_size_pointer = _offsets.get_mutable_data(); auto offsets_pointer = _offsets.get_mutable_data() + 1; - return frontier_view(this->get_data_ptr(), - this->get_mlb_ptr(), + return frontier_view(_data_layer.get_mutable_data(), + _mlb_layer.get_mutable_data(), offsets_pointer, offsets_size_pointer, _data_layer.get_count()); } - inline bitmap_t* get_data_ptr() const { - return _data_layer.get_mutable_data(); - } - - inline bitmap_t* get_mlb_ptr() const { - return _mlb_layer.get_mutable_data(); + inline ndview get_data() const { + return _data_layer; } - inline std::uint32_t* get_offsets_ptr() const { - return &(_offsets.get_mutable_data()[1]); + inline ndview get_mlb() const { + return _mlb_layer; } - inline std::uint32_t* get_offsets_size_ptr() const { - return _offsets.get_mutable_data(); + inline ndview get_offsets() const { + return _offsets.slice(1, _offsets.get_count()); } - inline size_t get_data_size() const { - return _data_layer.get_count(); - } - - inline size_t get_mlb_size() const { - return _mlb_layer.get_count(); + inline ndview get_offsets_size() const { + return _offsets.slice(0, 1); } bool empty() const { @@ -137,7 +130,7 @@ class frontier { cgh.depends_on(copy_e); const auto range = make_range_1d(_mlb_layer.get_count()); auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); - auto* f_ptr = this->get_mlb_ptr(); + auto* const f_ptr = _mlb_layer.get_mutable_data(); cgh.parallel_for(range, sum_reduction, [=](sycl::id<1> idx, auto& sum_v) { sum_v += f_ptr[idx]; @@ -148,31 +141,19 @@ class frontier { } void insert(bitmap_t idx) { - if (idx >= _data_layer.get_count() * bitset::element_bitsize) { - throw dal::domain_error("Index is out of range"); - } auto view = this->get_device_view(); - _queue - .single_task([=]() { - view.insert(idx); - }) - .wait_and_throw(); + _queue.submit( + [&](sycl::handler& cgh) { + cgh.single_task([=]() { + view.insert(idx); + }); + } + ).wait_and_throw(); } bool check(bitmap_t idx) const { - auto check_buff = _buffer.slice(0, 1); - fill(_queue, check_buff, buffer_t(0)).wait(); - auto check_buff_ptr = check_buff.get_mutable_data(); - - auto e = _queue.submit([&](sycl::handler& cgh) { - auto view = this->get_device_view(); - - cgh.single_task([=]() { - check_buff_ptr[0] = view.check(idx) ? buffer_t(1) : buffer_t(0); - }); - }); - auto check_res = check_buff.at_device(_queue, 0, { e }); - return check_res == buffer_t(1); + bitmap_t tmp_data = _data_layer.at_device(_queue, idx / bitset::element_bitsize); + return (tmp_data & (static_cast(1) << (idx % bitset::element_bitsize))) != 0; } void clear() { @@ -187,16 +168,19 @@ class frontier { sycl::event compute_active_frontier() const { auto bitmap = this->get_device_view(); + auto offsets_size_pointer = _offsets.get_mutable_data(); + auto offsets_pointer = _offsets.get_mutable_data() + 1; + uint32_t element_bitsize = decltype(bitmap._mlb_layer)::element_bitsize; size_t local_range = 1024; // Adjust as needed size_t global_range = _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); bool use_local_mem = - device_local_mem_size(this->_queue) >= (local_range * element_bitsize * sizeof(uint32_t)); + device_local_mem_size(this->_queue) >= static_cast(local_range * element_bitsize * sizeof(uint32_t)); auto e0 = _queue.submit([&](sycl::handler& cgh) { - cgh.single_task([=, offsets_size = this->get_offsets_size_ptr(), buffer_ptr = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG]() { + cgh.single_task([=, offsets_size = this->get_offsets_size().get_mutable_data(), buffer_ptr = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG]() { buffer_ptr[CAF_FLAG] = offsets_size[0] == 0 ? 1 : 0; }); }); @@ -207,9 +191,9 @@ class frontier { if (!use_local_mem || true) { // Force to use global memory for simplicity cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), [=, - offsets = this->get_offsets_ptr(), - offsets_size = this->get_offsets_size_ptr(), - data_layer = this->get_mlb_ptr(), + offsets = offsets_pointer, + offsets_size = offsets_size_pointer, + data_layer = this->_mlb_layer.get_mutable_data(), buffer = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG](sycl::id<1> idx) { @@ -234,9 +218,9 @@ class frontier { cgh.parallel_for( make_multiple_nd_range_1d(global_range, local_range), [=, - offsets = this->get_offsets_ptr(), - offsets_size = this->get_offsets_size_ptr(), - data_layer = this->get_mlb_ptr(), + offsets = offsets_pointer, + offsets_size = offsets_size_pointer, + data_layer = this->_mlb_layer.get_mutable_data(), size = this->_num_items, buffer = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { @@ -293,7 +277,7 @@ class frontier { ndarray _offsets; ndarray _buffer; const size_t _TMP_VAR = 0; - const size_t _CAF_FLAG = 0; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) + const size_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) }; #endif diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp index fa05bd1f9e7..93bb2737204 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp @@ -17,67 +17,14 @@ void print_device_name(sycl::queue& queue) { } template -void print_frontier(const T* data, size_t num_items) { +void print_frontier(const T* data, size_t count, size_t num_items) { size_t element_bitsize = sizeof(T) * 8; - for (size_t i = 0; i < num_items; ++i) { - size_t offset = num_items / element_bitsize; - size_t bit = i % element_bitsize; - std::cout << ((data[offset] & (static_cast(1) << bit)) ? "1" : "0"); - } -} - -TEST("frontier basic operations", "[frontier]") { - DECLARE_TEST_POLICY(policy); - auto& queue = policy.get_queue(); - print_device_name(queue); - - const std::size_t num_items = 100; - auto f = frontier(queue, num_items); - auto view = f.get_device_view(); - size_t expected_data_layer_size = (num_items + bitset::element_bitsize - 1) / - bitset::element_bitsize; - size_t expected_mlb_layer_size = - (expected_data_layer_size + bitset::element_bitsize - 1) / - bitset::element_bitsize; - - SECTION("frontier has correct data layer size", "[frontier]") { - REQUIRE(f.get_data_size() == expected_data_layer_size); - - REQUIRE(f.get_mlb_size() == expected_mlb_layer_size); + for (size_t i = 0; i < count; ++i) { + for (size_t j = 0; j < element_bitsize; ++j) { + std::cout << ((data[i] & (static_cast(1) << j)) ? "1" : "0"); + } } - - SECTION("frontier can insert elements", "[frontier]") { - view.insert(0); - view.insert(2); - view.insert(bitset::element_bitsize); - - auto data_layer = f.get_data_ptr(); - auto mlb_layer = f.get_mlb_ptr(); - - REQUIRE(data_layer[0] == static_cast(5)); - REQUIRE(data_layer[1] == static_cast(1)); - REQUIRE(mlb_layer[0] == static_cast(3)); - } - - SECTION("frontier can check elements", "[frontier]") { - view.insert(0); - view.insert(2); - view.insert(32); - view.insert(64); - - REQUIRE(view.check(0) == true); - REQUIRE(view.check(1) == false); - REQUIRE(view.check(2) == true); - REQUIRE(view.check(3) == false); - REQUIRE(view.check(31) == false); - REQUIRE(view.check(32) == true); - REQUIRE(view.check(33) == false); - REQUIRE(view.check(63) == false); - REQUIRE(view.check(64) == true); - REQUIRE(view.check(65) == false); - } - -} // TEST "frontier basic operations" +} TEST("frontier queue basic operations", "[frontier]") { DECLARE_TEST_POLICY(policy); @@ -85,79 +32,36 @@ TEST("frontier queue basic operations", "[frontier]") { print_device_name(queue); const std::size_t num_items = 100; - auto f = frontier(queue, num_items); - - SECTION("empty function", "[frontier]") { - REQUIRE(f.empty() == true); - queue.single_task([=, view = f.get_device_view()]() { - view.insert(0); - }).wait_and_throw(); - std::cout << (f.check(0) ? "Frontier is not empty" : "Frontier is empty") << std::endl; - std::vector data_layer_cpy(f.get_data_size()); - REQUIRE(f.empty() == false); - } - - SECTION("insert function", "[frontier]") { - f.insert(0); - f.insert(2); - f.insert(bitset::element_bitsize); - - auto* data_layer = f.get_data_ptr(); - auto* mlb_layer = f.get_mlb_ptr(); - - bool* check = sycl::malloc_device(1, queue); - queue.single_task([=, view = f.get_device_view()]() { - check[0] = data_layer[0] == static_cast(5); - check[0] &= data_layer[1] == static_cast(1); - check[0] &= mlb_layer[0] == static_cast(3); - }).wait_and_throw(); - bool tmp_check; - queue.copy(check, &tmp_check, 1).wait_and_throw(); - REQUIRE(tmp_check == true); - sycl::free(check, queue); - } - - SECTION("check function", "[frontier]") { - f.insert(0); - REQUIRE(f.check(0) == true); - REQUIRE(f.check(1) == false); + auto f = frontier(queue, num_items, sycl::usm::alloc::shared); + + REQUIRE(f.empty() == true); + f.insert(0); + f.insert(2); + f.insert(32); + f.insert(128); + + REQUIRE(f.empty() == false); + + REQUIRE(f.get_data().at_device(queue, 0) == 5); + REQUIRE(f.get_data().at_device(queue, 1) == 1); + REQUIRE(f.get_mlb().at_device(queue, 0) == 19); + + REQUIRE(f.check(0) == true); + REQUIRE(f.check(1) == false); + REQUIRE(f.check(2) == true); + REQUIRE(f.check(3) == false); + REQUIRE(f.check(bitset::element_bitsize) == true); + REQUIRE(f.check(bitset::element_bitsize + 1) == false); + + auto e = f.compute_active_frontier(); + REQUIRE(f.get_offsets_size().at_device(queue, 0, {e}) == 3); + for (int i = 0; i < 3; i++) { + std::cout << "Active frontier item " << i << ": " << f.get_offsets().at_device(queue, i) << std::endl; } - SECTION("clear function", "[frontier]") { - f.insert(0); - f.insert(2); - f.insert(bitset::element_bitsize); - REQUIRE(f.empty() == false); - f.clear(); - REQUIRE(f.empty() == true); - } + f.clear(); + REQUIRE(f.empty() == true); } // TEST "frontier queue operations" -TEST("compute active frontier", "[frontier]") { - DECLARE_TEST_POLICY(policy); - auto& queue = policy.get_queue(); - - const std::size_t num_items = 100000; - auto f = frontier(queue, num_items); - - queue.single_task([=, view = f.get_device_view()]() { - view.insert(0); - view.insert(2); - view.insert(32); - view.insert(33); - view.insert(64); - view.insert(65); - view.insert(95); - }).wait_and_throw(); - - auto e = f.compute_active_frontier(); - e.wait(); - - auto offsets_size = f.get_offsets_size_ptr(); - - REQUIRE(offsets_size[0] == 3); - f.clear(); -} // TEST "compute active frontier" - } // namespace oneapi::dal::backend::primitives::test From b14112805e8aa8f27df40d88a88d76663880ea02 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Thu, 17 Jul 2025 19:50:09 +0200 Subject: [PATCH 08/69] feat: add advance operation tests for frontier class; include device name printing and frontier checks --- .../dal/backend/primitives/bitset/bitset.hpp | 2 + .../dal/backend/primitives/frontier.hpp | 4 +- .../primitives/frontier/advance_dpc.hpp | 85 +++++----- .../primitives/frontier/frontier_dpc.hpp | 4 +- .../dal/backend/primitives/frontier/graph.hpp | 158 ++++++++++++++++++ .../frontier/test/advance_frontier_dpc.cpp | 82 +++++++++ 6 files changed, 291 insertions(+), 44 deletions(-) create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp index 63d728c5cc0..a821c04f00a 100644 --- a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "oneapi/dal/backend/memory.hpp" namespace oneapi::dal::backend::primitives { diff --git a/cpp/oneapi/dal/backend/primitives/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier.hpp index 0ce734a968e..9e35cff3f12 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier.hpp @@ -1 +1,3 @@ -#include "oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp" \ No newline at end of file +#include "oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/advance_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/graph.hpp" \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index da78687dcb0..31eb9bdb909 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -1,6 +1,8 @@ #pragma once -#include "oneapi/dal/backend/primitives/frontier.hpp" +#include "oneapi/dal/backend/primitives/ndarray.hpp" +#include "oneapi/dal/backend/primitives/frontier/graph.hpp" +#include "oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp" namespace oneapi::dal::backend::primitives { @@ -35,9 +37,9 @@ struct Context { inline void complete_iteration(ContextState& state) const { state.group_offset += state.item.get_group_range(0); } inline size_t get_assigned_element(const ContextState& state) const { - const uint16_t bitmap_range = in_dev_frontier.getBitmapRange(); + const uint16_t bitmap_range = in_dev_frontier.get_element_bitsize(); const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / bitmap_range); - const int* bitmap_offsets = in_dev_frontier.get_offsets(); + const auto* bitmap_offsets = in_dev_frontier.get_offsets(); // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * bitmap_range) + (state.item.get_local_linear_id() % bitmap_range); return assigned_vertex; @@ -55,15 +57,15 @@ struct Context { template struct BitmapKernel { void operator()(sycl::nd_item<1> item) const { // 0. retrieve global and local ids - const size_t gid = item.get_global_linear_id(); + // const size_t gid = item.get_global_linear_id(); const size_t lid = item.get_local_linear_id(); const auto wgroup = item.get_group(); - const auto wgroup_id = item.get_group_linear_id(); + // const auto wgroup_id = item.get_group_linear_id(); const size_t wgroup_size = wgroup.get_local_range(0); const auto sgroup = item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); @@ -85,7 +87,7 @@ struct BitmapKernel { const uint32_t offset = sgroup_id * sgroup_size; if (context.check(state, assigned_vertex)) { - uint32_t n_edges = graph_dev.getDegree(assigned_vertex); // GRAPH degree of the vertex + uint32_t n_edges = graph_dev.get_degree(assigned_vertex); // GRAPH degree of the vertex if (n_edges >= wgroup_size * wgroup_size) { // assign to the workgroup uint32_t loc = wg_tail.fetch_add(static_cast(1)); n_edges_wg[loc] = n_edges; @@ -110,8 +112,8 @@ struct BitmapKernel { for (auto j = lid; j < n_edges; j += wgroup_size) { auto n = start + j; - auto edge = n.getIndex(); // GRAPH edge index - auto weight = graph_dev.getEdgeWeight(edge); // GRAPH edge weight + auto edge = n.get_index(); // GRAPH edge index + auto weight = graph_dev.get_weight(edge); // GRAPH edge weight auto neighbor = *n; if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } } @@ -130,8 +132,8 @@ struct BitmapKernel { for (auto j = llid; j < n_edges; j += sgroup_size) { auto n = start + j; - auto edge = n.getIndex(); // GRAPH edge index - auto weight = graph_dev.getEdgeWeight(edge); // GRAPH edge weight + auto edge = n.get_index(); // GRAPH edge index + auto weight = graph_dev.get_weight(edge); // GRAPH edge weight auto neighbor = *n; if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } } @@ -146,8 +148,8 @@ struct BitmapKernel { auto end = graph_dev.end(vertex); // GRAPH edge iterator for (auto n = start; n != end; ++n) { - auto edge = n.getIndex(); // GRAPH edge index - auto weight = graph_dev.getEdgeWeight(edge); // GRAPH edge weight + auto edge = n.get_index(); // GRAPH edge index + auto weight = graph_dev.get_weight(edge); // GRAPH edge weight auto neighbor = *n; if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } } @@ -170,42 +172,43 @@ struct BitmapKernel { const LambdaT functor; }; -template -sygraph::Event launchBitmapKernel(GraphT& graph, const InFrontierT& in, const OutFrontierT& out, LambdaT&& functor, size_t expected_size) { - sycl::queue& q = graph.getQueue(); +sycl::event advance(const GraphT& graph, frontier& in, frontier& out, LambdaT&& functor, size_t expected_size = 0) { + sycl::queue& q = graph.get_queue(); - size_t num_nodes = graph.getVertexCount(); + size_t num_nodes = graph.get_vertex_count(); - using element_t = std::conditional_t; + using element_t = FrontierSizeT; + // using element_t = std::conditional_t; auto in_dev_frontier = in.get_device_view(); auto out_dev_frontier = out.get_device_view(); - auto graph_dev = graph.getDeviceGraph(); // GRAPH device view + auto graph_dev = graph.get_device_view(); // GRAPH device view - size_t coarsening_factor = types::detail::COMPUTE_UNIT_SIZE / 16; // sygraph::detail::device::getSubgroupSize(q); + size_t coarsening_factor = 256 /*CU size*/ / 16 /*Subgroup Size*/; sycl::event to_wait; sycl::range<1> local_range; size_t global_size; - size_t bitmap_range = in.get_element_bitsize(); + size_t bitmap_range = in_dev_frontier.get_element_bitsize(); to_wait = in.compute_active_frontier(); local_range = {bitmap_range * coarsening_factor}; if (expected_size > 0) { global_size = {expected_size + (local_range[0] - (expected_size % local_range[0]))}; } else { - global_size = {local_range[0] * (sygraph::detail::device::getMaxComputeUints(q) * 8)}; + global_size = {local_range[0] * 128}; + // global_size = {local_range[0] * (sygraph::detail::device::getMaxComputeUints(q) * 8)}; } sycl::range<1> global_range{global_size > local_range[0] ? global_size + (local_range[0] - (global_size % local_range[0])) : local_range[0]}; - Context context{num_nodes, in_dev_frontier, out_dev_frontier}; - using bitmap_kernel_t = BitmapKernel; + Context context{num_nodes, in_dev_frontier, out_dev_frontier}; + using bitmap_kernel_t = BitmapKernel; - const uint32_t max_num_subgroups = sygraph::detail::device::getMaxNumSubgroups(q); + const uint32_t max_num_subgroups = 32; + // const uint32_t max_num_subgroups = sygraph::detail::device::getMaxNumSubgroups(q); auto e = q.submit([&](sycl::handler& cgh) { cgh.depends_on(to_wait); @@ -222,19 +225,19 @@ sygraph::Event launchBitmapKernel(GraphT& graph, const InFrontierT& in, const Ou sycl::local_accessor individual_reduce_tail{1, cgh}; - cgh.parallel_for>(sycl::nd_range<1>{global_range, local_range}, - bitmap_kernel_t{context, - graph_dev, - n_edges_wg, - n_edges_sg, - visited, - subgroup_reduce, - subgroup_reduce_tail, - subgroup_ids, - workgroup_reduce, - workgroup_reduce_tail, - workgroup_ids, - std::forward(functor)}); + cgh.parallel_for(sycl::nd_range<1>{global_range, local_range}, + bitmap_kernel_t{context, + graph_dev, + n_edges_wg, + n_edges_sg, + visited, + subgroup_reduce, + subgroup_reduce_tail, + subgroup_ids, + workgroup_reduce, + workgroup_reduce_tail, + workgroup_ids, + std::forward(functor)}); }); return {e}; } diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index ce2747c4c39..05c7c310967 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -47,11 +47,11 @@ struct frontier_view { } inline std::uint32_t* get_offsets() const { - return _offsets_size; + return _offsets; } inline std::uint32_t* get_offsets_size() const { - return _offsets; + return _offsets_size; } size_t _num_items; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index e69de29bb2d..825a119dbc5 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -0,0 +1,158 @@ +#pragma once + +#include "oneapi/dal/common.hpp" +#include "oneapi/dal/graph/detail/common.hpp" +#include "oneapi/dal/graph/detail/container.hpp" +#include "oneapi/dal/backend/primitives/bitset.hpp" +#include "oneapi/dal/backend/primitives/ndarray.hpp" + +namespace oneapi::dal::backend::primitives { + +template +class csr_graph_view { + using vertex_t = VertexT; + using edge_t = EdgeT; + using weight_t = WeightT; + + struct neighbor_iterator_t { + neighbor_iterator_t(const vertex_t* start_ptr, vertex_t* ptr) + : _ptr(ptr), _start_ptr(start_ptr) {} + + SYCL_EXTERNAL bool operator==(const neighbor_iterator_t& other) const { + return _ptr == other._ptr; + } + + SYCL_EXTERNAL bool operator!=(const neighbor_iterator_t& other) const { + return _ptr != other._ptr; + } + + SYCL_EXTERNAL neighbor_iterator_t& operator++() { + ++_ptr; + return *this; + } + + SYCL_EXTERNAL neighbor_iterator_t operator+(int n) const { + neighbor_iterator_t tmp = *this; + tmp._ptr += n; + return tmp; + } + + SYCL_EXTERNAL vertex_t operator*() const { + return *_ptr; + } + + SYCL_EXTERNAL edge_t get_index() const { + return static_cast(_ptr - _start_ptr); + } + + vertex_t* _ptr; + const vertex_t* _start_ptr; + }; + +public: + csr_graph_view(std::size_t num_nodes, + vertex_t* row_ptr, + edge_t* col_indices, + weight_t* weights) + : _num_nodes(num_nodes), + _row_ptr(row_ptr), + _col_indices(col_indices), + _weights(weights) { + ONEDAL_ASSERT(_row_ptr != nullptr, "Row pointer must not be null"); + ONEDAL_ASSERT(_col_indices != nullptr, "Column indices must not be null"); + ONEDAL_ASSERT(_weights != nullptr, "Weights must not be null"); + } + + SYCL_EXTERNAL inline std::uint32_t get_degree(const vertex_t vertex) const { + ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); + return static_cast(_row_ptr[vertex + 1] - _row_ptr[vertex]); + } + + SYCL_EXTERNAL inline weight_t get_weight(const edge_t edge) const { + return _weights[edge]; + } + + SYCL_EXTERNAL inline neighbor_iterator_t begin(vertex_t vertex) const { + ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); + return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex]); + } + + SYCL_EXTERNAL inline neighbor_iterator_t end(vertex_t vertex) const { + ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); + return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex + 1]); + } + +private: + std::size_t _num_nodes; + vertex_t* _row_ptr; + edge_t* _col_indices; + weight_t* _weights; +}; + +template +class csr_graph { + using vertex_t = VertexT; + using edge_t = EdgeT; + using weight_t = WeightT; + using graph_view_t = csr_graph_view; + +public: + csr_graph(sycl::queue& queue, + std::vector row_ptr, + std::vector col_indices, + std::vector weights = {}, + sycl::usm::alloc alloc = sycl::usm::alloc::shared) + : _queue(queue), _num_nodes(row_ptr.size() - 1) { + + std::int64_t row_ptr_size = static_cast(row_ptr.size()); + std::int64_t col_indices_size = static_cast(col_indices.size()); + std::int64_t weights_size = static_cast(weights.size()); + + _row_ptr = ndarray::empty(_queue, {row_ptr_size}, alloc); + _col_indices = ndarray::empty(_queue, {col_indices_size}, alloc); + _weights = ndarray::empty(_queue, {weights_size}, alloc); + + auto e1 = dal::backend::copy_host2usm(_queue, + _row_ptr.get_mutable_data(), + row_ptr.data(), + row_ptr.size()); + + auto e2 = dal::backend::copy_host2usm(_queue, + _col_indices.get_mutable_data(), + col_indices.data(), + col_indices.size()); + + auto e3 = dal::backend::copy_host2usm(_queue, + _weights.get_mutable_data(), + weights.data(), + weights.size()); + + e1.wait_and_throw(); + e2.wait_and_throw(); + e3.wait_and_throw(); + } + + graph_view_t get_device_view() const { + return { _num_nodes, + _row_ptr.get_mutable_data(), + _col_indices.get_mutable_data(), + _weights.get_mutable_data() }; + } + + sycl::queue& get_queue() const { + return _queue; + } + + std::size_t get_vertex_count() const { + return _num_nodes; + } + +private: + sycl::queue& _queue; + std::size_t _num_nodes; + ndarray _row_ptr; + ndarray _col_indices; + ndarray _weights; +}; + +} // namespace oneapi::dal::backend::primitives \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp new file mode 100644 index 00000000000..0dc930e28a0 --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp @@ -0,0 +1,82 @@ +#include "oneapi/dal/backend/primitives/frontier.hpp" + +#include "oneapi/dal/test/engine/common.hpp" +#include "oneapi/dal/test/engine/fixtures.hpp" +#include "oneapi/dal/test/engine/dataframe.hpp" + +#include "oneapi/dal/test/engine/common.hpp" +#include "oneapi/dal/test/engine/fixtures.hpp" +#include "oneapi/dal/test/engine/dataframe.hpp" + +namespace oneapi::dal::backend::primitives::test { + +void print_device_name(sycl::queue& queue) { + const auto device = queue.get_device(); + const auto device_name = device.get_info(); + std::cout << "Running on device: " << device_name << std::endl; +} + +template +void print_frontier(const T* data, size_t count, size_t num_items) { + size_t element_bitsize = sizeof(T) * 8; + for (size_t i = 0; i < count; ++i) { + for (size_t j = 0; j < element_bitsize; ++j) { + std::cout << ((data[i] & (static_cast(1) << j)) ? "1" : "0"); + } + } +} + +TEST("test advance operation", "[advance]") { + DECLARE_TEST_POLICY(policy); + auto& queue = policy.get_queue(); + print_device_name(queue); + + std::vector row_ptr = {0, 2, 4, 6}; + std::vector col_indices = {1, 2, 0, 2, 0, 1}; + std::vector weights = {1, 1, 1, 1, 1, 1}; + + auto graph = csr_graph(queue, row_ptr, col_indices, weights); + auto first_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + auto second_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + auto third_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + + first_frontier.insert(0); + + REQUIRE(first_frontier.check(0) == true); + REQUIRE(first_frontier.check(1) == false); + REQUIRE(first_frontier.check(2) == false); + + std::cout << "First Frontier: "; + for (size_t i = 0; i < graph.get_vertex_count(); ++i) { + std::cout << "Vertex " << i << ": " << (first_frontier.check(i) ? "in frontier" : "not in frontier") << std::endl; + } + + advance(graph, first_frontier, second_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { + return true; // Always advance + }).wait_and_throw(); + + REQUIRE(second_frontier.check(0) == false); + REQUIRE(second_frontier.check(1) == true); + REQUIRE(second_frontier.check(2) == true); + + std::cout << "Second Frontier: "; + for (size_t i = 0; i < graph.get_vertex_count(); ++i) { + std::cout << "Vertex " << i << ": " << (second_frontier.check(i) ? "in frontier" : "not in frontier") << std::endl; + } + + advance(graph, second_frontier, third_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { + return true; // Always advance + }).wait_and_throw(); + + std::cout << "Third Frontier: "; + for (size_t i = 0; i < graph.get_vertex_count(); ++i) { + std::cout << "Vertex " << i << ": " << (third_frontier.check(i) ? "in frontier" : "not in frontier") << std::endl; + } + + REQUIRE(third_frontier.check(0) == true); + REQUIRE(third_frontier.check(1) == true); + REQUIRE(third_frontier.check(2) == true); + +} // TEST "test advance operation" + +} // namespace oneapi::dal::backend::primitives::test From 40eea0b3f1a2afa225919deb8653b582c51af305 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 23 Jul 2025 17:31:52 +0200 Subject: [PATCH 09/69] fixed advance operator --- cpp/oneapi/dal/backend/common.hpp | 5 + .../dal/backend/primitives/bitset/bitset.hpp | 4 +- .../primitives/frontier/advance_dpc.hpp | 204 ++++++++---------- .../primitives/frontier/frontier_dpc.hpp | 3 +- .../frontier/test/advance_frontier_dpc.cpp | 91 ++++---- 5 files changed, 152 insertions(+), 155 deletions(-) diff --git a/cpp/oneapi/dal/backend/common.hpp b/cpp/oneapi/dal/backend/common.hpp index 8298d49867f..7821809a343 100644 --- a/cpp/oneapi/dal/backend/common.hpp +++ b/cpp/oneapi/dal/backend/common.hpp @@ -564,6 +564,11 @@ inline std::int64_t device_max_sg_size(const sycl::queue& q) { return dal::detail::integral_cast(*result_iter); } +inline std::int64_t device_max_sg_count(const sycl::queue& q) { + const auto res = q.get_device().template get_info(); + return dal::detail::integral_cast(res); +} + inline std::int64_t propose_wg_size(const sycl::queue& q) { // TODO: a temporary solution that limits work item count used on the device. // Needs to change to more smart logic in the future. diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp index a821c04f00a..a6479a2864e 100644 --- a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp @@ -44,7 +44,7 @@ class bitset { element_t bit_index = index % element_bitsize; sycl::atomic_ref atomic_element(_data[element_index]); - atomic_element.store(atomic_element.load() | (element_t(1) << bit_index)); + atomic_element |= (element_t(1) << bit_index); } /// Clears the bit at the specified index using atomic operations. @@ -55,7 +55,7 @@ class bitset { element_t bit_index = index % element_bitsize; sycl::atomic_ref atomic_element(_data[element_index]); - atomic_element.store(atomic_element.load() & ~(element_t(1) << bit_index)); + atomic_element &= ~(element_t(1) << bit_index); } /// Checks if the bit at the specified index is set using atomic operations. diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index 31eb9bdb909..b0530a26373 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -26,31 +26,26 @@ struct Context { inline ContextState init(sycl::nd_item<1>& item) const { return { item.get_group_linear_id(), - static_cast(item.get_local_range(0) / in_dev_frontier.get_element_bitsize()), - in_dev_frontier.get_offsets_size()[0], + static_cast(item.get_local_range(0) / in_dev_frontier.getBitmapRange()), + in_dev_frontier.getOffsetsSize()[0], item, }; } - inline bool need_to_process(ContextState& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } - - inline void complete_iteration(ContextState& state) const { state.group_offset += state.item.get_group_range(0); } - - inline size_t get_assigned_element(const ContextState& state) const { - const uint16_t bitmap_range = in_dev_frontier.get_element_bitsize(); - const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / bitmap_range); + inline size_t get_assigned_element(sycl::nd_item<1> item) const { + const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); const auto* bitmap_offsets = in_dev_frontier.get_offsets(); - // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); - const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * bitmap_range) + (state.item.get_local_linear_id() % bitmap_range); + const size_t coarsening_factor = item.get_local_range(0) / element_bitsize; + const uint32_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / element_bitsize); + const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + (item.get_local_linear_id() % element_bitsize); return assigned_vertex; } - inline bool check(const ContextState& state, size_t vertex) const { - return vertex < limit && in_dev_frontier.check(vertex); - + inline bool check(sycl::nd_item<1> item, size_t vertex) const { + return vertex < limit && in_dev_frontier.check(vertex); } - inline void insert(const ContextState& state, size_t vertex) const { + inline void insert(size_t vertex) const { out_dev_frontier.insert(vertex); } }; @@ -62,99 +57,91 @@ template item) const { // 0. retrieve global and local ids - // const size_t gid = item.get_global_linear_id(); const size_t lid = item.get_local_linear_id(); const auto wgroup = item.get_group(); - // const auto wgroup_id = item.get_group_linear_id(); const size_t wgroup_size = wgroup.get_local_range(0); const auto sgroup = item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); const size_t sgroup_size = sgroup.get_local_range()[0]; const size_t llid = sgroup.get_local_linear_id(); - auto state = context.init(item); - - - while (context.need_to_process(state)) { - const auto assigned_vertex = context.get_assigned_element(state); - - // 1. load number of edges in local memory - if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; } - if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } - - sycl::atomic_ref sg_tail{subgroup_reduce_tail[sgroup_id]}; - sycl::atomic_ref wg_tail{workgroup_reduce_tail[0]}; - - const uint32_t offset = sgroup_id * sgroup_size; - if (context.check(state, assigned_vertex)) { - uint32_t n_edges = graph_dev.get_degree(assigned_vertex); // GRAPH degree of the vertex - if (n_edges >= wgroup_size * wgroup_size) { // assign to the workgroup - uint32_t loc = wg_tail.fetch_add(static_cast(1)); - n_edges_wg[loc] = n_edges; - workgroup_reduce[loc] = assigned_vertex; - workgroup_ids[loc] = lid; - } else if (n_edges >= sgroup_size) { // assign to the subgroup - uint32_t loc = sg_tail.fetch_add(static_cast(1)); - n_edges_sg[offset + loc] = n_edges; - subgroup_reduce[offset + loc] = assigned_vertex; - subgroup_ids[offset + loc] = lid; - } - visited[lid] = false; - } else { - visited[lid] = true; + const auto assigned_vertex = context.get_assigned_element(item); + + // 1. load number of edges in local memory + if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; } + if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } + + sycl::atomic_ref sg_tail{subgroup_reduce_tail[sgroup_id]}; + sycl::atomic_ref wg_tail{workgroup_reduce_tail[0]}; + + const uint32_t offset = sgroup_id * sgroup_size; + if (context.check(item, assigned_vertex)) { + uint32_t n_edges = graph_dev.get_degree(assigned_vertex); + if (n_edges >= wgroup_size * wgroup_size) { // assign to the workgroup + uint32_t loc = wg_tail.fetch_add(static_cast(1)); + n_edges_wg[loc] = n_edges; + workgroup_reduce[loc] = assigned_vertex; + workgroup_ids[loc] = lid; + } else if (n_edges >= sgroup_size) { // assign to the subgroup + uint32_t loc = sg_tail.fetch_add(static_cast(1)); + n_edges_sg[offset + loc] = n_edges; + subgroup_reduce[offset + loc] = assigned_vertex; + subgroup_ids[offset + loc] = lid; } + visited[lid] = false; + } else { + visited[lid] = true; + } - sycl::group_barrier(wgroup); - for (size_t i = 0; i < wg_tail.load(); i++) { - auto vertex = workgroup_reduce[i]; - size_t n_edges = n_edges_wg[i]; - auto start = graph_dev.begin(vertex); // GRAPH edge iterator - - for (auto j = lid; j < n_edges; j += wgroup_size) { - auto n = start + j; - auto edge = n.get_index(); // GRAPH edge index - auto weight = graph_dev.get_weight(edge); // GRAPH edge weight - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } - } - - if (wgroup.leader()) { visited[workgroup_ids[i]] = true; } + sycl::group_barrier(wgroup); + for (size_t i = 0; i < wg_tail.load(); i++) { + auto vertex = workgroup_reduce[i]; + size_t n_edges = n_edges_wg[i]; + auto start = graph_dev.begin(vertex); + + for (auto j = lid; j < n_edges; j += wgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(neighbor); } } - sycl::group_barrier(sgroup); + if (wgroup.leader()) { visited[workgroup_ids[i]] = true; } + } - for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size - size_t vertex_id = offset + i; - auto vertex = subgroup_reduce[vertex_id]; - size_t n_edges = n_edges_sg[vertex_id]; + sycl::group_barrier(sgroup); - auto start = graph_dev.begin(vertex); // GRAPH edge iterator + for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size + size_t vertex_id = offset + i; + auto vertex = subgroup_reduce[vertex_id]; + size_t n_edges = n_edges_sg[vertex_id]; - for (auto j = llid; j < n_edges; j += sgroup_size) { - auto n = start + j; - auto edge = n.get_index(); // GRAPH edge index - auto weight = graph_dev.get_weight(edge); // GRAPH edge weight - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } - } + auto start = graph_dev.begin(vertex); - if (sgroup.leader()) { visited[subgroup_ids[vertex_id]] = true; } + for (auto j = llid; j < n_edges; j += sgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(neighbor); } } - sycl::group_barrier(sgroup); - - if (!visited[lid]) { - auto vertex = assigned_vertex; - auto start = graph_dev.begin(vertex); // GRAPH edge iterator - auto end = graph_dev.end(vertex); // GRAPH edge iterator - - for (auto n = start; n != end; ++n) { - auto edge = n.get_index(); // GRAPH edge index - auto weight = graph_dev.get_weight(edge); // GRAPH edge weight - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } - } + + if (sgroup.leader()) { visited[subgroup_ids[vertex_id]] = true; } + } + sycl::group_barrier(sgroup); + + if (!visited[lid]) { + auto vertex = assigned_vertex; + auto start = graph_dev.begin(vertex); + auto end = graph_dev.end(vertex); + + for (auto n = start; n != end; ++n) { + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(neighbor); } } - context.complete_iteration(state); } } @@ -176,39 +163,30 @@ template sycl::event advance(const GraphT& graph, frontier& in, frontier& out, LambdaT&& functor, size_t expected_size = 0) { + using element_t = FrontierSizeT; + sycl::queue& q = graph.get_queue(); size_t num_nodes = graph.get_vertex_count(); - using element_t = FrontierSizeT; - // using element_t = std::conditional_t; - auto in_dev_frontier = in.get_device_view(); auto out_dev_frontier = out.get_device_view(); - auto graph_dev = graph.get_device_view(); // GRAPH device view - - size_t coarsening_factor = 256 /*CU size*/ / 16 /*Subgroup Size*/; - - sycl::event to_wait; - sycl::range<1> local_range; - size_t global_size; - size_t bitmap_range = in_dev_frontier.get_element_bitsize(); - to_wait = in.compute_active_frontier(); - local_range = {bitmap_range * coarsening_factor}; - if (expected_size > 0) { - global_size = {expected_size + (local_range[0] - (expected_size % local_range[0]))}; - } else { - global_size = {local_range[0] * 128}; - // global_size = {local_range[0] * (sygraph::detail::device::getMaxComputeUints(q) * 8)}; - } - - sycl::range<1> global_range{global_size > local_range[0] ? global_size + (local_range[0] - (global_size % local_range[0])) : local_range[0]}; + auto graph_dev = graph.get_device_view(); + + size_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups + + size_t element_bitsize = in_dev_frontier.get_element_bitsize(); + sycl::event to_wait = in.compute_active_frontier(); + size_t offset_size = in.get_offsets_size().at_device(q, 0, {to_wait}); + sycl::range<1> local_range = {element_bitsize * coarsening_factor}; + size_t global_size = offset_size * element_bitsize; + + sycl::range<1> global_range{(global_size % local_range[0] == 0) ? global_size : global_size + (local_range[0] - global_size % local_range[0])}; Context context{num_nodes, in_dev_frontier, out_dev_frontier}; using bitmap_kernel_t = BitmapKernel; - const uint32_t max_num_subgroups = 32; - // const uint32_t max_num_subgroups = sygraph::detail::device::getMaxNumSubgroups(q); + const uint32_t max_num_subgroups = device_max_sg_count(q); auto e = q.submit([&](sycl::handler& cgh) { cgh.depends_on(to_wait); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 05c7c310967..0d9a599bf74 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -1,6 +1,7 @@ #pragma once #include "oneapi/dal/common.hpp" +#include "oneapi/dal/backend/common.hpp" #include "oneapi/dal/graph/detail/common.hpp" #include "oneapi/dal/graph/detail/container.hpp" #include "oneapi/dal/backend/primitives/bitset.hpp" @@ -172,7 +173,7 @@ class frontier { auto offsets_pointer = _offsets.get_mutable_data() + 1; uint32_t element_bitsize = decltype(bitmap._mlb_layer)::element_bitsize; - size_t local_range = 1024; // Adjust as needed + size_t local_range = propose_wg_size(this->_queue); size_t global_range = _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp index 0dc930e28a0..750ff18b4e7 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp @@ -26,56 +26,69 @@ void print_frontier(const T* data, size_t count, size_t num_items) { } } +std::vector compute_next_frontier(std::vector& row_ptr, + std::vector& col_indices, + std::vector& frontier) { + std::vector next_frontier; + + for (auto node : frontier) { + auto start = row_ptr[node]; + auto end = row_ptr[node + 1]; + + for (size_t i = start; i < end; ++i) { + auto neighbor = col_indices[i]; + next_frontier.push_back(neighbor); + } + } + // Remove duplicates + std::sort(next_frontier.begin(), next_frontier.end()); + next_frontier.erase(std::unique(next_frontier.begin(), next_frontier.end()), next_frontier.end()); + return next_frontier; +} + +template +void compare_frontiers(T& device_frontier, std::vector& host_frontier, size_t num_nodes) { + for (size_t i = 0; i < num_nodes; ++i) { + bool tmpd = device_frontier.check(i); + bool tmph = std::find(host_frontier.begin(), host_frontier.end(), i) != host_frontier.end(); + if (tmpd != tmph) { + std::cout << "Mismatch at vertex " << i << ": device = " << tmpd << ", host = " << tmph << std::endl; + + } + REQUIRE(tmpd == tmph); + } +} + TEST("test advance operation", "[advance]") { DECLARE_TEST_POLICY(policy); auto& queue = policy.get_queue(); print_device_name(queue); - std::vector row_ptr = {0, 2, 4, 6}; - std::vector col_indices = {1, 2, 0, 2, 0, 1}; - std::vector weights = {1, 1, 1, 1, 1, 1}; - - auto graph = csr_graph(queue, row_ptr, col_indices, weights); - auto first_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - auto second_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - auto third_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - - first_frontier.insert(0); + // std::vector row_ptr = {0, 2, 4, 6}; + // std::vector col_indices = {1, 2, 0, 2, 0, 1}; + // std::vector weights = {1, 1, 1, 1, 1, 1}; + std::vector row_ptr = {0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, 485, 489, 493, 497, 501, 504, 506}; + std::vector col_indices = {1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, 125, 126}; + std::vector weights(col_indices.size(), 1); + size_t num_nodes = row_ptr.size() - 1; - REQUIRE(first_frontier.check(0) == true); - REQUIRE(first_frontier.check(1) == false); - REQUIRE(first_frontier.check(2) == false); - - std::cout << "First Frontier: "; - for (size_t i = 0; i < graph.get_vertex_count(); ++i) { - std::cout << "Vertex " << i << ": " << (first_frontier.check(i) ? "in frontier" : "not in frontier") << std::endl; - } - advance(graph, first_frontier, second_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { - return true; // Always advance - }).wait_and_throw(); - - REQUIRE(second_frontier.check(0) == false); - REQUIRE(second_frontier.check(1) == true); - REQUIRE(second_frontier.check(2) == true); + auto graph = csr_graph(queue, row_ptr, col_indices, weights); + auto in_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + auto out_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - std::cout << "Second Frontier: "; - for (size_t i = 0; i < graph.get_vertex_count(); ++i) { - std::cout << "Vertex " << i << ": " << (second_frontier.check(i) ? "in frontier" : "not in frontier") << std::endl; - } + in_frontier.insert(3); + in_frontier.insert(4); + in_frontier.insert(52); + in_frontier.insert(100); + std::vector host_frontier = {3, 4, 52, 100}; - advance(graph, second_frontier, third_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { + advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { return true; // Always advance }).wait_and_throw(); - - std::cout << "Third Frontier: "; - for (size_t i = 0; i < graph.get_vertex_count(); ++i) { - std::cout << "Vertex " << i << ": " << (third_frontier.check(i) ? "in frontier" : "not in frontier") << std::endl; - } - - REQUIRE(third_frontier.check(0) == true); - REQUIRE(third_frontier.check(1) == true); - REQUIRE(third_frontier.check(2) == true); + + auto tmp_frontier = compute_next_frontier(row_ptr, col_indices, host_frontier); + compare_frontiers(out_frontier, tmp_frontier, num_nodes); } // TEST "test advance operation" From 80835a60f16c13662ce22c3d4375bcb5b60f1761 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 23 Jul 2025 17:48:35 +0200 Subject: [PATCH 10/69] implemented async advance --- .../primitives/frontier/advance_dpc.hpp | 201 +++++++++++------- 1 file changed, 120 insertions(+), 81 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index b0530a26373..d590288a24e 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -7,6 +7,9 @@ namespace oneapi::dal::backend::primitives { +/// ContextState holds the state of the current processing group in the kernel +/// It includes the group offset, coarsening factor, offsets size, and the SYCL +/// nd_item for the current work item. struct ContextState { size_t group_offset; const uint16_t coarsening_factor; @@ -14,6 +17,12 @@ struct ContextState { const sycl::nd_item<1> item; }; +/// Context is a template class that provides an interface for the kernel to +/// interact with the frontier data structure. It holds the limit of the graph, +/// the input frontier, and the output frontier. It provides methods to initialize +/// the context state, check if there are more elements to process, get the +/// assigned element, check if a vertex is in the frontier, and insert a vertex +/// into the output frontier. template struct Context { size_t limit; @@ -26,37 +35,47 @@ struct Context { inline ContextState init(sycl::nd_item<1>& item) const { return { item.get_group_linear_id(), - static_cast(item.get_local_range(0) / in_dev_frontier.getBitmapRange()), - in_dev_frontier.getOffsetsSize()[0], + static_cast(item.get_local_range(0) / in_dev_frontier.get_element_bitsize()), + in_dev_frontier.get_offsets_size()[0], item, }; } - inline size_t get_assigned_element(sycl::nd_item<1> item) const { + /// This method checks if there are more elements to process in the current group. + inline bool need_to_process(ContextState& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } + + /// This method completes the current iteration by updating the group offset. + inline void complete_iteration(ContextState& state) const { state.group_offset += state.item.get_group_range(0); } + + /// This method retrieves the assigned element for the current work item. + inline size_t get_assigned_element(const ContextState& state) const { const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); - const auto* bitmap_offsets = in_dev_frontier.get_offsets(); - const size_t coarsening_factor = item.get_local_range(0) / element_bitsize; - const uint32_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / element_bitsize); - const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + (item.get_local_linear_id() % element_bitsize); + const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / element_bitsize); + const uint32_t* bitmap_offsets = in_dev_frontier.get_offsets(); + // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); + const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + (state.item.get_local_linear_id() % element_bitsize); return assigned_vertex; } - inline bool check(sycl::nd_item<1> item, size_t vertex) const { - return vertex < limit && in_dev_frontier.check(vertex); + /// This method checks if a vertex is in the input frontier. + inline bool check(const ContextState& state, size_t vertex) const { + return vertex < limit && in_dev_frontier.check(vertex); } - inline void insert(size_t vertex) const { + /// This method inserts a vertex into the output frontier. + inline void insert(const ContextState& state, size_t vertex) const { out_dev_frontier.insert(vertex); } }; +/// BitmapKernel is a template struct that defines the kernel to be executed on the device. +/// It processes the input frontier and advances it based on the provided functor. template struct BitmapKernel { void operator()(sycl::nd_item<1> item) const { - // 0. retrieve global and local ids const size_t lid = item.get_local_linear_id(); const auto wgroup = item.get_group(); const size_t wgroup_size = wgroup.get_local_range(0); @@ -65,83 +84,92 @@ struct BitmapKernel { const size_t sgroup_size = sgroup.get_local_range()[0]; const size_t llid = sgroup.get_local_linear_id(); - const auto assigned_vertex = context.get_assigned_element(item); - - // 1. load number of edges in local memory - if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; } - if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } - - sycl::atomic_ref sg_tail{subgroup_reduce_tail[sgroup_id]}; - sycl::atomic_ref wg_tail{workgroup_reduce_tail[0]}; - - const uint32_t offset = sgroup_id * sgroup_size; - if (context.check(item, assigned_vertex)) { - uint32_t n_edges = graph_dev.get_degree(assigned_vertex); - if (n_edges >= wgroup_size * wgroup_size) { // assign to the workgroup - uint32_t loc = wg_tail.fetch_add(static_cast(1)); - n_edges_wg[loc] = n_edges; - workgroup_reduce[loc] = assigned_vertex; - workgroup_ids[loc] = lid; - } else if (n_edges >= sgroup_size) { // assign to the subgroup - uint32_t loc = sg_tail.fetch_add(static_cast(1)); - n_edges_sg[offset + loc] = n_edges; - subgroup_reduce[offset + loc] = assigned_vertex; - subgroup_ids[offset + loc] = lid; + auto state = context.init(item); + + while (context.need_to_process(state)) { + const auto assigned_vertex = context.get_assigned_element(state); + + if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; } + if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } + + sycl::atomic_ref sg_tail{subgroup_reduce_tail[sgroup_id]}; + sycl::atomic_ref wg_tail{workgroup_reduce_tail[0]}; + + // 1. distribute the workload based on the number of edges to the workgroup, subgroup or workitem + const uint32_t offset = sgroup_id * sgroup_size; + if (context.check(state, assigned_vertex)) { + uint32_t n_edges = graph_dev.get_degree(assigned_vertex); + if (n_edges >= wgroup_size * wgroup_size) { // if the number of edges is large enough, we can assign the vertex to the workgroup + uint32_t loc = wg_tail.fetch_add(static_cast(1)); + n_edges_wg[loc] = n_edges; + workgroup_reduce[loc] = assigned_vertex; + workgroup_ids[loc] = lid; + } else if (n_edges >= sgroup_size) { // assign to the subgroup + uint32_t loc = sg_tail.fetch_add(static_cast(1)); + n_edges_sg[offset + loc] = n_edges; + subgroup_reduce[offset + loc] = assigned_vertex; + subgroup_ids[offset + loc] = lid; + } + visited[lid] = false; + } else { + visited[lid] = true; } - visited[lid] = false; - } else { - visited[lid] = true; - } - sycl::group_barrier(wgroup); - for (size_t i = 0; i < wg_tail.load(); i++) { - auto vertex = workgroup_reduce[i]; - size_t n_edges = n_edges_wg[i]; - auto start = graph_dev.begin(vertex); - - for (auto j = lid; j < n_edges; j += wgroup_size) { - auto n = start + j; - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(neighbor); } + sycl::group_barrier(wgroup); + + // 2. process the the edge of one vertex at a time using the workgroup + for (size_t i = 0; i < wg_tail.load(); i++) { + auto vertex = workgroup_reduce[i]; + size_t n_edges = n_edges_wg[i]; + auto start = graph_dev.begin(vertex); + + for (auto j = lid; j < n_edges; j += wgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } + } + + if (wgroup.leader()) { visited[workgroup_ids[i]] = true; } } - if (wgroup.leader()) { visited[workgroup_ids[i]] = true; } - } + sycl::group_barrier(sgroup); - sycl::group_barrier(sgroup); + // 3. process the edges of one vertex at a time using the subgroup + for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size + size_t vertex_id = offset + i; + auto vertex = subgroup_reduce[vertex_id]; + size_t n_edges = n_edges_sg[vertex_id]; - for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size - size_t vertex_id = offset + i; - auto vertex = subgroup_reduce[vertex_id]; - size_t n_edges = n_edges_sg[vertex_id]; + auto start = graph_dev.begin(vertex); - auto start = graph_dev.begin(vertex); + for (auto j = llid; j < n_edges; j += sgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } + } - for (auto j = llid; j < n_edges; j += sgroup_size) { - auto n = start + j; - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(neighbor); } + if (sgroup.leader()) { visited[subgroup_ids[vertex_id]] = true; } } - - if (sgroup.leader()) { visited[subgroup_ids[vertex_id]] = true; } - } - sycl::group_barrier(sgroup); - - if (!visited[lid]) { - auto vertex = assigned_vertex; - auto start = graph_dev.begin(vertex); - auto end = graph_dev.end(vertex); - - for (auto n = start; n != end; ++n) { - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(neighbor); } + sycl::group_barrier(sgroup); + + // 4. process the edges of the vertices that were not assigned to the workgroup or subgroup + if (!visited[lid]) { + auto vertex = assigned_vertex; + auto start = graph_dev.begin(vertex); + auto end = graph_dev.end(vertex); + + for (auto n = start; n != end; ++n) { + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } + } } + context.complete_iteration(state); // complete the current iteration } } @@ -159,6 +187,11 @@ struct BitmapKernel { const LambdaT functor; }; +/// advance is a function that launches the BitmapKernel on the device to advance the frontier. +/// It takes the graph, input frontier, output frontier, and the functor. +/// The expected_size parameter is used to specify the expected size of the input frontier, in order +/// to optimize the kernel launch parameters. If expected_size is zero, a default size is used. +/// It returns a sycl::event that can be used to synchronize the execution. template @@ -176,10 +209,16 @@ sycl::event advance(const GraphT& graph, frontier& in, frontier local_range = {element_bitsize * coarsening_factor}; - size_t global_size = offset_size * element_bitsize; + size_t global_size; + + if (expected_size > 0) { + global_size = expected_size * element_bitsize; + } else { + global_size = 1024; // This parameter should be tuned according to the device capabilities + } + + sycl::event to_wait = in.compute_active_frontier(); sycl::range<1> global_range{(global_size % local_range[0] == 0) ? global_size : global_size + (local_range[0] - global_size % local_range[0])}; From 944d754db653244d18222ad19ebe9546246c2788 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 23 Jul 2025 18:28:03 +0200 Subject: [PATCH 11/69] add documentation for frontier --- cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp index 0d9a599bf74..bd94141a91c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp @@ -9,6 +9,7 @@ namespace oneapi::dal::backend::primitives { +/// @brief A view of a frontier that provides an interface for the kernel to interact with the frontier data structure. template struct frontier_view { using bitmap_t = ElementType; @@ -66,6 +67,7 @@ struct frontier_view { #ifdef ONEDAL_DATA_PARALLEL +/// @brief The Two-Layer bitmap frontier class template class frontier { using bitmap_t = ElementType; @@ -166,6 +168,10 @@ class frontier { e2.wait_and_throw(); } + /// @brief Computes the active frontier by filling the offsets array with the indices of the active vertices. + /// It returns a sycl::event that can be used to synchronize the execution. + /// The offsets array is filled with the indices of the active vertices in the first layer of the frontier. + /// This is used by the primitives to understand which vertices are active in the frontier. sycl::event compute_active_frontier() const { auto bitmap = this->get_device_view(); From 8cbd1feace9077c1da140d130e0ac809a788da74 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Fri, 25 Jul 2025 16:07:42 +0200 Subject: [PATCH 12/69] Refactor frontier implementation and add tests - Removed the existing frontier_dpc.hpp file to streamline the codebase. - Introduced new test files for advance operation, BFS, and basic frontier operations. - Implemented comprehensive tests to validate the functionality of the frontier data structure. - Enhanced the frontier class with additional methods for better performance and usability. - Ensured compatibility with SYCL and improved device memory management. --- cpp/oneapi/dal/backend/primitives/BUILD | 2 + .../dal/backend/primitives/frontier.hpp | 2 +- .../dal/backend/primitives/frontier/BUILD | 14 +- .../primitives/frontier/advance_dpc.hpp | 2 +- .../backend/primitives/frontier/frontier.hpp | 145 +++++++++ .../primitives/frontier/frontier_dpc.cpp | 194 ++++++++++++ .../primitives/frontier/frontier_dpc.hpp | 292 ------------------ ...vance_frontier_dpc.cpp => advance_dpc.cpp} | 14 +- .../primitives/frontier/test/bfs_dpc.cpp | 90 ++++++ ..._frontier_ops_dpc.cpp => frontier_dpc.cpp} | 10 +- 10 files changed, 453 insertions(+), 312 deletions(-) create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp delete mode 100644 cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp rename cpp/oneapi/dal/backend/primitives/frontier/test/{advance_frontier_dpc.cpp => advance_dpc.cpp} (90%) create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp rename cpp/oneapi/dal/backend/primitives/frontier/test/{basic_frontier_ops_dpc.cpp => frontier_dpc.cpp} (87%) diff --git a/cpp/oneapi/dal/backend/primitives/BUILD b/cpp/oneapi/dal/backend/primitives/BUILD index c7241ade6af..2fc9e2cb5ca 100644 --- a/cpp/oneapi/dal/backend/primitives/BUILD +++ b/cpp/oneapi/dal/backend/primitives/BUILD @@ -37,6 +37,7 @@ dal_collect_modules( "lapack", "optimizers", "objective_function", + "frontier", "placement", "reduction", "regression", @@ -88,6 +89,7 @@ dal_collect_test_suites( "lapack", "optimizers", "objective_function", + "frontier", "placement", "reduction", "regression", diff --git a/cpp/oneapi/dal/backend/primitives/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier.hpp index 9e35cff3f12..245ef5b7f91 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier.hpp @@ -1,3 +1,3 @@ -#include "oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/backend/primitives/frontier/advance_dpc.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD index 394618090e5..1a224d76188 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/BUILD +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -6,7 +6,13 @@ load("@onedal//dev/bazel:dal.bzl", dal_module ( name = "frontier", - auto = True + auto = True, + dal_deps = [ + "@onedal//cpp/oneapi/dal/backend/primitives:common", + "@onedal//cpp/oneapi/dal/backend/primitives:blas", + "@onedal//cpp/oneapi/dal/backend/primitives/optimizers", + "@onedal//cpp/oneapi/dal/backend/primitives:sparse_blas", + ], ) dal_test_suite ( @@ -14,16 +20,10 @@ dal_test_suite ( framework = "catch2", compile_as = [ "dpc++" ], private = True, - # hdrs = glob([ - # "test/*.hpp", - # ]), srcs = glob([ "test/*_dpc.cpp", - ], exclude=[ - "test/*perf*.cpp", ]), dal_deps = [ ":frontier", - "@onedal//cpp/oneapi/dal/backend/primitives:rng", ], ) \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index d590288a24e..ef91511d661 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -2,7 +2,7 @@ #include "oneapi/dal/backend/primitives/ndarray.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" -#include "oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/frontier.hpp" namespace oneapi::dal::backend::primitives { diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp new file mode 100644 index 00000000000..5de56bc2fde --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -0,0 +1,145 @@ +#pragma once + +#include "oneapi/dal/common.hpp" +#include "oneapi/dal/backend/common.hpp" +#include "oneapi/dal/graph/detail/common.hpp" +#include "oneapi/dal/graph/detail/container.hpp" +#include "oneapi/dal/backend/primitives/bitset.hpp" +#include "oneapi/dal/backend/primitives/ndarray.hpp" + +namespace oneapi::dal::backend::primitives { + +/// @brief A view of a frontier that provides an interface for the kernel to interact with the frontier data structure. +template +class frontier_view { +public: + using bitmap_t = ElementType; + static constexpr std::size_t divide_factor = bitset::element_bitsize; + + frontier_view() = default; + frontier_view(bitmap_t* data_layer, + bitmap_t* mlb_layer, + std::uint32_t* offsets, + std::uint32_t* offsets_size, + size_t num_items) + : _num_items(num_items), + _data_layer(bitset{data_layer}), + _mlb_layer(bitset{mlb_layer}), + _offsets(offsets), + _offsets_size(offsets_size) {} + + inline void insert(std::uint32_t idx) const { + if (!_data_layer.test(idx)) { + _data_layer.atomic_set(idx); + } + if (!_mlb_layer.test(idx / divide_factor)) { + _mlb_layer.atomic_set(idx / divide_factor); + } + } + + inline void remove(std::uint32_t idx) const { + throw dal::domain_error("Frontier does not support remove operation"); + } + + inline bool check(std::uint32_t idx) const { + return _data_layer.atomic_test(idx); + } + + inline size_t get_element_bitsize() const { + return bitset::element_bitsize; + } + + inline std::uint32_t* get_offsets() const { + return _offsets; + } + + inline std::uint32_t* get_offsets_size() const { + return _offsets_size; + } + +private: + size_t _num_items; + + bitset _data_layer; + bitset _mlb_layer; + + std::uint32_t* _offsets; + std::uint32_t* _offsets_size; +}; + +/// @brief The Two-Layer bitmap frontier class +template +class frontier { + using buffer_t = std::uint32_t; + +public: + frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc = sycl::usm::alloc::shared); + + const frontier_view get_device_view() const { + auto offsets_size_pointer = _offsets.get_mutable_data(); + auto offsets_pointer = _offsets.get_mutable_data() + 1; + + return { _data_layer.get_mutable_data(), + _mlb_layer.get_mutable_data(), + offsets_pointer, + offsets_size_pointer, + static_cast(_data_layer.get_count()) }; + } + + inline ndview get_data() const { + return _data_layer; + } + + inline ndview get_mlb() const { + return _mlb_layer; + } + + inline ndview get_offsets() const { + return _offsets.slice(1, _offsets.get_count()); + } + + inline ndview get_offsets_size() const { + return _offsets.slice(0, 1); + } + + bool empty(); + + void insert(ElementType idx); + + bool check(ElementType idx); + + void clear(); + + /// @brief Computes the active frontier by filling the offsets array with the indices of the active vertices. + /// It returns a sycl::event that can be used to synchronize the execution. + /// The offsets array is filled with the indices of the active vertices in the first layer of the frontier. + /// This is used by the primitives to understand which vertices are active in the frontier. + sycl::event compute_active_frontier(); + + static void swap(frontier& f1, frontier& f2) { + using std::swap; + swap(f1._data_layer, f2._data_layer); + swap(f1._mlb_layer, f2._mlb_layer); + swap(f1._offsets, f2._offsets); + swap(f1._queue, f2._queue); + swap(f1._num_items, f2._num_items); + } + +private: + sycl::queue& _queue; + size_t _num_items; + + ndarray _data_layer; + ndarray _mlb_layer; + ndarray _offsets; + ndarray _buffer; + const size_t _TMP_VAR = 0; + const size_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) +}; + +template +void swap_frontiers(frontier& f1, frontier& f2) { + frontier::swap(f1, f2); +} + +} // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp new file mode 100644 index 00000000000..bbda488a7f9 --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -0,0 +1,194 @@ + +#include "oneapi/dal/backend/primitives/frontier/frontier.hpp" +#include "oneapi/dal/backend/common.hpp" +#include "oneapi/dal/backend/primitives/ndarray.hpp" +#include "oneapi/dal/graph/detail/common.hpp" + +namespace oneapi::dal::backend::primitives { + +#ifdef ONEDAL_DATA_PARALLEL + +template +frontier::frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc) : _queue(queue), _num_items(num_items) { + std::int64_t array_size = + (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; + std::int64_t mlb_size = (array_size + bitset::element_bitsize - 1) / + bitset::element_bitsize; + _data_layer = + ndarray::empty(_queue, { array_size }, alloc); + _mlb_layer = + ndarray::empty(_queue, { mlb_size }, alloc); + _offsets = + ndarray::empty(_queue, { array_size + 1 }, alloc); /// First offset is to keep the size of the frontier + _buffer = ndarray::empty(_queue, { 10 }, alloc); + + sycl::event e1, e2, e3; + e1 = _data_layer.fill(_queue, ElementType(0)); + e2 = _mlb_layer.fill(_queue, ElementType(0)); + e3 = _offsets.fill(_queue, std::uint32_t(0)); + + e1.wait_and_throw(); + e2.wait_and_throw(); + e3.wait_and_throw(); +} + +template +bool frontier::empty() { + ndview empty_buff = _buffer.slice(0, 1); + auto copy_e = fill(_queue, empty_buff, buffer_t(0)); + auto* const empty_buff_ptr = empty_buff.get_mutable_data(); + + auto e = _queue.submit([&](sycl::handler& cgh) { + cgh.depends_on(copy_e); + const auto range = make_range_1d(_mlb_layer.get_count()); + auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); + auto* const f_ptr = _mlb_layer.get_mutable_data(); + + cgh.parallel_for(range, sum_reduction, [=](sycl::id<1> idx, auto& sum_v) { + sum_v += f_ptr[idx]; + }); + }); + auto empty_sum = empty_buff.at_device(_queue, 0, { e }); + return empty_sum == 0; +} + +template +inline void frontier::insert(ElementType idx) { + auto view = this->get_device_view(); + _queue.submit([&](sycl::handler& cgh) { + cgh.single_task([=]() { + view.insert(idx); + }); + }).wait_and_throw(); +} + +template +inline bool frontier::check(ElementType idx) { + ElementType tmp_data = _data_layer.at_device(_queue, idx / bitset::element_bitsize); + return (tmp_data & (static_cast(1) << (idx % bitset::element_bitsize))) != 0; +} + +template +inline void frontier::clear() { + auto e = _data_layer.fill(_queue, ElementType(0)); + auto e1 = _mlb_layer.fill(_queue, ElementType(0)); + auto e2 = _offsets.fill(_queue, ElementType(0)); + e.wait_and_throw(); + e1.wait_and_throw(); + e2.wait_and_throw(); +} + +template +inline sycl::event frontier::compute_active_frontier() { + auto bitmap = this->get_device_view(); + + auto offsets_size_pointer = _offsets.get_mutable_data(); + auto offsets_pointer = _offsets.get_mutable_data() + 1; + + uint32_t element_bitsize = bitmap.get_element_bitsize(); + size_t local_range = propose_wg_size(this->_queue); + size_t global_range = + _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); + + bool use_local_mem = + device_local_mem_size(this->_queue) >= static_cast(local_range * element_bitsize * sizeof(uint32_t)); + + auto e0 = _queue.submit([&](sycl::handler& cgh) { + cgh.single_task([=, offsets_size = this->get_offsets_size().get_mutable_data(), buffer_ptr = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG]() { + buffer_ptr[CAF_FLAG] = offsets_size[0] == 0 ? 1 : 0; + }); + }); + + auto e1 = this->_queue.submit([&](sycl::handler& cgh) { + cgh.depends_on(e0); + + if (!use_local_mem || true) { // Force to use global memory for simplicity + cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), + [=, + offsets = offsets_pointer, + offsets_size = offsets_size_pointer, + data_layer = this->_mlb_layer.get_mutable_data(), + buffer = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG](sycl::id<1> idx) { + + if (!buffer[CAF_FLAG]) return; + + sycl::atomic_ref + offsets_size_ref{ offsets_size[0] }; + + ElementType data = data_layer[idx]; + for (size_t i = 0; i < element_bitsize; i++) { + if (data & (static_cast(1) << i)) { + offsets[offsets_size_ref++] = i + idx * element_bitsize; + } + } + }); + } else { + sycl::local_accessor local_offsets(local_range * element_bitsize, cgh); + sycl::local_accessor local_size(1, cgh); + + cgh.parallel_for( + make_multiple_nd_range_1d(global_range, local_range), + [=, + offsets = offsets_pointer, + offsets_size = offsets_size_pointer, + data_layer = this->_mlb_layer.get_mutable_data(), + size = this->_num_items, + buffer = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { + if (!buffer[CAF_FLAG]) return; + + auto group = item.get_group(); + sycl::atomic_ref + local_size_ref{ local_size[0] }; + sycl::atomic_ref + offsets_size_ref{ offsets_size[0] }; + + if (group.leader()) { + local_size_ref.store(0); + } + sycl::group_barrier(group); + for (uint32_t gid = item.get_global_linear_id(); gid < size; + gid += local_range) { + ElementType data = data_layer[gid]; + for (size_t i = 0; i < element_bitsize; i++) { + if (data & (static_cast(1) << i)) { + local_offsets[local_size_ref++] = i + gid * element_bitsize; + } + } + } + + sycl::group_barrier(group); + + size_t data_offset = 0; + if (group.leader()) { + data_offset = offsets_size_ref.fetch_add(local_size_ref.load()); + } + data_offset = sycl::group_broadcast(group, data_offset, 0); + for (size_t i = item.get_local_linear_id(); i < local_size_ref.load(); + i += item.get_local_range(0)) { + offsets[data_offset + i] = local_offsets[i]; + } + }); + } + + }); + return e1; + +} + +#define INSTANTIATE(F) \ + template class frontier; + +INSTANTIATE(std::uint64_t) +INSTANTIATE(std::uint32_t) + +#endif + +} // namespace oneapi::dal::backend::primitives \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp deleted file mode 100644 index bd94141a91c..00000000000 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.hpp +++ /dev/null @@ -1,292 +0,0 @@ -#pragma once - -#include "oneapi/dal/common.hpp" -#include "oneapi/dal/backend/common.hpp" -#include "oneapi/dal/graph/detail/common.hpp" -#include "oneapi/dal/graph/detail/container.hpp" -#include "oneapi/dal/backend/primitives/bitset.hpp" -#include "oneapi/dal/backend/primitives/ndarray.hpp" - -namespace oneapi::dal::backend::primitives { - -/// @brief A view of a frontier that provides an interface for the kernel to interact with the frontier data structure. -template -struct frontier_view { - using bitmap_t = ElementType; - static constexpr std::size_t divide_factor = bitset::element_bitsize; - - frontier_view() = default; - frontier_view(bitmap_t* data_layer, - bitmap_t* mlb_layer, - std::uint32_t* offsets, - std::uint32_t* offsets_size, - size_t num_items) - : _num_items(num_items), - _data_layer(bitset{data_layer}), - _mlb_layer(bitset{mlb_layer}), - _offsets(offsets), - _offsets_size(offsets_size) {} - - inline void insert(std::uint32_t idx) const { - if (!_data_layer.test(idx)) { - _data_layer.atomic_set(idx); - } - if (!_mlb_layer.test(idx / divide_factor)) { - _mlb_layer.atomic_set(idx / divide_factor); - } - } - - inline void remove(std::uint32_t idx) const { - throw dal::domain_error("Frontier does not support remove operation"); - } - - inline bool check(std::uint32_t idx) const { - return _data_layer.atomic_test(idx); - } - - inline size_t get_element_bitsize() const { - return bitset::element_bitsize; - } - - inline std::uint32_t* get_offsets() const { - return _offsets; - } - - inline std::uint32_t* get_offsets_size() const { - return _offsets_size; - } - - size_t _num_items; - - bitset _data_layer; - bitset _mlb_layer; - - std::uint32_t* _offsets; - std::uint32_t* _offsets_size; -}; - -#ifdef ONEDAL_DATA_PARALLEL - -/// @brief The Two-Layer bitmap frontier class -template -class frontier { - using bitmap_t = ElementType; - using buffer_t = std::uint32_t; - -public: - frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc = sycl::usm::alloc::shared) : _queue(queue), _num_items(num_items) { - std::int64_t array_size = - (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; - std::int64_t mlb_size = (array_size + bitset::element_bitsize - 1) / - bitset::element_bitsize; - _data_layer = - ndarray::empty(_queue, { array_size }, alloc); - _mlb_layer = - ndarray::empty(_queue, { mlb_size }, alloc); - _offsets = - ndarray::empty(_queue, { array_size + 1 }, alloc); /// First offset is to keep the size of the frontier - _buffer = ndarray::empty(_queue, { 10 }, alloc); - - sycl::event e1, e2, e3; - e1 = _data_layer.fill(_queue, bitmap_t(0)); - e2 = _mlb_layer.fill(_queue, bitmap_t(0)); - e3 = _offsets.fill(_queue, buffer_t(0)); - - e1.wait_and_throw(); - e2.wait_and_throw(); - e3.wait_and_throw(); - } - - const frontier_view get_device_view() const { - auto offsets_size_pointer = _offsets.get_mutable_data(); - auto offsets_pointer = _offsets.get_mutable_data() + 1; - - return frontier_view(_data_layer.get_mutable_data(), - _mlb_layer.get_mutable_data(), - offsets_pointer, - offsets_size_pointer, - _data_layer.get_count()); - } - - inline ndview get_data() const { - return _data_layer; - } - - inline ndview get_mlb() const { - return _mlb_layer; - } - - inline ndview get_offsets() const { - return _offsets.slice(1, _offsets.get_count()); - } - - inline ndview get_offsets_size() const { - return _offsets.slice(0, 1); - } - - bool empty() const { - ndview empty_buff = _buffer.slice(0, 1); - auto copy_e = fill(_queue, empty_buff, buffer_t(0)); - auto* const empty_buff_ptr = empty_buff.get_mutable_data(); - - auto e = _queue.submit([&](sycl::handler& cgh) { - cgh.depends_on(copy_e); - const auto range = make_range_1d(_mlb_layer.get_count()); - auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); - auto* const f_ptr = _mlb_layer.get_mutable_data(); - - cgh.parallel_for(range, sum_reduction, [=](sycl::id<1> idx, auto& sum_v) { - sum_v += f_ptr[idx]; - }); - }); - auto empty_sum = empty_buff.at_device(_queue, 0, { e }); - return empty_sum == 0; - } - - void insert(bitmap_t idx) { - auto view = this->get_device_view(); - _queue.submit( - [&](sycl::handler& cgh) { - cgh.single_task([=]() { - view.insert(idx); - }); - } - ).wait_and_throw(); - } - - bool check(bitmap_t idx) const { - bitmap_t tmp_data = _data_layer.at_device(_queue, idx / bitset::element_bitsize); - return (tmp_data & (static_cast(1) << (idx % bitset::element_bitsize))) != 0; - } - - void clear() { - auto e = fill(_queue, _data_layer, bitmap_t(0)); - auto e1 = fill(_queue, _mlb_layer, bitmap_t(0)); - auto e2 = fill(_queue, _offsets, buffer_t(0)); - e.wait_and_throw(); - e1.wait_and_throw(); - e2.wait_and_throw(); - } - - /// @brief Computes the active frontier by filling the offsets array with the indices of the active vertices. - /// It returns a sycl::event that can be used to synchronize the execution. - /// The offsets array is filled with the indices of the active vertices in the first layer of the frontier. - /// This is used by the primitives to understand which vertices are active in the frontier. - sycl::event compute_active_frontier() const { - auto bitmap = this->get_device_view(); - - auto offsets_size_pointer = _offsets.get_mutable_data(); - auto offsets_pointer = _offsets.get_mutable_data() + 1; - - uint32_t element_bitsize = decltype(bitmap._mlb_layer)::element_bitsize; - size_t local_range = propose_wg_size(this->_queue); - size_t global_range = - _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); - - bool use_local_mem = - device_local_mem_size(this->_queue) >= static_cast(local_range * element_bitsize * sizeof(uint32_t)); - - auto e0 = _queue.submit([&](sycl::handler& cgh) { - cgh.single_task([=, offsets_size = this->get_offsets_size().get_mutable_data(), buffer_ptr = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG]() { - buffer_ptr[CAF_FLAG] = offsets_size[0] == 0 ? 1 : 0; - }); - }); - - auto e1 = this->_queue.submit([&](sycl::handler& cgh) { - cgh.depends_on(e0); - - if (!use_local_mem || true) { // Force to use global memory for simplicity - cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), - [=, - offsets = offsets_pointer, - offsets_size = offsets_size_pointer, - data_layer = this->_mlb_layer.get_mutable_data(), - buffer = this->_buffer.get_mutable_data(), - CAF_FLAG = this->_CAF_FLAG](sycl::id<1> idx) { - - if (!buffer[CAF_FLAG]) return; - - sycl::atomic_ref - offsets_size_ref{ offsets_size[0] }; - - bitmap_t data = data_layer[idx]; - for (size_t i = 0; i < element_bitsize; i++) { - if (data & (static_cast(1) << i)) { - offsets[offsets_size_ref++] = i + idx * element_bitsize; - } - } - }); - } else { - sycl::local_accessor local_offsets(local_range * element_bitsize, cgh); - sycl::local_accessor local_size(1, cgh); - - cgh.parallel_for( - make_multiple_nd_range_1d(global_range, local_range), - [=, - offsets = offsets_pointer, - offsets_size = offsets_size_pointer, - data_layer = this->_mlb_layer.get_mutable_data(), - size = this->_num_items, - buffer = this->_buffer.get_mutable_data(), - CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { - if (!buffer[CAF_FLAG]) return; - - auto group = item.get_group(); - sycl::atomic_ref - local_size_ref{ local_size[0] }; - sycl::atomic_ref - offsets_size_ref{ offsets_size[0] }; - - if (group.leader()) { - local_size_ref.store(0); - } - sycl::group_barrier(group); - for (uint32_t gid = item.get_global_linear_id(); gid < size; - gid += local_range) { - bitmap_t data = data_layer[gid]; - for (size_t i = 0; i < element_bitsize; i++) { - if (data & (static_cast(1) << i)) { - local_offsets[local_size_ref++] = i + gid * element_bitsize; - } - } - } - - sycl::group_barrier(group); - - size_t data_offset = 0; - if (group.leader()) { - data_offset = offsets_size_ref.fetch_add(local_size_ref.load()); - } - data_offset = sycl::group_broadcast(group, data_offset, 0); - for (size_t i = item.get_local_linear_id(); i < local_size_ref.load(); - i += item.get_local_range(0)) { - offsets[data_offset + i] = local_offsets[i]; - } - }); - } - - }); - return e1; - } - -private: - sycl::queue& _queue; - size_t _num_items; - - ndarray _data_layer; - ndarray _mlb_layer; - ndarray _offsets; - ndarray _buffer; - const size_t _TMP_VAR = 0; - const size_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) -}; - -#endif - -} // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp similarity index 90% rename from cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp rename to cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 750ff18b4e7..0008d0196a6 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -1,4 +1,6 @@ -#include "oneapi/dal/backend/primitives/frontier.hpp" +#include "oneapi/dal/backend/primitives/frontier/frontier.hpp" +#include "oneapi/dal/backend/primitives/frontier/advance_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/graph.hpp" #include "oneapi/dal/test/engine/common.hpp" #include "oneapi/dal/test/engine/fixtures.hpp" @@ -10,6 +12,8 @@ namespace oneapi::dal::backend::primitives::test { +namespace pr = dal::backend::primitives; + void print_device_name(sycl::queue& queue) { const auto device = queue.get_device(); const auto device_name = device.get_info(); @@ -73,9 +77,9 @@ TEST("test advance operation", "[advance]") { size_t num_nodes = row_ptr.size() - 1; - auto graph = csr_graph(queue, row_ptr, col_indices, weights); - auto in_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - auto out_frontier = frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + auto graph = pr::csr_graph(queue, row_ptr, col_indices, weights); + auto in_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + auto out_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); in_frontier.insert(3); in_frontier.insert(4); @@ -83,7 +87,7 @@ TEST("test advance operation", "[advance]") { in_frontier.insert(100); std::vector host_frontier = {3, 4, 52, 100}; - advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { + pr::advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { return true; // Always advance }).wait_and_throw(); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp new file mode 100644 index 00000000000..6ab2f007cfe --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -0,0 +1,90 @@ +#include "oneapi/dal/backend/primitives/frontier.hpp" + +#include "oneapi/dal/test/engine/common.hpp" +#include "oneapi/dal/test/engine/fixtures.hpp" +#include "oneapi/dal/test/engine/dataframe.hpp" +#include + +namespace oneapi::dal::backend::primitives::test { + +namespace pr = dal::backend::primitives; + +void print_device_name(sycl::queue& queue) { + const auto device = queue.get_device(); + const auto device_name = device.get_info(); + std::cout << "Running on device: " << device_name << std::endl; +} + +template +std::vector host_bfs(std::vector& row_offsets, std::vector& col_indices, T src) { + std::vector distances(row_offsets.size() - 1, std::numeric_limits::max()); + std::queue q; + q.push(src); + distances[src] = 0; + + while (!q.empty()) { + T node = q.front(); + q.pop(); + + for (size_t i = row_offsets[node]; i < row_offsets[node + 1]; ++i) { + auto neighbor = col_indices[i]; + if (distances[neighbor] == std::numeric_limits::max()) { + distances[neighbor] = distances[node] + 1; + q.push(neighbor); + } + } + } + return distances; +} + +TEST("test advance operation", "[advance]") { + DECLARE_TEST_POLICY(policy); + auto& queue = policy.get_queue(); + print_device_name(queue); + + std::vector row_ptr = {0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, 485, 489, 493, 497, 501, 504, 506}; + std::vector col_indices = {1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, 125, 126}; + std::vector weights(col_indices.size(), 1); + + auto graph = pr::csr_graph(queue, row_ptr, col_indices, weights); + size_t num_nodes = row_ptr.size() - 1; + auto in_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); + auto out_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); + pr::ndarray distance = pr::ndarray::empty(queue, {static_cast(num_nodes)}, sycl::usm::alloc::device); + auto distance_ptr = distance.get_mutable_data(); + + const std::uint32_t src = 0; + + queue.submit([&](sycl::handler& cgh) { + cgh.parallel_for(sycl::range<1>(num_nodes), [=](sycl::id<1> idx) { + distance_ptr[idx] = idx[0] == src ? 0 : num_nodes + 1; + }); + }).wait_and_throw(); + + in_frontier.insert(src); + size_t iter = 0; + + /// Start BFS + while (!in_frontier.empty()) { + pr::advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { + bool visited = distance_ptr[neighbor] < num_nodes + 1; + if (!visited) { + distance_ptr[neighbor] = iter + 1; + } + return !visited; + }).wait_and_throw(); + iter++; + pr::swap_frontiers(in_frontier, out_frontier); + out_frontier.clear(); + } + /// End BFS + + auto expected_distances = host_bfs(row_ptr, col_indices, src); + auto actual_distances = distance.to_host(queue).get_data(); + for (size_t i = 0; i < num_nodes; ++i) { + REQUIRE(actual_distances[i] == expected_distances[i]); + } + +} // TEST "test advance operation" + +} // namespace oneapi::dal::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp similarity index 87% rename from cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp rename to cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index 93bb2737204..6117bf61ee2 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/basic_frontier_ops_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -1,8 +1,4 @@ -#include "oneapi/dal/backend/primitives/frontier.hpp" - -#include "oneapi/dal/test/engine/common.hpp" -#include "oneapi/dal/test/engine/fixtures.hpp" -#include "oneapi/dal/test/engine/dataframe.hpp" +#include "oneapi/dal/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/test/engine/common.hpp" #include "oneapi/dal/test/engine/fixtures.hpp" @@ -10,6 +6,8 @@ namespace oneapi::dal::backend::primitives::test { +namespace pr = dal::backend::primitives; + void print_device_name(sycl::queue& queue) { const auto device = queue.get_device(); const auto device_name = device.get_info(); @@ -32,7 +30,7 @@ TEST("frontier queue basic operations", "[frontier]") { print_device_name(queue); const std::size_t num_items = 100; - auto f = frontier(queue, num_items, sycl::usm::alloc::shared); + auto f = pr::frontier(queue, num_items, sycl::usm::alloc::shared); REQUIRE(f.empty() == true); f.insert(0); From 27a71b032754e5785676b2358d816437151f2bc0 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 28 Jul 2025 17:11:58 +0200 Subject: [PATCH 13/69] add performance tests for bfs --- .../dal/backend/primitives/frontier/BUILD | 15 ++++++ .../test/{bfs_dpc.cpp => bfs_perf_dpc.cpp} | 52 ++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) rename cpp/oneapi/dal/backend/primitives/frontier/test/{bfs_dpc.cpp => bfs_perf_dpc.cpp} (77%) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD index 1a224d76188..ef392864d39 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/BUILD +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -22,6 +22,21 @@ dal_test_suite ( private = True, srcs = glob([ "test/*_dpc.cpp", + ], exclude=[ + "test/*perf*.cpp", + ]), + dal_deps = [ + ":frontier", + ], +) + +dal_test_suite( + name = "perf_tests", + framework = "catch2", + compile_as = [ "dpc++" ], + private = True, + srcs = glob([ + "test/*perf_dpc.cpp", ]), dal_deps = [ ":frontier", diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp similarity index 77% rename from cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp rename to cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp index 6ab2f007cfe..579861e2841 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp @@ -4,11 +4,51 @@ #include "oneapi/dal/test/engine/fixtures.hpp" #include "oneapi/dal/test/engine/dataframe.hpp" #include +#include +#include +#include namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; +class PerformanceTester { +public: + void add(const std::string& name, const sycl::event& event) { + if (timings_.find(name) == timings_.end()) { + timings_[name] = std::vector(); + } + timings_[name].push_back(event); + } + + void set_start() { + start_time_ = std::chrono::high_resolution_clock::now(); + } + + void set_end() { + auto end_time = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(end_time - start_time_).count(); + std::cout << "Total execution time: " << duration << " ms" << std::endl; + } + + void print() const { + for (const auto& [name, events] : timings_) { + std::cout << "Performance for " << name << ": "; + for (const auto& event : events) { + auto duration = event.get_profiling_info() - + event.get_profiling_info(); + std::cout << duration / 1e6 << " ms "; + } + std::cout << std::endl; + } + } + +private: + // define start time + std::chrono::high_resolution_clock::time_point start_time_; + std::map> timings_; +}; + void print_device_name(sycl::queue& queue) { const auto device = queue.get_device(); const auto device_name = device.get_info(); @@ -42,6 +82,8 @@ TEST("test advance operation", "[advance]") { auto& queue = policy.get_queue(); print_device_name(queue); + PerformanceTester perf_tester; + std::vector row_ptr = {0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, 485, 489, 493, 497, 501, 504, 506}; std::vector col_indices = {1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, 125, 126}; std::vector weights(col_indices.size(), 1); @@ -65,20 +107,26 @@ TEST("test advance operation", "[advance]") { size_t iter = 0; /// Start BFS + perf_tester.set_start(); while (!in_frontier.empty()) { - pr::advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { + auto e = pr::advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { bool visited = distance_ptr[neighbor] < num_nodes + 1; if (!visited) { distance_ptr[neighbor] = iter + 1; } return !visited; - }).wait_and_throw(); + }); + perf_tester.add("advance", e); + e.wait_and_throw(); iter++; pr::swap_frontiers(in_frontier, out_frontier); out_frontier.clear(); } + perf_tester.set_end(); /// End BFS + // perf_tester.print(); + auto expected_distances = host_bfs(row_ptr, col_indices, src); auto actual_distances = distance.to_host(queue).get_data(); for (size_t i = 0; i < num_nodes; ++i) { From 9dcba2e83d1b872bf8f7a65c5e1013afbc41903f Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 27 Aug 2025 16:21:39 +0200 Subject: [PATCH 14/69] Refactor advance function to remove expected_size parameter and optimize global size calculation --- .../primitives/frontier/advance_dpc.hpp | 40 +++++++++---------- .../primitives/frontier/frontier_dpc.cpp | 21 +++++----- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index ef91511d661..38551a07279 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -195,7 +195,7 @@ struct BitmapKernel { template -sycl::event advance(const GraphT& graph, frontier& in, frontier& out, LambdaT&& functor, size_t expected_size = 0) { +sycl::event advance(const GraphT& graph, frontier& in, frontier& out, LambdaT&& functor) { using element_t = FrontierSizeT; sycl::queue& q = graph.get_queue(); @@ -207,19 +207,15 @@ sycl::event advance(const GraphT& graph, frontier& in, frontier local_range = {element_bitsize * coarsening_factor}; + + size_t element_bitsize = in_dev_frontier.get_element_bitsize(); // in bits + sycl::range<1> local_range = {element_bitsize * coarsening_factor}; size_t global_size; - if (expected_size > 0) { - global_size = expected_size * element_bitsize; - } else { - global_size = 1024; // This parameter should be tuned according to the device capabilities - } + sycl::event to_wait = in.compute_active_frontier(); // kernel launch to compute active bitmap regions + auto offset_size = in.get_offsets_size().at_device(q, 0, {to_wait}); + global_size = offset_size * element_bitsize; - sycl::event to_wait = in.compute_active_frontier(); - sycl::range<1> global_range{(global_size % local_range[0] == 0) ? global_size : global_size + (local_range[0] - global_size % local_range[0])}; Context context{num_nodes, in_dev_frontier, out_dev_frontier}; @@ -229,17 +225,17 @@ sycl::event advance(const GraphT& graph, frontier& in, frontier n_edges_wg{local_range, cgh}; - sycl::local_accessor n_edges_sg{local_range, cgh}; - sycl::local_accessor visited{local_range, cgh}; - sycl::local_accessor subgroup_reduce{local_range, cgh}; - sycl::local_accessor subgroup_reduce_tail{max_num_subgroups, cgh}; - sycl::local_accessor subgroup_ids{local_range, cgh}; - sycl::local_accessor workgroup_reduce{local_range, cgh}; - sycl::local_accessor workgroup_reduce_tail{1, cgh}; - sycl::local_accessor workgroup_ids{local_range, cgh}; - sycl::local_accessor individual_reduce{local_range, cgh}; - sycl::local_accessor individual_reduce_tail{1, cgh}; + sycl::local_accessor n_edges_wg{local_range, cgh}; // number of edges of vertices to process at work-group granularity + sycl::local_accessor n_edges_sg{local_range, cgh}; // number of edges of vertices to process at sub-group granularity + sycl::local_accessor visited{local_range, cgh}; // tracks the vertices already visited at work-group and sub-group granularity + sycl::local_accessor subgroup_reduce{local_range, cgh}; // stores the vertices to process at sub-group granularity + sycl::local_accessor subgroup_reduce_tail{max_num_subgroups, cgh}; // stores the tail of the subgroup reduction + sycl::local_accessor subgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at sub-group level + sycl::local_accessor workgroup_reduce{local_range, cgh}; // stores the vertices to process at work-group granularity + sycl::local_accessor workgroup_reduce_tail{1, cgh}; // stores the tail of the work-group reduction + sycl::local_accessor workgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at work-group level + sycl::local_accessor individual_reduce{local_range, cgh}; // stores the vertices to process at individual thread granularity + sycl::local_accessor individual_reduce_tail{1, cgh}; // stores the tail of the individual thread reduction cgh.parallel_for(sycl::nd_range<1>{global_range, local_range}, diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index bbda488a7f9..6287fbc2298 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -86,10 +86,11 @@ inline sycl::event frontier::compute_active_frontier() { auto offsets_pointer = _offsets.get_mutable_data() + 1; uint32_t element_bitsize = bitmap.get_element_bitsize(); - size_t local_range = propose_wg_size(this->_queue); - size_t global_range = - _mlb_layer.get_count() + local_range - (_mlb_layer.get_count() % local_range); + size_t local_range = 256;// propose_wg_size(this->_queue); + size_t mlb_count = _mlb_layer.get_count(); + size_t global_range = (mlb_count % local_range == 0) ? mlb_count : (mlb_count + local_range - (mlb_count % local_range)); + // check if local memory is enough bool use_local_mem = device_local_mem_size(this->_queue) >= static_cast(local_range * element_bitsize * sizeof(uint32_t)); @@ -102,7 +103,7 @@ inline sycl::event frontier::compute_active_frontier() { auto e1 = this->_queue.submit([&](sycl::handler& cgh) { cgh.depends_on(e0); - if (!use_local_mem || true) { // Force to use global memory for simplicity + if (!use_local_mem) { cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), [=, offsets = offsets_pointer, @@ -135,19 +136,19 @@ inline sycl::event frontier::compute_active_frontier() { offsets = offsets_pointer, offsets_size = offsets_size_pointer, data_layer = this->_mlb_layer.get_mutable_data(), - size = this->_num_items, + size = mlb_count, buffer = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { if (!buffer[CAF_FLAG]) return; auto group = item.get_group(); sycl::atomic_ref + sycl::memory_order::relaxed, + sycl::memory_scope::work_group> local_size_ref{ local_size[0] }; sycl::atomic_ref + sycl::memory_order::relaxed, + sycl::memory_scope::device> offsets_size_ref{ offsets_size[0] }; if (group.leader()) { @@ -155,7 +156,7 @@ inline sycl::event frontier::compute_active_frontier() { } sycl::group_barrier(group); for (uint32_t gid = item.get_global_linear_id(); gid < size; - gid += local_range) { + gid += item.get_global_range(0)) { ElementType data = data_layer[gid]; for (size_t i = 0; i < element_bitsize; i++) { if (data & (static_cast(1) << i)) { From fcc4f75462edd019724672372b629a2cf429a141 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 27 Aug 2025 16:30:26 +0200 Subject: [PATCH 15/69] moved bitset to frontier folder --- cpp/oneapi/dal/backend/primitives/bitset.hpp | 1 - .../dal/backend/primitives/{bitset => frontier}/bitset.hpp | 0 cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp | 2 +- cpp/oneapi/dal/backend/primitives/frontier/graph.hpp | 2 +- 4 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 cpp/oneapi/dal/backend/primitives/bitset.hpp rename cpp/oneapi/dal/backend/primitives/{bitset => frontier}/bitset.hpp (100%) diff --git a/cpp/oneapi/dal/backend/primitives/bitset.hpp b/cpp/oneapi/dal/backend/primitives/bitset.hpp deleted file mode 100644 index 905603885cb..00000000000 --- a/cpp/oneapi/dal/backend/primitives/bitset.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "oneapi/dal/backend/primitives/bitset/bitset.hpp" \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp similarity index 100% rename from cpp/oneapi/dal/backend/primitives/bitset/bitset.hpp rename to cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 5de56bc2fde..5ccfce81b74 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -4,7 +4,7 @@ #include "oneapi/dal/backend/common.hpp" #include "oneapi/dal/graph/detail/common.hpp" #include "oneapi/dal/graph/detail/container.hpp" -#include "oneapi/dal/backend/primitives/bitset.hpp" +#include "oneapi/dal/backend/primitives/frontier/bitset.hpp" #include "oneapi/dal/backend/primitives/ndarray.hpp" namespace oneapi::dal::backend::primitives { diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 825a119dbc5..f63ad131d9b 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -3,7 +3,7 @@ #include "oneapi/dal/common.hpp" #include "oneapi/dal/graph/detail/common.hpp" #include "oneapi/dal/graph/detail/container.hpp" -#include "oneapi/dal/backend/primitives/bitset.hpp" +#include "oneapi/dal/backend/primitives/frontier/bitset.hpp" #include "oneapi/dal/backend/primitives/ndarray.hpp" namespace oneapi::dal::backend::primitives { From 1e40aa94de1a1715bed9189617ad44ec9c137553 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 27 Aug 2025 16:32:22 +0200 Subject: [PATCH 16/69] applied clang-format --- .../primitives/frontier/advance_dpc.hpp | 504 ++++++++++-------- .../backend/primitives/frontier/bitset.hpp | 9 +- .../backend/primitives/frontier/frontier.hpp | 16 +- .../primitives/frontier/frontier_dpc.cpp | 129 +++-- .../dal/backend/primitives/frontier/graph.hpp | 252 ++++----- .../primitives/frontier/test/advance_dpc.cpp | 81 ++- .../primitives/frontier/test/bfs_perf_dpc.cpp | 98 +++- .../primitives/frontier/test/frontier_dpc.cpp | 9 +- 8 files changed, 637 insertions(+), 461 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index 38551a07279..c9c121eab69 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -4,17 +4,16 @@ #include "oneapi/dal/backend/primitives/frontier/graph.hpp" #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" - namespace oneapi::dal::backend::primitives { /// ContextState holds the state of the current processing group in the kernel /// It includes the group offset, coarsening factor, offsets size, and the SYCL /// nd_item for the current work item. struct ContextState { - size_t group_offset; - const uint16_t coarsening_factor; - const uint32_t offsets_size; - const sycl::nd_item<1> item; + size_t group_offset; + const uint16_t coarsening_factor; + const uint32_t offsets_size; + const sycl::nd_item<1> item; }; /// Context is a template class that provides an interface for the kernel to @@ -23,168 +22,195 @@ struct ContextState { /// the context state, check if there are more elements to process, get the /// assigned element, check if a vertex is in the frontier, and insert a vertex /// into the output frontier. -template +template struct Context { - size_t limit; - InFrontierDevT in_dev_frontier; - OutFrontierDevT out_dev_frontier; - - Context(size_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) - : limit(limit), in_dev_frontier(in_dev_frontier), out_dev_frontier(out_dev_frontier) {} - - inline ContextState init(sycl::nd_item<1>& item) const { - return { - item.get_group_linear_id(), - static_cast(item.get_local_range(0) / in_dev_frontier.get_element_bitsize()), - in_dev_frontier.get_offsets_size()[0], - item, - }; - } - - /// This method checks if there are more elements to process in the current group. - inline bool need_to_process(ContextState& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } - - /// This method completes the current iteration by updating the group offset. - inline void complete_iteration(ContextState& state) const { state.group_offset += state.item.get_group_range(0); } - - /// This method retrieves the assigned element for the current work item. - inline size_t get_assigned_element(const ContextState& state) const { - const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); - const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / element_bitsize); - const uint32_t* bitmap_offsets = in_dev_frontier.get_offsets(); - // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); - const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + (state.item.get_local_linear_id() % element_bitsize); - return assigned_vertex; - } - - /// This method checks if a vertex is in the input frontier. - inline bool check(const ContextState& state, size_t vertex) const { - return vertex < limit && in_dev_frontier.check(vertex); - } - - /// This method inserts a vertex into the output frontier. - inline void insert(const ContextState& state, size_t vertex) const { - out_dev_frontier.insert(vertex); - } -}; - -/// BitmapKernel is a template struct that defines the kernel to be executed on the device. -/// It processes the input frontier and advances it based on the provided functor. -template -struct BitmapKernel { - void operator()(sycl::nd_item<1> item) const { - const size_t lid = item.get_local_linear_id(); - const auto wgroup = item.get_group(); - const size_t wgroup_size = wgroup.get_local_range(0); - const auto sgroup = item.get_sub_group(); - const auto sgroup_id = sgroup.get_group_id(); - const size_t sgroup_size = sgroup.get_local_range()[0]; - const size_t llid = sgroup.get_local_linear_id(); - - auto state = context.init(item); - - while (context.need_to_process(state)) { - const auto assigned_vertex = context.get_assigned_element(state); - - if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; } - if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } - - sycl::atomic_ref sg_tail{subgroup_reduce_tail[sgroup_id]}; - sycl::atomic_ref wg_tail{workgroup_reduce_tail[0]}; - - // 1. distribute the workload based on the number of edges to the workgroup, subgroup or workitem - const uint32_t offset = sgroup_id * sgroup_size; - if (context.check(state, assigned_vertex)) { - uint32_t n_edges = graph_dev.get_degree(assigned_vertex); - if (n_edges >= wgroup_size * wgroup_size) { // if the number of edges is large enough, we can assign the vertex to the workgroup - uint32_t loc = wg_tail.fetch_add(static_cast(1)); - n_edges_wg[loc] = n_edges; - workgroup_reduce[loc] = assigned_vertex; - workgroup_ids[loc] = lid; - } else if (n_edges >= sgroup_size) { // assign to the subgroup - uint32_t loc = sg_tail.fetch_add(static_cast(1)); - n_edges_sg[offset + loc] = n_edges; - subgroup_reduce[offset + loc] = assigned_vertex; - subgroup_ids[offset + loc] = lid; - } - visited[lid] = false; - } else { - visited[lid] = true; - } - - sycl::group_barrier(wgroup); - - // 2. process the the edge of one vertex at a time using the workgroup - for (size_t i = 0; i < wg_tail.load(); i++) { - auto vertex = workgroup_reduce[i]; - size_t n_edges = n_edges_wg[i]; - auto start = graph_dev.begin(vertex); - - for (auto j = lid; j < n_edges; j += wgroup_size) { - auto n = start + j; - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } - } + size_t limit; + InFrontierDevT in_dev_frontier; + OutFrontierDevT out_dev_frontier; + + Context(size_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) + : limit(limit), + in_dev_frontier(in_dev_frontier), + out_dev_frontier(out_dev_frontier) {} + + inline ContextState init(sycl::nd_item<1>& item) const { + return { + item.get_group_linear_id(), + static_cast(item.get_local_range(0) / in_dev_frontier.get_element_bitsize()), + in_dev_frontier.get_offsets_size()[0], + item, + }; + } - if (wgroup.leader()) { visited[workgroup_ids[i]] = true; } - } + /// This method checks if there are more elements to process in the current group. + inline bool need_to_process(ContextState& state) const { + return (state.group_offset * state.coarsening_factor < state.offsets_size); + } - sycl::group_barrier(sgroup); + /// This method completes the current iteration by updating the group offset. + inline void complete_iteration(ContextState& state) const { + state.group_offset += state.item.get_group_range(0); + } - // 3. process the edges of one vertex at a time using the subgroup - for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size - size_t vertex_id = offset + i; - auto vertex = subgroup_reduce[vertex_id]; - size_t n_edges = n_edges_sg[vertex_id]; + /// This method retrieves the assigned element for the current work item. + inline size_t get_assigned_element(const ContextState& state) const { + const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); + const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + + (state.item.get_local_linear_id() / element_bitsize); + const uint32_t* bitmap_offsets = in_dev_frontier.get_offsets(); + // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); + const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + + (state.item.get_local_linear_id() % element_bitsize); + return assigned_vertex; + } - auto start = graph_dev.begin(vertex); + /// This method checks if a vertex is in the input frontier. + inline bool check(const ContextState& state, size_t vertex) const { + return vertex < limit && in_dev_frontier.check(vertex); + } - for (auto j = llid; j < n_edges; j += sgroup_size) { - auto n = start + j; - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } - } + /// This method inserts a vertex into the output frontier. + inline void insert(const ContextState& state, size_t vertex) const { + out_dev_frontier.insert(vertex); + } +}; - if (sgroup.leader()) { visited[subgroup_ids[vertex_id]] = true; } - } - sycl::group_barrier(sgroup); - - // 4. process the edges of the vertices that were not assigned to the workgroup or subgroup - if (!visited[lid]) { - auto vertex = assigned_vertex; - auto start = graph_dev.begin(vertex); - auto end = graph_dev.end(vertex); - - for (auto n = start; n != end; ++n) { - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { context.insert(state, neighbor); } +/// BitmapKernel is a template struct that defines the kernel to be executed on the device. +/// It processes the input frontier and advances it based on the provided functor. +template +struct BitmapKernel { + void operator()(sycl::nd_item<1> item) const { + const size_t lid = item.get_local_linear_id(); + const auto wgroup = item.get_group(); + const size_t wgroup_size = wgroup.get_local_range(0); + const auto sgroup = item.get_sub_group(); + const auto sgroup_id = sgroup.get_group_id(); + const size_t sgroup_size = sgroup.get_local_range()[0]; + const size_t llid = sgroup.get_local_linear_id(); + + auto state = context.init(item); + + while (context.need_to_process(state)) { + const auto assigned_vertex = context.get_assigned_element(state); + + if (sgroup.leader()) { + subgroup_reduce_tail[sgroup_id] = 0; + } + if (wgroup.leader()) { + workgroup_reduce_tail[0] = 0; + } + + sycl::atomic_ref + sg_tail{ subgroup_reduce_tail[sgroup_id] }; + sycl::atomic_ref + wg_tail{ workgroup_reduce_tail[0] }; + + // 1. distribute the workload based on the number of edges to the workgroup, subgroup or workitem + const uint32_t offset = sgroup_id * sgroup_size; + if (context.check(state, assigned_vertex)) { + uint32_t n_edges = graph_dev.get_degree(assigned_vertex); + if (n_edges >= + wgroup_size * + wgroup_size) { // if the number of edges is large enough, we can assign the vertex to the workgroup + uint32_t loc = wg_tail.fetch_add(static_cast(1)); + n_edges_wg[loc] = n_edges; + workgroup_reduce[loc] = assigned_vertex; + workgroup_ids[loc] = lid; + } + else if (n_edges >= sgroup_size) { // assign to the subgroup + uint32_t loc = sg_tail.fetch_add(static_cast(1)); + n_edges_sg[offset + loc] = n_edges; + subgroup_reduce[offset + loc] = assigned_vertex; + subgroup_ids[offset + loc] = lid; + } + visited[lid] = false; + } + else { + visited[lid] = true; + } + + sycl::group_barrier(wgroup); + + // 2. process the the edge of one vertex at a time using the workgroup + for (size_t i = 0; i < wg_tail.load(); i++) { + auto vertex = workgroup_reduce[i]; + size_t n_edges = n_edges_wg[i]; + auto start = graph_dev.begin(vertex); + + for (auto j = lid; j < n_edges; j += wgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { + context.insert(state, neighbor); + } + } + + if (wgroup.leader()) { + visited[workgroup_ids[i]] = true; + } + } + + sycl::group_barrier(sgroup); + + // 3. process the edges of one vertex at a time using the subgroup + for ( + size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; + i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size + size_t vertex_id = offset + i; + auto vertex = subgroup_reduce[vertex_id]; + size_t n_edges = n_edges_sg[vertex_id]; + + auto start = graph_dev.begin(vertex); + + for (auto j = llid; j < n_edges; j += sgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { + context.insert(state, neighbor); + } + } + + if (sgroup.leader()) { + visited[subgroup_ids[vertex_id]] = true; + } + } + sycl::group_barrier(sgroup); + + // 4. process the edges of the vertices that were not assigned to the workgroup or subgroup + if (!visited[lid]) { + auto vertex = assigned_vertex; + auto start = graph_dev.begin(vertex); + auto end = graph_dev.end(vertex); + + for (auto n = start; n != end; ++n) { + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { + context.insert(state, neighbor); + } + } + } + context.complete_iteration(state); // complete the current iteration } - } - context.complete_iteration(state); // complete the current iteration } - } - - const ContextT context; - const GraphDevT graph_dev; - const sycl::local_accessor n_edges_wg; - const sycl::local_accessor n_edges_sg; - const sycl::local_accessor visited; - const sycl::local_accessor subgroup_reduce; - const sycl::local_accessor subgroup_reduce_tail; - const sycl::local_accessor subgroup_ids; - const sycl::local_accessor workgroup_reduce; - const sycl::local_accessor workgroup_reduce_tail; - const sycl::local_accessor workgroup_ids; - const LambdaT functor; + + const ContextT context; + const GraphDevT graph_dev; + const sycl::local_accessor n_edges_wg; + const sycl::local_accessor n_edges_sg; + const sycl::local_accessor visited; + const sycl::local_accessor subgroup_reduce; + const sycl::local_accessor subgroup_reduce_tail; + const sycl::local_accessor subgroup_ids; + const sycl::local_accessor workgroup_reduce; + const sycl::local_accessor workgroup_reduce_tail; + const sycl::local_accessor workgroup_ids; + const LambdaT functor; }; /// advance is a function that launches the BitmapKernel on the device to advance the frontier. @@ -192,67 +218,107 @@ struct BitmapKernel { /// The expected_size parameter is used to specify the expected size of the input frontier, in order /// to optimize the kernel launch parameters. If expected_size is zero, a default size is used. /// It returns a sycl::event that can be used to synchronize the execution. -template -sycl::event advance(const GraphT& graph, frontier& in, frontier& out, LambdaT&& functor) { - using element_t = FrontierSizeT; - - sycl::queue& q = graph.get_queue(); - - size_t num_nodes = graph.get_vertex_count(); - - auto in_dev_frontier = in.get_device_view(); - auto out_dev_frontier = out.get_device_view(); - auto graph_dev = graph.get_device_view(); - - size_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups - - size_t element_bitsize = in_dev_frontier.get_element_bitsize(); // in bits - sycl::range<1> local_range = {element_bitsize * coarsening_factor}; - size_t global_size; - - sycl::event to_wait = in.compute_active_frontier(); // kernel launch to compute active bitmap regions - auto offset_size = in.get_offsets_size().at_device(q, 0, {to_wait}); - global_size = offset_size * element_bitsize; - - sycl::range<1> global_range{(global_size % local_range[0] == 0) ? global_size : global_size + (local_range[0] - global_size % local_range[0])}; - - Context context{num_nodes, in_dev_frontier, out_dev_frontier}; - using bitmap_kernel_t = BitmapKernel; - - const uint32_t max_num_subgroups = device_max_sg_count(q); - - auto e = q.submit([&](sycl::handler& cgh) { - cgh.depends_on(to_wait); - sycl::local_accessor n_edges_wg{local_range, cgh}; // number of edges of vertices to process at work-group granularity - sycl::local_accessor n_edges_sg{local_range, cgh}; // number of edges of vertices to process at sub-group granularity - sycl::local_accessor visited{local_range, cgh}; // tracks the vertices already visited at work-group and sub-group granularity - sycl::local_accessor subgroup_reduce{local_range, cgh}; // stores the vertices to process at sub-group granularity - sycl::local_accessor subgroup_reduce_tail{max_num_subgroups, cgh}; // stores the tail of the subgroup reduction - sycl::local_accessor subgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at sub-group level - sycl::local_accessor workgroup_reduce{local_range, cgh}; // stores the vertices to process at work-group granularity - sycl::local_accessor workgroup_reduce_tail{1, cgh}; // stores the tail of the work-group reduction - sycl::local_accessor workgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at work-group level - sycl::local_accessor individual_reduce{local_range, cgh}; // stores the vertices to process at individual thread granularity - sycl::local_accessor individual_reduce_tail{1, cgh}; // stores the tail of the individual thread reduction - - - cgh.parallel_for(sycl::nd_range<1>{global_range, local_range}, - bitmap_kernel_t{context, - graph_dev, - n_edges_wg, - n_edges_sg, - visited, - subgroup_reduce, - subgroup_reduce_tail, - subgroup_ids, - workgroup_reduce, - workgroup_reduce_tail, - workgroup_ids, - std::forward(functor)}); - }); - return {e}; +template +sycl::event advance(const GraphT& graph, + frontier& in, + frontier& out, + LambdaT&& functor) { + using element_t = FrontierSizeT; + + sycl::queue& q = graph.get_queue(); + + size_t num_nodes = graph.get_vertex_count(); + + auto in_dev_frontier = in.get_device_view(); + auto out_dev_frontier = out.get_device_view(); + auto graph_dev = graph.get_device_view(); + + size_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups + + size_t element_bitsize = in_dev_frontier.get_element_bitsize(); // in bits + sycl::range<1> local_range = { element_bitsize * coarsening_factor }; + size_t global_size; + + sycl::event to_wait = + in.compute_active_frontier(); // kernel launch to compute active bitmap regions + auto offset_size = in.get_offsets_size().at_device(q, 0, { to_wait }); + global_size = offset_size * element_bitsize; + + sycl::range<1> global_range{ (global_size % local_range[0] == 0) + ? global_size + : global_size + + (local_range[0] - global_size % local_range[0]) }; + + Context context{ num_nodes, + in_dev_frontier, + out_dev_frontier }; + using bitmap_kernel_t = + BitmapKernel; + + const uint32_t max_num_subgroups = device_max_sg_count(q); + + auto e = q.submit([&](sycl::handler& cgh) { + cgh.depends_on(to_wait); + sycl::local_accessor n_edges_wg{ + local_range, + cgh + }; // number of edges of vertices to process at work-group granularity + sycl::local_accessor n_edges_sg{ + local_range, + cgh + }; // number of edges of vertices to process at sub-group granularity + sycl::local_accessor visited{ + local_range, + cgh + }; // tracks the vertices already visited at work-group and sub-group granularity + sycl::local_accessor subgroup_reduce{ + local_range, + cgh + }; // stores the vertices to process at sub-group granularity + sycl::local_accessor subgroup_reduce_tail{ + max_num_subgroups, + cgh + }; // stores the tail of the subgroup reduction + sycl::local_accessor subgroup_ids{ + local_range, + cgh + }; // stores the thread id that found the vertex to process at sub-group level + sycl::local_accessor workgroup_reduce{ + local_range, + cgh + }; // stores the vertices to process at work-group granularity + sycl::local_accessor workgroup_reduce_tail{ + 1, + cgh + }; // stores the tail of the work-group reduction + sycl::local_accessor workgroup_ids{ + local_range, + cgh + }; // stores the thread id that found the vertex to process at work-group level + sycl::local_accessor individual_reduce{ + local_range, + cgh + }; // stores the vertices to process at individual thread granularity + sycl::local_accessor individual_reduce_tail{ + 1, + cgh + }; // stores the tail of the individual thread reduction + + cgh.parallel_for(sycl::nd_range<1>{ global_range, local_range }, + bitmap_kernel_t{ context, + graph_dev, + n_edges_wg, + n_edges_sg, + visited, + subgroup_reduce, + subgroup_reduce_tail, + subgroup_ids, + workgroup_reduce, + workgroup_reduce_tail, + workgroup_ids, + std::forward(functor) }); + }); + return { e }; } } // namespace oneapi::dal::backend::primitives \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index a6479a2864e..c4a75a1d704 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -42,8 +42,7 @@ class bitset { inline void atomic_set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; - sycl::atomic_ref - atomic_element(_data[element_index]); + sycl::atomic_ref atomic_element(_data[element_index]); atomic_element |= (element_t(1) << bit_index); } @@ -53,8 +52,7 @@ class bitset { inline void atomic_unset(std::uint32_t index) { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; - sycl::atomic_ref - atomic_element(_data[element_index]); + sycl::atomic_ref atomic_element(_data[element_index]); atomic_element &= ~(element_t(1) << bit_index); } @@ -64,8 +62,7 @@ class bitset { inline bool atomic_test(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; - sycl::atomic_ref - atomic_element(_data[element_index]); + sycl::atomic_ref atomic_element(_data[element_index]); return (atomic_element.load() & (element_t(1) << bit_index)) != 0; } diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 5ccfce81b74..eda1028746c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -23,8 +23,8 @@ class frontier_view { std::uint32_t* offsets_size, size_t num_items) : _num_items(num_items), - _data_layer(bitset{data_layer}), - _mlb_layer(bitset{mlb_layer}), + _data_layer(bitset{ data_layer }), + _mlb_layer(bitset{ mlb_layer }), _offsets(offsets), _offsets_size(offsets_size) {} @@ -73,17 +73,19 @@ class frontier { using buffer_t = std::uint32_t; public: - frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc = sycl::usm::alloc::shared); + frontier(sycl::queue& queue, + std::size_t num_items, + sycl::usm::alloc alloc = sycl::usm::alloc::shared); const frontier_view get_device_view() const { auto offsets_size_pointer = _offsets.get_mutable_data(); auto offsets_pointer = _offsets.get_mutable_data() + 1; return { _data_layer.get_mutable_data(), - _mlb_layer.get_mutable_data(), - offsets_pointer, - offsets_size_pointer, - static_cast(_data_layer.get_count()) }; + _mlb_layer.get_mutable_data(), + offsets_pointer, + offsets_size_pointer, + static_cast(_data_layer.get_count()) }; } inline ndview get_data() const { diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 6287fbc2298..7805d1fef4f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -7,19 +7,21 @@ namespace oneapi::dal::backend::primitives { #ifdef ONEDAL_DATA_PARALLEL - + template -frontier::frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc) : _queue(queue), _num_items(num_items) { - std::int64_t array_size = - (num_items + bitset::element_bitsize - 1) / bitset::element_bitsize; +frontier::frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc) + : _queue(queue), + _num_items(num_items) { + std::int64_t array_size = (num_items + bitset::element_bitsize - 1) / + bitset::element_bitsize; std::int64_t mlb_size = (array_size + bitset::element_bitsize - 1) / - bitset::element_bitsize; - _data_layer = - ndarray::empty(_queue, { array_size }, alloc); - _mlb_layer = - ndarray::empty(_queue, { mlb_size }, alloc); - _offsets = - ndarray::empty(_queue, { array_size + 1 }, alloc); /// First offset is to keep the size of the frontier + bitset::element_bitsize; + _data_layer = ndarray::empty(_queue, { array_size }, alloc); + _mlb_layer = ndarray::empty(_queue, { mlb_size }, alloc); + _offsets = ndarray::empty( + _queue, + { array_size + 1 }, + alloc); /// First offset is to keep the size of the frontier _buffer = ndarray::empty(_queue, { 10 }, alloc); sycl::event e1, e2, e3; @@ -55,17 +57,21 @@ bool frontier::empty() { template inline void frontier::insert(ElementType idx) { auto view = this->get_device_view(); - _queue.submit([&](sycl::handler& cgh) { - cgh.single_task([=]() { - view.insert(idx); - }); - }).wait_and_throw(); + _queue + .submit([&](sycl::handler& cgh) { + cgh.single_task([=]() { + view.insert(idx); + }); + }) + .wait_and_throw(); } template inline bool frontier::check(ElementType idx) { - ElementType tmp_data = _data_layer.at_device(_queue, idx / bitset::element_bitsize); - return (tmp_data & (static_cast(1) << (idx % bitset::element_bitsize))) != 0; + ElementType tmp_data = + _data_layer.at_device(_queue, idx / bitset::element_bitsize); + return (tmp_data & + (static_cast(1) << (idx % bitset::element_bitsize))) != 0; } template @@ -86,16 +92,22 @@ inline sycl::event frontier::compute_active_frontier() { auto offsets_pointer = _offsets.get_mutable_data() + 1; uint32_t element_bitsize = bitmap.get_element_bitsize(); - size_t local_range = 256;// propose_wg_size(this->_queue); + size_t local_range = 256; // propose_wg_size(this->_queue); size_t mlb_count = _mlb_layer.get_count(); - size_t global_range = (mlb_count % local_range == 0) ? mlb_count : (mlb_count + local_range - (mlb_count % local_range)); + size_t global_range = (mlb_count % local_range == 0) + ? mlb_count + : (mlb_count + local_range - (mlb_count % local_range)); // check if local memory is enough bool use_local_mem = - device_local_mem_size(this->_queue) >= static_cast(local_range * element_bitsize * sizeof(uint32_t)); + device_local_mem_size(this->_queue) >= + static_cast(local_range * element_bitsize * sizeof(uint32_t)); auto e0 = _queue.submit([&](sycl::handler& cgh) { - cgh.single_task([=, offsets_size = this->get_offsets_size().get_mutable_data(), buffer_ptr = this->_buffer.get_mutable_data(), CAF_FLAG = this->_CAF_FLAG]() { + cgh.single_task([=, + offsets_size = this->get_offsets_size().get_mutable_data(), + buffer_ptr = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG]() { buffer_ptr[CAF_FLAG] = offsets_size[0] == 0 ? 1 : 0; }); }); @@ -103,43 +115,45 @@ inline sycl::event frontier::compute_active_frontier() { auto e1 = this->_queue.submit([&](sycl::handler& cgh) { cgh.depends_on(e0); - if (!use_local_mem) { + if (!use_local_mem) { cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), - [=, - offsets = offsets_pointer, - offsets_size = offsets_size_pointer, - data_layer = this->_mlb_layer.get_mutable_data(), - buffer = this->_buffer.get_mutable_data(), - CAF_FLAG = this->_CAF_FLAG](sycl::id<1> idx) { - - if (!buffer[CAF_FLAG]) return; - - sycl::atomic_ref - offsets_size_ref{ offsets_size[0] }; - - ElementType data = data_layer[idx]; - for (size_t i = 0; i < element_bitsize; i++) { - if (data & (static_cast(1) << i)) { - offsets[offsets_size_ref++] = i + idx * element_bitsize; - } - } - }); - } else { + [=, + offsets = offsets_pointer, + offsets_size = offsets_size_pointer, + data_layer = this->_mlb_layer.get_mutable_data(), + buffer = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG](sycl::id<1> idx) { + if (!buffer[CAF_FLAG]) + return; + + sycl::atomic_ref + offsets_size_ref{ offsets_size[0] }; + + ElementType data = data_layer[idx]; + for (size_t i = 0; i < element_bitsize; i++) { + if (data & (static_cast(1) << i)) { + offsets[offsets_size_ref++] = i + idx * element_bitsize; + } + } + }); + } + else { sycl::local_accessor local_offsets(local_range * element_bitsize, cgh); sycl::local_accessor local_size(1, cgh); cgh.parallel_for( make_multiple_nd_range_1d(global_range, local_range), [=, - offsets = offsets_pointer, - offsets_size = offsets_size_pointer, - data_layer = this->_mlb_layer.get_mutable_data(), - size = mlb_count, - buffer = this->_buffer.get_mutable_data(), - CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { - if (!buffer[CAF_FLAG]) return; + offsets = offsets_pointer, + offsets_size = offsets_size_pointer, + data_layer = this->_mlb_layer.get_mutable_data(), + size = mlb_count, + buffer = this->_buffer.get_mutable_data(), + CAF_FLAG = this->_CAF_FLAG](sycl::nd_item<1> item) { + if (!buffer[CAF_FLAG]) + return; auto group = item.get_group(); sycl::atomic_ref::compute_active_frontier() { } sycl::group_barrier(group); for (uint32_t gid = item.get_global_linear_id(); gid < size; - gid += item.get_global_range(0)) { + gid += item.get_global_range(0)) { ElementType data = data_layer[gid]; for (size_t i = 0; i < element_bitsize; i++) { if (data & (static_cast(1) << i)) { @@ -173,20 +187,17 @@ inline sycl::event frontier::compute_active_frontier() { } data_offset = sycl::group_broadcast(group, data_offset, 0); for (size_t i = item.get_local_linear_id(); i < local_size_ref.load(); - i += item.get_local_range(0)) { + i += item.get_local_range(0)) { offsets[data_offset + i] = local_offsets[i]; } }); } - }); return e1; - } -#define INSTANTIATE(F) \ - template class frontier; - +#define INSTANTIATE(F) template class frontier; + INSTANTIATE(std::uint64_t) INSTANTIATE(std::uint32_t) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index f63ad131d9b..5e1e12d26d8 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -8,151 +8,153 @@ namespace oneapi::dal::backend::primitives { -template +template class csr_graph_view { - using vertex_t = VertexT; - using edge_t = EdgeT; - using weight_t = WeightT; - - struct neighbor_iterator_t { - neighbor_iterator_t(const vertex_t* start_ptr, vertex_t* ptr) - : _ptr(ptr), _start_ptr(start_ptr) {} - - SYCL_EXTERNAL bool operator==(const neighbor_iterator_t& other) const { - return _ptr == other._ptr; - } + using vertex_t = VertexT; + using edge_t = EdgeT; + using weight_t = WeightT; + + struct neighbor_iterator_t { + neighbor_iterator_t(const vertex_t* start_ptr, vertex_t* ptr) + : _ptr(ptr), + _start_ptr(start_ptr) {} + + SYCL_EXTERNAL bool operator==(const neighbor_iterator_t& other) const { + return _ptr == other._ptr; + } + + SYCL_EXTERNAL bool operator!=(const neighbor_iterator_t& other) const { + return _ptr != other._ptr; + } + + SYCL_EXTERNAL neighbor_iterator_t& operator++() { + ++_ptr; + return *this; + } + + SYCL_EXTERNAL neighbor_iterator_t operator+(int n) const { + neighbor_iterator_t tmp = *this; + tmp._ptr += n; + return tmp; + } + + SYCL_EXTERNAL vertex_t operator*() const { + return *_ptr; + } + + SYCL_EXTERNAL edge_t get_index() const { + return static_cast(_ptr - _start_ptr); + } + + vertex_t* _ptr; + const vertex_t* _start_ptr; + }; - SYCL_EXTERNAL bool operator!=(const neighbor_iterator_t& other) const { - return _ptr != other._ptr; +public: + csr_graph_view(std::size_t num_nodes, vertex_t* row_ptr, edge_t* col_indices, weight_t* weights) + : _num_nodes(num_nodes), + _row_ptr(row_ptr), + _col_indices(col_indices), + _weights(weights) { + ONEDAL_ASSERT(_row_ptr != nullptr, "Row pointer must not be null"); + ONEDAL_ASSERT(_col_indices != nullptr, "Column indices must not be null"); + ONEDAL_ASSERT(_weights != nullptr, "Weights must not be null"); } - SYCL_EXTERNAL neighbor_iterator_t& operator++() { - ++_ptr; - return *this; + SYCL_EXTERNAL inline std::uint32_t get_degree(const vertex_t vertex) const { + ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); + return static_cast(_row_ptr[vertex + 1] - _row_ptr[vertex]); } - SYCL_EXTERNAL neighbor_iterator_t operator+(int n) const { - neighbor_iterator_t tmp = *this; - tmp._ptr += n; - return tmp; + SYCL_EXTERNAL inline weight_t get_weight(const edge_t edge) const { + return _weights[edge]; } - SYCL_EXTERNAL vertex_t operator*() const { - return *_ptr; + SYCL_EXTERNAL inline neighbor_iterator_t begin(vertex_t vertex) const { + ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); + return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex]); } - SYCL_EXTERNAL edge_t get_index() const { - return static_cast(_ptr - _start_ptr); + SYCL_EXTERNAL inline neighbor_iterator_t end(vertex_t vertex) const { + ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); + return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex + 1]); } - vertex_t* _ptr; - const vertex_t* _start_ptr; - }; - -public: - csr_graph_view(std::size_t num_nodes, - vertex_t* row_ptr, - edge_t* col_indices, - weight_t* weights) - : _num_nodes(num_nodes), - _row_ptr(row_ptr), - _col_indices(col_indices), - _weights(weights) { - ONEDAL_ASSERT(_row_ptr != nullptr, "Row pointer must not be null"); - ONEDAL_ASSERT(_col_indices != nullptr, "Column indices must not be null"); - ONEDAL_ASSERT(_weights != nullptr, "Weights must not be null"); - } - - SYCL_EXTERNAL inline std::uint32_t get_degree(const vertex_t vertex) const { - ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); - return static_cast(_row_ptr[vertex + 1] - _row_ptr[vertex]); - } - - SYCL_EXTERNAL inline weight_t get_weight(const edge_t edge) const { - return _weights[edge]; - } - - SYCL_EXTERNAL inline neighbor_iterator_t begin(vertex_t vertex) const { - ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); - return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex]); - } - - SYCL_EXTERNAL inline neighbor_iterator_t end(vertex_t vertex) const { - ONEDAL_ASSERT(vertex < _num_nodes, "Vertex index out of bounds"); - return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex + 1]); - } - private: - std::size_t _num_nodes; - vertex_t* _row_ptr; - edge_t* _col_indices; - weight_t* _weights; + std::size_t _num_nodes; + vertex_t* _row_ptr; + edge_t* _col_indices; + weight_t* _weights; }; -template +template class csr_graph { - using vertex_t = VertexT; - using edge_t = EdgeT; - using weight_t = WeightT; - using graph_view_t = csr_graph_view; + using vertex_t = VertexT; + using edge_t = EdgeT; + using weight_t = WeightT; + using graph_view_t = csr_graph_view; public: - csr_graph(sycl::queue& queue, - std::vector row_ptr, - std::vector col_indices, - std::vector weights = {}, - sycl::usm::alloc alloc = sycl::usm::alloc::shared) - : _queue(queue), _num_nodes(row_ptr.size() - 1) { - - std::int64_t row_ptr_size = static_cast(row_ptr.size()); - std::int64_t col_indices_size = static_cast(col_indices.size()); - std::int64_t weights_size = static_cast(weights.size()); - - _row_ptr = ndarray::empty(_queue, {row_ptr_size}, alloc); - _col_indices = ndarray::empty(_queue, {col_indices_size}, alloc); - _weights = ndarray::empty(_queue, {weights_size}, alloc); - - auto e1 = dal::backend::copy_host2usm(_queue, - _row_ptr.get_mutable_data(), - row_ptr.data(), - row_ptr.size()); - - auto e2 = dal::backend::copy_host2usm(_queue, - _col_indices.get_mutable_data(), - col_indices.data(), - col_indices.size()); - - auto e3 = dal::backend::copy_host2usm(_queue, - _weights.get_mutable_data(), - weights.data(), - weights.size()); - - e1.wait_and_throw(); - e2.wait_and_throw(); - e3.wait_and_throw(); - } - - graph_view_t get_device_view() const { - return { _num_nodes, - _row_ptr.get_mutable_data(), - _col_indices.get_mutable_data(), - _weights.get_mutable_data() }; - } - - sycl::queue& get_queue() const { - return _queue; - } - - std::size_t get_vertex_count() const { - return _num_nodes; - } + csr_graph(sycl::queue& queue, + std::vector row_ptr, + std::vector col_indices, + std::vector weights = {}, + sycl::usm::alloc alloc = sycl::usm::alloc::shared) + : _queue(queue), + _num_nodes(row_ptr.size() - 1) { + std::int64_t row_ptr_size = static_cast(row_ptr.size()); + std::int64_t col_indices_size = static_cast(col_indices.size()); + std::int64_t weights_size = static_cast(weights.size()); + + _row_ptr = ndarray::empty(_queue, { row_ptr_size }, alloc); + _col_indices = ndarray::empty(_queue, { col_indices_size }, alloc); + _weights = ndarray::empty(_queue, { weights_size }, alloc); + + auto e1 = dal::backend::copy_host2usm(_queue, + _row_ptr.get_mutable_data(), + row_ptr.data(), + row_ptr.size()); + + auto e2 = dal::backend::copy_host2usm(_queue, + _col_indices.get_mutable_data(), + col_indices.data(), + col_indices.size()); + + auto e3 = dal::backend::copy_host2usm(_queue, + _weights.get_mutable_data(), + weights.data(), + weights.size()); + + e1.wait_and_throw(); + e2.wait_and_throw(); + e3.wait_and_throw(); + } + + graph_view_t get_device_view() const { + return { _num_nodes, + _row_ptr.get_mutable_data(), + _col_indices.get_mutable_data(), + _weights.get_mutable_data() }; + } + + sycl::queue& get_queue() const { + return _queue; + } + + std::size_t get_vertex_count() const { + return _num_nodes; + } private: - sycl::queue& _queue; - std::size_t _num_nodes; - ndarray _row_ptr; - ndarray _col_indices; - ndarray _weights; + sycl::queue& _queue; + std::size_t _num_nodes; + ndarray _row_ptr; + ndarray _col_indices; + ndarray _weights; }; } // namespace oneapi::dal::backend::primitives \ No newline at end of file diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 0008d0196a6..f037ebb0db2 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -20,7 +20,7 @@ void print_device_name(sycl::queue& queue) { std::cout << "Running on device: " << device_name << std::endl; } -template +template void print_frontier(const T* data, size_t count, size_t num_items) { size_t element_bitsize = sizeof(T) * 8; for (size_t i = 0; i < count; ++i) { @@ -31,8 +31,8 @@ void print_frontier(const T* data, size_t count, size_t num_items) { } std::vector compute_next_frontier(std::vector& row_ptr, - std::vector& col_indices, - std::vector& frontier) { + std::vector& col_indices, + std::vector& frontier) { std::vector next_frontier; for (auto node : frontier) { @@ -46,18 +46,19 @@ std::vector compute_next_frontier(std::vector& row_ptr, } // Remove duplicates std::sort(next_frontier.begin(), next_frontier.end()); - next_frontier.erase(std::unique(next_frontier.begin(), next_frontier.end()), next_frontier.end()); + next_frontier.erase(std::unique(next_frontier.begin(), next_frontier.end()), + next_frontier.end()); return next_frontier; } -template +template void compare_frontiers(T& device_frontier, std::vector& host_frontier, size_t num_nodes) { for (size_t i = 0; i < num_nodes; ++i) { bool tmpd = device_frontier.check(i); bool tmph = std::find(host_frontier.begin(), host_frontier.end(), i) != host_frontier.end(); if (tmpd != tmph) { - std::cout << "Mismatch at vertex " << i << ": device = " << tmpd << ", host = " << tmph << std::endl; - + std::cout << "Mismatch at vertex " << i << ": device = " << tmpd << ", host = " << tmph + << std::endl; } REQUIRE(tmpd == tmph); } @@ -71,26 +72,70 @@ TEST("test advance operation", "[advance]") { // std::vector row_ptr = {0, 2, 4, 6}; // std::vector col_indices = {1, 2, 0, 2, 0, 1}; // std::vector weights = {1, 1, 1, 1, 1, 1}; - std::vector row_ptr = {0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, 485, 489, 493, 497, 501, 504, 506}; - std::vector col_indices = {1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, 125, 126}; + std::vector row_ptr = { + 0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, + 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, + 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, + 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, + 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, + 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, + 473, 477, 481, 485, 489, 493, 497, 501, 504, 506 + }; + std::vector col_indices = { + 1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, + 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, + 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, + 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, + 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, + 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, + 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, + 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, + 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, + 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, + 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, + 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, + 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, + 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, + 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, + 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, + 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, + 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, + 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, + 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, + 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, + 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, + 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, + 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, + 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, + 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, + 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, + 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, + 125, 126 + }; std::vector weights(col_indices.size(), 1); size_t num_nodes = row_ptr.size() - 1; - auto graph = pr::csr_graph(queue, row_ptr, col_indices, weights); - auto in_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - auto out_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - + auto in_frontier = + pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + auto out_frontier = + pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + in_frontier.insert(3); in_frontier.insert(4); in_frontier.insert(52); in_frontier.insert(100); - std::vector host_frontier = {3, 4, 52, 100}; + std::vector host_frontier = { 3, 4, 52, 100 }; + + pr::advance(graph, + in_frontier, + out_frontier, + [=](auto vertex, auto neighbor, auto edge, auto weight) { + return true; // Always advance + }) + .wait_and_throw(); - pr::advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { - return true; // Always advance - }).wait_and_throw(); - auto tmp_frontier = compute_next_frontier(row_ptr, col_indices, host_frontier); compare_frontiers(out_frontier, tmp_frontier, num_nodes); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp index 579861e2841..396d29c59ce 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp @@ -27,7 +27,8 @@ class PerformanceTester { void set_end() { auto end_time = std::chrono::high_resolution_clock::now(); - auto duration = std::chrono::duration_cast(end_time - start_time_).count(); + auto duration = + std::chrono::duration_cast(end_time - start_time_).count(); std::cout << "Total execution time: " << duration << " ms" << std::endl; } @@ -35,8 +36,9 @@ class PerformanceTester { for (const auto& [name, events] : timings_) { std::cout << "Performance for " << name << ": "; for (const auto& event : events) { - auto duration = event.get_profiling_info() - - event.get_profiling_info(); + auto duration = + event.get_profiling_info() - + event.get_profiling_info(); std::cout << duration / 1e6 << " ms "; } std::cout << std::endl; @@ -55,9 +57,12 @@ void print_device_name(sycl::queue& queue) { std::cout << "Running on device: " << device_name << std::endl; } -template -std::vector host_bfs(std::vector& row_offsets, std::vector& col_indices, T src) { - std::vector distances(row_offsets.size() - 1, std::numeric_limits::max()); +template +std::vector host_bfs(std::vector& row_offsets, + std::vector& col_indices, + T src) { + std::vector distances(row_offsets.size() - 1, + std::numeric_limits::max()); std::queue q; q.push(src); distances[src] = 0; @@ -84,38 +89,85 @@ TEST("test advance operation", "[advance]") { PerformanceTester perf_tester; - std::vector row_ptr = {0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 481, 485, 489, 493, 497, 501, 504, 506}; - std::vector col_indices = {1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, 125, 126}; + std::vector row_ptr = { + 0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, + 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, + 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, + 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, + 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, + 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, + 473, 477, 481, 485, 489, 493, 497, 501, 504, 506 + }; + std::vector col_indices = { + 1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, + 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, + 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, + 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, + 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, + 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, + 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, + 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, + 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, + 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, + 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, + 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, + 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, + 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, + 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, + 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, + 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, + 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, + 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, + 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, + 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, + 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, + 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, + 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, + 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, + 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, + 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, + 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, + 125, 126 + }; std::vector weights(col_indices.size(), 1); - + auto graph = pr::csr_graph(queue, row_ptr, col_indices, weights); size_t num_nodes = row_ptr.size() - 1; auto in_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); auto out_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); - pr::ndarray distance = pr::ndarray::empty(queue, {static_cast(num_nodes)}, sycl::usm::alloc::device); + pr::ndarray distance = + pr::ndarray::empty(queue, + { static_cast(num_nodes) }, + sycl::usm::alloc::device); auto distance_ptr = distance.get_mutable_data(); const std::uint32_t src = 0; - queue.submit([&](sycl::handler& cgh) { - cgh.parallel_for(sycl::range<1>(num_nodes), [=](sycl::id<1> idx) { - distance_ptr[idx] = idx[0] == src ? 0 : num_nodes + 1; - }); - }).wait_and_throw(); - + queue + .submit([&](sycl::handler& cgh) { + cgh.parallel_for(sycl::range<1>(num_nodes), [=](sycl::id<1> idx) { + distance_ptr[idx] = idx[0] == src ? 0 : num_nodes + 1; + }); + }) + .wait_and_throw(); + in_frontier.insert(src); size_t iter = 0; /// Start BFS perf_tester.set_start(); while (!in_frontier.empty()) { - auto e = pr::advance(graph, in_frontier, out_frontier, [=](auto vertex, auto neighbor, auto edge, auto weight) { - bool visited = distance_ptr[neighbor] < num_nodes + 1; - if (!visited) { - distance_ptr[neighbor] = iter + 1; - } - return !visited; - }); + auto e = pr::advance(graph, + in_frontier, + out_frontier, + [=](auto vertex, auto neighbor, auto edge, auto weight) { + bool visited = distance_ptr[neighbor] < num_nodes + 1; + if (!visited) { + distance_ptr[neighbor] = iter + 1; + } + return !visited; + }); perf_tester.add("advance", e); e.wait_and_throw(); iter++; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index 6117bf61ee2..a214dea6473 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -14,7 +14,7 @@ void print_device_name(sycl::queue& queue) { std::cout << "Running on device: " << device_name << std::endl; } -template +template void print_frontier(const T* data, size_t count, size_t num_items) { size_t element_bitsize = sizeof(T) * 8; for (size_t i = 0; i < count; ++i) { @@ -50,11 +50,12 @@ TEST("frontier queue basic operations", "[frontier]") { REQUIRE(f.check(3) == false); REQUIRE(f.check(bitset::element_bitsize) == true); REQUIRE(f.check(bitset::element_bitsize + 1) == false); - + auto e = f.compute_active_frontier(); - REQUIRE(f.get_offsets_size().at_device(queue, 0, {e}) == 3); + REQUIRE(f.get_offsets_size().at_device(queue, 0, { e }) == 3); for (int i = 0; i < 3; i++) { - std::cout << "Active frontier item " << i << ": " << f.get_offsets().at_device(queue, i) << std::endl; + std::cout << "Active frontier item " << i << ": " << f.get_offsets().at_device(queue, i) + << std::endl; } f.clear(); From d471d0a594e39be9620917d95ca975c1e9166822 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 1 Sep 2025 14:12:46 +0200 Subject: [PATCH 17/69] added trailing new line to source files to complie with the CI formatter. --- cpp/oneapi/dal/backend/primitives/frontier.hpp | 2 +- cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp | 2 +- cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp | 2 +- cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp | 2 +- cpp/oneapi/dal/backend/primitives/frontier/graph.hpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier.hpp index 245ef5b7f91..8fc3b7fca39 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier.hpp @@ -1,3 +1,3 @@ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/backend/primitives/frontier/advance_dpc.hpp" -#include "oneapi/dal/backend/primitives/frontier/graph.hpp" \ No newline at end of file +#include "oneapi/dal/backend/primitives/frontier/graph.hpp" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp index c9c121eab69..9c5ee1ad2e6 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp @@ -321,4 +321,4 @@ sycl::event advance(const GraphT& graph, return { e }; } -} // namespace oneapi::dal::backend::primitives \ No newline at end of file +} // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index c4a75a1d704..e554f11c1ee 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -89,4 +89,4 @@ class bitset { element_t* _data; }; -} // namespace oneapi::dal::backend::primitives \ No newline at end of file +} // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 7805d1fef4f..faa0e2e7842 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -203,4 +203,4 @@ INSTANTIATE(std::uint32_t) #endif -} // namespace oneapi::dal::backend::primitives \ No newline at end of file +} // namespace oneapi::dal::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 5e1e12d26d8..11a9a529f8f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -157,4 +157,4 @@ class csr_graph { ndarray _weights; }; -} // namespace oneapi::dal::backend::primitives \ No newline at end of file +} // namespace oneapi::dal::backend::primitives From f720a870d251a38411cb8c38b0119a39ecb74081 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 3 Sep 2025 12:04:54 +0200 Subject: [PATCH 18/69] update headers to comply with the oneDAL naming style --- cpp/oneapi/dal/backend/primitives/frontier.hpp | 2 +- .../primitives/frontier/{advance_dpc.hpp => advance.hpp} | 0 cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename cpp/oneapi/dal/backend/primitives/frontier/{advance_dpc.hpp => advance.hpp} (100%) diff --git a/cpp/oneapi/dal/backend/primitives/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier.hpp index 8fc3b7fca39..69fe3aab466 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier.hpp @@ -1,3 +1,3 @@ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" -#include "oneapi/dal/backend/primitives/frontier/advance_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/advance.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp similarity index 100% rename from cpp/oneapi/dal/backend/primitives/frontier/advance_dpc.hpp rename to cpp/oneapi/dal/backend/primitives/frontier/advance.hpp diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index f037ebb0db2..2f421e997b2 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -1,5 +1,5 @@ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" -#include "oneapi/dal/backend/primitives/frontier/advance_dpc.hpp" +#include "oneapi/dal/backend/primitives/frontier/advance.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" #include "oneapi/dal/test/engine/common.hpp" From 10813a6916ab428c0f1a7ec06a54ddeb6110832b Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 3 Sep 2025 15:15:27 +0200 Subject: [PATCH 19/69] primitives/frontier: remove unused dependencies from BUILD --- cpp/oneapi/dal/backend/primitives/frontier/BUILD | 3 --- 1 file changed, 3 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD index ef392864d39..db480e28ed8 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/BUILD +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -9,9 +9,6 @@ dal_module ( auto = True, dal_deps = [ "@onedal//cpp/oneapi/dal/backend/primitives:common", - "@onedal//cpp/oneapi/dal/backend/primitives:blas", - "@onedal//cpp/oneapi/dal/backend/primitives/optimizers", - "@onedal//cpp/oneapi/dal/backend/primitives:sparse_blas", ], ) From 4da1b4ce4508b4ef8e81639fca7211ef461c7be8 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 3 Sep 2025 15:15:27 +0200 Subject: [PATCH 20/69] primitives/frontier: small code cleanup in advance.hpp (comment removal and add explanatory comment) --- cpp/oneapi/dal/backend/primitives/frontier/advance.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 9c5ee1ad2e6..3c8b2325e44 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -58,7 +58,6 @@ struct Context { const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / element_bitsize); const uint32_t* bitmap_offsets = in_dev_frontier.get_offsets(); - // const size_t acutal_id_offset = (item.get_group_linear_id() * coarsening_factor) + (item.get_local_linear_id() / bitmap_range); const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + (state.item.get_local_linear_id() % element_bitsize); return assigned_vertex; @@ -233,7 +232,8 @@ sycl::event advance(const GraphT& graph, auto out_dev_frontier = out.get_device_view(); auto graph_dev = graph.get_device_view(); - size_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups + /// The coarsening factor represents the number of integers a single work-group should handle. + size_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups; size_t element_bitsize = in_dev_frontier.get_element_bitsize(); // in bits sycl::range<1> local_range = { element_bitsize * coarsening_factor }; From 923f2fa4bf0a324a95fe222f55580fef1b235cb3 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 3 Sep 2025 15:15:27 +0200 Subject: [PATCH 21/69] primitives/frontier: remove unused includes and stray blank lines in headers, sources and tests --- cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp | 2 -- .../dal/backend/primitives/frontier/frontier_dpc.cpp | 4 ---- .../dal/backend/primitives/frontier/test/advance_dpc.cpp | 7 ------- .../dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp | 1 - .../dal/backend/primitives/frontier/test/frontier_dpc.cpp | 3 --- 5 files changed, 17 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index eda1028746c..9efe5365792 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -2,8 +2,6 @@ #include "oneapi/dal/common.hpp" #include "oneapi/dal/backend/common.hpp" -#include "oneapi/dal/graph/detail/common.hpp" -#include "oneapi/dal/graph/detail/container.hpp" #include "oneapi/dal/backend/primitives/frontier/bitset.hpp" #include "oneapi/dal/backend/primitives/ndarray.hpp" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index faa0e2e7842..4c142e2b83c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -1,8 +1,4 @@ - #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" -#include "oneapi/dal/backend/common.hpp" -#include "oneapi/dal/backend/primitives/ndarray.hpp" -#include "oneapi/dal/graph/detail/common.hpp" namespace oneapi::dal::backend::primitives { diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 2f421e997b2..7e35eeb7683 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -3,12 +3,6 @@ #include "oneapi/dal/backend/primitives/frontier/graph.hpp" #include "oneapi/dal/test/engine/common.hpp" -#include "oneapi/dal/test/engine/fixtures.hpp" -#include "oneapi/dal/test/engine/dataframe.hpp" - -#include "oneapi/dal/test/engine/common.hpp" -#include "oneapi/dal/test/engine/fixtures.hpp" -#include "oneapi/dal/test/engine/dataframe.hpp" namespace oneapi::dal::backend::primitives::test { @@ -138,7 +132,6 @@ TEST("test advance operation", "[advance]") { auto tmp_frontier = compute_next_frontier(row_ptr, col_indices, host_frontier); compare_frontiers(out_frontier, tmp_frontier, num_nodes); - } // TEST "test advance operation" } // namespace oneapi::dal::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp index 396d29c59ce..7b9c12b3ea8 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp @@ -184,7 +184,6 @@ TEST("test advance operation", "[advance]") { for (size_t i = 0; i < num_nodes; ++i) { REQUIRE(actual_distances[i] == expected_distances[i]); } - } // TEST "test advance operation" } // namespace oneapi::dal::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index a214dea6473..c3d089afb6d 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -1,8 +1,6 @@ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/test/engine/common.hpp" -#include "oneapi/dal/test/engine/fixtures.hpp" -#include "oneapi/dal/test/engine/dataframe.hpp" namespace oneapi::dal::backend::primitives::test { @@ -60,7 +58,6 @@ TEST("frontier queue basic operations", "[frontier]") { f.clear(); REQUIRE(f.empty() == true); - } // TEST "frontier queue operations" } // namespace oneapi::dal::backend::primitives::test From 7af91f5c5a79d1393357d308f5aad40cd77ddae5 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Fri, 19 Sep 2025 15:04:34 +0200 Subject: [PATCH 22/69] Remove perf_tests target from frontier BUILD --- cpp/oneapi/dal/backend/primitives/frontier/BUILD | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD index db480e28ed8..83d8a7dd277 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/BUILD +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -26,16 +26,3 @@ dal_test_suite ( ":frontier", ], ) - -dal_test_suite( - name = "perf_tests", - framework = "catch2", - compile_as = [ "dpc++" ], - private = True, - srcs = glob([ - "test/*perf_dpc.cpp", - ]), - dal_deps = [ - ":frontier", - ], -) \ No newline at end of file From 635619892142c69a40f2a84606e570237f5bc20e Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Fri, 19 Sep 2025 15:04:35 +0200 Subject: [PATCH 23/69] Refactor frontier context and bitmap kernel: rename Context/ContextState and introduce hierarchical reductions --- .../backend/primitives/frontier/advance.hpp | 250 ++++++++++-------- 1 file changed, 143 insertions(+), 107 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 3c8b2325e44..b4e191ee34f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -6,34 +6,31 @@ namespace oneapi::dal::backend::primitives { -/// ContextState holds the state of the current processing group in the kernel +/// frontier_context_state holds the state of the current processing group in the kernel /// It includes the group offset, coarsening factor, offsets size, and the SYCL /// nd_item for the current work item. -struct ContextState { +struct frontier_context_state { size_t group_offset; const uint16_t coarsening_factor; const uint32_t offsets_size; const sycl::nd_item<1> item; }; -/// Context is a template class that provides an interface for the kernel to +/// frontier_context is a template class that provides an interface for the kernel to /// interact with the frontier data structure. It holds the limit of the graph, /// the input frontier, and the output frontier. It provides methods to initialize /// the context state, check if there are more elements to process, get the /// assigned element, check if a vertex is in the frontier, and insert a vertex /// into the output frontier. template -struct Context { - size_t limit; - InFrontierDevT in_dev_frontier; - OutFrontierDevT out_dev_frontier; - - Context(size_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) +class frontier_context { +public: + frontier_context(size_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) : limit(limit), in_dev_frontier(in_dev_frontier), out_dev_frontier(out_dev_frontier) {} - inline ContextState init(sycl::nd_item<1>& item) const { + inline frontier_context_state init(sycl::nd_item<1>& item) const { return { item.get_group_linear_id(), static_cast(item.get_local_range(0) / in_dev_frontier.get_element_bitsize()), @@ -43,157 +40,196 @@ struct Context { } /// This method checks if there are more elements to process in the current group. - inline bool need_to_process(ContextState& state) const { + inline bool need_to_process(frontier_context_state& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } /// This method completes the current iteration by updating the group offset. - inline void complete_iteration(ContextState& state) const { + inline void complete_iteration(frontier_context_state& state) const { state.group_offset += state.item.get_group_range(0); } /// This method retrieves the assigned element for the current work item. - inline size_t get_assigned_element(const ContextState& state) const { + inline size_t get_assigned_element(const frontier_context_state& state) const { const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / element_bitsize); const uint32_t* bitmap_offsets = in_dev_frontier.get_offsets(); + ONEDAL_ASSERT(acutal_id_offset < in_dev_frontier.get_offsets_size()[0]); const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + (state.item.get_local_linear_id() % element_bitsize); return assigned_vertex; } /// This method checks if a vertex is in the input frontier. - inline bool check(const ContextState& state, size_t vertex) const { + inline bool check(const frontier_context_state& state, size_t vertex) const { return vertex < limit && in_dev_frontier.check(vertex); } /// This method inserts a vertex into the output frontier. - inline void insert(const ContextState& state, size_t vertex) const { + inline void insert(const frontier_context_state& state, size_t vertex) const { out_dev_frontier.insert(vertex); } + + size_t limit; + InFrontierDevT in_dev_frontier; + OutFrontierDevT out_dev_frontier; }; /// BitmapKernel is a template struct that defines the kernel to be executed on the device. /// It processes the input frontier and advances it based on the provided functor. template struct BitmapKernel { - void operator()(sycl::nd_item<1> item) const { - const size_t lid = item.get_local_linear_id(); - const auto wgroup = item.get_group(); + template + inline void distribute_workload(frontier_context_state& state, const VertexT& vertex) const { + const size_t lid = state.item.get_local_linear_id(); + const auto wgroup = state.item.get_group(); const size_t wgroup_size = wgroup.get_local_range(0); - const auto sgroup = item.get_sub_group(); + const auto sgroup = state.item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); const size_t sgroup_size = sgroup.get_local_range()[0]; - const size_t llid = sgroup.get_local_linear_id(); - auto state = context.init(item); + if (sgroup.leader()) { + subgroup_reduce_tail[sgroup_id] = 0; + } + if (wgroup.leader()) { + workgroup_reduce_tail[0] = 0; + } + + sycl::atomic_ref + sg_tail{ subgroup_reduce_tail[sgroup_id] }; + sycl::atomic_ref + wg_tail{ workgroup_reduce_tail[0] }; + const uint32_t offset = sgroup_id * sgroup_size; + + if (context.check(state, vertex)) { + uint32_t n_edges = graph_dev.get_degree(vertex); + if (n_edges >= wgroup_size * wgroup_size) { // if the number of edges is large enough, we can assign the vertex to the workgroup + uint32_t loc = wg_tail.fetch_add(static_cast(1)); + n_edges_wg[loc] = n_edges; + workgroup_reduce[loc] = vertex; + workgroup_ids[loc] = lid; + } + else if (n_edges >= sgroup_size) { // assign to the subgroup + uint32_t loc = sg_tail.fetch_add(static_cast(1)); + n_edges_sg[offset + loc] = n_edges; + subgroup_reduce[offset + loc] = vertex; + subgroup_ids[offset + loc] = lid; + } + visited[lid] = false; + } + else { + visited[lid] = true; + } + } - while (context.need_to_process(state)) { - const auto assigned_vertex = context.get_assigned_element(state); + inline void process_workgroup_reduction(frontier_context_state& state) const { + /// This function processes the vertices assigned to the workgroup. + sycl::atomic_ref + wg_tail{ workgroup_reduce_tail[0] }; + + const auto wgroup = state.item.get_group(); + const size_t lid = state.item.get_local_linear_id(); + const size_t wgroup_size = wgroup.get_local_range(0); - if (sgroup.leader()) { - subgroup_reduce_tail[sgroup_id] = 0; + for (size_t i = 0; i < wg_tail.load(); i++) { + auto vertex = workgroup_reduce[i]; + size_t n_edges = n_edges_wg[i]; + auto start = graph_dev.begin(vertex); + + for (auto j = lid; j < n_edges; j += wgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { + context.insert(state, neighbor); + } } + if (wgroup.leader()) { - workgroup_reduce_tail[0] = 0; + visited[workgroup_ids[i]] = true; } + } + } - sycl::atomic_ref - sg_tail{ subgroup_reduce_tail[sgroup_id] }; - sycl::atomic_ref - wg_tail{ workgroup_reduce_tail[0] }; - - // 1. distribute the workload based on the number of edges to the workgroup, subgroup or workitem - const uint32_t offset = sgroup_id * sgroup_size; - if (context.check(state, assigned_vertex)) { - uint32_t n_edges = graph_dev.get_degree(assigned_vertex); - if (n_edges >= - wgroup_size * - wgroup_size) { // if the number of edges is large enough, we can assign the vertex to the workgroup - uint32_t loc = wg_tail.fetch_add(static_cast(1)); - n_edges_wg[loc] = n_edges; - workgroup_reduce[loc] = assigned_vertex; - workgroup_ids[loc] = lid; - } - else if (n_edges >= sgroup_size) { // assign to the subgroup - uint32_t loc = sg_tail.fetch_add(static_cast(1)); - n_edges_sg[offset + loc] = n_edges; - subgroup_reduce[offset + loc] = assigned_vertex; - subgroup_ids[offset + loc] = lid; + inline void process_subgroup_reduction(frontier_context_state& state) const { + const auto sgroup = state.item.get_sub_group(); + const auto sgroup_id = sgroup.get_group_id(); + const size_t sgroup_size = sgroup.get_local_range()[0]; + const size_t llid = sgroup.get_local_linear_id(); + const uint32_t offset = sgroup_id * sgroup_size; + + sycl::atomic_ref + sg_tail{ subgroup_reduce_tail[sgroup_id] }; + + for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { + // active_elements_tail[subgroup_id] is always less or equal than subgroup_size + size_t vertex_id = offset + i; + auto vertex = subgroup_reduce[vertex_id]; + size_t n_edges = n_edges_sg[vertex_id]; + + auto start = graph_dev.begin(vertex); + + for (auto j = llid; j < n_edges; j += sgroup_size) { + auto n = start + j; + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { + context.insert(state, neighbor); } - visited[lid] = false; } - else { - visited[lid] = true; + + if (sgroup.leader()) { + visited[subgroup_ids[vertex_id]] = true; } + } + } - sycl::group_barrier(wgroup); + template + inline void process_workitem_reduction(frontier_context_state& state, const VertexT& vertex) const { + const size_t lid = state.item.get_local_linear_id(); - // 2. process the the edge of one vertex at a time using the workgroup - for (size_t i = 0; i < wg_tail.load(); i++) { - auto vertex = workgroup_reduce[i]; - size_t n_edges = n_edges_wg[i]; - auto start = graph_dev.begin(vertex); - - for (auto j = lid; j < n_edges; j += wgroup_size) { - auto n = start + j; - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { - context.insert(state, neighbor); - } - } + if (!visited[lid]) { + auto start = graph_dev.begin(vertex); + auto end = graph_dev.end(vertex); - if (wgroup.leader()) { - visited[workgroup_ids[i]] = true; + for (auto n = start; n != end; ++n) { + auto edge = n.get_index(); + auto weight = graph_dev.get_weight(edge); + auto neighbor = *n; + if (functor(vertex, neighbor, edge, weight)) { + context.insert(state, neighbor); } } + } + } + void operator()(sycl::nd_item<1> item) const { + auto state = context.init(item); + const auto wgroup = item.get_group(); + const auto sgroup = item.get_sub_group(); + + while (context.need_to_process(state)) { + const auto assigned_vertex = context.get_assigned_element(state); + + // 1. distribute the workload based on the number of edges to the workgroup, subgroup or workitem + distribute_workload(state, assigned_vertex); + + sycl::group_barrier(wgroup); + + // 2. process the the edge of one vertex at a time using the workgroup + process_workgroup_reduction(state); sycl::group_barrier(sgroup); // 3. process the edges of one vertex at a time using the subgroup - for ( - size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; - i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size - size_t vertex_id = offset + i; - auto vertex = subgroup_reduce[vertex_id]; - size_t n_edges = n_edges_sg[vertex_id]; - - auto start = graph_dev.begin(vertex); - - for (auto j = llid; j < n_edges; j += sgroup_size) { - auto n = start + j; - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { - context.insert(state, neighbor); - } - } - - if (sgroup.leader()) { - visited[subgroup_ids[vertex_id]] = true; - } - } + process_subgroup_reduction(state); sycl::group_barrier(sgroup); // 4. process the edges of the vertices that were not assigned to the workgroup or subgroup - if (!visited[lid]) { - auto vertex = assigned_vertex; - auto start = graph_dev.begin(vertex); - auto end = graph_dev.end(vertex); - - for (auto n = start; n != end; ++n) { - auto edge = n.get_index(); - auto weight = graph_dev.get_weight(edge); - auto neighbor = *n; - if (functor(vertex, neighbor, edge, weight)) { - context.insert(state, neighbor); - } - } - } + process_workitem_reduction(state, assigned_vertex); + context.complete_iteration(state); // complete the current iteration } } @@ -249,7 +285,7 @@ sycl::event advance(const GraphT& graph, : global_size + (local_range[0] - global_size % local_range[0]) }; - Context context{ num_nodes, + frontier_context context{ num_nodes, in_dev_frontier, out_dev_frontier }; using bitmap_kernel_t = From 2efbe84c7458c0a7c7e7d324a514053401b7db2c Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Fri, 19 Sep 2025 15:04:35 +0200 Subject: [PATCH 24/69] Remove performance testing scaffolding from frontier BFS test and rename test file --- .../test/{bfs_perf_dpc.cpp => bfs_dpc.cpp} | 46 ------------------- 1 file changed, 46 deletions(-) rename cpp/oneapi/dal/backend/primitives/frontier/test/{bfs_perf_dpc.cpp => bfs_dpc.cpp} (82%) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp similarity index 82% rename from cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp rename to cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index 7b9c12b3ea8..b9e4b017d91 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_perf_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -12,45 +12,6 @@ namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; -class PerformanceTester { -public: - void add(const std::string& name, const sycl::event& event) { - if (timings_.find(name) == timings_.end()) { - timings_[name] = std::vector(); - } - timings_[name].push_back(event); - } - - void set_start() { - start_time_ = std::chrono::high_resolution_clock::now(); - } - - void set_end() { - auto end_time = std::chrono::high_resolution_clock::now(); - auto duration = - std::chrono::duration_cast(end_time - start_time_).count(); - std::cout << "Total execution time: " << duration << " ms" << std::endl; - } - - void print() const { - for (const auto& [name, events] : timings_) { - std::cout << "Performance for " << name << ": "; - for (const auto& event : events) { - auto duration = - event.get_profiling_info() - - event.get_profiling_info(); - std::cout << duration / 1e6 << " ms "; - } - std::cout << std::endl; - } - } - -private: - // define start time - std::chrono::high_resolution_clock::time_point start_time_; - std::map> timings_; -}; - void print_device_name(sycl::queue& queue) { const auto device = queue.get_device(); const auto device_name = device.get_info(); @@ -87,8 +48,6 @@ TEST("test advance operation", "[advance]") { auto& queue = policy.get_queue(); print_device_name(queue); - PerformanceTester perf_tester; - std::vector row_ptr = { 0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, @@ -156,7 +115,6 @@ TEST("test advance operation", "[advance]") { size_t iter = 0; /// Start BFS - perf_tester.set_start(); while (!in_frontier.empty()) { auto e = pr::advance(graph, in_frontier, @@ -168,17 +126,13 @@ TEST("test advance operation", "[advance]") { } return !visited; }); - perf_tester.add("advance", e); e.wait_and_throw(); iter++; pr::swap_frontiers(in_frontier, out_frontier); out_frontier.clear(); } - perf_tester.set_end(); /// End BFS - // perf_tester.print(); - auto expected_distances = host_bfs(row_ptr, col_indices, src); auto actual_distances = distance.to_host(queue).get_data(); for (size_t i = 0; i < num_nodes; ++i) { From 2b7b2c4670c52d149dde885be5dc9ad56b0eacae Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Fri, 19 Sep 2025 15:19:52 +0200 Subject: [PATCH 25/69] Enhance code readability by adding comments and using const for variable declarations in BitmapKernel and frontier_dpc implementations --- .../backend/primitives/frontier/advance.hpp | 33 +++++++++++-------- .../primitives/frontier/frontier_dpc.cpp | 12 +++---- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index b4e191ee34f..b2c8076719a 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -80,7 +80,8 @@ class frontier_context { /// It processes the input frontier and advances it based on the provided functor. template struct BitmapKernel { - template + /// This function distributes the workload among the workgroup, subgroup, and individual work items + template inline void distribute_workload(frontier_context_state& state, const VertexT& vertex) const { const size_t lid = state.item.get_local_linear_id(); const auto wgroup = state.item.get_group(); @@ -91,11 +92,11 @@ struct BitmapKernel { if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; - } + } if (wgroup.leader()) { workgroup_reduce_tail[0] = 0; } - + sycl::atomic_ref sg_tail{ subgroup_reduce_tail[sgroup_id] }; sycl::atomic_ref @@ -104,7 +105,8 @@ struct BitmapKernel { if (context.check(state, vertex)) { uint32_t n_edges = graph_dev.get_degree(vertex); - if (n_edges >= wgroup_size * wgroup_size) { // if the number of edges is large enough, we can assign the vertex to the workgroup + // if the number of edges is large enough, we can assign the vertex to the workgroup + if (n_edges >= wgroup_size * wgroup_size) { uint32_t loc = wg_tail.fetch_add(static_cast(1)); n_edges_wg[loc] = n_edges; workgroup_reduce[loc] = vertex; @@ -123,11 +125,12 @@ struct BitmapKernel { } } + /// This function processes the vertices assigned to the workgroup. inline void process_workgroup_reduction(frontier_context_state& state) const { /// This function processes the vertices assigned to the workgroup. sycl::atomic_ref wg_tail{ workgroup_reduce_tail[0] }; - + const auto wgroup = state.item.get_group(); const size_t lid = state.item.get_local_linear_id(); const size_t wgroup_size = wgroup.get_local_range(0); @@ -153,6 +156,7 @@ struct BitmapKernel { } } + /// This function processes the vertices assigned to the subgroup. inline void process_subgroup_reduction(frontier_context_state& state) const { const auto sgroup = state.item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); @@ -163,7 +167,7 @@ struct BitmapKernel { sycl::atomic_ref sg_tail{ subgroup_reduce_tail[sgroup_id] }; - for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { + for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size size_t vertex_id = offset + i; auto vertex = subgroup_reduce[vertex_id]; @@ -187,8 +191,10 @@ struct BitmapKernel { } } - template - inline void process_workitem_reduction(frontier_context_state& state, const VertexT& vertex) const { + /// This function processes the vertices that were not assigned to the workgroup or subgroup. + template + inline void process_workitem_reduction(frontier_context_state& state, + const VertexT& vertex) const { const size_t lid = state.item.get_local_linear_id(); if (!visited[lid]) { @@ -216,7 +222,6 @@ struct BitmapKernel { // 1. distribute the workload based on the number of edges to the workgroup, subgroup or workitem distribute_workload(state, assigned_vertex); - sycl::group_barrier(wgroup); // 2. process the the edge of one vertex at a time using the workgroup @@ -229,7 +234,7 @@ struct BitmapKernel { // 4. process the edges of the vertices that were not assigned to the workgroup or subgroup process_workitem_reduction(state, assigned_vertex); - + context.complete_iteration(state); // complete the current iteration } } @@ -285,9 +290,11 @@ sycl::event advance(const GraphT& graph, : global_size + (local_range[0] - global_size % local_range[0]) }; - frontier_context context{ num_nodes, - in_dev_frontier, - out_dev_frontier }; + frontier_context context{ + num_nodes, + in_dev_frontier, + out_dev_frontier + }; using bitmap_kernel_t = BitmapKernel; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 4c142e2b83c..666d1cfb50d 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -87,12 +87,12 @@ inline sycl::event frontier::compute_active_frontier() { auto offsets_size_pointer = _offsets.get_mutable_data(); auto offsets_pointer = _offsets.get_mutable_data() + 1; - uint32_t element_bitsize = bitmap.get_element_bitsize(); - size_t local_range = 256; // propose_wg_size(this->_queue); - size_t mlb_count = _mlb_layer.get_count(); - size_t global_range = (mlb_count % local_range == 0) - ? mlb_count - : (mlb_count + local_range - (mlb_count % local_range)); + const uint32_t element_bitsize = bitmap.get_element_bitsize(); + const size_t local_range = 256; // propose_wg_size(this->_queue); + const size_t mlb_count = _mlb_layer.get_count(); + const size_t global_range = (mlb_count % local_range == 0) + ? mlb_count + : (mlb_count + local_range - (mlb_count % local_range)); // check if local memory is enough bool use_local_mem = From 5dda7de993fe5a1737c52a45a93b1e540c727ab4 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 11:27:18 +0200 Subject: [PATCH 26/69] Add copyright notices to header files in the frontier module --- .../backend/primitives/frontier/advance.hpp | 18 ++++++++++++++++++ .../dal/backend/primitives/frontier/bitset.hpp | 18 ++++++++++++++++++ .../backend/primitives/frontier/frontier.hpp | 18 ++++++++++++++++++ .../primitives/frontier/frontier_dpc.cpp | 18 ++++++++++++++++++ .../dal/backend/primitives/frontier/graph.hpp | 18 ++++++++++++++++++ .../primitives/frontier/test/advance_dpc.cpp | 18 ++++++++++++++++++ .../primitives/frontier/test/bfs_dpc.cpp | 18 ++++++++++++++++++ .../primitives/frontier/test/frontier_dpc.cpp | 18 ++++++++++++++++++ 8 files changed, 144 insertions(+) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index b2c8076719a..f7b42e6bc6a 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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/primitives/ndarray.hpp" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index e554f11c1ee..5f944c01dc5 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 9efe5365792..21864ad3d98 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 666d1cfb50d..9b9b7e9118d 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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/backend/primitives/frontier/frontier.hpp" namespace oneapi::dal::backend::primitives { diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 11a9a529f8f..39dd86a4d06 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 7e35eeb7683..83fc94c6254 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/backend/primitives/frontier/advance.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index b9e4b017d91..f5258ba0e58 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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/backend/primitives/frontier.hpp" #include "oneapi/dal/test/engine/common.hpp" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index c3d089afb6d..7119905157e 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -1,3 +1,21 @@ +/******************************************************************************* +* Copyright 2025 Intel Corporation +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/test/engine/common.hpp" From f2641e6811f745a24ae5274189fc3c6bd85c0b14 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 11:40:08 +0200 Subject: [PATCH 27/69] Refactor frontier test files: change vector to set for frontier representation and update test case names for clarity --- .../primitives/frontier/test/advance_dpc.cpp | 23 +++++++------------ .../primitives/frontier/test/bfs_dpc.cpp | 7 ++---- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 83fc94c6254..c9bdba2e67e 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -42,10 +42,10 @@ void print_frontier(const T* data, size_t count, size_t num_items) { } } -std::vector compute_next_frontier(std::vector& row_ptr, - std::vector& col_indices, - std::vector& frontier) { - std::vector next_frontier; +std::set compute_next_frontier(std::vector& row_ptr, + std::vector& col_indices, + std::set& frontier) { + std::set next_frontier; for (auto node : frontier) { auto start = row_ptr[node]; @@ -53,21 +53,17 @@ std::vector compute_next_frontier(std::vector& row_ptr, for (size_t i = start; i < end; ++i) { auto neighbor = col_indices[i]; - next_frontier.push_back(neighbor); + next_frontier.insert(neighbor); } } - // Remove duplicates - std::sort(next_frontier.begin(), next_frontier.end()); - next_frontier.erase(std::unique(next_frontier.begin(), next_frontier.end()), - next_frontier.end()); return next_frontier; } template -void compare_frontiers(T& device_frontier, std::vector& host_frontier, size_t num_nodes) { +void compare_frontiers(T& device_frontier, std::set& host_frontier, size_t num_nodes) { for (size_t i = 0; i < num_nodes; ++i) { bool tmpd = device_frontier.check(i); - bool tmph = std::find(host_frontier.begin(), host_frontier.end(), i) != host_frontier.end(); + bool tmph = host_frontier.find(i) != host_frontier.end(); if (tmpd != tmph) { std::cout << "Mismatch at vertex " << i << ": device = " << tmpd << ", host = " << tmph << std::endl; @@ -81,9 +77,6 @@ TEST("test advance operation", "[advance]") { auto& queue = policy.get_queue(); print_device_name(queue); - // std::vector row_ptr = {0, 2, 4, 6}; - // std::vector col_indices = {1, 2, 0, 2, 0, 1}; - // std::vector weights = {1, 1, 1, 1, 1, 1}; std::vector row_ptr = { 0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, @@ -138,7 +131,7 @@ TEST("test advance operation", "[advance]") { in_frontier.insert(4); in_frontier.insert(52); in_frontier.insert(100); - std::vector host_frontier = { 3, 4, 52, 100 }; + std::set host_frontier = { 3, 4, 52, 100 }; pr::advance(graph, in_frontier, diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index f5258ba0e58..25940923c23 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -17,14 +17,11 @@ *******************************************************************************/ #include "oneapi/dal/backend/primitives/frontier.hpp" - #include "oneapi/dal/test/engine/common.hpp" -#include "oneapi/dal/test/engine/fixtures.hpp" -#include "oneapi/dal/test/engine/dataframe.hpp" + #include #include #include -#include namespace oneapi::dal::backend::primitives::test { @@ -61,7 +58,7 @@ std::vector host_bfs(std::vector& row_offsets, return distances; } -TEST("test advance operation", "[advance]") { +TEST("test BFS", "[bfs]") { DECLARE_TEST_POLICY(policy); auto& queue = policy.get_queue(); print_device_name(queue); From 06265d4061fcd4200511ad78d44bc4d59483e84f Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 11:53:00 +0200 Subject: [PATCH 28/69] Refactor compute_next_frontier to use vector instead of set for improved performance and memory efficiency --- .../primitives/frontier/test/advance_dpc.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index c9bdba2e67e..398c072ff85 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -42,28 +42,30 @@ void print_frontier(const T* data, size_t count, size_t num_items) { } } -std::set compute_next_frontier(std::vector& row_ptr, - std::vector& col_indices, - std::set& frontier) { - std::set next_frontier; +std::vector compute_next_frontier(std::vector& row_ptr, + std::vector& col_indices, + std::vector& frontier) { + std::vector next_frontier(frontier.size(), false); + + for (size_t node = 0; node < frontier.size(); ++node) { + if (!frontier[node]) continue; - for (auto node : frontier) { auto start = row_ptr[node]; auto end = row_ptr[node + 1]; for (size_t i = start; i < end; ++i) { auto neighbor = col_indices[i]; - next_frontier.insert(neighbor); + next_frontier[neighbor] = true; } } return next_frontier; } template -void compare_frontiers(T& device_frontier, std::set& host_frontier, size_t num_nodes) { +void compare_frontiers(T& device_frontier, std::vector& host_frontier, size_t num_nodes) { for (size_t i = 0; i < num_nodes; ++i) { bool tmpd = device_frontier.check(i); - bool tmph = host_frontier.find(i) != host_frontier.end(); + bool tmph = host_frontier[i]; if (tmpd != tmph) { std::cout << "Mismatch at vertex " << i << ": device = " << tmpd << ", host = " << tmph << std::endl; @@ -131,7 +133,11 @@ TEST("test advance operation", "[advance]") { in_frontier.insert(4); in_frontier.insert(52); in_frontier.insert(100); - std::set host_frontier = { 3, 4, 52, 100 }; + std::vector host_frontier(num_nodes, false); + host_frontier[3] = true; + host_frontier[4] = true; + host_frontier[52] = true; + host_frontier[100] = true; pr::advance(graph, in_frontier, From df28d7a78e3287d62601e96411842438cd87992c Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 14:04:47 +0200 Subject: [PATCH 29/69] tests(frontier): add shared test utilities and wire includes; expose header to BUILD --- .../dal/backend/primitives/frontier/BUILD | 3 + .../primitives/frontier/test/advance_dpc.cpp | 7 +-- .../primitives/frontier/test/bfs_dpc.cpp | 13 ++-- .../primitives/frontier/test/frontier_dpc.cpp | 8 +-- .../primitives/frontier/test/utils.hpp | 62 +++++++++++++++++++ 5 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp diff --git a/cpp/oneapi/dal/backend/primitives/frontier/BUILD b/cpp/oneapi/dal/backend/primitives/frontier/BUILD index 83d8a7dd277..3e2ab8a790c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/BUILD +++ b/cpp/oneapi/dal/backend/primitives/frontier/BUILD @@ -17,6 +17,9 @@ dal_test_suite ( framework = "catch2", compile_as = [ "dpc++" ], private = True, + hdrs = glob([ + "test/*.hpp", + ]), srcs = glob([ "test/*_dpc.cpp", ], exclude=[ diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 398c072ff85..bfc48c4ad3a 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -19,6 +19,7 @@ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/backend/primitives/frontier/advance.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" +#include "oneapi/dal/backend/primitives/frontier/test/utils.hpp" #include "oneapi/dal/test/engine/common.hpp" @@ -26,12 +27,6 @@ namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; -void print_device_name(sycl::queue& queue) { - const auto device = queue.get_device(); - const auto device_name = device.get_info(); - std::cout << "Running on device: " << device_name << std::endl; -} - template void print_frontier(const T* data, size_t count, size_t num_items) { size_t element_bitsize = sizeof(T) * 8; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index 25940923c23..b63d405cabb 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -17,6 +17,7 @@ *******************************************************************************/ #include "oneapi/dal/backend/primitives/frontier.hpp" +#include "oneapi/dal/backend/primitives/frontier/test/utils.hpp" #include "oneapi/dal/test/engine/common.hpp" #include @@ -27,16 +28,10 @@ namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; -void print_device_name(sycl::queue& queue) { - const auto device = queue.get_device(); - const auto device_name = device.get_info(); - std::cout << "Running on device: " << device_name << std::endl; -} - template -std::vector host_bfs(std::vector& row_offsets, - std::vector& col_indices, - T src) { +std::vector host_bfs(const std::vector& row_offsets, + const std::vector& col_indices, + const T src) { std::vector distances(row_offsets.size() - 1, std::numeric_limits::max()); std::queue q; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index 7119905157e..bb128870ae8 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -17,19 +17,13 @@ *******************************************************************************/ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" - +#include "oneapi/dal/backend/primitives/frontier/test/utils.hpp" #include "oneapi/dal/test/engine/common.hpp" namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; -void print_device_name(sycl::queue& queue) { - const auto device = queue.get_device(); - const auto device_name = device.get_info(); - std::cout << "Running on device: " << device_name << std::endl; -} - template void print_frontier(const T* data, size_t count, size_t num_items) { size_t element_bitsize = sizeof(T) * 8; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp new file mode 100644 index 00000000000..dcecc208ffe --- /dev/null +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + + +void print_device_name(sycl::queue& queue) { + const auto device = queue.get_device(); + const auto device_name = device.get_info(); + std::cout << "Running on device: " << device_name << std::endl; +} + +namespace oneapi::dal::backend::primitives { + struct csr_graph_data { + std::vector row_ptr; + std::vector col_indices; + std::vector weights; +}; + +csr_graph_data generate_random_graph(std::size_t vertex_count, + double edge_probability, + std::uint32_t seed) { + if (vertex_count == 0) { + return { std::vector{ 0 }, {}, {} }; + } + + std::mt19937 rng(seed); + std::bernoulli_distribution edge_dist(edge_probability); + std::uniform_int_distribution vertex_dist(0, + static_cast(vertex_count - 1)); + + std::vector row_ptr(vertex_count + 1, 0); + std::vector col_indices; + col_indices.reserve(vertex_count); + + for (std::size_t src = 0; src < vertex_count; ++src) { + const auto edges_before = col_indices.size(); + for (std::size_t dst = 0; dst < vertex_count; ++dst) { + if (src == dst) { + continue; + } + if (edge_dist(rng)) { + col_indices.push_back(static_cast(dst)); + } + } + + if (col_indices.size() == edges_before && vertex_count > 1) { + std::uint32_t fallback = vertex_dist(rng); + if (fallback == src) { + fallback = (fallback + 1) % static_cast(vertex_count); + } + col_indices.push_back(fallback); + } + + row_ptr[src + 1] = static_cast(col_indices.size()); + } + + std::vector weights(col_indices.size(), 1); + return { std::move(row_ptr), std::move(col_indices), std::move(weights) }; +} + +} // namespace oneapi::dal::backend::primitives \ No newline at end of file From 225b1117d3c9823caf9911f9e37e960eb54618c3 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 14:04:47 +0200 Subject: [PATCH 30/69] tests(frontier): switch tests to randomized graph generation and refine helper signatures --- .../primitives/frontier/test/advance_dpc.cpp | 87 +++++++------------ .../primitives/frontier/test/bfs_dpc.cpp | 53 ++--------- 2 files changed, 36 insertions(+), 104 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index bfc48c4ad3a..990799febda 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -37,9 +37,9 @@ void print_frontier(const T* data, size_t count, size_t num_items) { } } -std::vector compute_next_frontier(std::vector& row_ptr, - std::vector& col_indices, - std::vector& frontier) { +std::vector compute_next_frontier(const std::vector& row_ptr, + const std::vector& col_indices, + const std::vector& frontier) { std::vector next_frontier(frontier.size(), false); for (size_t node = 0; node < frontier.size(); ++node) { @@ -57,7 +57,9 @@ std::vector compute_next_frontier(std::vector& row_ptr, } template -void compare_frontiers(T& device_frontier, std::vector& host_frontier, size_t num_nodes) { +void compare_frontiers(T& device_frontier, + const std::vector& host_frontier, + size_t num_nodes) { for (size_t i = 0; i < num_nodes; ++i) { bool tmpd = device_frontier.check(i); bool tmph = host_frontier[i]; @@ -74,65 +76,34 @@ TEST("test advance operation", "[advance]") { auto& queue = policy.get_queue(); print_device_name(queue); - std::vector row_ptr = { - 0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, - 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, - 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, - 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, - 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, - 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, - 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, - 473, 477, 481, 485, 489, 493, 497, 501, 504, 506 - }; - std::vector col_indices = { - 1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, - 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, - 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, - 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, - 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, - 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, - 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, - 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, - 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, - 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, - 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, - 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, - 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, - 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, - 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, - 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, - 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, - 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, - 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, - 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, - 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, - 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, - 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, - 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, - 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, - 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, - 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, - 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, - 125, 126 - }; - std::vector weights(col_indices.size(), 1); - size_t num_nodes = row_ptr.size() - 1; - - auto graph = pr::csr_graph(queue, row_ptr, col_indices, weights); + const std::uint32_t seed = GENERATE(42u, 313u, 2025u); + const double edge_probability = GENERATE(0.05, 0.1, 0.2); + const std::size_t num_nodes = GENERATE(128, 512, 1024); + + const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); + auto graph = pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); auto in_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); auto out_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); - in_frontier.insert(3); - in_frontier.insert(4); - in_frontier.insert(52); - in_frontier.insert(100); std::vector host_frontier(num_nodes, false); - host_frontier[3] = true; - host_frontier[4] = true; - host_frontier[52] = true; - host_frontier[100] = true; + std::mt19937 frontier_rng(seed ^ 0x9e3779b9u); + std::bernoulli_distribution frontier_dist(0.1); + + for (std::size_t vertex = 0; vertex < num_nodes; ++vertex) { + if (frontier_dist(frontier_rng)) { + in_frontier.insert(static_cast(vertex)); + host_frontier[vertex] = true; + } + } + + if (in_frontier.empty()) { + std::uniform_int_distribution vertex_dist(0, static_cast(num_nodes - 1)); + const auto fallback_vertex = vertex_dist(frontier_rng); + in_frontier.insert(fallback_vertex); + host_frontier[fallback_vertex] = true; + } pr::advance(graph, in_frontier, @@ -142,7 +113,7 @@ TEST("test advance operation", "[advance]") { }) .wait_and_throw(); - auto tmp_frontier = compute_next_frontier(row_ptr, col_indices, host_frontier); + auto tmp_frontier = compute_next_frontier(graph_data.row_ptr, graph_data.col_indices, host_frontier); compare_frontiers(out_frontier, tmp_frontier, num_nodes); } // TEST "test advance operation" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index b63d405cabb..7c0576ffc59 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -58,51 +58,12 @@ TEST("test BFS", "[bfs]") { auto& queue = policy.get_queue(); print_device_name(queue); - std::vector row_ptr = { - 0, 2, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, - 65, 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, - 133, 137, 141, 145, 149, 153, 157, 161, 165, 169, 173, 177, 181, 185, 189, 193, 197, - 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, - 269, 273, 277, 281, 285, 289, 293, 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, - 337, 341, 345, 349, 353, 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, - 405, 409, 413, 417, 421, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, - 473, 477, 481, 485, 489, 493, 497, 501, 504, 506 - }; - std::vector col_indices = { - 1, 2, 0, 2, 3, 0, 1, 3, 4, 1, 2, 4, 5, 2, 3, 5, 6, 3, - 4, 6, 7, 4, 5, 7, 8, 5, 6, 8, 9, 6, 7, 9, 10, 7, 8, 10, - 11, 8, 9, 11, 12, 9, 10, 12, 13, 10, 11, 13, 14, 11, 12, 14, 15, 12, - 13, 15, 16, 13, 14, 16, 17, 14, 15, 17, 18, 15, 16, 18, 19, 16, 17, 19, - 20, 17, 18, 20, 21, 18, 19, 21, 22, 19, 20, 22, 23, 20, 21, 23, 24, 21, - 22, 24, 25, 22, 23, 25, 26, 23, 24, 26, 27, 24, 25, 27, 28, 25, 26, 28, - 29, 26, 27, 29, 30, 27, 28, 30, 31, 28, 29, 31, 32, 29, 30, 32, 33, 30, - 31, 33, 34, 31, 32, 34, 35, 32, 33, 35, 36, 33, 34, 36, 37, 34, 35, 37, - 38, 35, 36, 38, 39, 36, 37, 39, 40, 37, 38, 40, 41, 38, 39, 41, 42, 39, - 40, 42, 43, 40, 41, 43, 44, 41, 42, 44, 45, 42, 43, 45, 46, 43, 44, 46, - 47, 44, 45, 47, 48, 45, 46, 48, 49, 46, 47, 49, 50, 47, 48, 50, 51, 48, - 49, 51, 52, 49, 50, 52, 53, 50, 51, 53, 54, 51, 52, 54, 55, 52, 53, 55, - 56, 53, 54, 56, 57, 54, 55, 57, 58, 55, 56, 58, 59, 56, 57, 59, 60, 57, - 58, 60, 61, 58, 59, 61, 62, 59, 60, 62, 63, 60, 61, 63, 64, 61, 62, 64, - 65, 62, 63, 65, 66, 63, 64, 66, 67, 64, 65, 67, 68, 65, 66, 68, 69, 66, - 67, 69, 70, 67, 68, 70, 71, 68, 69, 71, 72, 69, 70, 72, 73, 70, 71, 73, - 74, 71, 72, 74, 75, 72, 73, 75, 76, 73, 74, 76, 77, 74, 75, 77, 78, 75, - 76, 78, 79, 76, 77, 79, 80, 77, 78, 80, 81, 78, 79, 81, 82, 79, 80, 82, - 83, 80, 81, 83, 84, 81, 82, 84, 85, 82, 83, 85, 86, 83, 84, 86, 87, 84, - 85, 87, 88, 85, 86, 88, 89, 86, 87, 89, 90, 87, 88, 90, 91, 88, 89, 91, - 92, 89, 90, 92, 93, 90, 91, 93, 94, 91, 92, 94, 95, 92, 93, 95, 96, 93, - 94, 96, 97, 94, 95, 97, 98, 95, 96, 98, 99, 96, 97, 99, 100, 97, 98, 100, - 101, 98, 99, 101, 102, 99, 100, 102, 103, 100, 101, 103, 104, 101, 102, 104, 105, 102, - 103, 105, 106, 103, 104, 106, 107, 104, 105, 107, 108, 105, 106, 108, 109, 106, 107, 109, - 110, 107, 108, 110, 111, 108, 109, 111, 112, 109, 110, 112, 113, 110, 111, 113, 114, 111, - 112, 114, 115, 112, 113, 115, 116, 113, 114, 116, 117, 114, 115, 117, 118, 115, 116, 118, - 119, 116, 117, 119, 120, 117, 118, 120, 121, 118, 119, 121, 122, 119, 120, 122, 123, 120, - 121, 123, 124, 121, 122, 124, 125, 122, 123, 125, 126, 123, 124, 126, 127, 124, 125, 127, - 125, 126 - }; - std::vector weights(col_indices.size(), 1); - - auto graph = pr::csr_graph(queue, row_ptr, col_indices, weights); - size_t num_nodes = row_ptr.size() - 1; + const std::uint32_t seed = GENERATE(42u, 313u, 2025u); + const double edge_probability = GENERATE(0.05, 0.1, 0.2); + const std::size_t num_nodes = GENERATE(128, 512, 1024); + + const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); + auto graph = pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); auto in_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); auto out_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); pr::ndarray distance = @@ -143,7 +104,7 @@ TEST("test BFS", "[bfs]") { } /// End BFS - auto expected_distances = host_bfs(row_ptr, col_indices, src); + auto expected_distances = host_bfs(graph_data.row_ptr, graph_data.col_indices, src); auto actual_distances = distance.to_host(queue).get_data(); for (size_t i = 0; i < num_nodes; ++i) { REQUIRE(actual_distances[i] == expected_distances[i]); From a9c67478f320c92ec22b60bb6421854b5f362e24 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 14:06:44 +0200 Subject: [PATCH 31/69] applied clang-format to the new files --- .../primitives/frontier/test/advance_dpc.cpp | 13 +++++++++---- .../backend/primitives/frontier/test/bfs_dpc.cpp | 6 ++++-- .../dal/backend/primitives/frontier/test/utils.hpp | 8 ++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 990799febda..7496d46b460 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -43,7 +43,8 @@ std::vector compute_next_frontier(const std::vector& row_pt std::vector next_frontier(frontier.size(), false); for (size_t node = 0; node < frontier.size(); ++node) { - if (!frontier[node]) continue; + if (!frontier[node]) + continue; auto start = row_ptr[node]; auto end = row_ptr[node + 1]; @@ -81,7 +82,8 @@ TEST("test advance operation", "[advance]") { const std::size_t num_nodes = GENERATE(128, 512, 1024); const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); - auto graph = pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); + auto graph = + pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); auto in_frontier = pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); auto out_frontier = @@ -99,7 +101,9 @@ TEST("test advance operation", "[advance]") { } if (in_frontier.empty()) { - std::uniform_int_distribution vertex_dist(0, static_cast(num_nodes - 1)); + std::uniform_int_distribution vertex_dist( + 0, + static_cast(num_nodes - 1)); const auto fallback_vertex = vertex_dist(frontier_rng); in_frontier.insert(fallback_vertex); host_frontier[fallback_vertex] = true; @@ -113,7 +117,8 @@ TEST("test advance operation", "[advance]") { }) .wait_and_throw(); - auto tmp_frontier = compute_next_frontier(graph_data.row_ptr, graph_data.col_indices, host_frontier); + auto tmp_frontier = + compute_next_frontier(graph_data.row_ptr, graph_data.col_indices, host_frontier); compare_frontiers(out_frontier, tmp_frontier, num_nodes); } // TEST "test advance operation" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index 7c0576ffc59..eee1db7671d 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -63,7 +63,8 @@ TEST("test BFS", "[bfs]") { const std::size_t num_nodes = GENERATE(128, 512, 1024); const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); - auto graph = pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); + auto graph = + pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); auto in_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); auto out_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); pr::ndarray distance = @@ -104,7 +105,8 @@ TEST("test BFS", "[bfs]") { } /// End BFS - auto expected_distances = host_bfs(graph_data.row_ptr, graph_data.col_indices, src); + auto expected_distances = + host_bfs(graph_data.row_ptr, graph_data.col_indices, src); auto actual_distances = distance.to_host(queue).get_data(); for (size_t i = 0; i < num_nodes; ++i) { REQUIRE(actual_distances[i] == expected_distances[i]); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp index dcecc208ffe..7ec59e59f1e 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp @@ -3,7 +3,6 @@ #include #include - void print_device_name(sycl::queue& queue) { const auto device = queue.get_device(); const auto device_name = device.get_info(); @@ -11,7 +10,7 @@ void print_device_name(sycl::queue& queue) { } namespace oneapi::dal::backend::primitives { - struct csr_graph_data { +struct csr_graph_data { std::vector row_ptr; std::vector col_indices; std::vector weights; @@ -26,8 +25,9 @@ csr_graph_data generate_random_graph(std::size_t vertex_count, std::mt19937 rng(seed); std::bernoulli_distribution edge_dist(edge_probability); - std::uniform_int_distribution vertex_dist(0, - static_cast(vertex_count - 1)); + std::uniform_int_distribution vertex_dist( + 0, + static_cast(vertex_count - 1)); std::vector row_ptr(vertex_count + 1, 0); std::vector col_indices; From 67edbaf53608b1933765d6a64ba1e2f41f174ff5 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Mon, 22 Sep 2025 15:15:57 +0200 Subject: [PATCH 32/69] add trailing new line to comply with format checker --- cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp index 7ec59e59f1e..2ca64ac5b61 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp @@ -59,4 +59,4 @@ csr_graph_data generate_random_graph(std::size_t vertex_count, return { std::move(row_ptr), std::move(col_indices), std::move(weights) }; } -} // namespace oneapi::dal::backend::primitives \ No newline at end of file +} // namespace oneapi::dal::backend::primitives From 4a169554dfedb3c66a5c4bf4a55f21a7eed18a9d Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 18:49:55 +0200 Subject: [PATCH 33/69] Update copyright notices --- .../dal/backend/primitives/frontier/advance.hpp | 1 - .../dal/backend/primitives/frontier/bitset.hpp | 1 - .../backend/primitives/frontier/frontier.hpp | 1 - .../primitives/frontier/frontier_dpc.cpp | 1 - .../dal/backend/primitives/frontier/graph.hpp | 1 - .../primitives/frontier/test/advance_dpc.cpp | 1 - .../primitives/frontier/test/bfs_dpc.cpp | 1 - .../primitives/frontier/test/frontier_dpc.cpp | 1 - .../backend/primitives/frontier/test/utils.hpp | 17 +++++++++++++++++ 9 files changed, 17 insertions(+), 8 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index f7b42e6bc6a..9a7e1cf18de 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index 5f944c01dc5..f14fa7a2887 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 21864ad3d98..88bbbfd5931 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 9b9b7e9118d..ab1bfb9f301 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 39dd86a4d06..721c0c3d61a 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 7496d46b460..fffe7d34ab0 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index eee1db7671d..6508a3bd182 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index bb128870ae8..843d099d84f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -1,5 +1,4 @@ /******************************************************************************* -* Copyright 2025 Intel Corporation * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno * diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp index 2ca64ac5b61..3fa3b83afe7 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp @@ -1,3 +1,20 @@ +/******************************************************************************* +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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 From 44d96789cd31d0a903044f157c299e2f6b4ab085 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 18:50:29 +0200 Subject: [PATCH 34/69] update copyright notice and license information in frontier.hpp --- cpp/oneapi/dal/backend/primitives/frontier.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cpp/oneapi/dal/backend/primitives/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier.hpp index 69fe3aab466..52adfcd2496 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier.hpp @@ -1,3 +1,20 @@ +/******************************************************************************* +* Copyright contributors to the oneDAL project +* Copyright 2025 University of Salerno +* +* 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/backend/primitives/frontier/frontier.hpp" #include "oneapi/dal/backend/primitives/frontier/advance.hpp" #include "oneapi/dal/backend/primitives/frontier/graph.hpp" From 7bbaac7a30e5227fef8c70ceff9b5c5cfa0fa49c Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:11:39 +0200 Subject: [PATCH 35/69] =?UTF-8?q?frontier:=20refactor=20advance.hpp=20?= =?UTF-8?q?=E2=80=94=20use=20fixed-width=20integers=20and=20simplify=20fro?= =?UTF-8?q?ntier=5Fcontext=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/primitives/frontier/advance.hpp | 74 ++++++++++--------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 9a7e1cf18de..71d8c9e062d 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -27,9 +27,9 @@ namespace oneapi::dal::backend::primitives { /// It includes the group offset, coarsening factor, offsets size, and the SYCL /// nd_item for the current work item. struct frontier_context_state { - size_t group_offset; - const uint16_t coarsening_factor; - const uint32_t offsets_size; + std::uint64_t group_offset; // Offset of the current group being processed + const uint16_t coarsening_factor; // Number of integers a single work-group should handle + const uint32_t offsets_size; // Size of the offsets buffer array const sycl::nd_item<1> item; }; @@ -39,10 +39,12 @@ struct frontier_context_state { /// the context state, check if there are more elements to process, get the /// assigned element, check if a vertex is in the frontier, and insert a vertex /// into the output frontier. +/// \tparam InFrontierDevT input frontier device view type. Inferred from the input frontier. +/// \tparam OutFrontierDevT output frontier device view type. Inferred from the output frontier. template class frontier_context { public: - frontier_context(size_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) + frontier_context(std::uint64_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) : limit(limit), in_dev_frontier(in_dev_frontier), out_dev_frontier(out_dev_frontier) {} @@ -56,39 +58,39 @@ class frontier_context { }; } - /// This method checks if there are more elements to process in the current group. + /// checks if there are more elements to process in the current group. inline bool need_to_process(frontier_context_state& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } - /// This method completes the current iteration by updating the group offset. + /// completes the current iteration by updating the group offset. inline void complete_iteration(frontier_context_state& state) const { state.group_offset += state.item.get_group_range(0); } - /// This method retrieves the assigned element for the current work item. + /// retrieves the assigned element for the current work item. inline size_t get_assigned_element(const frontier_context_state& state) const { const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); - const uint32_t acutal_id_offset = (state.group_offset * state.coarsening_factor) + + const uint32_t actual_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / element_bitsize); + ONEDAL_ASSERT(actual_id_offset < in_dev_frontier.get_offsets_size()[0]); const uint32_t* bitmap_offsets = in_dev_frontier.get_offsets(); - ONEDAL_ASSERT(acutal_id_offset < in_dev_frontier.get_offsets_size()[0]); - const auto assigned_vertex = (bitmap_offsets[acutal_id_offset] * element_bitsize) + + const auto assigned_vertex = (bitmap_offsets[actual_id_offset] * element_bitsize) + (state.item.get_local_linear_id() % element_bitsize); return assigned_vertex; } - /// This method checks if a vertex is in the input frontier. - inline bool check(const frontier_context_state& state, size_t vertex) const { + /// checks if a vertex is in the input frontier. + inline bool check(std::uint64_t vertex) const { return vertex < limit && in_dev_frontier.check(vertex); } - /// This method inserts a vertex into the output frontier. - inline void insert(const frontier_context_state& state, size_t vertex) const { + /// inserts a vertex into the output frontier. + inline void insert(std::uint64_t vertex) const { out_dev_frontier.insert(vertex); } - size_t limit; + std::uint64_t limit; InFrontierDevT in_dev_frontier; OutFrontierDevT out_dev_frontier; }; @@ -100,12 +102,12 @@ struct BitmapKernel { /// This function distributes the workload among the workgroup, subgroup, and individual work items template inline void distribute_workload(frontier_context_state& state, const VertexT& vertex) const { - const size_t lid = state.item.get_local_linear_id(); + const std::uint64_t lid = state.item.get_local_linear_id(); const auto wgroup = state.item.get_group(); - const size_t wgroup_size = wgroup.get_local_range(0); + const std::uint64_t wgroup_size = wgroup.get_local_range(0); const auto sgroup = state.item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); - const size_t sgroup_size = sgroup.get_local_range()[0]; + const std::uint64_t sgroup_size = sgroup.get_local_range()[0]; if (sgroup.leader()) { subgroup_reduce_tail[sgroup_id] = 0; @@ -120,7 +122,7 @@ struct BitmapKernel { wg_tail{ workgroup_reduce_tail[0] }; const uint32_t offset = sgroup_id * sgroup_size; - if (context.check(state, vertex)) { + if (context.check(vertex)) { uint32_t n_edges = graph_dev.get_degree(vertex); // if the number of edges is large enough, we can assign the vertex to the workgroup if (n_edges >= wgroup_size * wgroup_size) { @@ -149,12 +151,12 @@ struct BitmapKernel { wg_tail{ workgroup_reduce_tail[0] }; const auto wgroup = state.item.get_group(); - const size_t lid = state.item.get_local_linear_id(); - const size_t wgroup_size = wgroup.get_local_range(0); + const std::uint64_t lid = state.item.get_local_linear_id(); + const std::uint64_t wgroup_size = wgroup.get_local_range(0); - for (size_t i = 0; i < wg_tail.load(); i++) { + for (std::uint64_t i = 0; i < wg_tail.load(); i++) { auto vertex = workgroup_reduce[i]; - size_t n_edges = n_edges_wg[i]; + std::uint64_t n_edges = n_edges_wg[i]; auto start = graph_dev.begin(vertex); for (auto j = lid; j < n_edges; j += wgroup_size) { @@ -163,7 +165,7 @@ struct BitmapKernel { auto weight = graph_dev.get_weight(edge); auto neighbor = *n; if (functor(vertex, neighbor, edge, weight)) { - context.insert(state, neighbor); + context.insert(neighbor); } } @@ -177,18 +179,18 @@ struct BitmapKernel { inline void process_subgroup_reduction(frontier_context_state& state) const { const auto sgroup = state.item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); - const size_t sgroup_size = sgroup.get_local_range()[0]; - const size_t llid = sgroup.get_local_linear_id(); + const std::uint64_t sgroup_size = sgroup.get_local_range()[0]; + const std::uint64_t llid = sgroup.get_local_linear_id(); const uint32_t offset = sgroup_id * sgroup_size; sycl::atomic_ref sg_tail{ subgroup_reduce_tail[sgroup_id] }; - for (size_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { + for (std::uint64_t i = 0; i < subgroup_reduce_tail[sgroup_id]; i++) { // active_elements_tail[subgroup_id] is always less or equal than subgroup_size - size_t vertex_id = offset + i; + std::uint64_t vertex_id = offset + i; auto vertex = subgroup_reduce[vertex_id]; - size_t n_edges = n_edges_sg[vertex_id]; + std::uint64_t n_edges = n_edges_sg[vertex_id]; auto start = graph_dev.begin(vertex); @@ -198,7 +200,7 @@ struct BitmapKernel { auto weight = graph_dev.get_weight(edge); auto neighbor = *n; if (functor(vertex, neighbor, edge, weight)) { - context.insert(state, neighbor); + context.insert(neighbor); } } @@ -212,7 +214,7 @@ struct BitmapKernel { template inline void process_workitem_reduction(frontier_context_state& state, const VertexT& vertex) const { - const size_t lid = state.item.get_local_linear_id(); + const std::uint64_t lid = state.item.get_local_linear_id(); if (!visited[lid]) { auto start = graph_dev.begin(vertex); @@ -223,7 +225,7 @@ struct BitmapKernel { auto weight = graph_dev.get_weight(edge); auto neighbor = *n; if (functor(vertex, neighbor, edge, weight)) { - context.insert(state, neighbor); + context.insert(neighbor); } } } @@ -284,18 +286,18 @@ sycl::event advance(const GraphT& graph, sycl::queue& q = graph.get_queue(); - size_t num_nodes = graph.get_vertex_count(); + std::uint64_t num_nodes = graph.get_vertex_count(); auto in_dev_frontier = in.get_device_view(); auto out_dev_frontier = out.get_device_view(); auto graph_dev = graph.get_device_view(); /// The coarsening factor represents the number of integers a single work-group should handle. - size_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups; + std::uint64_t coarsening_factor = 1; // it should be Compute Unit Size / num subgroups; - size_t element_bitsize = in_dev_frontier.get_element_bitsize(); // in bits + std::uint64_t element_bitsize = in_dev_frontier.get_element_bitsize(); // in bits sycl::range<1> local_range = { element_bitsize * coarsening_factor }; - size_t global_size; + std::uint64_t global_size; sycl::event to_wait = in.compute_active_frontier(); // kernel launch to compute active bitmap regions From 13673837f54ab4ebcd7b02bdaee43ba7b4eda41b Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:11:39 +0200 Subject: [PATCH 36/69] frontier: use std::uint64_t for sizes in bitset, frontier and frontier_dpc.cpp --- .../backend/primitives/frontier/bitset.hpp | 4 +-- .../backend/primitives/frontier/frontier.hpp | 26 +++++++++---------- .../primitives/frontier/frontier_dpc.cpp | 16 ++++++------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index f14fa7a2887..b55a64a8515 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -28,7 +28,7 @@ template class bitset { public: using element_t = ElementType; - static constexpr size_t element_bitsize = sizeof(element_t) * 8; // Number of bits in an element + static constexpr std::uint64_t element_bitsize = sizeof(element_t) * 8; // Number of bits in an element bitset(element_t* data) : _data(data) {} @@ -98,7 +98,7 @@ class bitset { } /// override operator [] - inline element_t& operator[](std::size_t index) { + inline element_t& operator[](std::uint64_t index) { return _data[index]; } diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 88bbbfd5931..4468371a09f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -29,14 +29,14 @@ template class frontier_view { public: using bitmap_t = ElementType; - static constexpr std::size_t divide_factor = bitset::element_bitsize; + static constexpr std::uint64_t divide_factor = bitset::element_bitsize; frontier_view() = default; - frontier_view(bitmap_t* data_layer, - bitmap_t* mlb_layer, - std::uint32_t* offsets, - std::uint32_t* offsets_size, - size_t num_items) + frontier_view(bitmap_t* data_layer, // First layer (tracks vertices in the frontier) + bitmap_t* mlb_layer, // Second layer (to track non-zero elements in the first layer) + std::uint32_t* offsets, // Array to store the indices of the non-zero elements + std::uint32_t* offsets_size, // Pointer to store the size of the offsets array + std::uint64_t num_items) // Maximum number of items that can be stored in the frontier : _num_items(num_items), _data_layer(bitset{ data_layer }), _mlb_layer(bitset{ mlb_layer }), @@ -60,7 +60,7 @@ class frontier_view { return _data_layer.atomic_test(idx); } - inline size_t get_element_bitsize() const { + inline std::uint64_t get_element_bitsize() const { return bitset::element_bitsize; } @@ -73,7 +73,7 @@ class frontier_view { } private: - size_t _num_items; + std::uint64_t _num_items; bitset _data_layer; bitset _mlb_layer; @@ -89,7 +89,7 @@ class frontier { public: frontier(sycl::queue& queue, - std::size_t num_items, + std::uint64_t num_items, sycl::usm::alloc alloc = sycl::usm::alloc::shared); const frontier_view get_device_view() const { @@ -100,7 +100,7 @@ class frontier { _mlb_layer.get_mutable_data(), offsets_pointer, offsets_size_pointer, - static_cast(_data_layer.get_count()) }; + static_cast(_data_layer.get_count()) }; } inline ndview get_data() const { @@ -144,14 +144,14 @@ class frontier { private: sycl::queue& _queue; - size_t _num_items; + std::uint64_t _num_items; ndarray _data_layer; ndarray _mlb_layer; ndarray _offsets; ndarray _buffer; - const size_t _TMP_VAR = 0; - const size_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) + const std::uint64_t _TMP_VAR = 0; + const std::uint64_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) }; template diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index ab1bfb9f301..0cae68f326e 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -22,7 +22,7 @@ namespace oneapi::dal::backend::primitives { #ifdef ONEDAL_DATA_PARALLEL template -frontier::frontier(sycl::queue& queue, std::size_t num_items, sycl::usm::alloc alloc) +frontier::frontier(sycl::queue& queue, std::uint64_t num_items, sycl::usm::alloc alloc) : _queue(queue), _num_items(num_items) { std::int64_t array_size = (num_items + bitset::element_bitsize - 1) / @@ -105,9 +105,9 @@ inline sycl::event frontier::compute_active_frontier() { auto offsets_pointer = _offsets.get_mutable_data() + 1; const uint32_t element_bitsize = bitmap.get_element_bitsize(); - const size_t local_range = 256; // propose_wg_size(this->_queue); - const size_t mlb_count = _mlb_layer.get_count(); - const size_t global_range = (mlb_count % local_range == 0) + const std::uint64_t local_range = 256; // propose_wg_size(this->_queue); + const std::uint64_t mlb_count = _mlb_layer.get_count(); + const std::uint64_t global_range = (mlb_count % local_range == 0) ? mlb_count : (mlb_count + local_range - (mlb_count % local_range)); @@ -145,7 +145,7 @@ inline sycl::event frontier::compute_active_frontier() { offsets_size_ref{ offsets_size[0] }; ElementType data = data_layer[idx]; - for (size_t i = 0; i < element_bitsize; i++) { + for (std::uint64_t i = 0; i < element_bitsize; i++) { if (data & (static_cast(1) << i)) { offsets[offsets_size_ref++] = i + idx * element_bitsize; } @@ -185,7 +185,7 @@ inline sycl::event frontier::compute_active_frontier() { for (uint32_t gid = item.get_global_linear_id(); gid < size; gid += item.get_global_range(0)) { ElementType data = data_layer[gid]; - for (size_t i = 0; i < element_bitsize; i++) { + for (std::uint64_t i = 0; i < element_bitsize; i++) { if (data & (static_cast(1) << i)) { local_offsets[local_size_ref++] = i + gid * element_bitsize; } @@ -194,12 +194,12 @@ inline sycl::event frontier::compute_active_frontier() { sycl::group_barrier(group); - size_t data_offset = 0; + std::uint64_t data_offset = 0; if (group.leader()) { data_offset = offsets_size_ref.fetch_add(local_size_ref.load()); } data_offset = sycl::group_broadcast(group, data_offset, 0); - for (size_t i = item.get_local_linear_id(); i < local_size_ref.load(); + for (std::uint64_t i = item.get_local_linear_id(); i < local_size_ref.load(); i += item.get_local_range(0)) { offsets[data_offset + i] = local_offsets[i]; } From 7b39e37d17a6a053f4db4722e0ed84d0f303b128 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:11:39 +0200 Subject: [PATCH 37/69] graph: use std::uint64_t for number of nodes in csr_graph_view --- cpp/oneapi/dal/backend/primitives/frontier/graph.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 721c0c3d61a..78208029312 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -70,7 +70,7 @@ class csr_graph_view { }; public: - csr_graph_view(std::size_t num_nodes, vertex_t* row_ptr, edge_t* col_indices, weight_t* weights) + csr_graph_view(std::uint64_t num_nodes, vertex_t* row_ptr, edge_t* col_indices, weight_t* weights) : _num_nodes(num_nodes), _row_ptr(row_ptr), _col_indices(col_indices), @@ -100,7 +100,7 @@ class csr_graph_view { } private: - std::size_t _num_nodes; + std::uint64_t _num_nodes; vertex_t* _row_ptr; edge_t* _col_indices; weight_t* _weights; @@ -162,13 +162,13 @@ class csr_graph { return _queue; } - std::size_t get_vertex_count() const { + std::uint64_t get_vertex_count() const { return _num_nodes; } private: sycl::queue& _queue; - std::size_t _num_nodes; + std::uint64_t _num_nodes; ndarray _row_ptr; ndarray _col_indices; ndarray _weights; From 12c499768998f069f81392a4a50580643d113edf Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:11:39 +0200 Subject: [PATCH 38/69] tests: adapt frontier and BFS tests to use std::uint64_t for counts and loops --- .../primitives/frontier/test/advance_dpc.cpp | 20 +++++++++---------- .../primitives/frontier/test/bfs_dpc.cpp | 8 ++++---- .../primitives/frontier/test/frontier_dpc.cpp | 10 +++++----- .../primitives/frontier/test/utils.hpp | 6 +++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index fffe7d34ab0..89681e8c6c2 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -27,10 +27,10 @@ namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; template -void print_frontier(const T* data, size_t count, size_t num_items) { - size_t element_bitsize = sizeof(T) * 8; - for (size_t i = 0; i < count; ++i) { - for (size_t j = 0; j < element_bitsize; ++j) { +void print_frontier(const T* data, std::uint64_t count, std::uint64_t num_items) { + std::uint64_t element_bitsize = sizeof(T) * 8; + for (std::uint64_t i = 0; i < count; ++i) { + for (std::uint64_t j = 0; j < element_bitsize; ++j) { std::cout << ((data[i] & (static_cast(1) << j)) ? "1" : "0"); } } @@ -41,14 +41,14 @@ std::vector compute_next_frontier(const std::vector& row_pt const std::vector& frontier) { std::vector next_frontier(frontier.size(), false); - for (size_t node = 0; node < frontier.size(); ++node) { + for (std::uint64_t node = 0; node < frontier.size(); ++node) { if (!frontier[node]) continue; auto start = row_ptr[node]; auto end = row_ptr[node + 1]; - for (size_t i = start; i < end; ++i) { + for (std::uint64_t i = start; i < end; ++i) { auto neighbor = col_indices[i]; next_frontier[neighbor] = true; } @@ -59,8 +59,8 @@ std::vector compute_next_frontier(const std::vector& row_pt template void compare_frontiers(T& device_frontier, const std::vector& host_frontier, - size_t num_nodes) { - for (size_t i = 0; i < num_nodes; ++i) { + std::uint64_t num_nodes) { + for (std::uint64_t i = 0; i < num_nodes; ++i) { bool tmpd = device_frontier.check(i); bool tmph = host_frontier[i]; if (tmpd != tmph) { @@ -78,7 +78,7 @@ TEST("test advance operation", "[advance]") { const std::uint32_t seed = GENERATE(42u, 313u, 2025u); const double edge_probability = GENERATE(0.05, 0.1, 0.2); - const std::size_t num_nodes = GENERATE(128, 512, 1024); + const std::uint64_t num_nodes = GENERATE(128, 512, 1024); const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); auto graph = @@ -92,7 +92,7 @@ TEST("test advance operation", "[advance]") { std::mt19937 frontier_rng(seed ^ 0x9e3779b9u); std::bernoulli_distribution frontier_dist(0.1); - for (std::size_t vertex = 0; vertex < num_nodes; ++vertex) { + for (std::uint64_t vertex = 0; vertex < num_nodes; ++vertex) { if (frontier_dist(frontier_rng)) { in_frontier.insert(static_cast(vertex)); host_frontier[vertex] = true; diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index 6508a3bd182..49ca07095ad 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -41,7 +41,7 @@ std::vector host_bfs(const std::vector& row_offsets, T node = q.front(); q.pop(); - for (size_t i = row_offsets[node]; i < row_offsets[node + 1]; ++i) { + for (std::uint64_t i = row_offsets[node]; i < row_offsets[node + 1]; ++i) { auto neighbor = col_indices[i]; if (distances[neighbor] == std::numeric_limits::max()) { distances[neighbor] = distances[node] + 1; @@ -59,7 +59,7 @@ TEST("test BFS", "[bfs]") { const std::uint32_t seed = GENERATE(42u, 313u, 2025u); const double edge_probability = GENERATE(0.05, 0.1, 0.2); - const std::size_t num_nodes = GENERATE(128, 512, 1024); + const std::uint64_t num_nodes = GENERATE(128, 512, 1024); const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); auto graph = @@ -83,7 +83,7 @@ TEST("test BFS", "[bfs]") { .wait_and_throw(); in_frontier.insert(src); - size_t iter = 0; + std::uint64_t iter = 0; /// Start BFS while (!in_frontier.empty()) { @@ -107,7 +107,7 @@ TEST("test BFS", "[bfs]") { auto expected_distances = host_bfs(graph_data.row_ptr, graph_data.col_indices, src); auto actual_distances = distance.to_host(queue).get_data(); - for (size_t i = 0; i < num_nodes; ++i) { + for (std::uint64_t i = 0; i < num_nodes; ++i) { REQUIRE(actual_distances[i] == expected_distances[i]); } } // TEST "test advance operation" diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index 843d099d84f..3abce2a0b09 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -24,10 +24,10 @@ namespace oneapi::dal::backend::primitives::test { namespace pr = dal::backend::primitives; template -void print_frontier(const T* data, size_t count, size_t num_items) { - size_t element_bitsize = sizeof(T) * 8; - for (size_t i = 0; i < count; ++i) { - for (size_t j = 0; j < element_bitsize; ++j) { +void print_frontier(const T* data, std::uint64_t count, std::uint64_t num_items) { + std::uint64_t element_bitsize = sizeof(T) * 8; + for (std::uint64_t i = 0; i < count; ++i) { + for (std::uint64_t j = 0; j < element_bitsize; ++j) { std::cout << ((data[i] & (static_cast(1) << j)) ? "1" : "0"); } } @@ -38,7 +38,7 @@ TEST("frontier queue basic operations", "[frontier]") { auto& queue = policy.get_queue(); print_device_name(queue); - const std::size_t num_items = 100; + const std::uint64_t num_items = 100; auto f = pr::frontier(queue, num_items, sycl::usm::alloc::shared); REQUIRE(f.empty() == true); diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp index 3fa3b83afe7..1d822aec69b 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp @@ -33,7 +33,7 @@ struct csr_graph_data { std::vector weights; }; -csr_graph_data generate_random_graph(std::size_t vertex_count, +csr_graph_data generate_random_graph(std::uint64_t vertex_count, double edge_probability, std::uint32_t seed) { if (vertex_count == 0) { @@ -50,9 +50,9 @@ csr_graph_data generate_random_graph(std::size_t vertex_count, std::vector col_indices; col_indices.reserve(vertex_count); - for (std::size_t src = 0; src < vertex_count; ++src) { + for (std::uint64_t src = 0; src < vertex_count; ++src) { const auto edges_before = col_indices.size(); - for (std::size_t dst = 0; dst < vertex_count; ++dst) { + for (std::uint64_t dst = 0; dst < vertex_count; ++dst) { if (src == dst) { continue; } From a85aa7ebe2f0a114974a8aa4a6c62bd9f2b01e59 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:29:23 +0200 Subject: [PATCH 39/69] frontier: add element count to bitset constructor and store size --- cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index b55a64a8515..72d888c5642 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -30,7 +30,7 @@ class bitset { using element_t = ElementType; static constexpr std::uint64_t element_bitsize = sizeof(element_t) * 8; // Number of bits in an element - bitset(element_t* data) : _data(data) {} + bitset(element_t* data, const size_t num_items) : _data(data), _num_items(num_items) {} /// Sets the bit at the specified index to 1. inline void set(std::uint32_t index) const { @@ -104,6 +104,7 @@ class bitset { private: element_t* _data; + std::uint64_t _num_items; }; } // namespace oneapi::dal::backend::primitives From 838e25a9e34584e9f9bc659ad2aac7c3ce6cc62f Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:29:23 +0200 Subject: [PATCH 40/69] frontier: propagate sizes and add docs and swap helper --- cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 4468371a09f..b9f966c4972 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -25,6 +25,7 @@ namespace oneapi::dal::backend::primitives { /// @brief A view of a frontier that provides an interface for the kernel to interact with the frontier data structure. +/// \tparam ElementType the type of the elements in the frontier (e.g., std::uint32_t). template class frontier_view { public: @@ -38,8 +39,8 @@ class frontier_view { std::uint32_t* offsets_size, // Pointer to store the size of the offsets array std::uint64_t num_items) // Maximum number of items that can be stored in the frontier : _num_items(num_items), - _data_layer(bitset{ data_layer }), - _mlb_layer(bitset{ mlb_layer }), + _data_layer(bitset{ data_layer, num_items }), // first layer size is num_items + _mlb_layer(bitset{ mlb_layer, num_items / divide_factor }), // second layer size is (num_items / divide_factor) because each bit in the second layer represents an element in the first layer _offsets(offsets), _offsets_size(offsets_size) {} @@ -83,6 +84,7 @@ class frontier_view { }; /// @brief The Two-Layer bitmap frontier class +/// \tparam ElementType the type that describes the bitmap integers type (e.g., std::uint32_t). template class frontier { using buffer_t = std::uint32_t; @@ -154,6 +156,8 @@ class frontier { const std::uint64_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) }; +/// Swaps the contents of two frontiers. +/// \tparam ElementType the type that describes the bitmap integers type (e.g., std::uint32_t). Inferred from the frontier. template void swap_frontiers(frontier& f1, frontier& f2) { frontier::swap(f1, f2); From 5a7ee624d5620f7ad07e6cb09d87bbb5bb7fe112 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:29:23 +0200 Subject: [PATCH 41/69] frontier: remove unnecessary bitset include from graph header --- cpp/oneapi/dal/backend/primitives/frontier/graph.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 78208029312..43e1e5b839c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -20,7 +20,6 @@ #include "oneapi/dal/common.hpp" #include "oneapi/dal/graph/detail/common.hpp" #include "oneapi/dal/graph/detail/container.hpp" -#include "oneapi/dal/backend/primitives/frontier/bitset.hpp" #include "oneapi/dal/backend/primitives/ndarray.hpp" namespace oneapi::dal::backend::primitives { From 5088c49161efc976ca56c0d00fc6074c4b51590f Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:29:23 +0200 Subject: [PATCH 42/69] frontier/advance: rename kernel, tighten types, and polish docs/formatting --- .../backend/primitives/frontier/advance.hpp | 95 +++++++------------ 1 file changed, 34 insertions(+), 61 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 71d8c9e062d..acc6b852d42 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -58,18 +58,18 @@ class frontier_context { }; } - /// checks if there are more elements to process in the current group. + /// Checks if there are more elements to process in the current group. inline bool need_to_process(frontier_context_state& state) const { return (state.group_offset * state.coarsening_factor < state.offsets_size); } - /// completes the current iteration by updating the group offset. + /// Completes the current iteration by updating the group offset. inline void complete_iteration(frontier_context_state& state) const { state.group_offset += state.item.get_group_range(0); } - /// retrieves the assigned element for the current work item. - inline size_t get_assigned_element(const frontier_context_state& state) const { + /// Retrieves the assigned element for the current work item. + inline std::uint64_t get_assigned_element(const frontier_context_state& state) const { const uint16_t element_bitsize = in_dev_frontier.get_element_bitsize(); const uint32_t actual_id_offset = (state.group_offset * state.coarsening_factor) + (state.item.get_local_linear_id() / element_bitsize); @@ -80,12 +80,12 @@ class frontier_context { return assigned_vertex; } - /// checks if a vertex is in the input frontier. + /// Checks if a vertex is in the input frontier. inline bool check(std::uint64_t vertex) const { return vertex < limit && in_dev_frontier.check(vertex); } - /// inserts a vertex into the output frontier. + /// Inserts a vertex into the output frontier. inline void insert(std::uint64_t vertex) const { out_dev_frontier.insert(vertex); } @@ -95,11 +95,15 @@ class frontier_context { OutFrontierDevT out_dev_frontier; }; -/// BitmapKernel is a template struct that defines the kernel to be executed on the device. +/// bitmap_kernel is a template struct that defines the kernel to be executed on the device. /// It processes the input frontier and advances it based on the provided functor. +/// \tparam T the type of the elements in the frontier (e.g., std::uint32_t). +/// \tparam ContextT the type of the frontier context. Inferred from the frontier_context. +/// \tparam GraphDevT the type of the graph device view. Inferred from the graph. +/// \tparam LambdaT the type of the functor to be applied to each edge. template -struct BitmapKernel { - /// This function distributes the workload among the workgroup, subgroup, and individual work items +struct bitmap_kernel { + /// Distributes the workload among the workgroup, subgroup, and individual work items template inline void distribute_workload(frontier_context_state& state, const VertexT& vertex) const { const std::uint64_t lid = state.item.get_local_linear_id(); @@ -144,9 +148,8 @@ struct BitmapKernel { } } - /// This function processes the vertices assigned to the workgroup. + /// Processes the vertices assigned to the workgroup. inline void process_workgroup_reduction(frontier_context_state& state) const { - /// This function processes the vertices assigned to the workgroup. sycl::atomic_ref wg_tail{ workgroup_reduce_tail[0] }; @@ -175,7 +178,7 @@ struct BitmapKernel { } } - /// This function processes the vertices assigned to the subgroup. + /// Processes the vertices assigned to the subgroup. inline void process_subgroup_reduction(frontier_context_state& state) const { const auto sgroup = state.item.get_sub_group(); const auto sgroup_id = sgroup.get_group_id(); @@ -210,7 +213,8 @@ struct BitmapKernel { } } - /// This function processes the vertices that were not assigned to the workgroup or subgroup. + /// Processes the vertices that were not assigned to the workgroup or subgroup. + /// \tparam VertexT the type of the vertex. Inferred from the graph. template inline void process_workitem_reduction(frontier_context_state& state, const VertexT& vertex) const { @@ -231,6 +235,7 @@ struct BitmapKernel { } } + /// The main operator that executes the kernel logic. void operator()(sycl::nd_item<1> item) const { auto state = context.init(item); const auto wgroup = item.get_group(); @@ -272,11 +277,12 @@ struct BitmapKernel { const LambdaT functor; }; -/// advance is a function that launches the BitmapKernel on the device to advance the frontier. +/// Advance is a function that launches the bitmap_kernel on the device to advance the frontier. /// It takes the graph, input frontier, output frontier, and the functor. -/// The expected_size parameter is used to specify the expected size of the input frontier, in order -/// to optimize the kernel launch parameters. If expected_size is zero, a default size is used. /// It returns a sycl::event that can be used to synchronize the execution. +/// \tparam FrontierSizeT the type of the elements in the frontier (e.g., std::uint32_t). +/// \tparam GraphT the type of the graph. Inferred from the csr_graph. +/// \tparam LambdaT the type of the functor to be applied to each edge. template sycl::event advance(const GraphT& graph, frontier& in, @@ -315,56 +321,23 @@ sycl::event advance(const GraphT& graph, out_dev_frontier }; using bitmap_kernel_t = - BitmapKernel; + bitmap_kernel; const uint32_t max_num_subgroups = device_max_sg_count(q); auto e = q.submit([&](sycl::handler& cgh) { cgh.depends_on(to_wait); - sycl::local_accessor n_edges_wg{ - local_range, - cgh - }; // number of edges of vertices to process at work-group granularity - sycl::local_accessor n_edges_sg{ - local_range, - cgh - }; // number of edges of vertices to process at sub-group granularity - sycl::local_accessor visited{ - local_range, - cgh - }; // tracks the vertices already visited at work-group and sub-group granularity - sycl::local_accessor subgroup_reduce{ - local_range, - cgh - }; // stores the vertices to process at sub-group granularity - sycl::local_accessor subgroup_reduce_tail{ - max_num_subgroups, - cgh - }; // stores the tail of the subgroup reduction - sycl::local_accessor subgroup_ids{ - local_range, - cgh - }; // stores the thread id that found the vertex to process at sub-group level - sycl::local_accessor workgroup_reduce{ - local_range, - cgh - }; // stores the vertices to process at work-group granularity - sycl::local_accessor workgroup_reduce_tail{ - 1, - cgh - }; // stores the tail of the work-group reduction - sycl::local_accessor workgroup_ids{ - local_range, - cgh - }; // stores the thread id that found the vertex to process at work-group level - sycl::local_accessor individual_reduce{ - local_range, - cgh - }; // stores the vertices to process at individual thread granularity - sycl::local_accessor individual_reduce_tail{ - 1, - cgh - }; // stores the tail of the individual thread reduction + sycl::local_accessor n_edges_wg{local_range, cgh}; // number of edges of vertices to process at work-group granularity + sycl::local_accessor n_edges_sg{local_range, cgh}; // number of edges of vertices to process at sub-group granularity + sycl::local_accessor visited{local_range, cgh}; // tracks the vertices already visited at work-group and sub-group granularity + sycl::local_accessor subgroup_reduce{local_range, cgh}; // stores the vertices to process at sub-group granularity + sycl::local_accessor subgroup_reduce_tail{max_num_subgroups, cgh}; // stores the tail of the subgroup reduction + sycl::local_accessor subgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at sub-group level + sycl::local_accessor workgroup_reduce{local_range, cgh}; // stores the vertices to process at work-group granularity + sycl::local_accessor workgroup_reduce_tail{1, cgh}; // stores the tail of the work-group reduction + sycl::local_accessor workgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at work-group level + sycl::local_accessor individual_reduce{local_range, cgh}; // stores the vertices to process at individual thread granularity + sycl::local_accessor individual_reduce_tail{1, cgh}; // stores the tail of the individual thread reduction cgh.parallel_for(sycl::nd_range<1>{ global_range, local_range }, bitmap_kernel_t{ context, From daf56a1f865304b07f610115a076bb85a8301337 Mon Sep 17 00:00:00 2001 From: Antonio De Caro Date: Wed, 15 Oct 2025 19:39:22 +0200 Subject: [PATCH 43/69] refactor: improve bitset layer size calculation for frontier initialization --- .../dal/backend/primitives/frontier/bitset.hpp | 17 +++++++++++++---- .../backend/primitives/frontier/frontier.hpp | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index 72d888c5642..6f54bcad949 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -21,21 +21,24 @@ namespace oneapi::dal::backend::primitives { -/** - * @brief A bitset class that provides a set of operations on a bitset. - */ +/// A bitset class that provides a set of operations on a bitset implemented using an array of integers. +/// \tparam ElementType the type of the elements in the bitset (e.g., std::uint32_t). template class bitset { public: using element_t = ElementType; static constexpr std::uint64_t element_bitsize = sizeof(element_t) * 8; // Number of bits in an element - bitset(element_t* data, const size_t num_items) : _data(data), _num_items(num_items) {} + /// Constructs a bitset with the given data pointer and number of items. + /// \param data pointer to the underlying data. + /// \param num_items number of items in the bitset. + bitset(element_t* data, const size_t num_items) : _data(data), _num_items((num_items + element_bitsize - 1) / element_bitsize) {} /// Sets the bit at the specified index to 1. inline void set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; + ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); _data[element_index] |= (element_t(1) << bit_index); } @@ -43,6 +46,7 @@ class bitset { inline void unset(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; + ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); _data[element_index] &= ~(element_t(1) << bit_index); } @@ -50,6 +54,7 @@ class bitset { inline bool test(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; + ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); return (_data[element_index] & (element_t(1) << bit_index)) != 0; } @@ -59,6 +64,7 @@ class bitset { inline void atomic_set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; + ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); sycl::atomic_ref atomic_element(_data[element_index]); atomic_element |= (element_t(1) << bit_index); } @@ -69,6 +75,7 @@ class bitset { inline void atomic_unset(std::uint32_t index) { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; + ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); sycl::atomic_ref atomic_element(_data[element_index]); atomic_element &= ~(element_t(1) << bit_index); } @@ -79,6 +86,7 @@ class bitset { inline bool atomic_test(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; + ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); sycl::atomic_ref atomic_element(_data[element_index]); return (atomic_element.load() & (element_t(1) << bit_index)) != 0; } @@ -99,6 +107,7 @@ class bitset { /// override operator [] inline element_t& operator[](std::uint64_t index) { + ONEDAL_ASSERT(index < _num_items, "Index out of bounds"); return _data[index]; } diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index b9f966c4972..47b6235d969 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -40,7 +40,7 @@ class frontier_view { std::uint64_t num_items) // Maximum number of items that can be stored in the frontier : _num_items(num_items), _data_layer(bitset{ data_layer, num_items }), // first layer size is num_items - _mlb_layer(bitset{ mlb_layer, num_items / divide_factor }), // second layer size is (num_items / divide_factor) because each bit in the second layer represents an element in the first layer + _mlb_layer(bitset{ mlb_layer, (num_items + divide_factor - 1) / divide_factor }), // second layer size is ceil(num_items / divide_factor) because each bit in the second layer represents an element in the first layer _offsets(offsets), _offsets_size(offsets_size) {} From 53b9f79b82e917f5bff4690dfff4f45b286ec4b8 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Fri, 16 Jan 2026 10:12:03 -0800 Subject: [PATCH 44/69] clang-format fix --- .../backend/primitives/frontier/advance.hpp | 59 +++++++++++++++---- .../backend/primitives/frontier/bitset.hpp | 7 ++- .../backend/primitives/frontier/frontier.hpp | 22 ++++--- .../primitives/frontier/frontier_dpc.cpp | 4 +- .../dal/backend/primitives/frontier/graph.hpp | 5 +- 5 files changed, 72 insertions(+), 25 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index acc6b852d42..e1168364956 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -44,7 +44,9 @@ struct frontier_context_state { template class frontier_context { public: - frontier_context(std::uint64_t limit, InFrontierDevT in_dev_frontier, OutFrontierDevT out_dev_frontier) + frontier_context(std::uint64_t limit, + InFrontierDevT in_dev_frontier, + OutFrontierDevT out_dev_frontier) : limit(limit), in_dev_frontier(in_dev_frontier), out_dev_frontier(out_dev_frontier) {} @@ -327,17 +329,50 @@ sycl::event advance(const GraphT& graph, auto e = q.submit([&](sycl::handler& cgh) { cgh.depends_on(to_wait); - sycl::local_accessor n_edges_wg{local_range, cgh}; // number of edges of vertices to process at work-group granularity - sycl::local_accessor n_edges_sg{local_range, cgh}; // number of edges of vertices to process at sub-group granularity - sycl::local_accessor visited{local_range, cgh}; // tracks the vertices already visited at work-group and sub-group granularity - sycl::local_accessor subgroup_reduce{local_range, cgh}; // stores the vertices to process at sub-group granularity - sycl::local_accessor subgroup_reduce_tail{max_num_subgroups, cgh}; // stores the tail of the subgroup reduction - sycl::local_accessor subgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at sub-group level - sycl::local_accessor workgroup_reduce{local_range, cgh}; // stores the vertices to process at work-group granularity - sycl::local_accessor workgroup_reduce_tail{1, cgh}; // stores the tail of the work-group reduction - sycl::local_accessor workgroup_ids{local_range, cgh}; // stores the thread id that found the vertex to process at work-group level - sycl::local_accessor individual_reduce{local_range, cgh}; // stores the vertices to process at individual thread granularity - sycl::local_accessor individual_reduce_tail{1, cgh}; // stores the tail of the individual thread reduction + sycl::local_accessor n_edges_wg{ + local_range, + cgh + }; // number of edges of vertices to process at work-group granularity + sycl::local_accessor n_edges_sg{ + local_range, + cgh + }; // number of edges of vertices to process at sub-group granularity + sycl::local_accessor visited{ + local_range, + cgh + }; // tracks the vertices already visited at work-group and sub-group granularity + sycl::local_accessor subgroup_reduce{ + local_range, + cgh + }; // stores the vertices to process at sub-group granularity + sycl::local_accessor subgroup_reduce_tail{ + max_num_subgroups, + cgh + }; // stores the tail of the subgroup reduction + sycl::local_accessor subgroup_ids{ + local_range, + cgh + }; // stores the thread id that found the vertex to process at sub-group level + sycl::local_accessor workgroup_reduce{ + local_range, + cgh + }; // stores the vertices to process at work-group granularity + sycl::local_accessor workgroup_reduce_tail{ + 1, + cgh + }; // stores the tail of the work-group reduction + sycl::local_accessor workgroup_ids{ + local_range, + cgh + }; // stores the thread id that found the vertex to process at work-group level + sycl::local_accessor individual_reduce{ + local_range, + cgh + }; // stores the vertices to process at individual thread granularity + sycl::local_accessor individual_reduce_tail{ + 1, + cgh + }; // stores the tail of the individual thread reduction cgh.parallel_for(sycl::nd_range<1>{ global_range, local_range }, bitmap_kernel_t{ context, diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index 6f54bcad949..618bacbd37a 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -27,12 +27,15 @@ template class bitset { public: using element_t = ElementType; - static constexpr std::uint64_t element_bitsize = sizeof(element_t) * 8; // Number of bits in an element + static constexpr std::uint64_t element_bitsize = + sizeof(element_t) * 8; // Number of bits in an element /// Constructs a bitset with the given data pointer and number of items. /// \param data pointer to the underlying data. /// \param num_items number of items in the bitset. - bitset(element_t* data, const size_t num_items) : _data(data), _num_items((num_items + element_bitsize - 1) / element_bitsize) {} + bitset(element_t* data, const size_t num_items) + : _data(data), + _num_items((num_items + element_bitsize - 1) / element_bitsize) {} /// Sets the bit at the specified index to 1. inline void set(std::uint32_t index) const { diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 47b6235d969..85ac5a2cd1f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -33,14 +33,19 @@ class frontier_view { static constexpr std::uint64_t divide_factor = bitset::element_bitsize; frontier_view() = default; - frontier_view(bitmap_t* data_layer, // First layer (tracks vertices in the frontier) - bitmap_t* mlb_layer, // Second layer (to track non-zero elements in the first layer) - std::uint32_t* offsets, // Array to store the indices of the non-zero elements - std::uint32_t* offsets_size, // Pointer to store the size of the offsets array - std::uint64_t num_items) // Maximum number of items that can be stored in the frontier + frontier_view( + bitmap_t* data_layer, // First layer (tracks vertices in the frontier) + bitmap_t* mlb_layer, // Second layer (to track non-zero elements in the first layer) + std::uint32_t* offsets, // Array to store the indices of the non-zero elements + std::uint32_t* offsets_size, // Pointer to store the size of the offsets array + std::uint64_t num_items) // Maximum number of items that can be stored in the frontier : _num_items(num_items), - _data_layer(bitset{ data_layer, num_items }), // first layer size is num_items - _mlb_layer(bitset{ mlb_layer, (num_items + divide_factor - 1) / divide_factor }), // second layer size is ceil(num_items / divide_factor) because each bit in the second layer represents an element in the first layer + _data_layer( + bitset{ data_layer, num_items }), // first layer size is num_items + _mlb_layer(bitset{ + mlb_layer, + (num_items + divide_factor - 1) / + divide_factor }), // second layer size is ceil(num_items / divide_factor) because each bit in the second layer represents an element in the first layer _offsets(offsets), _offsets_size(offsets_size) {} @@ -153,7 +158,8 @@ class frontier { ndarray _offsets; ndarray _buffer; const std::uint64_t _TMP_VAR = 0; - const std::uint64_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) + const std::uint64_t _CAF_FLAG = + 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) }; /// Swaps the contents of two frontiers. diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 0cae68f326e..2f35fa25210 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -108,8 +108,8 @@ inline sycl::event frontier::compute_active_frontier() { const std::uint64_t local_range = 256; // propose_wg_size(this->_queue); const std::uint64_t mlb_count = _mlb_layer.get_count(); const std::uint64_t global_range = (mlb_count % local_range == 0) - ? mlb_count - : (mlb_count + local_range - (mlb_count % local_range)); + ? mlb_count + : (mlb_count + local_range - (mlb_count % local_range)); // check if local memory is enough bool use_local_mem = diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 43e1e5b839c..681e2d52023 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -69,7 +69,10 @@ class csr_graph_view { }; public: - csr_graph_view(std::uint64_t num_nodes, vertex_t* row_ptr, edge_t* col_indices, weight_t* weights) + csr_graph_view(std::uint64_t num_nodes, + vertex_t* row_ptr, + edge_t* col_indices, + weight_t* weights) : _num_nodes(num_nodes), _row_ptr(row_ptr), _col_indices(col_indices), From e7feaece7f0c8eadf8c4530228ec314a203a7131 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Mon, 19 Jan 2026 17:21:58 -0800 Subject: [PATCH 45/69] Change license yaml to be able to add possible additional copyright --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index cf9e7d1a4fe..e4d950d7485 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,7 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project) + (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project(?:\nCopyright[^\n]+)?) Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not use this file except in compliance with the License\. From dc4f81d74857b034b4583b0b4a5fb3034fcd2501 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Mon, 19 Jan 2026 17:48:56 -0800 Subject: [PATCH 46/69] fix? --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index e4d950d7485..ccd5ae4d4db 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,7 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project(?:\nCopyright[^\n]+)?) + (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project(?:\n(?:\s*\*\s*)?Copyright[^\n]+)? Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not use this file except in compliance with the License\. From 862feda5ee8f6bbbf5e79d0bc55c74a3bf123f88 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Mon, 19 Jan 2026 18:02:53 -0800 Subject: [PATCH 47/69] fix? --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index ccd5ae4d4db..7a1cec790cb 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,7 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project(?:\n(?:\s*\*\s*)?Copyright[^\n]+)? + (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project(?:\n(?:\s*\*\s*)?Copyright[^\n]+)?) Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not use this file except in compliance with the License\. From 8e758c90e79558669dacd3e018872d55bbd1e460 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 05:27:22 -0800 Subject: [PATCH 48/69] fix? --- .github/.licenserc.yaml | 4 ++-- cpp/oneapi/dal/backend/primitives/frontier/advance.hpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 7a1cec790cb..fbbefdf3334 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,8 +19,8 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project(?:\n(?:\s*\*\s*)?Copyright[^\n]+)?) - + (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project) + (Copyright .*|) 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 diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index e1168364956..2432faaeafd 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -1,7 +1,6 @@ /******************************************************************************* * Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno -* * 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 From a7806e2108da78fa184629f1e204ee288ee49e9c Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 05:37:37 -0800 Subject: [PATCH 49/69] fix? --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index fbbefdf3334..e898308a2c9 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -20,7 +20,7 @@ header: copyright-owner: contributors to the oneDAL project pattern: | (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project) - (Copyright .*|) + (|Copyright .*) 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 From b40d6db9bde990949eca9ed82f93950d6cb3b289 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 05:42:13 -0800 Subject: [PATCH 50/69] fix? --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index e898308a2c9..1baff789167 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -20,7 +20,7 @@ header: copyright-owner: contributors to the oneDAL project pattern: | (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project) - (|Copyright .*) + (\s*|Copyright .*) 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 From d0de4ec461ca77a879986e22ea08f642a51538dc Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 05:49:32 -0800 Subject: [PATCH 51/69] fix? --- .github/.licenserc.yaml | 3 +-- cpp/oneapi/dal/backend/primitives/frontier/advance.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 1baff789167..4ee1f8adc27 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,8 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - (Copyright \d{4} Intel Corporation|Copyright contributors to the oneDAL project) - (\s*|Copyright .*) + Copyright .* 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 diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 2432faaeafd..7dc3fbe5688 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -1,6 +1,6 @@ /******************************************************************************* -* Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno +* * 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 From ca9b27e6032c8fdb1b4a9566dd2f1ddf24818254 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 06:02:29 -0800 Subject: [PATCH 52/69] fix? --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 4ee1f8adc27..2268d49877b 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,7 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - Copyright .* + Copyright ^[\n]+ 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 From f6c80b0b2205b5357b7a887f12e486df6341df93 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 06:54:07 -0800 Subject: [PATCH 53/69] fix? --- .github/.licenserc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 2268d49877b..2989b7798ff 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,7 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - Copyright ^[\n]+ + Copyright [^\n]+ 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 From 6797388dc5d34e224f7a480975111f7ac1b74fbe Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 07:02:41 -0800 Subject: [PATCH 54/69] fix? --- .github/.licenserc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 2989b7798ff..986ea3e7e8a 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -20,6 +20,7 @@ header: copyright-owner: contributors to the oneDAL project pattern: | Copyright [^\n]+ + 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 From 649f16ff0a8b0b0707e25bc66fc41353d2d89d7a Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 20 Jan 2026 07:17:47 -0800 Subject: [PATCH 55/69] test --- cpp/oneapi/dal/backend/primitives/frontier/advance.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 7dc3fbe5688..09d2302b41f 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -1,5 +1,6 @@ /******************************************************************************* * Copyright 2025 University of Salerno +* testtesttest * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 3859a984ebb0ebb4f6d8ae3a972da0bb308cf5e6 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 27 Jan 2026 06:08:39 -0800 Subject: [PATCH 56/69] fix --- .github/.licenserc.yaml | 2 +- cpp/oneapi/dal/backend/primitives/frontier/advance.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 986ea3e7e8a..490219d8227 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -19,7 +19,7 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - Copyright [^\n]+ + Copyright .* Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not use this file except in compliance with the License\. diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index 09d2302b41f..e1168364956 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -1,6 +1,6 @@ /******************************************************************************* +* Copyright contributors to the oneDAL project * Copyright 2025 University of Salerno -* testtesttest * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 22378f30068bf93813e4bd2c92f571f07a66bc22 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Thu, 29 Jan 2026 13:07:06 -0800 Subject: [PATCH 57/69] Make license checker strict --- .github/.licenserc.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/.licenserc.yaml b/.github/.licenserc.yaml index 490219d8227..2d7d9e9ae37 100644 --- a/.github/.licenserc.yaml +++ b/.github/.licenserc.yaml @@ -1,5 +1,5 @@ #=============================================================================== -# Copyright Contributors to the oneDAL Project +# Copyright contributors to the oneDAL Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,9 +19,10 @@ header: spdx-id: Apache-2.0 copyright-owner: contributors to the oneDAL project pattern: | - Copyright .* - - Licensed under the Apache License, Version 2\.0 \(the "License"\); + (?:Copyright \d{4} Intel Corporation + |Copyright contributors to the oneDAL project + |Copyright \d{4} University of Salerno + )+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 From a654178ee292899f457384b614741dc44bdf67ac Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Fri, 30 Jan 2026 15:08:30 -0800 Subject: [PATCH 58/69] Add preview namespace --- .../backend/primitives/frontier/advance.hpp | 6 ++-- .../backend/primitives/frontier/bitset.hpp | 4 +-- .../backend/primitives/frontier/frontier.hpp | 21 ++++++------ .../primitives/frontier/frontier_dpc.cpp | 22 ++++++------- .../dal/backend/primitives/frontier/graph.hpp | 16 ++++----- .../primitives/frontier/test/advance_dpc.cpp | 23 +++++++------ .../primitives/frontier/test/bfs_dpc.cpp | 33 +++++++++---------- .../primitives/frontier/test/frontier_dpc.cpp | 6 ++-- .../primitives/frontier/test/utils.hpp | 4 +-- 9 files changed, 67 insertions(+), 68 deletions(-) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp index e1168364956..00820e51391 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/advance.hpp @@ -21,7 +21,7 @@ #include "oneapi/dal/backend/primitives/frontier/graph.hpp" #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" -namespace oneapi::dal::backend::primitives { +namespace oneapi::dal::preview::backend::primitives { /// frontier_context_state holds the state of the current processing group in the kernel /// It includes the group offset, coarsening factor, offsets size, and the SYCL @@ -325,7 +325,7 @@ sycl::event advance(const GraphT& graph, using bitmap_kernel_t = bitmap_kernel; - const uint32_t max_num_subgroups = device_max_sg_count(q); + const uint32_t max_num_subgroups = oneapi::dal::backend::device_max_sg_count(q); auto e = q.submit([&](sycl::handler& cgh) { cgh.depends_on(to_wait); @@ -391,4 +391,4 @@ sycl::event advance(const GraphT& graph, return { e }; } -} // namespace oneapi::dal::backend::primitives +} // namespace oneapi::dal::preview::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index 618bacbd37a..bf5e97dece5 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -19,7 +19,7 @@ #include "oneapi/dal/backend/memory.hpp" -namespace oneapi::dal::backend::primitives { +namespace oneapi::dal::preview::backend::primitives { /// A bitset class that provides a set of operations on a bitset implemented using an array of integers. /// \tparam ElementType the type of the elements in the bitset (e.g., std::uint32_t). @@ -119,4 +119,4 @@ class bitset { std::uint64_t _num_items; }; -} // namespace oneapi::dal::backend::primitives +} // namespace oneapi::dal::preview::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp index 85ac5a2cd1f..886bb92b242 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier.hpp @@ -22,7 +22,8 @@ #include "oneapi/dal/backend/primitives/frontier/bitset.hpp" #include "oneapi/dal/backend/primitives/ndarray.hpp" -namespace oneapi::dal::backend::primitives { +namespace oneapi::dal::preview::backend::primitives { +namespace pr = dal::backend::primitives; /// @brief A view of a frontier that provides an interface for the kernel to interact with the frontier data structure. /// \tparam ElementType the type of the elements in the frontier (e.g., std::uint32_t). @@ -110,19 +111,19 @@ class frontier { static_cast(_data_layer.get_count()) }; } - inline ndview get_data() const { + inline pr::ndview get_data() const { return _data_layer; } - inline ndview get_mlb() const { + inline pr::ndview get_mlb() const { return _mlb_layer; } - inline ndview get_offsets() const { + inline pr::ndview get_offsets() const { return _offsets.slice(1, _offsets.get_count()); } - inline ndview get_offsets_size() const { + inline pr::ndview get_offsets_size() const { return _offsets.slice(0, 1); } @@ -153,10 +154,10 @@ class frontier { sycl::queue& _queue; std::uint64_t _num_items; - ndarray _data_layer; - ndarray _mlb_layer; - ndarray _offsets; - ndarray _buffer; + pr::ndarray _data_layer; + pr::ndarray _mlb_layer; + pr::ndarray _offsets; + pr::ndarray _buffer; const std::uint64_t _TMP_VAR = 0; const std::uint64_t _CAF_FLAG = 1; // Compute Active Frontier Flag (1 if already computed, 0 otherwise) @@ -169,4 +170,4 @@ void swap_frontiers(frontier& f1, frontier& f2) { frontier::swap(f1, f2); } -} // namespace oneapi::dal::backend::primitives +} // namespace oneapi::dal::preview::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp index 2f35fa25210..80aa6edf272 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/frontier_dpc.cpp @@ -17,7 +17,7 @@ #include "oneapi/dal/backend/primitives/frontier/frontier.hpp" -namespace oneapi::dal::backend::primitives { +namespace oneapi::dal::preview::backend::primitives { #ifdef ONEDAL_DATA_PARALLEL @@ -29,13 +29,13 @@ frontier::frontier(sycl::queue& queue, std::uint64_t num_items, syc bitset::element_bitsize; std::int64_t mlb_size = (array_size + bitset::element_bitsize - 1) / bitset::element_bitsize; - _data_layer = ndarray::empty(_queue, { array_size }, alloc); - _mlb_layer = ndarray::empty(_queue, { mlb_size }, alloc); - _offsets = ndarray::empty( + _data_layer = pr::ndarray::empty(_queue, { array_size }, alloc); + _mlb_layer = pr::ndarray::empty(_queue, { mlb_size }, alloc); + _offsets = pr::ndarray::empty( _queue, { array_size + 1 }, alloc); /// First offset is to keep the size of the frontier - _buffer = ndarray::empty(_queue, { 10 }, alloc); + _buffer = pr::ndarray::empty(_queue, { 10 }, alloc); sycl::event e1, e2, e3; e1 = _data_layer.fill(_queue, ElementType(0)); @@ -49,13 +49,13 @@ frontier::frontier(sycl::queue& queue, std::uint64_t num_items, syc template bool frontier::empty() { - ndview empty_buff = _buffer.slice(0, 1); + pr::ndview empty_buff = _buffer.slice(0, 1); auto copy_e = fill(_queue, empty_buff, buffer_t(0)); auto* const empty_buff_ptr = empty_buff.get_mutable_data(); auto e = _queue.submit([&](sycl::handler& cgh) { cgh.depends_on(copy_e); - const auto range = make_range_1d(_mlb_layer.get_count()); + const auto range = oneapi::dal::backend::make_range_1d(_mlb_layer.get_count()); auto sum_reduction = sycl::reduction(empty_buff_ptr, sycl::plus<>()); auto* const f_ptr = _mlb_layer.get_mutable_data(); @@ -113,7 +113,7 @@ inline sycl::event frontier::compute_active_frontier() { // check if local memory is enough bool use_local_mem = - device_local_mem_size(this->_queue) >= + oneapi::dal::backend::device_local_mem_size(this->_queue) >= static_cast(local_range * element_bitsize * sizeof(uint32_t)); auto e0 = _queue.submit([&](sycl::handler& cgh) { @@ -129,7 +129,7 @@ inline sycl::event frontier::compute_active_frontier() { cgh.depends_on(e0); if (!use_local_mem) { - cgh.parallel_for(make_range_1d(_mlb_layer.get_count()), + cgh.parallel_for(oneapi::dal::backend::make_range_1d(_mlb_layer.get_count()), [=, offsets = offsets_pointer, offsets_size = offsets_size_pointer, @@ -157,7 +157,7 @@ inline sycl::event frontier::compute_active_frontier() { sycl::local_accessor local_size(1, cgh); cgh.parallel_for( - make_multiple_nd_range_1d(global_range, local_range), + oneapi::dal::backend::make_multiple_nd_range_1d(global_range, local_range), [=, offsets = offsets_pointer, offsets_size = offsets_size_pointer, @@ -216,4 +216,4 @@ INSTANTIATE(std::uint32_t) #endif -} // namespace oneapi::dal::backend::primitives +} // namespace oneapi::dal::preview::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp index 681e2d52023..0c1f045d79c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/graph.hpp @@ -22,7 +22,7 @@ #include "oneapi/dal/graph/detail/container.hpp" #include "oneapi/dal/backend/primitives/ndarray.hpp" -namespace oneapi::dal::backend::primitives { +namespace oneapi::dal::preview::backend::primitives { template (col_indices.size()); std::int64_t weights_size = static_cast(weights.size()); - _row_ptr = ndarray::empty(_queue, { row_ptr_size }, alloc); - _col_indices = ndarray::empty(_queue, { col_indices_size }, alloc); - _weights = ndarray::empty(_queue, { weights_size }, alloc); + _row_ptr = pr::ndarray::empty(_queue, { row_ptr_size }, alloc); + _col_indices = pr::ndarray::empty(_queue, { col_indices_size }, alloc); + _weights = pr::ndarray::empty(_queue, { weights_size }, alloc); auto e1 = dal::backend::copy_host2usm(_queue, _row_ptr.get_mutable_data(), @@ -171,9 +171,9 @@ class csr_graph { private: sycl::queue& _queue; std::uint64_t _num_nodes; - ndarray _row_ptr; - ndarray _col_indices; - ndarray _weights; + pr::ndarray _row_ptr; + pr::ndarray _col_indices; + pr::ndarray _weights; }; -} // namespace oneapi::dal::backend::primitives +} // namespace oneapi::dal::preview::backend::primitives diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp index 89681e8c6c2..bc746e76dc0 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/advance_dpc.cpp @@ -22,7 +22,7 @@ #include "oneapi/dal/test/engine/common.hpp" -namespace oneapi::dal::backend::primitives::test { +namespace oneapi::dal::preview::backend::primitives::test { namespace pr = dal::backend::primitives; @@ -81,12 +81,11 @@ TEST("test advance operation", "[advance]") { const std::uint64_t num_nodes = GENERATE(128, 512, 1024); const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); - auto graph = - pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); + auto graph = csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); auto in_frontier = - pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); auto out_frontier = - pr::frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); + frontier(queue, graph.get_vertex_count(), sycl::usm::alloc::device); std::vector host_frontier(num_nodes, false); std::mt19937 frontier_rng(seed ^ 0x9e3779b9u); @@ -108,12 +107,12 @@ TEST("test advance operation", "[advance]") { host_frontier[fallback_vertex] = true; } - pr::advance(graph, - in_frontier, - out_frontier, - [=](auto vertex, auto neighbor, auto edge, auto weight) { - return true; // Always advance - }) + advance(graph, + in_frontier, + out_frontier, + [=](auto vertex, auto neighbor, auto edge, auto weight) { + return true; // Always advance + }) .wait_and_throw(); auto tmp_frontier = @@ -121,4 +120,4 @@ TEST("test advance operation", "[advance]") { compare_frontiers(out_frontier, tmp_frontier, num_nodes); } // TEST "test advance operation" -} // namespace oneapi::dal::backend::primitives::test +} // namespace oneapi::dal::preview::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp index 49ca07095ad..69ee98b9542 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/bfs_dpc.cpp @@ -23,7 +23,7 @@ #include #include -namespace oneapi::dal::backend::primitives::test { +namespace oneapi::dal::preview::backend::primitives::test { namespace pr = dal::backend::primitives; @@ -62,10 +62,9 @@ TEST("test BFS", "[bfs]") { const std::uint64_t num_nodes = GENERATE(128, 512, 1024); const auto graph_data = generate_random_graph(num_nodes, edge_probability, seed); - auto graph = - pr::csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); - auto in_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); - auto out_frontier = pr::frontier(queue, num_nodes, sycl::usm::alloc::device); + auto graph = csr_graph(queue, graph_data.row_ptr, graph_data.col_indices, graph_data.weights); + auto in_frontier = frontier(queue, num_nodes, sycl::usm::alloc::device); + auto out_frontier = frontier(queue, num_nodes, sycl::usm::alloc::device); pr::ndarray distance = pr::ndarray::empty(queue, { static_cast(num_nodes) }, @@ -87,19 +86,19 @@ TEST("test BFS", "[bfs]") { /// Start BFS while (!in_frontier.empty()) { - auto e = pr::advance(graph, - in_frontier, - out_frontier, - [=](auto vertex, auto neighbor, auto edge, auto weight) { - bool visited = distance_ptr[neighbor] < num_nodes + 1; - if (!visited) { - distance_ptr[neighbor] = iter + 1; - } - return !visited; - }); + auto e = advance(graph, + in_frontier, + out_frontier, + [=](auto vertex, auto neighbor, auto edge, auto weight) { + bool visited = distance_ptr[neighbor] < num_nodes + 1; + if (!visited) { + distance_ptr[neighbor] = iter + 1; + } + return !visited; + }); e.wait_and_throw(); iter++; - pr::swap_frontiers(in_frontier, out_frontier); + swap_frontiers(in_frontier, out_frontier); out_frontier.clear(); } /// End BFS @@ -112,4 +111,4 @@ TEST("test BFS", "[bfs]") { } } // TEST "test advance operation" -} // namespace oneapi::dal::backend::primitives::test +} // namespace oneapi::dal::preview::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp index 3abce2a0b09..9dcc156c83c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/frontier_dpc.cpp @@ -19,7 +19,7 @@ #include "oneapi/dal/backend/primitives/frontier/test/utils.hpp" #include "oneapi/dal/test/engine/common.hpp" -namespace oneapi::dal::backend::primitives::test { +namespace oneapi::dal::preview::backend::primitives::test { namespace pr = dal::backend::primitives; @@ -39,7 +39,7 @@ TEST("frontier queue basic operations", "[frontier]") { print_device_name(queue); const std::uint64_t num_items = 100; - auto f = pr::frontier(queue, num_items, sycl::usm::alloc::shared); + auto f = frontier(queue, num_items, sycl::usm::alloc::shared); REQUIRE(f.empty() == true); f.insert(0); @@ -71,4 +71,4 @@ TEST("frontier queue basic operations", "[frontier]") { REQUIRE(f.empty() == true); } // TEST "frontier queue operations" -} // namespace oneapi::dal::backend::primitives::test +} // namespace oneapi::dal::preview::backend::primitives::test diff --git a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp index 1d822aec69b..93911e05dd3 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/test/utils.hpp @@ -26,7 +26,7 @@ void print_device_name(sycl::queue& queue) { std::cout << "Running on device: " << device_name << std::endl; } -namespace oneapi::dal::backend::primitives { +namespace oneapi::dal::preview::backend::primitives { struct csr_graph_data { std::vector row_ptr; std::vector col_indices; @@ -76,4 +76,4 @@ csr_graph_data generate_random_graph(std::uint64_t vertex_count, return { std::move(row_ptr), std::move(col_indices), std::move(weights) }; } -} // namespace oneapi::dal::backend::primitives +} // namespace oneapi::dal::preview::backend::primitives From 8947a095627f5b953aa2a3d5582696a5a43851bb Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Mon, 11 May 2026 06:15:10 -0700 Subject: [PATCH 59/69] check --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4a82d13e98..7db6156f0bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,7 +75,7 @@ jobs: source /opt/intel/oneapi/setvars.sh .ci/scripts/build.sh --compiler icx --optimizations ${{ matrix.ISA }} --target oneapi_c --debug symbols --jobs 20 rm -rf __work - .ci/scripts/build.sh --compiler icx --optimizations ${{ matrix.ISA }} --target oneapi_dpc --debug symbols --jobs 20 + .ci/scripts/build.sh --compiler icx --optimizations ${{ matrix.ISA }} --target oneapi_dpc --jobs 20 # clean up build directory due to space limitations rm -rf __work echo "key=__release_lnx-$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" From 7b6c44916af446b652c08820204a73295b193741 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 12 May 2026 09:33:49 -0700 Subject: [PATCH 60/69] check --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7db6156f0bd..e4a82d13e98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,7 +75,7 @@ jobs: source /opt/intel/oneapi/setvars.sh .ci/scripts/build.sh --compiler icx --optimizations ${{ matrix.ISA }} --target oneapi_c --debug symbols --jobs 20 rm -rf __work - .ci/scripts/build.sh --compiler icx --optimizations ${{ matrix.ISA }} --target oneapi_dpc --jobs 20 + .ci/scripts/build.sh --compiler icx --optimizations ${{ matrix.ISA }} --target oneapi_dpc --debug symbols --jobs 20 # clean up build directory due to space limitations rm -rf __work echo "key=__release_lnx-$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" From db05f457832eae3e2523b9a42afbdb9fdd843994 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 12 May 2026 11:11:19 -0700 Subject: [PATCH 61/69] Fix dbg --- .../dal/backend/primitives/frontier/bitset.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp index bf5e97dece5..82f75f31e0c 100644 --- a/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp +++ b/cpp/oneapi/dal/backend/primitives/frontier/bitset.hpp @@ -41,7 +41,9 @@ class bitset { inline void set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); +#endif _data[element_index] |= (element_t(1) << bit_index); } @@ -49,7 +51,9 @@ class bitset { inline void unset(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); +#endif _data[element_index] &= ~(element_t(1) << bit_index); } @@ -57,7 +61,9 @@ class bitset { inline bool test(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); +#endif return (_data[element_index] & (element_t(1) << bit_index)) != 0; } @@ -67,7 +73,9 @@ class bitset { inline void atomic_set(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); +#endif sycl::atomic_ref atomic_element(_data[element_index]); atomic_element |= (element_t(1) << bit_index); } @@ -78,7 +86,9 @@ class bitset { inline void atomic_unset(std::uint32_t index) { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); +#endif sycl::atomic_ref atomic_element(_data[element_index]); atomic_element &= ~(element_t(1) << bit_index); } @@ -89,7 +99,9 @@ class bitset { inline bool atomic_test(std::uint32_t index) const { element_t element_index = index / element_bitsize; element_t bit_index = index % element_bitsize; +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(element_index < _num_items, "Index out of bounds"); +#endif sycl::atomic_ref atomic_element(_data[element_index]); return (atomic_element.load() & (element_t(1) << bit_index)) != 0; } @@ -110,7 +122,9 @@ class bitset { /// override operator [] inline element_t& operator[](std::uint64_t index) { +#ifndef __SYCL_DEVICE_ONLY__ ONEDAL_ASSERT(index < _num_items, "Index out of bounds"); +#endif return _data[index]; } From 87c706a5832e305b89eba2df8eba7d9c0e6beddb Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 5 May 2026 07:12:33 -0700 Subject: [PATCH 62/69] tc gpu --- cpp/oneapi/dal/algo/triangle_counting/BUILD | 17 +- .../backend/gpu/CMakeLists.txt | 5 + .../backend/gpu/triangle_counting.hpp | 16 + .../vertex_ranking_default_kernel_gpu_dpc.cpp | 258 +++++++++++ .../backend/gpu/vertex_ranking_kernel.hpp | 36 ++ .../dal/algo/triangle_counting/common.hpp | 20 + .../detail/select_kernel.hpp | 26 ++ .../detail/select_kernel_dpc.cpp | 122 +++++ .../detail/vertex_ranking_ops.hpp | 19 +- .../test/triangle_counting_gpu_test.cpp | 426 ++++++++++++++++++ cpp/oneapi/dal/detail/vertex_ranking_ops.hpp | 22 + cpp/oneapi/dal/graph/detail/csr_topology.hpp | 54 ++- .../dal/graph/detail/device_csr_topology.hpp | 265 +++++++++++ ...undirected_adjacency_vector_graph_impl.hpp | 37 ++ .../undirected_adjacency_vector_graph.hpp | 7 + cpp/oneapi/dal/vertex_ranking.hpp | 12 + .../triangle_counting_batch.cpp | 5 + examples/oneapi/dpc/BUILD | 1 + .../triangle_counting_batch.cpp | 67 +++ 19 files changed, 1410 insertions(+), 5 deletions(-) create mode 100644 cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt create mode 100644 cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp create mode 100644 cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp create mode 100644 cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp create mode 100644 cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp create mode 100644 cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp create mode 100644 cpp/oneapi/dal/graph/detail/device_csr_topology.hpp create mode 100644 examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp diff --git a/cpp/oneapi/dal/algo/triangle_counting/BUILD b/cpp/oneapi/dal/algo/triangle_counting/BUILD index ec0af5a5613..ab503dec297 100755 --- a/cpp/oneapi/dal/algo/triangle_counting/BUILD +++ b/cpp/oneapi/dal/algo/triangle_counting/BUILD @@ -10,7 +10,7 @@ dal_module( dal_deps = [ "@onedal//cpp/oneapi/dal:core", "@onedal//cpp/oneapi/dal/backend/primitives:intersection", - ] + ], ) dal_test_suite( @@ -19,6 +19,21 @@ dal_test_suite( framework = "catch2", srcs = glob([ "test/*.cpp", + ], + exclude = [ + "test/*_gpu_test.cpp", + ]), + dal_deps = [ + ":triangle_counting", + ], +) + +dal_test_suite( + name = "gpu_tests", + framework = "catch2", + compile_as = [ "dpc++" ], + srcs = glob([ + "test/*_gpu_test.cpp", ]), dal_deps = [ ":triangle_counting", diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt new file mode 100644 index 00000000000..a7f81fe3901 --- /dev/null +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt @@ -0,0 +1,5 @@ +set(ONEDAL_TRIANGLE_COUNTING_BACKEND_GPU_HEADERS + ${CMAKE_CURRENT_LIST_DIR}/triangle_counting.hpp + ${CMAKE_CURRENT_LIST_DIR}/vertex_ranking_kernel.hpp + PARENT_SCOPE +) diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp new file mode 100644 index 00000000000..a6c9dae0b66 --- /dev/null +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "oneapi/dal/algo/triangle_counting/common.hpp" +#include "oneapi/dal/algo/triangle_counting/vertex_ranking_types.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" + +namespace oneapi::dal::preview::triangle_counting::backend { + +template +struct vertex_ranking_kernel_gpu { + vertex_ranking_result operator()(const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const Topology& topology) const; +}; + +} // namespace oneapi::dal::preview::triangle_counting::backend diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp new file mode 100644 index 00000000000..51dda423f24 --- /dev/null +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp @@ -0,0 +1,258 @@ +/******************************************************************************* +* 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. +*******************************************************************************/ + +#include + +#include "oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp" +#include "oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" +#include "oneapi/dal/table/detail/table_builder.hpp" + +namespace oneapi::dal::preview::triangle_counting::backend { + +namespace detail_gpu { + +/// Counts triangles for each vertex in a CSR graph on the GPU using a +/// binary-search intersection approach. +/// +/// @tparam Index The index type used for vertex/edge indexing +/// @param[in] queue SYCL queue for device execution +/// @param[in] rows CSR row-offset array (vertex_count + 1 entries) +/// @param[in] cols CSR column-index array (2 * edge_count entries) +/// @param[in] vertex_count Number of vertices in the graph +/// @param[in] edge_count Number of undirected edges +/// @return A USM-allocated array of per-vertex triangle counts +template +std::int64_t* count_triangles_gpu(sycl::queue& queue, + const std::int64_t* rows, + const Index* cols, + std::int64_t vertex_count, + std::int64_t edge_count) { + auto* local_triangles = + sycl::malloc_shared(vertex_count, queue); + queue.memset(local_triangles, 0, vertex_count * sizeof(std::int64_t)).wait_and_throw(); + + // Parallel kernel: each work-item processes one vertex + queue.submit([&](sycl::handler& cgh) { + const std::int64_t* d_rows = rows; + const Index* d_cols = cols; + std::int64_t* d_triangles = local_triangles; + const std::int64_t vc = vertex_count; + + cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { + const std::int64_t u = idx[0]; + const std::int64_t u_start = d_rows[u]; + const std::int64_t u_end = d_rows[u + 1]; + + std::int64_t count = 0; + + // Iterate over each neighbor v of u where v > u + for (std::int64_t i = u_start; i < u_end; ++i) { + const std::int64_t v = d_cols[i]; + if (v <= u) continue; + + const std::int64_t v_start = d_rows[v]; + const std::int64_t v_end = d_rows[v + 1]; + + // Merge-based intersection of neighbors of u and v + std::int64_t ui = u_start; + std::int64_t vi = v_start; + while (ui < u_end && vi < v_end) { + const std::int64_t nu = d_cols[ui]; + const std::int64_t nv = d_cols[vi]; + if (nu == nv) { + // Only count if common neighbor w > v to avoid + // triple-counting the same triangle + if (nu > v) { + // Found a triangle (u, v, nu) with u < v < nu + count++; + // Atomically increment counts for v and the common neighbor + sycl::atomic_ref( + d_triangles[v]) + .fetch_add(1); + sycl::atomic_ref( + d_triangles[nu]) + .fetch_add(1); + } + ++ui; + ++vi; + } + else if (nu < nv) { + ++ui; + } + else { + ++vi; + } + } + } + // Add the count for vertex u + sycl::atomic_ref(d_triangles[u]) + .fetch_add(count); + }); + }).wait_and_throw(); + + return local_triangles; +} + +/// Sums per-vertex triangle counts and divides by 3 to get the global count. +/// +/// @param[in] queue SYCL queue for device execution +/// @param[in] local_triangles Per-vertex triangle count array +/// @param[in] vertex_count Number of vertices +/// @return The global (total) triangle count +std::int64_t sum_triangles_gpu(sycl::queue& queue, + const std::int64_t* local_triangles, + std::int64_t vertex_count) { + auto* sum_buf = sycl::malloc_shared(1, queue); + sum_buf[0] = 0; + + queue.submit([&](sycl::handler& cgh) { + const std::int64_t* d_triangles = local_triangles; + std::int64_t* d_sum = sum_buf; + const std::int64_t vc = vertex_count; + + cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { + sycl::atomic_ref(d_sum[0]) + .fetch_add(d_triangles[idx[0]]); + }); + }).wait_and_throw(); + + // Each triangle is counted 3 times (once per vertex) + const std::int64_t result = sum_buf[0] / 3; + sycl::free(sum_buf, queue); + return result; +} + +} // namespace detail_gpu + +template +vertex_ranking_result run_vertex_ranking_gpu(const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const csr_topology_gpu_view& topology) { + auto& queue = ctx.get_queue(); + + const auto vertex_count = topology.vertex_count; + const auto edge_count = topology.edge_count; + + if (vertex_count == 0) { + return vertex_ranking_result(); + } + + auto* local_triangles = + detail_gpu::count_triangles_gpu(queue, topology.rows, topology.cols, + vertex_count, edge_count); + + vertex_ranking_result result; + + if constexpr (std::is_same_v || + std::is_same_v) { + auto arr = array(queue, local_triangles, vertex_count, + [queue](std::int64_t* ptr) mutable { + sycl::free(ptr, queue); + }); + result.set_ranks(dal::detail::homogen_table_builder{} + .reset(arr, vertex_count, 1) + .build()); + } + + if constexpr (std::is_same_v || + std::is_same_v) { + std::int64_t global_count = + detail_gpu::sum_triangles_gpu(queue, local_triangles, vertex_count); + result.set_global_rank(global_count); + } + + // Free local_triangles only if not wrapped into the result table + if constexpr (std::is_same_v) { + sycl::free(local_triangles, queue); + } + + return result; +} + +template +vertex_ranking_result vertex_ranking_kernel_gpu::operator()( + const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const Topology& topology) const { + auto& queue = ctx.get_queue(); + const auto vertex_count = topology.get_vertex_count(); + + if (vertex_count == 0) { + return vertex_ranking_result(); + } + + using namespace dal::preview::detail; + + const auto* rows_ptr = topology._rows.get_data(); + const auto alloc_type = sycl::get_pointer_type(rows_ptr, queue.get_context()); + + if (alloc_type == sycl::usm::alloc::device || alloc_type == sycl::usm::alloc::shared) { + csr_topology_gpu_view gpu_view; + gpu_view.rows = rows_ptr; + gpu_view.cols = topology._cols.get_data(); + gpu_view.vertex_count = vertex_count; + gpu_view.edge_count = topology.get_edge_count(); + return run_vertex_ranking_gpu(ctx, desc, gpu_view); + } + + auto device_topo = topology_to_device(queue, topology); + const auto gpu_view = make_gpu_view(device_topo); + return run_vertex_ranking_gpu(ctx, desc, gpu_view); +} + +// Explicit template instantiations +template struct vertex_ranking_kernel_gpu>; +template struct vertex_ranking_kernel_gpu>; +template struct vertex_ranking_kernel_gpu>; + +template vertex_ranking_result +run_vertex_ranking_gpu( + const dal::backend::context_gpu&, + const detail::descriptor_base&, + const csr_topology_gpu_view&); + +template vertex_ranking_result +run_vertex_ranking_gpu( + const dal::backend::context_gpu&, + const detail::descriptor_base&, + const csr_topology_gpu_view&); + +template vertex_ranking_result +run_vertex_ranking_gpu( + const dal::backend::context_gpu&, + const detail::descriptor_base&, + const csr_topology_gpu_view&); + +} // namespace oneapi::dal::preview::triangle_counting::backend diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp new file mode 100644 index 00000000000..e3e0b15da03 --- /dev/null +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +#include "oneapi/dal/algo/triangle_counting/vertex_ranking_types.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" + +namespace oneapi::dal::preview::triangle_counting::backend { + +template +struct csr_topology_gpu_view { + const std::int64_t* rows = nullptr; + const Index* cols = nullptr; + std::int64_t vertex_count = 0; + std::int64_t edge_count = 0; +}; + +/// Creates a GPU view from a device_csr_topology (zero-copy, just extracts pointers). +template +csr_topology_gpu_view make_gpu_view( + const dal::preview::detail::device_csr_topology& device_topo) { + csr_topology_gpu_view view; + view.rows = device_topo.get_rows(); + view.cols = device_topo.get_cols(); + view.vertex_count = device_topo.get_vertex_count(); + view.edge_count = device_topo.get_edge_count(); + return view; +} + +template +vertex_ranking_result run_vertex_ranking_gpu(const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const csr_topology_gpu_view& topology); + +} // namespace oneapi::dal::preview::triangle_counting::backend diff --git a/cpp/oneapi/dal/algo/triangle_counting/common.hpp b/cpp/oneapi/dal/algo/triangle_counting/common.hpp index cb5ed359c56..2db9f54c9c6 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/common.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/common.hpp @@ -17,6 +17,7 @@ #pragma once #include "oneapi/dal/detail/common.hpp" #include "oneapi/dal/graph/undirected_adjacency_vector_graph.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" #include "oneapi/dal/table/common.hpp" namespace oneapi::dal::preview::triangle_counting { @@ -139,6 +140,24 @@ class descriptor : public detail::descriptor_base { namespace detail { +#ifdef ONEDAL_DATA_PARALLEL +template +struct is_device_csr_topology : std::false_type {}; + +template +struct is_device_csr_topology> + : std::true_type {}; + +template +constexpr bool is_valid_graph = + is_device_csr_topology::value || + dal::detail::is_one_of_v, + edge_user_value_type, + graph_user_value_type, + vertex_type, + graph_allocator>>; +#else template constexpr bool is_valid_graph = dal::detail::is_one_of_v, vertex_type, graph_allocator>>; +#endif } // namespace detail } // namespace oneapi::dal::preview::triangle_counting diff --git a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp index cf0b2f7acc7..84ed6c67fe8 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp @@ -21,6 +21,10 @@ #include "oneapi/dal/algo/triangle_counting/vertex_ranking_types.hpp" #include "oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp" +#ifdef ONEDAL_DATA_PARALLEL +#include "oneapi/dal/detail/policy.hpp" +#endif + namespace oneapi::dal::preview::triangle_counting::detail { template @@ -57,6 +61,28 @@ struct backend_default : public backend_base { } }; +#ifdef ONEDAL_DATA_PARALLEL +/// GPU dispatch specialization. +/// +/// The actual GPU kernel implementation is resolved at link time via the +/// pre-compiled oneDAL DPC++ library. Only a forward declaration of the +/// kernel struct is needed here, avoiding backend header dependencies +/// that are not part of the public/detail header set. +template +struct backend_default + : public backend_base { + using float_t = typename Descriptor::float_t; + using task_t = typename Descriptor::task_t; + using method_t = typename Descriptor::method_t; + using allocator_t = typename Descriptor::allocator_t; + + virtual vertex_ranking_result operator()( + const dal::detail::data_parallel_policy& ctx, + const Descriptor& descriptor, + const Topology& t); +}; +#endif + template dal::detail::shared> get_backend(const Descriptor& desc, const Topology& t) { diff --git a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp new file mode 100644 index 00000000000..170e5ae41ec --- /dev/null +++ b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp @@ -0,0 +1,122 @@ +/******************************************************************************* +* 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. +*******************************************************************************/ + +#include "oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp" +#include "oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp" +#include "oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp" +#include "oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" + +namespace oneapi::dal::preview::triangle_counting::detail { + +template +vertex_ranking_result +backend_default::operator()( + const dal::detail::data_parallel_policy& ctx, + const Descriptor& descriptor, + const Topology& t) { + using float_t = typename Descriptor::float_t; + using task_t = typename Descriptor::task_t; + using method_t = typename Descriptor::method_t; + using allocator_t = typename Descriptor::allocator_t; + + return dal::backend::dispatch_by_device( + ctx, + [&]() { + // CPU path: delegate to host policy kernel + return vertex_ranking_kernel_cpu()( + dal::detail::host_policy::get_default(), + descriptor, + descriptor.get_allocator(), + t); + }, + [&]() { + // GPU path: delegate to GPU kernel + dal::backend::context_gpu gpu_ctx{ ctx }; + return backend::vertex_ranking_kernel_gpu()( + gpu_ctx, + descriptor, + t); + }); +} + +/// Specialization for device_csr_topology: GPU-only path (no CPU fallback). +/// Handled directly in vertex_ranking_ops_dispatcher. + +template +vertex_ranking_result +vertex_ranking_ops_dispatcher>::operator()( + const dal::detail::data_parallel_policy &policy, + const Descriptor &descriptor, + input_t &input) const { + using float_t = typename Descriptor::float_t; + using task_t = typename Descriptor::task_t; + + const auto &device_topo = input.get_graph(); + if (device_topo.get_vertex_count() == 0) { + return vertex_ranking_result(); + } + dal::backend::context_gpu gpu_ctx{ policy }; + const auto gpu_view = backend::make_gpu_view(device_topo); + return backend::run_vertex_ranking_gpu(gpu_ctx, descriptor, gpu_view); +} + +// Explicit instantiations for supported descriptor/topology combinations +using default_descriptor_local = descriptor< + float, + method::ordered_count, + task::local, + std::allocator>; + +using default_descriptor_global = descriptor< + float, + method::ordered_count, + task::global, + std::allocator>; + +using default_descriptor_local_and_global = descriptor< + float, + method::ordered_count, + task::local_and_global, + std::allocator>; + +using default_topology = dal::preview::detail::topology; +using device_topology = dal::preview::detail::device_csr_topology; + +template struct ONEDAL_EXPORT backend_default; +template struct ONEDAL_EXPORT backend_default; +template struct ONEDAL_EXPORT backend_default; + +// Explicit instantiations for device_csr_topology dispatcher +template struct vertex_ranking_ops_dispatcher; +template struct vertex_ranking_ops_dispatcher; +template struct vertex_ranking_ops_dispatcher; + +} // namespace oneapi::dal::preview::triangle_counting::detail diff --git a/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp b/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp index e69b822283b..cef64393fb2 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp @@ -23,6 +23,7 @@ #include "oneapi/dal/detail/policy.hpp" #include "oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp" #include "oneapi/dal/graph/detail/undirected_adjacency_vector_graph_topology_builder.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" namespace oneapi::dal::preview::triangle_counting::detail { @@ -36,7 +37,7 @@ struct vertex_ranking_ops_dispatcher { const auto &t = topology_builder(input.get_graph()); - static auto impl = get_backend(descriptor, t); + auto impl = get_backend(descriptor, t); return (*impl)(policy, descriptor, t); } @@ -58,4 +59,20 @@ struct vertex_ranking_ops { } }; +#ifdef ONEDAL_DATA_PARALLEL +/// Specialization for device_csr_topology: skips host-to-device transfer +/// since the graph data is already on the device. +template +struct vertex_ranking_ops_dispatcher> { + using task_t = typename Descriptor::task_t; + using input_t = vertex_ranking_input, task_t>; + + vertex_ranking_result operator()( + const dal::detail::data_parallel_policy &policy, + const Descriptor &descriptor, + input_t &input) const; +}; +#endif + } // namespace oneapi::dal::preview::triangle_counting::detail diff --git a/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp b/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp new file mode 100644 index 00000000000..c28cc2f0517 --- /dev/null +++ b/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp @@ -0,0 +1,426 @@ +/******************************************************************************* +* 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. +*******************************************************************************/ + +#include + +#ifndef ONEDAL_DATA_PARALLEL +#define ONEDAL_DATA_PARALLEL +#endif + +#include + +#include "oneapi/dal/algo/triangle_counting/vertex_ranking.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" + +#include "oneapi/dal/test/engine/common.hpp" + +namespace oneapi::dal::algo::triangle_counting::gpu::test { + +class graph_base_data { +public: + graph_base_data() = default; + + std::int64_t get_vertex_count() const { + return vertex_count; + } + + std::int64_t get_edge_count() const { + return edge_count; + } + + std::int64_t get_global_triangle_count() const { + return global_triangle_count; + } + + std::int64_t get_cols_count() const { + return cols_count; + } + + std::int64_t get_rows_count() const { + return rows_count; + } + +protected: + std::int64_t vertex_count; + std::int64_t edge_count; + std::int64_t cols_count; + std::int64_t rows_count; + std::int64_t global_triangle_count; +}; + +class complete_graph_5_type : public graph_base_data { +public: + complete_graph_5_type() { + vertex_count = 5; + edge_count = 10; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + global_triangle_count = 10; + } + + std::array degrees = { 4, 4, 4, 4, 4 }; + std::array cols = { + 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3 + }; + std::array rows = { 0, 4, 8, 12, 16, 20 }; + std::array local_triangles = { 6, 6, 6, 6, 6 }; +}; + +class complete_graph_9_type : public graph_base_data { +public: + complete_graph_9_type() { + vertex_count = 9; + edge_count = 36; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + global_triangle_count = 84; + } + + std::array degrees = { 8, 8, 8, 8, 8, 8, 8, 8, 8 }; + std::array cols = { 1, 2, 3, 4, 5, 6, 7, 8, 0, 2, 3, 4, 5, 6, 7, 8, 0, 1, + 3, 4, 5, 6, 7, 8, 0, 1, 2, 4, 5, 6, 7, 8, 0, 1, 2, 3, + 5, 6, 7, 8, 0, 1, 2, 3, 4, 6, 7, 8, 0, 1, 2, 3, 4, 5, + 7, 8, 0, 1, 2, 3, 4, 5, 6, 8, 0, 1, 2, 3, 4, 5, 6, 7 }; + std::array rows = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72 }; + std::array local_triangles = { 28, 28, 28, 28, 28, 28, 28, 28, 28 }; +}; + +class triangle_graph_type : public graph_base_data { +public: + triangle_graph_type() { + vertex_count = 3; + edge_count = 3; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + global_triangle_count = 1; + } + + std::array degrees = { 2, 2, 2 }; + std::array cols = { 1, 2, 0, 2, 0, 1 }; + std::array rows = { 0, 2, 4, 6 }; + std::array local_triangles = { 1, 1, 1 }; +}; + +class two_vertices_graph_type : public graph_base_data { +public: + two_vertices_graph_type() { + vertex_count = 2; + edge_count = 1; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + global_triangle_count = 0; + } + + std::array degrees = { 1, 1 }; + std::array cols = { 1, 0 }; + std::array rows = { 0, 1, 2 }; + std::array local_triangles = { 0, 0 }; +}; + +class wheel_graph_6_type : public graph_base_data { +public: + wheel_graph_6_type() { + vertex_count = 6; + edge_count = 10; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + global_triangle_count = 5; + } + + std::array degrees = { 5, 3, 3, 3, 3, 3 }; + std::array cols = { + 1, 2, 3, 4, 5, 0, 2, 5, 0, 1, 3, 0, 2, 4, 0, 3, 5, 0, 1, 4 + }; + std::array rows = { 0, 5, 8, 11, 14, 17, 20 }; + std::array local_triangles = { 5, 2, 2, 2, 2, 2 }; +}; + +class graph_with_isolated_vertices_10_type : public graph_base_data { +public: + graph_with_isolated_vertices_10_type() { + vertex_count = 10; + edge_count = 11; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + global_triangle_count = 5; + } + + std::array degrees = { 5, 3, 2, 0, 3, 4, 0, 2, 0, 3 }; + std::array cols = { 1, 2, 4, 5, 7, 0, 5, 9, 0, 7, 0, + 5, 9, 0, 1, 4, 9, 0, 2, 1, 4, 5 }; + std::array rows = { 0, 5, 8, 10, 10, 13, 17, 17, 19, 19, 22 }; + std::array local_triangles = { 3, 2, 1, 0, 2, 4, 0, 1, 0, 2 }; +}; + +class triangle_counting_gpu_test { +public: + template + auto create_graph() { + GraphType graph_data; + dal::preview::undirected_adjacency_vector_graph<> g; + auto& graph_impl = oneapi::dal::detail::get_impl(g); + auto& vertex_allocator = graph_impl._vertex_allocator; + auto& edge_allocator = graph_impl._edge_allocator; + + const std::int64_t vertex_count = graph_data.get_vertex_count(); + const std::int64_t edge_count = graph_data.get_edge_count(); + const std::int64_t cols_count = graph_data.get_cols_count(); + const std::int64_t rows_count = graph_data.get_rows_count(); + + std::int32_t* degrees = + oneapi::dal::preview::detail::allocate(vertex_allocator, vertex_count); + std::int32_t* cols = oneapi::dal::preview::detail::allocate(vertex_allocator, cols_count); + std::int64_t* rows = oneapi::dal::preview::detail::allocate(edge_allocator, rows_count); + std::int32_t* rows_vertex = + oneapi::dal::preview::detail::allocate(vertex_allocator, rows_count); + + for (int i = 0; i < vertex_count; i++) { + degrees[i] = graph_data.degrees[i]; + } + + for (int i = 0; i < cols_count; i++) { + cols[i] = graph_data.cols[i]; + } + for (int i = 0; i < rows_count; i++) { + rows[i] = graph_data.rows[i]; + rows_vertex[i] = graph_data.rows[i]; + } + graph_impl.set_topology(vertex_count, edge_count, rows, cols, cols_count, degrees); + graph_impl.get_topology()._rows_vertex = + oneapi::dal::preview::detail::container::wrap(rows_vertex, rows_count); + return g; + } + + sycl::queue get_queue() { + return sycl::queue{ sycl::default_selector_v }; + } + + template + void check_local_task() { + GraphType graph_data; + const auto g = create_graph(); + std::int64_t vertex_count = graph_data.get_vertex_count(); + + auto q = get_queue(); + + std::allocator alloc; + const auto tc_desc = dal::preview::triangle_counting::descriptor< + float, + dal::preview::triangle_counting::method::ordered_count, + dal::preview::triangle_counting::task::local, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, g); + + const auto local_triangles_table = result.get_ranks(); + const auto& local_triangles = + static_cast(local_triangles_table); + const auto local_triangles_data = local_triangles.get_data(); + + REQUIRE(local_triangles_table.get_row_count() == vertex_count); + + int correct_local_triangle_count = 0; + for (std::int64_t i = 0; i < vertex_count; i++) { + if (local_triangles_data[i] == graph_data.local_triangles[i]) { + correct_local_triangle_count++; + } + } + REQUIRE(correct_local_triangle_count == vertex_count); + } + + template + void check_local_and_global_task() { + GraphType graph_data; + const auto g = create_graph(); + std::int64_t vertex_count = graph_data.get_vertex_count(); + std::int64_t global_triangle_count = graph_data.get_global_triangle_count(); + + auto q = get_queue(); + + std::allocator alloc; + const auto tc_desc = dal::preview::triangle_counting::descriptor< + float, + dal::preview::triangle_counting::method::ordered_count, + dal::preview::triangle_counting::task::local_and_global, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, g); + + const auto local_triangles_table = result.get_ranks(); + const auto& local_triangles = + static_cast(local_triangles_table); + const auto local_triangles_data = local_triangles.get_data(); + + REQUIRE(result.get_global_rank() == global_triangle_count); + REQUIRE(local_triangles_table.get_row_count() == vertex_count); + + int correct_local_triangle_count = 0; + for (std::int64_t i = 0; i < vertex_count; i++) { + if (local_triangles_data[i] == graph_data.local_triangles[i]) { + correct_local_triangle_count++; + } + } + REQUIRE(correct_local_triangle_count == vertex_count); + } + + template + void check_global_task() { + GraphType graph_data; + const auto g = create_graph(); + std::int64_t global_triangle_count = graph_data.get_global_triangle_count(); + + auto q = get_queue(); + + std::allocator alloc; + const auto tc_desc = dal::preview::triangle_counting::descriptor< + float, + dal::preview::triangle_counting::method::ordered_count, + dal::preview::triangle_counting::task::global, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, g); + REQUIRE(result.get_global_rank() == global_triangle_count); + } +}; + +TEST_M(triangle_counting_gpu_test, "GPU: Local task") { + this->check_local_task(); + this->check_local_task(); + this->check_local_task(); + this->check_local_task(); + this->check_local_task(); + this->check_local_task(); +} + +TEST_M(triangle_counting_gpu_test, "GPU: Local and global task") { + this->check_local_and_global_task(); + this->check_local_and_global_task(); + this->check_local_and_global_task(); + this->check_local_and_global_task(); + this->check_local_and_global_task(); + this->check_local_and_global_task(); +} + +TEST_M(triangle_counting_gpu_test, "GPU: Global task") { + this->check_global_task(); + this->check_global_task(); + this->check_global_task(); + this->check_global_task(); + this->check_global_task(); + this->check_global_task(); +} + +TEST_M(triangle_counting_gpu_test, "GPU: Null graph - local task") { + dal::preview::undirected_adjacency_vector_graph<> null_graph; + auto q = get_queue(); + + std::allocator alloc; + const auto tc_desc = dal::preview::triangle_counting::descriptor< + float, + dal::preview::triangle_counting::method::ordered_count, + dal::preview::triangle_counting::task::local, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, null_graph); + const auto& local_triangles = + static_cast(result.get_ranks()); + REQUIRE(local_triangles.has_data() == false); +} + +TEST_M(triangle_counting_gpu_test, "GPU: Null graph - global task") { + dal::preview::undirected_adjacency_vector_graph<> null_graph; + auto q = get_queue(); + + std::allocator alloc; + const auto tc_desc = dal::preview::triangle_counting::descriptor< + float, + dal::preview::triangle_counting::method::ordered_count, + dal::preview::triangle_counting::task::global, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, null_graph); + REQUIRE(result.get_global_rank() == 0); +} + +TEST_M(triangle_counting_gpu_test, "GPU: Null graph - local_and_global task") { + dal::preview::undirected_adjacency_vector_graph<> null_graph; + auto q = get_queue(); + + std::allocator alloc; + const auto tc_desc = dal::preview::triangle_counting::descriptor< + float, + dal::preview::triangle_counting::method::ordered_count, + dal::preview::triangle_counting::task::local_and_global, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, null_graph); + const auto& local_triangles = + static_cast(result.get_ranks()); + REQUIRE(local_triangles.has_data() == false); + REQUIRE(result.get_global_rank() == 0); +} + +TEST_M(triangle_counting_gpu_test, "GPU: topology_to_device round-trip") { + const auto g = create_graph(); + auto q = get_queue(); + + // Access the internal topology + const auto& topo = oneapi::dal::detail::get_impl(g).get_topology(); + + // Transfer topology to device + auto device_topo = + dal::preview::detail::topology_to_device(q, topo); + + REQUIRE(device_topo.get_vertex_count() == 5); + REQUIRE(device_topo.get_edge_count() == 10); + REQUIRE(device_topo.get_rows() != nullptr); + REQUIRE(device_topo.get_cols() != nullptr); + + // Transfer back to host and verify + auto host_topo = dal::preview::detail::topology_to_host(device_topo); + + REQUIRE(host_topo.get_vertex_count() == 5); + REQUIRE(host_topo.get_edge_count() == 10); + + // Verify row offsets match original + for (std::int64_t i = 0; i <= 5; ++i) { + REQUIRE(host_topo._rows[i] == topo._rows[i]); + } + + // Verify column indices match original + for (std::int64_t i = 0; i < 20; ++i) { + REQUIRE(host_topo._cols[i] == topo._cols[i]); + } +} + +TEST_M(triangle_counting_gpu_test, "GPU: Empty topology round-trip") { + auto q = get_queue(); + + dal::preview::detail::topology empty_topo; + + auto device_topo = + dal::preview::detail::topology_to_device(q, empty_topo); + + REQUIRE(device_topo.get_vertex_count() == 0); + REQUIRE(device_topo.get_edge_count() == 0); + + auto host_topo = dal::preview::detail::topology_to_host(device_topo); + + REQUIRE(host_topo.get_vertex_count() == 0); + REQUIRE(host_topo.get_edge_count() == 0); +} + +} // namespace oneapi::dal::algo::triangle_counting::gpu::test diff --git a/cpp/oneapi/dal/detail/vertex_ranking_ops.hpp b/cpp/oneapi/dal/detail/vertex_ranking_ops.hpp index d034d9c08e8..9c30b50e886 100644 --- a/cpp/oneapi/dal/detail/vertex_ranking_ops.hpp +++ b/cpp/oneapi/dal/detail/vertex_ranking_ops.hpp @@ -34,10 +34,32 @@ auto vertex_ranking_dispatch_by_input(const Descriptor &desc, Head &&head, Tail return ops_t()(dal::detail::host_policy::get_default(), desc, input); } +#ifdef ONEDAL_DATA_PARALLEL +template +auto vertex_ranking_dispatch_by_input(const dal::detail::data_parallel_policy &policy, + const Descriptor &desc, + Head &&head, + Tail &&...tail) { + using tag_t = typename Descriptor::tag_t; + using ops_t = vertex_ranking_ops, tag_t>; + using input_t = typename ops_t::input_t; + + auto input = input_t{ std::forward(head), std::forward(tail)... }; + return ops_t()(policy, desc, input); +} +#endif + template auto vertex_ranking_dispatch(Head &&head, Tail &&...tail) { return vertex_ranking_dispatch_by_input(std::forward(head), std::forward(tail)...); } +#ifdef ONEDAL_DATA_PARALLEL +template +auto vertex_ranking_dispatch(const dal::detail::data_parallel_policy &policy, Tail &&...tail) { + return vertex_ranking_dispatch_by_input(policy, std::forward(tail)...); +} +#endif + } // namespace detail } // namespace oneapi::dal::preview diff --git a/cpp/oneapi/dal/graph/detail/csr_topology.hpp b/cpp/oneapi/dal/graph/detail/csr_topology.hpp index 169635fc675..8606a9963ed 100755 --- a/cpp/oneapi/dal/graph/detail/csr_topology.hpp +++ b/cpp/oneapi/dal/graph/detail/csr_topology.hpp @@ -21,6 +21,10 @@ #include "oneapi/dal/graph/common.hpp" #include "oneapi/dal/graph/detail/container.hpp" +#ifdef ONEDAL_DATA_PARALLEL +#include +#endif + namespace oneapi::dal::preview::detail { template @@ -124,14 +128,58 @@ class topology { -> const_vertex_edge_iterator { return _cols_ptr + _rows[vertex + 1]; } + +#ifdef ONEDAL_DATA_PARALLEL + inline void set_topology(const sycl::queue& queue, + vertex_size_type vertex_count, + edge_size_type edge_count, + const edge_type* device_offsets, + const vertex_type* device_neighbors, + edge_size_type neighbors_count) { + _vertex_count = vertex_count; + _edge_count = edge_count; + _rows = edge_set::wrap(queue, device_offsets, vertex_count + 1); + _cols = vertex_set::wrap(queue, device_neighbors, neighbors_count); + _rows_ptr = _rows.get_data(); + _cols_ptr = _cols.get_data(); + _degrees_ptr = nullptr; + } + + topology to_device(sycl::queue& queue) const { + topology result; + result._vertex_count = _vertex_count; + result._edge_count = _edge_count; + + const auto rows_count = _vertex_count + 1; + const auto cols_count = _cols.get_count(); + + auto device_rows = edge_set::empty(queue, rows_count, sycl::usm::alloc::device); + auto device_cols = vertex_set::empty(queue, cols_count, sycl::usm::alloc::device); + + auto e1 = queue.memcpy(device_rows.get_mutable_data(), _rows.get_data(), + rows_count * sizeof(edge_type)); + auto e2 = queue.memcpy(device_cols.get_mutable_data(), _cols.get_data(), + cols_count * sizeof(vertex_type)); + e1.wait_and_throw(); + e2.wait_and_throw(); + + result._rows = device_rows; + result._cols = device_cols; + result._rows_ptr = result._rows.get_data(); + result._cols_ptr = result._cols.get_data(); + result._degrees_ptr = nullptr; + return result; + } +#endif + vertex_set _cols; vertex_set _degrees; edge_set _rows; vertex_edge_set _rows_vertex; - const vertex_type* _cols_ptr; - const vertex_type* _degrees_ptr; - const edge_type* _rows_ptr; + const vertex_type* _cols_ptr = nullptr; + const vertex_type* _degrees_ptr = nullptr; + const edge_type* _rows_ptr = nullptr; std::int64_t _vertex_count = 0; std::int64_t _edge_count = 0; diff --git a/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp b/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp new file mode 100644 index 00000000000..2ad2770b1ba --- /dev/null +++ b/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp @@ -0,0 +1,265 @@ +/******************************************************************************* +* 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 + +#include "oneapi/dal/array.hpp" +#include "oneapi/dal/graph/detail/csr_topology.hpp" + +namespace oneapi::dal::preview::detail { + +/// A device-resident CSR topology that holds row offsets, column indices, +/// and optionally edge weights as dal::array objects in device USM memory. +/// +/// Row offsets are stored as int64 (matching the host topology) and column +/// indices as IndexType (typically int32). Edge weights are optional — +/// set WeightType to void (default) for unweighted graphs. +/// +/// Construct via \ref topology_to_device() or \ref topology_to_host(). +template +class device_csr_topology { +public: + using index_type = IndexType; + using weight_type = WeightType; + + device_csr_topology() = default; + + /// Construct an unweighted device topology. + device_csr_topology(dal::array device_rows, + dal::array device_cols, + std::int64_t vertex_count, + std::int64_t edge_count) + : rows_(std::move(device_rows)), + cols_(std::move(device_cols)), + vertex_count_(vertex_count), + edge_count_(edge_count) {} + + /// Construct a weighted device topology. + device_csr_topology(dal::array device_rows, + dal::array device_cols, + dal::array device_weights, + std::int64_t vertex_count, + std::int64_t edge_count) + : rows_(std::move(device_rows)), + cols_(std::move(device_cols)), + weights_(std::move(device_weights)), + vertex_count_(vertex_count), + edge_count_(edge_count) {} + + /// Pointer to device-resident row offsets (vertex_count + 1 entries). + const std::int64_t* get_rows() const { + return rows_.get_data(); + } + + /// Pointer to device-resident column indices (2 * edge_count entries). + const IndexType* get_cols() const { + return cols_.get_data(); + } + + /// Pointer to device-resident edge weights (2 * edge_count entries), + /// or nullptr if the graph is unweighted. + const WeightType* get_weights() const { + return weights_.get_count() > 0 ? weights_.get_data() : nullptr; + } + + std::int64_t get_vertex_count() const { + return vertex_count_; + } + + std::int64_t get_edge_count() const { + return edge_count_; + } + + /// Returns the underlying device array for row offsets. + const dal::array& get_rows_array() const { + return rows_; + } + + /// Returns the underlying device array for column indices. + const dal::array& get_cols_array() const { + return cols_; + } + + /// Returns the underlying device array for edge weights. + const dal::array& get_weights_array() const { + return weights_; + } + +private: + dal::array rows_; + dal::array cols_; + dal::array weights_; + std::int64_t vertex_count_ = 0; + std::int64_t edge_count_ = 0; +}; + +/// Specialization for unweighted graphs (WeightType = void). +/// This preserves full backward compatibility with existing code. +template +class device_csr_topology { +public: + using index_type = IndexType; + using weight_type = void; + + device_csr_topology() = default; + + device_csr_topology(dal::array device_rows, + dal::array device_cols, + std::int64_t vertex_count, + std::int64_t edge_count) + : rows_(std::move(device_rows)), + cols_(std::move(device_cols)), + vertex_count_(vertex_count), + edge_count_(edge_count) {} + + /// Pointer to device-resident row offsets (vertex_count + 1 entries). + const std::int64_t* get_rows() const { + return rows_.get_data(); + } + + /// Pointer to device-resident column indices (2 * edge_count entries). + const IndexType* get_cols() const { + return cols_.get_data(); + } + + std::int64_t get_vertex_count() const { + return vertex_count_; + } + + std::int64_t get_edge_count() const { + return edge_count_; + } + + /// Returns the underlying device array for row offsets. + const dal::array& get_rows_array() const { + return rows_; + } + + /// Returns the underlying device array for column indices. + const dal::array& get_cols_array() const { + return cols_; + } + +private: + dal::array rows_; + dal::array cols_; + std::int64_t vertex_count_ = 0; + std::int64_t edge_count_ = 0; +}; + +/// Transfers a host topology to device memory. +/// Row offsets are kept as int64, column indices as IndexType. +/// +/// @tparam IndexType The index type for column indices (default int32) +/// @param queue SYCL queue identifying the target device +/// @param host_topo Host-resident CSR topology +/// @return A device_csr_topology with arrays in device USM memory +template +device_csr_topology topology_to_device(sycl::queue& queue, + const topology& host_topo) { + const auto vertex_count = host_topo.get_vertex_count(); + const auto edge_count = host_topo.get_edge_count(); + + if (vertex_count == 0) { + return device_csr_topology(); + } + + const std::int64_t rows_count = vertex_count + 1; + const std::int64_t cols_count = host_topo._cols.get_count(); + + // Transfer column indices (IndexType -> IndexType) to device + dal::array device_cols; + if (cols_count > 0) { + device_cols = + dal::array::empty(queue, cols_count, sycl::usm::alloc::device); + queue.memcpy(device_cols.get_mutable_data(), + host_topo._cols.get_data(), + cols_count * sizeof(IndexType)) + .wait_and_throw(); + } + + // Transfer row offsets (int64 -> int64) to device + auto device_rows = + dal::array::empty(queue, rows_count, sycl::usm::alloc::device); + queue.memcpy(device_rows.get_mutable_data(), + host_topo._rows.get_data(), + rows_count * sizeof(std::int64_t)) + .wait_and_throw(); + + return device_csr_topology(std::move(device_rows), + std::move(device_cols), + vertex_count, + edge_count); +} + +/// Transfers a device_csr_topology back to a host topology. +/// +/// @tparam IndexType The index type for column indices +/// @param device_topo Device-resident CSR topology +/// @return A host topology with arrays in host memory +template +topology topology_to_host(const device_csr_topology& device_topo) { + const auto vertex_count = device_topo.get_vertex_count(); + const auto edge_count = device_topo.get_edge_count(); + + if (vertex_count == 0) { + return topology(); + } + + const std::int64_t rows_count = vertex_count + 1; + const std::int64_t cols_count = device_topo.get_cols_array().get_count(); + + auto host_cols = dal::array::empty(cols_count); + auto host_rows = dal::array::empty(rows_count); + + // Retrieve the queue from the device arrays + auto q = device_topo.get_cols_array().get_queue().value(); + q.memcpy(host_cols.get_mutable_data(), + device_topo.get_cols(), + cols_count * sizeof(IndexType)) + .wait_and_throw(); + q.memcpy(host_rows.get_mutable_data(), + device_topo.get_rows(), + rows_count * sizeof(std::int64_t)) + .wait_and_throw(); + + // Build degrees from row offsets + auto host_degrees = dal::array::empty(vertex_count); + auto* deg = host_degrees.get_mutable_data(); + const auto* rows_data = host_rows.get_data(); + for (std::int64_t i = 0; i < vertex_count; ++i) { + deg[i] = static_cast(rows_data[i + 1] - rows_data[i]); + } + + topology result; + result._vertex_count = vertex_count; + result._edge_count = edge_count; + result._rows = std::move(host_rows); + result._cols = std::move(host_cols); + result._degrees = std::move(host_degrees); + result._rows_ptr = result._rows.get_data(); + result._cols_ptr = result._cols.get_data(); + result._degrees_ptr = result._degrees.get_data(); + return result; +} + +} // namespace oneapi::dal::preview::detail + +#endif // ONEDAL_DATA_PARALLEL diff --git a/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp b/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp index 3ec705a748f..70f9d89a36e 100644 --- a/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp +++ b/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp @@ -108,6 +108,43 @@ class ONEDAL_EXPORT undirected_adjacency_vector_graph_impl { return _topology; } +#ifdef ONEDAL_DATA_PARALLEL + inline void to_device(sycl::queue& queue) { + const auto* ptr = _topology._rows.get_data(); + if (ptr != nullptr) { + auto alloc_type = sycl::get_pointer_type(ptr, queue.get_context()); + if (alloc_type == sycl::usm::alloc::unknown || alloc_type == sycl::usm::alloc::host) { + _topology = _topology.to_device(queue); + } + } + + if constexpr (!std::is_same_v) { + transfer_array_to_device(queue, _vertex_values); + } + + if constexpr (!std::is_same_v) { + transfer_array_to_device(queue, _edge_values); + } + } + +private: + template + static void transfer_array_to_device(sycl::queue& queue, container& arr) { + const auto count = arr.get_count(); + if (count == 0) return; + const auto* src = arr.get_data(); + auto alloc_type = sycl::get_pointer_type(src, queue.get_context()); + if (alloc_type == sycl::usm::alloc::device || alloc_type == sycl::usm::alloc::shared) { + return; + } + auto device_arr = container::empty(queue, count, sycl::usm::alloc::device); + queue.memcpy(device_arr.get_mutable_data(), src, count * sizeof(T)).wait_and_throw(); + arr = device_arr; + } + +public: +#endif + inline vertex_values& get_vertex_values() { return _vertex_values; } diff --git a/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp b/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp index 01b823ea87c..b278382edb8 100644 --- a/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp +++ b/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp @@ -61,6 +61,13 @@ class ONEDAL_EXPORT undirected_adjacency_vector_graph { /// Swaps the implementation of this object and another one undirected_adjacency_vector_graph &operator=(undirected_adjacency_vector_graph &&other); +#ifdef ONEDAL_DATA_PARALLEL + /// Transfers graph data to device memory associated with the given queue + void to_device(sycl::queue& queue) { + dal::detail::pimpl_accessor{}.get_pimpl(*this)->to_device(queue); + } +#endif + private: using pimpl = dal::detail::pimpl::impl_type>; diff --git a/cpp/oneapi/dal/vertex_ranking.hpp b/cpp/oneapi/dal/vertex_ranking.hpp index d2c797d73bf..9d83cef4da0 100644 --- a/cpp/oneapi/dal/vertex_ranking.hpp +++ b/cpp/oneapi/dal/vertex_ranking.hpp @@ -30,4 +30,16 @@ auto vertex_ranking(Args &&...args) { return detail::vertex_ranking_dispatch(std::forward(args)...); } +#ifdef ONEDAL_DATA_PARALLEL +/// Overload that accepts a SYCL queue for GPU execution +/// +/// @param q SYCL queue specifying the target device +/// @param args Algorithm descriptor and input graph +template +auto vertex_ranking(sycl::queue& q, Args &&...args) { + const auto policy = dal::detail::data_parallel_policy{ q }; + return detail::vertex_ranking_dispatch(policy, std::forward(args)...); +} +#endif + } // namespace oneapi::dal::preview diff --git a/examples/oneapi/cpp/source/triangle_counting/triangle_counting_batch.cpp b/examples/oneapi/cpp/source/triangle_counting/triangle_counting_batch.cpp index 42e365df8e3..3ff621b60ef 100644 --- a/examples/oneapi/cpp/source/triangle_counting/triangle_counting_batch.cpp +++ b/examples/oneapi/cpp/source/triangle_counting/triangle_counting_batch.cpp @@ -14,6 +14,7 @@ * limitations under the License. *******************************************************************************/ +#include #include #include "example_util/utils.hpp" @@ -34,7 +35,11 @@ int main(int argc, char** argv) { const auto tc_desc = descriptor(); // compute local and global triangles + const auto t1 = std::chrono::steady_clock::now(); const auto result_vertex_ranking = dal::preview::vertex_ranking(tc_desc, graph); + const auto t2 = std::chrono::steady_clock::now(); + const auto dt = std::chrono::duration_cast(t2 - t1).count(); + std::cout << "Triangle counting compute time: " << dt << " ms" << std::endl; // extract the result std::cout << "Global triangles: " << result_vertex_ranking.get_global_rank() << std::endl; diff --git a/examples/oneapi/dpc/BUILD b/examples/oneapi/dpc/BUILD index ad28e0bbf6f..42519af0c62 100644 --- a/examples/oneapi/dpc/BUILD +++ b/examples/oneapi/dpc/BUILD @@ -68,6 +68,7 @@ dal_algo_example_suite( "pca", "rbf_kernel", "svm", + "triangle_counting", ], compile_as = [ "dpc++" ], data = _DATA_DEPS, diff --git a/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp b/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp new file mode 100644 index 00000000000..4f7ed528949 --- /dev/null +++ b/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp @@ -0,0 +1,67 @@ +/******************************************************************************* +* 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. +*******************************************************************************/ + +#include +#include +#include +#include + +#ifndef ONEDAL_DATA_PARALLEL +#define ONEDAL_DATA_PARALLEL +#endif + +#include "oneapi/dal/algo/triangle_counting.hpp" +#include "oneapi/dal/graph/undirected_adjacency_vector_graph.hpp" +#include "oneapi/dal/io/csv.hpp" + +#include "example_util/utils.hpp" + +namespace dal = oneapi::dal; +using namespace dal::preview::triangle_counting; + +void run(sycl::queue& q) { + const auto filename = get_data_path("data/graph.csv"); + + using graph_t = dal::preview::undirected_adjacency_vector_graph<>; + auto graph = dal::read(dal::csv::data_source{ filename }); + + graph.to_device(q); + + const auto tc_desc = descriptor(); + + const auto result = dal::preview::vertex_ranking(q, tc_desc, graph); + + std::cout << "Global triangles: " << result.get_global_rank() << std::endl; + std::cout << "Local triangles:" << std::endl; + + auto local_triangles_table = result.get_ranks(); + const auto& local_triangles = static_cast(local_triangles_table); + const auto local_triangles_data = local_triangles.get_data(); + for (auto i = 0; i < local_triangles_table.get_row_count(); i++) { + std::cout << i << ":\t" << local_triangles_data[i] << std::endl; + } +} + +int main(int argc, char const* argv[]) { + for (auto d : list_devices()) { + std::cout << "Running on " << d.get_platform().get_info() + << ", " << d.get_info() << "\n" + << std::endl; + auto q = sycl::queue{ d }; + run(q); + } + return 0; +} From 95fe2ce9dd5a7d3e8ea46a83607b41cd290f9258 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Sun, 10 May 2026 10:31:56 -0700 Subject: [PATCH 63/69] CI fix --- .../backend/gpu/CMakeLists.txt | 16 ++ .../backend/gpu/triangle_counting.hpp | 16 ++ .../vertex_ranking_default_kernel_gpu_dpc.cpp | 178 +++++++++--------- .../backend/gpu/vertex_ranking_kernel.hpp | 18 +- .../dal/algo/triangle_counting/common.hpp | 2 +- .../detail/select_kernel.hpp | 7 +- .../detail/select_kernel_dpc.cpp | 57 +++--- .../detail/vertex_ranking_ops.hpp | 10 +- .../test/triangle_counting_gpu_test.cpp | 20 +- cpp/oneapi/dal/graph/detail/csr_topology.hpp | 6 +- .../dal/graph/detail/device_csr_topology.hpp | 26 ++- ...undirected_adjacency_vector_graph_impl.hpp | 3 +- .../undirected_adjacency_vector_graph.hpp | 2 +- cpp/oneapi/dal/vertex_ranking.hpp | 2 +- .../triangle_counting_batch.cpp | 2 +- 15 files changed, 201 insertions(+), 164 deletions(-) mode change 100755 => 100644 cpp/oneapi/dal/graph/detail/csr_topology.hpp diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt index a7f81fe3901..7b397a68b92 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/CMakeLists.txt @@ -1,3 +1,19 @@ +#=============================================================================== +# Copyright 2026 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. +#=============================================================================== + set(ONEDAL_TRIANGLE_COUNTING_BACKEND_GPU_HEADERS ${CMAKE_CURRENT_LIST_DIR}/triangle_counting.hpp ${CMAKE_CURRENT_LIST_DIR}/vertex_ranking_kernel.hpp diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp index a6c9dae0b66..6533d2bddef 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/triangle_counting.hpp @@ -1,3 +1,19 @@ +/******************************************************************************* +* Copyright 2026 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/algo/triangle_counting/common.hpp" diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp index 51dda423f24..4f7eb7a11f6 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_default_kernel_gpu_dpc.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2020 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,77 +41,79 @@ std::int64_t* count_triangles_gpu(sycl::queue& queue, const Index* cols, std::int64_t vertex_count, std::int64_t edge_count) { - auto* local_triangles = - sycl::malloc_shared(vertex_count, queue); + auto* local_triangles = sycl::malloc_shared(vertex_count, queue); queue.memset(local_triangles, 0, vertex_count * sizeof(std::int64_t)).wait_and_throw(); // Parallel kernel: each work-item processes one vertex - queue.submit([&](sycl::handler& cgh) { - const std::int64_t* d_rows = rows; - const Index* d_cols = cols; - std::int64_t* d_triangles = local_triangles; - const std::int64_t vc = vertex_count; - - cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { - const std::int64_t u = idx[0]; - const std::int64_t u_start = d_rows[u]; - const std::int64_t u_end = d_rows[u + 1]; - - std::int64_t count = 0; - - // Iterate over each neighbor v of u where v > u - for (std::int64_t i = u_start; i < u_end; ++i) { - const std::int64_t v = d_cols[i]; - if (v <= u) continue; - - const std::int64_t v_start = d_rows[v]; - const std::int64_t v_end = d_rows[v + 1]; - - // Merge-based intersection of neighbors of u and v - std::int64_t ui = u_start; - std::int64_t vi = v_start; - while (ui < u_end && vi < v_end) { - const std::int64_t nu = d_cols[ui]; - const std::int64_t nv = d_cols[vi]; - if (nu == nv) { - // Only count if common neighbor w > v to avoid - // triple-counting the same triangle - if (nu > v) { - // Found a triangle (u, v, nu) with u < v < nu - count++; - // Atomically increment counts for v and the common neighbor - sycl::atomic_ref( - d_triangles[v]) - .fetch_add(1); - sycl::atomic_ref( - d_triangles[nu]) - .fetch_add(1); + queue + .submit([&](sycl::handler& cgh) { + const std::int64_t* d_rows = rows; + const Index* d_cols = cols; + std::int64_t* d_triangles = local_triangles; + const std::int64_t vc = vertex_count; + + cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { + const std::int64_t u = idx[0]; + const std::int64_t u_start = d_rows[u]; + const std::int64_t u_end = d_rows[u + 1]; + + std::int64_t count = 0; + + // Iterate over each neighbor v of u where v > u + for (std::int64_t i = u_start; i < u_end; ++i) { + const std::int64_t v = d_cols[i]; + if (v <= u) + continue; + + const std::int64_t v_start = d_rows[v]; + const std::int64_t v_end = d_rows[v + 1]; + + // Merge-based intersection of neighbors of u and v + std::int64_t ui = u_start; + std::int64_t vi = v_start; + while (ui < u_end && vi < v_end) { + const std::int64_t nu = d_cols[ui]; + const std::int64_t nv = d_cols[vi]; + if (nu == nv) { + // Only count if common neighbor w > v to avoid + // triple-counting the same triangle + if (nu > v) { + // Found a triangle (u, v, nu) with u < v < nu + count++; + // Atomically increment counts for v and the common neighbor + sycl::atomic_ref( + d_triangles[v]) + .fetch_add(1); + sycl::atomic_ref( + d_triangles[nu]) + .fetch_add(1); + } + ++ui; + ++vi; + } + else if (nu < nv) { + ++ui; + } + else { + ++vi; } - ++ui; - ++vi; - } - else if (nu < nv) { - ++ui; - } - else { - ++vi; } } - } - // Add the count for vertex u - sycl::atomic_ref(d_triangles[u]) - .fetch_add(count); - }); - }).wait_and_throw(); + // Add the count for vertex u + sycl::atomic_ref(d_triangles[u]) + .fetch_add(count); + }); + }) + .wait_and_throw(); return local_triangles; } @@ -128,19 +130,21 @@ std::int64_t sum_triangles_gpu(sycl::queue& queue, auto* sum_buf = sycl::malloc_shared(1, queue); sum_buf[0] = 0; - queue.submit([&](sycl::handler& cgh) { - const std::int64_t* d_triangles = local_triangles; - std::int64_t* d_sum = sum_buf; - const std::int64_t vc = vertex_count; - - cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { - sycl::atomic_ref(d_sum[0]) - .fetch_add(d_triangles[idx[0]]); - }); - }).wait_and_throw(); + queue + .submit([&](sycl::handler& cgh) { + const std::int64_t* d_triangles = local_triangles; + std::int64_t* d_sum = sum_buf; + const std::int64_t vc = vertex_count; + + cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { + sycl::atomic_ref(d_sum[0]) + .fetch_add(d_triangles[idx[0]]); + }); + }) + .wait_and_throw(); // Each triangle is counted 3 times (once per vertex) const std::int64_t result = sum_buf[0] / 3; @@ -163,21 +167,23 @@ vertex_ranking_result run_vertex_ranking_gpu(const dal::backend::context_g return vertex_ranking_result(); } - auto* local_triangles = - detail_gpu::count_triangles_gpu(queue, topology.rows, topology.cols, - vertex_count, edge_count); + auto* local_triangles = detail_gpu::count_triangles_gpu(queue, + topology.rows, + topology.cols, + vertex_count, + edge_count); vertex_ranking_result result; if constexpr (std::is_same_v || std::is_same_v) { - auto arr = array(queue, local_triangles, vertex_count, + auto arr = array(queue, + local_triangles, + vertex_count, [queue](std::int64_t* ptr) mutable { sycl::free(ptr, queue); }); - result.set_ranks(dal::detail::homogen_table_builder{} - .reset(arr, vertex_count, 1) - .build()); + result.set_ranks(dal::detail::homogen_table_builder{}.reset(arr, vertex_count, 1).build()); } if constexpr (std::is_same_v || diff --git a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp index e3e0b15da03..10eaa4ef23b 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/backend/gpu/vertex_ranking_kernel.hpp @@ -1,3 +1,19 @@ +/******************************************************************************* +* Copyright 2026 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 @@ -19,7 +35,7 @@ struct csr_topology_gpu_view { /// Creates a GPU view from a device_csr_topology (zero-copy, just extracts pointers). template csr_topology_gpu_view make_gpu_view( - const dal::preview::detail::device_csr_topology& device_topo) { + const dal::preview::detail::device_csr_topology& device_topo) { csr_topology_gpu_view view; view.rows = device_topo.get_rows(); view.cols = device_topo.get_cols(); diff --git a/cpp/oneapi/dal/algo/triangle_counting/common.hpp b/cpp/oneapi/dal/algo/triangle_counting/common.hpp index 2db9f54c9c6..e3782b3b5b9 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/common.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/common.hpp @@ -146,7 +146,7 @@ struct is_device_csr_topology : std::false_type {}; template struct is_device_csr_topology> - : std::true_type {}; + : std::true_type {}; template constexpr bool is_valid_graph = diff --git a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp index 84ed6c67fe8..12a2f8ba81e 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel.hpp @@ -76,10 +76,9 @@ struct backend_default using method_t = typename Descriptor::method_t; using allocator_t = typename Descriptor::allocator_t; - virtual vertex_ranking_result operator()( - const dal::detail::data_parallel_policy& ctx, - const Descriptor& descriptor, - const Topology& t); + virtual vertex_ranking_result operator()(const dal::detail::data_parallel_policy& ctx, + const Descriptor& descriptor, + const Topology& t); }; #endif diff --git a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp index 170e5ae41ec..2205be73cda 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp +++ b/cpp/oneapi/dal/algo/triangle_counting/detail/select_kernel_dpc.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2020 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,9 @@ namespace oneapi::dal::preview::triangle_counting::detail { template vertex_ranking_result backend_default::operator()( - const dal::detail::data_parallel_policy& ctx, - const Descriptor& descriptor, - const Topology& t) { + const dal::detail::data_parallel_policy &ctx, + const Descriptor &descriptor, + const Topology &t) { using float_t = typename Descriptor::float_t; using task_t = typename Descriptor::task_t; using method_t = typename Descriptor::method_t; @@ -47,10 +47,9 @@ backend_default::operat [&]() { // GPU path: delegate to GPU kernel dal::backend::context_gpu gpu_ctx{ ctx }; - return backend::vertex_ranking_kernel_gpu()( - gpu_ctx, - descriptor, - t); + return backend::vertex_ranking_kernel_gpu()(gpu_ctx, + descriptor, + t); }); } @@ -59,11 +58,12 @@ backend_default::operat template vertex_ranking_result -vertex_ranking_ops_dispatcher>::operator()( - const dal::detail::data_parallel_policy &policy, - const Descriptor &descriptor, - input_t &input) const { +vertex_ranking_ops_dispatcher>:: +operator()(const dal::detail::data_parallel_policy &policy, + const Descriptor &descriptor, + input_t &input) const { using float_t = typename Descriptor::float_t; using task_t = typename Descriptor::task_t; @@ -77,33 +77,22 @@ vertex_ranking_ops_dispatcher>; +using default_descriptor_local = + descriptor>; -using default_descriptor_global = descriptor< - float, - method::ordered_count, - task::global, - std::allocator>; +using default_descriptor_global = + descriptor>; -using default_descriptor_local_and_global = descriptor< - float, - method::ordered_count, - task::local_and_global, - std::allocator>; +using default_descriptor_local_and_global = + descriptor>; using default_topology = dal::preview::detail::topology; using device_topology = dal::preview::detail::device_csr_topology; -template struct ONEDAL_EXPORT backend_default; -template struct ONEDAL_EXPORT backend_default; +template struct ONEDAL_EXPORT + backend_default; +template struct ONEDAL_EXPORT + backend_default; template struct ONEDAL_EXPORT backend_default; diff --git a/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp b/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp index cef64393fb2..5c37ea52742 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp +++ b/cpp/oneapi/dal/algo/triangle_counting/detail/vertex_ranking_ops.hpp @@ -63,15 +63,15 @@ struct vertex_ranking_ops { /// Specialization for device_csr_topology: skips host-to-device transfer /// since the graph data is already on the device. template -struct vertex_ranking_ops_dispatcher> { using task_t = typename Descriptor::task_t; using input_t = vertex_ranking_input, task_t>; - vertex_ranking_result operator()( - const dal::detail::data_parallel_policy &policy, - const Descriptor &descriptor, - input_t &input) const; + vertex_ranking_result operator()(const dal::detail::data_parallel_policy &policy, + const Descriptor &descriptor, + input_t &input) const; }; #endif diff --git a/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp b/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp index c28cc2f0517..9705e4633b7 100644 --- a/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp +++ b/cpp/oneapi/dal/algo/triangle_counting/test/triangle_counting_gpu_test.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2020 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -226,8 +226,7 @@ class triangle_counting_gpu_test { const auto result = dal::preview::vertex_ranking(q, tc_desc, g); const auto local_triangles_table = result.get_ranks(); - const auto& local_triangles = - static_cast(local_triangles_table); + const auto& local_triangles = static_cast(local_triangles_table); const auto local_triangles_data = local_triangles.get_data(); REQUIRE(local_triangles_table.get_row_count() == vertex_count); @@ -260,8 +259,7 @@ class triangle_counting_gpu_test { const auto result = dal::preview::vertex_ranking(q, tc_desc, g); const auto local_triangles_table = result.get_ranks(); - const auto& local_triangles = - static_cast(local_triangles_table); + const auto& local_triangles = static_cast(local_triangles_table); const auto local_triangles_data = local_triangles.get_data(); REQUIRE(result.get_global_rank() == global_triangle_count); @@ -335,8 +333,7 @@ TEST_M(triangle_counting_gpu_test, "GPU: Null graph - local task") { std::allocator>(alloc); const auto result = dal::preview::vertex_ranking(q, tc_desc, null_graph); - const auto& local_triangles = - static_cast(result.get_ranks()); + const auto& local_triangles = static_cast(result.get_ranks()); REQUIRE(local_triangles.has_data() == false); } @@ -367,8 +364,7 @@ TEST_M(triangle_counting_gpu_test, "GPU: Null graph - local_and_global task") { std::allocator>(alloc); const auto result = dal::preview::vertex_ranking(q, tc_desc, null_graph); - const auto& local_triangles = - static_cast(result.get_ranks()); + const auto& local_triangles = static_cast(result.get_ranks()); REQUIRE(local_triangles.has_data() == false); REQUIRE(result.get_global_rank() == 0); } @@ -381,8 +377,7 @@ TEST_M(triangle_counting_gpu_test, "GPU: topology_to_device round-trip") { const auto& topo = oneapi::dal::detail::get_impl(g).get_topology(); // Transfer topology to device - auto device_topo = - dal::preview::detail::topology_to_device(q, topo); + auto device_topo = dal::preview::detail::topology_to_device(q, topo); REQUIRE(device_topo.get_vertex_count() == 5); REQUIRE(device_topo.get_edge_count() == 10); @@ -411,8 +406,7 @@ TEST_M(triangle_counting_gpu_test, "GPU: Empty topology round-trip") { dal::preview::detail::topology empty_topo; - auto device_topo = - dal::preview::detail::topology_to_device(q, empty_topo); + auto device_topo = dal::preview::detail::topology_to_device(q, empty_topo); REQUIRE(device_topo.get_vertex_count() == 0); REQUIRE(device_topo.get_edge_count() == 0); diff --git a/cpp/oneapi/dal/graph/detail/csr_topology.hpp b/cpp/oneapi/dal/graph/detail/csr_topology.hpp old mode 100755 new mode 100644 index 8606a9963ed..78fdf0d5d81 --- a/cpp/oneapi/dal/graph/detail/csr_topology.hpp +++ b/cpp/oneapi/dal/graph/detail/csr_topology.hpp @@ -156,9 +156,11 @@ class topology { auto device_rows = edge_set::empty(queue, rows_count, sycl::usm::alloc::device); auto device_cols = vertex_set::empty(queue, cols_count, sycl::usm::alloc::device); - auto e1 = queue.memcpy(device_rows.get_mutable_data(), _rows.get_data(), + auto e1 = queue.memcpy(device_rows.get_mutable_data(), + _rows.get_data(), rows_count * sizeof(edge_type)); - auto e2 = queue.memcpy(device_cols.get_mutable_data(), _cols.get_data(), + auto e2 = queue.memcpy(device_cols.get_mutable_data(), + _cols.get_data(), cols_count * sizeof(vertex_type)); e1.wait_and_throw(); e2.wait_and_throw(); diff --git a/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp b/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp index 2ad2770b1ba..9dc3f9d0fc7 100644 --- a/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp +++ b/cpp/oneapi/dal/graph/detail/device_csr_topology.hpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2020 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -187,20 +187,20 @@ device_csr_topology topology_to_device(sycl::queue& queue, // Transfer column indices (IndexType -> IndexType) to device dal::array device_cols; if (cols_count > 0) { - device_cols = - dal::array::empty(queue, cols_count, sycl::usm::alloc::device); - queue.memcpy(device_cols.get_mutable_data(), - host_topo._cols.get_data(), - cols_count * sizeof(IndexType)) + device_cols = dal::array::empty(queue, cols_count, sycl::usm::alloc::device); + queue + .memcpy(device_cols.get_mutable_data(), + host_topo._cols.get_data(), + cols_count * sizeof(IndexType)) .wait_and_throw(); } // Transfer row offsets (int64 -> int64) to device - auto device_rows = - dal::array::empty(queue, rows_count, sycl::usm::alloc::device); - queue.memcpy(device_rows.get_mutable_data(), - host_topo._rows.get_data(), - rows_count * sizeof(std::int64_t)) + auto device_rows = dal::array::empty(queue, rows_count, sycl::usm::alloc::device); + queue + .memcpy(device_rows.get_mutable_data(), + host_topo._rows.get_data(), + rows_count * sizeof(std::int64_t)) .wait_and_throw(); return device_csr_topology(std::move(device_rows), @@ -231,9 +231,7 @@ topology topology_to_host(const device_csr_topology& devic // Retrieve the queue from the device arrays auto q = device_topo.get_cols_array().get_queue().value(); - q.memcpy(host_cols.get_mutable_data(), - device_topo.get_cols(), - cols_count * sizeof(IndexType)) + q.memcpy(host_cols.get_mutable_data(), device_topo.get_cols(), cols_count * sizeof(IndexType)) .wait_and_throw(); q.memcpy(host_rows.get_mutable_data(), device_topo.get_rows(), diff --git a/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp b/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp index 70f9d89a36e..f5cbd79d135 100644 --- a/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp +++ b/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp @@ -131,7 +131,8 @@ class ONEDAL_EXPORT undirected_adjacency_vector_graph_impl { template static void transfer_array_to_device(sycl::queue& queue, container& arr) { const auto count = arr.get_count(); - if (count == 0) return; + if (count == 0) + return; const auto* src = arr.get_data(); auto alloc_type = sycl::get_pointer_type(src, queue.get_context()); if (alloc_type == sycl::usm::alloc::device || alloc_type == sycl::usm::alloc::shared) { diff --git a/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp b/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp index b278382edb8..d8486badb08 100644 --- a/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp +++ b/cpp/oneapi/dal/graph/undirected_adjacency_vector_graph.hpp @@ -63,7 +63,7 @@ class ONEDAL_EXPORT undirected_adjacency_vector_graph { #ifdef ONEDAL_DATA_PARALLEL /// Transfers graph data to device memory associated with the given queue - void to_device(sycl::queue& queue) { + void to_device(sycl::queue &queue) { dal::detail::pimpl_accessor{}.get_pimpl(*this)->to_device(queue); } #endif diff --git a/cpp/oneapi/dal/vertex_ranking.hpp b/cpp/oneapi/dal/vertex_ranking.hpp index 9d83cef4da0..2b2e2613c98 100644 --- a/cpp/oneapi/dal/vertex_ranking.hpp +++ b/cpp/oneapi/dal/vertex_ranking.hpp @@ -36,7 +36,7 @@ auto vertex_ranking(Args &&...args) { /// @param q SYCL queue specifying the target device /// @param args Algorithm descriptor and input graph template -auto vertex_ranking(sycl::queue& q, Args &&...args) { +auto vertex_ranking(sycl::queue &q, Args &&...args) { const auto policy = dal::detail::data_parallel_policy{ q }; return detail::vertex_ranking_dispatch(policy, std::forward(args)...); } diff --git a/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp b/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp index 4f7ed528949..e88dbf2291a 100644 --- a/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp +++ b/examples/oneapi/dpc/source/triangle_counting/triangle_counting_batch.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2020 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 53bf004d26919211eb91fc3ea4e83fa4199bb1dc Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 5 May 2026 18:57:38 -0700 Subject: [PATCH 64/69] CC gpu --- .../dal/algo/connected_components/BUILD | 19 +- .../backend/gpu/CMakeLists.txt | 5 + .../backend/gpu/connected_components.hpp | 32 + ...ex_partitioning_default_kernel_gpu_dpc.cpp | 298 +++ .../gpu/vertex_partitioning_kernel.hpp | 52 + .../detail/select_kernel.hpp | 40 +- .../detail/select_kernel_dpc.cpp | 64 + .../vertex_partitioning_default_kernel.hpp | 21 + .../detail/vertex_partitioning_ops.hpp | 10 +- .../test/connected_components_gpu_test.cpp | 278 +++ .../dal/detail/vertex_partitioning_ops.hpp | 20 + cpp/oneapi/dal/graph/detail/csr_topology.hpp | 24 +- ...undirected_adjacency_vector_graph_impl.hpp | 2 +- cpp/oneapi/dal/vertex_partitioning.hpp | 8 + examples/oneapi/dpc/BUILD | 1 + .../connected_components_batch | Bin 0 -> 511008 bytes .../intel_intel64_so/triangle_counting_batch | Bin 0 -> 515016 bytes examples/oneapi/dpc/build/Makefile | 1944 +++++++++++++++++ examples/oneapi/dpc/build/cmake_install.cmake | 54 + .../connected_components_batch.cpp | 58 + 20 files changed, 2913 insertions(+), 17 deletions(-) create mode 100644 cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt create mode 100644 cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp create mode 100644 cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp create mode 100644 cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp create mode 100644 cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp create mode 100644 cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp create mode 100755 examples/oneapi/dpc/_cmake_results/intel_intel64_so/connected_components_batch create mode 100755 examples/oneapi/dpc/_cmake_results/intel_intel64_so/triangle_counting_batch create mode 100644 examples/oneapi/dpc/build/Makefile create mode 100644 examples/oneapi/dpc/build/cmake_install.cmake create mode 100644 examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp diff --git a/cpp/oneapi/dal/algo/connected_components/BUILD b/cpp/oneapi/dal/algo/connected_components/BUILD index 8e7d9b35a5c..3ecf4190d9b 100755 --- a/cpp/oneapi/dal/algo/connected_components/BUILD +++ b/cpp/oneapi/dal/algo/connected_components/BUILD @@ -10,14 +10,31 @@ dal_module( dal_deps = [ "@onedal//cpp/oneapi/dal:core", "@onedal//cpp/oneapi/dal/backend/primitives:rng", - ] + "@onedal//cpp/oneapi/dal/backend/primitives:frontier", + ], ) dal_test_suite( name = "tests", + tests = [], framework = "catch2", srcs = glob([ "test/*.cpp", + ], + exclude = [ + "test/*_gpu_test.cpp", + ]), + dal_deps = [ + ":connected_components", + ], +) + +dal_test_suite( + name = "gpu_tests", + framework = "catch2", + compile_as = [ "dpc++" ], + srcs = glob([ + "test/*_gpu_test.cpp", ]), dal_deps = [ ":connected_components", diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt b/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt new file mode 100644 index 00000000000..105230f978f --- /dev/null +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt @@ -0,0 +1,5 @@ +set(ONEDAL_CONNECTED_COMPONENTS_BACKEND_GPU_HEADERS + ${CMAKE_CURRENT_LIST_DIR}/connected_components.hpp + ${CMAKE_CURRENT_LIST_DIR}/vertex_partitioning_kernel.hpp + PARENT_SCOPE +) diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp b/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp new file mode 100644 index 00000000000..1d8fb2ed78d --- /dev/null +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp @@ -0,0 +1,32 @@ +/******************************************************************************* +* 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 "oneapi/dal/algo/connected_components/common.hpp" +#include "oneapi/dal/algo/connected_components/vertex_partitioning_types.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" + +namespace oneapi::dal::preview::connected_components::backend { + +template +struct vertex_partitioning_kernel_gpu { + vertex_partitioning_result operator()(const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const Topology& topology) const; +}; + +} // namespace oneapi::dal::preview::connected_components::backend diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp new file mode 100644 index 00000000000..aa686630e46 --- /dev/null +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp @@ -0,0 +1,298 @@ +/******************************************************************************* +* 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 + +#include "oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp" +#include "oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" +#include "oneapi/dal/table/detail/table_builder.hpp" +#include "oneapi/dal/backend/primitives/frontier.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" + +namespace oneapi::dal::preview::connected_components::backend { + +namespace fp = oneapi::dal::preview::backend::primitives; + +namespace detail_gpu { + +template +struct mixed_csr_graph_view { + std::uint64_t _num_nodes; + OffsetT* _row_ptr; + VertexT* _col_indices; + + struct neighbor_iterator_t { + neighbor_iterator_t(const VertexT* start_ptr, VertexT* ptr) + : _ptr(ptr), + _start_ptr(start_ptr) {} + + SYCL_EXTERNAL bool operator==(const neighbor_iterator_t& other) const { + return _ptr == other._ptr; + } + + SYCL_EXTERNAL bool operator!=(const neighbor_iterator_t& other) const { + return _ptr != other._ptr; + } + + SYCL_EXTERNAL neighbor_iterator_t& operator++() { + ++_ptr; + return *this; + } + + SYCL_EXTERNAL neighbor_iterator_t operator+(int n) const { + neighbor_iterator_t tmp = *this; + tmp._ptr += n; + return tmp; + } + + SYCL_EXTERNAL VertexT operator*() const { + return *_ptr; + } + + SYCL_EXTERNAL std::uint32_t get_index() const { + return static_cast(_ptr - _start_ptr); + } + + VertexT* _ptr; + const VertexT* _start_ptr; + }; + + SYCL_EXTERNAL inline std::uint32_t get_degree(const std::uint32_t vertex) const { + return static_cast(_row_ptr[vertex + 1] - _row_ptr[vertex]); + } + + SYCL_EXTERNAL inline std::uint32_t get_weight(const std::uint64_t) const { + return 0; + } + + SYCL_EXTERNAL inline neighbor_iterator_t begin(std::uint32_t vertex) const { + return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex]); + } + + SYCL_EXTERNAL inline neighbor_iterator_t end(std::uint32_t vertex) const { + return neighbor_iterator_t(_col_indices, _col_indices + _row_ptr[vertex + 1]); + } +}; + +template +class csr_graph_device_wrapper { +public: + csr_graph_device_wrapper(sycl::queue& queue, + std::uint64_t vertex_count, + const OffsetT* rows, + const VertexT* cols) + : _queue(queue), + _num_nodes(vertex_count), + _rows(const_cast(rows)), + _cols(const_cast(cols)) {} + + mixed_csr_graph_view get_device_view() const { + return { _num_nodes, _rows, _cols }; + } + + sycl::queue& get_queue() const { + return _queue; + } + + std::uint64_t get_vertex_count() const { + return _num_nodes; + } + +private: + sycl::queue& _queue; + std::uint64_t _num_nodes; + OffsetT* _rows; + VertexT* _cols; +}; + +template +std::int32_t* compute_components_gpu(sycl::queue& queue, + const std::int64_t* rows, + const Index* cols, + std::int64_t vertex_count, + std::int64_t edge_count, + std::int64_t& component_count) { + auto* labels = sycl::malloc_shared(vertex_count, queue); + + queue + .submit([&](sycl::handler& cgh) { + std::int32_t* d_labels = labels; + const std::int64_t vc = vertex_count; + cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { + d_labels[idx[0]] = static_cast(idx[0]); + }); + }) + .wait_and_throw(); + + if (edge_count == 0) { + component_count = vertex_count; + return labels; + } + + csr_graph_device_wrapper graph( + queue, + static_cast(vertex_count), + rows, + cols); + + fp::frontier in_frontier(queue, vertex_count, sycl::usm::alloc::device); + fp::frontier out_frontier(queue, vertex_count, sycl::usm::alloc::device); + + { + auto fv = in_frontier.get_device_view(); + const std::int64_t vc = vertex_count; + queue + .submit([&](sycl::handler& cgh) { + cgh.parallel_for(sycl::range<1>(vc), [=](sycl::id<1> idx) { + fv.insert(static_cast(idx[0])); + }); + }) + .wait_and_throw(); + } + + std::int32_t* d_labels = labels; + while (!in_frontier.empty()) { + auto e = fp::advance( + graph, + in_frontier, + out_frontier, + [=](auto src, auto dst, auto edge, auto weight) -> bool { + const std::int32_t label_src = d_labels[src]; + const std::int32_t label_dst = d_labels[dst]; + + if (label_src < label_dst) { + std::int32_t old_val = + sycl::atomic_ref( + d_labels[dst]) + .fetch_min(label_src); + return label_src < old_val; + } + return false; + }); + e.wait_and_throw(); + + fp::swap_frontiers(in_frontier, out_frontier); + out_frontier.clear(); + } + + auto* ordered_labels = sycl::malloc_shared(vertex_count, queue); + auto* comp_count_ptr = sycl::malloc_shared(1, queue); + comp_count_ptr[0] = 0; + + queue.memset(ordered_labels, 0xFF, vertex_count * sizeof(std::int32_t)).wait_and_throw(); + + for (std::int64_t u = 0; u < vertex_count; ++u) { + std::int32_t root = labels[u]; + if (ordered_labels[root] < 0) { + ordered_labels[root] = comp_count_ptr[0]; + comp_count_ptr[0]++; + } + labels[u] = ordered_labels[root]; + } + + component_count = comp_count_ptr[0]; + + sycl::free(ordered_labels, queue); + sycl::free(comp_count_ptr, queue); + + return labels; +} + +} // namespace detail_gpu + +template +vertex_partitioning_result run_vertex_partitioning_gpu( + const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const csr_topology_gpu_view& topology) { + auto& queue = ctx.get_queue(); + + const auto vertex_count = topology.vertex_count; + const auto edge_count = topology.edge_count; + + if (vertex_count == 0) { + return vertex_partitioning_result(); + } + + std::int64_t component_count = 0; + auto* labels = detail_gpu::compute_components_gpu(queue, + topology.rows, + topology.cols, + vertex_count, + edge_count, + component_count); + + auto labels_arr = + array(queue, labels, vertex_count, [queue](std::int32_t* ptr) mutable { + sycl::free(ptr, queue); + }); + + vertex_partitioning_result result; + result.set_labels(dal::detail::homogen_table_builder{} + .reset(labels_arr, vertex_count, 1) + .build()); + result.set_component_count(component_count); + + return result; +} + +template +vertex_partitioning_result vertex_partitioning_kernel_gpu::operator()( + const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const Topology& topology) const { + auto& queue = ctx.get_queue(); + const auto vertex_count = topology.get_vertex_count(); + + if (vertex_count == 0) { + return vertex_partitioning_result(); + } + + using namespace dal::preview::detail; + + const auto* rows_ptr = topology._rows.get_data(); + const auto alloc_type = sycl::get_pointer_type(rows_ptr, queue.get_context()); + + if (alloc_type == sycl::usm::alloc::device || alloc_type == sycl::usm::alloc::shared) { + csr_topology_gpu_view gpu_view; + gpu_view.rows = rows_ptr; + gpu_view.cols = topology._cols.get_data(); + gpu_view.vertex_count = vertex_count; + gpu_view.edge_count = topology.get_edge_count(); + return run_vertex_partitioning_gpu(ctx, desc, gpu_view); + } + + auto device_topo = topology_to_device(queue, topology); + const auto gpu_view = make_gpu_view(device_topo); + return run_vertex_partitioning_gpu(ctx, desc, gpu_view); +} + +// Explicit template instantiations +template struct vertex_partitioning_kernel_gpu>; + +template vertex_partitioning_result +run_vertex_partitioning_gpu( + const dal::backend::context_gpu&, + const detail::descriptor_base&, + const csr_topology_gpu_view&); + +} // namespace oneapi::dal::preview::connected_components::backend diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp new file mode 100644 index 00000000000..27c2d0da948 --- /dev/null +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp @@ -0,0 +1,52 @@ +/******************************************************************************* +* 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/algo/connected_components/vertex_partitioning_types.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" +#include "oneapi/dal/graph/detail/device_csr_topology.hpp" + +namespace oneapi::dal::preview::connected_components::backend { + +template +struct csr_topology_gpu_view { + const std::int64_t* rows = nullptr; + const Index* cols = nullptr; + std::int64_t vertex_count = 0; + std::int64_t edge_count = 0; +}; + +template +csr_topology_gpu_view make_gpu_view( + const dal::preview::detail::device_csr_topology& device_topo) { + csr_topology_gpu_view view; + view.rows = device_topo.get_rows(); + view.cols = device_topo.get_cols(); + view.vertex_count = device_topo.get_vertex_count(); + view.edge_count = device_topo.get_edge_count(); + return view; +} + +template +vertex_partitioning_result run_vertex_partitioning_gpu( + const dal::backend::context_gpu& ctx, + const detail::descriptor_base& desc, + const csr_topology_gpu_view& topology); + +} // namespace oneapi::dal::preview::connected_components::backend diff --git a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp index b77d431c303..999a2fc583b 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp @@ -21,9 +21,13 @@ #include "oneapi/dal/algo/connected_components/vertex_partitioning_types.hpp" #include "oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp" +#ifdef ONEDAL_DATA_PARALLEL +#include "oneapi/dal/detail/policy.hpp" +#endif + namespace oneapi::dal::preview::connected_components::detail { -template +template struct backend_base { using float_t = typename Descriptor::float_t; using task_t = typename Descriptor::task_t; @@ -32,12 +36,12 @@ struct backend_base { virtual vertex_partitioning_result operator()(const Policy& ctx, const Descriptor& descriptor, - const Graph& t) = 0; + const Topology& t) = 0; virtual ~backend_base() = default; }; -template -struct backend_default : public backend_base { +template +struct backend_default : public backend_base { static_assert(dal::detail::is_one_of_v, "Host policy only is supported."); @@ -48,8 +52,8 @@ struct backend_default : public backend_base { virtual vertex_partitioning_result operator()(const Policy& ctx, const Descriptor& descriptor, - const Graph& t) { - return vertex_partitioning_kernel_cpu()( + const Topology& t) { + return vertex_partitioning_kernel_cpu()( ctx, descriptor, descriptor.get_allocator(), @@ -57,10 +61,26 @@ struct backend_default : public backend_base { } }; -template -dal::detail::shared> get_backend(const Descriptor& desc, - const Graph& t) { - return std::make_shared>(); +#ifdef ONEDAL_DATA_PARALLEL +template +struct backend_default + : public backend_base { + using float_t = typename Descriptor::float_t; + using task_t = typename Descriptor::task_t; + using method_t = typename Descriptor::method_t; + using allocator_t = typename Descriptor::allocator_t; + + virtual vertex_partitioning_result operator()( + const dal::detail::data_parallel_policy& ctx, + const Descriptor& descriptor, + const Topology& t); +}; +#endif + +template +dal::detail::shared> get_backend(const Descriptor& desc, + const Topology& t) { + return std::make_shared>(); } } // namespace oneapi::dal::preview::connected_components::detail diff --git a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp new file mode 100644 index 00000000000..627f2085510 --- /dev/null +++ b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp @@ -0,0 +1,64 @@ +/******************************************************************************* +* 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/algo/connected_components/detail/select_kernel.hpp" +#include "oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp" +#include "oneapi/dal/backend/dispatcher.hpp" + +namespace oneapi::dal::preview::connected_components::detail { + +template +vertex_partitioning_result +backend_default::operator()( + const dal::detail::data_parallel_policy& ctx, + const Descriptor& descriptor, + const Topology& t) { + using float_t = typename Descriptor::float_t; + using task_t = typename Descriptor::task_t; + using method_t = typename Descriptor::method_t; + using allocator_t = typename Descriptor::allocator_t; + + return dal::backend::dispatch_by_device( + ctx, + [&]() { + return vertex_partitioning_kernel_cpu()( + dal::detail::host_policy::get_default(), + descriptor, + descriptor.get_allocator(), + t); + }, + [&]() { + dal::backend::context_gpu gpu_ctx{ ctx }; + return backend::vertex_partitioning_kernel_gpu()( + gpu_ctx, + descriptor, + t); + }); +} + +using default_descriptor = descriptor< + float, + method::afforest, + task::vertex_partitioning, + std::allocator>; + +using default_topology = dal::preview::detail::topology; + +template struct ONEDAL_EXPORT backend_default; + +} // namespace oneapi::dal::preview::connected_components::detail diff --git a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp index a3849222fa5..ffa9e0024b7 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp @@ -78,4 +78,25 @@ struct vertex_partitioning_kernel_cpu +struct vertex_partitioning_kernel_cpu> { + inline vertex_partitioning_result operator()( + const dal::detail::host_policy& ctx, + const detail::descriptor_base& desc, + const Allocator& alloc, + const dal::preview::detail::topology& t) const { + alloc_connector alloc_con(alloc); + const auto vertex_count = t.get_vertex_count(); + if (vertex_count == 0) { + return vertex_partitioning_result(); + } + return afforest>{}(ctx, desc, t, &alloc_con); + } +}; + } // namespace oneapi::dal::preview::connected_components::detail diff --git a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_ops.hpp b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_ops.hpp index 0426b5dbbc3..26b4215f1bd 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_ops.hpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_ops.hpp @@ -22,6 +22,7 @@ #include "oneapi/dal/detail/error_messages.hpp" #include "oneapi/dal/detail/policy.hpp" #include "oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp" +#include "oneapi/dal/graph/detail/undirected_adjacency_vector_graph_topology_builder.hpp" namespace oneapi::dal::preview::connected_components::detail { @@ -32,8 +33,13 @@ struct vertex_partitioning_ops_dispatcher { const Policy &policy, const Descriptor &descriptor, vertex_partitioning_input &input) const { - static auto impl = get_backend(descriptor, input.get_graph()); - return (*impl)(policy, descriptor, input.get_graph()); + auto topology_builder = dal::preview::detail::csr_topology_builder(); + + const auto &t = topology_builder(input.get_graph()); + + auto impl = get_backend(descriptor, t); + + return (*impl)(policy, descriptor, t); } }; diff --git a/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp b/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp new file mode 100644 index 00000000000..878b449261b --- /dev/null +++ b/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp @@ -0,0 +1,278 @@ +/******************************************************************************* +* 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 +#include + +#ifndef ONEDAL_DATA_PARALLEL +#define ONEDAL_DATA_PARALLEL +#endif + +#include + +#include "oneapi/dal/algo/connected_components/vertex_partitioning.hpp" + +#include "oneapi/dal/test/engine/common.hpp" + +namespace oneapi::dal::algo::connected_components::gpu::test { + +class graph_base_data { +public: + graph_base_data() = default; + + std::int64_t get_vertex_count() const { + return vertex_count; + } + + std::int64_t get_edge_count() const { + return edge_count; + } + + std::int64_t get_component_count() const { + return component_count; + } + + std::int64_t get_cols_count() const { + return cols_count; + } + + std::int64_t get_rows_count() const { + return rows_count; + } + +protected: + std::int64_t vertex_count; + std::int64_t edge_count; + std::int64_t cols_count; + std::int64_t rows_count; + std::int64_t component_count; +}; + +class triangle_graph_type : public graph_base_data { +public: + triangle_graph_type() { + vertex_count = 3; + edge_count = 3; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + component_count = 1; + } + + std::array degrees = { 2, 2, 2 }; + std::array cols = { 1, 2, 0, 2, 0, 1 }; + std::array rows = { 0, 2, 4, 6 }; +}; + +class two_components_graph_type : public graph_base_data { +public: + two_components_graph_type() { + vertex_count = 4; + edge_count = 2; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + component_count = 2; + } + + std::array degrees = { 1, 1, 1, 1 }; + std::array cols = { 1, 0, 3, 2 }; + std::array rows = { 0, 1, 2, 3, 4 }; +}; + +class complete_graph_5_type : public graph_base_data { +public: + complete_graph_5_type() { + vertex_count = 5; + edge_count = 10; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + component_count = 1; + } + + std::array degrees = { 4, 4, 4, 4, 4 }; + std::array cols = { + 1, 2, 3, 4, 0, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 4, 0, 1, 2, 3 + }; + std::array rows = { 0, 4, 8, 12, 16, 20 }; +}; + +class isolated_vertices_5_type : public graph_base_data { +public: + isolated_vertices_5_type() { + vertex_count = 5; + edge_count = 0; + cols_count = 0; + rows_count = vertex_count + 1; + component_count = 5; + } + + std::array degrees = { 0, 0, 0, 0, 0 }; + std::array cols = { 0 }; + std::array rows = { 0, 0, 0, 0, 0, 0 }; +}; + +class three_components_graph_type : public graph_base_data { +public: + three_components_graph_type() { + vertex_count = 6; + edge_count = 4; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + component_count = 3; + } + + std::array degrees = { 2, 2, 2, 1, 1, 0 }; + std::array cols = { 1, 2, 0, 2, 0, 1, 4, 3 }; + std::array rows = { 0, 2, 4, 6, 7, 8, 8 }; +}; + +class line_graph_5_type : public graph_base_data { +public: + line_graph_5_type() { + vertex_count = 5; + edge_count = 4; + cols_count = edge_count * 2; + rows_count = vertex_count + 1; + component_count = 1; + } + + std::array degrees = { 1, 2, 2, 2, 1 }; + std::array cols = { 1, 0, 2, 1, 3, 2, 4, 3 }; + std::array rows = { 0, 1, 3, 5, 7, 8 }; +}; + +class connected_components_gpu_test { +public: + template + auto create_graph() { + GraphType graph_data; + dal::preview::undirected_adjacency_vector_graph<> g; + auto& graph_impl = oneapi::dal::detail::get_impl(g); + auto& vertex_allocator = graph_impl._vertex_allocator; + auto& edge_allocator = graph_impl._edge_allocator; + + const std::int64_t vertex_count = graph_data.get_vertex_count(); + const std::int64_t edge_count = graph_data.get_edge_count(); + const std::int64_t cols_count = graph_data.get_cols_count(); + const std::int64_t rows_count = graph_data.get_rows_count(); + + std::int32_t* degrees = + oneapi::dal::preview::detail::allocate(vertex_allocator, vertex_count); + std::int32_t* cols = oneapi::dal::preview::detail::allocate(vertex_allocator, cols_count); + std::int64_t* rows = oneapi::dal::preview::detail::allocate(edge_allocator, rows_count); + std::int32_t* rows_vertex = + oneapi::dal::preview::detail::allocate(vertex_allocator, rows_count); + + for (int i = 0; i < vertex_count; i++) { + degrees[i] = graph_data.degrees[i]; + } + + for (int i = 0; i < cols_count; i++) { + cols[i] = graph_data.cols[i]; + } + for (int i = 0; i < rows_count; i++) { + rows[i] = graph_data.rows[i]; + rows_vertex[i] = graph_data.rows[i]; + } + graph_impl.set_topology(vertex_count, edge_count, rows, cols, cols_count, degrees); + graph_impl.get_topology()._rows_vertex = + oneapi::dal::preview::detail::container::wrap(rows_vertex, rows_count); + return g; + } + + sycl::queue get_queue() { + return sycl::queue{ sycl::default_selector_v }; + } + + template + void check_vertex_partitioning() { + GraphType graph_data; + const auto g = create_graph(); + const std::int64_t vertex_count = graph_data.get_vertex_count(); + const std::int64_t expected_components = graph_data.get_component_count(); + + auto q = get_queue(); + + std::allocator alloc; + const auto cc_desc = dal::preview::connected_components::descriptor< + float, + dal::preview::connected_components::method::afforest, + dal::preview::connected_components::task::vertex_partitioning, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_partitioning(q, cc_desc, g); + + REQUIRE(result.get_component_count() == expected_components); + + const auto labels_table = result.get_labels(); + REQUIRE(labels_table.get_row_count() == vertex_count); + + const auto& labels = static_cast(labels_table); + const auto labels_data = labels.get_data(); + + std::set unique_labels(labels_data, labels_data + vertex_count); + REQUIRE(static_cast(unique_labels.size()) == expected_components); + + for (std::int64_t u = 0; u < vertex_count; ++u) { + std::int64_t u_start = graph_data.rows[u]; + std::int64_t u_end = graph_data.rows[u + 1]; + for (std::int64_t i = u_start; i < u_end; ++i) { + std::int32_t v = graph_data.cols[i]; + REQUIRE(labels_data[u] == labels_data[v]); + } + } + } +}; + +TEST_M(connected_components_gpu_test, "GPU: triangle graph - 1 component") { + this->check_vertex_partitioning(); +} + +TEST_M(connected_components_gpu_test, "GPU: two components") { + this->check_vertex_partitioning(); +} + +TEST_M(connected_components_gpu_test, "GPU: complete graph K5 - 1 component") { + this->check_vertex_partitioning(); +} + +TEST_M(connected_components_gpu_test, "GPU: isolated vertices - 5 components") { + this->check_vertex_partitioning(); +} + +TEST_M(connected_components_gpu_test, "GPU: three components") { + this->check_vertex_partitioning(); +} + +TEST_M(connected_components_gpu_test, "GPU: line graph - 1 component") { + this->check_vertex_partitioning(); +} + +TEST_M(connected_components_gpu_test, "GPU: null graph") { + dal::preview::undirected_adjacency_vector_graph<> null_graph; + auto q = get_queue(); + + std::allocator alloc; + const auto cc_desc = dal::preview::connected_components::descriptor< + float, + dal::preview::connected_components::method::afforest, + dal::preview::connected_components::task::vertex_partitioning, + std::allocator>(alloc); + + const auto result = dal::preview::vertex_partitioning(q, cc_desc, null_graph); + REQUIRE(result.get_component_count() == 0); +} + +} // namespace oneapi::dal::algo::connected_components::gpu::test diff --git a/cpp/oneapi/dal/detail/vertex_partitioning_ops.hpp b/cpp/oneapi/dal/detail/vertex_partitioning_ops.hpp index 8e531354168..efd203fe4c5 100644 --- a/cpp/oneapi/dal/detail/vertex_partitioning_ops.hpp +++ b/cpp/oneapi/dal/detail/vertex_partitioning_ops.hpp @@ -40,5 +40,25 @@ auto vertex_partitioning_dispatch(Head &&head, Tail &&...tail) { std::forward(tail)...); } +#ifdef ONEDAL_DATA_PARALLEL +template +auto vertex_partitioning_dispatch_by_input(const dal::detail::data_parallel_policy &policy, + const Descriptor &desc, + Head &&head, + Tail &&...tail) { + using tag_t = typename Descriptor::tag_t; + using ops_t = vertex_partitioning_ops, tag_t>; + using input_t = typename ops_t::input_t; + + auto input = input_t{ std::forward(head), std::forward(tail)... }; + return ops_t()(policy, desc, input); +} + +template +auto vertex_partitioning_dispatch(const dal::detail::data_parallel_policy &policy, Tail &&...tail) { + return vertex_partitioning_dispatch_by_input(policy, std::forward(tail)...); +} +#endif + } // namespace detail } // namespace oneapi::dal::preview diff --git a/cpp/oneapi/dal/graph/detail/csr_topology.hpp b/cpp/oneapi/dal/graph/detail/csr_topology.hpp index 78fdf0d5d81..c661be73d03 100644 --- a/cpp/oneapi/dal/graph/detail/csr_topology.hpp +++ b/cpp/oneapi/dal/graph/detail/csr_topology.hpp @@ -152,9 +152,11 @@ class topology { const auto rows_count = _vertex_count + 1; const auto cols_count = _cols.get_count(); + const auto degrees_count = _degrees.get_count(); + const auto rows_vertex_count = _rows_vertex.get_count(); - auto device_rows = edge_set::empty(queue, rows_count, sycl::usm::alloc::device); - auto device_cols = vertex_set::empty(queue, cols_count, sycl::usm::alloc::device); + auto device_rows = edge_set::empty(queue, rows_count, sycl::usm::alloc::shared); + auto device_cols = vertex_set::empty(queue, cols_count, sycl::usm::alloc::shared); auto e1 = queue.memcpy(device_rows.get_mutable_data(), _rows.get_data(), @@ -169,7 +171,23 @@ class topology { result._cols = device_cols; result._rows_ptr = result._rows.get_data(); result._cols_ptr = result._cols.get_data(); - result._degrees_ptr = nullptr; + + if (degrees_count > 0) { + auto device_degrees = vertex_set::empty(queue, degrees_count, sycl::usm::alloc::shared); + queue.memcpy(device_degrees.get_mutable_data(), _degrees.get_data(), + degrees_count * sizeof(vertex_type)).wait_and_throw(); + result._degrees = device_degrees; + result._degrees_ptr = result._degrees.get_data(); + } + + if (rows_vertex_count > 0) { + auto device_rows_vertex = vertex_edge_set::empty(queue, rows_vertex_count, + sycl::usm::alloc::shared); + queue.memcpy(device_rows_vertex.get_mutable_data(), _rows_vertex.get_data(), + rows_vertex_count * sizeof(vertex_edge_type)).wait_and_throw(); + result._rows_vertex = device_rows_vertex; + } + return result; } #endif diff --git a/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp b/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp index f5cbd79d135..8ff84805f57 100644 --- a/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp +++ b/cpp/oneapi/dal/graph/detail/undirected_adjacency_vector_graph_impl.hpp @@ -138,7 +138,7 @@ class ONEDAL_EXPORT undirected_adjacency_vector_graph_impl { if (alloc_type == sycl::usm::alloc::device || alloc_type == sycl::usm::alloc::shared) { return; } - auto device_arr = container::empty(queue, count, sycl::usm::alloc::device); + auto device_arr = container::empty(queue, count, sycl::usm::alloc::shared); queue.memcpy(device_arr.get_mutable_data(), src, count * sizeof(T)).wait_and_throw(); arr = device_arr; } diff --git a/cpp/oneapi/dal/vertex_partitioning.hpp b/cpp/oneapi/dal/vertex_partitioning.hpp index 0197912c5a7..342156e039c 100644 --- a/cpp/oneapi/dal/vertex_partitioning.hpp +++ b/cpp/oneapi/dal/vertex_partitioning.hpp @@ -29,4 +29,12 @@ auto vertex_partitioning(Args &&...args) { return detail::vertex_partitioning_dispatch(std::forward(args)...); } +#ifdef ONEDAL_DATA_PARALLEL +template +auto vertex_partitioning(sycl::queue& q, Args &&...args) { + const auto policy = dal::detail::data_parallel_policy{ q }; + return detail::vertex_partitioning_dispatch(policy, std::forward(args)...); +} +#endif + } // namespace oneapi::dal::preview diff --git a/examples/oneapi/dpc/BUILD b/examples/oneapi/dpc/BUILD index 42519af0c62..6a138d903ba 100644 --- a/examples/oneapi/dpc/BUILD +++ b/examples/oneapi/dpc/BUILD @@ -69,6 +69,7 @@ dal_algo_example_suite( "rbf_kernel", "svm", "triangle_counting", + "connected_components", ], compile_as = [ "dpc++" ], data = _DATA_DEPS, diff --git a/examples/oneapi/dpc/_cmake_results/intel_intel64_so/connected_components_batch b/examples/oneapi/dpc/_cmake_results/intel_intel64_so/connected_components_batch new file mode 100755 index 0000000000000000000000000000000000000000..be27c0f191b01a82d781ef84f0bdcb8909e80bbf GIT binary patch literal 511008 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

bZg6SE2%nQ_O2OI0a)(pr7!5^ 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�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 V{AOZ&m_%vY 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

WiON7=4wg*~e*eYn1 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 G&i?}nJ;#Lr literal 0 HcmV?d00001 diff --git a/examples/oneapi/dpc/build/Makefile b/examples/oneapi/dpc/build/Makefile new file mode 100644 index 00000000000..792d9aa324c --- /dev/null +++ b/examples/oneapi/dpc/build/Makefile @@ -0,0 +1,1944 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.25 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/cmake + +# The command to remove a file. +RM = /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /export/users/okruglov/oneDAL/examples/oneapi/dpc + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /export/users/okruglov/oneDAL/examples/oneapi/dpc/build + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." + /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /export/users/okruglov/oneDAL/examples/oneapi/dpc/build/CMakeFiles /export/users/okruglov/oneDAL/examples/oneapi/dpc/build//CMakeFiles/progress.marks + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /export/users/okruglov/oneDAL/examples/oneapi/dpc/build/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named basic_statistics_dense_batch + +# Build rule for target. +basic_statistics_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 basic_statistics_dense_batch +.PHONY : basic_statistics_dense_batch + +# fast build rule for target. +basic_statistics_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/build +.PHONY : basic_statistics_dense_batch/fast + +#============================================================================= +# Target rules for targets named basic_statistics_dense_online + +# Build rule for target. +basic_statistics_dense_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 basic_statistics_dense_online +.PHONY : basic_statistics_dense_online + +# fast build rule for target. +basic_statistics_dense_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/build +.PHONY : basic_statistics_dense_online/fast + +#============================================================================= +# Target rules for targets named connected_components_batch + +# Build rule for target. +connected_components_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 connected_components_batch +.PHONY : connected_components_batch + +# fast build rule for target. +connected_components_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/build +.PHONY : connected_components_batch/fast + +#============================================================================= +# Target rules for targets named correlation_distance_dense_batch + +# Build rule for target. +correlation_distance_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 correlation_distance_dense_batch +.PHONY : correlation_distance_dense_batch + +# fast build rule for target. +correlation_distance_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/build +.PHONY : correlation_distance_dense_batch/fast + +#============================================================================= +# Target rules for targets named cosine_distance_dense_batch + +# Build rule for target. +cosine_distance_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cosine_distance_dense_batch +.PHONY : cosine_distance_dense_batch + +# fast build rule for target. +cosine_distance_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/build +.PHONY : cosine_distance_dense_batch/fast + +#============================================================================= +# Target rules for targets named cor_dense_batch + +# Build rule for target. +cor_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cor_dense_batch +.PHONY : cor_dense_batch + +# fast build rule for target. +cor_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/build +.PHONY : cor_dense_batch/fast + +#============================================================================= +# Target rules for targets named cor_dense_online + +# Build rule for target. +cor_dense_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cor_dense_online +.PHONY : cor_dense_online + +# fast build rule for target. +cor_dense_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/build +.PHONY : cor_dense_online/fast + +#============================================================================= +# Target rules for targets named cov_dense_batch + +# Build rule for target. +cov_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_batch +.PHONY : cov_dense_batch + +# fast build rule for target. +cov_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/build +.PHONY : cov_dense_batch/fast + +#============================================================================= +# Target rules for targets named cov_dense_biased_batch + +# Build rule for target. +cov_dense_biased_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_biased_batch +.PHONY : cov_dense_biased_batch + +# fast build rule for target. +cov_dense_biased_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/build +.PHONY : cov_dense_biased_batch/fast + +#============================================================================= +# Target rules for targets named cov_dense_biased_online + +# Build rule for target. +cov_dense_biased_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_biased_online +.PHONY : cov_dense_biased_online + +# fast build rule for target. +cov_dense_biased_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/build +.PHONY : cov_dense_biased_online/fast + +#============================================================================= +# Target rules for targets named cov_dense_online + +# Build rule for target. +cov_dense_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_online +.PHONY : cov_dense_online + +# fast build rule for target. +cov_dense_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/build +.PHONY : cov_dense_online/fast + +#============================================================================= +# Target rules for targets named dbscan_brute_force_batch + +# Build rule for target. +dbscan_brute_force_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 dbscan_brute_force_batch +.PHONY : dbscan_brute_force_batch + +# fast build rule for target. +dbscan_brute_force_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/build +.PHONY : dbscan_brute_force_batch/fast + +#============================================================================= +# Target rules for targets named df_cls_hist_batch + +# Build rule for target. +df_cls_hist_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_cls_hist_batch +.PHONY : df_cls_hist_batch + +# fast build rule for target. +df_cls_hist_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/build +.PHONY : df_cls_hist_batch/fast + +#============================================================================= +# Target rules for targets named df_cls_hist_batch_random + +# Build rule for target. +df_cls_hist_batch_random: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_cls_hist_batch_random +.PHONY : df_cls_hist_batch_random + +# fast build rule for target. +df_cls_hist_batch_random/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/build +.PHONY : df_cls_hist_batch_random/fast + +#============================================================================= +# Target rules for targets named df_cls_traverse_model + +# Build rule for target. +df_cls_traverse_model: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_cls_traverse_model +.PHONY : df_cls_traverse_model + +# fast build rule for target. +df_cls_traverse_model/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/build +.PHONY : df_cls_traverse_model/fast + +#============================================================================= +# Target rules for targets named df_reg_hist_batch + +# Build rule for target. +df_reg_hist_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_reg_hist_batch +.PHONY : df_reg_hist_batch + +# fast build rule for target. +df_reg_hist_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/build +.PHONY : df_reg_hist_batch/fast + +#============================================================================= +# Target rules for targets named df_reg_hist_batch_random + +# Build rule for target. +df_reg_hist_batch_random: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_reg_hist_batch_random +.PHONY : df_reg_hist_batch_random + +# fast build rule for target. +df_reg_hist_batch_random/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/build +.PHONY : df_reg_hist_batch_random/fast + +#============================================================================= +# Target rules for targets named df_reg_traverse_model + +# Build rule for target. +df_reg_traverse_model: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_reg_traverse_model +.PHONY : df_reg_traverse_model + +# fast build rule for target. +df_reg_traverse_model/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/build +.PHONY : df_reg_traverse_model/fast + +#============================================================================= +# Target rules for targets named kmeans_lloyd_csr_batch + +# Build rule for target. +kmeans_lloyd_csr_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kmeans_lloyd_csr_batch +.PHONY : kmeans_lloyd_csr_batch + +# fast build rule for target. +kmeans_lloyd_csr_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/build +.PHONY : kmeans_lloyd_csr_batch/fast + +#============================================================================= +# Target rules for targets named kmeans_lloyd_dense_batch + +# Build rule for target. +kmeans_lloyd_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kmeans_lloyd_dense_batch +.PHONY : kmeans_lloyd_dense_batch + +# fast build rule for target. +kmeans_lloyd_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/build +.PHONY : kmeans_lloyd_dense_batch/fast + +#============================================================================= +# Target rules for targets named kmeans_init_dense + +# Build rule for target. +kmeans_init_dense: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kmeans_init_dense +.PHONY : kmeans_init_dense + +# fast build rule for target. +kmeans_init_dense/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/build +.PHONY : kmeans_init_dense/fast + +#============================================================================= +# Target rules for targets named knn_cls_brute_force_dense_batch + +# Build rule for target. +knn_cls_brute_force_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 knn_cls_brute_force_dense_batch +.PHONY : knn_cls_brute_force_dense_batch + +# fast build rule for target. +knn_cls_brute_force_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/build +.PHONY : knn_cls_brute_force_dense_batch/fast + +#============================================================================= +# Target rules for targets named knn_reg_brute_force_dense_batch + +# Build rule for target. +knn_reg_brute_force_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 knn_reg_brute_force_dense_batch +.PHONY : knn_reg_brute_force_dense_batch + +# fast build rule for target. +knn_reg_brute_force_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/build +.PHONY : knn_reg_brute_force_dense_batch/fast + +#============================================================================= +# Target rules for targets named knn_search_brute_force_dense_batch + +# Build rule for target. +knn_search_brute_force_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 knn_search_brute_force_dense_batch +.PHONY : knn_search_brute_force_dense_batch + +# fast build rule for target. +knn_search_brute_force_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/build +.PHONY : knn_search_brute_force_dense_batch/fast + +#============================================================================= +# Target rules for targets named linear_kernel_dense_batch + +# Build rule for target. +linear_kernel_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 linear_kernel_dense_batch +.PHONY : linear_kernel_dense_batch + +# fast build rule for target. +linear_kernel_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/build +.PHONY : linear_kernel_dense_batch/fast + +#============================================================================= +# Target rules for targets named linear_regression_dense_batch + +# Build rule for target. +linear_regression_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 linear_regression_dense_batch +.PHONY : linear_regression_dense_batch + +# fast build rule for target. +linear_regression_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/build +.PHONY : linear_regression_dense_batch/fast + +#============================================================================= +# Target rules for targets named linear_regression_dense_online + +# Build rule for target. +linear_regression_dense_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 linear_regression_dense_online +.PHONY : linear_regression_dense_online + +# fast build rule for target. +linear_regression_dense_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/build +.PHONY : linear_regression_dense_online/fast + +#============================================================================= +# Target rules for targets named logistic_regression_dense_batch + +# Build rule for target. +logistic_regression_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 logistic_regression_dense_batch +.PHONY : logistic_regression_dense_batch + +# fast build rule for target. +logistic_regression_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/build +.PHONY : logistic_regression_dense_batch/fast + +#============================================================================= +# Target rules for targets named read_batch + +# Build rule for target. +read_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 read_batch +.PHONY : read_batch + +# fast build rule for target. +read_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/build +.PHONY : read_batch/fast + +#============================================================================= +# Target rules for targets named pca_cor_dense_batch + +# Build rule for target. +pca_cor_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cor_dense_batch +.PHONY : pca_cor_dense_batch + +# fast build rule for target. +pca_cor_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/build +.PHONY : pca_cor_dense_batch/fast + +#============================================================================= +# Target rules for targets named pca_cor_dense_online + +# Build rule for target. +pca_cor_dense_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cor_dense_online +.PHONY : pca_cor_dense_online + +# fast build rule for target. +pca_cor_dense_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/build +.PHONY : pca_cor_dense_online/fast + +#============================================================================= +# Target rules for targets named pca_cov_dense_batch + +# Build rule for target. +pca_cov_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cov_dense_batch +.PHONY : pca_cov_dense_batch + +# fast build rule for target. +pca_cov_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/build +.PHONY : pca_cov_dense_batch/fast + +#============================================================================= +# Target rules for targets named pca_cov_dense_online + +# Build rule for target. +pca_cov_dense_online: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cov_dense_online +.PHONY : pca_cov_dense_online + +# fast build rule for target. +pca_cov_dense_online/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/build +.PHONY : pca_cov_dense_online/fast + +#============================================================================= +# Target rules for targets named pca_precomputed_cor_dense_batch + +# Build rule for target. +pca_precomputed_cor_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_precomputed_cor_dense_batch +.PHONY : pca_precomputed_cor_dense_batch + +# fast build rule for target. +pca_precomputed_cor_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/build +.PHONY : pca_precomputed_cor_dense_batch/fast + +#============================================================================= +# Target rules for targets named pca_precomputed_cov_dense_batch + +# Build rule for target. +pca_precomputed_cov_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_precomputed_cov_dense_batch +.PHONY : pca_precomputed_cov_dense_batch + +# fast build rule for target. +pca_precomputed_cov_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/build +.PHONY : pca_precomputed_cov_dense_batch/fast + +#============================================================================= +# Target rules for targets named pca_svd_dense_batch + +# Build rule for target. +pca_svd_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_svd_dense_batch +.PHONY : pca_svd_dense_batch + +# fast build rule for target. +pca_svd_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/build +.PHONY : pca_svd_dense_batch/fast + +#============================================================================= +# Target rules for targets named rbf_kernel_dense_batch + +# Build rule for target. +rbf_kernel_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 rbf_kernel_dense_batch +.PHONY : rbf_kernel_dense_batch + +# fast build rule for target. +rbf_kernel_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/build +.PHONY : rbf_kernel_dense_batch/fast + +#============================================================================= +# Target rules for targets named svm_two_class_thunder_dense_batch + +# Build rule for target. +svm_two_class_thunder_dense_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 svm_two_class_thunder_dense_batch +.PHONY : svm_two_class_thunder_dense_batch + +# fast build rule for target. +svm_two_class_thunder_dense_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/build +.PHONY : svm_two_class_thunder_dense_batch/fast + +#============================================================================= +# Target rules for targets named column_accessor_homogen + +# Build rule for target. +column_accessor_homogen: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 column_accessor_homogen +.PHONY : column_accessor_homogen + +# fast build rule for target. +column_accessor_homogen/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/build +.PHONY : column_accessor_homogen/fast + +#============================================================================= +# Target rules for targets named csr_accessor + +# Build rule for target. +csr_accessor: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 csr_accessor +.PHONY : csr_accessor + +# fast build rule for target. +csr_accessor/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/build +.PHONY : csr_accessor/fast + +#============================================================================= +# Target rules for targets named csr_table + +# Build rule for target. +csr_table: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 csr_table +.PHONY : csr_table + +# fast build rule for target. +csr_table/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/build +.PHONY : csr_table/fast + +#============================================================================= +# Target rules for targets named heterogen_table + +# Build rule for target. +heterogen_table: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 heterogen_table +.PHONY : heterogen_table + +# fast build rule for target. +heterogen_table/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/build +.PHONY : heterogen_table/fast + +#============================================================================= +# Target rules for targets named homogen_table + +# Build rule for target. +homogen_table: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 homogen_table +.PHONY : homogen_table + +# fast build rule for target. +homogen_table/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/build +.PHONY : homogen_table/fast + +#============================================================================= +# Target rules for targets named triangle_counting_batch + +# Build rule for target. +triangle_counting_batch: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 triangle_counting_batch +.PHONY : triangle_counting_batch + +# fast build rule for target. +triangle_counting_batch/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/build +.PHONY : triangle_counting_batch/fast + +source/basic_statistics/basic_statistics_dense_batch.o: source/basic_statistics/basic_statistics_dense_batch.cpp.o +.PHONY : source/basic_statistics/basic_statistics_dense_batch.o + +# target to build an object file +source/basic_statistics/basic_statistics_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/source/basic_statistics/basic_statistics_dense_batch.cpp.o +.PHONY : source/basic_statistics/basic_statistics_dense_batch.cpp.o + +source/basic_statistics/basic_statistics_dense_batch.i: source/basic_statistics/basic_statistics_dense_batch.cpp.i +.PHONY : source/basic_statistics/basic_statistics_dense_batch.i + +# target to preprocess a source file +source/basic_statistics/basic_statistics_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/source/basic_statistics/basic_statistics_dense_batch.cpp.i +.PHONY : source/basic_statistics/basic_statistics_dense_batch.cpp.i + +source/basic_statistics/basic_statistics_dense_batch.s: source/basic_statistics/basic_statistics_dense_batch.cpp.s +.PHONY : source/basic_statistics/basic_statistics_dense_batch.s + +# target to generate assembly for a file +source/basic_statistics/basic_statistics_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/source/basic_statistics/basic_statistics_dense_batch.cpp.s +.PHONY : source/basic_statistics/basic_statistics_dense_batch.cpp.s + +source/basic_statistics/basic_statistics_dense_online.o: source/basic_statistics/basic_statistics_dense_online.cpp.o +.PHONY : source/basic_statistics/basic_statistics_dense_online.o + +# target to build an object file +source/basic_statistics/basic_statistics_dense_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/source/basic_statistics/basic_statistics_dense_online.cpp.o +.PHONY : source/basic_statistics/basic_statistics_dense_online.cpp.o + +source/basic_statistics/basic_statistics_dense_online.i: source/basic_statistics/basic_statistics_dense_online.cpp.i +.PHONY : source/basic_statistics/basic_statistics_dense_online.i + +# target to preprocess a source file +source/basic_statistics/basic_statistics_dense_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/source/basic_statistics/basic_statistics_dense_online.cpp.i +.PHONY : source/basic_statistics/basic_statistics_dense_online.cpp.i + +source/basic_statistics/basic_statistics_dense_online.s: source/basic_statistics/basic_statistics_dense_online.cpp.s +.PHONY : source/basic_statistics/basic_statistics_dense_online.s + +# target to generate assembly for a file +source/basic_statistics/basic_statistics_dense_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/source/basic_statistics/basic_statistics_dense_online.cpp.s +.PHONY : source/basic_statistics/basic_statistics_dense_online.cpp.s + +source/connected_components/connected_components_batch.o: source/connected_components/connected_components_batch.cpp.o +.PHONY : source/connected_components/connected_components_batch.o + +# target to build an object file +source/connected_components/connected_components_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/source/connected_components/connected_components_batch.cpp.o +.PHONY : source/connected_components/connected_components_batch.cpp.o + +source/connected_components/connected_components_batch.i: source/connected_components/connected_components_batch.cpp.i +.PHONY : source/connected_components/connected_components_batch.i + +# target to preprocess a source file +source/connected_components/connected_components_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/source/connected_components/connected_components_batch.cpp.i +.PHONY : source/connected_components/connected_components_batch.cpp.i + +source/connected_components/connected_components_batch.s: source/connected_components/connected_components_batch.cpp.s +.PHONY : source/connected_components/connected_components_batch.s + +# target to generate assembly for a file +source/connected_components/connected_components_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/source/connected_components/connected_components_batch.cpp.s +.PHONY : source/connected_components/connected_components_batch.cpp.s + +source/correlation_distance/correlation_distance_dense_batch.o: source/correlation_distance/correlation_distance_dense_batch.cpp.o +.PHONY : source/correlation_distance/correlation_distance_dense_batch.o + +# target to build an object file +source/correlation_distance/correlation_distance_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/source/correlation_distance/correlation_distance_dense_batch.cpp.o +.PHONY : source/correlation_distance/correlation_distance_dense_batch.cpp.o + +source/correlation_distance/correlation_distance_dense_batch.i: source/correlation_distance/correlation_distance_dense_batch.cpp.i +.PHONY : source/correlation_distance/correlation_distance_dense_batch.i + +# target to preprocess a source file +source/correlation_distance/correlation_distance_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/source/correlation_distance/correlation_distance_dense_batch.cpp.i +.PHONY : source/correlation_distance/correlation_distance_dense_batch.cpp.i + +source/correlation_distance/correlation_distance_dense_batch.s: source/correlation_distance/correlation_distance_dense_batch.cpp.s +.PHONY : source/correlation_distance/correlation_distance_dense_batch.s + +# target to generate assembly for a file +source/correlation_distance/correlation_distance_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/source/correlation_distance/correlation_distance_dense_batch.cpp.s +.PHONY : source/correlation_distance/correlation_distance_dense_batch.cpp.s + +source/cosine_distance/cosine_distance_dense_batch.o: source/cosine_distance/cosine_distance_dense_batch.cpp.o +.PHONY : source/cosine_distance/cosine_distance_dense_batch.o + +# target to build an object file +source/cosine_distance/cosine_distance_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/source/cosine_distance/cosine_distance_dense_batch.cpp.o +.PHONY : source/cosine_distance/cosine_distance_dense_batch.cpp.o + +source/cosine_distance/cosine_distance_dense_batch.i: source/cosine_distance/cosine_distance_dense_batch.cpp.i +.PHONY : source/cosine_distance/cosine_distance_dense_batch.i + +# target to preprocess a source file +source/cosine_distance/cosine_distance_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/source/cosine_distance/cosine_distance_dense_batch.cpp.i +.PHONY : source/cosine_distance/cosine_distance_dense_batch.cpp.i + +source/cosine_distance/cosine_distance_dense_batch.s: source/cosine_distance/cosine_distance_dense_batch.cpp.s +.PHONY : source/cosine_distance/cosine_distance_dense_batch.s + +# target to generate assembly for a file +source/cosine_distance/cosine_distance_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/source/cosine_distance/cosine_distance_dense_batch.cpp.s +.PHONY : source/cosine_distance/cosine_distance_dense_batch.cpp.s + +source/covariance/cor_dense_batch.o: source/covariance/cor_dense_batch.cpp.o +.PHONY : source/covariance/cor_dense_batch.o + +# target to build an object file +source/covariance/cor_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/source/covariance/cor_dense_batch.cpp.o +.PHONY : source/covariance/cor_dense_batch.cpp.o + +source/covariance/cor_dense_batch.i: source/covariance/cor_dense_batch.cpp.i +.PHONY : source/covariance/cor_dense_batch.i + +# target to preprocess a source file +source/covariance/cor_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/source/covariance/cor_dense_batch.cpp.i +.PHONY : source/covariance/cor_dense_batch.cpp.i + +source/covariance/cor_dense_batch.s: source/covariance/cor_dense_batch.cpp.s +.PHONY : source/covariance/cor_dense_batch.s + +# target to generate assembly for a file +source/covariance/cor_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/source/covariance/cor_dense_batch.cpp.s +.PHONY : source/covariance/cor_dense_batch.cpp.s + +source/covariance/cor_dense_online.o: source/covariance/cor_dense_online.cpp.o +.PHONY : source/covariance/cor_dense_online.o + +# target to build an object file +source/covariance/cor_dense_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/source/covariance/cor_dense_online.cpp.o +.PHONY : source/covariance/cor_dense_online.cpp.o + +source/covariance/cor_dense_online.i: source/covariance/cor_dense_online.cpp.i +.PHONY : source/covariance/cor_dense_online.i + +# target to preprocess a source file +source/covariance/cor_dense_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/source/covariance/cor_dense_online.cpp.i +.PHONY : source/covariance/cor_dense_online.cpp.i + +source/covariance/cor_dense_online.s: source/covariance/cor_dense_online.cpp.s +.PHONY : source/covariance/cor_dense_online.s + +# target to generate assembly for a file +source/covariance/cor_dense_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/source/covariance/cor_dense_online.cpp.s +.PHONY : source/covariance/cor_dense_online.cpp.s + +source/covariance/cov_dense_batch.o: source/covariance/cov_dense_batch.cpp.o +.PHONY : source/covariance/cov_dense_batch.o + +# target to build an object file +source/covariance/cov_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/source/covariance/cov_dense_batch.cpp.o +.PHONY : source/covariance/cov_dense_batch.cpp.o + +source/covariance/cov_dense_batch.i: source/covariance/cov_dense_batch.cpp.i +.PHONY : source/covariance/cov_dense_batch.i + +# target to preprocess a source file +source/covariance/cov_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/source/covariance/cov_dense_batch.cpp.i +.PHONY : source/covariance/cov_dense_batch.cpp.i + +source/covariance/cov_dense_batch.s: source/covariance/cov_dense_batch.cpp.s +.PHONY : source/covariance/cov_dense_batch.s + +# target to generate assembly for a file +source/covariance/cov_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/source/covariance/cov_dense_batch.cpp.s +.PHONY : source/covariance/cov_dense_batch.cpp.s + +source/covariance/cov_dense_biased_batch.o: source/covariance/cov_dense_biased_batch.cpp.o +.PHONY : source/covariance/cov_dense_biased_batch.o + +# target to build an object file +source/covariance/cov_dense_biased_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/source/covariance/cov_dense_biased_batch.cpp.o +.PHONY : source/covariance/cov_dense_biased_batch.cpp.o + +source/covariance/cov_dense_biased_batch.i: source/covariance/cov_dense_biased_batch.cpp.i +.PHONY : source/covariance/cov_dense_biased_batch.i + +# target to preprocess a source file +source/covariance/cov_dense_biased_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/source/covariance/cov_dense_biased_batch.cpp.i +.PHONY : source/covariance/cov_dense_biased_batch.cpp.i + +source/covariance/cov_dense_biased_batch.s: source/covariance/cov_dense_biased_batch.cpp.s +.PHONY : source/covariance/cov_dense_biased_batch.s + +# target to generate assembly for a file +source/covariance/cov_dense_biased_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/source/covariance/cov_dense_biased_batch.cpp.s +.PHONY : source/covariance/cov_dense_biased_batch.cpp.s + +source/covariance/cov_dense_biased_online.o: source/covariance/cov_dense_biased_online.cpp.o +.PHONY : source/covariance/cov_dense_biased_online.o + +# target to build an object file +source/covariance/cov_dense_biased_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/source/covariance/cov_dense_biased_online.cpp.o +.PHONY : source/covariance/cov_dense_biased_online.cpp.o + +source/covariance/cov_dense_biased_online.i: source/covariance/cov_dense_biased_online.cpp.i +.PHONY : source/covariance/cov_dense_biased_online.i + +# target to preprocess a source file +source/covariance/cov_dense_biased_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/source/covariance/cov_dense_biased_online.cpp.i +.PHONY : source/covariance/cov_dense_biased_online.cpp.i + +source/covariance/cov_dense_biased_online.s: source/covariance/cov_dense_biased_online.cpp.s +.PHONY : source/covariance/cov_dense_biased_online.s + +# target to generate assembly for a file +source/covariance/cov_dense_biased_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/source/covariance/cov_dense_biased_online.cpp.s +.PHONY : source/covariance/cov_dense_biased_online.cpp.s + +source/covariance/cov_dense_online.o: source/covariance/cov_dense_online.cpp.o +.PHONY : source/covariance/cov_dense_online.o + +# target to build an object file +source/covariance/cov_dense_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/source/covariance/cov_dense_online.cpp.o +.PHONY : source/covariance/cov_dense_online.cpp.o + +source/covariance/cov_dense_online.i: source/covariance/cov_dense_online.cpp.i +.PHONY : source/covariance/cov_dense_online.i + +# target to preprocess a source file +source/covariance/cov_dense_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/source/covariance/cov_dense_online.cpp.i +.PHONY : source/covariance/cov_dense_online.cpp.i + +source/covariance/cov_dense_online.s: source/covariance/cov_dense_online.cpp.s +.PHONY : source/covariance/cov_dense_online.s + +# target to generate assembly for a file +source/covariance/cov_dense_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/source/covariance/cov_dense_online.cpp.s +.PHONY : source/covariance/cov_dense_online.cpp.s + +source/dbscan/dbscan_brute_force_batch.o: source/dbscan/dbscan_brute_force_batch.cpp.o +.PHONY : source/dbscan/dbscan_brute_force_batch.o + +# target to build an object file +source/dbscan/dbscan_brute_force_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/source/dbscan/dbscan_brute_force_batch.cpp.o +.PHONY : source/dbscan/dbscan_brute_force_batch.cpp.o + +source/dbscan/dbscan_brute_force_batch.i: source/dbscan/dbscan_brute_force_batch.cpp.i +.PHONY : source/dbscan/dbscan_brute_force_batch.i + +# target to preprocess a source file +source/dbscan/dbscan_brute_force_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/source/dbscan/dbscan_brute_force_batch.cpp.i +.PHONY : source/dbscan/dbscan_brute_force_batch.cpp.i + +source/dbscan/dbscan_brute_force_batch.s: source/dbscan/dbscan_brute_force_batch.cpp.s +.PHONY : source/dbscan/dbscan_brute_force_batch.s + +# target to generate assembly for a file +source/dbscan/dbscan_brute_force_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/source/dbscan/dbscan_brute_force_batch.cpp.s +.PHONY : source/dbscan/dbscan_brute_force_batch.cpp.s + +source/decision_forest/df_cls_hist_batch.o: source/decision_forest/df_cls_hist_batch.cpp.o +.PHONY : source/decision_forest/df_cls_hist_batch.o + +# target to build an object file +source/decision_forest/df_cls_hist_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/source/decision_forest/df_cls_hist_batch.cpp.o +.PHONY : source/decision_forest/df_cls_hist_batch.cpp.o + +source/decision_forest/df_cls_hist_batch.i: source/decision_forest/df_cls_hist_batch.cpp.i +.PHONY : source/decision_forest/df_cls_hist_batch.i + +# target to preprocess a source file +source/decision_forest/df_cls_hist_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/source/decision_forest/df_cls_hist_batch.cpp.i +.PHONY : source/decision_forest/df_cls_hist_batch.cpp.i + +source/decision_forest/df_cls_hist_batch.s: source/decision_forest/df_cls_hist_batch.cpp.s +.PHONY : source/decision_forest/df_cls_hist_batch.s + +# target to generate assembly for a file +source/decision_forest/df_cls_hist_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/source/decision_forest/df_cls_hist_batch.cpp.s +.PHONY : source/decision_forest/df_cls_hist_batch.cpp.s + +source/decision_forest/df_cls_hist_batch_random.o: source/decision_forest/df_cls_hist_batch_random.cpp.o +.PHONY : source/decision_forest/df_cls_hist_batch_random.o + +# target to build an object file +source/decision_forest/df_cls_hist_batch_random.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/source/decision_forest/df_cls_hist_batch_random.cpp.o +.PHONY : source/decision_forest/df_cls_hist_batch_random.cpp.o + +source/decision_forest/df_cls_hist_batch_random.i: source/decision_forest/df_cls_hist_batch_random.cpp.i +.PHONY : source/decision_forest/df_cls_hist_batch_random.i + +# target to preprocess a source file +source/decision_forest/df_cls_hist_batch_random.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/source/decision_forest/df_cls_hist_batch_random.cpp.i +.PHONY : source/decision_forest/df_cls_hist_batch_random.cpp.i + +source/decision_forest/df_cls_hist_batch_random.s: source/decision_forest/df_cls_hist_batch_random.cpp.s +.PHONY : source/decision_forest/df_cls_hist_batch_random.s + +# target to generate assembly for a file +source/decision_forest/df_cls_hist_batch_random.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/source/decision_forest/df_cls_hist_batch_random.cpp.s +.PHONY : source/decision_forest/df_cls_hist_batch_random.cpp.s + +source/decision_forest/df_cls_traverse_model.o: source/decision_forest/df_cls_traverse_model.cpp.o +.PHONY : source/decision_forest/df_cls_traverse_model.o + +# target to build an object file +source/decision_forest/df_cls_traverse_model.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/source/decision_forest/df_cls_traverse_model.cpp.o +.PHONY : source/decision_forest/df_cls_traverse_model.cpp.o + +source/decision_forest/df_cls_traverse_model.i: source/decision_forest/df_cls_traverse_model.cpp.i +.PHONY : source/decision_forest/df_cls_traverse_model.i + +# target to preprocess a source file +source/decision_forest/df_cls_traverse_model.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/source/decision_forest/df_cls_traverse_model.cpp.i +.PHONY : source/decision_forest/df_cls_traverse_model.cpp.i + +source/decision_forest/df_cls_traverse_model.s: source/decision_forest/df_cls_traverse_model.cpp.s +.PHONY : source/decision_forest/df_cls_traverse_model.s + +# target to generate assembly for a file +source/decision_forest/df_cls_traverse_model.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/source/decision_forest/df_cls_traverse_model.cpp.s +.PHONY : source/decision_forest/df_cls_traverse_model.cpp.s + +source/decision_forest/df_reg_hist_batch.o: source/decision_forest/df_reg_hist_batch.cpp.o +.PHONY : source/decision_forest/df_reg_hist_batch.o + +# target to build an object file +source/decision_forest/df_reg_hist_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/source/decision_forest/df_reg_hist_batch.cpp.o +.PHONY : source/decision_forest/df_reg_hist_batch.cpp.o + +source/decision_forest/df_reg_hist_batch.i: source/decision_forest/df_reg_hist_batch.cpp.i +.PHONY : source/decision_forest/df_reg_hist_batch.i + +# target to preprocess a source file +source/decision_forest/df_reg_hist_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/source/decision_forest/df_reg_hist_batch.cpp.i +.PHONY : source/decision_forest/df_reg_hist_batch.cpp.i + +source/decision_forest/df_reg_hist_batch.s: source/decision_forest/df_reg_hist_batch.cpp.s +.PHONY : source/decision_forest/df_reg_hist_batch.s + +# target to generate assembly for a file +source/decision_forest/df_reg_hist_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/source/decision_forest/df_reg_hist_batch.cpp.s +.PHONY : source/decision_forest/df_reg_hist_batch.cpp.s + +source/decision_forest/df_reg_hist_batch_random.o: source/decision_forest/df_reg_hist_batch_random.cpp.o +.PHONY : source/decision_forest/df_reg_hist_batch_random.o + +# target to build an object file +source/decision_forest/df_reg_hist_batch_random.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/source/decision_forest/df_reg_hist_batch_random.cpp.o +.PHONY : source/decision_forest/df_reg_hist_batch_random.cpp.o + +source/decision_forest/df_reg_hist_batch_random.i: source/decision_forest/df_reg_hist_batch_random.cpp.i +.PHONY : source/decision_forest/df_reg_hist_batch_random.i + +# target to preprocess a source file +source/decision_forest/df_reg_hist_batch_random.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/source/decision_forest/df_reg_hist_batch_random.cpp.i +.PHONY : source/decision_forest/df_reg_hist_batch_random.cpp.i + +source/decision_forest/df_reg_hist_batch_random.s: source/decision_forest/df_reg_hist_batch_random.cpp.s +.PHONY : source/decision_forest/df_reg_hist_batch_random.s + +# target to generate assembly for a file +source/decision_forest/df_reg_hist_batch_random.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/source/decision_forest/df_reg_hist_batch_random.cpp.s +.PHONY : source/decision_forest/df_reg_hist_batch_random.cpp.s + +source/decision_forest/df_reg_traverse_model.o: source/decision_forest/df_reg_traverse_model.cpp.o +.PHONY : source/decision_forest/df_reg_traverse_model.o + +# target to build an object file +source/decision_forest/df_reg_traverse_model.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/source/decision_forest/df_reg_traverse_model.cpp.o +.PHONY : source/decision_forest/df_reg_traverse_model.cpp.o + +source/decision_forest/df_reg_traverse_model.i: source/decision_forest/df_reg_traverse_model.cpp.i +.PHONY : source/decision_forest/df_reg_traverse_model.i + +# target to preprocess a source file +source/decision_forest/df_reg_traverse_model.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/source/decision_forest/df_reg_traverse_model.cpp.i +.PHONY : source/decision_forest/df_reg_traverse_model.cpp.i + +source/decision_forest/df_reg_traverse_model.s: source/decision_forest/df_reg_traverse_model.cpp.s +.PHONY : source/decision_forest/df_reg_traverse_model.s + +# target to generate assembly for a file +source/decision_forest/df_reg_traverse_model.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/source/decision_forest/df_reg_traverse_model.cpp.s +.PHONY : source/decision_forest/df_reg_traverse_model.cpp.s + +source/kmeans/kmeans_lloyd_csr_batch.o: source/kmeans/kmeans_lloyd_csr_batch.cpp.o +.PHONY : source/kmeans/kmeans_lloyd_csr_batch.o + +# target to build an object file +source/kmeans/kmeans_lloyd_csr_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/source/kmeans/kmeans_lloyd_csr_batch.cpp.o +.PHONY : source/kmeans/kmeans_lloyd_csr_batch.cpp.o + +source/kmeans/kmeans_lloyd_csr_batch.i: source/kmeans/kmeans_lloyd_csr_batch.cpp.i +.PHONY : source/kmeans/kmeans_lloyd_csr_batch.i + +# target to preprocess a source file +source/kmeans/kmeans_lloyd_csr_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/source/kmeans/kmeans_lloyd_csr_batch.cpp.i +.PHONY : source/kmeans/kmeans_lloyd_csr_batch.cpp.i + +source/kmeans/kmeans_lloyd_csr_batch.s: source/kmeans/kmeans_lloyd_csr_batch.cpp.s +.PHONY : source/kmeans/kmeans_lloyd_csr_batch.s + +# target to generate assembly for a file +source/kmeans/kmeans_lloyd_csr_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/source/kmeans/kmeans_lloyd_csr_batch.cpp.s +.PHONY : source/kmeans/kmeans_lloyd_csr_batch.cpp.s + +source/kmeans/kmeans_lloyd_dense_batch.o: source/kmeans/kmeans_lloyd_dense_batch.cpp.o +.PHONY : source/kmeans/kmeans_lloyd_dense_batch.o + +# target to build an object file +source/kmeans/kmeans_lloyd_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/source/kmeans/kmeans_lloyd_dense_batch.cpp.o +.PHONY : source/kmeans/kmeans_lloyd_dense_batch.cpp.o + +source/kmeans/kmeans_lloyd_dense_batch.i: source/kmeans/kmeans_lloyd_dense_batch.cpp.i +.PHONY : source/kmeans/kmeans_lloyd_dense_batch.i + +# target to preprocess a source file +source/kmeans/kmeans_lloyd_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/source/kmeans/kmeans_lloyd_dense_batch.cpp.i +.PHONY : source/kmeans/kmeans_lloyd_dense_batch.cpp.i + +source/kmeans/kmeans_lloyd_dense_batch.s: source/kmeans/kmeans_lloyd_dense_batch.cpp.s +.PHONY : source/kmeans/kmeans_lloyd_dense_batch.s + +# target to generate assembly for a file +source/kmeans/kmeans_lloyd_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/source/kmeans/kmeans_lloyd_dense_batch.cpp.s +.PHONY : source/kmeans/kmeans_lloyd_dense_batch.cpp.s + +source/kmeans_init/kmeans_init_dense.o: source/kmeans_init/kmeans_init_dense.cpp.o +.PHONY : source/kmeans_init/kmeans_init_dense.o + +# target to build an object file +source/kmeans_init/kmeans_init_dense.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/source/kmeans_init/kmeans_init_dense.cpp.o +.PHONY : source/kmeans_init/kmeans_init_dense.cpp.o + +source/kmeans_init/kmeans_init_dense.i: source/kmeans_init/kmeans_init_dense.cpp.i +.PHONY : source/kmeans_init/kmeans_init_dense.i + +# target to preprocess a source file +source/kmeans_init/kmeans_init_dense.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/source/kmeans_init/kmeans_init_dense.cpp.i +.PHONY : source/kmeans_init/kmeans_init_dense.cpp.i + +source/kmeans_init/kmeans_init_dense.s: source/kmeans_init/kmeans_init_dense.cpp.s +.PHONY : source/kmeans_init/kmeans_init_dense.s + +# target to generate assembly for a file +source/kmeans_init/kmeans_init_dense.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/source/kmeans_init/kmeans_init_dense.cpp.s +.PHONY : source/kmeans_init/kmeans_init_dense.cpp.s + +source/knn/knn_cls_brute_force_dense_batch.o: source/knn/knn_cls_brute_force_dense_batch.cpp.o +.PHONY : source/knn/knn_cls_brute_force_dense_batch.o + +# target to build an object file +source/knn/knn_cls_brute_force_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/source/knn/knn_cls_brute_force_dense_batch.cpp.o +.PHONY : source/knn/knn_cls_brute_force_dense_batch.cpp.o + +source/knn/knn_cls_brute_force_dense_batch.i: source/knn/knn_cls_brute_force_dense_batch.cpp.i +.PHONY : source/knn/knn_cls_brute_force_dense_batch.i + +# target to preprocess a source file +source/knn/knn_cls_brute_force_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/source/knn/knn_cls_brute_force_dense_batch.cpp.i +.PHONY : source/knn/knn_cls_brute_force_dense_batch.cpp.i + +source/knn/knn_cls_brute_force_dense_batch.s: source/knn/knn_cls_brute_force_dense_batch.cpp.s +.PHONY : source/knn/knn_cls_brute_force_dense_batch.s + +# target to generate assembly for a file +source/knn/knn_cls_brute_force_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/source/knn/knn_cls_brute_force_dense_batch.cpp.s +.PHONY : source/knn/knn_cls_brute_force_dense_batch.cpp.s + +source/knn/knn_reg_brute_force_dense_batch.o: source/knn/knn_reg_brute_force_dense_batch.cpp.o +.PHONY : source/knn/knn_reg_brute_force_dense_batch.o + +# target to build an object file +source/knn/knn_reg_brute_force_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/source/knn/knn_reg_brute_force_dense_batch.cpp.o +.PHONY : source/knn/knn_reg_brute_force_dense_batch.cpp.o + +source/knn/knn_reg_brute_force_dense_batch.i: source/knn/knn_reg_brute_force_dense_batch.cpp.i +.PHONY : source/knn/knn_reg_brute_force_dense_batch.i + +# target to preprocess a source file +source/knn/knn_reg_brute_force_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/source/knn/knn_reg_brute_force_dense_batch.cpp.i +.PHONY : source/knn/knn_reg_brute_force_dense_batch.cpp.i + +source/knn/knn_reg_brute_force_dense_batch.s: source/knn/knn_reg_brute_force_dense_batch.cpp.s +.PHONY : source/knn/knn_reg_brute_force_dense_batch.s + +# target to generate assembly for a file +source/knn/knn_reg_brute_force_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/source/knn/knn_reg_brute_force_dense_batch.cpp.s +.PHONY : source/knn/knn_reg_brute_force_dense_batch.cpp.s + +source/knn/knn_search_brute_force_dense_batch.o: source/knn/knn_search_brute_force_dense_batch.cpp.o +.PHONY : source/knn/knn_search_brute_force_dense_batch.o + +# target to build an object file +source/knn/knn_search_brute_force_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/source/knn/knn_search_brute_force_dense_batch.cpp.o +.PHONY : source/knn/knn_search_brute_force_dense_batch.cpp.o + +source/knn/knn_search_brute_force_dense_batch.i: source/knn/knn_search_brute_force_dense_batch.cpp.i +.PHONY : source/knn/knn_search_brute_force_dense_batch.i + +# target to preprocess a source file +source/knn/knn_search_brute_force_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/source/knn/knn_search_brute_force_dense_batch.cpp.i +.PHONY : source/knn/knn_search_brute_force_dense_batch.cpp.i + +source/knn/knn_search_brute_force_dense_batch.s: source/knn/knn_search_brute_force_dense_batch.cpp.s +.PHONY : source/knn/knn_search_brute_force_dense_batch.s + +# target to generate assembly for a file +source/knn/knn_search_brute_force_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/source/knn/knn_search_brute_force_dense_batch.cpp.s +.PHONY : source/knn/knn_search_brute_force_dense_batch.cpp.s + +source/linear_kernel/linear_kernel_dense_batch.o: source/linear_kernel/linear_kernel_dense_batch.cpp.o +.PHONY : source/linear_kernel/linear_kernel_dense_batch.o + +# target to build an object file +source/linear_kernel/linear_kernel_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/source/linear_kernel/linear_kernel_dense_batch.cpp.o +.PHONY : source/linear_kernel/linear_kernel_dense_batch.cpp.o + +source/linear_kernel/linear_kernel_dense_batch.i: source/linear_kernel/linear_kernel_dense_batch.cpp.i +.PHONY : source/linear_kernel/linear_kernel_dense_batch.i + +# target to preprocess a source file +source/linear_kernel/linear_kernel_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/source/linear_kernel/linear_kernel_dense_batch.cpp.i +.PHONY : source/linear_kernel/linear_kernel_dense_batch.cpp.i + +source/linear_kernel/linear_kernel_dense_batch.s: source/linear_kernel/linear_kernel_dense_batch.cpp.s +.PHONY : source/linear_kernel/linear_kernel_dense_batch.s + +# target to generate assembly for a file +source/linear_kernel/linear_kernel_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/source/linear_kernel/linear_kernel_dense_batch.cpp.s +.PHONY : source/linear_kernel/linear_kernel_dense_batch.cpp.s + +source/linear_regression/linear_regression_dense_batch.o: source/linear_regression/linear_regression_dense_batch.cpp.o +.PHONY : source/linear_regression/linear_regression_dense_batch.o + +# target to build an object file +source/linear_regression/linear_regression_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/source/linear_regression/linear_regression_dense_batch.cpp.o +.PHONY : source/linear_regression/linear_regression_dense_batch.cpp.o + +source/linear_regression/linear_regression_dense_batch.i: source/linear_regression/linear_regression_dense_batch.cpp.i +.PHONY : source/linear_regression/linear_regression_dense_batch.i + +# target to preprocess a source file +source/linear_regression/linear_regression_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/source/linear_regression/linear_regression_dense_batch.cpp.i +.PHONY : source/linear_regression/linear_regression_dense_batch.cpp.i + +source/linear_regression/linear_regression_dense_batch.s: source/linear_regression/linear_regression_dense_batch.cpp.s +.PHONY : source/linear_regression/linear_regression_dense_batch.s + +# target to generate assembly for a file +source/linear_regression/linear_regression_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/source/linear_regression/linear_regression_dense_batch.cpp.s +.PHONY : source/linear_regression/linear_regression_dense_batch.cpp.s + +source/linear_regression/linear_regression_dense_online.o: source/linear_regression/linear_regression_dense_online.cpp.o +.PHONY : source/linear_regression/linear_regression_dense_online.o + +# target to build an object file +source/linear_regression/linear_regression_dense_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/source/linear_regression/linear_regression_dense_online.cpp.o +.PHONY : source/linear_regression/linear_regression_dense_online.cpp.o + +source/linear_regression/linear_regression_dense_online.i: source/linear_regression/linear_regression_dense_online.cpp.i +.PHONY : source/linear_regression/linear_regression_dense_online.i + +# target to preprocess a source file +source/linear_regression/linear_regression_dense_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/source/linear_regression/linear_regression_dense_online.cpp.i +.PHONY : source/linear_regression/linear_regression_dense_online.cpp.i + +source/linear_regression/linear_regression_dense_online.s: source/linear_regression/linear_regression_dense_online.cpp.s +.PHONY : source/linear_regression/linear_regression_dense_online.s + +# target to generate assembly for a file +source/linear_regression/linear_regression_dense_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/source/linear_regression/linear_regression_dense_online.cpp.s +.PHONY : source/linear_regression/linear_regression_dense_online.cpp.s + +source/logistic_regression/logistic_regression_dense_batch.o: source/logistic_regression/logistic_regression_dense_batch.cpp.o +.PHONY : source/logistic_regression/logistic_regression_dense_batch.o + +# target to build an object file +source/logistic_regression/logistic_regression_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/source/logistic_regression/logistic_regression_dense_batch.cpp.o +.PHONY : source/logistic_regression/logistic_regression_dense_batch.cpp.o + +source/logistic_regression/logistic_regression_dense_batch.i: source/logistic_regression/logistic_regression_dense_batch.cpp.i +.PHONY : source/logistic_regression/logistic_regression_dense_batch.i + +# target to preprocess a source file +source/logistic_regression/logistic_regression_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/source/logistic_regression/logistic_regression_dense_batch.cpp.i +.PHONY : source/logistic_regression/logistic_regression_dense_batch.cpp.i + +source/logistic_regression/logistic_regression_dense_batch.s: source/logistic_regression/logistic_regression_dense_batch.cpp.s +.PHONY : source/logistic_regression/logistic_regression_dense_batch.s + +# target to generate assembly for a file +source/logistic_regression/logistic_regression_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/source/logistic_regression/logistic_regression_dense_batch.cpp.s +.PHONY : source/logistic_regression/logistic_regression_dense_batch.cpp.s + +source/misc/read_batch.o: source/misc/read_batch.cpp.o +.PHONY : source/misc/read_batch.o + +# target to build an object file +source/misc/read_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/source/misc/read_batch.cpp.o +.PHONY : source/misc/read_batch.cpp.o + +source/misc/read_batch.i: source/misc/read_batch.cpp.i +.PHONY : source/misc/read_batch.i + +# target to preprocess a source file +source/misc/read_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/source/misc/read_batch.cpp.i +.PHONY : source/misc/read_batch.cpp.i + +source/misc/read_batch.s: source/misc/read_batch.cpp.s +.PHONY : source/misc/read_batch.s + +# target to generate assembly for a file +source/misc/read_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/source/misc/read_batch.cpp.s +.PHONY : source/misc/read_batch.cpp.s + +source/pca/pca_cor_dense_batch.o: source/pca/pca_cor_dense_batch.cpp.o +.PHONY : source/pca/pca_cor_dense_batch.o + +# target to build an object file +source/pca/pca_cor_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/source/pca/pca_cor_dense_batch.cpp.o +.PHONY : source/pca/pca_cor_dense_batch.cpp.o + +source/pca/pca_cor_dense_batch.i: source/pca/pca_cor_dense_batch.cpp.i +.PHONY : source/pca/pca_cor_dense_batch.i + +# target to preprocess a source file +source/pca/pca_cor_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/source/pca/pca_cor_dense_batch.cpp.i +.PHONY : source/pca/pca_cor_dense_batch.cpp.i + +source/pca/pca_cor_dense_batch.s: source/pca/pca_cor_dense_batch.cpp.s +.PHONY : source/pca/pca_cor_dense_batch.s + +# target to generate assembly for a file +source/pca/pca_cor_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/source/pca/pca_cor_dense_batch.cpp.s +.PHONY : source/pca/pca_cor_dense_batch.cpp.s + +source/pca/pca_cor_dense_online.o: source/pca/pca_cor_dense_online.cpp.o +.PHONY : source/pca/pca_cor_dense_online.o + +# target to build an object file +source/pca/pca_cor_dense_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/source/pca/pca_cor_dense_online.cpp.o +.PHONY : source/pca/pca_cor_dense_online.cpp.o + +source/pca/pca_cor_dense_online.i: source/pca/pca_cor_dense_online.cpp.i +.PHONY : source/pca/pca_cor_dense_online.i + +# target to preprocess a source file +source/pca/pca_cor_dense_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/source/pca/pca_cor_dense_online.cpp.i +.PHONY : source/pca/pca_cor_dense_online.cpp.i + +source/pca/pca_cor_dense_online.s: source/pca/pca_cor_dense_online.cpp.s +.PHONY : source/pca/pca_cor_dense_online.s + +# target to generate assembly for a file +source/pca/pca_cor_dense_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/source/pca/pca_cor_dense_online.cpp.s +.PHONY : source/pca/pca_cor_dense_online.cpp.s + +source/pca/pca_cov_dense_batch.o: source/pca/pca_cov_dense_batch.cpp.o +.PHONY : source/pca/pca_cov_dense_batch.o + +# target to build an object file +source/pca/pca_cov_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/source/pca/pca_cov_dense_batch.cpp.o +.PHONY : source/pca/pca_cov_dense_batch.cpp.o + +source/pca/pca_cov_dense_batch.i: source/pca/pca_cov_dense_batch.cpp.i +.PHONY : source/pca/pca_cov_dense_batch.i + +# target to preprocess a source file +source/pca/pca_cov_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/source/pca/pca_cov_dense_batch.cpp.i +.PHONY : source/pca/pca_cov_dense_batch.cpp.i + +source/pca/pca_cov_dense_batch.s: source/pca/pca_cov_dense_batch.cpp.s +.PHONY : source/pca/pca_cov_dense_batch.s + +# target to generate assembly for a file +source/pca/pca_cov_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/source/pca/pca_cov_dense_batch.cpp.s +.PHONY : source/pca/pca_cov_dense_batch.cpp.s + +source/pca/pca_cov_dense_online.o: source/pca/pca_cov_dense_online.cpp.o +.PHONY : source/pca/pca_cov_dense_online.o + +# target to build an object file +source/pca/pca_cov_dense_online.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/source/pca/pca_cov_dense_online.cpp.o +.PHONY : source/pca/pca_cov_dense_online.cpp.o + +source/pca/pca_cov_dense_online.i: source/pca/pca_cov_dense_online.cpp.i +.PHONY : source/pca/pca_cov_dense_online.i + +# target to preprocess a source file +source/pca/pca_cov_dense_online.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/source/pca/pca_cov_dense_online.cpp.i +.PHONY : source/pca/pca_cov_dense_online.cpp.i + +source/pca/pca_cov_dense_online.s: source/pca/pca_cov_dense_online.cpp.s +.PHONY : source/pca/pca_cov_dense_online.s + +# target to generate assembly for a file +source/pca/pca_cov_dense_online.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/source/pca/pca_cov_dense_online.cpp.s +.PHONY : source/pca/pca_cov_dense_online.cpp.s + +source/pca/pca_precomputed_cor_dense_batch.o: source/pca/pca_precomputed_cor_dense_batch.cpp.o +.PHONY : source/pca/pca_precomputed_cor_dense_batch.o + +# target to build an object file +source/pca/pca_precomputed_cor_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/source/pca/pca_precomputed_cor_dense_batch.cpp.o +.PHONY : source/pca/pca_precomputed_cor_dense_batch.cpp.o + +source/pca/pca_precomputed_cor_dense_batch.i: source/pca/pca_precomputed_cor_dense_batch.cpp.i +.PHONY : source/pca/pca_precomputed_cor_dense_batch.i + +# target to preprocess a source file +source/pca/pca_precomputed_cor_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/source/pca/pca_precomputed_cor_dense_batch.cpp.i +.PHONY : source/pca/pca_precomputed_cor_dense_batch.cpp.i + +source/pca/pca_precomputed_cor_dense_batch.s: source/pca/pca_precomputed_cor_dense_batch.cpp.s +.PHONY : source/pca/pca_precomputed_cor_dense_batch.s + +# target to generate assembly for a file +source/pca/pca_precomputed_cor_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/source/pca/pca_precomputed_cor_dense_batch.cpp.s +.PHONY : source/pca/pca_precomputed_cor_dense_batch.cpp.s + +source/pca/pca_precomputed_cov_dense_batch.o: source/pca/pca_precomputed_cov_dense_batch.cpp.o +.PHONY : source/pca/pca_precomputed_cov_dense_batch.o + +# target to build an object file +source/pca/pca_precomputed_cov_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/source/pca/pca_precomputed_cov_dense_batch.cpp.o +.PHONY : source/pca/pca_precomputed_cov_dense_batch.cpp.o + +source/pca/pca_precomputed_cov_dense_batch.i: source/pca/pca_precomputed_cov_dense_batch.cpp.i +.PHONY : source/pca/pca_precomputed_cov_dense_batch.i + +# target to preprocess a source file +source/pca/pca_precomputed_cov_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/source/pca/pca_precomputed_cov_dense_batch.cpp.i +.PHONY : source/pca/pca_precomputed_cov_dense_batch.cpp.i + +source/pca/pca_precomputed_cov_dense_batch.s: source/pca/pca_precomputed_cov_dense_batch.cpp.s +.PHONY : source/pca/pca_precomputed_cov_dense_batch.s + +# target to generate assembly for a file +source/pca/pca_precomputed_cov_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/source/pca/pca_precomputed_cov_dense_batch.cpp.s +.PHONY : source/pca/pca_precomputed_cov_dense_batch.cpp.s + +source/pca/pca_svd_dense_batch.o: source/pca/pca_svd_dense_batch.cpp.o +.PHONY : source/pca/pca_svd_dense_batch.o + +# target to build an object file +source/pca/pca_svd_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/source/pca/pca_svd_dense_batch.cpp.o +.PHONY : source/pca/pca_svd_dense_batch.cpp.o + +source/pca/pca_svd_dense_batch.i: source/pca/pca_svd_dense_batch.cpp.i +.PHONY : source/pca/pca_svd_dense_batch.i + +# target to preprocess a source file +source/pca/pca_svd_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/source/pca/pca_svd_dense_batch.cpp.i +.PHONY : source/pca/pca_svd_dense_batch.cpp.i + +source/pca/pca_svd_dense_batch.s: source/pca/pca_svd_dense_batch.cpp.s +.PHONY : source/pca/pca_svd_dense_batch.s + +# target to generate assembly for a file +source/pca/pca_svd_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/source/pca/pca_svd_dense_batch.cpp.s +.PHONY : source/pca/pca_svd_dense_batch.cpp.s + +source/rbf_kernel/rbf_kernel_dense_batch.o: source/rbf_kernel/rbf_kernel_dense_batch.cpp.o +.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.o + +# target to build an object file +source/rbf_kernel/rbf_kernel_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/source/rbf_kernel/rbf_kernel_dense_batch.cpp.o +.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.cpp.o + +source/rbf_kernel/rbf_kernel_dense_batch.i: source/rbf_kernel/rbf_kernel_dense_batch.cpp.i +.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.i + +# target to preprocess a source file +source/rbf_kernel/rbf_kernel_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/source/rbf_kernel/rbf_kernel_dense_batch.cpp.i +.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.cpp.i + +source/rbf_kernel/rbf_kernel_dense_batch.s: source/rbf_kernel/rbf_kernel_dense_batch.cpp.s +.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.s + +# target to generate assembly for a file +source/rbf_kernel/rbf_kernel_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/source/rbf_kernel/rbf_kernel_dense_batch.cpp.s +.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.cpp.s + +source/svm/svm_two_class_thunder_dense_batch.o: source/svm/svm_two_class_thunder_dense_batch.cpp.o +.PHONY : source/svm/svm_two_class_thunder_dense_batch.o + +# target to build an object file +source/svm/svm_two_class_thunder_dense_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/source/svm/svm_two_class_thunder_dense_batch.cpp.o +.PHONY : source/svm/svm_two_class_thunder_dense_batch.cpp.o + +source/svm/svm_two_class_thunder_dense_batch.i: source/svm/svm_two_class_thunder_dense_batch.cpp.i +.PHONY : source/svm/svm_two_class_thunder_dense_batch.i + +# target to preprocess a source file +source/svm/svm_two_class_thunder_dense_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/source/svm/svm_two_class_thunder_dense_batch.cpp.i +.PHONY : source/svm/svm_two_class_thunder_dense_batch.cpp.i + +source/svm/svm_two_class_thunder_dense_batch.s: source/svm/svm_two_class_thunder_dense_batch.cpp.s +.PHONY : source/svm/svm_two_class_thunder_dense_batch.s + +# target to generate assembly for a file +source/svm/svm_two_class_thunder_dense_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/source/svm/svm_two_class_thunder_dense_batch.cpp.s +.PHONY : source/svm/svm_two_class_thunder_dense_batch.cpp.s + +source/table/column_accessor_homogen.o: source/table/column_accessor_homogen.cpp.o +.PHONY : source/table/column_accessor_homogen.o + +# target to build an object file +source/table/column_accessor_homogen.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/source/table/column_accessor_homogen.cpp.o +.PHONY : source/table/column_accessor_homogen.cpp.o + +source/table/column_accessor_homogen.i: source/table/column_accessor_homogen.cpp.i +.PHONY : source/table/column_accessor_homogen.i + +# target to preprocess a source file +source/table/column_accessor_homogen.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/source/table/column_accessor_homogen.cpp.i +.PHONY : source/table/column_accessor_homogen.cpp.i + +source/table/column_accessor_homogen.s: source/table/column_accessor_homogen.cpp.s +.PHONY : source/table/column_accessor_homogen.s + +# target to generate assembly for a file +source/table/column_accessor_homogen.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/source/table/column_accessor_homogen.cpp.s +.PHONY : source/table/column_accessor_homogen.cpp.s + +source/table/csr_accessor.o: source/table/csr_accessor.cpp.o +.PHONY : source/table/csr_accessor.o + +# target to build an object file +source/table/csr_accessor.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/source/table/csr_accessor.cpp.o +.PHONY : source/table/csr_accessor.cpp.o + +source/table/csr_accessor.i: source/table/csr_accessor.cpp.i +.PHONY : source/table/csr_accessor.i + +# target to preprocess a source file +source/table/csr_accessor.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/source/table/csr_accessor.cpp.i +.PHONY : source/table/csr_accessor.cpp.i + +source/table/csr_accessor.s: source/table/csr_accessor.cpp.s +.PHONY : source/table/csr_accessor.s + +# target to generate assembly for a file +source/table/csr_accessor.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/source/table/csr_accessor.cpp.s +.PHONY : source/table/csr_accessor.cpp.s + +source/table/csr_table.o: source/table/csr_table.cpp.o +.PHONY : source/table/csr_table.o + +# target to build an object file +source/table/csr_table.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/source/table/csr_table.cpp.o +.PHONY : source/table/csr_table.cpp.o + +source/table/csr_table.i: source/table/csr_table.cpp.i +.PHONY : source/table/csr_table.i + +# target to preprocess a source file +source/table/csr_table.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/source/table/csr_table.cpp.i +.PHONY : source/table/csr_table.cpp.i + +source/table/csr_table.s: source/table/csr_table.cpp.s +.PHONY : source/table/csr_table.s + +# target to generate assembly for a file +source/table/csr_table.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/source/table/csr_table.cpp.s +.PHONY : source/table/csr_table.cpp.s + +source/table/heterogen_table.o: source/table/heterogen_table.cpp.o +.PHONY : source/table/heterogen_table.o + +# target to build an object file +source/table/heterogen_table.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/source/table/heterogen_table.cpp.o +.PHONY : source/table/heterogen_table.cpp.o + +source/table/heterogen_table.i: source/table/heterogen_table.cpp.i +.PHONY : source/table/heterogen_table.i + +# target to preprocess a source file +source/table/heterogen_table.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/source/table/heterogen_table.cpp.i +.PHONY : source/table/heterogen_table.cpp.i + +source/table/heterogen_table.s: source/table/heterogen_table.cpp.s +.PHONY : source/table/heterogen_table.s + +# target to generate assembly for a file +source/table/heterogen_table.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/source/table/heterogen_table.cpp.s +.PHONY : source/table/heterogen_table.cpp.s + +source/table/homogen_table.o: source/table/homogen_table.cpp.o +.PHONY : source/table/homogen_table.o + +# target to build an object file +source/table/homogen_table.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/source/table/homogen_table.cpp.o +.PHONY : source/table/homogen_table.cpp.o + +source/table/homogen_table.i: source/table/homogen_table.cpp.i +.PHONY : source/table/homogen_table.i + +# target to preprocess a source file +source/table/homogen_table.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/source/table/homogen_table.cpp.i +.PHONY : source/table/homogen_table.cpp.i + +source/table/homogen_table.s: source/table/homogen_table.cpp.s +.PHONY : source/table/homogen_table.s + +# target to generate assembly for a file +source/table/homogen_table.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/source/table/homogen_table.cpp.s +.PHONY : source/table/homogen_table.cpp.s + +source/triangle_counting/triangle_counting_batch.o: source/triangle_counting/triangle_counting_batch.cpp.o +.PHONY : source/triangle_counting/triangle_counting_batch.o + +# target to build an object file +source/triangle_counting/triangle_counting_batch.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/source/triangle_counting/triangle_counting_batch.cpp.o +.PHONY : source/triangle_counting/triangle_counting_batch.cpp.o + +source/triangle_counting/triangle_counting_batch.i: source/triangle_counting/triangle_counting_batch.cpp.i +.PHONY : source/triangle_counting/triangle_counting_batch.i + +# target to preprocess a source file +source/triangle_counting/triangle_counting_batch.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/source/triangle_counting/triangle_counting_batch.cpp.i +.PHONY : source/triangle_counting/triangle_counting_batch.cpp.i + +source/triangle_counting/triangle_counting_batch.s: source/triangle_counting/triangle_counting_batch.cpp.s +.PHONY : source/triangle_counting/triangle_counting_batch.s + +# target to generate assembly for a file +source/triangle_counting/triangle_counting_batch.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/source/triangle_counting/triangle_counting_batch.cpp.s +.PHONY : source/triangle_counting/triangle_counting_batch.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... rebuild_cache" + @echo "... basic_statistics_dense_batch" + @echo "... basic_statistics_dense_online" + @echo "... column_accessor_homogen" + @echo "... connected_components_batch" + @echo "... cor_dense_batch" + @echo "... cor_dense_online" + @echo "... correlation_distance_dense_batch" + @echo "... cosine_distance_dense_batch" + @echo "... cov_dense_batch" + @echo "... cov_dense_biased_batch" + @echo "... cov_dense_biased_online" + @echo "... cov_dense_online" + @echo "... csr_accessor" + @echo "... csr_table" + @echo "... dbscan_brute_force_batch" + @echo "... df_cls_hist_batch" + @echo "... df_cls_hist_batch_random" + @echo "... df_cls_traverse_model" + @echo "... df_reg_hist_batch" + @echo "... df_reg_hist_batch_random" + @echo "... df_reg_traverse_model" + @echo "... heterogen_table" + @echo "... homogen_table" + @echo "... kmeans_init_dense" + @echo "... kmeans_lloyd_csr_batch" + @echo "... kmeans_lloyd_dense_batch" + @echo "... knn_cls_brute_force_dense_batch" + @echo "... knn_reg_brute_force_dense_batch" + @echo "... knn_search_brute_force_dense_batch" + @echo "... linear_kernel_dense_batch" + @echo "... linear_regression_dense_batch" + @echo "... linear_regression_dense_online" + @echo "... logistic_regression_dense_batch" + @echo "... pca_cor_dense_batch" + @echo "... pca_cor_dense_online" + @echo "... pca_cov_dense_batch" + @echo "... pca_cov_dense_online" + @echo "... pca_precomputed_cor_dense_batch" + @echo "... pca_precomputed_cov_dense_batch" + @echo "... pca_svd_dense_batch" + @echo "... rbf_kernel_dense_batch" + @echo "... read_batch" + @echo "... svm_two_class_thunder_dense_batch" + @echo "... triangle_counting_batch" + @echo "... source/basic_statistics/basic_statistics_dense_batch.o" + @echo "... source/basic_statistics/basic_statistics_dense_batch.i" + @echo "... source/basic_statistics/basic_statistics_dense_batch.s" + @echo "... source/basic_statistics/basic_statistics_dense_online.o" + @echo "... source/basic_statistics/basic_statistics_dense_online.i" + @echo "... source/basic_statistics/basic_statistics_dense_online.s" + @echo "... source/connected_components/connected_components_batch.o" + @echo "... source/connected_components/connected_components_batch.i" + @echo "... source/connected_components/connected_components_batch.s" + @echo "... source/correlation_distance/correlation_distance_dense_batch.o" + @echo "... source/correlation_distance/correlation_distance_dense_batch.i" + @echo "... source/correlation_distance/correlation_distance_dense_batch.s" + @echo "... source/cosine_distance/cosine_distance_dense_batch.o" + @echo "... source/cosine_distance/cosine_distance_dense_batch.i" + @echo "... source/cosine_distance/cosine_distance_dense_batch.s" + @echo "... source/covariance/cor_dense_batch.o" + @echo "... source/covariance/cor_dense_batch.i" + @echo "... source/covariance/cor_dense_batch.s" + @echo "... source/covariance/cor_dense_online.o" + @echo "... source/covariance/cor_dense_online.i" + @echo "... source/covariance/cor_dense_online.s" + @echo "... source/covariance/cov_dense_batch.o" + @echo "... source/covariance/cov_dense_batch.i" + @echo "... source/covariance/cov_dense_batch.s" + @echo "... source/covariance/cov_dense_biased_batch.o" + @echo "... source/covariance/cov_dense_biased_batch.i" + @echo "... source/covariance/cov_dense_biased_batch.s" + @echo "... source/covariance/cov_dense_biased_online.o" + @echo "... source/covariance/cov_dense_biased_online.i" + @echo "... source/covariance/cov_dense_biased_online.s" + @echo "... source/covariance/cov_dense_online.o" + @echo "... source/covariance/cov_dense_online.i" + @echo "... source/covariance/cov_dense_online.s" + @echo "... source/dbscan/dbscan_brute_force_batch.o" + @echo "... source/dbscan/dbscan_brute_force_batch.i" + @echo "... source/dbscan/dbscan_brute_force_batch.s" + @echo "... source/decision_forest/df_cls_hist_batch.o" + @echo "... source/decision_forest/df_cls_hist_batch.i" + @echo "... source/decision_forest/df_cls_hist_batch.s" + @echo "... source/decision_forest/df_cls_hist_batch_random.o" + @echo "... source/decision_forest/df_cls_hist_batch_random.i" + @echo "... source/decision_forest/df_cls_hist_batch_random.s" + @echo "... source/decision_forest/df_cls_traverse_model.o" + @echo "... source/decision_forest/df_cls_traverse_model.i" + @echo "... source/decision_forest/df_cls_traverse_model.s" + @echo "... source/decision_forest/df_reg_hist_batch.o" + @echo "... source/decision_forest/df_reg_hist_batch.i" + @echo "... source/decision_forest/df_reg_hist_batch.s" + @echo "... source/decision_forest/df_reg_hist_batch_random.o" + @echo "... source/decision_forest/df_reg_hist_batch_random.i" + @echo "... source/decision_forest/df_reg_hist_batch_random.s" + @echo "... source/decision_forest/df_reg_traverse_model.o" + @echo "... source/decision_forest/df_reg_traverse_model.i" + @echo "... source/decision_forest/df_reg_traverse_model.s" + @echo "... source/kmeans/kmeans_lloyd_csr_batch.o" + @echo "... source/kmeans/kmeans_lloyd_csr_batch.i" + @echo "... source/kmeans/kmeans_lloyd_csr_batch.s" + @echo "... source/kmeans/kmeans_lloyd_dense_batch.o" + @echo "... source/kmeans/kmeans_lloyd_dense_batch.i" + @echo "... source/kmeans/kmeans_lloyd_dense_batch.s" + @echo "... source/kmeans_init/kmeans_init_dense.o" + @echo "... source/kmeans_init/kmeans_init_dense.i" + @echo "... source/kmeans_init/kmeans_init_dense.s" + @echo "... source/knn/knn_cls_brute_force_dense_batch.o" + @echo "... source/knn/knn_cls_brute_force_dense_batch.i" + @echo "... source/knn/knn_cls_brute_force_dense_batch.s" + @echo "... source/knn/knn_reg_brute_force_dense_batch.o" + @echo "... source/knn/knn_reg_brute_force_dense_batch.i" + @echo "... source/knn/knn_reg_brute_force_dense_batch.s" + @echo "... source/knn/knn_search_brute_force_dense_batch.o" + @echo "... source/knn/knn_search_brute_force_dense_batch.i" + @echo "... source/knn/knn_search_brute_force_dense_batch.s" + @echo "... source/linear_kernel/linear_kernel_dense_batch.o" + @echo "... source/linear_kernel/linear_kernel_dense_batch.i" + @echo "... source/linear_kernel/linear_kernel_dense_batch.s" + @echo "... source/linear_regression/linear_regression_dense_batch.o" + @echo "... source/linear_regression/linear_regression_dense_batch.i" + @echo "... source/linear_regression/linear_regression_dense_batch.s" + @echo "... source/linear_regression/linear_regression_dense_online.o" + @echo "... source/linear_regression/linear_regression_dense_online.i" + @echo "... source/linear_regression/linear_regression_dense_online.s" + @echo "... source/logistic_regression/logistic_regression_dense_batch.o" + @echo "... source/logistic_regression/logistic_regression_dense_batch.i" + @echo "... source/logistic_regression/logistic_regression_dense_batch.s" + @echo "... source/misc/read_batch.o" + @echo "... source/misc/read_batch.i" + @echo "... source/misc/read_batch.s" + @echo "... source/pca/pca_cor_dense_batch.o" + @echo "... source/pca/pca_cor_dense_batch.i" + @echo "... source/pca/pca_cor_dense_batch.s" + @echo "... source/pca/pca_cor_dense_online.o" + @echo "... source/pca/pca_cor_dense_online.i" + @echo "... source/pca/pca_cor_dense_online.s" + @echo "... source/pca/pca_cov_dense_batch.o" + @echo "... source/pca/pca_cov_dense_batch.i" + @echo "... source/pca/pca_cov_dense_batch.s" + @echo "... source/pca/pca_cov_dense_online.o" + @echo "... source/pca/pca_cov_dense_online.i" + @echo "... source/pca/pca_cov_dense_online.s" + @echo "... source/pca/pca_precomputed_cor_dense_batch.o" + @echo "... source/pca/pca_precomputed_cor_dense_batch.i" + @echo "... source/pca/pca_precomputed_cor_dense_batch.s" + @echo "... source/pca/pca_precomputed_cov_dense_batch.o" + @echo "... source/pca/pca_precomputed_cov_dense_batch.i" + @echo "... source/pca/pca_precomputed_cov_dense_batch.s" + @echo "... source/pca/pca_svd_dense_batch.o" + @echo "... source/pca/pca_svd_dense_batch.i" + @echo "... source/pca/pca_svd_dense_batch.s" + @echo "... source/rbf_kernel/rbf_kernel_dense_batch.o" + @echo "... source/rbf_kernel/rbf_kernel_dense_batch.i" + @echo "... source/rbf_kernel/rbf_kernel_dense_batch.s" + @echo "... source/svm/svm_two_class_thunder_dense_batch.o" + @echo "... source/svm/svm_two_class_thunder_dense_batch.i" + @echo "... source/svm/svm_two_class_thunder_dense_batch.s" + @echo "... source/table/column_accessor_homogen.o" + @echo "... source/table/column_accessor_homogen.i" + @echo "... source/table/column_accessor_homogen.s" + @echo "... source/table/csr_accessor.o" + @echo "... source/table/csr_accessor.i" + @echo "... source/table/csr_accessor.s" + @echo "... source/table/csr_table.o" + @echo "... source/table/csr_table.i" + @echo "... source/table/csr_table.s" + @echo "... source/table/heterogen_table.o" + @echo "... source/table/heterogen_table.i" + @echo "... source/table/heterogen_table.s" + @echo "... source/table/homogen_table.o" + @echo "... source/table/homogen_table.i" + @echo "... source/table/homogen_table.s" + @echo "... source/triangle_counting/triangle_counting_batch.o" + @echo "... source/triangle_counting/triangle_counting_batch.i" + @echo "... source/triangle_counting/triangle_counting_batch.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/examples/oneapi/dpc/build/cmake_install.cmake b/examples/oneapi/dpc/build/cmake_install.cmake new file mode 100644 index 00000000000..15527649405 --- /dev/null +++ b/examples/oneapi/dpc/build/cmake_install.cmake @@ -0,0 +1,54 @@ +# Install script for directory: /export/users/okruglov/oneDAL/examples/oneapi/dpc + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Release") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +# Is this installation the result of a crosscompile? +if(NOT DEFINED CMAKE_CROSSCOMPILING) + set(CMAKE_CROSSCOMPILING "FALSE") +endif() + +# Set default install directory permissions. +if(NOT DEFINED CMAKE_OBJDUMP) + set(CMAKE_OBJDUMP "/usr/bin/objdump") +endif() + +if(CMAKE_INSTALL_COMPONENT) + set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") +else() + set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +endif() + +string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT + "${CMAKE_INSTALL_MANIFEST_FILES}") +file(WRITE "/export/users/okruglov/oneDAL/examples/oneapi/dpc/build/${CMAKE_INSTALL_MANIFEST}" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") diff --git a/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp b/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp new file mode 100644 index 00000000000..8181be33b79 --- /dev/null +++ b/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp @@ -0,0 +1,58 @@ +/******************************************************************************* +* 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 +#include + +#ifndef ONEDAL_DATA_PARALLEL +#define ONEDAL_DATA_PARALLEL +#endif + +#include "oneapi/dal/algo/connected_components.hpp" +#include "oneapi/dal/graph/undirected_adjacency_vector_graph.hpp" +#include "oneapi/dal/io/csv.hpp" + +#include "example_util/utils.hpp" + +namespace dal = oneapi::dal; + +void run(sycl::queue& q) { + const auto filename = get_data_path("data/graph.csv"); + + using graph_t = dal::preview::undirected_adjacency_vector_graph<>; + auto graph = dal::read(dal::csv::data_source{ filename }); + + graph.to_device(q); + + const auto cc_desc = dal::preview::connected_components::descriptor<>(); + + const auto result = dal::preview::vertex_partitioning(q, cc_desc, graph); + + std::cout << "Number of connected components: " << result.get_component_count() << std::endl; + std::cout << "Components' labels:" << std::endl; + std::cout << result.get_labels() << std::endl; +} + +int main(int argc, char const* argv[]) { + for (auto d : list_devices()) { + std::cout << "Running on " << d.get_platform().get_info() + << ", " << d.get_info() << "\n" + << std::endl; + auto q = sycl::queue{ d }; + run(q); + } + return 0; +} From 51c088f9e53e9d640c45b6fcca11a707319bea82 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Sun, 10 May 2026 10:53:16 -0700 Subject: [PATCH 65/69] CI fix --- .../backend/gpu/CMakeLists.txt | 16 ++++++++++++++ .../backend/gpu/connected_components.hpp | 2 +- ...ex_partitioning_default_kernel_gpu_dpc.cpp | 19 +++++++---------- .../gpu/vertex_partitioning_kernel.hpp | 4 ++-- .../detail/select_kernel.hpp | 2 +- .../detail/select_kernel_dpc.cpp | 21 +++++++------------ .../test/connected_components_gpu_test.cpp | 2 +- cpp/oneapi/dal/graph/detail/csr_topology.hpp | 18 ++++++++++------ cpp/oneapi/dal/vertex_partitioning.hpp | 2 +- .../connected_components_batch.cpp | 2 +- 10 files changed, 51 insertions(+), 37 deletions(-) diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt b/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt index 105230f978f..3d2ef8cd1f1 100644 --- a/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/CMakeLists.txt @@ -1,3 +1,19 @@ +#=============================================================================== +# Copyright 2026 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. +#=============================================================================== + set(ONEDAL_CONNECTED_COMPONENTS_BACKEND_GPU_HEADERS ${CMAKE_CURRENT_LIST_DIR}/connected_components.hpp ${CMAKE_CURRENT_LIST_DIR}/vertex_partitioning_kernel.hpp diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp b/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp index 1d8fb2ed78d..2d67863c840 100644 --- a/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/connected_components.hpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp index aa686630e46..753625468d6 100644 --- a/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_default_kernel_gpu_dpc.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -143,11 +143,10 @@ std::int32_t* compute_components_gpu(sycl::queue& queue, return labels; } - csr_graph_device_wrapper graph( - queue, - static_cast(vertex_count), - rows, - cols); + csr_graph_device_wrapper graph(queue, + static_cast(vertex_count), + rows, + cols); fp::frontier in_frontier(queue, vertex_count, sycl::usm::alloc::device); fp::frontier out_frontier(queue, vertex_count, sycl::usm::alloc::device); @@ -179,8 +178,7 @@ std::int32_t* compute_components_gpu(sycl::queue& queue, sycl::atomic_ref( - d_labels[dst]) + sycl::access::address_space::global_space>(d_labels[dst]) .fetch_min(label_src); return label_src < old_val; } @@ -245,9 +243,8 @@ vertex_partitioning_result run_vertex_partitioning_gpu( }); vertex_partitioning_result result; - result.set_labels(dal::detail::homogen_table_builder{} - .reset(labels_arr, vertex_count, 1) - .build()); + result.set_labels( + dal::detail::homogen_table_builder{}.reset(labels_arr, vertex_count, 1).build()); result.set_component_count(component_count); return result; diff --git a/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp index 27c2d0da948..c71a801885e 100644 --- a/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp +++ b/cpp/oneapi/dal/algo/connected_components/backend/gpu/vertex_partitioning_kernel.hpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ struct csr_topology_gpu_view { template csr_topology_gpu_view make_gpu_view( - const dal::preview::detail::device_csr_topology& device_topo) { + const dal::preview::detail::device_csr_topology& device_topo) { csr_topology_gpu_view view; view.rows = device_topo.get_rows(); view.cols = device_topo.get_cols(); diff --git a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp index 999a2fc583b..e6a47bdb9fb 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel.hpp @@ -79,7 +79,7 @@ struct backend_default template dal::detail::shared> get_backend(const Descriptor& desc, - const Topology& t) { + const Topology& t) { return std::make_shared>(); } diff --git a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp index 627f2085510..07b44340ff3 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/select_kernel_dpc.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,23 +42,18 @@ backend_default::operat }, [&]() { dal::backend::context_gpu gpu_ctx{ ctx }; - return backend::vertex_partitioning_kernel_gpu()( - gpu_ctx, - descriptor, - t); + return backend::vertex_partitioning_kernel_gpu()(gpu_ctx, + descriptor, + t); }); } -using default_descriptor = descriptor< - float, - method::afforest, - task::vertex_partitioning, - std::allocator>; +using default_descriptor = + descriptor>; using default_topology = dal::preview::detail::topology; -template struct ONEDAL_EXPORT backend_default; +template struct ONEDAL_EXPORT + backend_default; } // namespace oneapi::dal::preview::connected_components::detail diff --git a/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp b/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp index 878b449261b..e0cf6685d23 100644 --- a/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp +++ b/cpp/oneapi/dal/algo/connected_components/test/connected_components_gpu_test.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cpp/oneapi/dal/graph/detail/csr_topology.hpp b/cpp/oneapi/dal/graph/detail/csr_topology.hpp index c661be73d03..44dd8102bf7 100644 --- a/cpp/oneapi/dal/graph/detail/csr_topology.hpp +++ b/cpp/oneapi/dal/graph/detail/csr_topology.hpp @@ -174,17 +174,23 @@ class topology { if (degrees_count > 0) { auto device_degrees = vertex_set::empty(queue, degrees_count, sycl::usm::alloc::shared); - queue.memcpy(device_degrees.get_mutable_data(), _degrees.get_data(), - degrees_count * sizeof(vertex_type)).wait_and_throw(); + queue + .memcpy(device_degrees.get_mutable_data(), + _degrees.get_data(), + degrees_count * sizeof(vertex_type)) + .wait_and_throw(); result._degrees = device_degrees; result._degrees_ptr = result._degrees.get_data(); } if (rows_vertex_count > 0) { - auto device_rows_vertex = vertex_edge_set::empty(queue, rows_vertex_count, - sycl::usm::alloc::shared); - queue.memcpy(device_rows_vertex.get_mutable_data(), _rows_vertex.get_data(), - rows_vertex_count * sizeof(vertex_edge_type)).wait_and_throw(); + auto device_rows_vertex = + vertex_edge_set::empty(queue, rows_vertex_count, sycl::usm::alloc::shared); + queue + .memcpy(device_rows_vertex.get_mutable_data(), + _rows_vertex.get_data(), + rows_vertex_count * sizeof(vertex_edge_type)) + .wait_and_throw(); result._rows_vertex = device_rows_vertex; } diff --git a/cpp/oneapi/dal/vertex_partitioning.hpp b/cpp/oneapi/dal/vertex_partitioning.hpp index 342156e039c..097ebbf9255 100644 --- a/cpp/oneapi/dal/vertex_partitioning.hpp +++ b/cpp/oneapi/dal/vertex_partitioning.hpp @@ -31,7 +31,7 @@ auto vertex_partitioning(Args &&...args) { #ifdef ONEDAL_DATA_PARALLEL template -auto vertex_partitioning(sycl::queue& q, Args &&...args) { +auto vertex_partitioning(sycl::queue &q, Args &&...args) { const auto policy = dal::detail::data_parallel_policy{ q }; return detail::vertex_partitioning_dispatch(policy, std::forward(args)...); } diff --git a/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp b/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp index 8181be33b79..b4ad445ad8c 100644 --- a/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp +++ b/examples/oneapi/dpc/source/connected_components/connected_components_batch.cpp @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright 2021 Intel Corporation +* Copyright 2026 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 7b82ee124d8f57c0e6f8660077d99774bc26f2fe Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Sun, 10 May 2026 11:32:37 -0700 Subject: [PATCH 66/69] Deleted accidentally pushed --- .../connected_components_batch | Bin 511008 -> 0 bytes .../intel_intel64_so/triangle_counting_batch | Bin 515016 -> 0 bytes examples/oneapi/dpc/build/Makefile | 1944 ----------------- examples/oneapi/dpc/build/cmake_install.cmake | 54 - 4 files changed, 1998 deletions(-) delete mode 100755 examples/oneapi/dpc/_cmake_results/intel_intel64_so/connected_components_batch delete mode 100755 examples/oneapi/dpc/_cmake_results/intel_intel64_so/triangle_counting_batch delete mode 100644 examples/oneapi/dpc/build/Makefile delete mode 100644 examples/oneapi/dpc/build/cmake_install.cmake diff --git a/examples/oneapi/dpc/_cmake_results/intel_intel64_so/connected_components_batch b/examples/oneapi/dpc/_cmake_results/intel_intel64_so/connected_components_batch deleted file mode 100755 index be27c0f191b01a82d781ef84f0bdcb8909e80bbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 511008 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
WiON7=4wg*~e*eYn1 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 G&i?}nJ;#Lr diff --git a/examples/oneapi/dpc/build/Makefile b/examples/oneapi/dpc/build/Makefile deleted file mode 100644 index 792d9aa324c..00000000000 --- a/examples/oneapi/dpc/build/Makefile +++ /dev/null @@ -1,1944 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 3.25 - -# Default target executed when no arguments are given to make. -default_target: all -.PHONY : default_target - -# Allow only one "make -f Makefile2" at a time, but pass parallelism. -.NOTPARALLEL: - -#============================================================================= -# Special targets provided by cmake. - -# Disable implicit rules so canonical targets will work. -.SUFFIXES: - -# Disable VCS-based implicit rules. -% : %,v - -# Disable VCS-based implicit rules. -% : RCS/% - -# Disable VCS-based implicit rules. -% : RCS/%,v - -# Disable VCS-based implicit rules. -% : SCCS/s.% - -# Disable VCS-based implicit rules. -% : s.% - -.SUFFIXES: .hpux_make_needs_suffix_list - -# Command-line flag to silence nested $(MAKE). -$(VERBOSE)MAKESILENT = -s - -#Suppress display of executed commands. -$(VERBOSE).SILENT: - -# A target that is always out of date. -cmake_force: -.PHONY : cmake_force - -#============================================================================= -# Set environment variables for the build. - -# The shell in which to execute make rules. -SHELL = /bin/sh - -# The CMake executable. -CMAKE_COMMAND = /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/cmake - -# The command to remove a file. -RM = /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/cmake -E rm -f - -# Escaping for special characters. -EQUALS = = - -# The top-level source directory on which CMake was run. -CMAKE_SOURCE_DIR = /export/users/okruglov/oneDAL/examples/oneapi/dpc - -# The top-level build directory on which CMake was run. -CMAKE_BINARY_DIR = /export/users/okruglov/oneDAL/examples/oneapi/dpc/build - -#============================================================================= -# Targets provided globally by CMake. - -# Special rule for the target edit_cache -edit_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..." - /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/ccmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : edit_cache - -# Special rule for the target edit_cache -edit_cache/fast: edit_cache -.PHONY : edit_cache/fast - -# Special rule for the target rebuild_cache -rebuild_cache: - @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." - /localdisk2/mkl/okruglov/cache/cmake/3.25.2/lnx/package/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -.PHONY : rebuild_cache - -# Special rule for the target rebuild_cache -rebuild_cache/fast: rebuild_cache -.PHONY : rebuild_cache/fast - -# The main all target -all: cmake_check_build_system - $(CMAKE_COMMAND) -E cmake_progress_start /export/users/okruglov/oneDAL/examples/oneapi/dpc/build/CMakeFiles /export/users/okruglov/oneDAL/examples/oneapi/dpc/build//CMakeFiles/progress.marks - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all - $(CMAKE_COMMAND) -E cmake_progress_start /export/users/okruglov/oneDAL/examples/oneapi/dpc/build/CMakeFiles 0 -.PHONY : all - -# The main clean target -clean: - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean -.PHONY : clean - -# The main clean target -clean/fast: clean -.PHONY : clean/fast - -# Prepare targets for installation. -preinstall: all - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall - -# Prepare targets for installation. -preinstall/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall -.PHONY : preinstall/fast - -# clear depends -depend: - $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 -.PHONY : depend - -#============================================================================= -# Target rules for targets named basic_statistics_dense_batch - -# Build rule for target. -basic_statistics_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 basic_statistics_dense_batch -.PHONY : basic_statistics_dense_batch - -# fast build rule for target. -basic_statistics_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/build -.PHONY : basic_statistics_dense_batch/fast - -#============================================================================= -# Target rules for targets named basic_statistics_dense_online - -# Build rule for target. -basic_statistics_dense_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 basic_statistics_dense_online -.PHONY : basic_statistics_dense_online - -# fast build rule for target. -basic_statistics_dense_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/build -.PHONY : basic_statistics_dense_online/fast - -#============================================================================= -# Target rules for targets named connected_components_batch - -# Build rule for target. -connected_components_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 connected_components_batch -.PHONY : connected_components_batch - -# fast build rule for target. -connected_components_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/build -.PHONY : connected_components_batch/fast - -#============================================================================= -# Target rules for targets named correlation_distance_dense_batch - -# Build rule for target. -correlation_distance_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 correlation_distance_dense_batch -.PHONY : correlation_distance_dense_batch - -# fast build rule for target. -correlation_distance_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/build -.PHONY : correlation_distance_dense_batch/fast - -#============================================================================= -# Target rules for targets named cosine_distance_dense_batch - -# Build rule for target. -cosine_distance_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cosine_distance_dense_batch -.PHONY : cosine_distance_dense_batch - -# fast build rule for target. -cosine_distance_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/build -.PHONY : cosine_distance_dense_batch/fast - -#============================================================================= -# Target rules for targets named cor_dense_batch - -# Build rule for target. -cor_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cor_dense_batch -.PHONY : cor_dense_batch - -# fast build rule for target. -cor_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/build -.PHONY : cor_dense_batch/fast - -#============================================================================= -# Target rules for targets named cor_dense_online - -# Build rule for target. -cor_dense_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cor_dense_online -.PHONY : cor_dense_online - -# fast build rule for target. -cor_dense_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/build -.PHONY : cor_dense_online/fast - -#============================================================================= -# Target rules for targets named cov_dense_batch - -# Build rule for target. -cov_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_batch -.PHONY : cov_dense_batch - -# fast build rule for target. -cov_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/build -.PHONY : cov_dense_batch/fast - -#============================================================================= -# Target rules for targets named cov_dense_biased_batch - -# Build rule for target. -cov_dense_biased_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_biased_batch -.PHONY : cov_dense_biased_batch - -# fast build rule for target. -cov_dense_biased_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/build -.PHONY : cov_dense_biased_batch/fast - -#============================================================================= -# Target rules for targets named cov_dense_biased_online - -# Build rule for target. -cov_dense_biased_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_biased_online -.PHONY : cov_dense_biased_online - -# fast build rule for target. -cov_dense_biased_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/build -.PHONY : cov_dense_biased_online/fast - -#============================================================================= -# Target rules for targets named cov_dense_online - -# Build rule for target. -cov_dense_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cov_dense_online -.PHONY : cov_dense_online - -# fast build rule for target. -cov_dense_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/build -.PHONY : cov_dense_online/fast - -#============================================================================= -# Target rules for targets named dbscan_brute_force_batch - -# Build rule for target. -dbscan_brute_force_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 dbscan_brute_force_batch -.PHONY : dbscan_brute_force_batch - -# fast build rule for target. -dbscan_brute_force_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/build -.PHONY : dbscan_brute_force_batch/fast - -#============================================================================= -# Target rules for targets named df_cls_hist_batch - -# Build rule for target. -df_cls_hist_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_cls_hist_batch -.PHONY : df_cls_hist_batch - -# fast build rule for target. -df_cls_hist_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/build -.PHONY : df_cls_hist_batch/fast - -#============================================================================= -# Target rules for targets named df_cls_hist_batch_random - -# Build rule for target. -df_cls_hist_batch_random: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_cls_hist_batch_random -.PHONY : df_cls_hist_batch_random - -# fast build rule for target. -df_cls_hist_batch_random/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/build -.PHONY : df_cls_hist_batch_random/fast - -#============================================================================= -# Target rules for targets named df_cls_traverse_model - -# Build rule for target. -df_cls_traverse_model: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_cls_traverse_model -.PHONY : df_cls_traverse_model - -# fast build rule for target. -df_cls_traverse_model/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/build -.PHONY : df_cls_traverse_model/fast - -#============================================================================= -# Target rules for targets named df_reg_hist_batch - -# Build rule for target. -df_reg_hist_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_reg_hist_batch -.PHONY : df_reg_hist_batch - -# fast build rule for target. -df_reg_hist_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/build -.PHONY : df_reg_hist_batch/fast - -#============================================================================= -# Target rules for targets named df_reg_hist_batch_random - -# Build rule for target. -df_reg_hist_batch_random: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_reg_hist_batch_random -.PHONY : df_reg_hist_batch_random - -# fast build rule for target. -df_reg_hist_batch_random/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/build -.PHONY : df_reg_hist_batch_random/fast - -#============================================================================= -# Target rules for targets named df_reg_traverse_model - -# Build rule for target. -df_reg_traverse_model: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 df_reg_traverse_model -.PHONY : df_reg_traverse_model - -# fast build rule for target. -df_reg_traverse_model/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/build -.PHONY : df_reg_traverse_model/fast - -#============================================================================= -# Target rules for targets named kmeans_lloyd_csr_batch - -# Build rule for target. -kmeans_lloyd_csr_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kmeans_lloyd_csr_batch -.PHONY : kmeans_lloyd_csr_batch - -# fast build rule for target. -kmeans_lloyd_csr_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/build -.PHONY : kmeans_lloyd_csr_batch/fast - -#============================================================================= -# Target rules for targets named kmeans_lloyd_dense_batch - -# Build rule for target. -kmeans_lloyd_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kmeans_lloyd_dense_batch -.PHONY : kmeans_lloyd_dense_batch - -# fast build rule for target. -kmeans_lloyd_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/build -.PHONY : kmeans_lloyd_dense_batch/fast - -#============================================================================= -# Target rules for targets named kmeans_init_dense - -# Build rule for target. -kmeans_init_dense: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 kmeans_init_dense -.PHONY : kmeans_init_dense - -# fast build rule for target. -kmeans_init_dense/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/build -.PHONY : kmeans_init_dense/fast - -#============================================================================= -# Target rules for targets named knn_cls_brute_force_dense_batch - -# Build rule for target. -knn_cls_brute_force_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 knn_cls_brute_force_dense_batch -.PHONY : knn_cls_brute_force_dense_batch - -# fast build rule for target. -knn_cls_brute_force_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/build -.PHONY : knn_cls_brute_force_dense_batch/fast - -#============================================================================= -# Target rules for targets named knn_reg_brute_force_dense_batch - -# Build rule for target. -knn_reg_brute_force_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 knn_reg_brute_force_dense_batch -.PHONY : knn_reg_brute_force_dense_batch - -# fast build rule for target. -knn_reg_brute_force_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/build -.PHONY : knn_reg_brute_force_dense_batch/fast - -#============================================================================= -# Target rules for targets named knn_search_brute_force_dense_batch - -# Build rule for target. -knn_search_brute_force_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 knn_search_brute_force_dense_batch -.PHONY : knn_search_brute_force_dense_batch - -# fast build rule for target. -knn_search_brute_force_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/build -.PHONY : knn_search_brute_force_dense_batch/fast - -#============================================================================= -# Target rules for targets named linear_kernel_dense_batch - -# Build rule for target. -linear_kernel_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 linear_kernel_dense_batch -.PHONY : linear_kernel_dense_batch - -# fast build rule for target. -linear_kernel_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/build -.PHONY : linear_kernel_dense_batch/fast - -#============================================================================= -# Target rules for targets named linear_regression_dense_batch - -# Build rule for target. -linear_regression_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 linear_regression_dense_batch -.PHONY : linear_regression_dense_batch - -# fast build rule for target. -linear_regression_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/build -.PHONY : linear_regression_dense_batch/fast - -#============================================================================= -# Target rules for targets named linear_regression_dense_online - -# Build rule for target. -linear_regression_dense_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 linear_regression_dense_online -.PHONY : linear_regression_dense_online - -# fast build rule for target. -linear_regression_dense_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/build -.PHONY : linear_regression_dense_online/fast - -#============================================================================= -# Target rules for targets named logistic_regression_dense_batch - -# Build rule for target. -logistic_regression_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 logistic_regression_dense_batch -.PHONY : logistic_regression_dense_batch - -# fast build rule for target. -logistic_regression_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/build -.PHONY : logistic_regression_dense_batch/fast - -#============================================================================= -# Target rules for targets named read_batch - -# Build rule for target. -read_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 read_batch -.PHONY : read_batch - -# fast build rule for target. -read_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/build -.PHONY : read_batch/fast - -#============================================================================= -# Target rules for targets named pca_cor_dense_batch - -# Build rule for target. -pca_cor_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cor_dense_batch -.PHONY : pca_cor_dense_batch - -# fast build rule for target. -pca_cor_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/build -.PHONY : pca_cor_dense_batch/fast - -#============================================================================= -# Target rules for targets named pca_cor_dense_online - -# Build rule for target. -pca_cor_dense_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cor_dense_online -.PHONY : pca_cor_dense_online - -# fast build rule for target. -pca_cor_dense_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/build -.PHONY : pca_cor_dense_online/fast - -#============================================================================= -# Target rules for targets named pca_cov_dense_batch - -# Build rule for target. -pca_cov_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cov_dense_batch -.PHONY : pca_cov_dense_batch - -# fast build rule for target. -pca_cov_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/build -.PHONY : pca_cov_dense_batch/fast - -#============================================================================= -# Target rules for targets named pca_cov_dense_online - -# Build rule for target. -pca_cov_dense_online: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_cov_dense_online -.PHONY : pca_cov_dense_online - -# fast build rule for target. -pca_cov_dense_online/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/build -.PHONY : pca_cov_dense_online/fast - -#============================================================================= -# Target rules for targets named pca_precomputed_cor_dense_batch - -# Build rule for target. -pca_precomputed_cor_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_precomputed_cor_dense_batch -.PHONY : pca_precomputed_cor_dense_batch - -# fast build rule for target. -pca_precomputed_cor_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/build -.PHONY : pca_precomputed_cor_dense_batch/fast - -#============================================================================= -# Target rules for targets named pca_precomputed_cov_dense_batch - -# Build rule for target. -pca_precomputed_cov_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_precomputed_cov_dense_batch -.PHONY : pca_precomputed_cov_dense_batch - -# fast build rule for target. -pca_precomputed_cov_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/build -.PHONY : pca_precomputed_cov_dense_batch/fast - -#============================================================================= -# Target rules for targets named pca_svd_dense_batch - -# Build rule for target. -pca_svd_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pca_svd_dense_batch -.PHONY : pca_svd_dense_batch - -# fast build rule for target. -pca_svd_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/build -.PHONY : pca_svd_dense_batch/fast - -#============================================================================= -# Target rules for targets named rbf_kernel_dense_batch - -# Build rule for target. -rbf_kernel_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 rbf_kernel_dense_batch -.PHONY : rbf_kernel_dense_batch - -# fast build rule for target. -rbf_kernel_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/build -.PHONY : rbf_kernel_dense_batch/fast - -#============================================================================= -# Target rules for targets named svm_two_class_thunder_dense_batch - -# Build rule for target. -svm_two_class_thunder_dense_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 svm_two_class_thunder_dense_batch -.PHONY : svm_two_class_thunder_dense_batch - -# fast build rule for target. -svm_two_class_thunder_dense_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/build -.PHONY : svm_two_class_thunder_dense_batch/fast - -#============================================================================= -# Target rules for targets named column_accessor_homogen - -# Build rule for target. -column_accessor_homogen: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 column_accessor_homogen -.PHONY : column_accessor_homogen - -# fast build rule for target. -column_accessor_homogen/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/build -.PHONY : column_accessor_homogen/fast - -#============================================================================= -# Target rules for targets named csr_accessor - -# Build rule for target. -csr_accessor: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 csr_accessor -.PHONY : csr_accessor - -# fast build rule for target. -csr_accessor/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/build -.PHONY : csr_accessor/fast - -#============================================================================= -# Target rules for targets named csr_table - -# Build rule for target. -csr_table: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 csr_table -.PHONY : csr_table - -# fast build rule for target. -csr_table/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/build -.PHONY : csr_table/fast - -#============================================================================= -# Target rules for targets named heterogen_table - -# Build rule for target. -heterogen_table: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 heterogen_table -.PHONY : heterogen_table - -# fast build rule for target. -heterogen_table/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/build -.PHONY : heterogen_table/fast - -#============================================================================= -# Target rules for targets named homogen_table - -# Build rule for target. -homogen_table: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 homogen_table -.PHONY : homogen_table - -# fast build rule for target. -homogen_table/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/build -.PHONY : homogen_table/fast - -#============================================================================= -# Target rules for targets named triangle_counting_batch - -# Build rule for target. -triangle_counting_batch: cmake_check_build_system - $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 triangle_counting_batch -.PHONY : triangle_counting_batch - -# fast build rule for target. -triangle_counting_batch/fast: - $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/build -.PHONY : triangle_counting_batch/fast - -source/basic_statistics/basic_statistics_dense_batch.o: source/basic_statistics/basic_statistics_dense_batch.cpp.o -.PHONY : source/basic_statistics/basic_statistics_dense_batch.o - -# target to build an object file -source/basic_statistics/basic_statistics_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/source/basic_statistics/basic_statistics_dense_batch.cpp.o -.PHONY : source/basic_statistics/basic_statistics_dense_batch.cpp.o - -source/basic_statistics/basic_statistics_dense_batch.i: source/basic_statistics/basic_statistics_dense_batch.cpp.i -.PHONY : source/basic_statistics/basic_statistics_dense_batch.i - -# target to preprocess a source file -source/basic_statistics/basic_statistics_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/source/basic_statistics/basic_statistics_dense_batch.cpp.i -.PHONY : source/basic_statistics/basic_statistics_dense_batch.cpp.i - -source/basic_statistics/basic_statistics_dense_batch.s: source/basic_statistics/basic_statistics_dense_batch.cpp.s -.PHONY : source/basic_statistics/basic_statistics_dense_batch.s - -# target to generate assembly for a file -source/basic_statistics/basic_statistics_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_batch.dir/build.make CMakeFiles/basic_statistics_dense_batch.dir/source/basic_statistics/basic_statistics_dense_batch.cpp.s -.PHONY : source/basic_statistics/basic_statistics_dense_batch.cpp.s - -source/basic_statistics/basic_statistics_dense_online.o: source/basic_statistics/basic_statistics_dense_online.cpp.o -.PHONY : source/basic_statistics/basic_statistics_dense_online.o - -# target to build an object file -source/basic_statistics/basic_statistics_dense_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/source/basic_statistics/basic_statistics_dense_online.cpp.o -.PHONY : source/basic_statistics/basic_statistics_dense_online.cpp.o - -source/basic_statistics/basic_statistics_dense_online.i: source/basic_statistics/basic_statistics_dense_online.cpp.i -.PHONY : source/basic_statistics/basic_statistics_dense_online.i - -# target to preprocess a source file -source/basic_statistics/basic_statistics_dense_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/source/basic_statistics/basic_statistics_dense_online.cpp.i -.PHONY : source/basic_statistics/basic_statistics_dense_online.cpp.i - -source/basic_statistics/basic_statistics_dense_online.s: source/basic_statistics/basic_statistics_dense_online.cpp.s -.PHONY : source/basic_statistics/basic_statistics_dense_online.s - -# target to generate assembly for a file -source/basic_statistics/basic_statistics_dense_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/basic_statistics_dense_online.dir/build.make CMakeFiles/basic_statistics_dense_online.dir/source/basic_statistics/basic_statistics_dense_online.cpp.s -.PHONY : source/basic_statistics/basic_statistics_dense_online.cpp.s - -source/connected_components/connected_components_batch.o: source/connected_components/connected_components_batch.cpp.o -.PHONY : source/connected_components/connected_components_batch.o - -# target to build an object file -source/connected_components/connected_components_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/source/connected_components/connected_components_batch.cpp.o -.PHONY : source/connected_components/connected_components_batch.cpp.o - -source/connected_components/connected_components_batch.i: source/connected_components/connected_components_batch.cpp.i -.PHONY : source/connected_components/connected_components_batch.i - -# target to preprocess a source file -source/connected_components/connected_components_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/source/connected_components/connected_components_batch.cpp.i -.PHONY : source/connected_components/connected_components_batch.cpp.i - -source/connected_components/connected_components_batch.s: source/connected_components/connected_components_batch.cpp.s -.PHONY : source/connected_components/connected_components_batch.s - -# target to generate assembly for a file -source/connected_components/connected_components_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/connected_components_batch.dir/build.make CMakeFiles/connected_components_batch.dir/source/connected_components/connected_components_batch.cpp.s -.PHONY : source/connected_components/connected_components_batch.cpp.s - -source/correlation_distance/correlation_distance_dense_batch.o: source/correlation_distance/correlation_distance_dense_batch.cpp.o -.PHONY : source/correlation_distance/correlation_distance_dense_batch.o - -# target to build an object file -source/correlation_distance/correlation_distance_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/source/correlation_distance/correlation_distance_dense_batch.cpp.o -.PHONY : source/correlation_distance/correlation_distance_dense_batch.cpp.o - -source/correlation_distance/correlation_distance_dense_batch.i: source/correlation_distance/correlation_distance_dense_batch.cpp.i -.PHONY : source/correlation_distance/correlation_distance_dense_batch.i - -# target to preprocess a source file -source/correlation_distance/correlation_distance_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/source/correlation_distance/correlation_distance_dense_batch.cpp.i -.PHONY : source/correlation_distance/correlation_distance_dense_batch.cpp.i - -source/correlation_distance/correlation_distance_dense_batch.s: source/correlation_distance/correlation_distance_dense_batch.cpp.s -.PHONY : source/correlation_distance/correlation_distance_dense_batch.s - -# target to generate assembly for a file -source/correlation_distance/correlation_distance_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/correlation_distance_dense_batch.dir/build.make CMakeFiles/correlation_distance_dense_batch.dir/source/correlation_distance/correlation_distance_dense_batch.cpp.s -.PHONY : source/correlation_distance/correlation_distance_dense_batch.cpp.s - -source/cosine_distance/cosine_distance_dense_batch.o: source/cosine_distance/cosine_distance_dense_batch.cpp.o -.PHONY : source/cosine_distance/cosine_distance_dense_batch.o - -# target to build an object file -source/cosine_distance/cosine_distance_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/source/cosine_distance/cosine_distance_dense_batch.cpp.o -.PHONY : source/cosine_distance/cosine_distance_dense_batch.cpp.o - -source/cosine_distance/cosine_distance_dense_batch.i: source/cosine_distance/cosine_distance_dense_batch.cpp.i -.PHONY : source/cosine_distance/cosine_distance_dense_batch.i - -# target to preprocess a source file -source/cosine_distance/cosine_distance_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/source/cosine_distance/cosine_distance_dense_batch.cpp.i -.PHONY : source/cosine_distance/cosine_distance_dense_batch.cpp.i - -source/cosine_distance/cosine_distance_dense_batch.s: source/cosine_distance/cosine_distance_dense_batch.cpp.s -.PHONY : source/cosine_distance/cosine_distance_dense_batch.s - -# target to generate assembly for a file -source/cosine_distance/cosine_distance_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cosine_distance_dense_batch.dir/build.make CMakeFiles/cosine_distance_dense_batch.dir/source/cosine_distance/cosine_distance_dense_batch.cpp.s -.PHONY : source/cosine_distance/cosine_distance_dense_batch.cpp.s - -source/covariance/cor_dense_batch.o: source/covariance/cor_dense_batch.cpp.o -.PHONY : source/covariance/cor_dense_batch.o - -# target to build an object file -source/covariance/cor_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/source/covariance/cor_dense_batch.cpp.o -.PHONY : source/covariance/cor_dense_batch.cpp.o - -source/covariance/cor_dense_batch.i: source/covariance/cor_dense_batch.cpp.i -.PHONY : source/covariance/cor_dense_batch.i - -# target to preprocess a source file -source/covariance/cor_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/source/covariance/cor_dense_batch.cpp.i -.PHONY : source/covariance/cor_dense_batch.cpp.i - -source/covariance/cor_dense_batch.s: source/covariance/cor_dense_batch.cpp.s -.PHONY : source/covariance/cor_dense_batch.s - -# target to generate assembly for a file -source/covariance/cor_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_batch.dir/build.make CMakeFiles/cor_dense_batch.dir/source/covariance/cor_dense_batch.cpp.s -.PHONY : source/covariance/cor_dense_batch.cpp.s - -source/covariance/cor_dense_online.o: source/covariance/cor_dense_online.cpp.o -.PHONY : source/covariance/cor_dense_online.o - -# target to build an object file -source/covariance/cor_dense_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/source/covariance/cor_dense_online.cpp.o -.PHONY : source/covariance/cor_dense_online.cpp.o - -source/covariance/cor_dense_online.i: source/covariance/cor_dense_online.cpp.i -.PHONY : source/covariance/cor_dense_online.i - -# target to preprocess a source file -source/covariance/cor_dense_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/source/covariance/cor_dense_online.cpp.i -.PHONY : source/covariance/cor_dense_online.cpp.i - -source/covariance/cor_dense_online.s: source/covariance/cor_dense_online.cpp.s -.PHONY : source/covariance/cor_dense_online.s - -# target to generate assembly for a file -source/covariance/cor_dense_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cor_dense_online.dir/build.make CMakeFiles/cor_dense_online.dir/source/covariance/cor_dense_online.cpp.s -.PHONY : source/covariance/cor_dense_online.cpp.s - -source/covariance/cov_dense_batch.o: source/covariance/cov_dense_batch.cpp.o -.PHONY : source/covariance/cov_dense_batch.o - -# target to build an object file -source/covariance/cov_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/source/covariance/cov_dense_batch.cpp.o -.PHONY : source/covariance/cov_dense_batch.cpp.o - -source/covariance/cov_dense_batch.i: source/covariance/cov_dense_batch.cpp.i -.PHONY : source/covariance/cov_dense_batch.i - -# target to preprocess a source file -source/covariance/cov_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/source/covariance/cov_dense_batch.cpp.i -.PHONY : source/covariance/cov_dense_batch.cpp.i - -source/covariance/cov_dense_batch.s: source/covariance/cov_dense_batch.cpp.s -.PHONY : source/covariance/cov_dense_batch.s - -# target to generate assembly for a file -source/covariance/cov_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_batch.dir/build.make CMakeFiles/cov_dense_batch.dir/source/covariance/cov_dense_batch.cpp.s -.PHONY : source/covariance/cov_dense_batch.cpp.s - -source/covariance/cov_dense_biased_batch.o: source/covariance/cov_dense_biased_batch.cpp.o -.PHONY : source/covariance/cov_dense_biased_batch.o - -# target to build an object file -source/covariance/cov_dense_biased_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/source/covariance/cov_dense_biased_batch.cpp.o -.PHONY : source/covariance/cov_dense_biased_batch.cpp.o - -source/covariance/cov_dense_biased_batch.i: source/covariance/cov_dense_biased_batch.cpp.i -.PHONY : source/covariance/cov_dense_biased_batch.i - -# target to preprocess a source file -source/covariance/cov_dense_biased_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/source/covariance/cov_dense_biased_batch.cpp.i -.PHONY : source/covariance/cov_dense_biased_batch.cpp.i - -source/covariance/cov_dense_biased_batch.s: source/covariance/cov_dense_biased_batch.cpp.s -.PHONY : source/covariance/cov_dense_biased_batch.s - -# target to generate assembly for a file -source/covariance/cov_dense_biased_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_batch.dir/build.make CMakeFiles/cov_dense_biased_batch.dir/source/covariance/cov_dense_biased_batch.cpp.s -.PHONY : source/covariance/cov_dense_biased_batch.cpp.s - -source/covariance/cov_dense_biased_online.o: source/covariance/cov_dense_biased_online.cpp.o -.PHONY : source/covariance/cov_dense_biased_online.o - -# target to build an object file -source/covariance/cov_dense_biased_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/source/covariance/cov_dense_biased_online.cpp.o -.PHONY : source/covariance/cov_dense_biased_online.cpp.o - -source/covariance/cov_dense_biased_online.i: source/covariance/cov_dense_biased_online.cpp.i -.PHONY : source/covariance/cov_dense_biased_online.i - -# target to preprocess a source file -source/covariance/cov_dense_biased_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/source/covariance/cov_dense_biased_online.cpp.i -.PHONY : source/covariance/cov_dense_biased_online.cpp.i - -source/covariance/cov_dense_biased_online.s: source/covariance/cov_dense_biased_online.cpp.s -.PHONY : source/covariance/cov_dense_biased_online.s - -# target to generate assembly for a file -source/covariance/cov_dense_biased_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_biased_online.dir/build.make CMakeFiles/cov_dense_biased_online.dir/source/covariance/cov_dense_biased_online.cpp.s -.PHONY : source/covariance/cov_dense_biased_online.cpp.s - -source/covariance/cov_dense_online.o: source/covariance/cov_dense_online.cpp.o -.PHONY : source/covariance/cov_dense_online.o - -# target to build an object file -source/covariance/cov_dense_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/source/covariance/cov_dense_online.cpp.o -.PHONY : source/covariance/cov_dense_online.cpp.o - -source/covariance/cov_dense_online.i: source/covariance/cov_dense_online.cpp.i -.PHONY : source/covariance/cov_dense_online.i - -# target to preprocess a source file -source/covariance/cov_dense_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/source/covariance/cov_dense_online.cpp.i -.PHONY : source/covariance/cov_dense_online.cpp.i - -source/covariance/cov_dense_online.s: source/covariance/cov_dense_online.cpp.s -.PHONY : source/covariance/cov_dense_online.s - -# target to generate assembly for a file -source/covariance/cov_dense_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/cov_dense_online.dir/build.make CMakeFiles/cov_dense_online.dir/source/covariance/cov_dense_online.cpp.s -.PHONY : source/covariance/cov_dense_online.cpp.s - -source/dbscan/dbscan_brute_force_batch.o: source/dbscan/dbscan_brute_force_batch.cpp.o -.PHONY : source/dbscan/dbscan_brute_force_batch.o - -# target to build an object file -source/dbscan/dbscan_brute_force_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/source/dbscan/dbscan_brute_force_batch.cpp.o -.PHONY : source/dbscan/dbscan_brute_force_batch.cpp.o - -source/dbscan/dbscan_brute_force_batch.i: source/dbscan/dbscan_brute_force_batch.cpp.i -.PHONY : source/dbscan/dbscan_brute_force_batch.i - -# target to preprocess a source file -source/dbscan/dbscan_brute_force_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/source/dbscan/dbscan_brute_force_batch.cpp.i -.PHONY : source/dbscan/dbscan_brute_force_batch.cpp.i - -source/dbscan/dbscan_brute_force_batch.s: source/dbscan/dbscan_brute_force_batch.cpp.s -.PHONY : source/dbscan/dbscan_brute_force_batch.s - -# target to generate assembly for a file -source/dbscan/dbscan_brute_force_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/dbscan_brute_force_batch.dir/build.make CMakeFiles/dbscan_brute_force_batch.dir/source/dbscan/dbscan_brute_force_batch.cpp.s -.PHONY : source/dbscan/dbscan_brute_force_batch.cpp.s - -source/decision_forest/df_cls_hist_batch.o: source/decision_forest/df_cls_hist_batch.cpp.o -.PHONY : source/decision_forest/df_cls_hist_batch.o - -# target to build an object file -source/decision_forest/df_cls_hist_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/source/decision_forest/df_cls_hist_batch.cpp.o -.PHONY : source/decision_forest/df_cls_hist_batch.cpp.o - -source/decision_forest/df_cls_hist_batch.i: source/decision_forest/df_cls_hist_batch.cpp.i -.PHONY : source/decision_forest/df_cls_hist_batch.i - -# target to preprocess a source file -source/decision_forest/df_cls_hist_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/source/decision_forest/df_cls_hist_batch.cpp.i -.PHONY : source/decision_forest/df_cls_hist_batch.cpp.i - -source/decision_forest/df_cls_hist_batch.s: source/decision_forest/df_cls_hist_batch.cpp.s -.PHONY : source/decision_forest/df_cls_hist_batch.s - -# target to generate assembly for a file -source/decision_forest/df_cls_hist_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch.dir/build.make CMakeFiles/df_cls_hist_batch.dir/source/decision_forest/df_cls_hist_batch.cpp.s -.PHONY : source/decision_forest/df_cls_hist_batch.cpp.s - -source/decision_forest/df_cls_hist_batch_random.o: source/decision_forest/df_cls_hist_batch_random.cpp.o -.PHONY : source/decision_forest/df_cls_hist_batch_random.o - -# target to build an object file -source/decision_forest/df_cls_hist_batch_random.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/source/decision_forest/df_cls_hist_batch_random.cpp.o -.PHONY : source/decision_forest/df_cls_hist_batch_random.cpp.o - -source/decision_forest/df_cls_hist_batch_random.i: source/decision_forest/df_cls_hist_batch_random.cpp.i -.PHONY : source/decision_forest/df_cls_hist_batch_random.i - -# target to preprocess a source file -source/decision_forest/df_cls_hist_batch_random.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/source/decision_forest/df_cls_hist_batch_random.cpp.i -.PHONY : source/decision_forest/df_cls_hist_batch_random.cpp.i - -source/decision_forest/df_cls_hist_batch_random.s: source/decision_forest/df_cls_hist_batch_random.cpp.s -.PHONY : source/decision_forest/df_cls_hist_batch_random.s - -# target to generate assembly for a file -source/decision_forest/df_cls_hist_batch_random.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_hist_batch_random.dir/build.make CMakeFiles/df_cls_hist_batch_random.dir/source/decision_forest/df_cls_hist_batch_random.cpp.s -.PHONY : source/decision_forest/df_cls_hist_batch_random.cpp.s - -source/decision_forest/df_cls_traverse_model.o: source/decision_forest/df_cls_traverse_model.cpp.o -.PHONY : source/decision_forest/df_cls_traverse_model.o - -# target to build an object file -source/decision_forest/df_cls_traverse_model.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/source/decision_forest/df_cls_traverse_model.cpp.o -.PHONY : source/decision_forest/df_cls_traverse_model.cpp.o - -source/decision_forest/df_cls_traverse_model.i: source/decision_forest/df_cls_traverse_model.cpp.i -.PHONY : source/decision_forest/df_cls_traverse_model.i - -# target to preprocess a source file -source/decision_forest/df_cls_traverse_model.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/source/decision_forest/df_cls_traverse_model.cpp.i -.PHONY : source/decision_forest/df_cls_traverse_model.cpp.i - -source/decision_forest/df_cls_traverse_model.s: source/decision_forest/df_cls_traverse_model.cpp.s -.PHONY : source/decision_forest/df_cls_traverse_model.s - -# target to generate assembly for a file -source/decision_forest/df_cls_traverse_model.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_cls_traverse_model.dir/build.make CMakeFiles/df_cls_traverse_model.dir/source/decision_forest/df_cls_traverse_model.cpp.s -.PHONY : source/decision_forest/df_cls_traverse_model.cpp.s - -source/decision_forest/df_reg_hist_batch.o: source/decision_forest/df_reg_hist_batch.cpp.o -.PHONY : source/decision_forest/df_reg_hist_batch.o - -# target to build an object file -source/decision_forest/df_reg_hist_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/source/decision_forest/df_reg_hist_batch.cpp.o -.PHONY : source/decision_forest/df_reg_hist_batch.cpp.o - -source/decision_forest/df_reg_hist_batch.i: source/decision_forest/df_reg_hist_batch.cpp.i -.PHONY : source/decision_forest/df_reg_hist_batch.i - -# target to preprocess a source file -source/decision_forest/df_reg_hist_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/source/decision_forest/df_reg_hist_batch.cpp.i -.PHONY : source/decision_forest/df_reg_hist_batch.cpp.i - -source/decision_forest/df_reg_hist_batch.s: source/decision_forest/df_reg_hist_batch.cpp.s -.PHONY : source/decision_forest/df_reg_hist_batch.s - -# target to generate assembly for a file -source/decision_forest/df_reg_hist_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch.dir/build.make CMakeFiles/df_reg_hist_batch.dir/source/decision_forest/df_reg_hist_batch.cpp.s -.PHONY : source/decision_forest/df_reg_hist_batch.cpp.s - -source/decision_forest/df_reg_hist_batch_random.o: source/decision_forest/df_reg_hist_batch_random.cpp.o -.PHONY : source/decision_forest/df_reg_hist_batch_random.o - -# target to build an object file -source/decision_forest/df_reg_hist_batch_random.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/source/decision_forest/df_reg_hist_batch_random.cpp.o -.PHONY : source/decision_forest/df_reg_hist_batch_random.cpp.o - -source/decision_forest/df_reg_hist_batch_random.i: source/decision_forest/df_reg_hist_batch_random.cpp.i -.PHONY : source/decision_forest/df_reg_hist_batch_random.i - -# target to preprocess a source file -source/decision_forest/df_reg_hist_batch_random.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/source/decision_forest/df_reg_hist_batch_random.cpp.i -.PHONY : source/decision_forest/df_reg_hist_batch_random.cpp.i - -source/decision_forest/df_reg_hist_batch_random.s: source/decision_forest/df_reg_hist_batch_random.cpp.s -.PHONY : source/decision_forest/df_reg_hist_batch_random.s - -# target to generate assembly for a file -source/decision_forest/df_reg_hist_batch_random.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_hist_batch_random.dir/build.make CMakeFiles/df_reg_hist_batch_random.dir/source/decision_forest/df_reg_hist_batch_random.cpp.s -.PHONY : source/decision_forest/df_reg_hist_batch_random.cpp.s - -source/decision_forest/df_reg_traverse_model.o: source/decision_forest/df_reg_traverse_model.cpp.o -.PHONY : source/decision_forest/df_reg_traverse_model.o - -# target to build an object file -source/decision_forest/df_reg_traverse_model.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/source/decision_forest/df_reg_traverse_model.cpp.o -.PHONY : source/decision_forest/df_reg_traverse_model.cpp.o - -source/decision_forest/df_reg_traverse_model.i: source/decision_forest/df_reg_traverse_model.cpp.i -.PHONY : source/decision_forest/df_reg_traverse_model.i - -# target to preprocess a source file -source/decision_forest/df_reg_traverse_model.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/source/decision_forest/df_reg_traverse_model.cpp.i -.PHONY : source/decision_forest/df_reg_traverse_model.cpp.i - -source/decision_forest/df_reg_traverse_model.s: source/decision_forest/df_reg_traverse_model.cpp.s -.PHONY : source/decision_forest/df_reg_traverse_model.s - -# target to generate assembly for a file -source/decision_forest/df_reg_traverse_model.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/df_reg_traverse_model.dir/build.make CMakeFiles/df_reg_traverse_model.dir/source/decision_forest/df_reg_traverse_model.cpp.s -.PHONY : source/decision_forest/df_reg_traverse_model.cpp.s - -source/kmeans/kmeans_lloyd_csr_batch.o: source/kmeans/kmeans_lloyd_csr_batch.cpp.o -.PHONY : source/kmeans/kmeans_lloyd_csr_batch.o - -# target to build an object file -source/kmeans/kmeans_lloyd_csr_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/source/kmeans/kmeans_lloyd_csr_batch.cpp.o -.PHONY : source/kmeans/kmeans_lloyd_csr_batch.cpp.o - -source/kmeans/kmeans_lloyd_csr_batch.i: source/kmeans/kmeans_lloyd_csr_batch.cpp.i -.PHONY : source/kmeans/kmeans_lloyd_csr_batch.i - -# target to preprocess a source file -source/kmeans/kmeans_lloyd_csr_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/source/kmeans/kmeans_lloyd_csr_batch.cpp.i -.PHONY : source/kmeans/kmeans_lloyd_csr_batch.cpp.i - -source/kmeans/kmeans_lloyd_csr_batch.s: source/kmeans/kmeans_lloyd_csr_batch.cpp.s -.PHONY : source/kmeans/kmeans_lloyd_csr_batch.s - -# target to generate assembly for a file -source/kmeans/kmeans_lloyd_csr_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_csr_batch.dir/build.make CMakeFiles/kmeans_lloyd_csr_batch.dir/source/kmeans/kmeans_lloyd_csr_batch.cpp.s -.PHONY : source/kmeans/kmeans_lloyd_csr_batch.cpp.s - -source/kmeans/kmeans_lloyd_dense_batch.o: source/kmeans/kmeans_lloyd_dense_batch.cpp.o -.PHONY : source/kmeans/kmeans_lloyd_dense_batch.o - -# target to build an object file -source/kmeans/kmeans_lloyd_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/source/kmeans/kmeans_lloyd_dense_batch.cpp.o -.PHONY : source/kmeans/kmeans_lloyd_dense_batch.cpp.o - -source/kmeans/kmeans_lloyd_dense_batch.i: source/kmeans/kmeans_lloyd_dense_batch.cpp.i -.PHONY : source/kmeans/kmeans_lloyd_dense_batch.i - -# target to preprocess a source file -source/kmeans/kmeans_lloyd_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/source/kmeans/kmeans_lloyd_dense_batch.cpp.i -.PHONY : source/kmeans/kmeans_lloyd_dense_batch.cpp.i - -source/kmeans/kmeans_lloyd_dense_batch.s: source/kmeans/kmeans_lloyd_dense_batch.cpp.s -.PHONY : source/kmeans/kmeans_lloyd_dense_batch.s - -# target to generate assembly for a file -source/kmeans/kmeans_lloyd_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_lloyd_dense_batch.dir/build.make CMakeFiles/kmeans_lloyd_dense_batch.dir/source/kmeans/kmeans_lloyd_dense_batch.cpp.s -.PHONY : source/kmeans/kmeans_lloyd_dense_batch.cpp.s - -source/kmeans_init/kmeans_init_dense.o: source/kmeans_init/kmeans_init_dense.cpp.o -.PHONY : source/kmeans_init/kmeans_init_dense.o - -# target to build an object file -source/kmeans_init/kmeans_init_dense.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/source/kmeans_init/kmeans_init_dense.cpp.o -.PHONY : source/kmeans_init/kmeans_init_dense.cpp.o - -source/kmeans_init/kmeans_init_dense.i: source/kmeans_init/kmeans_init_dense.cpp.i -.PHONY : source/kmeans_init/kmeans_init_dense.i - -# target to preprocess a source file -source/kmeans_init/kmeans_init_dense.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/source/kmeans_init/kmeans_init_dense.cpp.i -.PHONY : source/kmeans_init/kmeans_init_dense.cpp.i - -source/kmeans_init/kmeans_init_dense.s: source/kmeans_init/kmeans_init_dense.cpp.s -.PHONY : source/kmeans_init/kmeans_init_dense.s - -# target to generate assembly for a file -source/kmeans_init/kmeans_init_dense.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/kmeans_init_dense.dir/build.make CMakeFiles/kmeans_init_dense.dir/source/kmeans_init/kmeans_init_dense.cpp.s -.PHONY : source/kmeans_init/kmeans_init_dense.cpp.s - -source/knn/knn_cls_brute_force_dense_batch.o: source/knn/knn_cls_brute_force_dense_batch.cpp.o -.PHONY : source/knn/knn_cls_brute_force_dense_batch.o - -# target to build an object file -source/knn/knn_cls_brute_force_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/source/knn/knn_cls_brute_force_dense_batch.cpp.o -.PHONY : source/knn/knn_cls_brute_force_dense_batch.cpp.o - -source/knn/knn_cls_brute_force_dense_batch.i: source/knn/knn_cls_brute_force_dense_batch.cpp.i -.PHONY : source/knn/knn_cls_brute_force_dense_batch.i - -# target to preprocess a source file -source/knn/knn_cls_brute_force_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/source/knn/knn_cls_brute_force_dense_batch.cpp.i -.PHONY : source/knn/knn_cls_brute_force_dense_batch.cpp.i - -source/knn/knn_cls_brute_force_dense_batch.s: source/knn/knn_cls_brute_force_dense_batch.cpp.s -.PHONY : source/knn/knn_cls_brute_force_dense_batch.s - -# target to generate assembly for a file -source/knn/knn_cls_brute_force_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_cls_brute_force_dense_batch.dir/build.make CMakeFiles/knn_cls_brute_force_dense_batch.dir/source/knn/knn_cls_brute_force_dense_batch.cpp.s -.PHONY : source/knn/knn_cls_brute_force_dense_batch.cpp.s - -source/knn/knn_reg_brute_force_dense_batch.o: source/knn/knn_reg_brute_force_dense_batch.cpp.o -.PHONY : source/knn/knn_reg_brute_force_dense_batch.o - -# target to build an object file -source/knn/knn_reg_brute_force_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/source/knn/knn_reg_brute_force_dense_batch.cpp.o -.PHONY : source/knn/knn_reg_brute_force_dense_batch.cpp.o - -source/knn/knn_reg_brute_force_dense_batch.i: source/knn/knn_reg_brute_force_dense_batch.cpp.i -.PHONY : source/knn/knn_reg_brute_force_dense_batch.i - -# target to preprocess a source file -source/knn/knn_reg_brute_force_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/source/knn/knn_reg_brute_force_dense_batch.cpp.i -.PHONY : source/knn/knn_reg_brute_force_dense_batch.cpp.i - -source/knn/knn_reg_brute_force_dense_batch.s: source/knn/knn_reg_brute_force_dense_batch.cpp.s -.PHONY : source/knn/knn_reg_brute_force_dense_batch.s - -# target to generate assembly for a file -source/knn/knn_reg_brute_force_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_reg_brute_force_dense_batch.dir/build.make CMakeFiles/knn_reg_brute_force_dense_batch.dir/source/knn/knn_reg_brute_force_dense_batch.cpp.s -.PHONY : source/knn/knn_reg_brute_force_dense_batch.cpp.s - -source/knn/knn_search_brute_force_dense_batch.o: source/knn/knn_search_brute_force_dense_batch.cpp.o -.PHONY : source/knn/knn_search_brute_force_dense_batch.o - -# target to build an object file -source/knn/knn_search_brute_force_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/source/knn/knn_search_brute_force_dense_batch.cpp.o -.PHONY : source/knn/knn_search_brute_force_dense_batch.cpp.o - -source/knn/knn_search_brute_force_dense_batch.i: source/knn/knn_search_brute_force_dense_batch.cpp.i -.PHONY : source/knn/knn_search_brute_force_dense_batch.i - -# target to preprocess a source file -source/knn/knn_search_brute_force_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/source/knn/knn_search_brute_force_dense_batch.cpp.i -.PHONY : source/knn/knn_search_brute_force_dense_batch.cpp.i - -source/knn/knn_search_brute_force_dense_batch.s: source/knn/knn_search_brute_force_dense_batch.cpp.s -.PHONY : source/knn/knn_search_brute_force_dense_batch.s - -# target to generate assembly for a file -source/knn/knn_search_brute_force_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/knn_search_brute_force_dense_batch.dir/build.make CMakeFiles/knn_search_brute_force_dense_batch.dir/source/knn/knn_search_brute_force_dense_batch.cpp.s -.PHONY : source/knn/knn_search_brute_force_dense_batch.cpp.s - -source/linear_kernel/linear_kernel_dense_batch.o: source/linear_kernel/linear_kernel_dense_batch.cpp.o -.PHONY : source/linear_kernel/linear_kernel_dense_batch.o - -# target to build an object file -source/linear_kernel/linear_kernel_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/source/linear_kernel/linear_kernel_dense_batch.cpp.o -.PHONY : source/linear_kernel/linear_kernel_dense_batch.cpp.o - -source/linear_kernel/linear_kernel_dense_batch.i: source/linear_kernel/linear_kernel_dense_batch.cpp.i -.PHONY : source/linear_kernel/linear_kernel_dense_batch.i - -# target to preprocess a source file -source/linear_kernel/linear_kernel_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/source/linear_kernel/linear_kernel_dense_batch.cpp.i -.PHONY : source/linear_kernel/linear_kernel_dense_batch.cpp.i - -source/linear_kernel/linear_kernel_dense_batch.s: source/linear_kernel/linear_kernel_dense_batch.cpp.s -.PHONY : source/linear_kernel/linear_kernel_dense_batch.s - -# target to generate assembly for a file -source/linear_kernel/linear_kernel_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_kernel_dense_batch.dir/build.make CMakeFiles/linear_kernel_dense_batch.dir/source/linear_kernel/linear_kernel_dense_batch.cpp.s -.PHONY : source/linear_kernel/linear_kernel_dense_batch.cpp.s - -source/linear_regression/linear_regression_dense_batch.o: source/linear_regression/linear_regression_dense_batch.cpp.o -.PHONY : source/linear_regression/linear_regression_dense_batch.o - -# target to build an object file -source/linear_regression/linear_regression_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/source/linear_regression/linear_regression_dense_batch.cpp.o -.PHONY : source/linear_regression/linear_regression_dense_batch.cpp.o - -source/linear_regression/linear_regression_dense_batch.i: source/linear_regression/linear_regression_dense_batch.cpp.i -.PHONY : source/linear_regression/linear_regression_dense_batch.i - -# target to preprocess a source file -source/linear_regression/linear_regression_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/source/linear_regression/linear_regression_dense_batch.cpp.i -.PHONY : source/linear_regression/linear_regression_dense_batch.cpp.i - -source/linear_regression/linear_regression_dense_batch.s: source/linear_regression/linear_regression_dense_batch.cpp.s -.PHONY : source/linear_regression/linear_regression_dense_batch.s - -# target to generate assembly for a file -source/linear_regression/linear_regression_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_batch.dir/build.make CMakeFiles/linear_regression_dense_batch.dir/source/linear_regression/linear_regression_dense_batch.cpp.s -.PHONY : source/linear_regression/linear_regression_dense_batch.cpp.s - -source/linear_regression/linear_regression_dense_online.o: source/linear_regression/linear_regression_dense_online.cpp.o -.PHONY : source/linear_regression/linear_regression_dense_online.o - -# target to build an object file -source/linear_regression/linear_regression_dense_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/source/linear_regression/linear_regression_dense_online.cpp.o -.PHONY : source/linear_regression/linear_regression_dense_online.cpp.o - -source/linear_regression/linear_regression_dense_online.i: source/linear_regression/linear_regression_dense_online.cpp.i -.PHONY : source/linear_regression/linear_regression_dense_online.i - -# target to preprocess a source file -source/linear_regression/linear_regression_dense_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/source/linear_regression/linear_regression_dense_online.cpp.i -.PHONY : source/linear_regression/linear_regression_dense_online.cpp.i - -source/linear_regression/linear_regression_dense_online.s: source/linear_regression/linear_regression_dense_online.cpp.s -.PHONY : source/linear_regression/linear_regression_dense_online.s - -# target to generate assembly for a file -source/linear_regression/linear_regression_dense_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/linear_regression_dense_online.dir/build.make CMakeFiles/linear_regression_dense_online.dir/source/linear_regression/linear_regression_dense_online.cpp.s -.PHONY : source/linear_regression/linear_regression_dense_online.cpp.s - -source/logistic_regression/logistic_regression_dense_batch.o: source/logistic_regression/logistic_regression_dense_batch.cpp.o -.PHONY : source/logistic_regression/logistic_regression_dense_batch.o - -# target to build an object file -source/logistic_regression/logistic_regression_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/source/logistic_regression/logistic_regression_dense_batch.cpp.o -.PHONY : source/logistic_regression/logistic_regression_dense_batch.cpp.o - -source/logistic_regression/logistic_regression_dense_batch.i: source/logistic_regression/logistic_regression_dense_batch.cpp.i -.PHONY : source/logistic_regression/logistic_regression_dense_batch.i - -# target to preprocess a source file -source/logistic_regression/logistic_regression_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/source/logistic_regression/logistic_regression_dense_batch.cpp.i -.PHONY : source/logistic_regression/logistic_regression_dense_batch.cpp.i - -source/logistic_regression/logistic_regression_dense_batch.s: source/logistic_regression/logistic_regression_dense_batch.cpp.s -.PHONY : source/logistic_regression/logistic_regression_dense_batch.s - -# target to generate assembly for a file -source/logistic_regression/logistic_regression_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/logistic_regression_dense_batch.dir/build.make CMakeFiles/logistic_regression_dense_batch.dir/source/logistic_regression/logistic_regression_dense_batch.cpp.s -.PHONY : source/logistic_regression/logistic_regression_dense_batch.cpp.s - -source/misc/read_batch.o: source/misc/read_batch.cpp.o -.PHONY : source/misc/read_batch.o - -# target to build an object file -source/misc/read_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/source/misc/read_batch.cpp.o -.PHONY : source/misc/read_batch.cpp.o - -source/misc/read_batch.i: source/misc/read_batch.cpp.i -.PHONY : source/misc/read_batch.i - -# target to preprocess a source file -source/misc/read_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/source/misc/read_batch.cpp.i -.PHONY : source/misc/read_batch.cpp.i - -source/misc/read_batch.s: source/misc/read_batch.cpp.s -.PHONY : source/misc/read_batch.s - -# target to generate assembly for a file -source/misc/read_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/read_batch.dir/build.make CMakeFiles/read_batch.dir/source/misc/read_batch.cpp.s -.PHONY : source/misc/read_batch.cpp.s - -source/pca/pca_cor_dense_batch.o: source/pca/pca_cor_dense_batch.cpp.o -.PHONY : source/pca/pca_cor_dense_batch.o - -# target to build an object file -source/pca/pca_cor_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/source/pca/pca_cor_dense_batch.cpp.o -.PHONY : source/pca/pca_cor_dense_batch.cpp.o - -source/pca/pca_cor_dense_batch.i: source/pca/pca_cor_dense_batch.cpp.i -.PHONY : source/pca/pca_cor_dense_batch.i - -# target to preprocess a source file -source/pca/pca_cor_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/source/pca/pca_cor_dense_batch.cpp.i -.PHONY : source/pca/pca_cor_dense_batch.cpp.i - -source/pca/pca_cor_dense_batch.s: source/pca/pca_cor_dense_batch.cpp.s -.PHONY : source/pca/pca_cor_dense_batch.s - -# target to generate assembly for a file -source/pca/pca_cor_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_batch.dir/build.make CMakeFiles/pca_cor_dense_batch.dir/source/pca/pca_cor_dense_batch.cpp.s -.PHONY : source/pca/pca_cor_dense_batch.cpp.s - -source/pca/pca_cor_dense_online.o: source/pca/pca_cor_dense_online.cpp.o -.PHONY : source/pca/pca_cor_dense_online.o - -# target to build an object file -source/pca/pca_cor_dense_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/source/pca/pca_cor_dense_online.cpp.o -.PHONY : source/pca/pca_cor_dense_online.cpp.o - -source/pca/pca_cor_dense_online.i: source/pca/pca_cor_dense_online.cpp.i -.PHONY : source/pca/pca_cor_dense_online.i - -# target to preprocess a source file -source/pca/pca_cor_dense_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/source/pca/pca_cor_dense_online.cpp.i -.PHONY : source/pca/pca_cor_dense_online.cpp.i - -source/pca/pca_cor_dense_online.s: source/pca/pca_cor_dense_online.cpp.s -.PHONY : source/pca/pca_cor_dense_online.s - -# target to generate assembly for a file -source/pca/pca_cor_dense_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cor_dense_online.dir/build.make CMakeFiles/pca_cor_dense_online.dir/source/pca/pca_cor_dense_online.cpp.s -.PHONY : source/pca/pca_cor_dense_online.cpp.s - -source/pca/pca_cov_dense_batch.o: source/pca/pca_cov_dense_batch.cpp.o -.PHONY : source/pca/pca_cov_dense_batch.o - -# target to build an object file -source/pca/pca_cov_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/source/pca/pca_cov_dense_batch.cpp.o -.PHONY : source/pca/pca_cov_dense_batch.cpp.o - -source/pca/pca_cov_dense_batch.i: source/pca/pca_cov_dense_batch.cpp.i -.PHONY : source/pca/pca_cov_dense_batch.i - -# target to preprocess a source file -source/pca/pca_cov_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/source/pca/pca_cov_dense_batch.cpp.i -.PHONY : source/pca/pca_cov_dense_batch.cpp.i - -source/pca/pca_cov_dense_batch.s: source/pca/pca_cov_dense_batch.cpp.s -.PHONY : source/pca/pca_cov_dense_batch.s - -# target to generate assembly for a file -source/pca/pca_cov_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_batch.dir/build.make CMakeFiles/pca_cov_dense_batch.dir/source/pca/pca_cov_dense_batch.cpp.s -.PHONY : source/pca/pca_cov_dense_batch.cpp.s - -source/pca/pca_cov_dense_online.o: source/pca/pca_cov_dense_online.cpp.o -.PHONY : source/pca/pca_cov_dense_online.o - -# target to build an object file -source/pca/pca_cov_dense_online.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/source/pca/pca_cov_dense_online.cpp.o -.PHONY : source/pca/pca_cov_dense_online.cpp.o - -source/pca/pca_cov_dense_online.i: source/pca/pca_cov_dense_online.cpp.i -.PHONY : source/pca/pca_cov_dense_online.i - -# target to preprocess a source file -source/pca/pca_cov_dense_online.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/source/pca/pca_cov_dense_online.cpp.i -.PHONY : source/pca/pca_cov_dense_online.cpp.i - -source/pca/pca_cov_dense_online.s: source/pca/pca_cov_dense_online.cpp.s -.PHONY : source/pca/pca_cov_dense_online.s - -# target to generate assembly for a file -source/pca/pca_cov_dense_online.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_cov_dense_online.dir/build.make CMakeFiles/pca_cov_dense_online.dir/source/pca/pca_cov_dense_online.cpp.s -.PHONY : source/pca/pca_cov_dense_online.cpp.s - -source/pca/pca_precomputed_cor_dense_batch.o: source/pca/pca_precomputed_cor_dense_batch.cpp.o -.PHONY : source/pca/pca_precomputed_cor_dense_batch.o - -# target to build an object file -source/pca/pca_precomputed_cor_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/source/pca/pca_precomputed_cor_dense_batch.cpp.o -.PHONY : source/pca/pca_precomputed_cor_dense_batch.cpp.o - -source/pca/pca_precomputed_cor_dense_batch.i: source/pca/pca_precomputed_cor_dense_batch.cpp.i -.PHONY : source/pca/pca_precomputed_cor_dense_batch.i - -# target to preprocess a source file -source/pca/pca_precomputed_cor_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/source/pca/pca_precomputed_cor_dense_batch.cpp.i -.PHONY : source/pca/pca_precomputed_cor_dense_batch.cpp.i - -source/pca/pca_precomputed_cor_dense_batch.s: source/pca/pca_precomputed_cor_dense_batch.cpp.s -.PHONY : source/pca/pca_precomputed_cor_dense_batch.s - -# target to generate assembly for a file -source/pca/pca_precomputed_cor_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cor_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cor_dense_batch.dir/source/pca/pca_precomputed_cor_dense_batch.cpp.s -.PHONY : source/pca/pca_precomputed_cor_dense_batch.cpp.s - -source/pca/pca_precomputed_cov_dense_batch.o: source/pca/pca_precomputed_cov_dense_batch.cpp.o -.PHONY : source/pca/pca_precomputed_cov_dense_batch.o - -# target to build an object file -source/pca/pca_precomputed_cov_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/source/pca/pca_precomputed_cov_dense_batch.cpp.o -.PHONY : source/pca/pca_precomputed_cov_dense_batch.cpp.o - -source/pca/pca_precomputed_cov_dense_batch.i: source/pca/pca_precomputed_cov_dense_batch.cpp.i -.PHONY : source/pca/pca_precomputed_cov_dense_batch.i - -# target to preprocess a source file -source/pca/pca_precomputed_cov_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/source/pca/pca_precomputed_cov_dense_batch.cpp.i -.PHONY : source/pca/pca_precomputed_cov_dense_batch.cpp.i - -source/pca/pca_precomputed_cov_dense_batch.s: source/pca/pca_precomputed_cov_dense_batch.cpp.s -.PHONY : source/pca/pca_precomputed_cov_dense_batch.s - -# target to generate assembly for a file -source/pca/pca_precomputed_cov_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_precomputed_cov_dense_batch.dir/build.make CMakeFiles/pca_precomputed_cov_dense_batch.dir/source/pca/pca_precomputed_cov_dense_batch.cpp.s -.PHONY : source/pca/pca_precomputed_cov_dense_batch.cpp.s - -source/pca/pca_svd_dense_batch.o: source/pca/pca_svd_dense_batch.cpp.o -.PHONY : source/pca/pca_svd_dense_batch.o - -# target to build an object file -source/pca/pca_svd_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/source/pca/pca_svd_dense_batch.cpp.o -.PHONY : source/pca/pca_svd_dense_batch.cpp.o - -source/pca/pca_svd_dense_batch.i: source/pca/pca_svd_dense_batch.cpp.i -.PHONY : source/pca/pca_svd_dense_batch.i - -# target to preprocess a source file -source/pca/pca_svd_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/source/pca/pca_svd_dense_batch.cpp.i -.PHONY : source/pca/pca_svd_dense_batch.cpp.i - -source/pca/pca_svd_dense_batch.s: source/pca/pca_svd_dense_batch.cpp.s -.PHONY : source/pca/pca_svd_dense_batch.s - -# target to generate assembly for a file -source/pca/pca_svd_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/pca_svd_dense_batch.dir/build.make CMakeFiles/pca_svd_dense_batch.dir/source/pca/pca_svd_dense_batch.cpp.s -.PHONY : source/pca/pca_svd_dense_batch.cpp.s - -source/rbf_kernel/rbf_kernel_dense_batch.o: source/rbf_kernel/rbf_kernel_dense_batch.cpp.o -.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.o - -# target to build an object file -source/rbf_kernel/rbf_kernel_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/source/rbf_kernel/rbf_kernel_dense_batch.cpp.o -.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.cpp.o - -source/rbf_kernel/rbf_kernel_dense_batch.i: source/rbf_kernel/rbf_kernel_dense_batch.cpp.i -.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.i - -# target to preprocess a source file -source/rbf_kernel/rbf_kernel_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/source/rbf_kernel/rbf_kernel_dense_batch.cpp.i -.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.cpp.i - -source/rbf_kernel/rbf_kernel_dense_batch.s: source/rbf_kernel/rbf_kernel_dense_batch.cpp.s -.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.s - -# target to generate assembly for a file -source/rbf_kernel/rbf_kernel_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/rbf_kernel_dense_batch.dir/build.make CMakeFiles/rbf_kernel_dense_batch.dir/source/rbf_kernel/rbf_kernel_dense_batch.cpp.s -.PHONY : source/rbf_kernel/rbf_kernel_dense_batch.cpp.s - -source/svm/svm_two_class_thunder_dense_batch.o: source/svm/svm_two_class_thunder_dense_batch.cpp.o -.PHONY : source/svm/svm_two_class_thunder_dense_batch.o - -# target to build an object file -source/svm/svm_two_class_thunder_dense_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/source/svm/svm_two_class_thunder_dense_batch.cpp.o -.PHONY : source/svm/svm_two_class_thunder_dense_batch.cpp.o - -source/svm/svm_two_class_thunder_dense_batch.i: source/svm/svm_two_class_thunder_dense_batch.cpp.i -.PHONY : source/svm/svm_two_class_thunder_dense_batch.i - -# target to preprocess a source file -source/svm/svm_two_class_thunder_dense_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/source/svm/svm_two_class_thunder_dense_batch.cpp.i -.PHONY : source/svm/svm_two_class_thunder_dense_batch.cpp.i - -source/svm/svm_two_class_thunder_dense_batch.s: source/svm/svm_two_class_thunder_dense_batch.cpp.s -.PHONY : source/svm/svm_two_class_thunder_dense_batch.s - -# target to generate assembly for a file -source/svm/svm_two_class_thunder_dense_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/svm_two_class_thunder_dense_batch.dir/build.make CMakeFiles/svm_two_class_thunder_dense_batch.dir/source/svm/svm_two_class_thunder_dense_batch.cpp.s -.PHONY : source/svm/svm_two_class_thunder_dense_batch.cpp.s - -source/table/column_accessor_homogen.o: source/table/column_accessor_homogen.cpp.o -.PHONY : source/table/column_accessor_homogen.o - -# target to build an object file -source/table/column_accessor_homogen.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/source/table/column_accessor_homogen.cpp.o -.PHONY : source/table/column_accessor_homogen.cpp.o - -source/table/column_accessor_homogen.i: source/table/column_accessor_homogen.cpp.i -.PHONY : source/table/column_accessor_homogen.i - -# target to preprocess a source file -source/table/column_accessor_homogen.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/source/table/column_accessor_homogen.cpp.i -.PHONY : source/table/column_accessor_homogen.cpp.i - -source/table/column_accessor_homogen.s: source/table/column_accessor_homogen.cpp.s -.PHONY : source/table/column_accessor_homogen.s - -# target to generate assembly for a file -source/table/column_accessor_homogen.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/column_accessor_homogen.dir/build.make CMakeFiles/column_accessor_homogen.dir/source/table/column_accessor_homogen.cpp.s -.PHONY : source/table/column_accessor_homogen.cpp.s - -source/table/csr_accessor.o: source/table/csr_accessor.cpp.o -.PHONY : source/table/csr_accessor.o - -# target to build an object file -source/table/csr_accessor.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/source/table/csr_accessor.cpp.o -.PHONY : source/table/csr_accessor.cpp.o - -source/table/csr_accessor.i: source/table/csr_accessor.cpp.i -.PHONY : source/table/csr_accessor.i - -# target to preprocess a source file -source/table/csr_accessor.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/source/table/csr_accessor.cpp.i -.PHONY : source/table/csr_accessor.cpp.i - -source/table/csr_accessor.s: source/table/csr_accessor.cpp.s -.PHONY : source/table/csr_accessor.s - -# target to generate assembly for a file -source/table/csr_accessor.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_accessor.dir/build.make CMakeFiles/csr_accessor.dir/source/table/csr_accessor.cpp.s -.PHONY : source/table/csr_accessor.cpp.s - -source/table/csr_table.o: source/table/csr_table.cpp.o -.PHONY : source/table/csr_table.o - -# target to build an object file -source/table/csr_table.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/source/table/csr_table.cpp.o -.PHONY : source/table/csr_table.cpp.o - -source/table/csr_table.i: source/table/csr_table.cpp.i -.PHONY : source/table/csr_table.i - -# target to preprocess a source file -source/table/csr_table.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/source/table/csr_table.cpp.i -.PHONY : source/table/csr_table.cpp.i - -source/table/csr_table.s: source/table/csr_table.cpp.s -.PHONY : source/table/csr_table.s - -# target to generate assembly for a file -source/table/csr_table.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/csr_table.dir/build.make CMakeFiles/csr_table.dir/source/table/csr_table.cpp.s -.PHONY : source/table/csr_table.cpp.s - -source/table/heterogen_table.o: source/table/heterogen_table.cpp.o -.PHONY : source/table/heterogen_table.o - -# target to build an object file -source/table/heterogen_table.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/source/table/heterogen_table.cpp.o -.PHONY : source/table/heterogen_table.cpp.o - -source/table/heterogen_table.i: source/table/heterogen_table.cpp.i -.PHONY : source/table/heterogen_table.i - -# target to preprocess a source file -source/table/heterogen_table.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/source/table/heterogen_table.cpp.i -.PHONY : source/table/heterogen_table.cpp.i - -source/table/heterogen_table.s: source/table/heterogen_table.cpp.s -.PHONY : source/table/heterogen_table.s - -# target to generate assembly for a file -source/table/heterogen_table.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/heterogen_table.dir/build.make CMakeFiles/heterogen_table.dir/source/table/heterogen_table.cpp.s -.PHONY : source/table/heterogen_table.cpp.s - -source/table/homogen_table.o: source/table/homogen_table.cpp.o -.PHONY : source/table/homogen_table.o - -# target to build an object file -source/table/homogen_table.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/source/table/homogen_table.cpp.o -.PHONY : source/table/homogen_table.cpp.o - -source/table/homogen_table.i: source/table/homogen_table.cpp.i -.PHONY : source/table/homogen_table.i - -# target to preprocess a source file -source/table/homogen_table.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/source/table/homogen_table.cpp.i -.PHONY : source/table/homogen_table.cpp.i - -source/table/homogen_table.s: source/table/homogen_table.cpp.s -.PHONY : source/table/homogen_table.s - -# target to generate assembly for a file -source/table/homogen_table.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/homogen_table.dir/build.make CMakeFiles/homogen_table.dir/source/table/homogen_table.cpp.s -.PHONY : source/table/homogen_table.cpp.s - -source/triangle_counting/triangle_counting_batch.o: source/triangle_counting/triangle_counting_batch.cpp.o -.PHONY : source/triangle_counting/triangle_counting_batch.o - -# target to build an object file -source/triangle_counting/triangle_counting_batch.cpp.o: - $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/source/triangle_counting/triangle_counting_batch.cpp.o -.PHONY : source/triangle_counting/triangle_counting_batch.cpp.o - -source/triangle_counting/triangle_counting_batch.i: source/triangle_counting/triangle_counting_batch.cpp.i -.PHONY : source/triangle_counting/triangle_counting_batch.i - -# target to preprocess a source file -source/triangle_counting/triangle_counting_batch.cpp.i: - $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/source/triangle_counting/triangle_counting_batch.cpp.i -.PHONY : source/triangle_counting/triangle_counting_batch.cpp.i - -source/triangle_counting/triangle_counting_batch.s: source/triangle_counting/triangle_counting_batch.cpp.s -.PHONY : source/triangle_counting/triangle_counting_batch.s - -# target to generate assembly for a file -source/triangle_counting/triangle_counting_batch.cpp.s: - $(MAKE) $(MAKESILENT) -f CMakeFiles/triangle_counting_batch.dir/build.make CMakeFiles/triangle_counting_batch.dir/source/triangle_counting/triangle_counting_batch.cpp.s -.PHONY : source/triangle_counting/triangle_counting_batch.cpp.s - -# Help Target -help: - @echo "The following are some of the valid targets for this Makefile:" - @echo "... all (the default if no target is provided)" - @echo "... clean" - @echo "... depend" - @echo "... edit_cache" - @echo "... rebuild_cache" - @echo "... basic_statistics_dense_batch" - @echo "... basic_statistics_dense_online" - @echo "... column_accessor_homogen" - @echo "... connected_components_batch" - @echo "... cor_dense_batch" - @echo "... cor_dense_online" - @echo "... correlation_distance_dense_batch" - @echo "... cosine_distance_dense_batch" - @echo "... cov_dense_batch" - @echo "... cov_dense_biased_batch" - @echo "... cov_dense_biased_online" - @echo "... cov_dense_online" - @echo "... csr_accessor" - @echo "... csr_table" - @echo "... dbscan_brute_force_batch" - @echo "... df_cls_hist_batch" - @echo "... df_cls_hist_batch_random" - @echo "... df_cls_traverse_model" - @echo "... df_reg_hist_batch" - @echo "... df_reg_hist_batch_random" - @echo "... df_reg_traverse_model" - @echo "... heterogen_table" - @echo "... homogen_table" - @echo "... kmeans_init_dense" - @echo "... kmeans_lloyd_csr_batch" - @echo "... kmeans_lloyd_dense_batch" - @echo "... knn_cls_brute_force_dense_batch" - @echo "... knn_reg_brute_force_dense_batch" - @echo "... knn_search_brute_force_dense_batch" - @echo "... linear_kernel_dense_batch" - @echo "... linear_regression_dense_batch" - @echo "... linear_regression_dense_online" - @echo "... logistic_regression_dense_batch" - @echo "... pca_cor_dense_batch" - @echo "... pca_cor_dense_online" - @echo "... pca_cov_dense_batch" - @echo "... pca_cov_dense_online" - @echo "... pca_precomputed_cor_dense_batch" - @echo "... pca_precomputed_cov_dense_batch" - @echo "... pca_svd_dense_batch" - @echo "... rbf_kernel_dense_batch" - @echo "... read_batch" - @echo "... svm_two_class_thunder_dense_batch" - @echo "... triangle_counting_batch" - @echo "... source/basic_statistics/basic_statistics_dense_batch.o" - @echo "... source/basic_statistics/basic_statistics_dense_batch.i" - @echo "... source/basic_statistics/basic_statistics_dense_batch.s" - @echo "... source/basic_statistics/basic_statistics_dense_online.o" - @echo "... source/basic_statistics/basic_statistics_dense_online.i" - @echo "... source/basic_statistics/basic_statistics_dense_online.s" - @echo "... source/connected_components/connected_components_batch.o" - @echo "... source/connected_components/connected_components_batch.i" - @echo "... source/connected_components/connected_components_batch.s" - @echo "... source/correlation_distance/correlation_distance_dense_batch.o" - @echo "... source/correlation_distance/correlation_distance_dense_batch.i" - @echo "... source/correlation_distance/correlation_distance_dense_batch.s" - @echo "... source/cosine_distance/cosine_distance_dense_batch.o" - @echo "... source/cosine_distance/cosine_distance_dense_batch.i" - @echo "... source/cosine_distance/cosine_distance_dense_batch.s" - @echo "... source/covariance/cor_dense_batch.o" - @echo "... source/covariance/cor_dense_batch.i" - @echo "... source/covariance/cor_dense_batch.s" - @echo "... source/covariance/cor_dense_online.o" - @echo "... source/covariance/cor_dense_online.i" - @echo "... source/covariance/cor_dense_online.s" - @echo "... source/covariance/cov_dense_batch.o" - @echo "... source/covariance/cov_dense_batch.i" - @echo "... source/covariance/cov_dense_batch.s" - @echo "... source/covariance/cov_dense_biased_batch.o" - @echo "... source/covariance/cov_dense_biased_batch.i" - @echo "... source/covariance/cov_dense_biased_batch.s" - @echo "... source/covariance/cov_dense_biased_online.o" - @echo "... source/covariance/cov_dense_biased_online.i" - @echo "... source/covariance/cov_dense_biased_online.s" - @echo "... source/covariance/cov_dense_online.o" - @echo "... source/covariance/cov_dense_online.i" - @echo "... source/covariance/cov_dense_online.s" - @echo "... source/dbscan/dbscan_brute_force_batch.o" - @echo "... source/dbscan/dbscan_brute_force_batch.i" - @echo "... source/dbscan/dbscan_brute_force_batch.s" - @echo "... source/decision_forest/df_cls_hist_batch.o" - @echo "... source/decision_forest/df_cls_hist_batch.i" - @echo "... source/decision_forest/df_cls_hist_batch.s" - @echo "... source/decision_forest/df_cls_hist_batch_random.o" - @echo "... source/decision_forest/df_cls_hist_batch_random.i" - @echo "... source/decision_forest/df_cls_hist_batch_random.s" - @echo "... source/decision_forest/df_cls_traverse_model.o" - @echo "... source/decision_forest/df_cls_traverse_model.i" - @echo "... source/decision_forest/df_cls_traverse_model.s" - @echo "... source/decision_forest/df_reg_hist_batch.o" - @echo "... source/decision_forest/df_reg_hist_batch.i" - @echo "... source/decision_forest/df_reg_hist_batch.s" - @echo "... source/decision_forest/df_reg_hist_batch_random.o" - @echo "... source/decision_forest/df_reg_hist_batch_random.i" - @echo "... source/decision_forest/df_reg_hist_batch_random.s" - @echo "... source/decision_forest/df_reg_traverse_model.o" - @echo "... source/decision_forest/df_reg_traverse_model.i" - @echo "... source/decision_forest/df_reg_traverse_model.s" - @echo "... source/kmeans/kmeans_lloyd_csr_batch.o" - @echo "... source/kmeans/kmeans_lloyd_csr_batch.i" - @echo "... source/kmeans/kmeans_lloyd_csr_batch.s" - @echo "... source/kmeans/kmeans_lloyd_dense_batch.o" - @echo "... source/kmeans/kmeans_lloyd_dense_batch.i" - @echo "... source/kmeans/kmeans_lloyd_dense_batch.s" - @echo "... source/kmeans_init/kmeans_init_dense.o" - @echo "... source/kmeans_init/kmeans_init_dense.i" - @echo "... source/kmeans_init/kmeans_init_dense.s" - @echo "... source/knn/knn_cls_brute_force_dense_batch.o" - @echo "... source/knn/knn_cls_brute_force_dense_batch.i" - @echo "... source/knn/knn_cls_brute_force_dense_batch.s" - @echo "... source/knn/knn_reg_brute_force_dense_batch.o" - @echo "... source/knn/knn_reg_brute_force_dense_batch.i" - @echo "... source/knn/knn_reg_brute_force_dense_batch.s" - @echo "... source/knn/knn_search_brute_force_dense_batch.o" - @echo "... source/knn/knn_search_brute_force_dense_batch.i" - @echo "... source/knn/knn_search_brute_force_dense_batch.s" - @echo "... source/linear_kernel/linear_kernel_dense_batch.o" - @echo "... source/linear_kernel/linear_kernel_dense_batch.i" - @echo "... source/linear_kernel/linear_kernel_dense_batch.s" - @echo "... source/linear_regression/linear_regression_dense_batch.o" - @echo "... source/linear_regression/linear_regression_dense_batch.i" - @echo "... source/linear_regression/linear_regression_dense_batch.s" - @echo "... source/linear_regression/linear_regression_dense_online.o" - @echo "... source/linear_regression/linear_regression_dense_online.i" - @echo "... source/linear_regression/linear_regression_dense_online.s" - @echo "... source/logistic_regression/logistic_regression_dense_batch.o" - @echo "... source/logistic_regression/logistic_regression_dense_batch.i" - @echo "... source/logistic_regression/logistic_regression_dense_batch.s" - @echo "... source/misc/read_batch.o" - @echo "... source/misc/read_batch.i" - @echo "... source/misc/read_batch.s" - @echo "... source/pca/pca_cor_dense_batch.o" - @echo "... source/pca/pca_cor_dense_batch.i" - @echo "... source/pca/pca_cor_dense_batch.s" - @echo "... source/pca/pca_cor_dense_online.o" - @echo "... source/pca/pca_cor_dense_online.i" - @echo "... source/pca/pca_cor_dense_online.s" - @echo "... source/pca/pca_cov_dense_batch.o" - @echo "... source/pca/pca_cov_dense_batch.i" - @echo "... source/pca/pca_cov_dense_batch.s" - @echo "... source/pca/pca_cov_dense_online.o" - @echo "... source/pca/pca_cov_dense_online.i" - @echo "... source/pca/pca_cov_dense_online.s" - @echo "... source/pca/pca_precomputed_cor_dense_batch.o" - @echo "... source/pca/pca_precomputed_cor_dense_batch.i" - @echo "... source/pca/pca_precomputed_cor_dense_batch.s" - @echo "... source/pca/pca_precomputed_cov_dense_batch.o" - @echo "... source/pca/pca_precomputed_cov_dense_batch.i" - @echo "... source/pca/pca_precomputed_cov_dense_batch.s" - @echo "... source/pca/pca_svd_dense_batch.o" - @echo "... source/pca/pca_svd_dense_batch.i" - @echo "... source/pca/pca_svd_dense_batch.s" - @echo "... source/rbf_kernel/rbf_kernel_dense_batch.o" - @echo "... source/rbf_kernel/rbf_kernel_dense_batch.i" - @echo "... source/rbf_kernel/rbf_kernel_dense_batch.s" - @echo "... source/svm/svm_two_class_thunder_dense_batch.o" - @echo "... source/svm/svm_two_class_thunder_dense_batch.i" - @echo "... source/svm/svm_two_class_thunder_dense_batch.s" - @echo "... source/table/column_accessor_homogen.o" - @echo "... source/table/column_accessor_homogen.i" - @echo "... source/table/column_accessor_homogen.s" - @echo "... source/table/csr_accessor.o" - @echo "... source/table/csr_accessor.i" - @echo "... source/table/csr_accessor.s" - @echo "... source/table/csr_table.o" - @echo "... source/table/csr_table.i" - @echo "... source/table/csr_table.s" - @echo "... source/table/heterogen_table.o" - @echo "... source/table/heterogen_table.i" - @echo "... source/table/heterogen_table.s" - @echo "... source/table/homogen_table.o" - @echo "... source/table/homogen_table.i" - @echo "... source/table/homogen_table.s" - @echo "... source/triangle_counting/triangle_counting_batch.o" - @echo "... source/triangle_counting/triangle_counting_batch.i" - @echo "... source/triangle_counting/triangle_counting_batch.s" -.PHONY : help - - - -#============================================================================= -# Special targets to cleanup operation of make. - -# Special rule to run CMake to check the build system integrity. -# No rule that depends on this can have commands that come from listfiles -# because they might be regenerated. -cmake_check_build_system: - $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 -.PHONY : cmake_check_build_system - diff --git a/examples/oneapi/dpc/build/cmake_install.cmake b/examples/oneapi/dpc/build/cmake_install.cmake deleted file mode 100644 index 15527649405..00000000000 --- a/examples/oneapi/dpc/build/cmake_install.cmake +++ /dev/null @@ -1,54 +0,0 @@ -# Install script for directory: /export/users/okruglov/oneDAL/examples/oneapi/dpc - -# Set the install prefix -if(NOT DEFINED CMAKE_INSTALL_PREFIX) - set(CMAKE_INSTALL_PREFIX "/usr/local") -endif() -string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") - -# Set the install configuration name. -if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) - if(BUILD_TYPE) - string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" - CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") - else() - set(CMAKE_INSTALL_CONFIG_NAME "Release") - endif() - message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") -endif() - -# Set the component getting installed. -if(NOT CMAKE_INSTALL_COMPONENT) - if(COMPONENT) - message(STATUS "Install component: \"${COMPONENT}\"") - set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") - else() - set(CMAKE_INSTALL_COMPONENT) - endif() -endif() - -# Install shared libraries without execute permission? -if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) - set(CMAKE_INSTALL_SO_NO_EXE "1") -endif() - -# Is this installation the result of a crosscompile? -if(NOT DEFINED CMAKE_CROSSCOMPILING) - set(CMAKE_CROSSCOMPILING "FALSE") -endif() - -# Set default install directory permissions. -if(NOT DEFINED CMAKE_OBJDUMP) - set(CMAKE_OBJDUMP "/usr/bin/objdump") -endif() - -if(CMAKE_INSTALL_COMPONENT) - set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") -else() - set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") -endif() - -string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT - "${CMAKE_INSTALL_MANIFEST_FILES}") -file(WRITE "/export/users/okruglov/oneDAL/examples/oneapi/dpc/build/${CMAKE_INSTALL_MANIFEST}" - "${CMAKE_INSTALL_MANIFEST_CONTENT}") From 2e7f266297aaba5d916b4741274c0c574180976b Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Mon, 11 May 2026 09:31:17 -0700 Subject: [PATCH 67/69] Temaplate instantiation fix --- .../detail/vertex_partitioning_default_kernel.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp index 096de96fb9f..09a8c3dd618 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp @@ -32,7 +32,8 @@ operator()(const dal::detail::host_policy& policy, }); } -template struct ONEDAL_EXPORT - afforest>; +template struct afforest>; } // namespace oneapi::dal::preview::connected_components::detail From 17536dba9f0630d717147273256524cc0d40dcda Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Mon, 11 May 2026 11:33:51 -0700 Subject: [PATCH 68/69] Fix --- .../detail/vertex_partitioning_default_kernel.cpp | 10 ++++++++++ .../detail/vertex_partitioning_default_kernel.hpp | 10 +++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp index 09a8c3dd618..4235f6ea1cb 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp @@ -36,4 +36,14 @@ template struct afforest>; +vertex_partitioning_result run_afforest( + const dal::detail::host_policy& ctx, + const detail::descriptor_base& desc, + const dal::preview::detail::topology& t, + byte_alloc_iface* alloc) { + return afforest>{}(ctx, desc, t, alloc); +} + } // namespace oneapi::dal::preview::connected_components::detail diff --git a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp index ffa9e0024b7..4372c04bfaf 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.hpp @@ -78,6 +78,12 @@ struct vertex_partitioning_kernel_cpu run_afforest( + const dal::detail::host_policy& ctx, + const detail::descriptor_base& desc, + const dal::preview::detail::topology& t, + byte_alloc_iface* alloc); + template struct vertex_partitioning_kernel_cpu(); } - return afforest>{}(ctx, desc, t, &alloc_con); + return run_afforest(ctx, desc, t, &alloc_con); } }; From 4c04417299e6fa7816953ecf6f3ea8f896306552 Mon Sep 17 00:00:00 2001 From: "Kruglov, Oleg" Date: Tue, 12 May 2026 08:24:30 -0700 Subject: [PATCH 69/69] Format fix --- .../detail/vertex_partitioning_default_kernel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp index 4235f6ea1cb..05caed3188c 100644 --- a/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp +++ b/cpp/oneapi/dal/algo/connected_components/detail/vertex_partitioning_default_kernel.cpp @@ -33,8 +33,8 @@ operator()(const dal::detail::host_policy& policy, } template struct afforest>; + task::vertex_partitioning, + dal::preview::detail::topology>; vertex_partitioning_result run_afforest( const dal::detail::host_policy& ctx,

bZg6SE2%nQ_O2OI0a)(pr7!5^ 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�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 V{AOZ&m_%vY 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