Skip to content

Commit

Permalink
ENH: Implement GPU version of spectral decomposition as linear regres…
Browse files Browse the repository at this point in the history
…sion fallback (#2976)

* add spectral decomposition fallback on GPU

* fix failing min diagonal

* switch back to sycl reduction for diag min

* try another way

* use ndarray instead of array for allocation

* avoid copying unused entries in array

* Update cpp/oneapi/dal/backend/primitives/lapack/solve_dpc.cpp

Co-authored-by: Victoriya Fedotova <[email protected]>

* follow internal logic for error messages

* add comment about the try-catch block

* add manual wait-and-throw call where appropriate

* use internal wrappers for blas calls

* add comment about dimensions of inputs

* change format of comments

* add comment about threshold for diagonal minimum

* avoid manually throwing MKL error

* remove accidentally commited file

* wrap procedure in a function

---------

Co-authored-by: Victoriya Fedotova <[email protected]>
  • Loading branch information
david-cortes-intel and Vika-F authored Nov 21, 2024
1 parent 49c0200 commit 08fd918
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 43 deletions.
3 changes: 2 additions & 1 deletion cpp/oneapi/dal/algo/linear_regression/test/batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ TEMPLATE_LIST_TEST_M(lr_batch_test, "LR common flow", "[lr][batch]", lr_types) {
}

TEMPLATE_LIST_TEST_M(lr_batch_test, "LR with non-PSD matrix", "[lr][batch-nonpsd]", lr_types) {
SKIP_IF(this->non_psd_system_not_supported_on_device());
SKIP_IF(this->not_float64_friendly());

this->generate(777);

this->run_and_check_linear_indefinite();
this->run_and_check_linear_indefinite_multioutput();
}
Expand Down
78 changes: 39 additions & 39 deletions cpp/oneapi/dal/algo/linear_regression/test/fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
return static_cast<Derived*>(this);
}

bool non_psd_system_not_supported_on_device() {
return this->get_policy().is_gpu();
}

table compute_responses(const table& beta, const table& bias, const table& data) const {
const auto s_count = data.get_row_count();

Expand Down Expand Up @@ -299,18 +295,20 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
here is not positive-definite, thus it has an infinite number of possible solutions. The
solution here is the one with minimum norm, which is typically more desirable. */
void run_and_check_linear_indefinite(double tol = 1e-3) {
const double X[] = { -0.98912135, -0.36778665, 1.28792526, 0.19397442, 0.9202309,
0.57710379, -0.63646365, 0.54195222, -0.31659545, -0.32238912,
0.09716732, -1.52593041, 1.1921661, -0.67108968, 1.00026942 };
const double y[] = { 0.13632112, 1.53203308, -0.65996941 };
const auto dtype =
std::is_same<float_t, double>::value ? data_type::float64 : data_type::float32;
const float_t X[] = { -0.98912135, -0.36778665, 1.28792526, 0.19397442, 0.9202309,
0.57710379, -0.63646365, 0.54195222, -0.31659545, -0.32238912,
0.09716732, -1.52593041, 1.1921661, -0.67108968, 1.00026942 };
const float_t y[] = { 0.13632112, 1.53203308, -0.65996941 };
auto X_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(3, 5)
.copy_data(X, 3, 5)
.build();
auto y_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(3, 1)
.copy_data(y, 3, 1)
Expand All @@ -321,20 +319,20 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
const auto coefs = train_res.get_coefficients();

if (desc.get_result_options().test(result_options::intercept)) {
const double expected_beta[] = { 0.27785494,
0.53011669,
0.34352259,
0.40506216,
-1.26026447 };
const double expected_intercept[] = { 1.24485441 };
const float_t expected_beta[] = { 0.27785494,
0.53011669,
0.34352259,
0.40506216,
-1.26026447 };
const float_t expected_intercept[] = { 1.24485441 };
const auto expected_beta_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(1, 5)
.copy_data(expected_beta, 1, 5)
.build();
const auto expected_intercept_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(1, 1)
.copy_data(expected_intercept, 1, 1)
Expand All @@ -351,13 +349,13 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
}

else {
const double expected_beta[] = { 0.38217445,
0.2732197,
1.87135517,
0.63458468,
-2.08473134 };
const float_t expected_beta[] = { 0.38217445,
0.2732197,
1.87135517,
0.63458468,
-2.08473134 };
const auto expected_beta_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(1, 5)
.copy_data(expected_beta, 1, 5)
Expand All @@ -369,19 +367,21 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
}

void run_and_check_linear_indefinite_multioutput(double tol = 1e-3) {
const double X[] = { -0.98912135, -0.36778665, 1.28792526, 0.19397442, 0.9202309,
0.57710379, -0.63646365, 0.54195222, -0.31659545, -0.32238912,
0.09716732, -1.52593041, 1.1921661, -0.67108968, 1.00026942 };
const double y[] = { 0.13632112, 1.53203308, -0.65996941,
-0.31179486, 0.33776913, -2.2074711 };
const auto dtype =
std::is_same<float_t, double>::value ? data_type::float64 : data_type::float32;
const float_t X[] = { -0.98912135, -0.36778665, 1.28792526, 0.19397442, 0.9202309,
0.57710379, -0.63646365, 0.54195222, -0.31659545, -0.32238912,
0.09716732, -1.52593041, 1.1921661, -0.67108968, 1.00026942 };
const float_t y[] = { 0.13632112, 1.53203308, -0.65996941,
-0.31179486, 0.33776913, -2.2074711 };
auto X_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(3, 5)
.copy_data(X, 3, 5)
.build();
auto y_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(3, 2)
.copy_data(y, 3, 2)
Expand All @@ -392,19 +392,19 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
const auto coefs = train_res.get_coefficients();

if (desc.get_result_options().test(result_options::intercept)) {
const double expected_beta[] = {
const float_t expected_beta[] = {
-0.18692112, -0.20034801, -0.09590892, -0.13672683, 0.56229012,
-0.97006008, 1.39413595, 0.49238012, 1.11041239, -0.79213452,
};
const double expected_intercept[] = { -0.48964358, 0.96467681 };
const float_t expected_intercept[] = { -0.48964358, 0.96467681 };
const auto expected_beta_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(2, 5)
.copy_data(expected_beta, 2, 5)
.build();
const auto expected_intercept_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(1, 2)
.copy_data(expected_intercept, 1, 2)
Expand All @@ -421,11 +421,11 @@ class lr_test : public te::crtp_algo_fixture<TestType, Derived> {
}

else {
const double expected_beta[] = { -0.22795353, -0.09930168, -0.69685744, -0.22700585,
0.88658098, -0.88921961, 1.19505839, 1.67634561,
1.2882766, -1.43103981 };
const float_t expected_beta[] = { -0.22795353, -0.09930168, -0.69685744, -0.22700585,
0.88658098, -0.88921961, 1.19505839, 1.67634561,
1.2882766, -1.43103981 };
const auto expected_beta_tbl = oneapi::dal::detail::homogen_table_builder()
.set_data_type(data_type::float64)
.set_data_type(dtype)
.set_layout(data_layout::row_major)
.allocate(2, 5)
.copy_data(expected_beta, 2, 5)
Expand Down
Loading

0 comments on commit 08fd918

Please sign in to comment.