Skip to content

Commit

Permalink
implementation of dpnp.fft.rfft2, dpnp.fft.irfft2, `dpnp.fft.rfft…
Browse files Browse the repository at this point in the history
…n`, `dpnp.fft.irfftn` (#1982)

* implement rfft2, irfft2, rfftn, irfftn

* clean up backend

* address comments

* remove hermitian

* minor changes

* add no_none=True

* remove _normalize_order

---------

Co-authored-by: Anton <[email protected]>
  • Loading branch information
vtavana and antonwolfy authored Aug 19, 2024
1 parent 5c9752b commit dea8ada
Show file tree
Hide file tree
Showing 10 changed files with 969 additions and 403 deletions.
2 changes: 1 addition & 1 deletion dpnp/backend/extensions/fft/in_place.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ std::pair<sycl::event, sycl::event>
const bool is_forward,
const std::vector<sycl::event> &depends)
{
bool committed = descr.is_committed();
const bool committed = descr.is_committed();
if (!committed) {
throw py::value_error("Descriptor is not committed");
}
Expand Down
15 changes: 8 additions & 7 deletions dpnp/backend/extensions/fft/out_of_place.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ std::pair<sycl::event, sycl::event>
const bool is_forward,
const std::vector<sycl::event> &depends)
{
bool committed = descr.is_committed();
const bool committed = descr.is_committed();
if (!committed) {
throw py::value_error("Descriptor is not committed");
}
Expand Down Expand Up @@ -93,8 +93,8 @@ std::pair<sycl::event, sycl::event>
if (in_nd > 1) {
for (int i = 0; i < in_nd - 1; ++i) {
if (in_shape[i] != out_shape[i]) {
throw py::value_error("The shape of the input and output "
"arrays must be the same.");
throw py::value_error("The shape of the output array is not "
"correct for the given input array.");
}
in_size *= in_shape[i];
}
Expand All @@ -105,17 +105,18 @@ std::pair<sycl::event, sycl::event>
// r2c FFT
N = m / 2 + 1; // integer divide
if (n != N) {
throw py::value_error("The shape of the output array is not "
"correct for real to complex transform.");
throw py::value_error(
"The shape of the output array is not correct for the given "
"input array in real to complex FFT transform.");
}
}
else {
// c2c and c2r FFT. For c2r FFT, input is zero-padded in python side to
// have the same size as output before calling this function
N = m;
if (n != N) {
throw py::value_error("The shape of the input array must be "
"the same as the shape of the output array.");
throw py::value_error("The shape of the output array is not "
"correct for the given input array.");
}
}

Expand Down
22 changes: 0 additions & 22 deletions dpnp/dpnp_utils/dpnp_algo_utils.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,12 @@ cpdef checker_throw_value_error(function_name, param_name, param, expected)
"""


cpdef checker_throw_axis_error(function_name, param_name, param, expected)
""" Throw exception AxisError if 'param' is not 'expected'
"""


cpdef checker_throw_type_error(function_name, given_type)
""" Throw exception TypeError if 'given_type' type is not supported
"""


cpdef checker_throw_index_error(function_name, index, size)
""" Throw exception IndexError if 'index' is out of bounds
"""


cpdef cpp_bool use_origin_backend(input1=*, size_t compute_size=*)
"""
This function needs to redirect particular computation cases to original backend
Expand All @@ -69,17 +57,7 @@ Return:


cpdef tuple _object_to_tuple(object obj)
cdef int _normalize_order(order, cpp_bool allow_k=*) except? 0

cpdef shape_type_c normalize_axis(object axis, size_t shape_size)
"""
Conversion of the transformation shape axis [-1, 0, 1] into [2, 0, 1] where numbers are `id`s of array shape axis
"""

cpdef long _get_linear_index(key, tuple shape, int ndim)
"""
Compute linear index of an element in memory from array indices
"""

cpdef tuple get_axis_offsets(shape)
"""
Expand Down
78 changes: 0 additions & 78 deletions dpnp/dpnp_utils/dpnp_algo_utils.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,14 @@ Python import functions
"""
__all__ = [
"call_origin",
"checker_throw_axis_error",
"checker_throw_index_error",
"checker_throw_type_error",
"checker_throw_value_error",
"create_output_descriptor_py",
"convert_item",
"dpnp_descriptor",
"get_axis_offsets",
"get_usm_allocations",
"_get_linear_index",
"map_dtype_to_device",
"normalize_axis",
"_object_to_tuple",
"unwrap_array",
"use_origin_backend"
Expand Down Expand Up @@ -308,17 +304,6 @@ def map_dtype_to_device(dtype, device):
raise RuntimeError(f"Unrecognized type of input dtype={dtype}")


cpdef checker_throw_axis_error(function_name, param_name, param, expected):
err_msg = f"{ERROR_PREFIX} in function {function_name}()"
err_msg += f" axes '{param_name}' expected `{expected}`, but '{param}' provided"
raise AxisError(err_msg)


cpdef checker_throw_index_error(function_name, index, size):
raise IndexError(
f"{ERROR_PREFIX} in function {function_name}() index {index} is out of bounds. dimension size `{size}`")


cpdef checker_throw_type_error(function_name, given_type):
raise TypeError(f"{ERROR_PREFIX} in function {function_name}() type '{given_type}' is not supported")

Expand Down Expand Up @@ -364,22 +349,6 @@ cpdef tuple get_axis_offsets(shape):
return _object_to_tuple(result)


cpdef long _get_linear_index(key, tuple shape, int ndim):
"""
Compute linear index of an element in memory from array indices
"""

if isinstance(key, tuple):
li = 0
m = 1
for i in range(ndim - 1, -1, -1):
li += key[i] * m
m *= shape[i]
else:
li = key
return li


cdef dpnp_descriptor create_output_descriptor(shape_type_c output_shape,
DPNPFuncType c_type,
dpnp_descriptor requested_out,
Expand Down Expand Up @@ -412,53 +381,6 @@ cdef dpnp_descriptor create_output_descriptor(shape_type_c output_shape,
return result_desc


cpdef shape_type_c normalize_axis(object axis_obj, size_t shape_size_inp):
"""
Conversion of the transformation shape axis [-1, 0, 1] into [2, 0, 1] where numbers are `id`s of array shape axis
"""

cdef shape_type_c axis = _object_to_tuple(axis_obj) # axis_obj might be a scalar
cdef ssize_t shape_size = shape_size_inp # convert type for comparison with axis id

cdef size_t axis_size = axis.size()
cdef shape_type_c result = shape_type_c(axis_size, 0)
for i in range(axis_size):
if (axis[i] >= shape_size) or (axis[i] < -shape_size):
checker_throw_axis_error("normalize_axis", "axis", axis[i], shape_size - 1)

if (axis[i] < 0):
result[i] = shape_size + axis[i]
else:
result[i] = axis[i]

return result


@cython.profile(False)
cdef inline int _normalize_order(order, cpp_bool allow_k=True) except? 0:
""" Converts memory order letters to some common view
"""

cdef int order_type
order_type = b'C' if len(order) == 0 else ord(order[0])

if order_type == b'K' or order_type == b'k':
if not allow_k:
raise ValueError("DPNP _normalize_order(): order \'K\' is not permitted")
order_type = b'K'
elif order_type == b'A' or order_type == b'a':
order_type = b'A'
elif order_type == b'C' or order_type == b'c':
order_type = b'C'
elif order_type == b'F' or order_type == b'f':
order_type = b'F'
else:
raise TypeError("DPNP _normalize_order(): order is not understood")

return order_type


@cython.profile(False)
cpdef inline tuple _object_to_tuple(object obj):
""" Converts Python object into tuple
Expand Down
Loading

0 comments on commit dea8ada

Please sign in to comment.