• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IntelPython / dpnp / 16126000227

07 Jul 2025 07:24PM UTC coverage: 22.684% (-49.4%) from 72.051%
16126000227

Pull #2519

github

web-flow
Merge bd753a3a3 into 624f14f20
Pull Request #2519: tmp changes

889 of 9756 branches covered (9.11%)

Branch coverage included in aggregate %.

6317 of 22011 relevant lines covered (28.7%)

35.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.11
/dpnp/backend/extensions/vm/copysign.cpp
1
//*****************************************************************************
2
// Copyright (c) 2025, Intel Corporation
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are met:
7
// - Redistributions of source code must retain the above copyright notice,
8
//   this list of conditions and the following disclaimer.
9
// - Redistributions in binary form must reproduce the above copyright notice,
10
//   this list of conditions and the following disclaimer in the documentation
11
//   and/or other materials provided with the distribution.
12
//
13
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
// THE POSSIBILITY OF SUCH DAMAGE.
24
//*****************************************************************************
25

26
#include <stdexcept>
27

28
#include <oneapi/mkl.hpp>
29
#include <sycl/sycl.hpp>
30

31
#include "dpctl4pybind11.hpp"
32

33
#include "common.hpp"
34
#include "copysign.hpp"
35

36
// include a local copy of elementwise common header from dpctl tensor:
37
// dpctl/tensor/libtensor/source/elementwise_functions/elementwise_functions.hpp
38
// TODO: replace by including dpctl header once available
39
#include "../elementwise_functions/elementwise_functions.hpp"
40

41
// dpctl tensor headers
42
#include "kernels/elementwise_functions/common.hpp"
43
#include "utils/type_dispatch.hpp"
44
#include "utils/type_utils.hpp"
45

