Skip to content

dpnp.divide() doesn't work properly with a scalar #1295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions dpnp/backend/include/dpnp_gen_2arg_3type_tbl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@

MACRO_2ARG_3TYPES_OP(dpnp_add_c,
input1_elem + input2_elem,
sycl::add_sat(x1, x2),
MACRO_UNPACK_TYPES(int, long),
x1 + x2,
MACRO_UNPACK_TYPES(int, long, bool),
oneapi::mkl::vm::add,
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

Expand All @@ -132,10 +132,10 @@ MACRO_2ARG_3TYPES_OP(dpnp_copysign_c,

MACRO_2ARG_3TYPES_OP(dpnp_divide_c,
input1_elem / input2_elem,
nullptr,
std::false_type,
x1 / x2,
MACRO_UNPACK_TYPES(int, long, bool),
oneapi::mkl::vm::div,
MACRO_UNPACK_TYPES(float, double))
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

MACRO_2ARG_3TYPES_OP(dpnp_fmod_c,
sycl::fmod((double)input1_elem, (double)input2_elem),
Expand Down Expand Up @@ -169,9 +169,9 @@ MACRO_2ARG_3TYPES_OP(dpnp_minimum_c,
// pytest "tests/third_party/cupy/creation_tests/test_ranges.py::TestMgrid::test_mgrid3"
// requires multiplication shape1[10] with shape2[10,1] and result expected as shape[10,10]
MACRO_2ARG_3TYPES_OP(dpnp_multiply_c,
input1_elem* input2_elem,
nullptr,
std::false_type,
input1_elem * input2_elem,
x1 * x2,
MACRO_UNPACK_TYPES(int, long, bool),
oneapi::mkl::vm::mul,
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

Expand All @@ -184,9 +184,9 @@ MACRO_2ARG_3TYPES_OP(dpnp_power_c,

MACRO_2ARG_3TYPES_OP(dpnp_subtract_c,
input1_elem - input2_elem,
nullptr,
std::false_type,
x1 - x2,
MACRO_UNPACK_TYPES(int, long, bool),
oneapi::mkl::vm::sub,
MACRO_UNPACK_TYPES(float, double))
MACRO_UNPACK_TYPES(float, double, std::complex<float>, std::complex<double>))

#undef MACRO_2ARG_3TYPES_OP
22 changes: 20 additions & 2 deletions dpnp/backend/include/dpnp_iface_fptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,26 @@ size_t operator-(DPNPFuncType lhs, DPNPFuncType rhs);
*/
typedef struct DPNPFuncData
{
DPNPFuncType return_type; /**< return type identifier which expected by the @ref ptr function */
void* ptr; /**< C++ backend function pointer */
DPNPFuncData(const DPNPFuncType gen_type, void* gen_ptr, const DPNPFuncType type_no_fp64, void* ptr_no_fp64)
: return_type(gen_type)
, ptr(gen_ptr)
, return_type_no_fp64(type_no_fp64)
, ptr_no_fp64(ptr_no_fp64)
{
}
DPNPFuncData(const DPNPFuncType gen_type, void* gen_ptr)
: DPNPFuncData(gen_type, gen_ptr, DPNPFuncType::DPNP_FT_NONE, nullptr)
{
}
DPNPFuncData()
: DPNPFuncData(DPNPFuncType::DPNP_FT_NONE, nullptr)
{
}

DPNPFuncType return_type; /**< return type identifier which expected by the @ref ptr function */
void* ptr; /**< C++ backend function pointer */
DPNPFuncType return_type_no_fp64; /**< alternative return type identifier when no fp64 support by device */
void* ptr_no_fp64; /**< alternative C++ backend function pointer when no fp64 support by device */
} DPNPFuncData_t;

/**
Expand Down
262 changes: 136 additions & 126 deletions dpnp/backend/kernels/dpnp_krnl_elemwise.cpp

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions dpnp/backend/src/dpnp_fptr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <map>
#include <complex>

#include <CL/sycl.hpp>

#include <dpnp_iface_fptr.hpp>

/**
Expand Down Expand Up @@ -116,6 +118,31 @@ static constexpr DPNPFuncType populate_func_types()
return (FT1 < FT2) ? FT2 : FT1;
}

/**
* @brief A helper function to cast SYCL vector between types.
*/
template <typename Op, typename Vec, std::size_t... I>
static auto dpnp_vec_cast_impl(const Vec& v, std::index_sequence<I...>)
{
return Op{v[I]...};
}

/**
* @brief A casting function for SYCL vector.
*
* @tparam dstT A result type upon casting.
* @tparam srcT An incoming type of the vector.
* @tparam N A number of elements with the vector.
* @tparam Indices A sequence of integers
* @param s An incoming SYCL vector to cast.
* @return SYCL vector casted to desctination type.
*/
template <typename dstT, typename srcT, std::size_t N, typename Indices = std::make_index_sequence<N>>
static auto dpnp_vec_cast(const sycl::vec<srcT, N>& s)
{
return dpnp_vec_cast_impl<sycl::vec<dstT, N>, sycl::vec<srcT, N>>(s, Indices{});
}

/**
* Removes parentheses for a passed list of types separated by comma.
* It's intended to be used in operations macro.
Expand All @@ -142,6 +169,12 @@ struct are_same : std::conjunction<std::is_same<T, Ts>...> {};
template <typename T1, typename T2, typename... Ts>
constexpr auto both_types_are_same = std::conjunction_v<is_any<T1, Ts...>, are_same<T1, T2>>;

/**
* A template constat to check if both types T1 and T2 match any type from Ts.
*/
template <typename T1, typename T2, typename... Ts>
constexpr auto both_types_are_any_of = std::conjunction_v<is_any<T1, Ts...>, is_any<T2, Ts...>>;

/**
* A template constat to check if both types T1 and T2 don't match any type from Ts sequence.
*/
Expand Down
2 changes: 2 additions & 0 deletions dpnp/dpnp_algo/dpnp_algo.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ cdef extern from "dpnp_iface_fptr.hpp":
struct DPNPFuncData:
DPNPFuncType return_type
void * ptr
DPNPFuncType return_type_no_fp64
void *ptr_no_fp64

DPNPFuncData get_dpnp_function_ptr(DPNPFuncName name, DPNPFuncType first_type, DPNPFuncType second_type) except +

Expand Down
14 changes: 10 additions & 4 deletions dpnp/dpnp_algo/dpnp_algo.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,6 @@ cdef utils.dpnp_descriptor call_fptr_2in_1out_strides(DPNPFuncName fptr_name,
# get the FPTR data structure
cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(fptr_name, x1_c_type, x2_c_type)

result_type = dpnp_DPNPFuncType_to_dtype( < size_t > kernel_data.return_type)

# Create result array
cdef shape_type_c x1_shape = x1_obj.shape

Expand All @@ -495,6 +493,15 @@ cdef utils.dpnp_descriptor call_fptr_2in_1out_strides(DPNPFuncName fptr_name,

result_sycl_device, result_usm_type, result_sycl_queue = utils.get_common_usm_allocation(x1_obj, x2_obj)

# get FPTR function and result type
cdef fptr_2in_1out_strides_t func = NULL
if fptr_name != DPNP_FN_DIVIDE_EXT or result_sycl_device.has_aspect_fp64:
result_type = dpnp_DPNPFuncType_to_dtype(< size_t > kernel_data.return_type)
func = < fptr_2in_1out_strides_t > kernel_data.ptr
else:
result_type = dpnp_DPNPFuncType_to_dtype(< size_t > kernel_data.return_type_no_fp64)
func = < fptr_2in_1out_strides_t > kernel_data.ptr_no_fp64

if out is None:
""" Create result array with type given by FPTR data """
result = utils.create_output_descriptor(result_shape,
Expand All @@ -517,11 +524,10 @@ cdef utils.dpnp_descriptor call_fptr_2in_1out_strides(DPNPFuncName fptr_name,

result_obj = result.get_array()

cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_obj.sycl_queue
cdef c_dpctl.SyclQueue q = < c_dpctl.SyclQueue > result_obj.sycl_queue
cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()

""" Call FPTR function """
cdef fptr_2in_1out_strides_t func = <fptr_2in_1out_strides_t > kernel_data.ptr
cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
result.get_data(),
result.size,
Expand Down
4 changes: 3 additions & 1 deletion dpnp/dpnp_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,9 @@ def __rmul__(self, other):
# '__rpow__',
# '__rrshift__',
# '__rshift__',
# '__rsub__',

def __rsub__(self, other):
return dpnp.subtract(other, self)

def __rtruediv__(self, other):
return dpnp.true_divide(other, self)
Expand Down
Loading