46
namespace dpnp::extensions::vm
47
{
48
namespace py = pybind11;
49
namespace py_int = dpnp::extensions::py_internal;
50
namespace td_ns = dpctl::tensor::type_dispatch;
51

52
namespace impl
53
{
54
namespace ew_cmn_ns = dpctl::tensor::kernels::elementwise_common;
55
namespace mkl_vm = oneapi::mkl::vm; // OneMKL namespace with VM functions
56
namespace tu_ns = dpctl::tensor::type_utils;
57

58
/**
59
 * @brief A factory to define pairs of supported types for which
60
 * MKL VM library provides support in oneapi::mkl::vm::copysign<T> function.
61
 *
62
 * @tparam T Type of input vectors `a` and `b` and of result vector `y`.
63
 */
64
template <typename T1, typename T2>
65
struct OutputType
66
{
67
    using value_type = typename std::disjunction<
68
        td_ns::BinaryTypeMapResultEntry<T1, double, T2, double, double>,
69
        td_ns::BinaryTypeMapResultEntry<T1, float, T2, float, float>,
70
        td_ns::DefaultResultEntry<void>>::result_type;
71
};
72

73
template <typename T1, typename T2>
74
static sycl::event copysign_contig_impl(sycl::queue &exec_q,
75
                                        std::size_t in_n,
76
                                        const char *in_a,
77
                                        py::ssize_t a_offset,
78
                                        const char *in_b,
79
                                        py::ssize_t b_offset,
80
                                        char *out_y,
81
                                        py::ssize_t out_offset,
82
                                        const std::vector<sycl::event> &depends)
83
{
×
84
    tu_ns::validate_type_for_device<T1>(exec_q);
×
85
    tu_ns::validate_type_for_device<T2>(exec_q);
×
86

87
    if ((a_offset != 0) || (b_offset != 0) || (out_offset != 0)) {
×
88
        throw std::runtime_error("Arrays offsets have to be equals to 0");
×
89
    }
×
90

91
    std::int64_t n = static_cast<std::int64_t>(in_n);
×
92
    const T1 *a = reinterpret_cast<const T1 *>(in_a);
×
93
    const T2 *b = reinterpret_cast<const T2 *>(in_b);
×
94

95
    using resTy = typename OutputType<T1, T2>::value_type;
×
96
    resTy *y = reinterpret_cast<resTy *>(out_y);
×
97

98
    return mkl_vm::copysign(
×
99
        exec_q,
×
100
        n, // number of elements to be calculated
×
101
        a, // pointer `a` containing 1st input vector of size n
×
102
        b, // pointer `b` containing 2nd input vector of size n
×
103
        y, // pointer `y` to the output vector of size n
×
104
        depends);
×
105
}
×
106

107
using ew_cmn_ns::binary_contig_impl_fn_ptr_t;
108
using ew_cmn_ns::binary_contig_matrix_contig_row_broadcast_impl_fn_ptr_t;
109
using ew_cmn_ns::binary_contig_row_contig_matrix_broadcast_impl_fn_ptr_t;
110
using ew_cmn_ns::binary_strided_impl_fn_ptr_t;
111

112
static int output_typeid_vector[td_ns::num_types][td_ns::num_types];
113
static binary_contig_impl_fn_ptr_t contig_dispatch_vector[td_ns::num_types]
114
                                                         [td_ns::num_types];
115

116
MACRO_POPULATE_DISPATCH_TABLES(copysign);
117
} // namespace impl
118

119
void init_copysign(py::module_ m)
120
{
2✔
121
    using arrayT = dpctl::tensor::usm_ndarray;
2✔
122
    using event_vecT = std::vector<sycl::event>;
2✔
123

124
    impl::populate_dispatch_tables();
2✔
125
    using impl::contig_dispatch_vector;
2✔
126
    using impl::output_typeid_vector;
2✔
127

128
    auto copysign_pyapi = [&](sycl::queue &exec_q, const arrayT &src1,
2✔
129
                              const arrayT &src2, const arrayT &dst,
2✔
130
                              const event_vecT &depends = {}) {
2✔
131
        return py_int::py_binary_ufunc(
×
132
            src1, src2, dst, exec_q, depends, output_typeid_vector,
×
133
            contig_dispatch_vector,
×
134
            // no support of strided implementation in OneMKL
135
            td_ns::NullPtrTable<impl::binary_strided_impl_fn_ptr_t>{},
×
136
            // no support of C-contig row with broadcasting in OneMKL
137
            td_ns::NullPtrTable<
×
138
                impl::
×
139
                    binary_contig_matrix_contig_row_broadcast_impl_fn_ptr_t>{},
×
140
            td_ns::NullPtrTable<
×
141
                impl::
×
142
                    binary_contig_row_contig_matrix_broadcast_impl_fn_ptr_t>{});
×
143
    };
×
144
    m.def(
2✔
145
        "_copysign", copysign_pyapi,
2✔
146
        "Call `copysign` function from OneMKL VM library to return `dst` with "
2✔
147
        "the elements of `src1` with the sign changed to match the sign "
2✔
148
        "of the corresponding elements of `src2`",
2✔
149
        py::arg("sycl_queue"), py::arg("src1"), py::arg("src2"), py::arg("dst"),
2✔
150
        py::arg("depends") = py::list());
2✔
151

152
    auto copysign_need_to_call_pyapi = [&](sycl::queue &exec_q,
2✔
153
                                           const arrayT &src1,
2✔
154
                                           const arrayT &src2,
2✔
155
                                           const arrayT &dst) {
2✔
156
        return py_internal::need_to_call_binary_ufunc(exec_q, src1, src2, dst,
×
157
                                                      output_typeid_vector,
×
158
                                                      contig_dispatch_vector);
×
159
    };
×
160
    m.def("_mkl_copysign_to_call", copysign_need_to_call_pyapi,
2✔
161
          "Check input arguments to answer if `copysign` function from "
2✔
162
          "OneMKL VM library can be used",
2✔
163
          py::arg("sycl_queue"), py::arg("src1"), py::arg("src2"),
2✔
164
          py::arg("dst"));
2✔
165
}
2✔
166
} // namespace dpnp::extensions::vm
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc