Repository: IntelPython/dpnp (language: python)

Issue:
Reuse dpctl.tensor.floor_divide() function.
Reused dpctl.tensor.floor_divide() function.
Fixed crash for device without support double precision.
Added tests.

The PR is about to close https://github.com/IntelPython/dpnp/issues/1404.

- [x] Have you provided a meaningful PR description?
- [x] Have you added a test, reproducer or referred to issue with a reproducer?
- [x] Have you tested your changes locally for CPU and GPU devices?
- [x] Have you made sure that new changes do not introduce compiler warnings?
- [ ] Have you checked performance impact of proposed changes?
- [ ] If this PR is a work in progress, are you filing the PR as a draft?



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/build-sphinx.yml b/.github/workflows/build-sphinx.yml
index 800c0bcf006..f58021db135 100644
--- a/.github/workflows/build-sphinx.yml
+++ b/.github/workflows/build-sphinx.yml
@@ -27,6 +27,8 @@ jobs:
 
       - name: Free Disk Space (Ubuntu)
         uses: jlumbroso/free-disk-space@main
+        with:
+          docker-images: false
 
       - name: Install Intel repository
         run: |
@@ -47,7 +49,7 @@ jobs:
         run: |
           sudo apt-get install intel-oneapi-mkl                \
                                intel-oneapi-mkl-devel          \
-                               intel-oneapi-dpcpp-cpp-compiler
+                               intel-oneapi-compiler-dpcpp-cpp
 
       # https://github.com/marketplace/actions/checkout
       - name: Install nvidia-cuda support drivers
@@ -78,7 +80,7 @@ jobs:
       - name: Install dpnp dependencies
         run: |
           conda install dpctl mkl-devel-dpcpp onedpl-devel tbb-devel dpcpp_linux-64 \
-              cmake cython pytest ninja scikit-build sysroot_linux-64">=2.28" ${{ env.CHANNELS }}
+              cmake cython"<3" pytest ninja scikit-build sysroot_linux-64">=2.28" ${{ env.CHANNELS }}
 
       - name: Install cuPy dependencies
         run: conda install cupy cudatoolkit=10.0
diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml
index 05c21604209..2f0956f8cc4 100644
--- a/.github/workflows/conda-package.yml
+++ b/.github/workflows/conda-package.yml
@@ -20,7 +20,12 @@ env:
       test_random_state.py
       test_sort.py
       test_special.py
+      test_umath.py
       test_usm_type.py
+      third_party/cupy/linalg_tests/test_product.py
+      third_party/cupy/math_tests/test_explog.py
+      third_party/cupy/math_tests/test_misc.py
+      third_party/cupy/math_tests/test_trigonometric.py
       third_party/cupy/sorting_tests/test_sort.py
   VER_JSON_NAME: 'version.json'
   VER_SCRIPT1: "import json; f = open('version.json', 'r'); j = json.load(f); f.close(); "
@@ -350,7 +355,7 @@ jobs:
       run:
         shell: ${{ matrix.os == 'windows-latest' && 'cmd /C CALL {0}' || 'bash -l {0}' }}
 
-    continue-on-error: false
+    continue-on-error: true
 
     if: |
       (github.repository == 'IntelPython/dpnp') &&
diff --git a/.github/workflows/generate_coverage.yaml b/.github/workflows/generate_coverage.yaml
index 413835d336c..5091f93a916 100644
--- a/.github/workflows/generate_coverage.yaml
+++ b/.github/workflows/generate_coverage.yaml
@@ -41,7 +41,7 @@ jobs:
           sudo apt-get install lcov
       - name: Install dpnp dependencies
         run: |
-          conda install cython llvm cmake">=3.21" scikit-build ninja pytest pytest-cov coverage[toml] \
+          conda install cython"<3" llvm cmake">=3.21" scikit-build ninja pytest pytest-cov coverage[toml] \
               dpctl dpcpp_linux-64 sysroot_linux-64">=2.28" mkl-devel-dpcpp tbb-devel onedpl-devel ${{ env.CHANNELS }}
       - name: Conda info
         run: |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7af00de7ce8..e212880a1ef 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,38 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.12.1] - 07/18/2023
+
+### Added
+
+* Added `classifiers metadata` to a description of dpnp package [#1460](https://github.com/IntelPython/dpnp/pull/1460)
+* Added `pygrep-hooks` to pre-commit config [#1454](https://github.com/IntelPython/dpnp/pull/1454)
+* Added `flake8` to pre-commit config [#1453](https://github.com/IntelPython/dpnp/pull/1453)
+* Added `isort` to pre-commit config [#1451](https://github.com/IntelPython/dpnp/pull/1451)
+* Added `clang` format to pre-commit config [#1450](https://github.com/IntelPython/dpnp/pull/1450)
+* Added `black` to pre-commit config [#1449](https://github.com/IntelPython/dpnp/pull/1449)
+* Added `pre-commit` hooks [#1448](https://github.com/IntelPython/dpnp/pull/1448)
+
+### Changed
+
+* Pinned to `dpctl>=0.14.5` as host and run dependencies [#1481](https://github.com/IntelPython/dpnp/pull/1481)
+* Pinned dependent `cython` package to a version less than `3.0.0` [#1480](https://github.com/IntelPython/dpnp/pull/1480)
+* Added a specialized kernel for `dpnp.sum` with `axis=0` as a pybind11 extension [#1479](https://github.com/IntelPython/dpnp/pull/1479)
+* Redesigned `dpnp.square` function through pybind11 extension of OneMKL call where possible or Leveraging on `dpctl.tensor` implementation [#1473](https://github.com/IntelPython/dpnp/pull/1473)
+* Redesigned `dpnp.cos` and `dpnp.sin` functions through pybind11 extension of OneMKL calls where possible or Leveraging on `dpctl.tensor` implementation [#1471](https://github.com/IntelPython/dpnp/pull/1471)
+* Redesigned `dpnp.sqrt` function through pybind11 extension of OneMKL call where possible or Leveraging on `dpctl.tensor` implementation [#1470](https://github.com/IntelPython/dpnp/pull/1470)
+* Redesigned `dpnp.log` function through pybind11 extension of OneMKL call where possible or Leveraging on `dpctl.tensor` implementation [#1469](https://github.com/IntelPython/dpnp/pull/1469)
+* Leveraged `dpctl.tensor` implementation for logical operations [#1464](https://github.com/IntelPython/dpnp/pull/1464)
+* Leveraged `dpctl.tensor` implementation for `dpnp.floor_divide` function [#1462](https://github.com/IntelPython/dpnp/pull/1462)
+* Leveraged `dpctl.tensor` implementation for comparison functions [#1458](https://github.com/IntelPython/dpnp/pull/1458)
+### Fixed
+
+* Improved `dpnp.dot` function to support OneMKL calls for input and output arrays with strides [#1477](https://github.com/IntelPython/dpnp/pull/1477)
+* Resolved issues with running `dpnp.linalg` functions on a device without fp64 support [#1474](https://github.com/IntelPython/dpnp/pull/1474)
+* Added `dtype` check of fp64 support by the resulting array in `call_origin` function [#1457](https://github.com/IntelPython/dpnp/pull/1457)
+* Resolved a compilation warning with `std::getenv()` call on Windows [#1452](https://github.com/IntelPython/dpnp/pull/1452)
+* Corrected a link to OneAPI Toolkit in Installation Guide [#1445](https://github.com/IntelPython/dpnp/pull/1445)
+
 ## [0.12.0] - 06/15/2023
 
 ### Added
diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml
index a7f20f0f01d..0701aee878a 100644
--- a/conda-recipe/meta.yaml
+++ b/conda-recipe/meta.yaml
@@ -9,11 +9,11 @@ requirements:
       - python
       - setuptools
       - numpy 1.21
-      - cython
+      - cython <3
       - cmake >=3.21
       - ninja
       - git
-      - dpctl >=0.14.3
+      - dpctl >=0.14.5
       - mkl-devel-dpcpp {{ environ.get('MKL_VER', '>=2023.1.0') }}
       - onedpl-devel
       - tbb-devel
@@ -25,7 +25,7 @@ requirements:
       - sysroot_linux-64 >=2.28 # [linux]
     run:
       - python
-      - dpctl >=0.14.3
+      - dpctl >=0.14.5
       - {{ pin_compatible('dpcpp-cpp-rt', min_pin='x.x', max_pin='x') }}
       - {{ pin_compatible('mkl-dpcpp', min_pin='x.x', max_pin='x') }}
       - {{ pin_compatible('numpy', min_pin='x.x', max_pin='x') }}
diff --git a/doc/conf.py b/doc/conf.py
index 21361e1e701..f5d7a5db811 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -33,7 +33,7 @@
 # The short X.Y version
 version = "0.12"
 # The full version, including alpha/beta/rc tags
-release = "0.12.1dev0"
+release = "0.12.1"
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/dpnp/CMakeLists.txt b/dpnp/CMakeLists.txt
index 89524ab1c58..5ee84b28153 100644
--- a/dpnp/CMakeLists.txt
+++ b/dpnp/CMakeLists.txt
@@ -49,6 +49,7 @@ build_dpnp_cython_ext_with_backend(dparray ${CMAKE_CURRENT_SOURCE_DIR}/dparray.p
 add_subdirectory(backend)
 add_subdirectory(backend/extensions/lapack)
 add_subdirectory(backend/extensions/vm)
+add_subdirectory(backend/extensions/sycl_ext)
 
 add_subdirectory(dpnp_algo)
 add_subdirectory(dpnp_utils)
diff --git a/dpnp/backend/doc/Doxyfile b/dpnp/backend/doc/Doxyfile
index 342259d1fe1..ec73279f6eb 100644
--- a/dpnp/backend/doc/Doxyfile
+++ b/dpnp/backend/doc/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME           = "DPNP C++ backend kernel library"
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.12.1dev0
+PROJECT_NUMBER         = 0.12.1
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/dpnp/backend/extensions/sycl_ext/CMakeLists.txt b/dpnp/backend/extensions/sycl_ext/CMakeLists.txt
new file mode 100644
index 00000000000..9a18630eb3b
--- /dev/null
+++ b/dpnp/backend/extensions/sycl_ext/CMakeLists.txt
@@ -0,0 +1,72 @@
+# *****************************************************************************
+# Copyright (c) 2016-2023, Intel Corporation
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# - Redistributions of source code must retain the above copyright notice,
+#   this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+# *****************************************************************************
+
+
+set(python_module_name _sycl_ext_impl)
+pybind11_add_module(${python_module_name} MODULE
+    sum_mean.cpp
+)
+
+if (WIN32)
+    if (${CMAKE_VERSION} VERSION_LESS "3.27")
+        # this is a work-around for target_link_options inserting option after -link option, cause
+        # linker to ignore it.
+        set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -fsycl-device-code-split=per_kernel")
+    endif()
+endif()
+
+set_target_properties(${python_module_name} PROPERTIES CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+target_include_directories(${python_module_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
+target_include_directories(${python_module_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../src)
+
+target_include_directories(${python_module_name} PUBLIC ${Dpctl_INCLUDE_DIRS})
+target_include_directories(${python_module_name} PUBLIC ${Dpctl_TENSOR_INCLUDE_DIR})
+
+if (WIN32)
+  target_compile_options(${python_module_name} PRIVATE
+    /clang:-fno-approx-func
+    /clang:-fno-finite-math-only
+    )
+else()
+  target_compile_options(${python_module_name} PRIVATE
+    -fno-approx-func
+    -fno-finite-math-only
+    )
+endif()
+
+target_link_options(${python_module_name} PUBLIC -fsycl-device-code-split=per_kernel)
+if (UNIX)
+    # this option is support on Linux only
+    target_link_options(${python_module_name} PUBLIC -fsycl-link-huge-device-code)
+endif()
+
+if (DPNP_GENERATE_COVERAGE)
+    target_link_options(${python_module_name} PRIVATE -fprofile-instr-generate -fcoverage-mapping)
+endif()
+
+install(TARGETS ${python_module_name}
+  DESTINATION "dpnp/backend/extensions/sycl_ext"
+)
diff --git a/dpnp/backend/extensions/sycl_ext/dispatcher_utils.hpp b/dpnp/backend/extensions/sycl_ext/dispatcher_utils.hpp
new file mode 100644
index 00000000000..57f1a4e43a0
--- /dev/null
+++ b/dpnp/backend/extensions/sycl_ext/dispatcher_utils.hpp
@@ -0,0 +1,505 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <array>
+#include <tuple>
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace sycl_ext
+{
+
+template <template <typename...> class C, typename Tuple>
+struct resolve_type
+{
+};
+
+template <template <typename...> class C, typename... Args>
+struct resolve_type<C, std::tuple<Args...>>
+{
+    using type = C<Args...>;
+};
+
+template <typename Tuple>
+struct pop_tuple_type
+{
+};
+
+template <typename T, typename... Args>
+struct pop_tuple_type<std::tuple<T, Args...>>
+{
+    using element = T;
+    using rest = std::tuple<Args...>;
+};
+
+template <typename FirstTuple, typename SecondTuple>
+struct merge_two_tuple_types
+{
+};
+
+template <typename... FirstTupleArgs, typename... SecondTupleArgs>
+struct merge_two_tuple_types<std::tuple<FirstTupleArgs...>,
+                             std::tuple<SecondTupleArgs...>>
+{
+    using type = std::tuple<FirstTupleArgs..., SecondTupleArgs...>;
+};
+
+template <typename FirstTuple, typename SecondTuple>
+struct merge_two_inner_tuple_types
+{
+};
+
+template <typename... FirstTupleArgs, typename... SecondTupleArgs>
+struct merge_two_inner_tuple_types<std::tuple<std::tuple<FirstTupleArgs...>>,
+                                   std::tuple<std::tuple<SecondTupleArgs...>>>
+{
+    using type = std::tuple<std::tuple<FirstTupleArgs..., SecondTupleArgs...>>;
+};
+
+template <typename... FirstTupleArgs, typename... SecondTupleArgs>
+struct merge_two_inner_tuple_types<std::tuple<FirstTupleArgs...>,
+                                   std::tuple<SecondTupleArgs...>>
+{
+    using T1 = typename pop_tuple_type<std::tuple<FirstTupleArgs...>>::element;
+    using rest1 = typename pop_tuple_type<std::tuple<FirstTupleArgs...>>::rest;
+
+    using T2 = typename pop_tuple_type<std::tuple<SecondTupleArgs...>>::element;
+    using rest2 = typename pop_tuple_type<std::tuple<SecondTupleArgs...>>::rest;
+
+    using merged_first = typename merge_two_tuple_types<T1, T2>::type;
+    using merged_rest =
+        typename merge_two_inner_tuple_types<rest1, rest2>::type;
+
+    using type = typename merge_two_tuple_types<std::tuple<merged_first>,
+                                                merged_rest>::type;
+};
+
+template <typename Tuple, typename T>
+struct extend_tuple_type
+{
+};
+
+template <typename... Args, typename T>
+struct extend_tuple_type<std::tuple<Args...>, T>
+{
+    using type = std::tuple<Args..., T>;
+};
+
+template <typename... Args>
+struct tuple_of_tuples
+{
+};
+
+template <typename T>
+struct tuple_of_tuples<std::tuple<T>>
+{
+    using type = std::tuple<std::tuple<T>>;
+};
+
+template <typename... Args>
+struct tuple_of_tuples<std::tuple<Args...>>
+{
+    using T = typename pop_tuple_type<std::tuple<Args...>>::element;
+    using other = typename pop_tuple_type<std::tuple<Args...>>::rest;
+
+    using tuple_t = std::tuple<T>;
+    using tuple_other = typename tuple_of_tuples<other>::type;
+    using type =
+        typename merge_two_tuple_types<std::tuple<tuple_t>, tuple_other>::type;
+};
+
+template <typename T, int N>
+struct tuple_of_n_elements
+{
+    using type =
+        typename extend_tuple_type<typename tuple_of_n_elements<T, N - 1>::type,
+                                   T>::type;
+};
+
+template <typename T>
+struct tuple_of_n_elements<T, 1>
+{
+    using type = std::tuple<T>;
+};
+
+template <typename T>
+struct tuple_of_n_elements<T, 0>
+{
+    using type = std::tuple<>;
+};
+
+template <typename... Args>
+struct cartesian_product_impl
+{
+};
+
+template <typename T, typename... SecondTupleArgs>
+struct cartesian_product_impl<std::tuple<std::tuple<T>>,
+                              std::tuple<SecondTupleArgs...>>
+{
+    using extended_T_tuple =
+        typename tuple_of_n_elements<T, sizeof...(SecondTupleArgs)>::type;
+    using extended_T_tuple_of_tuples =
+        typename tuple_of_tuples<extended_T_tuple>::type;
+    using type = typename merge_two_inner_tuple_types<
+        extended_T_tuple_of_tuples,
+        std::tuple<SecondTupleArgs...>>::type;
+};
+
+template <typename T, typename... FirstTupleArgs, typename... SecondTupleArgs>
+struct cartesian_product_impl<std::tuple<std::tuple<T>, FirstTupleArgs...>,
+                              std::tuple<SecondTupleArgs...>>
+{
+    using extended_T_tuple =
+        typename tuple_of_n_elements<T, sizeof...(SecondTupleArgs)>::type;
+    using extended_T_tuple_of_tuples =
+        typename tuple_of_tuples<extended_T_tuple>::type;
+    using cartesian_with_first = typename merge_two_inner_tuple_types<
+        extended_T_tuple_of_tuples,
+        std::tuple<SecondTupleArgs...>>::type;
+    using cartesian_with_other =
+        typename cartesian_product_impl<std::tuple<FirstTupleArgs...>,
+                                        std::tuple<SecondTupleArgs...>>::type;
+    using type = typename merge_two_tuple_types<cartesian_with_first,
+                                                cartesian_with_other>::type;
+};
+
+template <typename... Args>
+struct cartesian_product
+{
+};
+
+template <typename... FirstTupleArgs>
+struct cartesian_product<std::tuple<std::tuple<FirstTupleArgs...>>>
+{
+    using type = typename tuple_of_tuples<std::tuple<FirstTupleArgs...>>::type;
+};
+
+template <typename... Tuples>
+struct cartesian_product<std::tuple<Tuples...>>
+{
+    using first_tuple = typename pop_tuple_type<std::tuple<Tuples...>>::element;
+    using other = typename pop_tuple_type<std::tuple<Tuples...>>::rest;
+    using cartesian_other = typename cartesian_product<other>::type;
+    using first_tuple_of_tuples = typename tuple_of_tuples<first_tuple>::type;
+    using type = typename cartesian_product_impl<first_tuple_of_tuples,
+                                                 cartesian_other>::type;
+};
+
+template <template <typename...> class C, typename FnT, typename Tuple>
+struct populate_table
+{
+};
+
+template <template <typename...> class C, typename FnT, typename... Args>
+struct populate_table<C, FnT, std::tuple<std::tuple<Args...>>>
+{
+    static void populate(FnT *data)
+    {
+        data[0] = resolve_type<C, std::tuple<Args...>>::type::call;
+    }
+};
+
+template <template <typename...> class C, typename FnT, typename... Args>
+struct populate_table<C, FnT, std::tuple<Args...>>
+{
+    static void populate(FnT *data)
+    {
+        using T = typename pop_tuple_type<std::tuple<Args...>>::element;
+        using rest = typename pop_tuple_type<std::tuple<Args...>>::rest;
+
+        data[0] = resolve_type<C, T>::type::call;
+        populate_table<C, FnT, rest>::populate(data + 1);
+    }
+};
+
+template <size_t idx, typename DispatchT, typename Matcher, typename Tuple>
+struct index_on_axis
+{
+};
+
+template <size_t idx, typename DispatchT, typename Matcher, typename T>
+struct index_on_axis<idx, DispatchT, Matcher, std::tuple<T>>
+{
+    static int get_index(const DispatchT &val, int *result)
+    {
+        if (Matcher::template match<T>(val)) {
+            result[0] = idx;
+            return true;
+        }
+
+        result[0] = idx + 1;
+        return false;
+    }
+};
+
+template <size_t idx,
+          typename DispatchT,
+          typename Matcher,
+          typename... AxisData>
+struct index_on_axis<idx, DispatchT, Matcher, std::tuple<AxisData...>>
+{
+    using T = typename pop_tuple_type<std::tuple<AxisData...>>::element;
+    using rest = typename pop_tuple_type<std::tuple<AxisData...>>::rest;
+
+    static int get_index(const DispatchT &val, int *result)
+    {
+        if (Matcher::template match<T>(val)) {
+            result[0] = idx;
+            return true;
+        }
+
+        return index_on_axis<idx + 1, DispatchT, Matcher, rest>::get_index(
+            val, result);
+    }
+};
+
+template <typename DispatchT, typename Matcher, typename... AxisData>
+struct coord_in_space
+{
+};
+
+template <typename DispatchT, typename Matcher, typename CurrentAxis>
+struct coord_in_space<DispatchT, Matcher, std::tuple<CurrentAxis>>
+{
+    static bool get(const DispatchT *data, int *result)
+    {
+        auto found =
+            index_on_axis<0, DispatchT, Matcher, CurrentAxis>::get_index(
+                data[0], result);
+
+        return found;
+    }
+};
+
+template <typename DispatchT, typename Matcher, typename... Axises>
+struct coord_in_space<DispatchT, Matcher, std::tuple<Axises...>>
+{
+    using CurrentAxis = typename pop_tuple_type<std::tuple<Axises...>>::element;
+    using OtherAxises = typename pop_tuple_type<std::tuple<Axises...>>::rest;
+
+    static bool get(const DispatchT *data, int *result)
+    {
+        auto found =
+            index_on_axis<0, DispatchT, Matcher, CurrentAxis>::get_index(
+                data[0], result);
+        if (found) {
+            found = coord_in_space<DispatchT, Matcher, OtherAxises>::get(
+                data + 1, result + 1);
+
+            return found;
+        }
+
+        return found;
+    }
+};
+
+template <typename Tuple>
+struct elements_count
+{
+};
+
+template <typename T>
+struct elements_count<std::tuple<T>>
+{
+    static constexpr int count()
+    {
+        return std::tuple_size_v<T>;
+    }
+};
+
+template <typename T, typename... Axis>
+struct elements_count<std::tuple<T, Axis...>>
+{
+    static constexpr int count()
+    {
+        return std::tuple_size_v<T> *
+               elements_count<std::tuple<Axis...>>::count();
+    }
+};
+
+template <typename Tuple>
+struct get_linear_id
+{
+};
+
+template <typename T>
+struct get_linear_id<std::tuple<T>>
+{
+    static int get(const int *data)
+    {
+        return data[0];
+    }
+};
+
+template <typename T, typename... Axis>
+struct get_linear_id<std::tuple<T, Axis...>>
+{
+    static int get(const int *data)
+    {
+        return data[0] * elements_count<std::tuple<Axis...>>::count() +
+               get_linear_id<std::tuple<Axis...>>::get(data + 1);
+    }
+};
+
+template <template <typename...> class C,
+          typename FnT,
+          typename DispatchT,
+          typename Matcher,
+          typename... Axis>
+struct CartesianDispatcher
+{
+    using space = typename cartesian_product<std::tuple<Axis...>>::type;
+
+    std::array<FnT, std::tuple_size_v<space>> dispatch_table;
+
+    CartesianDispatcher()
+    {
+        populate_table<C, FnT, space>::populate(dispatch_table.data());
+    }
+
+    FnT operator()(std::initializer_list<DispatchT> values)
+    {
+        // though std::initializer_list::size is constexpr it doesnt work for
+        // some reson constexpr auto const list_size = values.size();
+        std::array<int, sizeof...(Axis)> idx;
+        bool found =
+            coord_in_space<DispatchT, Matcher, std::tuple<Axis...>>::get(
+                std::data(values), idx.data());
+
+        if (found) {
+            int linear_idx =
+                get_linear_id<std::tuple<Axis...>>::get(idx.data());
+            return dispatch_table[linear_idx];
+        }
+
+        return nullptr;
+    }
+};
+
+struct UsmArrayMatcher
+{
+    template <class T>
+    static bool match(const dpctl::tensor::usm_ndarray &)
+    {
+        return false;
+    }
+};
+
+template <>
+bool UsmArrayMatcher::match<int8_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return arr.get_typenum() == UAR_BYTE;
+}
+
+template <>
+bool UsmArrayMatcher::match<uint8_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return arr.get_typenum() == UAR_UBYTE;
+}
+
+template <>
+bool UsmArrayMatcher::match<int16_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return arr.get_typenum() == UAR_SHORT;
+}
+
+template <>
+bool UsmArrayMatcher::match<uint16_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return arr.get_typenum() == UAR_USHORT;
+}
+
+template <>
+bool UsmArrayMatcher::match<int32_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return (arr.get_typenum() == UAR_INT and sizeof(int) == sizeof(int32_t)) or
+           (arr.get_typenum() == UAR_LONG and sizeof(long) == sizeof(int32_t));
+}
+
+template <>
+bool UsmArrayMatcher::match<uint32_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return (arr.get_typenum() == UAR_UINT and
+            sizeof(unsigned int) == sizeof(uint32_t)) or
+           (arr.get_typenum() == UAR_ULONG and
+            sizeof(unsigned long) == sizeof(uint32_t));
+}
+
+template <>
+bool UsmArrayMatcher::match<int64_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return (arr.get_typenum() == UAR_INT and sizeof(int) == sizeof(int64_t)) or
+           (arr.get_typenum() == UAR_LONG and
+            sizeof(long) == sizeof(int64_t)) or
+           (arr.get_typenum() == UAR_LONGLONG and
+            sizeof(long long) == sizeof(int64_t));
+}
+
+template <>
+bool UsmArrayMatcher::match<uint64_t>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return (arr.get_typenum() == UAR_UINT and
+            sizeof(unsigned int) == sizeof(uint64_t)) or
+           (arr.get_typenum() == UAR_ULONG and
+            sizeof(unsigned long) == sizeof(uint64_t)) or
+           (arr.get_typenum() == UAR_ULONGLONG and
+            sizeof(unsigned long long) == sizeof(uint64_t));
+}
+
+template <>
+bool UsmArrayMatcher::match<float>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return arr.get_typenum() == UAR_FLOAT;
+}
+
+template <>
+bool UsmArrayMatcher::match<double>(const dpctl::tensor::usm_ndarray &arr)
+{
+    return arr.get_typenum() == UAR_DOUBLE;
+}
+
+template <class NumT, class DenT>
+NumT DivUp(NumT numerator, DenT denominator)
+{
+    return (numerator + denominator - 1) / denominator;
+}
+
+template <class VT, class BT>
+VT Align(VT value, BT base)
+{
+    return base * DivUp(value, base);
+}
+
+} // namespace sycl_ext
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/sycl_ext/sum_mean.cpp b/dpnp/backend/extensions/sycl_ext/sum_mean.cpp
new file mode 100644
index 00000000000..e5097cd060a
--- /dev/null
+++ b/dpnp/backend/extensions/sycl_ext/sum_mean.cpp
@@ -0,0 +1,121 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+//
+// This file defines functions of dpnp.backend._sycl_ext_impl extensions
+//
+//*****************************************************************************
+
+#include <memory>
+
+#include <pybind11/functional.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+#include "dpctl4pybind11.hpp"
+#include "sum_mean.hpp"
+
+namespace sycl_ext = dpnp::backend::ext::sycl_ext;
+namespace py = pybind11;
+
+using dpctl::tensor::usm_ndarray;
+
+std::unique_ptr<sycl_ext::SumOverAxisContigDispatcher> sum_dispatcher;
+std::unique_ptr<sycl_ext::MeanOverAxisContigDispatcher> mean_dispatcher;
+
+void init_dispatchers(void)
+{
+    sum_dispatcher.reset(new sycl_ext::SumOverAxisContigDispatcher());
+    mean_dispatcher.reset(new sycl_ext::MeanOverAxisContigDispatcher());
+}
+
+using SumMeanFnT = sycl::event (*)(const usm_ndarray &,
+                                   usm_ndarray &,
+                                   const std::vector<sycl::event> &);
+
+sycl::event sum_over_axis(usm_ndarray input,
+                          usm_ndarray output,
+                          std::vector<sycl::event> depends)
+{
+    auto sum_fn = (*sum_dispatcher)({input, output});
+
+    if (sum_fn == nullptr)
+        throw py::value_error("No suitable implementation found");
+
+    return sum_fn(input, output, depends);
+}
+
+sycl::event mean_over_axis(usm_ndarray input,
+                           usm_ndarray output,
+                           std::vector<sycl::event> depends)
+{
+    auto mean_fn = (*mean_dispatcher)({input, output});
+
+    if (mean_fn == nullptr)
+        throw py::value_error("No suitable implementation found");
+
+    return mean_fn(input, output, depends);
+}
+
+py::object get_sum_over_axis(usm_ndarray input, usm_ndarray output)
+{
+    if (not sycl_ext::check_limitations(input, output))
+        return py::none();
+
+    auto sum = (*sum_dispatcher)({input, output});
+    if (sum == nullptr)
+        return py::none();
+
+    return py::cpp_function(sum);
+}
+
+py::object get_mean_over_axis(usm_ndarray input, usm_ndarray output)
+{
+    if (not sycl_ext::check_limitations(input, output))
+        return py::none();
+
+    auto mean = (*mean_dispatcher)({input, output});
+    if (mean == nullptr)
+        return py::none();
+
+    return py::cpp_function(mean);
+}
+
+PYBIND11_MODULE(_sycl_ext_impl, m)
+{
+    import_dpctl();
+    init_dispatchers();
+
+    m.def("_sum_over_axis_0", &sum_over_axis, "Sum over axis 0",
+          py::arg("input"), py::arg("output"), py::arg("depends") = py::list());
+
+    m.def("_mean_over_axis_0", &mean_over_axis, "Mean over axis 0",
+          py::arg("input"), py::arg("output"), py::arg("depends") = py::list());
+
+    m.def("_get_sum_over_axis_0", &get_sum_over_axis, "Sum over axis 0",
+          py::arg("input"), py::arg("output"));
+
+    m.def("_get_mean_over_axis_0", &get_mean_over_axis, "Mean over axis 0",
+          py::arg("input"), py::arg("output"));
+}
diff --git a/dpnp/backend/extensions/sycl_ext/sum_mean.hpp b/dpnp/backend/extensions/sycl_ext/sum_mean.hpp
new file mode 100644
index 00000000000..a3779901501
--- /dev/null
+++ b/dpnp/backend/extensions/sycl_ext/sum_mean.hpp
@@ -0,0 +1,220 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include "dispatcher_utils.hpp"
+#include <CL/sycl.hpp>
+#include <tuple>
+
+#include "utils/memory_overlap.hpp"
+#include "utils/type_utils.hpp"
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace sycl_ext
+{
+
+namespace py = pybind11;
+namespace type_utils = dpctl::tensor::type_utils;
+
+bool check_limitations(const dpctl::tensor::usm_ndarray &in,
+                       const dpctl::tensor::usm_ndarray &out,
+                       bool throw_on_fail = false)
+{
+    if (not in.is_c_contiguous() or not out.is_c_contiguous()) {
+        if (throw_on_fail)
+            throw py::value_error(
+                "Input and output arrays must be c-contiguos");
+
+        return false;
+    }
+
+    auto device = in.get_queue().get_device();
+    auto local_mem_size = device.get_info<sycl::info::device::local_mem_size>();
+    size_t out_full_size = out.get_size() * out.get_elemsize();
+    if (out_full_size > local_mem_size) {
+        if (throw_on_fail)
+            throw py::value_error("Resulting array exceeds local memroy size" +
+                                  std::to_string(local_mem_size));
+
+        return false;
+    }
+
+    if (out.get_elemsize() == 64 and not device.has(sycl::aspect::atomic64)) {
+        if (throw_on_fail)
+            throw py::value_error("64-bit atomics are not supported");
+
+        return false;
+    }
+
+    return true;
+}
+
+using SumMeanFuncT = sycl::event (*)(const dpctl::tensor::usm_ndarray &,
+                                     dpctl::tensor::usm_ndarray &,
+                                     const std::vector<sycl::event> &);
+
+template <typename InT, typename OutT, bool Mean>
+struct sum_mean
+{
+    static sycl::event call(sycl::queue exec_q,
+                            const InT *in,
+                            OutT *out,
+                            const size_t height,
+                            const size_t width,
+                            const std::vector<sycl::event> &depends)
+    {
+        int local_size = std::min(
+            1024,
+            int(exec_q.get_device()
+                    .get_info<sycl::info::device::max_work_group_size>()));
+
+        int WorkPI = 32; // empirically found number
+        auto _total_size = height * width;
+        auto global_size = Align(DivUp(_total_size, WorkPI), local_size);
+
+        auto fill_e = exec_q.fill(out, OutT(0), width, depends);
+
+        return exec_q.submit([&](sycl::handler &cgh) {
+            cgh.depends_on(fill_e);
+            auto local_result =
+                sycl::local_accessor<OutT>(sycl::range<1>(width), cgh);
+            cgh.parallel_for<sum_mean<InT, OutT, Mean>>(
+                sycl::nd_range<1>(global_size, local_size),
+                [=](sycl::nd_item<1> item) {
+                    auto grid = item.get_group_linear_id();
+                    auto group = item.get_group();
+                    auto llid = item.get_local_linear_id();
+
+                    for (size_t i = llid; i < width; i += local_size) {
+                        local_result[i] = 0;
+                    }
+
+                    sycl::group_barrier(group);
+
+                    for (int i = 0; i < WorkPI; ++i) {
+                        auto id =
+                            grid * WorkPI * local_size + i * local_size + llid;
+                        if (id < _total_size) {
+                            sycl::atomic_ref<OutT, sycl::memory_order::relaxed,
+                                             sycl::memory_scope::work_group>
+                                aresult(local_result[id % width]);
+                            aresult += in[id];
+                        }
+                    }
+
+                    sycl::group_barrier(group);
+
+                    for (size_t i = llid; i < width; i += local_size) {
+                        sycl::atomic_ref<OutT, sycl::memory_order::relaxed,
+                                         sycl::memory_scope::device>
+                            autput(out[i]);
+
+                        auto r = local_result[i];
+                        autput += Mean ? r / height : r;
+                    }
+                });
+        });
+    }
+
+    static sycl::event call(const dpctl::tensor::usm_ndarray &in,
+                            dpctl::tensor::usm_ndarray &out,
+                            const std::vector<sycl::event> &depends)
+    {
+        validate_params(in, out);
+        return call(in.get_queue(), in.get_data<InT>(), out.get_data<OutT>(),
+                    in.get_shape(0), in.get_shape(1), depends);
+    }
+
+    static void validate_params(const dpctl::tensor::usm_ndarray &in,
+                                dpctl::tensor::usm_ndarray &out)
+    {
+        auto exec_q = in.get_queue();
+
+        type_utils::validate_type_for_device<InT>(exec_q);
+        type_utils::validate_type_for_device<OutT>(exec_q);
+
+        // check compatibility of execution queue and allocation queue
+        if (!dpctl::utils::queues_are_compatible(exec_q, {in, out})) {
+            throw py::value_error(
+                "Execution queue is not compatible with allocation queues");
+        }
+
+        if (in.get_shape(1) != out.get_shape(0))
+            throw py::value_error(
+                "Input array axis 1 size must match output array size");
+
+        auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
+        if (overlap(in, out))
+            throw py::value_error("Input and output array are overlapped");
+
+        check_limitations(in, out, true);
+    }
+};
+
+template <typename InT, typename OutT>
+using SumOverAxisContig = sum_mean<InT, OutT, false>;
+using SumInputTypes = std::tuple<int8_t,
+                                 uint8_t,
+                                 int16_t,
+                                 uint16_t,
+                                 int32_t,
+                                 uint32_t,
+                                 int64_t,
+                                 uint64_t,
+                                 float,
+                                 double>;
+using SumOutputTypes =
+    std::tuple<int32_t, uint32_t, int64_t, uint64_t, float, double>;
+
+template <typename InT, typename OutT>
+using MeanOverAxisContig = sum_mean<InT, OutT, true>;
+using MeanInputTypes = SumInputTypes;
+using MeanOutputTypes = std::tuple<float, double>;
+
+using SumOverAxisContigDispatcher =
+    CartesianDispatcher<SumOverAxisContig,
+                        SumMeanFuncT,
+                        dpctl::tensor::usm_ndarray,
+                        UsmArrayMatcher,
+                        SumInputTypes,
+                        SumOutputTypes>;
+
+using MeanOverAxisContigDispatcher =
+    CartesianDispatcher<MeanOverAxisContig,
+                        SumMeanFuncT,
+                        dpctl::tensor::usm_ndarray,
+                        UsmArrayMatcher,
+                        SumInputTypes,
+                        MeanOutputTypes>;
+} // namespace sycl_ext
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/CMakeLists.txt b/dpnp/backend/extensions/vm/CMakeLists.txt
index 8f3086ec3a9..a81dbe1df68 100644
--- a/dpnp/backend/extensions/vm/CMakeLists.txt
+++ b/dpnp/backend/extensions/vm/CMakeLists.txt
@@ -27,7 +27,6 @@
 set(python_module_name _vm_impl)
 pybind11_add_module(${python_module_name} MODULE
     vm_py.cpp
-    div.cpp
 )
 
 if (WIN32)
diff --git a/dpnp/backend/extensions/vm/common.hpp b/dpnp/backend/extensions/vm/common.hpp
new file mode 100644
index 00000000000..787e9cd47bd
--- /dev/null
+++ b/dpnp/backend/extensions/vm/common.hpp
@@ -0,0 +1,494 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <CL/sycl.hpp>
+#include <oneapi/mkl.hpp>
+
+#include <dpctl4pybind11.hpp>
+#include <pybind11/numpy.h>
+#include <pybind11/pybind11.h>
+
+// dpctl tensor headers
+#include "utils/memory_overlap.hpp"
+#include "utils/type_dispatch.hpp"
+#include "utils/type_utils.hpp"
+
+// OneMKL namespace with VM functions
+namespace mkl_vm = oneapi::mkl::vm;
+
+// dpctl namespace for type utils
+namespace type_utils = dpctl::tensor::type_utils;
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace vm
+{
+typedef sycl::event (*unary_impl_fn_ptr_t)(sycl::queue,
+                                           const std::int64_t,
+                                           const char *,
+                                           char *,
+                                           const std::vector<sycl::event> &);
+
+typedef sycl::event (*binary_impl_fn_ptr_t)(sycl::queue,
+                                            const std::int64_t,
+                                            const char *,
+                                            const char *,
+                                            char *,
+                                            const std::vector<sycl::event> &);
+
+namespace dpctl_td_ns = dpctl::tensor::type_dispatch;
+namespace py = pybind11;
+
+template <typename dispatchT>
+std::pair<sycl::event, sycl::event>
+    unary_ufunc(sycl::queue exec_q,
+                dpctl::tensor::usm_ndarray src,
+                dpctl::tensor::usm_ndarray dst, // dst = op(src), elementwise
+                const std::vector<sycl::event> &depends,
+                const dispatchT &dispatch_vector)
+{
+    // check type_nums
+    int src_typenum = src.get_typenum();
+    int dst_typenum = dst.get_typenum();
+
+    auto array_types = dpctl_td_ns::usm_ndarray_types();
+    int src_typeid = array_types.typenum_to_lookup_id(src_typenum);
+    int dst_typeid = array_types.typenum_to_lookup_id(dst_typenum);
+
+    if (src_typeid != dst_typeid) {
+        throw py::value_error("Input and output arrays have different types.");
+    }
+
+    // check that queues are compatible
+    if (!dpctl::utils::queues_are_compatible(exec_q, {src, dst})) {
+        throw py::value_error(
+            "Execution queue is not compatible with allocation queues.");
+    }
+
+    // check that dimensions are the same
+    int dst_nd = dst.get_ndim();
+    if (dst_nd != src.get_ndim()) {
+        throw py::value_error(
+            "Input and output arrays have have different dimensions.");
+    }
+
+    // check that shapes are the same
+    const py::ssize_t *src_shape = src.get_shape_raw();
+    const py::ssize_t *dst_shape = dst.get_shape_raw();
+    bool shapes_equal(true);
+    size_t src_nelems(1);
+
+    for (int i = 0; i < dst_nd; ++i) {
+        src_nelems *= static_cast<size_t>(src_shape[i]);
+        shapes_equal = shapes_equal && (src_shape[i] == dst_shape[i]);
+    }
+    if (!shapes_equal) {
+        throw py::value_error("Input and output arrays have different shapes.");
+    }
+
+    // if nelems is zero, return
+    if (src_nelems == 0) {
+        return std::make_pair(sycl::event(), sycl::event());
+    }
+
+    // ensure that output is ample enough to accomodate all elements
+    auto dst_offsets = dst.get_minmax_offsets();
+    // destination must be ample enough to accomodate all elements
+    {
+        size_t range =
+            static_cast<size_t>(dst_offsets.second - dst_offsets.first);
+        if (range + 1 < src_nelems) {
+            throw py::value_error(
+                "Destination array can not accomodate all the elements "
+                "of source array.");
+        }
+    }
+
+    // check memory overlap
+    auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
+    if (overlap(src, dst)) {
+        throw py::value_error("Arrays index overlapping segments of memory.");
+    }
+
+    const char *src_data = src.get_data();
+    char *dst_data = dst.get_data();
+
+    // handle contiguous inputs
+    bool is_src_c_contig = src.is_c_contiguous();
+    bool is_dst_c_contig = dst.is_c_contiguous();
+
+    bool all_c_contig = (is_src_c_contig && is_dst_c_contig);
+    if (!all_c_contig) {
+        throw py::value_error("Input and outpur arrays must be C-contiguous.");
+    }
+
+    auto dispatch_fn = dispatch_vector[dst_typeid];
+    if (dispatch_fn == nullptr) {
+        throw py::value_error("No implementation is defined for ufunc.");
+    }
+    sycl::event comp_ev =
+        dispatch_fn(exec_q, src_nelems, src_data, dst_data, depends);
+
+    sycl::event ht_ev =
+        dpctl::utils::keep_args_alive(exec_q, {src, dst}, {comp_ev});
+    return std::make_pair(ht_ev, comp_ev);
+}
+
+template <typename dispatchT>
+std::pair<sycl::event, sycl::event> binary_ufunc(
+    sycl::queue exec_q,
+    dpctl::tensor::usm_ndarray src1,
+    dpctl::tensor::usm_ndarray src2,
+    dpctl::tensor::usm_ndarray dst, // dst = op(src1, src2), elementwise
+    const std::vector<sycl::event> &depends,
+    const dispatchT &dispatch_vector)
+{
+    // check type_nums
+    int src1_typenum = src1.get_typenum();
+    int src2_typenum = src2.get_typenum();
+    int dst_typenum = dst.get_typenum();
+
+    auto array_types = dpctl_td_ns::usm_ndarray_types();
+    int src1_typeid = array_types.typenum_to_lookup_id(src1_typenum);
+    int src2_typeid = array_types.typenum_to_lookup_id(src2_typenum);
+    int dst_typeid = array_types.typenum_to_lookup_id(dst_typenum);
+
+    if (src1_typeid != src2_typeid || src2_typeid != dst_typeid) {
+        throw py::value_error(
+            "Either any of input arrays or output array have different types.");
+    }
+
+    // check that queues are compatible
+    if (!dpctl::utils::queues_are_compatible(exec_q, {src1, src2, dst})) {
+        throw py::value_error(
+            "Execution queue is not compatible with allocation queues.");
+    }
+
+    // check shapes, broadcasting is assumed done by caller
+    // check that dimensions are the same
+    int dst_nd = dst.get_ndim();
+    if (dst_nd != src1.get_ndim() || dst_nd != src2.get_ndim()) {
+        throw py::value_error("Array dimensions are not the same.");
+    }
+
+    // check that shapes are the same
+    const py::ssize_t *src1_shape = src1.get_shape_raw();
+    const py::ssize_t *src2_shape = src2.get_shape_raw();
+    const py::ssize_t *dst_shape = dst.get_shape_raw();
+    bool shapes_equal(true);
+    size_t src_nelems(1);
+
+    for (int i = 0; i < dst_nd; ++i) {
+        src_nelems *= static_cast<size_t>(src1_shape[i]);
+        shapes_equal = shapes_equal && (src1_shape[i] == dst_shape[i] &&
+                                        src2_shape[i] == dst_shape[i]);
+    }
+    if (!shapes_equal) {
+        throw py::value_error("Array shapes are not the same.");
+    }
+
+    // if nelems is zero, return
+    if (src_nelems == 0) {
+        return std::make_pair(sycl::event(), sycl::event());
+    }
+
+    // ensure that output is ample enough to accomodate all elements
+    auto dst_offsets = dst.get_minmax_offsets();
+    // destination must be ample enough to accomodate all elements
+    {
+        size_t range =
+            static_cast<size_t>(dst_offsets.second - dst_offsets.first);
+        if (range + 1 < src_nelems) {
+            throw py::value_error(
+                "Destination array can not accomodate all the "
+                "elements of source array.");
+        }
+    }
+
+    // check memory overlap
+    auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
+    if (overlap(src1, dst) || overlap(src2, dst)) {
+        throw py::value_error("Arrays index overlapping segments of memory.");
+    }
+
+    const char *src1_data = src1.get_data();
+    const char *src2_data = src2.get_data();
+    char *dst_data = dst.get_data();
+
+    // handle contiguous inputs
+    bool is_src1_c_contig = src1.is_c_contiguous();
+    bool is_src2_c_contig = src2.is_c_contiguous();
+    bool is_dst_c_contig = dst.is_c_contiguous();
+
+    bool all_c_contig =
+        (is_src1_c_contig && is_src2_c_contig && is_dst_c_contig);
+    if (!all_c_contig) {
+        throw py::value_error("Input and outpur arrays must be C-contiguous.");
+    }
+
+    auto dispatch_fn = dispatch_vector[dst_typeid];
+    if (dispatch_fn == nullptr) {
+        throw py::value_error("No implementation is defined for ufunc.");
+    }
+    sycl::event comp_ev = dispatch_fn(exec_q, src_nelems, src1_data, src2_data,
+                                      dst_data, depends);
+
+    sycl::event ht_ev =
+        dpctl::utils::keep_args_alive(exec_q, {src1, src2, dst}, {comp_ev});
+    return std::make_pair(ht_ev, comp_ev);
+}
+
+template <typename dispatchT>
+bool need_to_call_unary_ufunc(sycl::queue exec_q,
+                              dpctl::tensor::usm_ndarray src,
+                              dpctl::tensor::usm_ndarray dst,
+                              const dispatchT &dispatch_vector)
+{
+#if INTEL_MKL_VERSION >= 20230002
+    // check type_nums
+    int src_typenum = src.get_typenum();
+    int dst_typenum = dst.get_typenum();
+
+    auto array_types = dpctl_td_ns::usm_ndarray_types();
+    int src_typeid = array_types.typenum_to_lookup_id(src_typenum);
+    int dst_typeid = array_types.typenum_to_lookup_id(dst_typenum);
+
+    // types must be the same
+    if (src_typeid != dst_typeid) {
+        return false;
+    }
+
+    // OneMKL VM functions perform a copy on host if no double type support
+    if (!exec_q.get_device().has(sycl::aspect::fp64)) {
+        return false;
+    }
+
+    // check that queues are compatible
+    if (!dpctl::utils::queues_are_compatible(exec_q, {src, dst})) {
+        return false;
+    }
+
+    // dimensions must be the same
+    int dst_nd = dst.get_ndim();
+    if (dst_nd != src.get_ndim()) {
+        return false;
+    }
+    else if (dst_nd == 0) {
+        // don't call OneMKL for 0d arrays
+        return false;
+    }
+
+    // shapes must be the same
+    const py::ssize_t *src_shape = src.get_shape_raw();
+    const py::ssize_t *dst_shape = dst.get_shape_raw();
+    bool shapes_equal(true);
+    size_t src_nelems(1);
+
+    for (int i = 0; i < dst_nd; ++i) {
+        src_nelems *= static_cast<size_t>(src_shape[i]);
+        shapes_equal = shapes_equal && (src_shape[i] == dst_shape[i]);
+    }
+    if (!shapes_equal) {
+        return false;
+    }
+
+    // if nelems is zero, return false
+    if (src_nelems == 0) {
+        return false;
+    }
+
+    // ensure that output is ample enough to accomodate all elements
+    auto dst_offsets = dst.get_minmax_offsets();
+    // destination must be ample enough to accomodate all elements
+    {
+        size_t range =
+            static_cast<size_t>(dst_offsets.second - dst_offsets.first);
+        if (range + 1 < src_nelems) {
+            return false;
+        }
+    }
+
+    // check memory overlap
+    auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
+    if (overlap(src, dst)) {
+        return false;
+    }
+
+    // suppport only contiguous inputs
+    bool is_src_c_contig = src.is_c_contiguous();
+    bool is_dst_c_contig = dst.is_c_contiguous();
+
+    bool all_c_contig = (is_src_c_contig && is_dst_c_contig);
+    if (!all_c_contig) {
+        return false;
+    }
+
+    // MKL function is not defined for the type
+    if (dispatch_vector[dst_typeid] == nullptr) {
+        return false;
+    }
+    return true;
+#else
+    // In OneMKL 2023.1.0 the call of oneapi::mkl::vm::div() is going to dead
+    // lock inside ~usm_wrapper_to_host()->{...; q_->wait_and_throw(); ...}
+
+    (void)exec_q;
+    (void)src;
+    (void)dst;
+    (void)dispatch_vector;
+    return false;
+#endif // INTEL_MKL_VERSION >= 20230002
+}
+
+template <typename dispatchT>
+bool need_to_call_binary_ufunc(sycl::queue exec_q,
+                               dpctl::tensor::usm_ndarray src1,
+                               dpctl::tensor::usm_ndarray src2,
+                               dpctl::tensor::usm_ndarray dst,
+                               const dispatchT &dispatch_vector)
+{
+#if INTEL_MKL_VERSION >= 20230002
+    // check type_nums
+    int src1_typenum = src1.get_typenum();
+    int src2_typenum = src2.get_typenum();
+    int dst_typenum = dst.get_typenum();
+
+    auto array_types = dpctl_td_ns::usm_ndarray_types();
+    int src1_typeid = array_types.typenum_to_lookup_id(src1_typenum);
+    int src2_typeid = array_types.typenum_to_lookup_id(src2_typenum);
+    int dst_typeid = array_types.typenum_to_lookup_id(dst_typenum);
+
+    // types must be the same
+    if (src1_typeid != src2_typeid || src2_typeid != dst_typeid) {
+        return false;
+    }
+
+    // OneMKL VM functions perform a copy on host if no double type support
+    if (!exec_q.get_device().has(sycl::aspect::fp64)) {
+        return false;
+    }
+
+    // check that queues are compatible
+    if (!dpctl::utils::queues_are_compatible(exec_q, {src1, src2, dst})) {
+        return false;
+    }
+
+    // dimensions must be the same
+    int dst_nd = dst.get_ndim();
+    if (dst_nd != src1.get_ndim() || dst_nd != src2.get_ndim()) {
+        return false;
+    }
+    else if (dst_nd == 0) {
+        // don't call OneMKL for 0d arrays
+        return false;
+    }
+
+    // shapes must be the same
+    const py::ssize_t *src1_shape = src1.get_shape_raw();
+    const py::ssize_t *src2_shape = src2.get_shape_raw();
+    const py::ssize_t *dst_shape = dst.get_shape_raw();
+    bool shapes_equal(true);
+    size_t src_nelems(1);
+
+    for (int i = 0; i < dst_nd; ++i) {
+        src_nelems *= static_cast<size_t>(src1_shape[i]);
+        shapes_equal = shapes_equal && (src1_shape[i] == dst_shape[i] &&
+                                        src2_shape[i] == dst_shape[i]);
+    }
+    if (!shapes_equal) {
+        return false;
+    }
+
+    // if nelems is zero, return false
+    if (src_nelems == 0) {
+        return false;
+    }
+
+    // ensure that output is ample enough to accomodate all elements
+    auto dst_offsets = dst.get_minmax_offsets();
+    // destination must be ample enough to accomodate all elements
+    {
+        size_t range =
+            static_cast<size_t>(dst_offsets.second - dst_offsets.first);
+        if (range + 1 < src_nelems) {
+            return false;
+        }
+    }
+
+    // check memory overlap
+    auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
+    if (overlap(src1, dst) || overlap(src2, dst)) {
+        return false;
+    }
+
+    // suppport only contiguous inputs
+    bool is_src1_c_contig = src1.is_c_contiguous();
+    bool is_src2_c_contig = src2.is_c_contiguous();
+    bool is_dst_c_contig = dst.is_c_contiguous();
+
+    bool all_c_contig =
+        (is_src1_c_contig && is_src2_c_contig && is_dst_c_contig);
+    if (!all_c_contig) {
+        return false;
+    }
+
+    // MKL function is not defined for the type
+    if (dispatch_vector[dst_typeid] == nullptr) {
+        return false;
+    }
+    return true;
+#else
+    // In OneMKL 2023.1.0 the call of oneapi::mkl::vm::div() is going to dead
+    // lock inside ~usm_wrapper_to_host()->{...; q_->wait_and_throw(); ...}
+
+    (void)exec_q;
+    (void)src1;
+    (void)src2;
+    (void)dst;
+    (void)dispatch_vector;
+    return false;
+#endif // INTEL_MKL_VERSION >= 20230002
+}
+
+template <typename dispatchT,
+          template <typename fnT, typename T>
+          typename factoryT>
+void init_ufunc_dispatch_vector(dispatchT dispatch_vector[])
+{
+    dpctl_td_ns::DispatchVectorBuilder<dispatchT, factoryT,
+                                       dpctl_td_ns::num_types>
+        contig;
+    contig.populate_dispatch_vector(dispatch_vector);
+}
+} // namespace vm
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/cos.hpp b/dpnp/backend/extensions/vm/cos.hpp
new file mode 100644
index 00000000000..d7212b67e1c
--- /dev/null
+++ b/dpnp/backend/extensions/vm/cos.hpp
@@ -0,0 +1,78 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <CL/sycl.hpp>
+
+#include "common.hpp"
+#include "types_matrix.hpp"
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace vm
+{
+template <typename T>
+sycl::event cos_contig_impl(sycl::queue exec_q,
+                            const std::int64_t n,
+                            const char *in_a,
+                            char *out_y,
+                            const std::vector<sycl::event> &depends)
+{
+    type_utils::validate_type_for_device<T>(exec_q);
+
+    const T *a = reinterpret_cast<const T *>(in_a);
+    T *y = reinterpret_cast<T *>(out_y);
+
+    return mkl_vm::cos(exec_q,
+                       n, // number of elements to be calculated
+                       a, // pointer `a` containing input vector of size n
+                       y, // pointer `y` to the output vector of size n
+                       depends);
+}
+
+template <typename fnT, typename T>
+struct CosContigFactory
+{
+    fnT get()
+    {
+        if constexpr (std::is_same_v<
+                          typename types::CosOutputType<T>::value_type, void>)
+        {
+            return nullptr;
+        }
+        else {
+            return cos_contig_impl<T>;
+        }
+    }
+};
+} // namespace vm
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/div.cpp b/dpnp/backend/extensions/vm/div.cpp
deleted file mode 100644
index e7417749a28..00000000000
--- a/dpnp/backend/extensions/vm/div.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-//*****************************************************************************
-// Copyright (c) 2023, Intel Corporation
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// - Redistributions of source code must retain the above copyright notice,
-//   this list of conditions and the following disclaimer.
-// - Redistributions in binary form must reproduce the above copyright notice,
-//   this list of conditions and the following disclaimer in the documentation
-//   and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-//*****************************************************************************
-
-#include <pybind11/pybind11.h>
-
-// dpctl tensor headers
-#include "utils/memory_overlap.hpp"
-#include "utils/type_utils.hpp"
-
-#include "div.hpp"
-#include "types_matrix.hpp"
-
-#include "dpnp_utils.hpp"
-
-namespace dpnp
-{
-namespace backend
-{
-namespace ext
-{
-namespace vm
-{
-namespace mkl_vm = oneapi::mkl::vm;
-namespace py = pybind11;
-namespace type_utils = dpctl::tensor::type_utils;
-
-typedef sycl::event (*div_impl_fn_ptr_t)(sycl::queue,
-                                         const std::int64_t,
-                                         const char *,
-                                         const char *,
-                                         char *,
-                                         const std::vector<sycl::event> &);
-
-static div_impl_fn_ptr_t div_dispatch_vector[dpctl_td_ns::num_types];
-
-template <typename T>
-static sycl::event div_impl(sycl::queue exec_q,
-                            const std::int64_t n,
-                            const char *in_a,
-                            const char *in_b,
-                            char *out_y,
-                            const std::vector<sycl::event> &depends)
-{
-    type_utils::validate_type_for_device<T>(exec_q);
-
-    const T *a = reinterpret_cast<const T *>(in_a);
-    const T *b = reinterpret_cast<const T *>(in_b);
-    T *y = reinterpret_cast<T *>(out_y);
-
-    return mkl_vm::div(exec_q,
-                       n, // number of elements to be calculated
-                       a, // pointer `a` containing 1st input vector of size n
-                       b, // pointer `b` containing 2nd input vector of size n
-                       y, // pointer `y` to the output vector of size n
-                       depends);
-}
-
-std::pair<sycl::event, sycl::event>
-    div(sycl::queue exec_q,
-        dpctl::tensor::usm_ndarray src1,
-        dpctl::tensor::usm_ndarray src2,
-        dpctl::tensor::usm_ndarray dst, // dst = op(src1, src2), elementwise
-        const std::vector<sycl::event> &depends)
-{
-    // check type_nums
-    int src1_typenum = src1.get_typenum();
-    int src2_typenum = src2.get_typenum();
-    int dst_typenum = dst.get_typenum();
-
-    auto array_types = dpctl_td_ns::usm_ndarray_types();
-    int src1_typeid = array_types.typenum_to_lookup_id(src1_typenum);
-    int src2_typeid = array_types.typenum_to_lookup_id(src2_typenum);
-    int dst_typeid = array_types.typenum_to_lookup_id(dst_typenum);
-
-    if (src1_typeid != src2_typeid || src2_typeid != dst_typeid) {
-        throw py::value_error(
-            "Either any of input arrays or output array have different types");
-    }
-
-    // check that queues are compatible
-    if (!dpctl::utils::queues_are_compatible(exec_q, {src1, src2, dst})) {
-        throw py::value_error(
-            "Execution queue is not compatible with allocation queues");
-    }
-
-    // check shapes, broadcasting is assumed done by caller
-    // check that dimensions are the same
-    int dst_nd = dst.get_ndim();
-    if (dst_nd != src1.get_ndim() || dst_nd != src2.get_ndim()) {
-        throw py::value_error("Array dimensions are not the same.");
-    }
-
-    // check that shapes are the same
-    const py::ssize_t *src1_shape = src1.get_shape_raw();
-    const py::ssize_t *src2_shape = src2.get_shape_raw();
-    const py::ssize_t *dst_shape = dst.get_shape_raw();
-    bool shapes_equal(true);
-    size_t src_nelems(1);
-
-    for (int i = 0; i < dst_nd; ++i) {
-        src_nelems *= static_cast<size_t>(src1_shape[i]);
-        shapes_equal = shapes_equal && (src1_shape[i] == dst_shape[i] &&
-                                        src2_shape[i] == dst_shape[i]);
-    }
-    if (!shapes_equal) {
-        throw py::value_error("Array shapes are not the same.");
-    }
-
-    // if nelems is zero, return
-    if (src_nelems == 0) {
-        return std::make_pair(sycl::event(), sycl::event());
-    }
-
-    // ensure that output is ample enough to accomodate all elements
-    auto dst_offsets = dst.get_minmax_offsets();
-    // destination must be ample enough to accomodate all elements
-    {
-        size_t range =
-            static_cast<size_t>(dst_offsets.second - dst_offsets.first);
-        if (range + 1 < src_nelems) {
-            throw py::value_error(
-                "Destination array can not accomodate all the "
-                "elements of source array.");
-        }
-    }
-
-    // check memory overlap
-    auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
-    if (overlap(src1, dst) || overlap(src2, dst)) {
-        throw py::value_error("Arrays index overlapping segments of memory");
-    }
-
-    const char *src1_data = src1.get_data();
-    const char *src2_data = src2.get_data();
-    char *dst_data = dst.get_data();
-
-    // handle contiguous inputs
-    bool is_src1_c_contig = src1.is_c_contiguous();
-    bool is_src2_c_contig = src2.is_c_contiguous();
-    bool is_dst_c_contig = dst.is_c_contiguous();
-
-    bool all_c_contig =
-        (is_src1_c_contig && is_src2_c_contig && is_dst_c_contig);
-    if (!all_c_contig) {
-        throw py::value_error("Input and outpur arrays must be C-contiguous");
-    }
-
-    auto div_fn = div_dispatch_vector[dst_typeid];
-    if (div_fn == nullptr) {
-        throw py::value_error("No div implementation defined");
-    }
-    sycl::event sum_ev =
-        div_fn(exec_q, src_nelems, src1_data, src2_data, dst_data, depends);
-
-    sycl::event ht_ev =
-        dpctl::utils::keep_args_alive(exec_q, {src1, src2, dst}, {sum_ev});
-    return std::make_pair(ht_ev, sum_ev);
-    return std::make_pair(sycl::event(), sycl::event());
-}
-
-bool can_call_div(sycl::queue exec_q,
-                  dpctl::tensor::usm_ndarray src1,
-                  dpctl::tensor::usm_ndarray src2,
-                  dpctl::tensor::usm_ndarray dst)
-{
-#if INTEL_MKL_VERSION >= 20230002
-    // check type_nums
-    int src1_typenum = src1.get_typenum();
-    int src2_typenum = src2.get_typenum();
-    int dst_typenum = dst.get_typenum();
-
-    auto array_types = dpctl_td_ns::usm_ndarray_types();
-    int src1_typeid = array_types.typenum_to_lookup_id(src1_typenum);
-    int src2_typeid = array_types.typenum_to_lookup_id(src2_typenum);
-    int dst_typeid = array_types.typenum_to_lookup_id(dst_typenum);
-
-    // types must be the same
-    if (src1_typeid != src2_typeid || src2_typeid != dst_typeid) {
-        return false;
-    }
-
-    // OneMKL VM functions perform a copy on host if no double type support
-    if (!exec_q.get_device().has(sycl::aspect::fp64)) {
-        return false;
-    }
-
-    // check that queues are compatible
-    if (!dpctl::utils::queues_are_compatible(exec_q, {src1, src2, dst})) {
-        return false;
-    }
-
-    // dimensions must be the same
-    int dst_nd = dst.get_ndim();
-    if (dst_nd != src1.get_ndim() || dst_nd != src2.get_ndim()) {
-        return false;
-    }
-    else if (dst_nd == 0) {
-        // don't call OneMKL for 0d arrays
-        return false;
-    }
-
-    // shapes must be the same
-    const py::ssize_t *src1_shape = src1.get_shape_raw();
-    const py::ssize_t *src2_shape = src2.get_shape_raw();
-    const py::ssize_t *dst_shape = dst.get_shape_raw();
-    bool shapes_equal(true);
-    size_t src_nelems(1);
-
-    for (int i = 0; i < dst_nd; ++i) {
-        src_nelems *= static_cast<size_t>(src1_shape[i]);
-        shapes_equal = shapes_equal && (src1_shape[i] == dst_shape[i] &&
-                                        src2_shape[i] == dst_shape[i]);
-    }
-    if (!shapes_equal) {
-        return false;
-    }
-
-    // if nelems is zero, return false
-    if (src_nelems == 0) {
-        return false;
-    }
-
-    // ensure that output is ample enough to accomodate all elements
-    auto dst_offsets = dst.get_minmax_offsets();
-    // destination must be ample enough to accomodate all elements
-    {
-        size_t range =
-            static_cast<size_t>(dst_offsets.second - dst_offsets.first);
-        if (range + 1 < src_nelems) {
-            return false;
-        }
-    }
-
-    // check memory overlap
-    auto const &overlap = dpctl::tensor::overlap::MemoryOverlap();
-    if (overlap(src1, dst) || overlap(src2, dst)) {
-        return false;
-    }
-
-    // suppport only contiguous inputs
-    bool is_src1_c_contig = src1.is_c_contiguous();
-    bool is_src2_c_contig = src2.is_c_contiguous();
-    bool is_dst_c_contig = dst.is_c_contiguous();
-
-    bool all_c_contig =
-        (is_src1_c_contig && is_src2_c_contig && is_dst_c_contig);
-    if (!all_c_contig) {
-        return false;
-    }
-
-    // MKL function is not defined for the type
-    if (div_dispatch_vector[src1_typeid] == nullptr) {
-        return false;
-    }
-    return true;
-#else
-    // In OneMKL 2023.1.0 the call of oneapi::mkl::vm::div() is going to dead
-    // lock inside ~usm_wrapper_to_host()->{...; q_->wait_and_throw(); ...}
-
-    (void)exec_q;
-    (void)src1;
-    (void)src2;
-    (void)dst;
-    return false;
-#endif // INTEL_MKL_VERSION >= 20230002
-}
-
-template <typename fnT, typename T>
-struct DivContigFactory
-{
-    fnT get()
-    {
-        if constexpr (types::DivTypePairSupportFactory<T>::is_defined) {
-            return div_impl<T>;
-        }
-        else {
-            return nullptr;
-        }
-    }
-};
-
-void init_div_dispatch_vector(void)
-{
-    dpctl_td_ns::DispatchVectorBuilder<div_impl_fn_ptr_t, DivContigFactory,
-                                       dpctl_td_ns::num_types>
-        contig;
-    contig.populate_dispatch_vector(div_dispatch_vector);
-}
-} // namespace vm
-} // namespace ext
-} // namespace backend
-} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/div.hpp b/dpnp/backend/extensions/vm/div.hpp
index 4d42e4d6a0d..e309daa988d 100644
--- a/dpnp/backend/extensions/vm/div.hpp
+++ b/dpnp/backend/extensions/vm/div.hpp
@@ -26,10 +26,9 @@
 #pragma once
 
 #include <CL/sycl.hpp>
-#include <oneapi/mkl.hpp>
 
-#include <dpctl4pybind11.hpp>
-#include <pybind11/numpy.h>
+#include "common.hpp"
+#include "types_matrix.hpp"
 
 namespace dpnp
 {
@@ -39,19 +38,43 @@ namespace ext
 {
 namespace vm
 {
-extern std::pair<sycl::event, sycl::event>
-    div(sycl::queue exec_q,
-        dpctl::tensor::usm_ndarray src1,
-        dpctl::tensor::usm_ndarray src2,
-        dpctl::tensor::usm_ndarray dst,
-        const std::vector<sycl::event> &depends);
+template <typename T>
+sycl::event div_contig_impl(sycl::queue exec_q,
+                            const std::int64_t n,
+                            const char *in_a,
+                            const char *in_b,
+                            char *out_y,
+                            const std::vector<sycl::event> &depends)
+{
+    type_utils::validate_type_for_device<T>(exec_q);
+
+    const T *a = reinterpret_cast<const T *>(in_a);
+    const T *b = reinterpret_cast<const T *>(in_b);
+    T *y = reinterpret_cast<T *>(out_y);
 
-extern bool can_call_div(sycl::queue exec_q,
-                         dpctl::tensor::usm_ndarray src1,
-                         dpctl::tensor::usm_ndarray src2,
-                         dpctl::tensor::usm_ndarray dst);
+    return mkl_vm::div(exec_q,
+                       n, // number of elements to be calculated
+                       a, // pointer `a` containing 1st input vector of size n
+                       b, // pointer `b` containing 2nd input vector of size n
+                       y, // pointer `y` to the output vector of size n
+                       depends);
+}
 
-extern void init_div_dispatch_vector(void);
+template <typename fnT, typename T>
+struct DivContigFactory
+{
+    fnT get()
+    {
+        if constexpr (std::is_same_v<
+                          typename types::DivOutputType<T>::value_type, void>)
+        {
+            return nullptr;
+        }
+        else {
+            return div_contig_impl<T>;
+        }
+    }
+};
 } // namespace vm
 } // namespace ext
 } // namespace backend
diff --git a/dpnp/backend/extensions/vm/ln.hpp b/dpnp/backend/extensions/vm/ln.hpp
new file mode 100644
index 00000000000..edf58d98724
--- /dev/null
+++ b/dpnp/backend/extensions/vm/ln.hpp
@@ -0,0 +1,77 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <CL/sycl.hpp>
+
+#include "common.hpp"
+#include "types_matrix.hpp"
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace vm
+{
+template <typename T>
+sycl::event ln_contig_impl(sycl::queue exec_q,
+                           const std::int64_t n,
+                           const char *in_a,
+                           char *out_y,
+                           const std::vector<sycl::event> &depends)
+{
+    type_utils::validate_type_for_device<T>(exec_q);
+
+    const T *a = reinterpret_cast<const T *>(in_a);
+    T *y = reinterpret_cast<T *>(out_y);
+
+    return mkl_vm::ln(exec_q,
+                      n, // number of elements to be calculated
+                      a, // pointer `a` containing input vector of size n
+                      y, // pointer `y` to the output vector of size n
+                      depends);
+}
+
+template <typename fnT, typename T>
+struct LnContigFactory
+{
+    fnT get()
+    {
+        if constexpr (std::is_same_v<
+                          typename types::LnOutputType<T>::value_type, void>) {
+            return nullptr;
+        }
+        else {
+            return ln_contig_impl<T>;
+        }
+    }
+};
+} // namespace vm
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/sin.hpp b/dpnp/backend/extensions/vm/sin.hpp
new file mode 100644
index 00000000000..90fa3ad114e
--- /dev/null
+++ b/dpnp/backend/extensions/vm/sin.hpp
@@ -0,0 +1,78 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <CL/sycl.hpp>
+
+#include "common.hpp"
+#include "types_matrix.hpp"
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace vm
+{
+template <typename T>
+sycl::event sin_contig_impl(sycl::queue exec_q,
+                            const std::int64_t n,
+                            const char *in_a,
+                            char *out_y,
+                            const std::vector<sycl::event> &depends)
+{
+    type_utils::validate_type_for_device<T>(exec_q);
+
+    const T *a = reinterpret_cast<const T *>(in_a);
+    T *y = reinterpret_cast<T *>(out_y);
+
+    return mkl_vm::sin(exec_q,
+                       n, // number of elements to be calculated
+                       a, // pointer `a` containing input vector of size n
+                       y, // pointer `y` to the output vector of size n
+                       depends);
+}
+
+template <typename fnT, typename T>
+struct SinContigFactory
+{
+    fnT get()
+    {
+        if constexpr (std::is_same_v<
+                          typename types::SinOutputType<T>::value_type, void>)
+        {
+            return nullptr;
+        }
+        else {
+            return sin_contig_impl<T>;
+        }
+    }
+};
+} // namespace vm
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/sqr.hpp b/dpnp/backend/extensions/vm/sqr.hpp
new file mode 100644
index 00000000000..ceb9a3896f1
--- /dev/null
+++ b/dpnp/backend/extensions/vm/sqr.hpp
@@ -0,0 +1,78 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <CL/sycl.hpp>
+
+#include "common.hpp"
+#include "types_matrix.hpp"
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace vm
+{
+template <typename T>
+sycl::event sqr_contig_impl(sycl::queue exec_q,
+                            const std::int64_t n,
+                            const char *in_a,
+                            char *out_y,
+                            const std::vector<sycl::event> &depends)
+{
+    type_utils::validate_type_for_device<T>(exec_q);
+
+    const T *a = reinterpret_cast<const T *>(in_a);
+    T *y = reinterpret_cast<T *>(out_y);
+
+    return mkl_vm::sqr(exec_q,
+                       n, // number of elements to be calculated
+                       a, // pointer `a` containing input vector of size n
+                       y, // pointer `y` to the output vector of size n
+                       depends);
+}
+
+template <typename fnT, typename T>
+struct SqrContigFactory
+{
+    fnT get()
+    {
+        if constexpr (std::is_same_v<
+                          typename types::SqrOutputType<T>::value_type, void>)
+        {
+            return nullptr;
+        }
+        else {
+            return sqr_contig_impl<T>;
+        }
+    }
+};
+} // namespace vm
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/sqrt.hpp b/dpnp/backend/extensions/vm/sqrt.hpp
new file mode 100644
index 00000000000..df20ee4b050
--- /dev/null
+++ b/dpnp/backend/extensions/vm/sqrt.hpp
@@ -0,0 +1,78 @@
+//*****************************************************************************
+// Copyright (c) 2023, Intel Corporation
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// - Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// - Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//*****************************************************************************
+
+#pragma once
+
+#include <CL/sycl.hpp>
+
+#include "common.hpp"
+#include "types_matrix.hpp"
+
+namespace dpnp
+{
+namespace backend
+{
+namespace ext
+{
+namespace vm
+{
+template <typename T>
+sycl::event sqrt_contig_impl(sycl::queue exec_q,
+                             const std::int64_t n,
+                             const char *in_a,
+                             char *out_y,
+                             const std::vector<sycl::event> &depends)
+{
+    type_utils::validate_type_for_device<T>(exec_q);
+
+    const T *a = reinterpret_cast<const T *>(in_a);
+    T *y = reinterpret_cast<T *>(out_y);
+
+    return mkl_vm::sqrt(exec_q,
+                        n, // number of elements to be calculated
+                        a, // pointer `a` containing input vector of size n
+                        y, // pointer `y` to the output vector of size n
+                        depends);
+}
+
+template <typename fnT, typename T>
+struct SqrtContigFactory
+{
+    fnT get()
+    {
+        if constexpr (std::is_same_v<
+                          typename types::SqrtOutputType<T>::value_type, void>)
+        {
+            return nullptr;
+        }
+        else {
+            return sqrt_contig_impl<T>;
+        }
+    }
+};
+} // namespace vm
+} // namespace ext
+} // namespace backend
+} // namespace dpnp
diff --git a/dpnp/backend/extensions/vm/types_matrix.hpp b/dpnp/backend/extensions/vm/types_matrix.hpp
index 4990170f7f0..667e27f0c9a 100644
--- a/dpnp/backend/extensions/vm/types_matrix.hpp
+++ b/dpnp/backend/extensions/vm/types_matrix.hpp
@@ -30,7 +30,7 @@
 // dpctl tensor headers
 #include "utils/type_dispatch.hpp"
 
-// dpctl namespace for operations with types
+// dpctl namespace for types dispatching
 namespace dpctl_td_ns = dpctl::tensor::type_dispatch;
 
 namespace dpnp
@@ -50,21 +50,113 @@ namespace types
  * @tparam T Type of input vectors `a` and `b` and of result vector `y`.
  */
 template <typename T>
-struct DivTypePairSupportFactory
+struct DivOutputType
 {
-    static constexpr bool is_defined = std::disjunction<
-        dpctl_td_ns::TypePairDefinedEntry<T,
-                                          std::complex<double>,
-                                          T,
-                                          std::complex<double>>,
-        dpctl_td_ns::TypePairDefinedEntry<T,
-                                          std::complex<float>,
-                                          T,
-                                          std::complex<float>>,
-        dpctl_td_ns::TypePairDefinedEntry<T, double, T, double>,
-        dpctl_td_ns::TypePairDefinedEntry<T, float, T, float>,
-        // fall-through
-        dpctl_td_ns::NotDefinedEntry>::is_defined;
+    using value_type = typename std::disjunction<
+        dpctl_td_ns::BinaryTypeMapResultEntry<T,
+                                              std::complex<double>,
+                                              T,
+                                              std::complex<double>,
+                                              std::complex<double>>,
+        dpctl_td_ns::BinaryTypeMapResultEntry<T,
+                                              std::complex<float>,
+                                              T,
+                                              std::complex<float>,
+                                              std::complex<float>>,
+        dpctl_td_ns::BinaryTypeMapResultEntry<T, double, T, double, double>,
+        dpctl_td_ns::BinaryTypeMapResultEntry<T, float, T, float, float>,
+        dpctl_td_ns::DefaultResultEntry<void>>::result_type;
+};
+
+/**
+ * @brief A factory to define pairs of supported types for which
+ * MKL VM library provides support in oneapi::mkl::vm::cos<T> function.
+ *
+ * @tparam T Type of input vector `a` and of result vector `y`.
+ */
+template <typename T>
+struct CosOutputType
+{
+    using value_type = typename std::disjunction<
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<double>, std::complex<double>>,
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<float>, std::complex<float>>,
+        dpctl_td_ns::TypeMapResultEntry<T, double, double>,
+        dpctl_td_ns::TypeMapResultEntry<T, float, float>,
+        dpctl_td_ns::DefaultResultEntry<void>>::result_type;
+};
+
+/**
+ * @brief A factory to define pairs of supported types for which
+ * MKL VM library provides support in oneapi::mkl::vm::ln<T> function.
+ *
+ * @tparam T Type of input vector `a` and of result vector `y`.
+ */
+template <typename T>
+struct LnOutputType
+{
+    using value_type = typename std::disjunction<
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<double>, std::complex<double>>,
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<float>, std::complex<float>>,
+        dpctl_td_ns::TypeMapResultEntry<T, double, double>,
+        dpctl_td_ns::TypeMapResultEntry<T, float, float>,
+        dpctl_td_ns::DefaultResultEntry<void>>::result_type;
+};
+
+/**
+ * @brief A factory to define pairs of supported types for which
+ * MKL VM library provides support in oneapi::mkl::vm::sin<T> function.
+ *
+ * @tparam T Type of input vector `a` and of result vector `y`.
+ */
+template <typename T>
+struct SinOutputType
+{
+    using value_type = typename std::disjunction<
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<double>, std::complex<double>>,
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<float>, std::complex<float>>,
+        dpctl_td_ns::TypeMapResultEntry<T, double, double>,
+        dpctl_td_ns::TypeMapResultEntry<T, float, float>,
+        dpctl_td_ns::DefaultResultEntry<void>>::result_type;
+};
+
+/**
+ * @brief A factory to define pairs of supported types for which
+ * MKL VM library provides support in oneapi::mkl::vm::sqr<T> function.
+ *
+ * @tparam T Type of input vector `a` and of result vector `y`.
+ */
+template <typename T>
+struct SqrOutputType
+{
+    using value_type = typename std::disjunction<
+        dpctl_td_ns::TypeMapResultEntry<T, double, double>,
+        dpctl_td_ns::TypeMapResultEntry<T, float, float>,
+        dpctl_td_ns::DefaultResultEntry<void>>::result_type;
+};
+
+/**
+ * @brief A factory to define pairs of supported types for which
+ * MKL VM library provides support in oneapi::mkl::vm::sqrt<T> function.
+ *
+ * @tparam T Type of input vector `a` and of result vector `y`.
+ */
+template <typename T>
+struct SqrtOutputType
+{
+    using value_type = typename std::disjunction<
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<double>, std::complex<double>>,
+        dpctl_td_ns::
+            TypeMapResultEntry<T, std::complex<float>, std::complex<float>>,
+        dpctl_td_ns::TypeMapResultEntry<T, double, double>,
+        dpctl_td_ns::TypeMapResultEntry<T, float, float>,
+        dpctl_td_ns::DefaultResultEntry<void>>::result_type;
 };
 } // namespace types
 } // namespace vm
diff --git a/dpnp/backend/extensions/vm/vm_py.cpp b/dpnp/backend/extensions/vm/vm_py.cpp
index 8d81ed33f7e..924db66025b 100644
--- a/dpnp/backend/extensions/vm/vm_py.cpp
+++ b/dpnp/backend/extensions/vm/vm_py.cpp
@@ -30,35 +30,204 @@
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>
 
+#include "common.hpp"
+#include "cos.hpp"
 #include "div.hpp"
+#include "ln.hpp"
+#include "sin.hpp"
+#include "sqr.hpp"
+#include "sqrt.hpp"
+#include "types_matrix.hpp"
 
-namespace vm_ext = dpnp::backend::ext::vm;
 namespace py = pybind11;
+namespace vm_ext = dpnp::backend::ext::vm;
 
-// populate dispatch vectors
-void init_dispatch_vectors(void)
-{
-    vm_ext::init_div_dispatch_vector();
-}
+using vm_ext::binary_impl_fn_ptr_t;
+using vm_ext::unary_impl_fn_ptr_t;
+
+static binary_impl_fn_ptr_t div_dispatch_vector[dpctl_td_ns::num_types];
 
-// populate dispatch tables
-void init_dispatch_tables(void) {}
+static unary_impl_fn_ptr_t cos_dispatch_vector[dpctl_td_ns::num_types];
+static unary_impl_fn_ptr_t ln_dispatch_vector[dpctl_td_ns::num_types];
+static unary_impl_fn_ptr_t sin_dispatch_vector[dpctl_td_ns::num_types];
+static unary_impl_fn_ptr_t sqr_dispatch_vector[dpctl_td_ns::num_types];
+static unary_impl_fn_ptr_t sqrt_dispatch_vector[dpctl_td_ns::num_types];
 
 PYBIND11_MODULE(_vm_impl, m)
 {
-    init_dispatch_vectors();
-    init_dispatch_tables();
-
-    m.def("_div", &vm_ext::div,
-          "Call `div` from OneMKL VM library to performs element by element "
-          "division "
-          "of vector `src1` by vector `src2` to resulting vector `dst`",
-          py::arg("sycl_queue"), py::arg("src1"), py::arg("src2"),
-          py::arg("dst"), py::arg("depends") = py::list());
-
-    m.def("_can_call_div", &vm_ext::can_call_div,
-          "Check input arrays to answer if `div` function from OneMKL VM "
-          "library can be used",
-          py::arg("sycl_queue"), py::arg("src1"), py::arg("src2"),
-          py::arg("dst"));
+    using arrayT = dpctl::tensor::usm_ndarray;
+    using event_vecT = std::vector<sycl::event>;
+
+    // BinaryUfunc: ==== Div(x1, x2) ====
+    {
+        vm_ext::init_ufunc_dispatch_vector<binary_impl_fn_ptr_t,
+                                           vm_ext::DivContigFactory>(
+            div_dispatch_vector);
+
+        auto div_pyapi = [&](sycl::queue exec_q, arrayT src1, arrayT src2,
+                             arrayT dst, const event_vecT &depends = {}) {
+            return vm_ext::binary_ufunc(exec_q, src1, src2, dst, depends,
+                                        div_dispatch_vector);
+        };
+        m.def("_div", div_pyapi,
+              "Call `div` function from OneMKL VM library to performs element "
+              "by element division of vector `src1` by vector `src2` "
+              "to resulting vector `dst`",
+              py::arg("sycl_queue"), py::arg("src1"), py::arg("src2"),
+              py::arg("dst"), py::arg("depends") = py::list());
+
+        auto div_need_to_call_pyapi = [&](sycl::queue exec_q, arrayT src1,
+                                          arrayT src2, arrayT dst) {
+            return vm_ext::need_to_call_binary_ufunc(exec_q, src1, src2, dst,
+                                                     div_dispatch_vector);
+        };
+        m.def("_mkl_div_to_call", div_need_to_call_pyapi,
+              "Check input arguments to answer if `div` function from "
+              "OneMKL VM library can be used",
+              py::arg("sycl_queue"), py::arg("src1"), py::arg("src2"),
+              py::arg("dst"));
+    }
+
+    // UnaryUfunc: ==== Cos(x) ====
+    {
+        vm_ext::init_ufunc_dispatch_vector<unary_impl_fn_ptr_t,
+                                           vm_ext::CosContigFactory>(
+            cos_dispatch_vector);
+
+        auto cos_pyapi = [&](sycl::queue exec_q, arrayT src, arrayT dst,
+                             const event_vecT &depends = {}) {
+            return vm_ext::unary_ufunc(exec_q, src, dst, depends,
+                                       cos_dispatch_vector);
+        };
+        m.def("_cos", cos_pyapi,
+              "Call `cos` function from OneMKL VM library to compute "
+              "cosine of vector elements",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"),
+              py::arg("depends") = py::list());
+
+        auto cos_need_to_call_pyapi = [&](sycl::queue exec_q, arrayT src,
+                                          arrayT dst) {
+            return vm_ext::need_to_call_unary_ufunc(exec_q, src, dst,
+                                                    cos_dispatch_vector);
+        };
+        m.def("_mkl_cos_to_call", cos_need_to_call_pyapi,
+              "Check input arguments to answer if `cos` function from "
+              "OneMKL VM library can be used",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"));
+    }
+
+    // UnaryUfunc: ==== Ln(x) ====
+    {
+        vm_ext::init_ufunc_dispatch_vector<unary_impl_fn_ptr_t,
+                                           vm_ext::LnContigFactory>(
+            ln_dispatch_vector);
+
+        auto ln_pyapi = [&](sycl::queue exec_q, arrayT src, arrayT dst,
+                            const event_vecT &depends = {}) {
+            return vm_ext::unary_ufunc(exec_q, src, dst, depends,
+                                       ln_dispatch_vector);
+        };
+        m.def("_ln", ln_pyapi,
+              "Call `ln` function from OneMKL VM library to compute "
+              "natural logarithm of vector elements",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"),
+              py::arg("depends") = py::list());
+
+        auto ln_need_to_call_pyapi = [&](sycl::queue exec_q, arrayT src,
+                                         arrayT dst) {
+            return vm_ext::need_to_call_unary_ufunc(exec_q, src, dst,
+                                                    ln_dispatch_vector);
+        };
+        m.def("_mkl_ln_to_call", ln_need_to_call_pyapi,
+              "Check input arguments to answer if `ln` function from "
+              "OneMKL VM library can be used",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"));
+    }
+
+    // UnaryUfunc: ==== Sin(x) ====
+    {
+        vm_ext::init_ufunc_dispatch_vector<unary_impl_fn_ptr_t,
+                                           vm_ext::SinContigFactory>(
+            sin_dispatch_vector);
+
+        auto sin_pyapi = [&](sycl::queue exec_q, arrayT src, arrayT dst,
+                             const event_vecT &depends = {}) {
+            return vm_ext::unary_ufunc(exec_q, src, dst, depends,
+                                       sin_dispatch_vector);
+        };
+        m.def("_sin", sin_pyapi,
+              "Call `sin` function from OneMKL VM library to compute "
+              "sine of vector elements",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"),
+              py::arg("depends") = py::list());
+
+        auto sin_need_to_call_pyapi = [&](sycl::queue exec_q, arrayT src,
+                                          arrayT dst) {
+            return vm_ext::need_to_call_unary_ufunc(exec_q, src, dst,
+                                                    sin_dispatch_vector);
+        };
+        m.def("_mkl_sin_to_call", sin_need_to_call_pyapi,
+              "Check input arguments to answer if `sin` function from "
+              "OneMKL VM library can be used",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"));
+    }
+
+    // UnaryUfunc: ==== Sqr(x) ====
+    {
+        vm_ext::init_ufunc_dispatch_vector<unary_impl_fn_ptr_t,
+                                           vm_ext::SqrContigFactory>(
+            sqr_dispatch_vector);
+
+        auto sqr_pyapi = [&](sycl::queue exec_q, arrayT src, arrayT dst,
+                             const event_vecT &depends = {}) {
+            return vm_ext::unary_ufunc(exec_q, src, dst, depends,
+                                       sqr_dispatch_vector);
+        };
+        m.def(
+            "_sqr", sqr_pyapi,
+            "Call `sqr` from OneMKL VM library to performs element by element "
+            "operation of squaring of vector `src` to resulting vector `dst`",
+            py::arg("sycl_queue"), py::arg("src"), py::arg("dst"),
+            py::arg("depends") = py::list());
+
+        auto sqr_need_to_call_pyapi = [&](sycl::queue exec_q, arrayT src,
+                                          arrayT dst) {
+            return vm_ext::need_to_call_unary_ufunc(exec_q, src, dst,
+                                                    sqr_dispatch_vector);
+        };
+        m.def("_mkl_sqr_to_call", sqr_need_to_call_pyapi,
+              "Check input arguments to answer if `sqr` function from "
+              "OneMKL VM library can be used",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"));
+    }
+
+    // UnaryUfunc: ==== Sqrt(x) ====
+    {
+        vm_ext::init_ufunc_dispatch_vector<unary_impl_fn_ptr_t,
+                                           vm_ext::SqrtContigFactory>(
+            sqrt_dispatch_vector);
+
+        auto sqrt_pyapi = [&](sycl::queue exec_q, arrayT src, arrayT dst,
+                              const event_vecT &depends = {}) {
+            return vm_ext::unary_ufunc(exec_q, src, dst, depends,
+                                       sqrt_dispatch_vector);
+        };
+        m.def(
+            "_sqrt", sqrt_pyapi,
+            "Call `sqrt` from OneMKL VM library to performs element by element "
+            "operation of extracting the square root "
+            "of vector `src` to resulting vector `dst`",
+            py::arg("sycl_queue"), py::arg("src"), py::arg("dst"),
+            py::arg("depends") = py::list());
+
+        auto sqrt_need_to_call_pyapi = [&](sycl::queue exec_q, arrayT src,
+                                           arrayT dst) {
+            return vm_ext::need_to_call_unary_ufunc(exec_q, src, dst,
+                                                    sqrt_dispatch_vector);
+        };
+        m.def("_mkl_sqrt_to_call", sqrt_need_to_call_pyapi,
+              "Check input arguments to answer if `sqrt` function from "
+              "OneMKL VM library can be used",
+              py::arg("sycl_queue"), py::arg("src"), py::arg("dst"));
+    }
 }
diff --git a/dpnp/backend/include/dpnp_gen_1arg_1type_tbl.hpp b/dpnp/backend/include/dpnp_gen_1arg_1type_tbl.hpp
index 591f6c36ea4..795d3e9c534 100644
--- a/dpnp/backend/include/dpnp_gen_1arg_1type_tbl.hpp
+++ b/dpnp/backend/include/dpnp_gen_1arg_1type_tbl.hpp
@@ -104,60 +104,6 @@ MACRO_1ARG_1TYPE_OP(dpnp_square_c,
 
 #undef MACRO_1ARG_1TYPE_OP
 
-#elif defined(MACRO_1ARG_1TYPE_LOGIC_OP)
-
-/*
- * This header file contains single argument element wise functions definitions
- *
- * Macro `MACRO_1ARG_1TYPE_LOGIC_OP` must be defined before usage
- *
- * Parameters:
- * - public name of the function and kernel name
- * - operation used to calculate the result
- *
- */
-
-#ifdef _SECTION_DOCUMENTATION_GENERATION_
-
-#define MACRO_1ARG_1TYPE_LOGIC_OP(__name__, __operation__)                     \
-    /** @ingroup BACKEND_API */                                                \
-    /** @brief Per element operation function __name__ */                      \
-    /** */                                                                     \
-    /** Function "__name__" executes operator "__operation__" over             \
-     * corresponding elements of input array             */                    \
-    /** */                                                                     \
-    /** @param[in]  q_ref              Reference to SYCL queue. */             \
-    /** @param[out] result_out         Output array. */                        \
-    /** @param[in]  result_size        Output array size. */                   \
-    /** @param[in]  result_ndim        Number of output array                  \
-     * dimensions. */                                                          \
-    /** @param[in]  result_shape       Output array shape. */                  \
-    /** @param[in]  result_strides     Output array strides. */                \
-    /** @param[in]  input1_in          Input array 1. */                       \
-    /** @param[in]  input1_size        Input array 1 size. */                  \
-    /** @param[in]  input1_ndim        Number of input array 1                 \
-     * dimensions. */                                                          \
-    /** @param[in]  input1_shape       Input array 1 shape. */                 \
-    /** @param[in]  input1_strides     Input array 1 strides. */               \
-    /** @param[in]  where              Where condition. */                     \
-    /** @param[in]  dep_event_vec_ref  Reference to vector of SYCL             \
-     * events. */                                                              \
-    template <typename _DataType_input1>                                       \
-    DPCTLSyclEventRef __name__(                                                \
-        DPCTLSyclQueueRef q_ref, void *result_out, const size_t result_size,   \
-        const size_t result_ndim, const shape_elem_type *result_shape,         \
-        const shape_elem_type *result_strides, const void *input1_in,          \
-        const size_t input1_size, const size_t input1_ndim,                    \
-        const shape_elem_type *input1_shape,                                   \
-        const shape_elem_type *input1_strides, const size_t *where,            \
-        const DPCTLEventVectorRef dep_event_vec_ref);
-
-#endif // _SECTION_DOCUMENTATION_GENERATION_
-
-MACRO_1ARG_1TYPE_LOGIC_OP(dpnp_logical_not_c, !input1_elem)
-
-#undef MACRO_1ARG_1TYPE_LOGIC_OP
-
 #else
-#error "MACRO_1ARG_1TYPE_OP or MACRO_1ARG_1TYPE_LOGIC_OP is not defined"
-#endif // MACRO_1ARG_1TYPE_OP || MACRO_1ARG_1TYPE_LOGIC_OP
+#error "MACRO_1ARG_1TYPE_OP is not defined"
+#endif // MACRO_1ARG_1TYPE_OP
diff --git a/dpnp/backend/include/dpnp_gen_2arg_2type_tbl.hpp b/dpnp/backend/include/dpnp_gen_2arg_2type_tbl.hpp
index 22d3ff6b277..bb54c4b152e 100644
--- a/dpnp/backend/include/dpnp_gen_2arg_2type_tbl.hpp
+++ b/dpnp/backend/include/dpnp_gen_2arg_2type_tbl.hpp
@@ -89,10 +89,6 @@ MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_greater_c, input1_elem > input2_elem)
 MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_greater_equal_c, input1_elem >= input2_elem)
 MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_less_c, input1_elem < input2_elem)
 MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_less_equal_c, input1_elem <= input2_elem)
-MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_logical_and_c, input1_elem &&input2_elem)
-MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_logical_or_c, input1_elem || input2_elem)
-MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_logical_xor_c,
-                           (!!input1_elem) != (!!input2_elem))
 MACRO_2ARG_2TYPES_LOGIC_OP(dpnp_not_equal_c, input1_elem != input2_elem)
 
 #undef MACRO_2ARG_2TYPES_LOGIC_OP
diff --git a/dpnp/backend/include/dpnp_iface_fptr.hpp b/dpnp/backend/include/dpnp_iface_fptr.hpp
index c0f4404ff57..70771130661 100644
--- a/dpnp/backend/include/dpnp_iface_fptr.hpp
+++ b/dpnp/backend/include/dpnp_iface_fptr.hpp
@@ -145,8 +145,7 @@ enum class DPNPFuncName : size_t
     DPNP_FN_CORRELATE_EXT, /**< Used in numpy.correlate() impl, requires extra
                               parameters */
     DPNP_FN_COS,           /**< Used in numpy.cos() impl  */
-    DPNP_FN_COS_EXT, /**< Used in numpy.cos() impl, requires extra parameters */
-    DPNP_FN_COSH,    /**< Used in numpy.cosh() impl  */
+    DPNP_FN_COSH,          /**< Used in numpy.cosh() impl  */
     DPNP_FN_COSH_EXT, /**< Used in numpy.cosh() impl, requires extra parameters
                        */
     DPNP_FN_COUNT_NONZERO,     /**< Used in numpy.count_nonzero() impl  */
@@ -262,25 +261,16 @@ enum class DPNPFuncName : size_t
     DPNP_FN_LESS_EQUAL_EXT, /**< Used in numpy.less_equal() impl, requires extra
                                parameters */
     DPNP_FN_LOG,            /**< Used in numpy.log() impl  */
-    DPNP_FN_LOG_EXT, /**< Used in numpy.log() impl, requires extra parameters */
-    DPNP_FN_LOG10,   /**< Used in numpy.log10() impl  */
-    DPNP_FN_LOG10_EXT, /**< Used in numpy.log10() impl, requires extra
-                          parameters  */
-    DPNP_FN_LOG2,      /**< Used in numpy.log2() impl  */
+    DPNP_FN_LOG10,          /**< Used in numpy.log10() impl  */
+    DPNP_FN_LOG10_EXT,      /**< Used in numpy.log10() impl, requires extra
+                               parameters  */
+    DPNP_FN_LOG2,           /**< Used in numpy.log2() impl  */
     DPNP_FN_LOG2_EXT,  /**< Used in numpy.log2() impl, requires extra parameters
                         */
     DPNP_FN_LOG1P,     /**< Used in numpy.log1p() impl  */
     DPNP_FN_LOG1P_EXT, /**< Used in numpy.log1p() impl, requires extra
                           parameters  */
-    DPNP_FN_LOGICAL_AND_EXT, /**< Used in numpy.logical_and() impl, requires
-                                extra parameters */
-    DPNP_FN_LOGICAL_NOT_EXT, /**< Used in numpy.logical_not() impl, requires
-                                extra parameters */
-    DPNP_FN_LOGICAL_OR_EXT, /**< Used in numpy.logical_or() impl, requires extra
-                               parameters */
-    DPNP_FN_LOGICAL_XOR_EXT, /**< Used in numpy.logical_xor() impl, requires
-                                extra parameters */
-    DPNP_FN_MATMUL,          /**< Used in numpy.matmul() impl  */
+    DPNP_FN_MATMUL,    /**< Used in numpy.matmul() impl  */
     DPNP_FN_MATMUL_EXT,      /**< Used in numpy.matmul() impl, requires extra
                                 parameters */
     DPNP_FN_MATRIX_RANK,     /**< Used in numpy.linalg.matrix_rank() impl  */
@@ -476,8 +466,7 @@ enum class DPNPFuncName : size_t
     DPNP_FN_SIGN_EXT, /**< Used in numpy.sign() impl, requires extra parameters
                        */
     DPNP_FN_SIN,      /**< Used in numpy.sin() impl  */
-    DPNP_FN_SIN_EXT, /**< Used in numpy.sin() impl, requires extra parameters */
-    DPNP_FN_SINH,    /**< Used in numpy.sinh() impl  */
+    DPNP_FN_SINH,     /**< Used in numpy.sinh() impl  */
     DPNP_FN_SINH_EXT, /**< Used in numpy.sinh() impl, requires extra parameters
                        */
     DPNP_FN_SORT,     /**< Used in numpy.sort() impl  */
@@ -487,9 +476,7 @@ enum class DPNPFuncName : size_t
     DPNP_FN_SQRT_EXT, /**< Used in numpy.sqrt() impl, requires extra parameters
                        */
     DPNP_FN_SQUARE,   /**< Used in numpy.square() impl  */
-    DPNP_FN_SQUARE_EXT, /**< Used in numpy.square() impl, requires extra
-                           parameters */
-    DPNP_FN_STD,        /**< Used in numpy.std() impl  */
+    DPNP_FN_STD,      /**< Used in numpy.std() impl  */
     DPNP_FN_STD_EXT, /**< Used in numpy.std() impl, requires extra parameters */
     DPNP_FN_SUBTRACT,     /**< Used in numpy.subtract() impl  */
     DPNP_FN_SUBTRACT_EXT, /**< Used in numpy.subtract() impl, requires extra
diff --git a/dpnp/backend/kernels/dpnp_krnl_common.cpp b/dpnp/backend/kernels/dpnp_krnl_common.cpp
index 15defa1f842..84107d293ac 100644
--- a/dpnp/backend/kernels/dpnp_krnl_common.cpp
+++ b/dpnp/backend/kernels/dpnp_krnl_common.cpp
@@ -34,6 +34,7 @@
 #include <dpnp_iface.hpp>
 
 namespace mkl_blas = oneapi::mkl::blas;
+namespace mkl_blas_cm = oneapi::mkl::blas::column_major;
 namespace mkl_blas_rm = oneapi::mkl::blas::row_major;
 namespace mkl_lapack = oneapi::mkl::lapack;
 
@@ -227,12 +228,10 @@ DPCTLSyclEventRef dpnp_dot_c(DPCTLSyclQueueRef q_ref,
     DPCTLSyclEventRef event_ref = nullptr;
     sycl::queue q = *(reinterpret_cast<sycl::queue *>(q_ref));
 
-    DPNPC_ptr_adapter<_DataType_input1> input1_ptr(q_ref, input1_in,
-                                                   input1_size);
-    DPNPC_ptr_adapter<_DataType_input2> input2_ptr(q_ref, input2_in,
-                                                   input2_size);
-    _DataType_input1 *input1 = input1_ptr.get_ptr();
-    _DataType_input2 *input2 = input2_ptr.get_ptr();
+    _DataType_input1 *input1 =
+        static_cast<_DataType_input1 *>(const_cast<void *>(input1_in));
+    _DataType_input2 *input2 =
+        static_cast<_DataType_input2 *>(const_cast<void *>(input2_in));
     _DataType_output *result = reinterpret_cast<_DataType_output *>(result_out);
 
     if (!input1_size || !input2_size) {
@@ -257,10 +256,12 @@ DPCTLSyclEventRef dpnp_dot_c(DPCTLSyclQueueRef q_ref,
     // if both arrays are vectors
     if ((input1_ndim == 1) && (input2_ndim == 1)) {
         assert(input1_size == input2_size);
+
         sycl::event event = dot(q, result, input1, input2, input1_strides[0],
                                 input2_strides[0], input1_size);
-        event.wait();
-        return event_ref;
+
+        event_ref = reinterpret_cast<DPCTLSyclEventRef>(&event);
+        return DPCTLEvent_Copy(event_ref);
     }
 
     // 1D vector
@@ -297,13 +298,17 @@ DPCTLSyclEventRef dpnp_dot_c(DPCTLSyclQueueRef q_ref,
     size_t ext_result_ndim =
         ((input1_ndim == 1) || (input2_ndim == 1)) ? 2 : result_ndim;
     shape_elem_type *ext_result_shape = new shape_elem_type[ext_result_ndim];
+    shape_elem_type *ext_result_strides = new shape_elem_type[ext_result_ndim];
     if ((input1_ndim == 1) || (input2_ndim == 1)) {
         ext_result_shape[0] = ext_input1_shape[0];
         ext_result_shape[1] = ext_input2_shape[1];
+        ext_result_strides[0] = 0;
+        ext_result_strides[1] = result_strides[0];
     }
     else {
         for (size_t i = 0; i < ext_result_ndim; ++i) {
             ext_result_shape[i] = result_shape[i];
+            ext_result_strides[i] = result_strides[i];
         }
     }
 
@@ -316,80 +321,89 @@ DPCTLSyclEventRef dpnp_dot_c(DPCTLSyclQueueRef q_ref,
         // check if GEMM can be executed (strides)
         // TODO: rewrite the condition in general case for ndims > 2
         // (looks like there are such another cases)
-
         if (ext_input1_ndim == 2 && ext_input2_ndim == 2) {
-// there is a difference of behavior with trans and sizes params in previous
-// version of GEMM only new version is supported, in case of old version
-// computation goes in common way
-#if INTEL_MKL_VERSION >= 20210004
-            // is mat1 F-contiguous, C-contiguous
-            bool mat1_f_contig =
-                (((ext_input1_shape[0] == 1) || (ext_input1_strides[0] == 1)) &&
-                 ((ext_input1_shape[1] == 1) ||
-                  (ext_input1_strides[1] == ext_input1_shape[0])));
-            bool mat1_c_contig =
-                (((ext_input1_shape[1] == 1) || (ext_input1_strides[1] == 1)) &&
-                 ((ext_input1_shape[0] == 1) ||
-                  (ext_input1_strides[0] == ext_input1_shape[1])));
-            // is mat2 F-contiguous, C-contiguous
-            bool mat2_f_contig =
-                (((ext_input2_shape[0] == 1) || (ext_input2_strides[0] == 1)) &&
-                 ((ext_input2_shape[1] == 1) ||
-                  (ext_input2_strides[1] == ext_input2_shape[0])));
-            bool mat2_c_contig =
-                (((ext_input2_shape[1] == 1) || (ext_input2_strides[1] == 1)) &&
-                 ((ext_input2_shape[0] == 1) ||
-                  (ext_input2_strides[0] == ext_input2_shape[1])));
-
-            if ((mat1_f_contig || mat1_c_contig) &&
-                (mat2_f_contig || mat2_c_contig)) {
-                oneapi::mkl::transpose trans1 =
-                    (mat1_f_contig && !mat1_c_contig)
-                        ? oneapi::mkl::transpose::trans
-                        : oneapi::mkl::transpose::nontrans;
-                oneapi::mkl::transpose trans2 =
-                    (mat2_f_contig && !mat2_c_contig)
-                        ? oneapi::mkl::transpose::trans
-                        : oneapi::mkl::transpose::nontrans;
+            // OneMKL gemm suports only arrays contiguous on inner dimension,
+            // so stride for at least one dimension should be equal to 1
+            if ((ext_input1_strides[0] == 1 || ext_input1_strides[1] == 1) &&
+                (ext_input2_strides[0] == 1 || ext_input2_strides[1] == 1) &&
+                (ext_result_strides[0] == 1 || ext_result_strides[1] == 1))
+            {
+                const bool isRowmA =
+                    (ext_input1_strides[1] == 1 || ext_input1_strides[0] == 0);
+                const bool isRowmB =
+                    (ext_input2_strides[1] == 1 || ext_input2_strides[1] == 0);
+                const bool isRowmC =
+                    (ext_result_strides[1] == 1 || ext_result_strides[0] == 0);
+
+                oneapi::mkl::transpose transA =
+                    (isRowmA != isRowmC) ? oneapi::mkl::transpose::trans
+                                         : oneapi::mkl::transpose::nontrans;
+                oneapi::mkl::transpose transB =
+                    (isRowmB != isRowmC) ? oneapi::mkl::transpose::trans
+                                         : oneapi::mkl::transpose::nontrans;
 
                 const size_t size_m = ext_input1_shape[0];
                 const size_t size_n = ext_input2_shape[1];
                 const size_t size_k = ext_input1_shape[1];
 
-                const std::int64_t lda =
-                    trans1 == oneapi::mkl::transpose::nontrans
-                        ? ext_input1_strides[0]
-                        : ext_input1_strides[1];
-                const std::int64_t ldb =
-                    trans2 == oneapi::mkl::transpose::nontrans
-                        ? ext_input2_strides[0]
-                        : ext_input2_strides[1];
-
-                // definition of ldc will be another for result with
-                // non-standard (c-contiguous) strides const std::int64_t ldc =
-                // result_strides[0] == 1 ? result_strides[1] :
-                // result_strides[0];
-                const std::int64_t ldc = size_n;
+                auto getLdaLdc = [](const bool isRown, shape_elem_type *strides,
+                                    shape_elem_type *shapes) {
+                    if (isRown) {
+                        return (strides[0] != 0) ? strides[0] : shapes[1];
+                    }
+                    return strides[1];
+                };
+
+                const std::int64_t lda = static_cast<std::int64_t>(
+                    getLdaLdc(isRowmA, ext_input1_strides, ext_input1_shape));
+                const std::int64_t ldb = static_cast<std::int64_t>(
+                    isRowmB ? ext_input2_strides[0] : ext_input2_strides[1]);
+                const std::int64_t ldc = static_cast<std::int64_t>(
+                    getLdaLdc(isRowmC, ext_result_strides, ext_result_shape));
+
+                constexpr _DataType_output alpha = 1;
+                constexpr _DataType_output beta = 0;
+
+                std::stringstream error_msg;
+                std::int64_t info = 0;
 
                 try {
-                    sycl::event event = mkl_blas_rm::gemm(
-                        q, trans1, trans2, size_m, size_n, size_k,
-                        _DataType_output(1), // alpha
-                        input1, lda, input2, ldb,
-                        _DataType_output(0), // beta
-                        result, ldc);
-                    event.wait();
-                    delete[] ext_input1_shape;
-                    delete[] ext_input1_strides;
-                    delete[] ext_input2_shape;
-                    delete[] ext_input2_strides;
-                    delete[] ext_result_shape;
-
-                    return event_ref;
+                    if (isRowmC) {
+                        mkl_blas_rm::gemm(q, transA, transB, size_m, size_n,
+                                          size_k, alpha, input1, lda, input2,
+                                          ldb, beta, result, ldc)
+                            .wait();
+                    }
+                    else {
+                        mkl_blas_cm::gemm(q, transA, transB, size_m, size_n,
+                                          size_k, alpha, input1, lda, input2,
+                                          ldb, beta, result, ldc)
+                            .wait();
+                    }
+                } catch (mkl_lapack::exception const &e) {
+                    error_msg << "Unexpected MKL exception caught during "
+                                 "gemm() call:\nreason: "
+                              << e.what() << "\ninfo: " << e.info();
+                    info = e.info();
                 } catch (const std::exception &e) {
-                    // do nothing, proceed to general case
+                    error_msg << "Unexpected SYCL exception caught during "
+                                 "gemm() call:\n"
+                              << e.what();
+                    info = -1;
                 }
-#endif
+
+                if (info != 0) // an unexected error occurs
+                {
+                    throw std::runtime_error(error_msg.str());
+                }
+
+                delete[] ext_input1_shape;
+                delete[] ext_input1_strides;
+                delete[] ext_input2_shape;
+                delete[] ext_input2_strides;
+                delete[] ext_result_shape;
+                delete[] ext_result_strides;
+                return event_ref;
             }
         }
     }
@@ -437,6 +451,7 @@ DPCTLSyclEventRef dpnp_dot_c(DPCTLSyclQueueRef q_ref,
     delete[] ext_input2_shape;
     delete[] ext_input2_strides;
     delete[] ext_result_shape;
+    delete[] ext_result_strides;
 
     return event_ref;
 }
@@ -1152,9 +1167,21 @@ void func_map_init_linalg(func_map_t &fmap)
         eft_DBL, (void *)dpnp_eig_default_c<double, double>};
 
     fmap[DPNPFuncName::DPNP_FN_EIG_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_eig_ext_c<int32_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_eig_ext_c<
+            int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_eig_ext_c<
+            int32_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_EIG_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_eig_ext_c<int64_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_eig_ext_c<
+            int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_eig_ext_c<
+            int64_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_EIG_EXT][eft_FLT][eft_FLT] = {
         eft_FLT, (void *)dpnp_eig_ext_c<float, float>};
     fmap[DPNPFuncName::DPNP_FN_EIG_EXT][eft_DBL][eft_DBL] = {
@@ -1170,9 +1197,21 @@ void func_map_init_linalg(func_map_t &fmap)
         eft_DBL, (void *)dpnp_eigvals_default_c<double, double>};
 
     fmap[DPNPFuncName::DPNP_FN_EIGVALS_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_eigvals_ext_c<int32_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_eigvals_ext_c<
+            int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_eigvals_ext_c<
+            int32_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_EIGVALS_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_eigvals_ext_c<int64_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_eigvals_ext_c<
+            int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_eigvals_ext_c<
+            int64_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_EIGVALS_EXT][eft_FLT][eft_FLT] = {
         eft_FLT, (void *)dpnp_eigvals_ext_c<float, float>};
     fmap[DPNPFuncName::DPNP_FN_EIGVALS_EXT][eft_DBL][eft_DBL] = {
diff --git a/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp b/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp
index b8105ddc828..404657965ff 100644
--- a/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp
+++ b/dpnp/backend/kernels/dpnp_krnl_elemwise.cpp
@@ -486,15 +486,6 @@ static void func_map_init_elemwise_1arg_2type(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_COS][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_cos_c_default<double, double>};
 
-    fmap[DPNPFuncName::DPNP_FN_COS_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_cos_c_ext<int32_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_COS_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_cos_c_ext<int64_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_COS_EXT][eft_FLT][eft_FLT] = {
-        eft_FLT, (void *)dpnp_cos_c_ext<float, float>};
-    fmap[DPNPFuncName::DPNP_FN_COS_EXT][eft_DBL][eft_DBL] = {
-        eft_DBL, (void *)dpnp_cos_c_ext<double, double>};
-
     fmap[DPNPFuncName::DPNP_FN_COSH][eft_INT][eft_INT] = {
         eft_DBL, (void *)dpnp_cosh_c_default<int32_t, double>};
     fmap[DPNPFuncName::DPNP_FN_COSH][eft_LNG][eft_LNG] = {
@@ -684,15 +675,6 @@ static void func_map_init_elemwise_1arg_2type(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_LOG][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_log_c_default<double, double>};
 
-    fmap[DPNPFuncName::DPNP_FN_LOG_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_log_c_ext<int32_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_LOG_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_log_c_ext<int64_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_LOG_EXT][eft_FLT][eft_FLT] = {
-        eft_FLT, (void *)dpnp_log_c_ext<float, float>};
-    fmap[DPNPFuncName::DPNP_FN_LOG_EXT][eft_DBL][eft_DBL] = {
-        eft_DBL, (void *)dpnp_log_c_ext<double, double>};
-
     fmap[DPNPFuncName::DPNP_FN_RADIANS][eft_INT][eft_INT] = {
         eft_DBL, (void *)dpnp_radians_c_default<int32_t, double>};
     fmap[DPNPFuncName::DPNP_FN_RADIANS][eft_LNG][eft_LNG] = {
@@ -720,15 +702,6 @@ static void func_map_init_elemwise_1arg_2type(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_SIN][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_sin_c_default<double, double>};
 
-    fmap[DPNPFuncName::DPNP_FN_SIN_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_sin_c_ext<int32_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_SIN_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_sin_c_ext<int64_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_SIN_EXT][eft_FLT][eft_FLT] = {
-        eft_FLT, (void *)dpnp_sin_c_ext<float, float>};
-    fmap[DPNPFuncName::DPNP_FN_SIN_EXT][eft_DBL][eft_DBL] = {
-        eft_DBL, (void *)dpnp_sin_c_ext<double, double>};
-
     fmap[DPNPFuncName::DPNP_FN_SINH][eft_INT][eft_INT] = {
         eft_DBL, (void *)dpnp_sinh_c_default<int32_t, double>};
     fmap[DPNPFuncName::DPNP_FN_SINH][eft_LNG][eft_LNG] = {
@@ -756,10 +729,7 @@ static void func_map_init_elemwise_1arg_2type(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_SQRT][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_sqrt_c_default<double, double>};
 
-    fmap[DPNPFuncName::DPNP_FN_SQRT_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_sqrt_c_ext<int32_t, double>};
-    fmap[DPNPFuncName::DPNP_FN_SQRT_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_sqrt_c_ext<int64_t, double>};
+    // Used in dpnp_std_c
     fmap[DPNPFuncName::DPNP_FN_SQRT_EXT][eft_FLT][eft_FLT] = {
         eft_FLT, (void *)dpnp_sqrt_c_ext<float, float>};
     fmap[DPNPFuncName::DPNP_FN_SQRT_EXT][eft_DBL][eft_DBL] = {
@@ -1186,15 +1156,6 @@ static void func_map_init_elemwise_1arg_1type(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_SQUARE][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_square_c_default<double>};
 
-    fmap[DPNPFuncName::DPNP_FN_SQUARE_EXT][eft_INT][eft_INT] = {
-        eft_INT, (void *)dpnp_square_c_ext<int32_t>};
-    fmap[DPNPFuncName::DPNP_FN_SQUARE_EXT][eft_LNG][eft_LNG] = {
-        eft_LNG, (void *)dpnp_square_c_ext<int64_t>};
-    fmap[DPNPFuncName::DPNP_FN_SQUARE_EXT][eft_FLT][eft_FLT] = {
-        eft_FLT, (void *)dpnp_square_c_ext<float>};
-    fmap[DPNPFuncName::DPNP_FN_SQUARE_EXT][eft_DBL][eft_DBL] = {
-        eft_DBL, (void *)dpnp_square_c_ext<double>};
-
     return;
 }
 
diff --git a/dpnp/backend/kernels/dpnp_krnl_linalg.cpp b/dpnp/backend/kernels/dpnp_krnl_linalg.cpp
index f106a7bddc6..b83295aa894 100644
--- a/dpnp/backend/kernels/dpnp_krnl_linalg.cpp
+++ b/dpnp/backend/kernels/dpnp_krnl_linalg.cpp
@@ -874,16 +874,28 @@ void func_map_init_linalg_func(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_INV][eft_LNG][eft_LNG] = {
         eft_DBL, (void *)dpnp_inv_default_c<int64_t, double>};
     fmap[DPNPFuncName::DPNP_FN_INV][eft_FLT][eft_FLT] = {
-        eft_DBL, (void *)dpnp_inv_default_c<float, double>};
+        eft_DBL, (void *)dpnp_inv_default_c<float, float>};
     fmap[DPNPFuncName::DPNP_FN_INV][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_inv_default_c<double, double>};
 
     fmap[DPNPFuncName::DPNP_FN_INV_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_inv_ext_c<int32_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_inv_ext_c<
+            int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_inv_ext_c<
+            int32_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_INV_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_inv_ext_c<int64_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_inv_ext_c<
+            int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_inv_ext_c<
+            int64_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_INV_EXT][eft_FLT][eft_FLT] = {
-        eft_DBL, (void *)dpnp_inv_ext_c<float, double>};
+        eft_FLT, (void *)dpnp_inv_ext_c<float, float>};
     fmap[DPNPFuncName::DPNP_FN_INV_EXT][eft_DBL][eft_DBL] = {
         eft_DBL, (void *)dpnp_inv_ext_c<double, double>};
 
@@ -1039,9 +1051,21 @@ void func_map_init_linalg_func(func_map_t &fmap)
     // eft_C128, (void*)dpnp_qr_c<std::complex<double>, std::complex<double>>};
 
     fmap[DPNPFuncName::DPNP_FN_QR_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_qr_ext_c<int32_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_qr_ext_c<
+            int32_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_qr_ext_c<
+            int32_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_QR_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_qr_ext_c<int64_t, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_qr_ext_c<
+            int64_t, func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)dpnp_qr_ext_c<
+            int64_t, func_type_map_t::find_type<
+                         get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_QR_EXT][eft_FLT][eft_FLT] = {
         eft_FLT, (void *)dpnp_qr_ext_c<float, float>};
     fmap[DPNPFuncName::DPNP_FN_QR_EXT][eft_DBL][eft_DBL] = {
@@ -1062,9 +1086,29 @@ void func_map_init_linalg_func(func_map_t &fmap)
                                              std::complex<double>, double>};
 
     fmap[DPNPFuncName::DPNP_FN_SVD_EXT][eft_INT][eft_INT] = {
-        eft_DBL, (void *)dpnp_svd_ext_c<int32_t, double, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_svd_ext_c<
+            int32_t, func_type_map_t::find_type<get_default_floating_type<>()>,
+            func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)
+            dpnp_svd_ext_c<int32_t,
+                           func_type_map_t::find_type<
+                               get_default_floating_type<std::false_type>()>,
+                           func_type_map_t::find_type<
+                               get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_SVD_EXT][eft_LNG][eft_LNG] = {
-        eft_DBL, (void *)dpnp_svd_ext_c<int64_t, double, double>};
+        get_default_floating_type<>(),
+        (void *)dpnp_svd_ext_c<
+            int64_t, func_type_map_t::find_type<get_default_floating_type<>()>,
+            func_type_map_t::find_type<get_default_floating_type<>()>>,
+        get_default_floating_type<std::false_type>(),
+        (void *)
+            dpnp_svd_ext_c<int64_t,
+                           func_type_map_t::find_type<
+                               get_default_floating_type<std::false_type>()>,
+                           func_type_map_t::find_type<
+                               get_default_floating_type<std::false_type>()>>};
     fmap[DPNPFuncName::DPNP_FN_SVD_EXT][eft_FLT][eft_FLT] = {
         eft_FLT, (void *)dpnp_svd_ext_c<float, float, float>};
     fmap[DPNPFuncName::DPNP_FN_SVD_EXT][eft_DBL][eft_DBL] = {
diff --git a/dpnp/backend/kernels/dpnp_krnl_logic.cpp b/dpnp/backend/kernels/dpnp_krnl_logic.cpp
index befcb25cf6d..e2fe0d460cf 100644
--- a/dpnp/backend/kernels/dpnp_krnl_logic.cpp
+++ b/dpnp/backend/kernels/dpnp_krnl_logic.cpp
@@ -322,195 +322,6 @@ DPCTLSyclEventRef (*dpnp_any_ext_c)(DPCTLSyclQueueRef,
                                     const DPCTLEventVectorRef) =
     dpnp_any_c<_DataType, _ResultType>;
 
-#define MACRO_1ARG_1TYPE_LOGIC_OP(__name__, __operation__)                     \
-    template <typename _KernelNameSpecialization>                              \
-    class __name__##_kernel;                                                   \
-                                                                               \
-    template <typename _KernelNameSpecialization>                              \
-    class __name__##_broadcast_kernel;                                         \
-                                                                               \
-    template <typename _KernelNameSpecialization>                              \
-    class __name__##_strides_kernel;                                           \
-                                                                               \
-    template <typename _DataType_input1>                                       \
-    DPCTLSyclEventRef __name__(                                                \
-        DPCTLSyclQueueRef q_ref, void *result_out, const size_t result_size,   \
-        const size_t result_ndim, const shape_elem_type *result_shape,         \
-        const shape_elem_type *result_strides, const void *input1_in,          \
-        const size_t input1_size, const size_t input1_ndim,                    \
-        const shape_elem_type *input1_shape,                                   \
-        const shape_elem_type *input1_strides, const size_t *where,            \
-        const DPCTLEventVectorRef dep_event_vec_ref)                           \
-    {                                                                          \
-        /* avoid warning unused variable*/                                     \
-        (result_shape);                                                        \
-        (void)where;                                                           \
-        (void)dep_event_vec_ref;                                               \
-                                                                               \
-        DPCTLSyclEventRef event_ref = nullptr;                                 \
-                                                                               \
-        if (!input1_size) {                                                    \
-            return event_ref;                                                  \
-        }                                                                      \
-                                                                               \
-        sycl::queue q = *(reinterpret_cast<sycl::queue *>(q_ref));             \
-                                                                               \
-        _DataType_input1 *input1_data =                                        \
-            static_cast<_DataType_input1 *>(const_cast<void *>(input1_in));    \
-        bool *result = static_cast<bool *>(result_out);                        \
-                                                                               \
-        shape_elem_type *input1_shape_offsets =                                \
-            new shape_elem_type[input1_ndim];                                  \
-                                                                               \
-        get_shape_offsets_inkernel(input1_shape, input1_ndim,                  \
-                                   input1_shape_offsets);                      \
-        bool use_strides = !array_equal(input1_strides, input1_ndim,           \
-                                        input1_shape_offsets, input1_ndim);    \
-        delete[] input1_shape_offsets;                                         \
-                                                                               \
-        if (use_strides) {                                                     \
-            if (result_ndim != input1_ndim) {                                  \
-                throw std::runtime_error(                                      \
-                    "Result ndim=" + std::to_string(result_ndim) +             \
-                    " mismatches with input1 ndim=" +                          \
-                    std::to_string(input1_ndim));                              \
-            }                                                                  \
-                                                                               \
-            /* memory transfer optimization, use USM-host for temporary speeds \
-             * up tranfer to device */                                         \
-            using usm_host_allocatorT =                                        \
-                sycl::usm_allocator<shape_elem_type, sycl::usm::alloc::host>;  \
-                                                                               \
-            size_t strides_size = 2 * result_ndim;                             \
-            shape_elem_type *dev_strides_data =                                \
-                sycl::malloc_device<shape_elem_type>(strides_size, q);         \
-                                                                               \
-            /* create host temporary for packed strides managed by shared      \
-             * pointer */                                                      \
-            auto strides_host_packed =                                         \
-                std::vector<shape_elem_type, usm_host_allocatorT>(             \
-                    strides_size, usm_host_allocatorT(q));                     \
-                                                                               \
-            /* packed vector is concatenation of result_strides and            \
-             * input1_strides */                                               \
-            std::copy(result_strides, result_strides + result_ndim,            \
-                      strides_host_packed.begin());                            \
-            std::copy(input1_strides, input1_strides + result_ndim,            \
-                      strides_host_packed.begin() + result_ndim);              \
-                                                                               \
-            auto copy_strides_ev = q.copy<shape_elem_type>(                    \
-                strides_host_packed.data(), dev_strides_data,                  \
-                strides_host_packed.size());                                   \
-                                                                               \
-            auto kernel_parallel_for_func = [=](sycl::id<1> global_id) {       \
-                const size_t output_id =                                       \
-                    global_id[0]; /* for (size_t i = 0; i < result_size; ++i)  \
-                                   */                                          \
-                {                                                              \
-                    const shape_elem_type *result_strides_data =               \
-                        &dev_strides_data[0];                                  \
-                    const shape_elem_type *input1_strides_data =               \
-                        &dev_strides_data[result_ndim];                        \
-                                                                               \
-                    size_t input1_id = 0;                                      \
-                                                                               \
-                    for (size_t i = 0; i < result_ndim; ++i) {                 \
-                        const size_t output_xyz_id =                           \
-                            get_xyz_id_by_id_inkernel(output_id,               \
-                                                      result_strides_data,     \
-                                                      result_ndim, i);         \
-                        input1_id += output_xyz_id * input1_strides_data[i];   \
-                    }                                                          \
-                                                                               \
-                    const _DataType_input1 input1_elem =                       \
-                        input1_data[input1_id];                                \
-                    result[output_id] = __operation__;                         \
-                }                                                              \
-            };                                                                 \
-            auto kernel_func = [&](sycl::handler &cgh) {                       \
-                cgh.depends_on(copy_strides_ev);                               \
-                cgh.parallel_for<                                              \
-                    class __name__##_strides_kernel<_DataType_input1>>(        \
-                    sycl::range<1>(result_size), kernel_parallel_for_func);    \
-            };                                                                 \
-                                                                               \
-            q.submit(kernel_func).wait();                                      \
-                                                                               \
-            sycl::free(dev_strides_data, q);                                   \
-            return event_ref;                                                  \
-        }                                                                      \
-        else {                                                                 \
-            constexpr size_t lws = 64;                                         \
-            constexpr unsigned int vec_sz = 8;                                 \
-            constexpr sycl::access::address_space global_space =               \
-                sycl::access::address_space::global_space;                     \
-                                                                               \
-            auto gws_range = sycl::range<1>(                                   \
-                ((result_size + lws * vec_sz - 1) / (lws * vec_sz)) * lws);    \
-            auto lws_range = sycl::range<1>(lws);                              \
-                                                                               \
-            auto kernel_parallel_for_func = [=](sycl::nd_item<1> nd_it) {      \
-                auto sg = nd_it.get_sub_group();                               \
-                const auto max_sg_size = sg.get_max_local_range()[0];          \
-                const size_t start =                                           \
-                    vec_sz * (nd_it.get_group(0) * nd_it.get_local_range(0) +  \
-                              sg.get_group_id()[0] * max_sg_size);             \
-                                                                               \
-                if (start + static_cast<size_t>(vec_sz) * max_sg_size <        \
-                    result_size) {                                             \
-                    sycl::vec<_DataType_input1, vec_sz> x1 = sg.load<vec_sz>(  \
-                        sycl::multi_ptr<_DataType_input1, global_space>(       \
-                            &input1_data[start]));                             \
-                    sycl::vec<bool, vec_sz> res_vec;                           \
-                                                                               \
-                    for (size_t k = 0; k < vec_sz; ++k) {                      \
-                        const _DataType_input1 input1_elem = x1[k];            \
-                        res_vec[k] = __operation__;                            \
-                    }                                                          \
-                    sg.store<vec_sz>(                                          \
-                        sycl::multi_ptr<bool, global_space>(&result[start]),   \
-                        res_vec);                                              \
-                }                                                              \
-                else {                                                         \
-                    for (size_t k = start; k < result_size; ++k) {             \
-                        const _DataType_input1 input1_elem = input1_data[k];   \
-                        result[k] = __operation__;                             \
-                    }                                                          \
-                }                                                              \
-            };                                                                 \
-                                                                               \
-            auto kernel_func = [&](sycl::handler &cgh) {                       \
-                cgh.parallel_for<class __name__##_kernel<_DataType_input1>>(   \
-                    sycl::nd_range<1>(gws_range, lws_range),                   \
-                    kernel_parallel_for_func);                                 \
-            };                                                                 \
-            sycl::event event = q.submit(kernel_func);                         \
-                                                                               \
-            event_ref = reinterpret_cast<DPCTLSyclEventRef>(&event);           \
-            return DPCTLEvent_Copy(event_ref);                                 \
-        }                                                                      \
-        return event_ref;                                                      \
-    }                                                                          \
-                                                                               \
-    template <typename _DataType_input1>                                       \
-    DPCTLSyclEventRef (*__name__##_ext)(                                       \
-        DPCTLSyclQueueRef, void *, const size_t, const size_t,                 \
-        const shape_elem_type *, const shape_elem_type *, const void *,        \
-        const size_t, const size_t, const shape_elem_type *,                   \
-        const shape_elem_type *, const size_t *, const DPCTLEventVectorRef) =  \
-        __name__<_DataType_input1>;
-
-#include <dpnp_gen_1arg_1type_tbl.hpp>
-
-template <DPNPFuncType... FTs>
-static void func_map_logic_1arg_1type_helper(func_map_t &fmap)
-{
-    ((fmap[DPNPFuncName::DPNP_FN_LOGICAL_NOT_EXT][FTs][FTs] =
-          {eft_BLN,
-           (void *)dpnp_logical_not_c_ext<func_type_map_t::find_type<FTs>>}),
-     ...);
-}
-
 #define MACRO_2ARG_2TYPES_LOGIC_OP(__name__, __operation__)                    \
     template <typename _KernelNameSpecialization1,                             \
               typename _KernelNameSpecialization2>                             \
@@ -803,21 +614,6 @@ static void func_map_logic_2arg_2type_core(func_map_t &fmap)
            (void *)dpnp_less_equal_c_ext<func_type_map_t::find_type<FT1>,
                                          func_type_map_t::find_type<FTs>>}),
      ...);
-    ((fmap[DPNPFuncName::DPNP_FN_LOGICAL_AND_EXT][FT1][FTs] =
-          {eft_BLN,
-           (void *)dpnp_logical_and_c_ext<func_type_map_t::find_type<FT1>,
-                                          func_type_map_t::find_type<FTs>>}),
-     ...);
-    ((fmap[DPNPFuncName::DPNP_FN_LOGICAL_OR_EXT][FT1][FTs] =
-          {eft_BLN,
-           (void *)dpnp_logical_or_c_ext<func_type_map_t::find_type<FT1>,
-                                         func_type_map_t::find_type<FTs>>}),
-     ...);
-    ((fmap[DPNPFuncName::DPNP_FN_LOGICAL_XOR_EXT][FT1][FTs] =
-          {eft_BLN,
-           (void *)dpnp_logical_xor_c_ext<func_type_map_t::find_type<FT1>,
-                                          func_type_map_t::find_type<FTs>>}),
-     ...);
     ((fmap[DPNPFuncName::DPNP_FN_NOT_EQUAL_EXT][FT1][FTs] =
           {eft_BLN,
            (void *)dpnp_not_equal_c_ext<func_type_map_t::find_type<FT1>,
@@ -951,8 +747,6 @@ void func_map_init_logic(func_map_t &fmap)
     fmap[DPNPFuncName::DPNP_FN_ANY_EXT][eft_C128][eft_C128] = {
         eft_C128, (void *)dpnp_any_ext_c<std::complex<double>, bool>};
 
-    func_map_logic_1arg_1type_helper<eft_BLN, eft_INT, eft_LNG, eft_FLT,
-                                     eft_DBL>(fmap);
     func_map_logic_2arg_2type_helper<eft_BLN, eft_INT, eft_LNG, eft_FLT,
                                      eft_DBL>(fmap);
 
diff --git a/dpnp/backend/src/dpnp_fptr.hpp b/dpnp/backend/src/dpnp_fptr.hpp
index 2502aba646b..446083204fc 100644
--- a/dpnp/backend/src/dpnp_fptr.hpp
+++ b/dpnp/backend/src/dpnp_fptr.hpp
@@ -260,6 +260,17 @@ class dpnp_less_comp
     }
 };
 
+/**
+ * A template function that determines the default floating-point type
+ * based on the value of the template parameter has_fp64.
+ */
+template <typename has_fp64 = std::true_type>
+static constexpr DPNPFuncType get_default_floating_type()
+{
+    return has_fp64::value ? DPNPFuncType::DPNP_FT_DOUBLE
+                           : DPNPFuncType::DPNP_FT_FLOAT;
+}
+
 /**
  * FPTR interface initialization functions
  */
diff --git a/dpnp/dpnp_algo/dpnp_algo.pxd b/dpnp/dpnp_algo/dpnp_algo.pxd
index 3142f33e0d7..b56557f75c8 100644
--- a/dpnp/dpnp_algo/dpnp_algo.pxd
+++ b/dpnp/dpnp_algo/dpnp_algo.pxd
@@ -90,8 +90,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName":  # need this na
         DPNP_FN_COPYTO_EXT
         DPNP_FN_CORRELATE
         DPNP_FN_CORRELATE_EXT
-        DPNP_FN_COS
-        DPNP_FN_COS_EXT
         DPNP_FN_COSH
         DPNP_FN_COSH_EXT
         DPNP_FN_COUNT_NONZERO
@@ -120,7 +118,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName":  # need this na
         DPNP_FN_EIG_EXT
         DPNP_FN_EIGVALS
         DPNP_FN_EIGVALS_EXT
-        DPNP_FN_EQUAL_EXT
         DPNP_FN_ERF
         DPNP_FN_ERF_EXT
         DPNP_FN_EYE
@@ -143,14 +140,10 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName":  # need this na
         DPNP_FN_FLATTEN_EXT
         DPNP_FN_FLOOR
         DPNP_FN_FLOOR_EXT
-        DPNP_FN_FLOOR_DIVIDE
-        DPNP_FN_FLOOR_DIVIDE_EXT
         DPNP_FN_FMOD
         DPNP_FN_FMOD_EXT
         DPNP_FN_FULL
         DPNP_FN_FULL_LIKE
-        DPNP_FN_GREATER_EXT
-        DPNP_FN_GREATER_EQUAL_EXT
         DPNP_FN_HYPOT
         DPNP_FN_HYPOT_EXT
         DPNP_FN_IDENTITY
@@ -165,20 +158,12 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName":  # need this na
         DPNP_FN_KRON_EXT
         DPNP_FN_LEFT_SHIFT
         DPNP_FN_LEFT_SHIFT_EXT
-        DPNP_FN_LESS_EXT
-        DPNP_FN_LESS_EQUAL_EXT
-        DPNP_FN_LOG
-        DPNP_FN_LOG_EXT
         DPNP_FN_LOG10
         DPNP_FN_LOG10_EXT
         DPNP_FN_LOG1P
         DPNP_FN_LOG1P_EXT
         DPNP_FN_LOG2
         DPNP_FN_LOG2_EXT
-        DPNP_FN_LOGICAL_AND_EXT
-        DPNP_FN_LOGICAL_NOT_EXT
-        DPNP_FN_LOGICAL_OR_EXT
-        DPNP_FN_LOGICAL_XOR_EXT
         DPNP_FN_MATMUL
         DPNP_FN_MATMUL_EXT
         DPNP_FN_MATRIX_RANK
@@ -200,7 +185,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName":  # need this na
         DPNP_FN_NEGATIVE
         DPNP_FN_NEGATIVE_EXT
         DPNP_FN_NONZERO
-        DPNP_FN_NOT_EQUAL_EXT
         DPNP_FN_ONES
         DPNP_FN_ONES_LIKE
         DPNP_FN_PARTITION
@@ -301,16 +285,10 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName":  # need this na
         DPNP_FN_SEARCHSORTED_EXT
         DPNP_FN_SIGN
         DPNP_FN_SIGN_EXT
-        DPNP_FN_SIN
-        DPNP_FN_SIN_EXT
         DPNP_FN_SINH
         DPNP_FN_SINH_EXT
         DPNP_FN_SORT
         DPNP_FN_SORT_EXT
-        DPNP_FN_SQRT
-        DPNP_FN_SQRT_EXT
-        DPNP_FN_SQUARE
-        DPNP_FN_SQUARE_EXT
         DPNP_FN_STD
         DPNP_FN_STD_EXT
         DPNP_FN_SUM
@@ -358,6 +336,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 +
 
@@ -481,18 +461,8 @@ cpdef dpnp_descriptor dpnp_right_shift(dpnp_descriptor x1_obj,
 """
 Logic functions
 """
-cpdef dpnp_descriptor dpnp_equal(dpnp_descriptor array1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_greater(dpnp_descriptor input1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_greater_equal(dpnp_descriptor input1, dpnp_descriptor input2)
 cpdef dpnp_descriptor dpnp_isclose(dpnp_descriptor input1, dpnp_descriptor input2,
                                    double rtol=*, double atol=*, cpp_bool equal_nan=*)
-cpdef dpnp_descriptor dpnp_less(dpnp_descriptor input1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_less_equal(dpnp_descriptor input1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_logical_and(dpnp_descriptor input1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_logical_not(dpnp_descriptor input1)
-cpdef dpnp_descriptor dpnp_logical_or(dpnp_descriptor input1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_logical_xor(dpnp_descriptor input1, dpnp_descriptor input2)
-cpdef dpnp_descriptor dpnp_not_equal(dpnp_descriptor input1, dpnp_descriptor input2)
 
 
 """
@@ -560,21 +530,16 @@ cpdef dpnp_descriptor dpnp_arcsinh(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_arctan(dpnp_descriptor array1, dpnp_descriptor out)
 cpdef dpnp_descriptor dpnp_arctanh(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_cbrt(dpnp_descriptor array1)
-cpdef dpnp_descriptor dpnp_cos(dpnp_descriptor array1, dpnp_descriptor out)
 cpdef dpnp_descriptor dpnp_cosh(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_degrees(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_exp(dpnp_descriptor array1, dpnp_descriptor out)
 cpdef dpnp_descriptor dpnp_exp2(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_expm1(dpnp_descriptor array1)
-cpdef dpnp_descriptor dpnp_log(dpnp_descriptor array1, dpnp_descriptor out)
 cpdef dpnp_descriptor dpnp_log10(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_log1p(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_log2(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_radians(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_recip(dpnp_descriptor array1)
-cpdef dpnp_descriptor dpnp_sin(dpnp_descriptor array1, dpnp_descriptor out)
 cpdef dpnp_descriptor dpnp_sinh(dpnp_descriptor array1)
-cpdef dpnp_descriptor dpnp_sqrt(dpnp_descriptor array1, dpnp_descriptor out)
-cpdef dpnp_descriptor dpnp_square(dpnp_descriptor array1)
 cpdef dpnp_descriptor dpnp_tan(dpnp_descriptor array1, dpnp_descriptor out)
 cpdef dpnp_descriptor dpnp_tanh(dpnp_descriptor array1)
diff --git a/dpnp/dpnp_algo/dpnp_algo_linearalgebra.pxi b/dpnp/dpnp_algo/dpnp_algo_linearalgebra.pxi
index 407d3466c9b..ffa80c97be4 100644
--- a/dpnp/dpnp_algo/dpnp_algo_linearalgebra.pxi
+++ b/dpnp/dpnp_algo/dpnp_algo_linearalgebra.pxi
@@ -55,7 +55,7 @@ ctypedef c_dpctl.DPCTLSyclEventRef(*fptr_2in_1out_dot_t)(c_dpctl.DPCTLSyclQueueR
                                                          const shape_elem_type *, const shape_elem_type * ,
                                                          void * , const size_t, const size_t,
                                                          const shape_elem_type *, const shape_elem_type * ,
-                                                         const c_dpctl.DPCTLEventVectorRef)
+                                                         const c_dpctl.DPCTLEventVectorRef) except +
 ctypedef c_dpctl.DPCTLSyclEventRef(*fptr_2in_1out_matmul_t)(c_dpctl.DPCTLSyclQueueRef,
                                                             void * , const size_t, const size_t,
                                                             const shape_elem_type *, const shape_elem_type * ,
diff --git a/dpnp/dpnp_algo/dpnp_algo_logic.pxi b/dpnp/dpnp_algo/dpnp_algo_logic.pxi
index f84e90b186f..0d26f1ddeb5 100644
--- a/dpnp/dpnp_algo/dpnp_algo_logic.pxi
+++ b/dpnp/dpnp_algo/dpnp_algo_logic.pxi
@@ -39,20 +39,10 @@ __all__ += [
     "dpnp_all",
     "dpnp_allclose",
     "dpnp_any",
-    "dpnp_equal",
-    "dpnp_greater",
-    "dpnp_greater_equal",
     "dpnp_isclose",
     "dpnp_isfinite",
     "dpnp_isinf",
     "dpnp_isnan",
-    "dpnp_less",
-    "dpnp_less_equal",
-    "dpnp_logical_and",
-    "dpnp_logical_not",
-    "dpnp_logical_or",
-    "dpnp_logical_xor",
-    "dpnp_not_equal"
 ]
 
 
@@ -167,30 +157,6 @@ cpdef utils.dpnp_descriptor dpnp_any(utils.dpnp_descriptor array1):
     return result
 
 
-cpdef utils.dpnp_descriptor dpnp_equal(utils.dpnp_descriptor x1_obj,
-                                       utils.dpnp_descriptor x2_obj,
-                                       object dtype=None,
-                                       utils.dpnp_descriptor out=None,
-                                       object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="equal")
-
-
-cpdef utils.dpnp_descriptor dpnp_greater(utils.dpnp_descriptor x1_obj,
-                                         utils.dpnp_descriptor x2_obj,
-                                         object dtype=None,
-                                         utils.dpnp_descriptor out=None,
-                                         object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_GREATER_EXT, x1_obj, x2_obj, dtype, out, where, func_name="greater")
-
-
-cpdef utils.dpnp_descriptor dpnp_greater_equal(utils.dpnp_descriptor x1_obj,
-                                               utils.dpnp_descriptor x2_obj,
-                                               object dtype=None,
-                                               utils.dpnp_descriptor out=None,
-                                               object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_GREATER_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="greater_equal")
-
-
 cpdef utils.dpnp_descriptor dpnp_isclose(utils.dpnp_descriptor input1,
                                          utils.dpnp_descriptor input2,
                                          double rtol=1e-05,
@@ -253,58 +219,3 @@ cpdef utils.dpnp_descriptor dpnp_isnan(utils.dpnp_descriptor input1):
         result.get_pyobj()[i] = numpy.isnan(input1.get_pyobj()[i])
 
     return result
-
-
-cpdef utils.dpnp_descriptor dpnp_less(utils.dpnp_descriptor x1_obj,
-                                      utils.dpnp_descriptor x2_obj,
-                                      object dtype=None,
-                                      utils.dpnp_descriptor out=None,
-                                      object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_LESS_EXT, x1_obj, x2_obj, dtype, out, where, func_name="less")
-
-
-cpdef utils.dpnp_descriptor dpnp_less_equal(utils.dpnp_descriptor x1_obj,
-                                            utils.dpnp_descriptor x2_obj,
-                                            object dtype=None,
-                                            utils.dpnp_descriptor out=None,
-                                            object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_LESS_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="less_equal")
-
-
-cpdef utils.dpnp_descriptor dpnp_logical_and(utils.dpnp_descriptor x1_obj,
-                                             utils.dpnp_descriptor x2_obj,
-                                             object dtype=None,
-                                             utils.dpnp_descriptor out=None,
-                                             object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_AND_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_and")
-
-
-cpdef utils.dpnp_descriptor dpnp_logical_not(utils.dpnp_descriptor x_obj,
-                                            object dtype=None,
-                                            utils.dpnp_descriptor out=None,
-                                            object where=True):
-    return call_fptr_1in_1out_strides(DPNP_FN_LOGICAL_NOT_EXT, x_obj, dtype, out, where, func_name="logical_not")
-
-
-cpdef utils.dpnp_descriptor dpnp_logical_or(utils.dpnp_descriptor x1_obj,
-                                            utils.dpnp_descriptor x2_obj,
-                                            object dtype=None,
-                                            utils.dpnp_descriptor out=None,
-                                            object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_OR_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_or")
-
-
-cpdef utils.dpnp_descriptor dpnp_logical_xor(utils.dpnp_descriptor x1_obj,
-                                             utils.dpnp_descriptor x2_obj,
-                                             object dtype=None,
-                                             utils.dpnp_descriptor out=None,
-                                             object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_XOR_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_xor")
-
-
-cpdef utils.dpnp_descriptor dpnp_not_equal(utils.dpnp_descriptor x1_obj,
-                                           utils.dpnp_descriptor x2_obj,
-                                           object dtype=None,
-                                           utils.dpnp_descriptor out=None,
-                                           object where=True):
-    return call_fptr_2in_1out_strides(DPNP_FN_NOT_EQUAL_EXT, x1_obj, x2_obj, dtype, out, where, func_name="not_equal")
diff --git a/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi b/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi
index 4860feb7226..ae03fa54051 100644
--- a/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi
+++ b/dpnp/dpnp_algo/dpnp_algo_mathematical.pxi
@@ -49,7 +49,6 @@ __all__ += [
     "dpnp_ediff1d",
     "dpnp_fabs",
     "dpnp_floor",
-    "dpnp_floor_divide",
     "dpnp_fmod",
     "dpnp_gradient",
     'dpnp_hypot',
@@ -301,14 +300,6 @@ cpdef utils.dpnp_descriptor dpnp_floor(utils.dpnp_descriptor x1, utils.dpnp_desc
     return call_fptr_1in_1out_strides(DPNP_FN_FLOOR_EXT, x1, dtype=None, out=out, where=True, func_name='floor')
 
 
-cpdef utils.dpnp_descriptor dpnp_floor_divide(utils.dpnp_descriptor x1_obj,
-                                              utils.dpnp_descriptor x2_obj,
-                                              object dtype=None,
-                                              utils.dpnp_descriptor out=None,
-                                              object where=True):
-    return call_fptr_2in_1out(DPNP_FN_FLOOR_DIVIDE_EXT, x1_obj, x2_obj, dtype, out, where)
-
-
 cpdef utils.dpnp_descriptor dpnp_fmod(utils.dpnp_descriptor x1_obj,
                                       utils.dpnp_descriptor x2_obj,
                                       object dtype=None,
diff --git a/dpnp/dpnp_algo/dpnp_algo_trigonometric.pxi b/dpnp/dpnp_algo/dpnp_algo_trigonometric.pxi
index d7610336584..ec129a5285e 100644
--- a/dpnp/dpnp_algo/dpnp_algo_trigonometric.pxi
+++ b/dpnp/dpnp_algo/dpnp_algo_trigonometric.pxi
@@ -43,22 +43,17 @@ __all__ += [
     'dpnp_arctan',
     'dpnp_arctanh',
     'dpnp_cbrt',
-    'dpnp_cos',
     'dpnp_cosh',
     'dpnp_degrees',
     'dpnp_exp',
     'dpnp_exp2',
     'dpnp_expm1',
-    'dpnp_log',
     'dpnp_log10',
     'dpnp_log1p',
     'dpnp_log2',
     'dpnp_radians',
     'dpnp_recip',
-    'dpnp_sin',
     'dpnp_sinh',
-    'dpnp_sqrt',
-    'dpnp_square',
     'dpnp_tan',
     'dpnp_tanh',
     'dpnp_unwrap'
@@ -93,10 +88,6 @@ cpdef utils.dpnp_descriptor dpnp_cbrt(utils.dpnp_descriptor x1):
     return call_fptr_1in_1out_strides(DPNP_FN_CBRT_EXT, x1)
 
 
-cpdef utils.dpnp_descriptor dpnp_cos(utils.dpnp_descriptor x1, utils.dpnp_descriptor out):
-    return call_fptr_1in_1out_strides(DPNP_FN_COS_EXT, x1, dtype=None, out=out, where=True, func_name='cos')
-
-
 cpdef utils.dpnp_descriptor dpnp_cosh(utils.dpnp_descriptor x1):
     return call_fptr_1in_1out_strides(DPNP_FN_COSH_EXT, x1)
 
@@ -117,10 +108,6 @@ cpdef utils.dpnp_descriptor dpnp_expm1(utils.dpnp_descriptor x1):
     return call_fptr_1in_1out_strides(DPNP_FN_EXPM1_EXT, x1)
 
 
-cpdef utils.dpnp_descriptor dpnp_log(utils.dpnp_descriptor x1, utils.dpnp_descriptor out):
-    return call_fptr_1in_1out_strides(DPNP_FN_LOG_EXT, x1, dtype=None, out=out, where=True, func_name='log')
-
-
 cpdef utils.dpnp_descriptor dpnp_log10(utils.dpnp_descriptor x1):
     return call_fptr_1in_1out_strides(DPNP_FN_LOG10_EXT, x1)
 
@@ -141,22 +128,10 @@ cpdef utils.dpnp_descriptor dpnp_radians(utils.dpnp_descriptor x1):
     return call_fptr_1in_1out_strides(DPNP_FN_RADIANS_EXT, x1)
 
 
-cpdef utils.dpnp_descriptor dpnp_sin(utils.dpnp_descriptor x1, utils.dpnp_descriptor out):
-    return call_fptr_1in_1out_strides(DPNP_FN_SIN_EXT, x1, dtype=None, out=out, where=True, func_name='sin')
-
-
 cpdef utils.dpnp_descriptor dpnp_sinh(utils.dpnp_descriptor x1):
     return call_fptr_1in_1out_strides(DPNP_FN_SINH_EXT, x1)
 
 
-cpdef utils.dpnp_descriptor dpnp_sqrt(utils.dpnp_descriptor x1, utils.dpnp_descriptor out):
-    return call_fptr_1in_1out_strides(DPNP_FN_SQRT_EXT, x1, dtype=None, out=out, where=True, func_name='sqrt')
-
-
-cpdef utils.dpnp_descriptor dpnp_square(utils.dpnp_descriptor x1):
-    return call_fptr_1in_1out_strides(DPNP_FN_SQUARE_EXT, x1)
-
-
 cpdef utils.dpnp_descriptor dpnp_tan(utils.dpnp_descriptor x1, utils.dpnp_descriptor out):
     return call_fptr_1in_1out_strides(DPNP_FN_TAN_EXT, x1, dtype=None, out=out, where=True, func_name='tan')
 
diff --git a/dpnp/dpnp_algo/dpnp_elementwise_common.py b/dpnp/dpnp_algo/dpnp_elementwise_common.py
index a4dd92cec74..e7aab3ba490 100644
--- a/dpnp/dpnp_algo/dpnp_elementwise_common.py
+++ b/dpnp/dpnp_algo/dpnp_elementwise_common.py
@@ -30,17 +30,110 @@
 import dpctl
 import dpctl.tensor as dpt
 import dpctl.tensor._tensor_impl as ti
-from dpctl.tensor._elementwise_common import BinaryElementwiseFunc
+from dpctl.tensor._elementwise_common import (
+    BinaryElementwiseFunc,
+    UnaryElementwiseFunc,
+)
 
 import dpnp
 import dpnp.backend.extensions.vm._vm_impl as vmi
 from dpnp.dpnp_array import dpnp_array
+from dpnp.dpnp_utils import call_origin
 
-__all__ = ["dpnp_add", "dpnp_divide", "dpnp_multiply", "dpnp_subtract"]
+__all__ = [
+    "check_nd_call_func",
+    "dpnp_add",
+    "dpnp_cos",
+    "dpnp_divide",
+    "dpnp_equal",
+    "dpnp_floor_divide",
+    "dpnp_greater",
+    "dpnp_greater_equal",
+    "dpnp_less",
+    "dpnp_less_equal",
+    "dpnp_log",
+    "dpnp_logical_and",
+    "dpnp_logical_not",
+    "dpnp_logical_or",
+    "dpnp_logical_xor",
+    "dpnp_multiply",
+    "dpnp_not_equal",
+    "dpnp_sin",
+    "dpnp_sqrt",
+    "dpnp_square",
+    "dpnp_subtract",
+]
+
+
+def check_nd_call_func(
+    origin_func,
+    dpnp_func,
+    *x_args,
+    out=None,
+    where=True,
+    order="K",
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
+    """
+    Checks arguments and calls function with a single input array.
+
+    Chooses a common internal elementwise function to call in DPNP based on input arguments
+    or to fallback on NumPy call if any passed argument is not currently supported.
+
+    """
+
+    args_len = len(x_args)
+    if kwargs:
+        pass
+    elif where is not True:
+        pass
+    elif dtype is not None:
+        pass
+    elif subok is not True:
+        pass
+    elif args_len < 1 or args_len > 2:
+        raise ValueError(
+            "Unsupported number of input arrays to pass in elementwise function {}".format(
+                dpnp_func.__name__
+            )
+        )
+    elif args_len == 1 and dpnp.isscalar(x_args[0]):
+        # input has to be an array
+        pass
+    elif (
+        args_len == 2 and dpnp.isscalar(x_args[0]) and dpnp.isscalar(x_args[1])
+    ):
+        # at least one of input has to be an array
+        pass
+    else:
+        if order in "afkcAFKC":
+            order = order.upper()
+        elif order is None:
+            order = "K"
+        else:
+            raise ValueError(
+                "order must be one of 'C', 'F', 'A', or 'K' (got '{}')".format(
+                    order
+                )
+            )
+
+        return dpnp_func(*x_args, out=out, order=order)
+    return call_origin(
+        origin_func,
+        *x_args,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
+    )
 
 
 _add_docstring_ = """
-add(x1, x2, out=None, order='K')
+add(x1, x2, out=None, order="K")
 
 Calculates the sum for each element `x1_i` of the input array `x1` with
 the respective element `x2_i` of the input array `x2`.
@@ -84,8 +177,57 @@ def dpnp_add(x1, x2, out=None, order="K"):
     return dpnp_array._create_from_usm_ndarray(res_usm)
 
 
+_cos_docstring = """
+cos(x, out=None, order='K')
+Computes cosine for each element `x_i` for input array `x`.
+Args:
+    x (dpnp.ndarray):
+        Input array, expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate. Array must have the correct
+        shape and the expected data type.
+    order ("C","F","A","K", optional): memory layout of the new
+        output array, if parameter `out` is `None`.
+        Default: "K".
+Return:
+    dpnp.ndarray:
+        An array containing the element-wise cosine. The data type
+        of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_cos(x, out=None, order="K"):
+    """
+    Invokes cos() function from pybind11 extension of OneMKL VM if possible.
+
+    Otherwise fully relies on dpctl.tensor implementation for cos() function.
+
+    """
+
+    def _call_cos(src, dst, sycl_queue, depends=None):
+        """A callback to register in UnaryElementwiseFunc class of dpctl.tensor"""
+
+        if depends is None:
+            depends = []
+
+        if vmi._mkl_cos_to_call(sycl_queue, src, dst):
+            # call pybind11 extension for cos() function from OneMKL VM
+            return vmi._cos(sycl_queue, src, dst, depends)
+        return ti._cos(src, dst, sycl_queue, depends)
+
+    # dpctl.tensor only works with usm_ndarray
+    x1_usm = dpnp.get_usm_ndarray(x)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = UnaryElementwiseFunc(
+        "cos", ti._cos_result_type, _call_cos, _cos_docstring
+    )
+    res_usm = func(x1_usm, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
 _divide_docstring_ = """
-divide(x1, x2, out=None, order='K')
+divide(x1, x2, out=None, order="K")
 
 Calculates the ratio for each element `x1_i` of the input array `x1` with
 the respective element `x2_i` of the input array `x2`.
@@ -122,7 +264,7 @@ def _call_divide(src1, src2, dst, sycl_queue, depends=None):
         if depends is None:
             depends = []
 
-        if vmi._can_call_div(sycl_queue, src1, src2, dst):
+        if vmi._mkl_div_to_call(sycl_queue, src1, src2, dst):
             # call pybind11 extension for div() function from OneMKL VM
             return vmi._div(sycl_queue, src1, src2, dst, depends)
         return ti._divide(src1, src2, dst, sycl_queue, depends)
@@ -162,8 +304,457 @@ def _call_divide_inplace(lhs, rhs, sycl_queue, depends=None):
     return dpnp_array._create_from_usm_ndarray(res_usm)
 
 
+_equal_docstring_ = """
+
+equal(x1, x2, out=None, order="K")
+Calculates equality results for each element `x1_i` of
+the input array `x1` the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        an array containing the result of element-wise equality comparison.
+        The data type of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_equal(x1, x2, out=None, order="K"):
+    """Invokes equal() from dpctl.tensor implementation for equal() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "equal", ti._equal_result_type, ti._equal, _equal_docstring_
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_floor_divide_docstring_ = """
+floor_divide(x1, x2, out=None, order="K")
+Calculates the ratio for each element `x1_i` of the input array `x1` with
+the respective element `x2_i` of the input array `x2` to the greatest
+integer-value number that is not greater than the division result.
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        an array containing the result of element-wise floor division.
+        The data type of the returned array is determined by the Type
+        Promotion Rules
+"""
+
+
+def dpnp_floor_divide(x1, x2, out=None, order="K"):
+    """Invokes floor_divide() from dpctl.tensor implementation for floor_divide() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "floor_divide",
+        ti._floor_divide_result_type,
+        ti._floor_divide,
+        _floor_divide_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_greater_docstring_ = """
+greater(x1, x2, out=None, order="K")
+
+Calculates the greater-than results for each element `x1_i` of
+the input array `x1` the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        an array containing the result of element-wise greater-than comparison.
+        The data type of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_greater(x1, x2, out=None, order="K"):
+    """Invokes greater() from dpctl.tensor implementation for greater() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "greater", ti._greater_result_type, ti._greater, _greater_docstring_
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_greater_equal_docstring_ = """
+greater_equal(x1, x2, out=None, order="K")
+
+Calculates the greater-than or equal-to results for each element `x1_i` of
+the input array `x1` the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        an array containing the result of element-wise greater-than or equal-to comparison.
+        The data type of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_greater_equal(x1, x2, out=None, order="K"):
+    """Invokes greater_equal() from dpctl.tensor implementation for greater_equal() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "greater_equal",
+        ti._greater_equal_result_type,
+        ti._greater_equal,
+        _greater_equal_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_less_docstring_ = """
+less(x1, x2, out=None, order="K")
+
+Calculates the less-than results for each element `x1_i` of
+the input array `x1` the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        an array containing the result of element-wise less-than comparison.
+        The data type of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_less(x1, x2, out=None, order="K"):
+    """Invokes less() from dpctl.tensor implementation for less() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "less", ti._less_result_type, ti._less, _less_docstring_
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_less_equal_docstring_ = """
+less_equal(x1, x2, out=None, order="K")
+
+Calculates the less-than or equal-to results for each element `x1_i` of
+the input array `x1` the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        An array containing the result of element-wise less-than or equal-to comparison.
+        The data type of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_less_equal(x1, x2, out=None, order="K"):
+    """Invokes less_equal() from dpctl.tensor implementation for less_equal() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "less_equal",
+        ti._less_equal_result_type,
+        ti._less_equal,
+        _less_equal_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_log_docstring = """
+log(x, out=None, order='K')
+Computes the natural logarithm element-wise.
+Args:
+    x (dpnp.ndarray):
+        Input array, expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate. Array must have the correct
+        shape and the expected data type.
+    order ("C","F","A","K", optional): memory layout of the new
+        output array, if parameter `out` is `None`.
+        Default: "K".
+Return:
+    dpnp.ndarray:
+        An array containing the element-wise natural logarithm values.
+"""
+
+
+def dpnp_log(x, out=None, order="K"):
+    """
+    Invokes log() function from pybind11 extension of OneMKL VM if possible.
+
+    Otherwise fully relies on dpctl.tensor implementation for log() function.
+
+    """
+
+    def _call_log(src, dst, sycl_queue, depends=None):
+        """A callback to register in UnaryElementwiseFunc class of dpctl.tensor"""
+
+        if depends is None:
+            depends = []
+
+        if vmi._mkl_ln_to_call(sycl_queue, src, dst):
+            # call pybind11 extension for ln() function from OneMKL VM
+            return vmi._ln(sycl_queue, src, dst, depends)
+        return ti._log(src, dst, sycl_queue, depends)
+
+    # dpctl.tensor only works with usm_ndarray
+    x1_usm = dpnp.get_usm_ndarray(x)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = UnaryElementwiseFunc(
+        "log", ti._log_result_type, _call_log, _log_docstring
+    )
+    res_usm = func(x1_usm, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_logical_and_docstring_ = """
+logical_and(x1, x2, out=None, order='K')
+
+Computes the logical AND for each element `x1_i` of the input array `x1`
+with the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array.
+    x2 (dpnp.ndarray):
+        Second input array.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    usm_narray:
+        An array containing the element-wise logical AND results.
+"""
+
+
+def dpnp_logical_and(x1, x2, out=None, order="K"):
+    """Invokes logical_and() from dpctl.tensor implementation for logical_and() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "logical_and",
+        ti._logical_and_result_type,
+        ti._logical_and,
+        _logical_and_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_logical_not_docstring_ = """
+logical_not(x, out=None, order='K')
+Computes the logical NOT for each element `x_i` of input array `x`.
+Args:
+    x (dpnp.ndarray):
+        Input array.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate. Array must have the correct
+        shape and the expected data type.
+    order ("C","F","A","K", optional): memory layout of the new
+        output array, if parameter `out` is `None`.
+        Default: "K".
+Return:
+    usm_ndarray:
+        An array containing the element-wise logical NOT results.
+"""
+
+
+def dpnp_logical_not(x, out=None, order="K"):
+    """Invokes logical_not() from dpctl.tensor implementation for logical_not() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x_usm = dpnp.get_usm_ndarray(x)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = UnaryElementwiseFunc(
+        "logical_not",
+        ti._logical_not_result_type,
+        ti._logical_not,
+        _logical_not_docstring_,
+    )
+    res_usm = func(x_usm, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_logical_or_docstring_ = """
+logical_or(x1, x2, out=None, order='K')
+
+Computes the logical OR for each element `x1_i` of the input array `x1`
+with the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array.
+    x2 (dpnp.ndarray):
+        Second input array.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    usm_narray:
+        An array containing the element-wise logical OR results.
+"""
+
+
+def dpnp_logical_or(x1, x2, out=None, order="K"):
+    """Invokes logical_or() from dpctl.tensor implementation for logical_or() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "logical_or",
+        ti._logical_or_result_type,
+        ti._logical_or,
+        _logical_or_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_logical_xor_docstring_ = """
+logical_xor(x1, x2, out=None, order='K')
+
+Computes the logical XOR for each element `x1_i` of the input array `x1`
+with the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array.
+    x2 (dpnp.ndarray):
+        Second input array.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    usm_narray:
+        An array containing the element-wise logical XOR results.
+"""
+
+
+def dpnp_logical_xor(x1, x2, out=None, order="K"):
+    """Invokes logical_xor() from dpctl.tensor implementation for logical_xor() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "logical_xor",
+        ti._logical_xor_result_type,
+        ti._logical_xor,
+        _logical_xor_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
 _multiply_docstring_ = """
-multiply(x1, x2, out=None, order='K')
+multiply(x1, x2, out=None, order="K")
 
 Calculates the product for each element `x1_i` of the input array `x1`
 with the respective element `x2_i` of the input array `x2`.
@@ -211,8 +802,201 @@ def dpnp_multiply(x1, x2, out=None, order="K"):
     return dpnp_array._create_from_usm_ndarray(res_usm)
 
 
+_not_equal_docstring_ = """
+not_equal(x1, x2, out=None, order="K")
+
+Calculates inequality results for each element `x1_i` of
+the input array `x1` the respective element `x2_i` of the input array `x2`.
+
+Args:
+    x1 (dpnp.ndarray):
+        First input array, expected to have numeric data type.
+    x2 (dpnp.ndarray):
+        Second input array, also expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate.
+        Array have the correct shape and the expected data type.
+    order ("C","F","A","K", None, optional):
+        Memory layout of the newly output array, if parameter `out` is `None`.
+        Default: "K".
+Returns:
+    dpnp.ndarray:
+        an array containing the result of element-wise inequality comparison.
+        The data type of the returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_not_equal(x1, x2, out=None, order="K"):
+    """Invokes not_equal() from dpctl.tensor implementation for not_equal() function."""
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
+    x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = BinaryElementwiseFunc(
+        "not_equal",
+        ti._not_equal_result_type,
+        ti._not_equal,
+        _not_equal_docstring_,
+    )
+    res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_sin_docstring = """
+sin(x, out=None, order='K')
+Computes sine for each element `x_i` of input array `x`.
+Args:
+    x (dpnp.ndarray):
+        Input array, expected to have numeric data type.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate. Array must have the correct
+        shape and the expected data type.
+    order ("C","F","A","K", optional): memory layout of the new
+        output array, if parameter `out` is `None`.
+        Default: "K".
+Return:
+    dpnp.ndarray:
+        An array containing the element-wise sine. The data type of the
+        returned array is determined by the Type Promotion Rules.
+"""
+
+
+def dpnp_sin(x, out=None, order="K"):
+    """
+    Invokes sin() function from pybind11 extension of OneMKL VM if possible.
+
+    Otherwise fully relies on dpctl.tensor implementation for sin() function.
+
+    """
+
+    def _call_sin(src, dst, sycl_queue, depends=None):
+        """A callback to register in UnaryElementwiseFunc class of dpctl.tensor"""
+
+        if depends is None:
+            depends = []
+
+        if vmi._mkl_sin_to_call(sycl_queue, src, dst):
+            # call pybind11 extension for sin() function from OneMKL VM
+            return vmi._sin(sycl_queue, src, dst, depends)
+        return ti._sin(src, dst, sycl_queue, depends)
+
+    # dpctl.tensor only works with usm_ndarray
+    x1_usm = dpnp.get_usm_ndarray(x)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = UnaryElementwiseFunc(
+        "sin", ti._sin_result_type, _call_sin, _sin_docstring
+    )
+    res_usm = func(x1_usm, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_sqrt_docstring_ = """
+sqrt(x, out=None, order='K')
+Computes the non-negative square-root for each element `x_i` for input array `x`.
+Args:
+    x (dpnp.ndarray):
+        Input array.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate. Array must have the correct
+        shape and the expected data type.
+    order ("C","F","A","K", optional): memory layout of the new
+        output array, if parameter `out` is `None`.
+        Default: "K".
+Return:
+    dpnp.ndarray:
+        An array containing the element-wise square-root results.
+"""
+
+
+def dpnp_sqrt(x, out=None, order="K"):
+    """
+    Invokes sqrt() function from pybind11 extension of OneMKL VM if possible.
+
+    Otherwise fully relies on dpctl.tensor implementation for sqrt() function.
+
+    """
+
+    def _call_sqrt(src, dst, sycl_queue, depends=None):
+        """A callback to register in UnaryElementwiseFunc class of dpctl.tensor"""
+
+        if depends is None:
+            depends = []
+
+        if vmi._mkl_sqrt_to_call(sycl_queue, src, dst):
+            # call pybind11 extension for sqrt() function from OneMKL VM
+            return vmi._sqrt(sycl_queue, src, dst, depends)
+        return ti._sqrt(src, dst, sycl_queue, depends)
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x_usm = dpnp.get_usm_ndarray(x)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = UnaryElementwiseFunc(
+        "sqrt",
+        ti._sqrt_result_type,
+        _call_sqrt,
+        _sqrt_docstring_,
+    )
+    res_usm = func(x_usm, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
+_square_docstring_ = """
+square(x, out=None, order='K')
+Computes `x_i**2` (or `x_i*x_i`) for each element `x_i` of input array `x`.
+Args:
+    x (dpnp.ndarray):
+        Input array.
+    out ({None, dpnp.ndarray}, optional):
+        Output array to populate. Array must have the correct
+        shape and the expected data type.
+    order ("C","F","A","K", optional): memory layout of the new
+        output array, if parameter `out` is `None`.
+        Default: "K".
+Return:
+    dpnp.ndarray:
+        An array containing the element-wise square results.
+"""
+
+
+def dpnp_square(x, out=None, order="K"):
+    """
+    Invokes sqr() function from pybind11 extension of OneMKL VM if possible.
+
+    Otherwise fully relies on dpctl.tensor implementation for square() function.
+
+    """
+
+    def _call_square(src, dst, sycl_queue, depends=None):
+        """A callback to register in UnaryElementwiseFunc class of dpctl.tensor"""
+
+        if depends is None:
+            depends = []
+
+        if vmi._mkl_sqr_to_call(sycl_queue, src, dst):
+            # call pybind11 extension for sqr() function from OneMKL VM
+            return vmi._sqr(sycl_queue, src, dst, depends)
+        return ti._square(src, dst, sycl_queue, depends)
+
+    # dpctl.tensor only works with usm_ndarray or scalar
+    x_usm = dpnp.get_usm_ndarray(x)
+    out_usm = None if out is None else dpnp.get_usm_ndarray(out)
+
+    func = UnaryElementwiseFunc(
+        "square",
+        ti._square_result_type,
+        _call_square,
+        _square_docstring_,
+    )
+    res_usm = func(x_usm, out=out_usm, order=order)
+    return dpnp_array._create_from_usm_ndarray(res_usm)
+
+
 _subtract_docstring_ = """
-subtract(x1, x2, out=None, order='K')
+subtract(x1, x2, out=None, order="K")
 
 Calculates the difference bewteen each element `x1_i` of the input
 array `x1` and the respective element `x2_i` of the input array `x2`.
diff --git a/dpnp/dpnp_iface_bitwise.py b/dpnp/dpnp_iface_bitwise.py
index ecaa68ec2f7..4bffb71417f 100644
--- a/dpnp/dpnp_iface_bitwise.py
+++ b/dpnp/dpnp_iface_bitwise.py
@@ -133,7 +133,7 @@ def bitwise_and(x1, x2, dtype=None, out=None, where=True, **kwargs):
     Returns
     -------
     y : dpnp.ndarray
-        An array containing the element-wise results.
+        An array containing the element-wise results of positive square root.
 
     Limitations
     -----------
diff --git a/dpnp/dpnp_iface_linearalgebra.py b/dpnp/dpnp_iface_linearalgebra.py
index ab33ece608e..70e2a8048c0 100644
--- a/dpnp/dpnp_iface_linearalgebra.py
+++ b/dpnp/dpnp_iface_linearalgebra.py
@@ -108,17 +108,16 @@ def dot(x1, x2, out=None, **kwargs):
             else (None, None)
         )
 
-        # TODO: copy_when_strides=False (now it's done for faster implementation with transpose arrays)
         x1_desc = dpnp.get_dpnp_descriptor(
             x1,
-            copy_when_strides=True,
+            copy_when_strides=False,
             copy_when_nondefault_queue=False,
             alloc_usm_type=usm_type,
             alloc_queue=queue,
         )
         x2_desc = dpnp.get_dpnp_descriptor(
             x2,
-            copy_when_strides=True,
+            copy_when_strides=False,
             copy_when_nondefault_queue=False,
             alloc_usm_type=usm_type,
             alloc_queue=queue,
@@ -131,7 +130,9 @@ def dot(x1, x2, out=None, **kwargs):
                     )
                 out_desc = (
                     dpnp.get_dpnp_descriptor(
-                        out, copy_when_nondefault_queue=False
+                        out,
+                        copy_when_strides=False,
+                        copy_when_nondefault_queue=False,
                     )
                     or None
                 )
diff --git a/dpnp/dpnp_iface_logic.py b/dpnp/dpnp_iface_logic.py
index 658459bd303..fdf1dcb3532 100644
--- a/dpnp/dpnp_iface_logic.py
+++ b/dpnp/dpnp_iface_logic.py
@@ -46,6 +46,20 @@
 from dpnp.dpnp_algo import *
 from dpnp.dpnp_utils import *
 
+from .dpnp_algo.dpnp_elementwise_common import (
+    check_nd_call_func,
+    dpnp_equal,
+    dpnp_greater,
+    dpnp_greater_equal,
+    dpnp_less,
+    dpnp_less_equal,
+    dpnp_logical_and,
+    dpnp_logical_not,
+    dpnp_logical_or,
+    dpnp_logical_xor,
+    dpnp_not_equal,
+)
+
 __all__ = [
     "all",
     "allclose",
@@ -223,7 +237,18 @@ def any(x1, /, axis=None, out=None, keepdims=False, *, where=True):
     )
 
 
-def equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def equal(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the truth value of (x1 == x2) element-wise.
 
@@ -238,10 +263,9 @@ def equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -256,54 +280,51 @@ def equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([0, 1, 3])
     >>> x2 = np.arange(3)
-    >>> out = np.equal(x1, x2)
-    >>> [i for i in out]
-    [True, True, False]
+    >>> np.equal(x1, x2)
+    array([ True,  True, False])
 
-    """
+    What is compared are values, not types. So an int (1) and an array of
+    length one can evaluate as True:
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_equal(x1_desc, x2_desc).get_pyobj()
+    >>> np.equal(1, np.ones(1))
+    array([ True])
 
-    return call_origin(
-        numpy.equal, x1, x2, out=out, where=where, dtype=dtype, subok=subok
+    The ``==`` operator can be used as a shorthand for ``equal`` on
+    :class:`dpnp.ndarray`.
+
+    >>> a = np.array([2, 4, 6])
+    >>> b = np.array([2, 4, 2])
+    >>> a == b
+    array([ True,  True, False])
+
+    """
+
+    return check_nd_call_func(
+        numpy.equal,
+        dpnp_equal,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
-def greater(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def greater(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the truth value of (x1 > x2) element-wise.
 
@@ -318,10 +339,9 @@ def greater(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -336,54 +356,45 @@ def greater(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([4, 2])
     >>> x2 = np.array([2, 2])
-    >>> out = np.greater(x1, x2)
-    >>> [i for i in out]
-    [True, False]
+    >>> np.greater(x1, x2)
+    array([ True, False])
 
-    """
+    The ``>`` operator can be used as a shorthand for ``greater`` on
+    :class:`dpnp.ndarray`.
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_greater(x1_desc, x2_desc).get_pyobj()
+    >>> a = np.array([4, 2])
+    >>> b = np.array([2, 2])
+    >>> a > b
+    array([ True, False])
 
-    return call_origin(
-        numpy.greater, x1, x2, out=out, where=where, dtype=dtype, subok=subok
+    """
+
+    return check_nd_call_func(
+        numpy.greater,
+        dpnp_greater,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
-def greater_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def greater_equal(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the truth value of (x1 >= x2) element-wise.
 
@@ -398,10 +409,9 @@ def greater_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -416,56 +426,30 @@ def greater_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([4, 2, 1])
     >>> x2 = np.array([2, 2, 2])
-    >>> out = np.greater_equal(x1, x2)
-    >>> [i for i in out]
-    [True, True, False]
+    >>> np.greater_equal(x1, x2)
+    array([ True,  True, False])
 
-    """
+    The ``>=`` operator can be used as a shorthand for ``greater_equal`` on
+    :class:`dpnp.ndarray`.
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_greater_equal(x1_desc, x2_desc).get_pyobj()
+    >>> a = np.array([4, 2, 1])
+    >>> b = np.array([2, 2, 2])
+    >>> a >= b
+    array([ True,  True, False])
 
-    return call_origin(
+    """
+
+    return check_nd_call_func(
         numpy.greater_equal,
+        dpnp_greater_equal,
         x1,
         x2,
         out=out,
         where=where,
+        order=order,
         dtype=dtype,
         subok=subok,
+        **kwargs,
     )
 
 
@@ -646,7 +630,18 @@ def isnan(x1, out=None, **kwargs):
     return call_origin(numpy.isnan, x1, out, **kwargs)
 
 
-def less(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def less(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the truth value of (x1 < x2) element-wise.
 
@@ -661,10 +656,9 @@ def less(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -679,54 +673,45 @@ def less(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([1, 2])
     >>> x2 = np.array([2, 2])
-    >>> out = np.less(x1, x2)
-    >>> [i for i in out]
-    [True, False]
+    >>> np.less(x1, x2)
+    array([ True, False])
 
-    """
+    The ``<`` operator can be used as a shorthand for ``less`` on
+    :class:`dpnp.ndarray`.
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_less(x1_desc, x2_desc).get_pyobj()
+    >>> a = np.array([1, 2])
+    >>> b = np.array([2, 2])
+    >>> a < b
+    array([ True, False])
 
-    return call_origin(
-        numpy.less, x1, x2, out=out, where=where, dtype=dtype, subok=subok
+    """
+
+    return check_nd_call_func(
+        numpy.less,
+        dpnp_less,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
-def less_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def less_equal(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the truth value of (x1 <= x2) element-wise.
 
@@ -741,10 +726,9 @@ def less_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -758,55 +742,46 @@ def less_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     --------
     >>> import dpnp as np
     >>> x1 = np.array([4, 2, 1])
-    >>> x2 = np.array([2, 2, 2])
-    >>> out = np.less_equal(x1, x2)
-    >>> [i for i in out]
-    [False, True, True]
+    >>> x2 = np.array([2, 2, 2]
+    >>> np.less_equal(x1, x2)
+    array([False,  True,  True])
 
-    """
+    The ``<=`` operator can be used as a shorthand for ``less_equal`` on
+    :class:`dpnp.ndarray`.
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_less_equal(x1_desc, x2_desc).get_pyobj()
+    >>> a = np.array([4, 2, 1])
+    >>> b = np.array([2, 2, 2])
+    >>> a <= b
+    array([False,  True,  True])
 
-    return call_origin(
-        numpy.less_equal, x1, x2, out=out, where=where, dtype=dtype, subok=subok
+    """
+
+    return check_nd_call_func(
+        numpy.less_equal,
+        dpnp_less_equal,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
-def logical_and(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def logical_and(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Compute the truth value of x1 AND x2 element-wise.
 
@@ -815,16 +790,16 @@ def logical_and(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     Returns
     -------
     out : dpnp.ndarray
-        Output array of bool type, element-wise logical comparison of `x1` and `x2`.
+        Boolean result of the logical AND operation applied to the elements
+        of `x1` and `x2`; the shape is determined by broadcasting.
 
     Limitations
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -838,60 +813,48 @@ def logical_and(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([True, False])
     >>> x2 = np.array([False, False])
-    >>> out = np.logical_and(x1, x2)
-    >>> [i for i in out]
-    [False, False]
+    >>> np.logical_and(x1, x2)
+    array([False, False])
 
-    """
+    >>> x = np.arange(5)
+    >>> np.logical_and(x > 1, x < 4)
+    array([False, False,  True,  True, False])
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_logical_and(x1_desc, x2_desc).get_pyobj()
+    The ``&`` operator can be used as a shorthand for ``logical_and`` on
+    boolean :class:`dpnp.ndarray`.
 
-    return call_origin(
+    >>> a = np.array([True, False])
+    >>> b = np.array([False, False])
+    >>> a & b
+    array([False, False])
+
+    """
+
+    return check_nd_call_func(
         numpy.logical_and,
+        dpnp_logical_and,
         x1,
         x2,
         out=out,
         where=where,
+        order=order,
         dtype=dtype,
         subok=subok,
+        **kwargs,
     )
 
 
-def logical_not(x, /, out=None, *, where=True, dtype=None, subok=True):
+def logical_not(
+    x,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Compute the truth value of NOT x element-wise.
 
@@ -906,10 +869,9 @@ def logical_not(x, /, out=None, *, where=True, dtype=None, subok=True):
     Limitations
     -----------
     Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data type is limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -921,33 +883,40 @@ def logical_not(x, /, out=None, *, where=True, dtype=None, subok=True):
     --------
     >>> import dpnp as np
     >>> x = np.array([True, False, 0, 1])
-    >>> out = np.logical_not(x)
-    >>> [i for i in out]
-    [False, True, True, False]
+    >>> np.logical_not(x)
+    array([False,  True,  True, False])
 
-    """
+    >>> x = np.arange(5)
+    >>> np.logical_not(x < 3)
+    array([False, False, False,  True,  True])
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    else:
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x, copy_when_strides=False, copy_when_nondefault_queue=False
-        )
-        if x1_desc:
-            return dpnp_logical_not(x1_desc).get_pyobj()
+    """
 
-    return call_origin(
-        numpy.logical_not, x, out=out, where=where, dtype=dtype, subok=subok
+    return check_nd_call_func(
+        numpy.logical_not,
+        dpnp_logical_not,
+        x,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
-def logical_or(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def logical_or(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Compute the truth value of x1 OR x2 element-wise.
 
@@ -956,16 +925,16 @@ def logical_or(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     Returns
     -------
     out : dpnp.ndarray
-        Output array of bool type, element-wise logical comparison of `x1` and `x2`.
+        Boolean result of the logical OR operation applied to the elements
+        of `x1` and `x2`; the shape is determined by broadcasting.
 
     Limitations
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -979,54 +948,49 @@ def logical_or(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([True, False])
     >>> x2 = np.array([False, False])
-    >>> out = np.logical_or(x1, x2)
-    >>> [i for i in out]
-    [True, False]
+    >>> np.logical_or(x1, x2)
+    array([ True, False])
 
-    """
+    >>> x = np.arange(5)
+    >>> np.logical_or(x < 1, x > 3)
+    array([ True, False, False, False,  True])
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_logical_or(x1_desc, x2_desc).get_pyobj()
+    The ``|`` operator can be used as a shorthand for ``logical_or`` on
+    boolean :class:`dpnp.ndarray`.
 
-    return call_origin(
-        numpy.logical_or, x1, x2, out=out, where=where, dtype=dtype, subok=subok
+    >>> a = np.array([True, False])
+    >>> b = np.array([False, False])
+    >>> a | b
+    array([ True, False])
+
+    """
+
+    return check_nd_call_func(
+        numpy.logical_or,
+        dpnp_logical_or,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
-def logical_xor(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def logical_xor(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Compute the truth value of x1 XOR x2 element-wise.
 
@@ -1035,16 +999,16 @@ def logical_xor(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     Returns
     -------
     out : dpnp.ndarray
-        Output array of bool type, element-wise logical comparison of `x1` and `x2`.
+        Boolean result of the logical XOR operation applied to the elements
+        of `x1` and `x2`; the shape is determined by broadcasting.
 
     Limitations
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -1058,60 +1022,47 @@ def logical_xor(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([True, True, False, False])
     >>> x2 = np.array([True, False, True, False])
-    >>> out = np.logical_xor(x1, x2)
-    >>> [i for i in out]
-    [False, True, True, False]
+    >>> np.logical_xor(x1, x2)
+    array([False,  True,  True, False])
 
-    """
+    >>> x = np.arange(5)
+    >>> np.logical_xor(x < 1, x > 3)
+    array([ True, False, False, False,  True])
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_logical_xor(x1_desc, x2_desc).get_pyobj()
+    Simple example showing support of broadcasting
 
-    return call_origin(
+    >>> np.logical_xor(0, np.eye(2))
+    array([[ True, False],
+           [False,  True]])
+
+    """
+
+    return check_nd_call_func(
         numpy.logical_xor,
+        dpnp_logical_xor,
         x1,
         x2,
         out=out,
         where=where,
+        order=order,
         dtype=dtype,
         subok=subok,
+        **kwargs,
     )
 
 
-def not_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
+def not_equal(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the truth value of (x1 != x2) element-wise.
 
@@ -1126,10 +1077,9 @@ def not_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     -----------
     Parameters `x1` and `x2` are supported as either scalar, :class:`dpnp.ndarray`
     or :class:`dpctl.tensor.usm_ndarray`, but both `x1` and `x2` can not be scalars at the same time.
-    Parameters `out`, `where`, `dtype` and `subok` are supported with their default values.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Input array data types are limited by supported DPNP :ref:`Data types`,
-    excluding `dpnp.complex64` and `dpnp.complex128`.
+    Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
@@ -1144,48 +1094,28 @@ def not_equal(x1, x2, /, out=None, *, where=True, dtype=None, subok=True):
     >>> import dpnp as np
     >>> x1 = np.array([1., 2.])
     >>> x2 = np.arange(1., 3.)
-    >>> out = np.not_equal(x1, x2)
-    >>> [i for i in out]
-    [False, False]
+    >>> np.not_equal(x1, x2)
+    array([False, False])
 
-    """
+    The ``!=`` operator can be used as a shorthand for ``not_equal`` on
+    :class:`dpnp.ndarray`.
 
-    if out is not None:
-        pass
-    elif where is not True:
-        pass
-    elif dtype is not None:
-        pass
-    elif subok is not True:
-        pass
-    elif dpnp.isscalar(x1) and dpnp.isscalar(x2):
-        # at least either x1 or x2 has to be an array
-        pass
-    else:
-        # get USM type and queue to copy scalar from the host memory into a USM allocation
-        usm_type, queue = (
-            get_usm_allocations([x1, x2])
-            if dpnp.isscalar(x1) or dpnp.isscalar(x2)
-            else (None, None)
-        )
-
-        x1_desc = dpnp.get_dpnp_descriptor(
-            x1,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        x2_desc = dpnp.get_dpnp_descriptor(
-            x2,
-            copy_when_strides=False,
-            copy_when_nondefault_queue=False,
-            alloc_usm_type=usm_type,
-            alloc_queue=queue,
-        )
-        if x1_desc and x2_desc:
-            return dpnp_not_equal(x1_desc, x2_desc).get_pyobj()
+    >>> a = np.array([1., 2.])
+    >>> b = np.array([1., 3.])
+    >>> a != b
+    array([False,  True])
 
-    return call_origin(
-        numpy.not_equal, x1, x2, out=out, where=where, dtype=dtype, subok=subok
+    """
+
+    return check_nd_call_func(
+        numpy.not_equal,
+        dpnp_not_equal,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
diff --git a/dpnp/dpnp_iface_mathematical.py b/dpnp/dpnp_iface_mathematical.py
index eaf3bfca3e1..2c45f05e2b9 100644
--- a/dpnp/dpnp_iface_mathematical.py
+++ b/dpnp/dpnp_iface_mathematical.py
@@ -42,6 +42,7 @@
 
 import dpctl.tensor as dpt
 import numpy
+from numpy.core.numeric import normalize_axis_tuple
 
 import dpnp
 from dpnp.dpnp_array import dpnp_array
@@ -50,6 +51,7 @@
 from .dpnp_algo.dpnp_elementwise_common import (
     dpnp_add,
     dpnp_divide,
+    dpnp_floor_divide,
     dpnp_multiply,
     dpnp_subtract,
 )
@@ -821,7 +823,18 @@ def floor(x1, out=None, **kwargs):
     return call_origin(numpy.floor, x1, out=out, **kwargs)
 
 
-def floor_divide(x1, x2, dtype=None, out=None, where=True, **kwargs):
+def floor_divide(
+    x1,
+    x2,
+    /,
+    out=None,
+    *,
+    where=True,
+    order="K",
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Compute the largest integer smaller or equal to the division of the inputs.
 
@@ -830,7 +843,7 @@ def floor_divide(x1, x2, dtype=None, out=None, where=True, **kwargs):
     Limitations
     -----------
         Parameters ``x1`` and ``x2`` are supported as either :obj:`dpnp.ndarray` or scalar.
-        Parameters ``dtype``, ``out`` and ``where`` are supported with their default values.
+        Parameters ``where``, ``dtype`` and ``subok`` are supported with their default values.
         Keyword arguments ``kwargs`` are currently unsupported.
         Otherwise the functions will be executed sequentially on CPU.
         Input array data types are limited by supported DPNP :ref:`Data types`.
@@ -845,55 +858,22 @@ def floor_divide(x1, x2, dtype=None, out=None, where=True, **kwargs):
     Examples
     --------
     >>> import dpnp as np
-    >>> result = np.floor_divide(np.array([1, -1, -2, -9]), np.array([-2, -2, -2, -2]))
-    >>> [x for x in result]
-    [-1, 0, 1, 4]
+    >>> np.floor_divide(np.array([1, -1, -2, -9]), np.array([-2, -2, -2, -2]))
+    array([-1,  0,  1,  4])
 
     """
 
-    x1_is_scalar = dpnp.isscalar(x1)
-    x2_is_scalar = dpnp.isscalar(x2)
-    x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
-    x2_desc = dpnp.get_dpnp_descriptor(x2, copy_when_nondefault_queue=False)
-
-    if x1_desc and x2_desc and not kwargs:
-        if not x1_desc and not x1_is_scalar:
-            pass
-        elif not x2_desc and not x2_is_scalar:
-            pass
-        elif x1_is_scalar and x2_is_scalar:
-            pass
-        elif x1_desc and x1_desc.ndim == 0:
-            pass
-        elif x2_desc and x2_desc.ndim == 0:
-            pass
-        elif x2_is_scalar and not x2_desc:
-            pass
-        elif x1_desc and x2_desc and x1_desc.size != x2_desc.size:
-            # TODO: enable broadcasting
-            pass
-        elif x1_desc and x2_desc and x1_desc.shape != x2_desc.shape:
-            pass
-        elif dtype is not None:
-            pass
-        elif out is not None:
-            pass
-        elif not where:
-            pass
-        elif x1_is_scalar and x2_desc.ndim > 1:
-            pass
-        else:
-            out_desc = (
-                dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False)
-                if out is not None
-                else None
-            )
-            return dpnp_floor_divide(
-                x1_desc, x2_desc, dtype, out_desc, where
-            ).get_pyobj()
-
-    return call_origin(
-        numpy.floor_divide, x1, x2, out=out, where=where, dtype=dtype, **kwargs
+    return _check_nd_call(
+        numpy.floor_divide,
+        dpnp_floor_divide,
+        x1,
+        x2,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
 
 
@@ -1835,6 +1815,12 @@ def sum(
 
     """
 
+    if axis is not None:
+        if not isinstance(axis, (tuple, list)):
+            axis = (axis,)
+
+        axis = normalize_axis_tuple(axis, x.ndim, "axis")
+
     if out is not None:
         pass
     elif initial != 0:
@@ -1842,6 +1828,30 @@ def sum(
     elif where is not True:
         pass
     else:
+        if axis == (0,) and len(x.shape) == 2 and not keepdims:
+            from dpctl.tensor._reduction import _default_reduction_dtype
+
+            from dpnp.backend.extensions.sycl_ext import _sycl_ext_impl
+
+            input = dpnp.get_usm_ndarray(x)
+
+            queue = input.sycl_queue
+            out_dtype = (
+                _default_reduction_dtype(input.dtype, queue)
+                if dtype is None
+                else dtype
+            )
+            output = dpt.empty(
+                input.shape[1], dtype=out_dtype, sycl_queue=queue
+            )
+
+            get_sum = _sycl_ext_impl._get_sum_over_axis_0
+            sum = get_sum(input, output)
+
+            if sum:
+                sum(input, output, []).wait()
+                return dpnp_array._create_from_usm_ndarray(output)
+
         y = dpt.sum(
             dpnp.get_usm_ndarray(x), axis=axis, dtype=dtype, keepdims=keepdims
         )
diff --git a/dpnp/dpnp_iface_trigonometric.py b/dpnp/dpnp_iface_trigonometric.py
index 43bd618e224..904e1e3a1a1 100644
--- a/dpnp/dpnp_iface_trigonometric.py
+++ b/dpnp/dpnp_iface_trigonometric.py
@@ -40,13 +40,21 @@
 """
 
 
-import dpctl.tensor as dpt
 import numpy
 
 import dpnp
 from dpnp.dpnp_algo import *
 from dpnp.dpnp_utils import *
 
+from .dpnp_algo.dpnp_elementwise_common import (
+    check_nd_call_func,
+    dpnp_cos,
+    dpnp_log,
+    dpnp_sin,
+    dpnp_sqrt,
+    dpnp_square,
+)
+
 __all__ = [
     "arccos",
     "arccosh",
@@ -403,39 +411,54 @@ def arctan2(x1, x2, dtype=None, out=None, where=True, **kwargs):
     )
 
 
-def cos(x1, out=None, **kwargs):
+def cos(
+    x,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Trigonometric cosine, element-wise.
 
     For full documentation refer to :obj:`numpy.cos`.
 
+    Returns
+    -------
+    y : dpnp.ndarray
+        The cosine of each element of `x`.
+
     Limitations
     -----------
-    Input array is supported as :obj:`dpnp.ndarray`.
+    Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
+    Otherwise the function will be executed sequentially on CPU.
     Input array data types are limited by supported DPNP :ref:`Data types`.
 
     Examples
     --------
     >>> import dpnp as np
     >>> x = np.array([0, np.pi/2, np.pi])
-    >>> out = np.cos(x)
-    >>> [i for i in out]
-    [1.0, 6.123233995736766e-17, -1.0]
+    >>> np.cos(x)
+    array([ 1.000000e+00, -4.371139e-08, -1.000000e+00])
 
     """
 
-    x1_desc = dpnp.get_dpnp_descriptor(
-        x1, copy_when_strides=False, copy_when_nondefault_queue=False
+    return check_nd_call_func(
+        numpy.cos,
+        dpnp_cos,
+        x,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
-    if x1_desc:
-        out_desc = (
-            dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False)
-            if out is not None
-            else None
-        )
-        return dpnp_cos(x1_desc, out_desc).get_pyobj()
-
-    return call_origin(numpy.cos, x1, out=out, **kwargs)
 
 
 def cosh(x1):
@@ -693,15 +716,35 @@ def hypot(x1, x2, dtype=None, out=None, where=True, **kwargs):
     )
 
 
-def log(x1, out=None, **kwargs):
+def log(
+    x,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
-    Trigonometric logarithm, element-wise.
+    Natural logarithm, element-wise.
+
+    The natural logarithm `log` is the inverse of the exponential function,
+    so that `log(exp(x)) = x`. The natural logarithm is logarithm in base `e`.
 
     For full documentation refer to :obj:`numpy.log`.
 
+    Returns
+    -------
+    y : dpnp.ndarray
+        The natural logarithm of `x`, element-wise.
+
     Limitations
     -----------
-    Input array is supported as :obj:`dpnp.ndarray`.
+    Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
+    Otherwise the function will be executed sequentially on CPU.
     Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
@@ -715,25 +758,23 @@ def log(x1, out=None, **kwargs):
     Examples
     --------
     >>> import dpnp as np
-    >>> x = np.array([1.0, np.e, np.e**2, 0.0])
-    >>> out = np.log(x)
-    >>> [i for i in out]
-    [0.0, 1.0, 2.0, -inf]
+    >>> x = np.array([1, np.e, np.e**2, 0])
+    >>> np.log(x)
+    array([  0.,   1.,   2., -inf])
 
     """
 
-    x1_desc = dpnp.get_dpnp_descriptor(
-        x1, copy_when_strides=False, copy_when_nondefault_queue=False
+    return check_nd_call_func(
+        numpy.log,
+        dpnp_log,
+        x,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
-    if x1_desc:
-        out_desc = (
-            dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False)
-            if out is not None
-            else None
-        )
-        return dpnp_log(x1_desc, out_desc).get_pyobj()
-
-    return call_origin(numpy.log, x1, out=out, **kwargs)
 
 
 def log10(x1):
@@ -922,18 +963,32 @@ def radians(x1):
     return call_origin(numpy.radians, x1, **kwargs)
 
 
-def sin(x1, out=None, **kwargs):
+def sin(
+    x,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Trigonometric sine, element-wise.
 
     For full documentation refer to :obj:`numpy.sin`.
 
+    Returns
+    -------
+    y : dpnp.ndarray
+        The sine of each element of `x`.
+
     Limitations
     -----------
-    Parameters ``x1`` is supported as :obj:`dpnp.ndarray`.
-    Parameter ``out`` is supported as default value ``None``.
-    Keyword arguments ``kwargs`` are currently unsupported.
-    Otherwise the functions will be executed sequentially on CPU.
+    Parameters `x` is only supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
+    Otherwise the function will be executed sequentially on CPU.
     Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
@@ -946,24 +1001,22 @@ def sin(x1, out=None, **kwargs):
     --------
     >>> import dpnp as np
     >>> x = np.array([0, np.pi/2, np.pi])
-    >>> out = np.sin(x)
-    >>> [i for i in out]
-    [0.0, 1.0, 1.2246467991473532e-16]
+    >>> np.sin(x)
+    array([ 0.000000e+00,  1.000000e+00, -8.742278e-08])
 
     """
 
-    x1_desc = dpnp.get_dpnp_descriptor(
-        x1, copy_when_strides=False, copy_when_nondefault_queue=False
+    return check_nd_call_func(
+        numpy.sin,
+        dpnp_sin,
+        x,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
-    if x1_desc:
-        out_desc = (
-            dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False)
-            if out is not None
-            else None
-        )
-        return dpnp_sin(x1_desc, out_desc).get_pyobj()
-
-    return call_origin(numpy.sin, x1, out=out, **kwargs)
 
 
 def sinh(x1):
@@ -996,66 +1049,100 @@ def sinh(x1):
     return call_origin(numpy.sinh, x1, **kwargs)
 
 
-def sqrt(x1, /, out=None, **kwargs):
+def sqrt(
+    x,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
-    Return the positive square-root of an array, element-wise.
+    Return the non-negative square-root of an array, element-wise.
 
     For full documentation refer to :obj:`numpy.sqrt`.
 
+    Returns
+    -------
+    y : dpnp.ndarray
+        An array of the same shape as `x`, containing the positive
+        square-root of each element in `x`.  If any element in `x` is
+        complex, a complex array is returned (and the square-roots of
+        negative reals are calculated).  If all of the elements in `x`
+        are real, so is `y`, with negative elements returning ``nan``.
+
     Limitations
     -----------
     Input array is supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`.
     Parameter `out` is supported as class:`dpnp.ndarray`, class:`dpctl.tensor.usm_ndarray` or
     with default value ``None``.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
     Otherwise the function will be executed sequentially on CPU.
-    Keyword arguments ``kwargs`` are currently unsupported.
     Input array data types are limited by supported DPNP :ref:`Data types`.
 
     Examples
     --------
     >>> import dpnp as np
     >>> x = np.array([1, 4, 9])
-    >>> out = np.sqrt(x)
-    >>> [i for i in out]
-    [1.0, 2.0, 3.0]
+    >>> np.sqrt(x)
+    array([1., 2., 3.])
+
+    >>> x2 = np.array([4, -1, np.inf])
+    >>> np.sqrt(x2)
+    array([ 2., nan, inf])
 
     """
 
-    x1_desc = (
-        dpnp.get_dpnp_descriptor(
-            x1, copy_when_strides=False, copy_when_nondefault_queue=False
-        )
-        if not kwargs
-        else None
+    return check_nd_call_func(
+        numpy.sqrt,
+        dpnp_sqrt,
+        x,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
-    if x1_desc:
-        if out is not None:
-            if not isinstance(out, (dpnp.ndarray, dpt.usm_ndarray)):
-                raise TypeError("return array must be of supported array type")
-            out_desc = (
-                dpnp.get_dpnp_descriptor(out, copy_when_nondefault_queue=False)
-                or None
-            )
-        else:
-            out_desc = None
-        return dpnp_sqrt(x1_desc, out=out_desc).get_pyobj()
 
-    return call_origin(numpy.sqrt, x1, out=out, **kwargs)
 
-
-def square(x1):
+def square(
+    x,
+    /,
+    out=None,
+    *,
+    order="K",
+    where=True,
+    dtype=None,
+    subok=True,
+    **kwargs,
+):
     """
     Return the element-wise square of the input.
 
     For full documentation refer to :obj:`numpy.square`.
 
+    Returns
+    -------
+    y : dpnp.ndarray
+        Element-wise `x * x`, of the same shape and dtype as `x`.
+
     Limitations
     -----------
-    Input array is supported as :obj:`dpnp.ndarray`.
+    Input array is supported as either :class:`dpnp.ndarray` or :class:`dpctl.tensor.usm_ndarray`.
+    Parameter `out` is supported as class:`dpnp.ndarray`, class:`dpctl.tensor.usm_ndarray` or
+    with default value ``None``.
+    Parameters `where`, `dtype` and `subok` are supported with their default values.
+    Otherwise the function will be executed sequentially on CPU.
     Input array data types are limited by supported DPNP :ref:`Data types`.
 
     See Also
     --------
+    :obj:`dpnp..linalg.matrix_power` : Raise a square matrix
+                                       to the (integer) power `n`.
     :obj:`dpnp.sqrt` : Return the positive square-root of an array,
                        element-wise.
     :obj:`dpnp.power` : First array elements raised to powers
@@ -1064,20 +1151,23 @@ def square(x1):
     Examples
     --------
     >>> import dpnp as np
-    >>> x = np.array([1, 2, 3])
-    >>> out = np.square(x)
-    >>> [i for i in out]
-    [1, 4, 9]
+    >>> x = np.array([-1j, 1])
+    >>> np.square(x)
+    array([-1.+0.j,  1.+0.j])
 
     """
 
-    x1_desc = dpnp.get_dpnp_descriptor(
-        x1, copy_when_strides=False, copy_when_nondefault_queue=False
+    return check_nd_call_func(
+        numpy.square,
+        dpnp_square,
+        x,
+        out=out,
+        where=where,
+        order=order,
+        dtype=dtype,
+        subok=subok,
+        **kwargs,
     )
-    if x1_desc:
-        return dpnp_square(x1_desc).get_pyobj()
-
-    return call_origin(numpy.square, x1, **kwargs)
 
 
 def tan(x1, out=None, **kwargs):
diff --git a/dpnp/dpnp_utils/dpnp_algo_utils.pyx b/dpnp/dpnp_utils/dpnp_algo_utils.pyx
index 269d21a15e2..b69bceea9e6 100644
--- a/dpnp/dpnp_utils/dpnp_algo_utils.pyx
+++ b/dpnp/dpnp_utils/dpnp_algo_utils.pyx
@@ -201,7 +201,11 @@ def call_origin(function, *args, **kwargs):
         for res_origin in result:
             res = res_origin
             if isinstance(res_origin, numpy.ndarray):
-                res = dpnp_container.empty(res_origin.shape, dtype=res_origin.dtype, sycl_queue=exec_q)
+                if exec_q is not None:
+                    result_dtype = map_dtype_to_device(res_origin.dtype, exec_q.sycl_device)
+                else:
+                    result_dtype = res_origin.d_type
+                res = dpnp_container.empty(res_origin.shape, dtype=result_dtype, sycl_queue=exec_q)
                 copy_from_origin(res, res_origin)
             result_list.append(res)
 
diff --git a/dpnp/linalg/dpnp_algo_linalg.pyx b/dpnp/linalg/dpnp_algo_linalg.pyx
index 56b18935ce4..eeb9bf7f5f8 100644
--- a/dpnp/linalg/dpnp_algo_linalg.pyx
+++ b/dpnp/linalg/dpnp_algo_linalg.pyx
@@ -79,6 +79,16 @@ ctypedef c_dpctl.DPCTLSyclEventRef(*custom_linalg_2in_1out_func_ptr_t)(c_dpctl.D
                                                                        const c_dpctl.DPCTLEventVectorRef)
 
 
+cdef (DPNPFuncType, void *) get_ret_type_and_func(x1_obj, DPNPFuncData kernel_data):
+    if dpnp.issubdtype(x1_obj.dtype, dpnp.integer) and not x1_obj.sycl_device.has_aspect_fp64:
+        return_type = kernel_data.return_type_no_fp64
+        func = kernel_data.ptr_no_fp64
+    else:
+        return_type = kernel_data.return_type
+        func = kernel_data.ptr
+    return return_type, func
+
+
 cpdef utils.dpnp_descriptor dpnp_cholesky(utils.dpnp_descriptor input_):
     size_ = input_.shape[-1]
 
@@ -194,18 +204,20 @@ cpdef tuple dpnp_eig(utils.dpnp_descriptor x1):
     cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(x1.dtype)
     cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_EIG_EXT, param1_type, param1_type)
 
-    result_type = dpnp_DPNPFuncType_to_dtype(< size_t > kernel_data.return_type)
-
     x1_obj = x1.get_array()
 
+    cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(x1_obj, kernel_data)
+    cdef DPNPFuncType return_type = ret_type_and_func[0]
+    cdef custom_linalg_2in_1out_func_ptr_t func = < custom_linalg_2in_1out_func_ptr_t > ret_type_and_func[1]
+
     cdef utils.dpnp_descriptor res_val = utils.create_output_descriptor((size,),
-                                                                        kernel_data.return_type,
+                                                                        return_type,
                                                                         None,
                                                                         device=x1_obj.sycl_device,
                                                                         usm_type=x1_obj.usm_type,
                                                                         sycl_queue=x1_obj.sycl_queue)
     cdef utils.dpnp_descriptor res_vec = utils.create_output_descriptor(x1_shape,
-                                                                        kernel_data.return_type,
+                                                                        return_type,
                                                                         None,
                                                                         device=x1_obj.sycl_device,
                                                                         usm_type=x1_obj.usm_type,
@@ -216,7 +228,6 @@ cpdef tuple dpnp_eig(utils.dpnp_descriptor x1):
     cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
     cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
 
-    cdef custom_linalg_2in_1out_func_ptr_t func = <custom_linalg_2in_1out_func_ptr_t > kernel_data.ptr
     # call FPTR function
     cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
                                                     x1.get_data(),
@@ -241,9 +252,13 @@ cpdef utils.dpnp_descriptor dpnp_eigvals(utils.dpnp_descriptor input):
 
     input_obj = input.get_array()
 
+    cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(input_obj, kernel_data)
+    cdef DPNPFuncType return_type = ret_type_and_func[0]
+    cdef custom_linalg_1in_1out_with_size_func_ptr_t_ func = < custom_linalg_1in_1out_with_size_func_ptr_t_ > ret_type_and_func[1]
+
     # ceate result array with type given by FPTR data
     cdef utils.dpnp_descriptor res_val = utils.create_output_descriptor((size,),
-                                                                         kernel_data.return_type,
+                                                                         return_type,
                                                                          None,
                                                                          device=input_obj.sycl_device,
                                                                          usm_type=input_obj.usm_type,
@@ -254,7 +269,6 @@ cpdef utils.dpnp_descriptor dpnp_eigvals(utils.dpnp_descriptor input):
     cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
     cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
 
-    cdef custom_linalg_1in_1out_with_size_func_ptr_t_ func = <custom_linalg_1in_1out_with_size_func_ptr_t_ > kernel_data.ptr
     # call FPTR function
     cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
                                                     input.get_data(),
@@ -277,9 +291,13 @@ cpdef utils.dpnp_descriptor dpnp_inv(utils.dpnp_descriptor input):
 
     input_obj = input.get_array()
 
+    cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(input_obj, kernel_data)
+    cdef DPNPFuncType return_type = ret_type_and_func[0]
+    cdef custom_linalg_1in_1out_func_ptr_t func = < custom_linalg_1in_1out_func_ptr_t > ret_type_and_func[1]
+
     # ceate result array with type given by FPTR data
     cdef utils.dpnp_descriptor result = utils.create_output_descriptor(input_shape,
-                                                                       kernel_data.return_type,
+                                                                       return_type,
                                                                        None,
                                                                        device=input_obj.sycl_device,
                                                                        usm_type=input_obj.usm_type,
@@ -290,8 +308,6 @@ cpdef utils.dpnp_descriptor dpnp_inv(utils.dpnp_descriptor input):
     cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
     cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
 
-    cdef custom_linalg_1in_1out_func_ptr_t func = <custom_linalg_1in_1out_func_ptr_t > kernel_data.ptr
-
     cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
                                                     input.get_data(),
                                                     result.get_data(),
@@ -345,7 +361,8 @@ cpdef object dpnp_norm(object input, ord=None, axis=None):
     cdef long size_input = input.size
     cdef shape_type_c shape_input = input.shape
 
-    if input.dtype == dpnp.float32:
+    dev = input.get_array().sycl_device
+    if input.dtype == dpnp.float32 or not dev.has_aspect_fp64:
         res_type = dpnp.float32
     else:
         res_type = dpnp.float64
@@ -366,7 +383,7 @@ cpdef object dpnp_norm(object input, ord=None, axis=None):
 
             input = dpnp.ravel(input, order='K')
             sqnorm = dpnp.dot(input, input)
-            ret = dpnp.sqrt([sqnorm])
+            ret = dpnp.sqrt([sqnorm], dtype=res_type)
             return dpnp.array(ret.reshape(1, *ret.shape), dtype=res_type)
 
     len_axis = 1 if axis is None else len(axis_)
@@ -379,7 +396,7 @@ cpdef object dpnp_norm(object input, ord=None, axis=None):
             return input.dtype.type(dpnp.count_nonzero(input, axis=axis))
         elif ord is None or ord == 2:
             s = input * input
-            return dpnp.sqrt(dpnp.sum(s, axis=axis))
+            return dpnp.sqrt(dpnp.sum(s, axis=axis), dtype=res_type)
         elif isinstance(ord, str):
             raise ValueError(f"Invalid norm order '{ord}' for vectors")
         else:
@@ -455,20 +472,24 @@ cpdef tuple dpnp_qr(utils.dpnp_descriptor x1, str mode):
 
     x1_obj = x1.get_array()
 
+    cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(x1_obj, kernel_data)
+    cdef DPNPFuncType return_type = ret_type_and_func[0]
+    cdef custom_linalg_1in_3out_shape_t func = < custom_linalg_1in_3out_shape_t > ret_type_and_func[1]
+
     cdef utils.dpnp_descriptor res_q = utils.create_output_descriptor((size_m, min_m_n),
-                                                                       kernel_data.return_type,
+                                                                       return_type,
                                                                        None,
                                                                        device=x1_obj.sycl_device,
                                                                        usm_type=x1_obj.usm_type,
                                                                        sycl_queue=x1_obj.sycl_queue)
     cdef utils.dpnp_descriptor res_r = utils.create_output_descriptor((min_m_n, size_n),
-                                                                       kernel_data.return_type,
+                                                                       return_type,
                                                                        None,
                                                                        device=x1_obj.sycl_device,
                                                                        usm_type=x1_obj.usm_type,
                                                                        sycl_queue=x1_obj.sycl_queue)
     cdef utils.dpnp_descriptor tau = utils.create_output_descriptor((size_tau, ),
-                                                                     kernel_data.return_type,
+                                                                     return_type,
                                                                      None,
                                                                      device=x1_obj.sycl_device,
                                                                      usm_type=x1_obj.usm_type,
@@ -479,8 +500,6 @@ cpdef tuple dpnp_qr(utils.dpnp_descriptor x1, str mode):
     cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
     cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
 
-    cdef custom_linalg_1in_3out_shape_t func = < custom_linalg_1in_3out_shape_t > kernel_data.ptr
-
     cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
                                                     x1.get_data(),
                                                     res_q.get_data(),
@@ -504,26 +523,26 @@ cpdef tuple dpnp_svd(utils.dpnp_descriptor x1, cpp_bool full_matrices, cpp_bool
     cdef DPNPFuncType param1_type = dpnp_dtype_to_DPNPFuncType(x1.dtype)
     cdef DPNPFuncData kernel_data = get_dpnp_function_ptr(DPNP_FN_SVD_EXT, param1_type, param1_type)
 
-    cdef DPNPFuncType type_s = DPNP_FT_DOUBLE
-    if x1.dtype == dpnp.float32:
-        type_s = DPNP_FT_FLOAT
-
     x1_obj = x1.get_array()
 
+    cdef (DPNPFuncType, void *) ret_type_and_func = get_ret_type_and_func(x1_obj, kernel_data)
+    cdef DPNPFuncType return_type = ret_type_and_func[0]
+    cdef custom_linalg_1in_3out_shape_t func = < custom_linalg_1in_3out_shape_t > ret_type_and_func[1]
+
     cdef utils.dpnp_descriptor res_u = utils.create_output_descriptor((size_m, size_m),
-                                                                       kernel_data.return_type,
+                                                                       return_type,
                                                                        None,
                                                                        device=x1_obj.sycl_device,
                                                                        usm_type=x1_obj.usm_type,
                                                                        sycl_queue=x1_obj.sycl_queue)
     cdef utils.dpnp_descriptor res_s = utils.create_output_descriptor((size_s, ),
-                                                                       type_s,
+                                                                       return_type,
                                                                        None,
                                                                        device=x1_obj.sycl_device,
                                                                        usm_type=x1_obj.usm_type,
                                                                        sycl_queue=x1_obj.sycl_queue)
     cdef utils.dpnp_descriptor res_vt = utils.create_output_descriptor((size_n, size_n),
-                                                                       kernel_data.return_type,
+                                                                       return_type,
                                                                        None,
                                                                        device=x1_obj.sycl_device,
                                                                        usm_type=x1_obj.usm_type,
@@ -534,8 +553,6 @@ cpdef tuple dpnp_svd(utils.dpnp_descriptor x1, cpp_bool full_matrices, cpp_bool
     cdef c_dpctl.SyclQueue q = <c_dpctl.SyclQueue> result_sycl_queue
     cdef c_dpctl.DPCTLSyclQueueRef q_ref = q.get_queue_ref()
 
-    cdef custom_linalg_1in_3out_shape_t func = < custom_linalg_1in_3out_shape_t > kernel_data.ptr
-
     cdef c_dpctl.DPCTLSyclEventRef event_ref = func(q_ref,
                                                     x1.get_data(),
                                                     res_u.get_data(),
diff --git a/dpnp/linalg/dpnp_iface_linalg.py b/dpnp/linalg/dpnp_iface_linalg.py
index 0b96df5e141..3addcdc3258 100644
--- a/dpnp/linalg/dpnp_iface_linalg.py
+++ b/dpnp/linalg/dpnp_iface_linalg.py
@@ -97,9 +97,14 @@ def cholesky(input):
             pass
         else:
             if input.dtype == dpnp.int32 or input.dtype == dpnp.int64:
+                dev = x1_desc.get_array().sycl_device
+                if dev.has_aspect_fp64:
+                    dtype = dpnp.float64
+                else:
+                    dtype = dpnp.float32
                 # TODO memory copy. needs to move into DPNPC
                 input_ = dpnp.get_dpnp_descriptor(
-                    dpnp.astype(input, dpnp.float64),
+                    dpnp.astype(input, dtype=dtype),
                     copy_when_nondefault_queue=False,
                 )
             else:
diff --git a/dpnp/random/dpnp_algo_random.pyx b/dpnp/random/dpnp_algo_random.pyx
index 7c6eaae16ff..b46b4827f7e 100644
--- a/dpnp/random/dpnp_algo_random.pyx
+++ b/dpnp/random/dpnp_algo_random.pyx
@@ -458,7 +458,13 @@ cdef class MT19937(_Engine):
         MT19937_Delete(&self.mt19937)
 
     cdef bint is_uint_range(self, value):
-        return value >= 0 and value <= numpy.iinfo(numpy.uint32).max
+        if value < 0:
+            return False
+
+        max_val = numpy.iinfo(numpy.uint32).max
+        if isinstance(value, dpnp_array):
+            max_val = dpnp.array(max_val, dtype=numpy.uint32)
+        return value <= max_val
 
 
 cdef class MCG59(_Engine):
@@ -489,7 +495,13 @@ cdef class MCG59(_Engine):
         MCG59_Delete(&self.mcg59)
 
     cdef bint is_uint64_range(self, value):
-        return value >= 0 and value <= numpy.iinfo(numpy.uint64).max
+        if value < 0:
+            return False
+
+        max_val = numpy.iinfo(numpy.uint64).max
+        if isinstance(value, dpnp_array):
+            max_val = dpnp.array(max_val, dtype=numpy.uint64)
+        return value <= max_val
 
 
 cpdef utils.dpnp_descriptor dpnp_rng_beta(double a, double b, size):
diff --git a/dpnp/version.py b/dpnp/version.py
index e9e9a0d6df2..7a7e657e1f1 100755
--- a/dpnp/version.py
+++ b/dpnp/version.py
@@ -29,6 +29,6 @@
 DPNP version module
 """
 
-__version__: str = "0.12.1dev0"
+__version__: str = "0.12.1"
 
 version: str = __version__
diff --git a/setup.py b/setup.py
index df994b9aa7a..9b56902f359 100644
--- a/setup.py
+++ b/setup.py
@@ -12,13 +12,42 @@
 ).load_module()
 __version__ = version_mod.__version__
 
+"""
+Set project auxilary data like readme and licence files
+"""
+with open("README.md") as f:
+    __readme_file__ = f.read()
+
+CLASSIFIERS = """\
+Development Status :: 4 - Beta
+Intended Audience :: Science/Research
+Intended Audience :: Developers
+License :: OSI Approved :: Apache Software License
+Programming Language :: C++
+Programming Language :: Cython
+Programming Language :: Python
+Programming Language :: Python :: 3
+Programming Language :: Python :: 3.8
+Programming Language :: Python :: 3.9
+Programming Language :: Python :: 3.10
+Programming Language :: Python :: Implementation :: CPython
+Topic :: Software Development
+Topic :: Scientific/Engineering
+Operating System :: Microsoft :: Windows
+Operating System :: POSIX
+Operating System :: Unix
+"""
+
 setup(
     name="dpnp",
     version=__version__,
-    description="",
-    long_description="",
+    description="Data Parallel Extension for NumPy",
+    long_description=__readme_file__,
     long_description_content_type="text/markdown",
     license="Apache 2.0",
+    classifiers=[_f for _f in CLASSIFIERS.split("\n") if _f],
+    keywords="sycl numpy python3 intel mkl oneapi gpu dpcpp",
+    platforms=["Linux", "Windows"],
     author="Intel Corporation",
     url="https://github.com/IntelPython/dpnp",
     packages=[


Test patch:
diff --git a/tests/helper.py b/tests/helper.py
index 902db51f850..6971feecb53 100644
--- a/tests/helper.py
+++ b/tests/helper.py
@@ -90,6 +90,15 @@ def is_win_platform():
     return platform.startswith("win")
 
 
+def has_support_aspect16(device=None):
+    """
+    Return True if the device supports 16-bit precision floating point operations,
+    False otherwise.
+    """
+    dev = dpctl.select_default_device() if device is None else device
+    return dev.has_aspect_fp16
+
+
 def has_support_aspect64(device=None):
     """
     Return True if the device supports 64-bit precision floating point operations,
diff --git a/tests/skipped_tests.tbl b/tests/skipped_tests.tbl
index d0fb01ec90a..d5eab8dc75c 100644
--- a/tests/skipped_tests.tbl
+++ b/tests/skipped_tests.tbl
@@ -7,9 +7,7 @@ tests/test_random.py::TestPermutationsTestShuffle::test_shuffle1[lambda x: dpnp.
 
 tests/test_sycl_queue.py::test_1in_1out[opencl:gpu:0-trapz-data19]
 tests/test_sycl_queue.py::test_1in_1out[opencl:cpu:0-trapz-data19]
-tests/test_sycl_queue.py::test_broadcasting[opencl:gpu:0-floor_divide-data12-data22]
 tests/test_sycl_queue.py::test_broadcasting[opencl:gpu:0-remainder-data15-data25]
-tests/test_sycl_queue.py::test_broadcasting[opencl:cpu:0-floor_divide-data12-data22]
 tests/test_sycl_queue.py::test_broadcasting[opencl:cpu:0-remainder-data15-data25]
 
 tests/third_party/cupy/fft_tests/test_fft.py::TestFft2_param_1_{axes=None, norm=None, s=(1, None), shape=(3, 4)}::test_fft2
@@ -78,22 +76,18 @@ tests/test_dparray.py::test_astype[[]-complex-int32]
 tests/test_dparray.py::test_astype[[]-complex-bool]
 tests/test_dparray.py::test_astype[[]-complex-complex]
 
-tests/test_linalg.py::test_cond[None-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
-tests/test_linalg.py::test_cond[None-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
-tests/test_linalg.py::test_cond[1-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
-tests/test_linalg.py::test_cond[1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
-tests/test_linalg.py::test_cond[-1-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
 tests/test_linalg.py::test_cond[-1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
-tests/test_linalg.py::test_cond[2-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
-tests/test_linalg.py::test_cond[2-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
+tests/test_linalg.py::test_cond[1-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
 tests/test_linalg.py::test_cond[-2-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
+tests/test_linalg.py::test_cond[2-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
 tests/test_linalg.py::test_cond[-2-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
-tests/test_linalg.py::test_cond[numpy.inf-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
-tests/test_linalg.py::test_cond[numpy.inf-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
-tests/test_linalg.py::test_cond[-numpy.inf-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
-tests/test_linalg.py::test_cond[-numpy.inf-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
+tests/test_linalg.py::test_cond[2-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
 tests/test_linalg.py::test_cond["fro"-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
 tests/test_linalg.py::test_cond["fro"-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
+tests/test_linalg.py::test_cond[None-[[1, 0, -1], [0, 1, 0], [1, 0, 1]]]
+tests/test_linalg.py::test_cond[None-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
+tests/test_linalg.py::test_cond[-numpy.inf-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
+tests/test_linalg.py::test_cond[numpy.inf-[[1, 2, 3], [4, 5, 6], [7, 8, 9]]]
 
 tests/test_linalg.py::test_matrix_rank[None-[0, 1]-float64]
 tests/test_linalg.py::test_matrix_rank[None-[0, 1]-float32]
@@ -118,79 +112,6 @@ tests/test_linalg.py::test_norm1[None-3-[7]]
 tests/test_linalg.py::test_norm1[None-3-[1, 2]]
 tests/test_linalg.py::test_norm1[None-3-[1, 0]]
 
-tests/test_linalg.py::test_norm2[(0, 1)-None-[[1, 0]]]
-tests/test_linalg.py::test_norm2[(0, 1)-None-[[1, 2]]]
-tests/test_linalg.py::test_norm2[(0, 1)-None-[[1, 0], [3, 0]]]
-tests/test_linalg.py::test_norm2[(0, 1)-None-[[1, 2], [3, 4]]]
-tests/test_linalg.py::test_norm2[(0, 1)-"fro"-[[1, 0]]]
-tests/test_linalg.py::test_norm2[(0, 1)-"fro"-[[1, 2]]]
-tests/test_linalg.py::test_norm2[(0, 1)-"fro"-[[1, 0], [3, 0]]]
-tests/test_linalg.py::test_norm2[(0, 1)-"fro"-[[1, 2], [3, 4]]]
-tests/test_linalg.py::test_norm2[None-None-[[1, 2]]]
-tests/test_linalg.py::test_norm2[None-None-[[1, 0], [3, 0]]]
-tests/test_linalg.py::test_norm2[None-None-[[1, 2], [3, 4]]]
-tests/test_linalg.py::test_norm2[None-"fro"-[[1, 2]]]
-tests/test_linalg.py::test_norm2[None-"fro"-[[1, 0], [3, 0]]]
-tests/test_linalg.py::test_norm2[None-"fro"-[[1, 2], [3, 4]]]
-
-tests/test_linalg.py::test_norm3[0-None-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[0-None-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[0--2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[0--2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[0--1-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[0--1-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[0-2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[0-2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[1-None-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[1-None-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[1--2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[1--2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[1--1-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[1--1-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[1-2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[1-2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[2-None-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[2-None-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[2--2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[2--1-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[2-2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 1)-None-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 1)-None-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[(0, 1)--2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 1)--2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[(0, 1)-2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 1)-2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[(0, 2)-None-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 2)-None-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[(0, 2)--2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 2)-2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(0, 2)-2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[(1, 2)-None-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(1, 2)-None-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-tests/test_linalg.py::test_norm3[(1, 2)--2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(1, 2)-2-[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]]
-tests/test_linalg.py::test_norm3[(1, 2)-2-[[[1, 0], [3, 0]], [[5, 0], [7, 0]]]]
-
-tests/test_linalg.py::test_qr[complete-(2,2)-float64]
-tests/test_linalg.py::test_qr[complete-(3,4)-float64]
-tests/test_linalg.py::test_qr[complete-(3,4)-int64]
-tests/test_linalg.py::test_qr[complete-(3,4)-int32]
-tests/test_linalg.py::test_qr[complete-(5,3)-float64]
-tests/test_linalg.py::test_qr[complete-(5,3)-int64]
-tests/test_linalg.py::test_qr[complete-(5,3)-int32]
-tests/test_linalg.py::test_qr[complete-(16,16)-float64]
-tests/test_linalg.py::test_qr[complete-(16,16)-int64]
-tests/test_linalg.py::test_qr[complete-(16,16)-int32]
-tests/test_linalg.py::test_qr[reduced-(2,2)-float64]
-tests/test_linalg.py::test_qr[reduced-(3,4)-float64]
-tests/test_linalg.py::test_qr[reduced-(5,3)-float64]
-tests/test_linalg.py::test_qr[reduced-(16,16)-float64]
-
-tests/test_linalg.py::test_svd[(2,2)-float64]
-tests/test_linalg.py::test_svd[(3,4)-float64]
-tests/test_linalg.py::test_svd[(5,3)-float64]
-tests/test_linalg.py::test_svd[(16,16)-float64]
-
 tests/test_logic.py::test_allclose[int32]
 tests/test_logic.py::test_allclose[int64]
 tests/test_logic.py::test_allclose[float32]
@@ -693,19 +614,15 @@ tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_2_{reps
 tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_3_{reps=(0, 1)}::test_array_tile
 tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_4_{reps=(2, 3)}::test_array_tile
 tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_5_{reps=(2, 3, 4, 5)}::test_array_tile
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_455_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_457_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='fmod', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_459_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='remainder', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_461_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='mod', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_463_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_465_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='fmod', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_467_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='remainder', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_469_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='mod', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_535_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_537_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='fmod', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_539_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='remainder', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_541_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='mod', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_543_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_545_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='fmod', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_547_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='remainder', use_dtype=False}::test_binary
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_549_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='mod', use_dtype=False}::test_binary
@@ -714,35 +631,164 @@ tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticModf::test_m
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_10_{name='remainder', nargs=2}::test_raises_with_numpy_input
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_11_{name='mod', nargs=2}::test_raises_with_numpy_input
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_1_{name='angle', nargs=1}::test_raises_with_numpy_input
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_8_{name='floor_divide', nargs=2}::test_raises_with_numpy_input
 
 tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp
 tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp2
+tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp2_infinities
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_copysign_float
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_frexp
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_ldexp
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_nextafter_combination
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_nextafter_float
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_signbit
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_absolute_negative
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip1
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip2
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip3
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_max_none
+
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_max_none
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_none
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip1
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip2
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip4
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_absolute_negative
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_sign_negative
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_maximum_nan
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_minimum_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fmax_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fmin_nan
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_for_old_numpy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative_for_old_numpy
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf_nan
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_nan
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative_for_old_numpy
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_sign_negative
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_nan_arg
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf_arg
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_broadcast[nan]
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_broadcast[posinf]
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_broadcast[neginf]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_0_{mode='valid'}::test_convolve_empty
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_0_{mode='valid'}::test_convolve_ndim
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_1_{mode='same'}::test_convolve_empty
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_1_{mode='same'}::test_convolve_ndim
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_2_{mode='full'}::test_convolve_empty
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_2_{mode='full'}::test_convolve_ndim
+
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip1
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip3
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_none
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_max_none
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip1
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip2
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip3
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip2
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_cbrt
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fabs
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fabs_negative
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_scalar_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_copy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inplace
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_real_dtypes
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_tol_real_dtypes
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_true
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_false
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_integer_tol_true
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_integer_tol_false
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_float_tol_true
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_float_tol_false
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_period
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_left_right
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_nan_fy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_nan_fx
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_nan_x
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_fy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_fx
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_x
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_size1
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_to_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_heaviside
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_heaviside_nan_inf
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_0_{mode='valid', shape1=(), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_1_{mode='valid', shape1=(), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_2_{mode='valid', shape1=(), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_3_{mode='valid', shape1=(), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_4_{mode='valid', shape1=(), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_5_{mode='valid', shape1=(5,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_6_{mode='valid', shape1=(5,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_7_{mode='valid', shape1=(5,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_8_{mode='valid', shape1=(5,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_9_{mode='valid', shape1=(5,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_10_{mode='valid', shape1=(6,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_11_{mode='valid', shape1=(6,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_12_{mode='valid', shape1=(6,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_13_{mode='valid', shape1=(6,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_14_{mode='valid', shape1=(6,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_15_{mode='valid', shape1=(20,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_16_{mode='valid', shape1=(20,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_17_{mode='valid', shape1=(20,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_18_{mode='valid', shape1=(20,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_19_{mode='valid', shape1=(20,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_20_{mode='valid', shape1=(21,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_21_{mode='valid', shape1=(21,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_22_{mode='valid', shape1=(21,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_23_{mode='valid', shape1=(21,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_24_{mode='valid', shape1=(21,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_25_{mode='same', shape1=(), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_26_{mode='same', shape1=(), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_27_{mode='same', shape1=(), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_28_{mode='same', shape1=(), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_29_{mode='same', shape1=(), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_30_{mode='same', shape1=(5,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_31_{mode='same', shape1=(5,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_32_{mode='same', shape1=(5,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_33_{mode='same', shape1=(5,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_34_{mode='same', shape1=(5,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_35_{mode='same', shape1=(6,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_36_{mode='same', shape1=(6,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_37_{mode='same', shape1=(6,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_38_{mode='same', shape1=(6,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_39_{mode='same', shape1=(6,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_40_{mode='same', shape1=(20,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_41_{mode='same', shape1=(20,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_42_{mode='same', shape1=(20,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_43_{mode='same', shape1=(20,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_44_{mode='same', shape1=(20,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_45_{mode='same', shape1=(21,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_46_{mode='same', shape1=(21,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_47_{mode='same', shape1=(21,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_48_{mode='same', shape1=(21,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_49_{mode='same', shape1=(21,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_50_{mode='full', shape1=(), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_51_{mode='full', shape1=(), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_52_{mode='full', shape1=(), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_53_{mode='full', shape1=(), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_54_{mode='full', shape1=(), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_55_{mode='full', shape1=(5,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_56_{mode='full', shape1=(5,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_57_{mode='full', shape1=(5,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_58_{mode='full', shape1=(5,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_59_{mode='full', shape1=(5,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_60_{mode='full', shape1=(6,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_61_{mode='full', shape1=(6,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_62_{mode='full', shape1=(6,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_63_{mode='full', shape1=(6,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_64_{mode='full', shape1=(6,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_65_{mode='full', shape1=(20,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_66_{mode='full', shape1=(20,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_67_{mode='full', shape1=(20,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_68_{mode='full', shape1=(20,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_69_{mode='full', shape1=(20,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_70_{mode='full', shape1=(21,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_71_{mode='full', shape1=(21,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_72_{mode='full', shape1=(21,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_73_{mode='full', shape1=(21,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_74_{mode='full', shape1=(21,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_non_contiguous[valid]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_non_contiguous[same]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_non_contiguous[full]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_large_non_contiguous[valid]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_large_non_contiguous[same]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_large_non_contiguous[full]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff_types[valid]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff_types[same]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff_types[full]
+
 tests/third_party/cupy/math_tests/test_rounding.py::TestRoundBorder_param_0_{value=(14, -1)}::test_around_negative2
 tests/third_party/cupy/math_tests/test_rounding.py::TestRoundBorder_param_0_{value=(14, -1)}::test_around_positive2
 tests/third_party/cupy/math_tests/test_rounding.py::TestRoundBorder_param_1_{value=(15, -1)}::test_around_negative2
@@ -819,9 +865,13 @@ tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_9
 tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_9_{axis=0, func='nanprod', keepdims=True, shape=(2, 3, 4), transpose_axes=False}::test_nansum_axis_transposed
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_period
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont_and_period
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_axis
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_discont
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_without_axis
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_period
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_discont_and_period
 tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsBeta_param_0_{a_shape=(), b_shape=(), shape=(4, 3, 2)}::test_beta
 tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsBeta_param_1_{a_shape=(), b_shape=(), shape=(3, 2)}::test_beta
 tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsBeta_param_2_{a_shape=(), b_shape=(3, 2), shape=(4, 3, 2)}::test_beta
diff --git a/tests/skipped_tests_gpu.tbl b/tests/skipped_tests_gpu.tbl
index 727d9650bfb..9a44f4cbfce 100644
--- a/tests/skipped_tests_gpu.tbl
+++ b/tests/skipped_tests_gpu.tbl
@@ -40,11 +40,8 @@ tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-sum-data18]
 tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-trapz-data19]
 tests/test_sycl_queue.py::test_1in_1out[level_zero:gpu:0-trunc-data20]
 
-tests/test_sycl_queue.py::test_broadcasting[level_zero:gpu:0-floor_divide-data12-data22]
 tests/test_sycl_queue.py::test_broadcasting[level_zero:gpu:0-remainder-data15-data25]
-tests/test_sycl_queue.py::test_broadcasting[opencl:gpu:0-floor_divide-data12-data22]
 tests/test_sycl_queue.py::test_broadcasting[opencl:gpu:0-remainder-data15-data25]
-tests/test_sycl_queue.py::test_broadcasting[opencl:cpu:0-floor_divide-data12-data22]
 tests/test_sycl_queue.py::test_broadcasting[opencl:cpu:0-remainder-data15-data25]
 
 tests/test_sycl_queue.py::test_modf[level_zero:gpu:0]
@@ -71,19 +68,6 @@ tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesFrom_param_
 tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesFrom_param_1_{shape=(0, 0)}::test_diag_indices_from
 tests/third_party/cupy/indexing_tests/test_insert.py::TestDiagIndicesFrom_param_2_{shape=(2, 2, 2)}::test_diag_indices_from
 
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_295_{arg1=array([[1., 2., 3.],       [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_303_{arg1=array([[1., 2., 3.],       [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int64), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_375_{arg1=array([[1., 2., 3.],       [4., 5., 6.]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_383_{arg1=array([[1., 2., 3.],       [4., 5., 6.]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int64), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_439_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0., 1., 2.],       [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_447_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0., 1., 2.],       [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_455_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_463_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int64), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_519_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int64), arg2=array([[0., 1., 2.],       [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_527_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int64), arg2=array([[0., 1., 2.],       [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_535_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int64), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_543_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int64), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int64), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-
 tests/third_party/cupy/math_tests/test_sumprod.py::TestSumprod::test_external_prod_all
 tests/third_party/cupy/math_tests/test_sumprod.py::TestSumprod::test_external_prod_axis
 tests/third_party/cupy/math_tests/test_sumprod.py::TestSumprod::test_prod_all
@@ -825,55 +809,167 @@ tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_3_{reps
 tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_4_{reps=(2, 3)}::test_array_tile
 tests/third_party/cupy/manipulation_tests/test_tiling.py::TestTile_param_5_{reps=(2, 3, 4, 5)}::test_array_tile
 
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_279_{arg1=array([[1., 2., 3.],       [4., 5., 6.]], dtype=float32), arg2=array([[0., 1., 2.],       [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_287_{arg1=array([[1., 2., 3.],       [4., 5., 6.]], dtype=float32), arg2=array([[0., 1., 2.],       [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_295_{arg1=array([[1., 2., 3.],       [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_303_{arg1=array([[1., 2., 3.],       [4., 5., 6.]], dtype=float32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_359_{arg1=array([[1., 2., 3.],       [4., 5., 6.]]), arg2=array([[0., 1., 2.],       [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_367_{arg1=array([[1., 2., 3.],       [4., 5., 6.]]), arg2=array([[0., 1., 2.],       [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_375_{arg1=array([[1., 2., 3.],       [4., 5., 6.]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_383_{arg1=array([[1., 2., 3.],       [4., 5., 6.]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_439_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0., 1., 2.],       [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_447_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0., 1., 2.],       [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_455_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_463_{arg1=array([[1, 2, 3],       [4, 5, 6]], dtype=int32), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_519_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0., 1., 2.],       [3., 4., 5.]], dtype=float32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_527_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0., 1., 2.],       [3., 4., 5.]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_535_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]], dtype=int32), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticBinary2_param_543_{arg1=array([[1, 2, 3],       [4, 5, 6]]), arg2=array([[0, 1, 2],       [3, 4, 5]]), dtype=float64, name='floor_divide', use_dtype=False}::test_binary
-
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_10_{name='remainder', nargs=2}::test_raises_with_numpy_input
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_11_{name='mod', nargs=2}::test_raises_with_numpy_input
 tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_1_{name='angle', nargs=1}::test_raises_with_numpy_input
-tests/third_party/cupy/math_tests/test_arithmetic.py::TestArithmeticRaisesWithNumpyInput_param_8_{name='floor_divide', nargs=2}::test_raises_with_numpy_input
 
 tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp
 tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp2
+tests/third_party/cupy/math_tests/test_explog.py::TestExplog::test_logaddexp2_infinities
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_copysign_float
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_frexp
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_ldexp
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_nextafter_combination
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_nextafter_float
 tests/third_party/cupy/math_tests/test_floating.py::TestFloating::test_signbit
+
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_max_none
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip4
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_absolute_negative
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_sign_negative
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip1
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip2
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip3
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_max_none
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_max_none
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_none
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip1
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip2
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_maximum_nan
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_minimum_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fmax_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fmin_nan
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_for_old_numpy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative_for_old_numpy
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf_nan
 tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_nan
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative
-tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_negative_for_old_numpy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_nan_arg
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inf_arg
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_broadcast[nan]
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_broadcast[posinf]
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_broadcast[neginf]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_0_{mode='valid'}::test_convolve_empty
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_0_{mode='valid'}::test_convolve_ndim
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_1_{mode='same'}::test_convolve_empty
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_1_{mode='same'}::test_convolve_ndim
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_2_{mode='full'}::test_convolve_empty
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveInvalid_param_2_{mode='full'}::test_convolve_ndim
+
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip1
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip3
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_min_none
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip_max_none
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip1
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip2
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_external_clip3
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_clip2
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_cbrt
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fabs
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_fabs_negative
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_scalar_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_copy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_nan_to_num_inplace
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_real_dtypes
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_tol_real_dtypes
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_true
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_false
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_integer_tol_true
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_integer_tol_false
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_float_tol_true
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_real_if_close_with_float_tol_false
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_period
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_left_right
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_nan_fy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_nan_fx
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_nan_x
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_fy
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_fx
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_x
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_size1
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_interp_inf_to_nan
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_heaviside
+tests/third_party/cupy/math_tests/test_misc.py::TestMisc::test_heaviside_nan_inf
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_0_{mode='valid', shape1=(), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_1_{mode='valid', shape1=(), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_2_{mode='valid', shape1=(), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_3_{mode='valid', shape1=(), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_4_{mode='valid', shape1=(), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_5_{mode='valid', shape1=(5,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_6_{mode='valid', shape1=(5,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_7_{mode='valid', shape1=(5,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_8_{mode='valid', shape1=(5,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_9_{mode='valid', shape1=(5,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_10_{mode='valid', shape1=(6,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_11_{mode='valid', shape1=(6,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_12_{mode='valid', shape1=(6,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_13_{mode='valid', shape1=(6,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_14_{mode='valid', shape1=(6,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_15_{mode='valid', shape1=(20,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_16_{mode='valid', shape1=(20,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_17_{mode='valid', shape1=(20,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_18_{mode='valid', shape1=(20,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_19_{mode='valid', shape1=(20,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_20_{mode='valid', shape1=(21,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_21_{mode='valid', shape1=(21,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_22_{mode='valid', shape1=(21,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_23_{mode='valid', shape1=(21,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_24_{mode='valid', shape1=(21,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_25_{mode='same', shape1=(), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_26_{mode='same', shape1=(), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_27_{mode='same', shape1=(), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_28_{mode='same', shape1=(), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_29_{mode='same', shape1=(), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_30_{mode='same', shape1=(5,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_31_{mode='same', shape1=(5,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_32_{mode='same', shape1=(5,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_33_{mode='same', shape1=(5,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_34_{mode='same', shape1=(5,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_35_{mode='same', shape1=(6,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_36_{mode='same', shape1=(6,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_37_{mode='same', shape1=(6,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_38_{mode='same', shape1=(6,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_39_{mode='same', shape1=(6,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_40_{mode='same', shape1=(20,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_41_{mode='same', shape1=(20,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_42_{mode='same', shape1=(20,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_43_{mode='same', shape1=(20,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_44_{mode='same', shape1=(20,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_45_{mode='same', shape1=(21,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_46_{mode='same', shape1=(21,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_47_{mode='same', shape1=(21,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_48_{mode='same', shape1=(21,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_49_{mode='same', shape1=(21,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_50_{mode='full', shape1=(), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_51_{mode='full', shape1=(), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_52_{mode='full', shape1=(), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_53_{mode='full', shape1=(), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_54_{mode='full', shape1=(), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_55_{mode='full', shape1=(5,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_56_{mode='full', shape1=(5,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_57_{mode='full', shape1=(5,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_58_{mode='full', shape1=(5,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_59_{mode='full', shape1=(5,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_60_{mode='full', shape1=(6,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_61_{mode='full', shape1=(6,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_62_{mode='full', shape1=(6,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_63_{mode='full', shape1=(6,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_64_{mode='full', shape1=(6,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_65_{mode='full', shape1=(20,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_66_{mode='full', shape1=(20,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_67_{mode='full', shape1=(20,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_68_{mode='full', shape1=(20,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_69_{mode='full', shape1=(20,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_70_{mode='full', shape1=(21,), shape2=()}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_71_{mode='full', shape1=(21,), shape2=(5,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_72_{mode='full', shape1=(21,), shape2=(6,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_73_{mode='full', shape1=(21,), shape2=(20,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolveShapeCombination_param_74_{mode='full', shape1=(21,), shape2=(21,)}::test_convolve
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_non_contiguous[valid]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_non_contiguous[same]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_non_contiguous[full]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_large_non_contiguous[valid]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_large_non_contiguous[same]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_large_non_contiguous[full]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff_types[valid]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff_types[same]
+tests/third_party/cupy/math_tests/test_misc.py::TestConvolve::test_convolve_diff_types[full]
+
 tests/third_party/cupy/math_tests/test_rounding.py::TestRoundBorder_param_0_{value=(14, -1)}::test_around_negative2
 tests/third_party/cupy/math_tests/test_rounding.py::TestRoundBorder_param_0_{value=(14, -1)}::test_around_positive2
 tests/third_party/cupy/math_tests/test_rounding.py::TestRoundBorder_param_1_{value=(15, -1)}::test_around_negative2
@@ -947,9 +1043,13 @@ tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_9
 tests/third_party/cupy/math_tests/test_sumprod.py::TestNansumNanprodLong_param_9_{axis=0, func='nanprod', keepdims=True, shape=(2, 3, 4), transpose_axes=False}::test_nansum_axis_transposed
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_period
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_1dim_with_discont_and_period
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_axis
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_discont
 tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_without_axis
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_period
+tests/third_party/cupy/math_tests/test_trigonometric.py::TestUnwrap::test_unwrap_2dim_with_discont_and_period
 tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsBeta_param_0_{a_shape=(), b_shape=(), shape=(4, 3, 2)}::test_beta
 tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsBeta_param_1_{a_shape=(), b_shape=(), shape=(3, 2)}::test_beta
 tests/third_party/cupy/random_tests/test_distributions.py::TestDistributionsBeta_param_2_{a_shape=(), b_shape=(3, 2), shape=(4, 3, 2)}::test_beta
diff --git a/tests/test_extensions.py b/tests/test_extensions.py
new file mode 100644
index 00000000000..a020be77637
--- /dev/null
+++ b/tests/test_extensions.py
@@ -0,0 +1,238 @@
+from itertools import product
+
+import dpctl
+import dpctl.tensor as dpt
+import pytest
+
+import dpnp
+from dpnp.backend.extensions.sycl_ext import _sycl_ext_impl
+
+all_devices = [
+    device for device in dpctl.get_devices() if device.is_cpu or device.is_gpu
+]
+sum_supported_input_dtypes = [
+    dpt.dtype("i1"),
+    dpt.dtype("u1"),
+    dpt.dtype("i2"),
+    dpt.dtype("u2"),
+    dpt.dtype("i4"),
+    dpt.dtype("u4"),
+    dpt.dtype("i8"),
+    dpt.dtype("u8"),
+    dpt.float32,
+    dpt.float64,
+]
+sum_supported_output_dtypes = [
+    dpt.dtype("i4"),
+    dpt.dtype("u4"),
+    dpt.dtype("i8"),
+    dpt.dtype("u8"),
+    dpt.float32,
+    dpt.float64,
+]
+
+mean_supported_output_dtypes = [dpt.float32, dpt.float64]
+sum_without_mean_supported_dtypes = list(
+    set(sum_supported_output_dtypes) - set(mean_supported_output_dtypes)
+)
+
+sum_unsupported_input_dtypes = [
+    dpt.bool,
+    dpt.float16,
+    dpt.complex64,
+    dpt.complex128,
+]
+sum_unsupported_output_dtypes = [
+    dpt.bool,
+    dpt.dtype("i1"),
+    dpt.dtype("u1"),
+    dpt.dtype("i2"),
+    dpt.dtype("u2"),
+    dpt.float16,
+    dpt.complex64,
+    dpt.complex128,
+]
+
+mean_unsupported_output_dtypes = [
+    dpt.bool,
+    dpt.dtype("i1"),
+    dpt.dtype("u1"),
+    dpt.dtype("i2"),
+    dpt.dtype("u2"),
+    dpt.dtype("i4"),
+    dpt.dtype("u4"),
+    dpt.dtype("i8"),
+    dpt.dtype("u8"),
+    dpt.float16,
+    dpt.complex64,
+    dpt.complex128,
+]
+
+
+sum_only = [_sycl_ext_impl._get_sum_over_axis_0]
+mean_only = [_sycl_ext_impl._get_mean_over_axis_0]
+mean_sum = sum_only + mean_only
+
+
+def supported_by_device(device, typ):
+    if typ == dpt.float64 or typ == dpt.complex128:
+        return device.has_aspect_fp64
+
+    if typ == dpt.float16:
+        return device.has_aspect_fp16
+
+    return True
+
+
+def skip_unsupported(device, typ):
+    if not supported_by_device(device, typ):
+        pytest.skip(f"{typ} type is not supported by {device}")
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(
+        mean_sum,
+        all_devices,
+        sum_supported_input_dtypes,
+        mean_supported_output_dtypes,
+    ),
+)
+def test_mean_sum_over_axis_0_supported_types(
+    func, device, input_type, output_type
+):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 20
+    width = 10
+
+    input = dpt.empty((height, width), dtype=input_type, device=device)
+    output = dpt.empty(width, dtype=output_type, device=device)
+
+    assert func(input, output) is not None
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(
+        sum_only,
+        all_devices,
+        sum_supported_input_dtypes,
+        sum_without_mean_supported_dtypes,
+    ),
+)
+def test_sum_over_axis_0_supported_types(func, device, input_type, output_type):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 20
+    width = 10
+
+    input = dpt.empty((height, width), dtype=input_type, device=device)
+    output = dpt.empty(width, dtype=output_type, device=device)
+
+    assert func(input, output) is not None
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(mean_sum, all_devices, sum_unsupported_input_dtypes, [dpt.float32]),
+)
+def test_mean_sum_over_axis_0_unsupported_in_types(
+    func, device, input_type, output_type
+):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 1
+    width = 1
+
+    input = dpt.empty((height, width), dtype=input_type, device=device)
+    output = dpt.empty(width, dtype=output_type, device=device)
+
+    assert func(input, output) is None
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(
+        sum_only, all_devices, [dpt.float32], sum_unsupported_output_dtypes
+    ),
+)
+def test_sum_over_axis_0_unsupported_out_types(
+    func, device, input_type, output_type
+):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 1
+    width = 1
+
+    input = dpt.empty((height, width), dtype=input_type, device=device)
+    output = dpt.empty(width, dtype=output_type, device=device)
+
+    assert func(input, output) is None
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(
+        mean_only, all_devices, [dpt.float32], mean_unsupported_output_dtypes
+    ),
+)
+def test_mean_over_axis_0_unsupported_out_types(
+    func, device, input_type, output_type
+):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 1
+    width = 1
+
+    input = dpt.empty((height, width), dtype=input_type, device=device)
+    output = dpt.empty(width, dtype=output_type, device=device)
+
+    if func(input, output):
+        print(output_type)
+    assert func(input, output) is None
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(mean_sum, all_devices, [dpt.float32], [dpt.float32]),
+)
+def test_mean_over_axis_0_f_contig_input(func, device, input_type, output_type):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 20
+    width = 10
+
+    input = dpt.empty((height, width), dtype=input_type, device=device).T
+    output = dpt.empty(width, dtype=output_type, device=device)
+
+    if func(input, output):
+        print(output_type)
+    assert func(input, output) is None
+
+
+@pytest.mark.parametrize(
+    "func, device, input_type, output_type",
+    product(mean_sum, all_devices, [dpt.float32], [dpt.float32]),
+)
+def test_mean_over_axis_0_f_contig_output(
+    func, device, input_type, output_type
+):
+    skip_unsupported(device, input_type)
+    skip_unsupported(device, output_type)
+
+    height = 1
+    width = 10
+
+    input = dpt.empty((height, 10), dtype=input_type, device=device)
+    output = dpt.empty(20, dtype=output_type, device=device)[::2]
+
+    if func(input, output):
+        print(output_type)
+    assert func(input, output) is None
diff --git a/tests/test_histograms.py b/tests/test_histograms.py
index eeb8cbf563f..b62f653b0c9 100644
--- a/tests/test_histograms.py
+++ b/tests/test_histograms.py
@@ -15,12 +15,12 @@ def teardown(self):
     def test_simple(self):
         n = 100
         v = dpnp.random.rand(n)
-        (a, b) = dpnp.histogram(v)
+        a, _ = dpnp.histogram(v)
         # check if the sum of the bins equals the number of samples
         numpy.testing.assert_equal(dpnp.sum(a, axis=0), n)
         # check that the bin counts are evenly spaced when the data is from
         # a linear function
-        (a, b) = dpnp.histogram(numpy.linspace(0, 10, 100))
+        a, _ = dpnp.histogram(dpnp.linspace(0, 10, 100))
         numpy.testing.assert_array_equal(a, 10)
 
     @pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -67,7 +67,7 @@ def test_density(self):
 
         # Taken from a bug report from N. Becker on the numpy-discussion
         # mailing list Aug. 6, 2010.
-        counts, dmy = dpnp.histogram(
+        counts, _ = dpnp.histogram(
             [1, 2, 3, 4], [0.5, 1.5, numpy.inf], density=True
         )
         numpy.testing.assert_equal(counts, [0.25, 0])
diff --git a/tests/test_linalg.py b/tests/test_linalg.py
index 6adeabc5980..2327ca2e940 100644
--- a/tests/test_linalg.py
+++ b/tests/test_linalg.py
@@ -5,7 +5,7 @@
 
 import dpnp as inp
 
-from .helper import get_all_dtypes, get_complex_dtypes
+from .helper import get_all_dtypes, get_complex_dtypes, has_support_aspect64
 
 
 def vvsort(val, vec, size, xp):
@@ -109,15 +109,9 @@ def test_det(array):
     assert_allclose(expected, result)
 
 
-@pytest.mark.usefixtures("allow_fall_back_on_numpy")
 @pytest.mark.parametrize("type", get_all_dtypes(no_bool=True, no_complex=True))
 @pytest.mark.parametrize("size", [2, 4, 8, 16, 300])
 def test_eig_arange(type, size):
-    if dpctl.get_current_device_type() != dpctl.device_type.gpu:
-        pytest.skip(
-            "eig function doesn't work on CPU: https://github.com/IntelPython/dpnp/issues/1005"
-        )
-
     a = numpy.arange(size * size, dtype=type).reshape((size, size))
     symm_orig = (
         numpy.tril(a)
@@ -145,8 +139,9 @@ def test_eig_arange(type, size):
     assert_array_equal(symm_orig, symm)
     assert_array_equal(dpnp_symm_orig, dpnp_symm)
 
-    assert dpnp_val.dtype == np_val.dtype
-    assert dpnp_vec.dtype == np_vec.dtype
+    if has_support_aspect64():
+        assert dpnp_val.dtype == np_val.dtype
+        assert dpnp_vec.dtype == np_vec.dtype
     assert dpnp_val.shape == np_val.shape
     assert dpnp_vec.shape == np_vec.shape
     assert dpnp_val.usm_type == dpnp_symm.usm_type
@@ -156,10 +151,13 @@ def test_eig_arange(type, size):
     assert_allclose(dpnp_vec, np_vec, rtol=1e-05, atol=1e-05)
 
 
-@pytest.mark.usefixtures("allow_fall_back_on_numpy")
 @pytest.mark.parametrize("type", get_all_dtypes(no_bool=True, no_none=True))
 @pytest.mark.parametrize("size", [2, 4, 8])
 def test_eigh_arange(type, size):
+    if dpctl.get_current_device_type() != dpctl.device_type.gpu:
+        pytest.skip(
+            "eig function doesn't work on CPU: https://github.com/IntelPython/dpnp/issues/1005"
+        )
     a = numpy.arange(size * size, dtype=type).reshape((size, size))
     symm_orig = (
         numpy.tril(a)
@@ -202,7 +200,6 @@ def test_eigvals(type):
         pytest.skip(
             "eigvals function doesn't work on CPU: https://github.com/IntelPython/dpnp/issues/1005"
         )
-
     arrays = [[[0, 0], [0, 0]], [[1, 2], [1, 2]], [[1, 2], [3, 4]]]
     for array in arrays:
         a = numpy.array(array, dtype=type)
@@ -223,7 +220,7 @@ def test_inv(type, array):
     ia = inp.array(a)
     result = inp.linalg.inv(ia)
     expected = numpy.linalg.inv(a)
-    assert_allclose(expected, result)
+    assert_allclose(expected, result, rtol=1e-06)
 
 
 @pytest.mark.parametrize(
@@ -305,7 +302,7 @@ def test_norm2(array, ord, axis):
     ia = inp.array(a)
     result = inp.linalg.norm(ia, ord=ord, axis=axis)
     expected = numpy.linalg.norm(a, ord=ord, axis=axis)
-    assert_array_equal(expected, result)
+    assert_allclose(expected, result)
 
 
 @pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -335,7 +332,7 @@ def test_norm3(array, ord, axis):
     ia = inp.array(a)
     result = inp.linalg.norm(ia, ord=ord, axis=axis)
     expected = numpy.linalg.norm(a, ord=ord, axis=axis)
-    assert_array_equal(expected, result)
+    assert_allclose(expected, result)
 
 
 @pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -355,15 +352,19 @@ def test_qr(type, shape, mode):
     np_q, np_r = numpy.linalg.qr(a, mode)
     dpnp_q, dpnp_r = inp.linalg.qr(ia, mode)
 
-    assert dpnp_q.dtype == np_q.dtype
-    assert dpnp_r.dtype == np_r.dtype
+    support_aspect64 = has_support_aspect64()
+
+    if support_aspect64:
+        assert dpnp_q.dtype == np_q.dtype
+        assert dpnp_r.dtype == np_r.dtype
     assert dpnp_q.shape == np_q.shape
     assert dpnp_r.shape == np_r.shape
 
-    if type == numpy.float32:
+    tol = 1e-6
+    if type == inp.float32:
+        tol = 1e-02
+    elif not support_aspect64 and type in (inp.int32, inp.int64, None):
         tol = 1e-02
-    else:
-        tol = 1e-11
 
     # check decomposition
     assert_allclose(
@@ -402,17 +403,21 @@ def test_svd(type, shape):
     np_u, np_s, np_vt = numpy.linalg.svd(a)
     dpnp_u, dpnp_s, dpnp_vt = inp.linalg.svd(ia)
 
-    assert dpnp_u.dtype == np_u.dtype
-    assert dpnp_s.dtype == np_s.dtype
-    assert dpnp_vt.dtype == np_vt.dtype
+    support_aspect64 = has_support_aspect64()
+
+    if support_aspect64:
+        assert dpnp_u.dtype == np_u.dtype
+        assert dpnp_s.dtype == np_s.dtype
+        assert dpnp_vt.dtype == np_vt.dtype
     assert dpnp_u.shape == np_u.shape
     assert dpnp_s.shape == np_s.shape
     assert dpnp_vt.shape == np_vt.shape
 
-    if type == numpy.float32:
+    tol = 1e-12
+    if type == inp.float32:
+        tol = 1e-03
+    elif not support_aspect64 and type in (inp.int32, inp.int64, None):
         tol = 1e-03
-    else:
-        tol = 1e-12
 
     # check decomposition
     dpnp_diag_s = inp.zeros(shape, dtype=dpnp_s.dtype)
diff --git a/tests/test_mathematical.py b/tests/test_mathematical.py
index 344d5698185..873a134a9c1 100644
--- a/tests/test_mathematical.py
+++ b/tests/test_mathematical.py
@@ -164,11 +164,12 @@ def test_divide(self, dtype, lhs, rhs):
     def test_fmod(self, dtype, lhs, rhs):
         self._test_mathematical("fmod", dtype, lhs, rhs)
 
-    @pytest.mark.usefixtures("allow_fall_back_on_numpy")
-    @pytest.mark.parametrize(
-        "dtype", get_all_dtypes(no_bool=True, no_complex=True)
-    )
+    @pytest.mark.parametrize("dtype", get_all_dtypes(no_complex=True))
     def test_floor_divide(self, dtype, lhs, rhs):
+        if dtype == dpnp.float32 and rhs == 0.3:
+            pytest.skip(
+                "In this case, a different result, but similar to xp.floor(xp.divide(lhs, rhs)."
+            )
         self._test_mathematical("floor_divide", dtype, lhs, rhs)
 
     @pytest.mark.usefixtures("allow_fall_back_on_numpy")
diff --git a/tests/test_random_state.py b/tests/test_random_state.py
index 5b3c937ac18..f6be26202fb 100644
--- a/tests/test_random_state.py
+++ b/tests/test_random_state.py
@@ -12,6 +12,7 @@
 )
 
 import dpnp
+from dpnp.dpnp_array import dpnp_array
 from dpnp.random import RandomState
 
 from .helper import is_cpu_device
@@ -547,6 +548,9 @@ def test_zero_size(self, zero_size):
         ids=["[2]", "dpnp.array([2])", "numpy.array([2])"],
     )
     def test_bounds_fallback(self, low, high):
+        if isinstance(high, dpnp_array) and high.dtype == numpy.int32:
+            pytest.skip("NumPy fails: 'high' is out of bounds for int32")
+
         seed = 15
         size = (3, 2, 5)
 
diff --git a/tests/test_umath.py b/tests/test_umath.py
index 8f844baa198..7d8bb4acfe5 100644
--- a/tests/test_umath.py
+++ b/tests/test_umath.py
@@ -1,10 +1,19 @@
 import numpy
 import pytest
-from numpy.testing import assert_allclose, assert_array_equal
+from numpy.testing import (
+    assert_allclose,
+    assert_array_almost_equal,
+    assert_array_equal,
+)
 
 import dpnp
 
-from .helper import get_all_dtypes, get_float_dtypes
+from .helper import (
+    get_all_dtypes,
+    get_complex_dtypes,
+    has_support_aspect16,
+    has_support_aspect64,
+)
 
 # full list of umaths
 umaths = [i for i in dir(numpy) if isinstance(getattr(numpy, i), numpy.ufunc)]
@@ -92,20 +101,64 @@ def test_umaths(test_cases):
 
 
 class TestSin:
-    def test_sin_ordinary(self):
-        array_data = numpy.arange(10)
-        out = numpy.empty(10, dtype=numpy.float64)
+    @pytest.mark.parametrize(
+        "dtype", get_all_dtypes(no_bool=True, no_complex=True)
+    )
+    def test_sin(self, dtype):
+        np_array = numpy.arange(10, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.float64)
 
         # DPNP
-        dp_array = dpnp.array(array_data, dtype=dpnp.float64)
-        dp_out = dpnp.array(out, dtype=dpnp.float64)
+        dp_out_dtype = dpnp.float32
+        if has_support_aspect64() and dtype != dpnp.float32:
+            dp_out_dtype = dpnp.float64
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
         result = dpnp.sin(dp_array, out=dp_out)
 
         # original
-        np_array = numpy.array(array_data, dtype=numpy.float64)
-        expected = numpy.sin(np_array, out=out)
+        expected = numpy.sin(np_array, out=np_out)
 
-        assert_array_equal(expected, result)
+        precision = numpy.finfo(dtype=result.dtype).precision
+        assert_array_almost_equal(expected, result.asnumpy(), decimal=precision)
+
+    @pytest.mark.parametrize("dtype", get_complex_dtypes())
+    def test_sin_complex(self, dtype):
+        np_array = numpy.arange(10, 20, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.complex128)
+
+        # DPNP
+        dp_out_dtype = dpnp.complex64
+        if has_support_aspect64() and dtype != dpnp.complex64:
+            dp_out_dtype = dpnp.complex128
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
+        result = dpnp.sin(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.sin(np_array, out=np_out)
+
+        precision = numpy.finfo(dtype=result.dtype).precision
+        assert_array_almost_equal(expected, result.asnumpy(), decimal=precision)
+
+    @pytest.mark.usefixtures("suppress_divide_numpy_warnings")
+    @pytest.mark.skipif(
+        not has_support_aspect16(), reason="No fp16 support by device"
+    )
+    def test_sin_bool(self):
+        np_array = numpy.arange(2, dtype=numpy.bool_)
+        np_out = numpy.empty(2, dtype=numpy.float16)
+
+        # DPNP
+        dp_array = dpnp.array(np_array, dtype=np_array.dtype)
+        dp_out = dpnp.array(np_out, dtype=np_out.dtype)
+        result = dpnp.sin(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.sin(np_array, out=np_out)
+        assert_allclose(expected, result)
 
     @pytest.mark.parametrize(
         "dtype",
@@ -113,38 +166,82 @@ def test_sin_ordinary(self):
         ids=["numpy.float32", "numpy.int64", "numpy.int32"],
     )
     def test_invalid_dtype(self, dtype):
-        dp_array = dpnp.arange(10, dtype=dpnp.float64)
+        dp_array = dpnp.arange(10, dtype=dpnp.complex64)
         dp_out = dpnp.empty(10, dtype=dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.sin(dp_array, out=dp_out)
 
     @pytest.mark.parametrize(
         "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
     )
     def test_invalid_shape(self, shape):
-        dp_array = dpnp.arange(10, dtype=dpnp.float64)
-        dp_out = dpnp.empty(shape, dtype=dpnp.float64)
+        dp_array = dpnp.arange(10)
+        dp_out = dpnp.empty(shape, dtype=dp_array.dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.sin(dp_array, out=dp_out)
 
 
 class TestCos:
-    def test_cos(self):
-        array_data = numpy.arange(10)
-        out = numpy.empty(10, dtype=numpy.float64)
+    @pytest.mark.parametrize(
+        "dtype", get_all_dtypes(no_bool=True, no_complex=True)
+    )
+    def test_cos(self, dtype):
+        np_array = numpy.arange(10, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.float64)
 
         # DPNP
-        dp_array = dpnp.array(array_data, dtype=dpnp.float64)
-        dp_out = dpnp.array(out, dtype=dpnp.float64)
+        dp_out_dtype = dpnp.float32
+        if has_support_aspect64() and dtype != dpnp.float32:
+            dp_out_dtype = dpnp.float64
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
         result = dpnp.cos(dp_array, out=dp_out)
 
         # original
-        np_array = numpy.array(array_data, dtype=numpy.float64)
-        expected = numpy.cos(np_array, out=out)
+        expected = numpy.cos(np_array, out=np_out)
 
-        assert_array_equal(expected, result)
+        precision = numpy.finfo(dtype=result.dtype).precision
+        assert_array_almost_equal(expected, result.asnumpy(), decimal=precision)
+
+    @pytest.mark.parametrize("dtype", get_complex_dtypes())
+    def test_cos_complex(self, dtype):
+        np_array = numpy.arange(10, 20, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.complex128)
+
+        # DPNP
+        dp_out_dtype = dpnp.complex64
+        if has_support_aspect64() and dtype != dpnp.complex64:
+            dp_out_dtype = dpnp.complex128
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
+        result = dpnp.cos(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.cos(np_array, out=np_out)
+
+        precision = numpy.finfo(dtype=result.dtype).precision
+        assert_array_almost_equal(expected, result.asnumpy(), decimal=precision)
+
+    @pytest.mark.usefixtures("suppress_divide_numpy_warnings")
+    @pytest.mark.skipif(
+        not has_support_aspect16(), reason="No fp16 support by device"
+    )
+    def test_cos_bool(self):
+        np_array = numpy.arange(2, dtype=numpy.bool_)
+        np_out = numpy.empty(2, dtype=numpy.float16)
+
+        # DPNP
+        dp_array = dpnp.array(np_array, dtype=np_array.dtype)
+        dp_out = dpnp.array(np_out, dtype=np_out.dtype)
+        result = dpnp.cos(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.cos(np_array, out=np_out)
+        assert_allclose(expected, result)
 
     @pytest.mark.parametrize(
         "dtype",
@@ -152,38 +249,82 @@ def test_cos(self):
         ids=["numpy.float32", "numpy.int64", "numpy.int32"],
     )
     def test_invalid_dtype(self, dtype):
-        dp_array = dpnp.arange(10, dtype=dpnp.float64)
+        dp_array = dpnp.arange(10, dtype=dpnp.complex64)
         dp_out = dpnp.empty(10, dtype=dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.cos(dp_array, out=dp_out)
 
     @pytest.mark.parametrize(
         "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
     )
     def test_invalid_shape(self, shape):
-        dp_array = dpnp.arange(10, dtype=dpnp.float64)
-        dp_out = dpnp.empty(shape, dtype=dpnp.float64)
+        dp_array = dpnp.arange(10)
+        dp_out = dpnp.empty(shape, dtype=dp_array.dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.cos(dp_array, out=dp_out)
 
 
 class TestsLog:
-    def test_log(self):
-        array_data = numpy.arange(10)
-        out = numpy.empty(10, dtype=numpy.float64)
+    @pytest.mark.parametrize(
+        "dtype", get_all_dtypes(no_bool=True, no_complex=True)
+    )
+    def test_log(self, dtype):
+        np_array = numpy.arange(10, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.float64)
 
         # DPNP
-        dp_array = dpnp.array(array_data, dtype=dpnp.float64)
-        dp_out = dpnp.array(out, dtype=dpnp.float64)
+        dp_out_dtype = dpnp.float32
+        if has_support_aspect64() and dtype != dpnp.float32:
+            dp_out_dtype = dpnp.float64
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
         result = dpnp.log(dp_array, out=dp_out)
 
         # original
-        np_array = numpy.array(array_data, dtype=numpy.float64)
-        expected = numpy.log(np_array, out=out)
+        expected = numpy.log(np_array, out=np_out)
 
-        assert_array_equal(expected, result)
+        precision = numpy.finfo(dtype=result.dtype).precision
+        assert_array_almost_equal(expected, result.asnumpy(), decimal=precision)
+
+    @pytest.mark.parametrize("dtype", get_complex_dtypes())
+    def test_log_complex(self, dtype):
+        np_array = numpy.arange(10, 20, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.complex128)
+
+        # DPNP
+        dp_out_dtype = dpnp.complex64
+        if has_support_aspect64() and dtype != dpnp.complex64:
+            dp_out_dtype = dpnp.complex128
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
+        result = dpnp.log(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.log(np_array, out=np_out)
+
+        precision = numpy.finfo(dtype=result.dtype).precision
+        assert_array_almost_equal(expected, result.asnumpy(), decimal=precision)
+
+    @pytest.mark.usefixtures("suppress_divide_numpy_warnings")
+    @pytest.mark.skipif(
+        not has_support_aspect16(), reason="No fp16 support by device"
+    )
+    def test_log_bool(self):
+        np_array = numpy.arange(2, dtype=numpy.bool_)
+        np_out = numpy.empty(2, dtype=numpy.float16)
+
+        # DPNP
+        dp_array = dpnp.array(np_array, dtype=np_array.dtype)
+        dp_out = dpnp.array(np_out, dtype=np_out.dtype)
+        result = dpnp.log(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.log(np_array, out=np_out)
+        assert_allclose(expected, result)
 
     @pytest.mark.parametrize(
         "dtype",
@@ -191,20 +332,20 @@ def test_log(self):
         ids=["numpy.float32", "numpy.int64", "numpy.int32"],
     )
     def test_invalid_dtype(self, dtype):
-        dp_array = dpnp.arange(10, dtype=dpnp.float64)
+        dp_array = dpnp.arange(10, dtype=dpnp.complex64)
         dp_out = dpnp.empty(10, dtype=dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.log(dp_array, out=dp_out)
 
     @pytest.mark.parametrize(
         "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
     )
     def test_invalid_shape(self, shape):
-        dp_array = dpnp.arange(10, dtype=dpnp.float64)
-        dp_out = dpnp.empty(shape, dtype=dpnp.float64)
+        dp_array = dpnp.arange(10)
+        dp_out = dpnp.empty(shape, dtype=dp_array.dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.log(dp_array, out=dp_out)
 
 
@@ -408,22 +549,60 @@ def test_invalid_shape(self, shape):
 
 
 class TestSqrt:
-    @pytest.mark.parametrize("dtype", get_float_dtypes())
-    def test_sqrt_ordinary(self, dtype):
-        array_data = numpy.arange(10)
-        out = numpy.empty(10, dtype=dtype)
+    @pytest.mark.parametrize(
+        "dtype", get_all_dtypes(no_bool=True, no_complex=True)
+    )
+    def test_sqrt_int_float(self, dtype):
+        np_array = numpy.arange(10, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.float64)
 
         # DPNP
-        dp_array = dpnp.array(array_data, dtype=dtype)
-        dp_out = dpnp.array(out, dtype=dtype)
+        dp_out_dtype = dpnp.float32
+        if has_support_aspect64() and dtype != dpnp.float32:
+            dp_out_dtype = dpnp.float64
+
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
         result = dpnp.sqrt(dp_array, out=dp_out)
 
         # original
-        np_array = numpy.array(array_data, dtype=dtype)
-        expected = numpy.sqrt(np_array, out=out)
+        expected = numpy.sqrt(np_array, out=np_out)
+        assert_allclose(expected, result)
+
+    @pytest.mark.parametrize("dtype", get_complex_dtypes())
+    def test_sqrt_complex(self, dtype):
+        np_array = numpy.arange(10, 20, dtype=dtype)
+        np_out = numpy.empty(10, dtype=numpy.complex128)
+
+        # DPNP
+        dp_out_dtype = dpnp.complex64
+        if has_support_aspect64() and dtype != dpnp.complex64:
+            dp_out_dtype = dpnp.complex128
 
-        numpy.testing.assert_allclose(expected, result)
-        numpy.testing.assert_allclose(out, dp_out)
+        dp_out = dpnp.array(np_out, dtype=dp_out_dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
+        result = dpnp.sqrt(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.sqrt(np_array, out=np_out)
+        assert_allclose(expected, result)
+
+    @pytest.mark.usefixtures("suppress_divide_numpy_warnings")
+    @pytest.mark.skipif(
+        not has_support_aspect16(), reason="No fp16 support by device"
+    )
+    def test_sqrt_bool(self):
+        np_array = numpy.arange(2, dtype=numpy.bool_)
+        np_out = numpy.empty(2, dtype=numpy.float16)
+
+        # DPNP
+        dp_array = dpnp.array(np_array, dtype=np_array.dtype)
+        dp_out = dpnp.array(np_out, dtype=np_out.dtype)
+        result = dpnp.sqrt(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.sqrt(np_array, out=np_out)
+        assert_allclose(expected, result)
 
     @pytest.mark.parametrize(
         "dtype", [numpy.int64, numpy.int32], ids=["numpy.int64", "numpy.int32"]
@@ -432,7 +611,7 @@ def test_invalid_dtype(self, dtype):
         dp_array = dpnp.arange(10, dtype=dpnp.float32)
         dp_out = dpnp.empty(10, dtype=dtype)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.sqrt(dp_array, out=dp_out)
 
     @pytest.mark.parametrize(
@@ -442,7 +621,7 @@ def test_invalid_shape(self, shape):
         dp_array = dpnp.arange(10, dtype=dpnp.float32)
         dp_out = dpnp.empty(shape, dtype=dpnp.float32)
 
-        with pytest.raises(ValueError):
+        with pytest.raises(TypeError):
             dpnp.sqrt(dp_array, out=dp_out)
 
     @pytest.mark.parametrize(
@@ -455,3 +634,65 @@ def test_invalid_out(self, out):
 
         numpy.testing.assert_raises(TypeError, dpnp.sqrt, a, out)
         numpy.testing.assert_raises(TypeError, numpy.sqrt, a.asnumpy(), out)
+
+
+class TestSquare:
+    @pytest.mark.parametrize(
+        "dtype", get_all_dtypes(no_bool=True, no_none=True)
+    )
+    def test_square(self, dtype):
+        np_array = numpy.arange(10, dtype=dtype)
+        np_out = numpy.empty(10, dtype=dtype)
+
+        # DPNP
+        dp_out = dpnp.array(np_out, dtype=dtype)
+        dp_array = dpnp.array(np_array, dtype=dtype)
+        result = dpnp.square(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.square(np_array, out=np_out)
+        assert_allclose(expected, result)
+
+    def test_square_bool(self):
+        np_array = numpy.arange(2, dtype=numpy.bool_)
+        np_out = numpy.empty(2, dtype=numpy.int8)
+
+        # DPNP
+        dp_array = dpnp.array(np_array, dtype=np_array.dtype)
+        dp_out = dpnp.array(np_out, dtype=np_out.dtype)
+        result = dpnp.square(dp_array, out=dp_out)
+
+        # original
+        expected = numpy.square(np_array, out=np_out)
+        assert_allclose(expected, result)
+
+    @pytest.mark.parametrize(
+        "dtype", get_all_dtypes(no_bool=True, no_none=True)
+    )
+    def test_invalid_dtype(self, dtype):
+        dp_array = dpnp.ones(10, dtype=dpnp.bool)
+        dp_out = dpnp.empty(10, dtype=dtype)
+
+        with pytest.raises(TypeError):
+            dpnp.square(dp_array, out=dp_out)
+
+    @pytest.mark.parametrize(
+        "shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
+    )
+    def test_invalid_shape(self, shape):
+        dp_array = dpnp.arange(10, dtype=dpnp.float32)
+        dp_out = dpnp.empty(shape, dtype=dpnp.float32)
+
+        with pytest.raises(TypeError):
+            dpnp.square(dp_array, out=dp_out)
+
+    @pytest.mark.parametrize(
+        "out",
+        [4, (), [], (3, 7), [2, 4]],
+        ids=["4", "()", "[]", "(3, 7)", "[2, 4]"],
+    )
+    def test_invalid_out(self, out):
+        a = dpnp.arange(10)
+
+        numpy.testing.assert_raises(TypeError, dpnp.square, a, out)
+        numpy.testing.assert_raises(TypeError, numpy.square, a.asnumpy(), out)
diff --git a/tests/third_party/cupy/logic_tests/test_ops.py b/tests/third_party/cupy/logic_tests/test_ops.py
index 400a7993fe4..ab2b97a6246 100644
--- a/tests/third_party/cupy/logic_tests/test_ops.py
+++ b/tests/third_party/cupy/logic_tests/test_ops.py
@@ -1,11 +1,8 @@
 import unittest
 
-import pytest
-
 from tests.third_party.cupy import testing
 
 
-@testing.gpu
 class TestOps(unittest.TestCase):
     @testing.for_all_dtypes(no_complex=True)
     @testing.numpy_cupy_allclose(atol=1e-5)
diff --git a/tests/third_party/cupy/math_tests/test_explog.py b/tests/third_party/cupy/math_tests/test_explog.py
index adc6c1a8735..9d68b125a1d 100644
--- a/tests/third_party/cupy/math_tests/test_explog.py
+++ b/tests/third_party/cupy/math_tests/test_explog.py
@@ -1,11 +1,11 @@
 import unittest
 
 import numpy
+import pytest
 
 from tests.third_party.cupy import testing
 
 
-@testing.gpu
 class TestExplog(unittest.TestCase):
     @testing.for_all_dtypes()
     @testing.numpy_cupy_allclose(atol=1e-5)
@@ -55,3 +55,10 @@ def test_logaddexp(self):
 
     def test_logaddexp2(self):
         self.check_binary("logaddexp2", no_complex=True)
+
+    @pytest.mark.parametrize("val", [numpy.inf, -numpy.inf])
+    @testing.for_float_dtypes()
+    @testing.numpy_cupy_allclose()
+    def test_logaddexp2_infinities(self, xp, dtype, val):
+        a = xp.full((2, 3), val, dtype=dtype)
+        return xp.logaddexp2(a, a)
diff --git a/tests/third_party/cupy/math_tests/test_misc.py b/tests/third_party/cupy/math_tests/test_misc.py
index 545712c7547..9ae4ad058e2 100644
--- a/tests/third_party/cupy/math_tests/test_misc.py
+++ b/tests/third_party/cupy/math_tests/test_misc.py
@@ -1,6 +1,3 @@
-import sys
-import unittest
-
 import numpy
 import pytest
 
@@ -8,10 +5,9 @@
 from tests.third_party.cupy import testing
 
 
-@testing.gpu
-class TestMisc(unittest.TestCase):
+class TestMisc:
     @testing.for_all_dtypes()
-    @testing.numpy_cupy_allclose(atol=1e-5)
+    @testing.numpy_cupy_allclose(atol=1e-5, type_check=False)
     def check_unary(self, name, xp, dtype, no_bool=False):
         if no_bool and numpy.dtype(dtype).char == "?":
             return numpy.int_(0)
@@ -27,7 +23,7 @@ def check_binary(self, name, xp, dtype, no_bool=False):
         b = testing.shaped_reverse_arange((2, 3), xp, dtype)
         return getattr(xp, name)(a, b)
 
-    @testing.for_dtypes(["i", "q", "f", "d"])
+    @testing.for_dtypes(["?", "b", "h", "i", "q", "e", "f", "d", "F", "D"])
     @testing.numpy_cupy_allclose(atol=1e-5)
     def check_unary_negative(self, name, xp, dtype, no_bool=False):
         if no_bool and numpy.dtype(dtype).char == "?":
@@ -37,9 +33,9 @@ def check_unary_negative(self, name, xp, dtype, no_bool=False):
             a += (a * 1j).astype(dtype)
         return getattr(xp, name)(a)
 
-    @testing.for_dtypes(["f", "d"])
+    @testing.for_dtypes(["e", "f", "d", "F", "D"])
     @testing.numpy_cupy_allclose(atol=1e-5)
-    def check_unary_inf(self, name, xp, dtype):
+    def check_unary_inf(self, name, xp, dtype, **kwargs):
         inf = numpy.inf
         if numpy.dtype(dtype).kind != "c":
             a = xp.array([0, -1, 1, -inf, inf], dtype=dtype)
@@ -52,11 +48,11 @@ def check_unary_inf(self, name, xp, dtype):
                 ],
                 dtype=dtype,
             )
-        return getattr(xp, name)(a)
+        return getattr(xp, name)(a, **kwargs)
 
-    @testing.for_dtypes(["f", "d"])
+    @testing.for_dtypes(["e", "f", "d", "F", "D"])
     @testing.numpy_cupy_allclose(atol=1e-5)
-    def check_unary_nan(self, name, xp, dtype):
+    def check_unary_nan(self, name, xp, dtype, **kwargs):
         nan = numpy.nan
         if numpy.dtype(dtype).kind != "c":
             a = xp.array([0, -1, 1, -nan, nan], dtype=dtype)
@@ -69,9 +65,9 @@ def check_unary_nan(self, name, xp, dtype):
                 ],
                 dtype=dtype,
             )
-        return getattr(xp, name)(a)
+        return getattr(xp, name)(a, **kwargs)
 
-    @testing.for_dtypes(["f", "d"])
+    @testing.for_dtypes(["e", "f", "d", "F", "D"])
     @testing.numpy_cupy_allclose(atol=1e-5)
     def check_unary_inf_nan(self, name, xp, dtype):
         inf = numpy.inf
@@ -89,7 +85,7 @@ def check_unary_inf_nan(self, name, xp, dtype):
             )
         return getattr(xp, name)(a)
 
-    @testing.for_dtypes(["f", "d"])
+    @testing.for_dtypes(["e", "f", "d", "F", "D"])
     @testing.numpy_cupy_array_equal()
     def check_binary_nan(self, name, xp, dtype):
         a = xp.array(
@@ -100,7 +96,6 @@ def check_binary_nan(self, name, xp, dtype):
         )
         return getattr(xp, name)(a, b)
 
-    @unittest.skipIf(sys.platform == "win32", "dtype problem on Windows")
     @testing.for_all_dtypes(no_complex=True)
     @testing.numpy_cupy_array_equal()
     def test_clip1(self, xp, dtype):
@@ -132,7 +127,6 @@ def test_clip_min_max_none(self, dtype):
             with pytest.raises(ValueError):
                 a.clip(None, None)
 
-    @unittest.skipIf(sys.platform == "win32", "dtype problem on Windows")
     @testing.for_all_dtypes(no_complex=True)
     @testing.numpy_cupy_array_equal()
     def test_external_clip1(self, xp, dtype):
@@ -145,6 +139,19 @@ def test_external_clip2(self, xp, dtype):
         a = testing.shaped_arange((2, 3, 4), xp, dtype)
         return xp.clip(a, 3, 13)
 
+    @testing.for_all_dtypes(no_bool=True, no_complex=True)
+    @testing.numpy_cupy_array_equal()
+    def test_external_clip3(self, xp, dtype):
+        a = testing.shaped_arange((2, 3, 4), xp, dtype)
+        return xp.clip(a, 8, 4)
+
+    @testing.for_all_dtypes(no_bool=True, no_complex=True)
+    def test_external_clip4(self, dtype):
+        for xp in (numpy, cupy):
+            a = testing.shaped_arange((2, 3, 4), xp, dtype)
+            with pytest.raises(TypeError):
+                xp.clip(a, 3)
+
     @testing.for_all_dtypes(no_complex=True)
     @testing.numpy_cupy_array_equal()
     def test_clip2(self, xp, dtype):
@@ -171,8 +178,17 @@ def test_absolute(self):
     def test_absolute_negative(self):
         self.check_unary_negative("absolute")
 
-    def test_fabs(self):
-        self.check_unary("fabs")
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_fabs(self, xp, dtype):
+        a = xp.array([2, 3, 4], dtype=dtype)
+        return xp.fabs(a)
+
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_fabs_negative(self, xp, dtype):
+        a = xp.array([-2.0, -4.0, 0.0, 4.0], dtype=dtype)
+        return xp.fabs(a)
 
     def test_sign(self):
         self.check_unary("sign", no_bool=True)
@@ -222,5 +238,312 @@ def test_nan_to_num_inf(self):
     def test_nan_to_num_nan(self):
         self.check_unary_nan("nan_to_num")
 
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_nan_to_num_scalar_nan(self, xp):
+        return xp.nan_to_num(xp.nan)
+
     def test_nan_to_num_inf_nan(self):
         self.check_unary_inf_nan("nan_to_num")
+
+    def test_nan_to_num_nan_arg(self):
+        self.check_unary_nan("nan_to_num", nan=1.0)
+
+    def test_nan_to_num_inf_arg(self):
+        self.check_unary_inf("nan_to_num", posinf=1.0, neginf=-1.0)
+
+    @testing.numpy_cupy_array_equal()
+    def test_nan_to_num_copy(self, xp):
+        x = xp.asarray([0, 1, xp.nan, 4], dtype=xp.float64)
+        y = xp.nan_to_num(x, copy=True)
+        assert x is not y
+        return y
+
+    @testing.numpy_cupy_array_equal()
+    def test_nan_to_num_inplace(self, xp):
+        x = xp.asarray([0, 1, xp.nan, 4], dtype=xp.float64)
+        y = xp.nan_to_num(x, copy=False)
+        assert x is y
+        return y
+
+    @pytest.mark.parametrize("kwarg", ["nan", "posinf", "neginf"])
+    def test_nan_to_num_broadcast(self, kwarg):
+        for xp in (numpy, cupy):
+            x = xp.asarray([0, 1, xp.nan, 4], dtype=xp.float64)
+            y = xp.zeros((2, 4), dtype=xp.float64)
+            with pytest.raises(ValueError):
+                xp.nan_to_num(x, **{kwarg: y})
+            with pytest.raises(ValueError):
+                xp.nan_to_num(0.0, **{kwarg: y})
+
+    @testing.for_all_dtypes(no_bool=True, no_complex=True)
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_real_dtypes(self, xp, dtype):
+        x = testing.shaped_random((10,), xp, dtype)
+        return xp.real_if_close(x)
+
+    @testing.for_all_dtypes(no_bool=True, no_complex=True)
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_with_tol_real_dtypes(self, xp, dtype):
+        x = testing.shaped_random((10,), xp, dtype)
+        return xp.real_if_close(x, tol=1e-6)
+
+    @testing.for_complex_dtypes()
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_true(self, xp, dtype):
+        dtype = numpy.dtype(dtype).char.lower()
+        tol = numpy.finfo(dtype).eps * 90
+        x = testing.shaped_random((10,), xp, dtype) + tol * 1j
+        out = xp.real_if_close(x)
+        assert x.dtype != out.dtype
+        return out
+
+    @testing.for_complex_dtypes()
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_false(self, xp, dtype):
+        dtype = numpy.dtype(dtype).char.lower()
+        tol = numpy.finfo(dtype).eps * 110
+        x = testing.shaped_random((10,), xp, dtype) + tol * 1j
+        out = xp.real_if_close(x)
+        assert x.dtype == out.dtype
+        return out
+
+    @testing.for_complex_dtypes()
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_with_integer_tol_true(self, xp, dtype):
+        dtype = numpy.dtype(dtype).char.lower()
+        tol = numpy.finfo(dtype).eps * 140
+        x = testing.shaped_random((10,), xp, dtype) + tol * 1j
+        out = xp.real_if_close(x, tol=150)
+        assert x.dtype != out.dtype
+        return out
+
+    @testing.for_complex_dtypes()
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_with_integer_tol_false(self, xp, dtype):
+        dtype = numpy.dtype(dtype).char.lower()
+        tol = numpy.finfo(dtype).eps * 50
+        x = testing.shaped_random((10,), xp, dtype) + tol * 1j
+        out = xp.real_if_close(x, tol=30)
+        assert x.dtype == out.dtype
+        return out
+
+    @testing.for_complex_dtypes()
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_with_float_tol_true(self, xp, dtype):
+        dtype = numpy.dtype(dtype).char.lower()
+        x = testing.shaped_random((10,), xp, dtype) + 3e-4j
+        out = xp.real_if_close(x, tol=1e-3)
+        assert x.dtype != out.dtype
+        return out
+
+    @testing.for_complex_dtypes()
+    @testing.numpy_cupy_array_equal()
+    def test_real_if_close_with_float_tol_false(self, xp, dtype):
+        dtype = numpy.dtype(dtype).char.lower()
+        x = testing.shaped_random((10,), xp, dtype) + 3e-3j
+        out = xp.real_if_close(x, tol=1e-3)
+        assert x.dtype == out.dtype
+        return out
+
+    @testing.for_all_dtypes(name="dtype_x", no_bool=True, no_complex=True)
+    @testing.for_all_dtypes(name="dtype_y", no_bool=True)
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        return xp.interp(x, fx, fy)
+
+    @testing.for_all_dtypes(name="dtype_x", no_bool=True, no_complex=True)
+    @testing.for_all_dtypes(name="dtype_y", no_bool=True)
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_period(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        return xp.interp(x, fx, fy, period=5)
+
+    @testing.for_all_dtypes(name="dtype_x", no_bool=True, no_complex=True)
+    @testing.for_all_dtypes(name="dtype_y", no_bool=True)
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_left_right(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        left = 10
+        right = 20
+        return xp.interp(x, fx, fy, left, right)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_all_dtypes(name="dtype_x", no_bool=True, no_complex=True)
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_nan_fy(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        fy[0] = fy[2] = fy[-1] = numpy.nan
+        return xp.interp(x, fx, fy)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_float_dtypes(name="dtype_x")
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_nan_fx(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        fx[-1] = numpy.nan  # x and fx must remain sorted (NaNs are the last)
+        return xp.interp(x, fx, fy)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_float_dtypes(name="dtype_x")
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_nan_x(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        x[-1] = numpy.nan  # x and fx must remain sorted (NaNs are the last)
+        return xp.interp(x, fx, fy)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_all_dtypes(name="dtype_x", no_bool=True, no_complex=True)
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_inf_fy(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        fy[0] = fy[2] = fy[-1] = numpy.inf
+        return xp.interp(x, fx, fy)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_float_dtypes(name="dtype_x")
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_inf_fx(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        fx[-1] = numpy.inf  # x and fx must remain sorted
+        return xp.interp(x, fx, fy)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_float_dtypes(name="dtype_x")
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_inf_x(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([1, 3, 5, 7, 9], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        x[-1] = numpy.inf  # x and fx must remain sorted
+        return xp.interp(x, fx, fy)
+
+    @testing.for_all_dtypes(name="dtype_x", no_bool=True, no_complex=True)
+    @testing.for_all_dtypes(name="dtype_y", no_bool=True)
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_size1(self, xp, dtype_y, dtype_x):
+        # interpolate at points on and outside the boundaries
+        x = xp.asarray([0, 1, 2, 4, 6, 8, 9, 10], dtype=dtype_x)
+        fx = xp.asarray([5], dtype=dtype_x)
+        fy = xp.sin(fx).astype(dtype_y)
+        left = 10
+        right = 20
+        return xp.interp(x, fx, fy, left, right)
+
+    @testing.with_requires("numpy>=1.17.0")
+    @testing.for_float_dtypes(name="dtype_x")
+    @testing.for_dtypes("efdFD", name="dtype_y")
+    @testing.numpy_cupy_allclose(atol=1e-5)
+    def test_interp_inf_to_nan(self, xp, dtype_y, dtype_x):
+        # from NumPy's test_non_finite_inf
+        x = xp.asarray([0.5], dtype=dtype_x)
+        fx = xp.asarray([-numpy.inf, numpy.inf], dtype=dtype_x)
+        fy = xp.asarray([0, 10], dtype=dtype_y)
+        return xp.interp(x, fx, fy)
+
+    @testing.for_all_dtypes(name="dtype_2", no_bool=True, no_complex=True)
+    @testing.for_all_dtypes(name="dtype_1", no_bool=True, no_complex=True)
+    @testing.numpy_cupy_array_equal()
+    def test_heaviside(self, xp, dtype_1, dtype_2):
+        x = testing.shaped_random((10,), xp, dtype_1)
+        h = xp.asarray([10], dtype=dtype_2)
+        return xp.heaviside(x, h)
+
+    @testing.for_all_dtypes(name="dtype_2", no_bool=True, no_complex=True)
+    @testing.for_float_dtypes(name="dtype_1")
+    @testing.numpy_cupy_array_equal()
+    def test_heaviside_nan_inf(self, xp, dtype_1, dtype_2):
+        x = xp.asarray([-2.0, 0.0, 3.0, xp.nan, xp.inf, -xp.inf], dtype=dtype_1)
+        h = xp.asarray([10], dtype=dtype_2)
+        return xp.heaviside(x, h)
+
+
+@testing.parameterize(
+    *testing.product(
+        {
+            "mode": ["valid", "same", "full"],
+            "shape1": [(), (5,), (6,), (20,), (21,)],
+            "shape2": [(), (5,), (6,), (20,), (21,)],
+        }
+    )
+)
+class TestConvolveShapeCombination:
+    @testing.for_all_dtypes(no_float16=True)
+    @testing.numpy_cupy_allclose(rtol=1e-3)
+    def test_convolve(self, xp, dtype):
+        a = testing.shaped_arange(self.shape1, xp, dtype)
+        b = testing.shaped_arange(self.shape2, xp, dtype)
+        return xp.convolve(a, b, mode=self.mode)
+
+
+@pytest.mark.parametrize("mode", ["valid", "same", "full"])
+class TestConvolve:
+    @testing.for_all_dtypes(no_float16=True)
+    @testing.numpy_cupy_allclose(rtol=1e-6)
+    def test_convolve_non_contiguous(self, xp, dtype, mode):
+        a = testing.shaped_arange((300,), xp, dtype)
+        b = testing.shaped_arange((100,), xp, dtype)
+        return xp.convolve(a[::200], b[10::70], mode=mode)
+
+    @testing.for_all_dtypes(no_float16=True)
+    @testing.numpy_cupy_allclose(rtol=1e-4)
+    def test_convolve_large_non_contiguous(self, xp, dtype, mode):
+        a = testing.shaped_arange((10000,), xp, dtype)
+        b = testing.shaped_arange((100,), xp, dtype)
+        return xp.convolve(a[200::], b[10::70], mode=mode)
+
+    @testing.for_all_dtypes_combination(names=["dtype1", "dtype2"])
+    @testing.numpy_cupy_allclose(rtol=1e-2)
+    def test_convolve_diff_types(self, xp, dtype1, dtype2, mode):
+        a = testing.shaped_random((200,), xp, dtype1)
+        b = testing.shaped_random((100,), xp, dtype2)
+        return xp.convolve(a, b, mode=mode)
+
+
+@testing.parameterize(*testing.product({"mode": ["valid", "same", "full"]}))
+class TestConvolveInvalid:
+    @testing.for_all_dtypes()
+    def test_convolve_empty(self, dtype):
+        for xp in (numpy, cupy):
+            a = xp.zeros((0,), dtype)
+            with pytest.raises(ValueError):
+                xp.convolve(a, a, mode=self.mode)
+
+    @testing.for_all_dtypes()
+    def test_convolve_ndim(self, dtype):
+        for xp in (numpy, cupy):
+            a = testing.shaped_arange((2, 3, 4), xp, dtype)
+            b = testing.shaped_arange((10, 5), xp, dtype)
+            with pytest.raises(ValueError):
+                xp.convolve(a, b, mode=self.mode)
diff --git a/tests/third_party/cupy/math_tests/test_trigonometric.py b/tests/third_party/cupy/math_tests/test_trigonometric.py
index 41064306769..60533205d93 100644
--- a/tests/third_party/cupy/math_tests/test_trigonometric.py
+++ b/tests/third_party/cupy/math_tests/test_trigonometric.py
@@ -3,10 +3,9 @@
 from tests.third_party.cupy import testing
 
 
-@testing.gpu
 class TestTrigonometric(unittest.TestCase):
     @testing.for_all_dtypes(no_complex=True)
-    @testing.numpy_cupy_allclose(atol=1e-5)
+    @testing.numpy_cupy_allclose(atol=1e-5, type_check=False)
     def check_unary(self, name, xp, dtype):
         a = testing.shaped_arange((2, 3), xp, dtype)
         return getattr(xp, name)(a)
@@ -55,7 +54,7 @@ def test_rad2deg(self):
         self.check_unary("rad2deg")
 
 
-@testing.gpu
+@testing.with_requires("numpy>=1.21.0")
 class TestUnwrap(unittest.TestCase):
     @testing.for_all_dtypes(no_complex=True)
     @testing.numpy_cupy_allclose()
@@ -69,6 +68,18 @@ def test_unwrap_1dim_with_discont(self, xp, dtype):
         a = testing.shaped_random((5,), xp, dtype)
         return xp.unwrap(a, discont=1.0)
 
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_allclose()
+    def test_unwrap_1dim_with_period(self, xp, dtype):
+        a = testing.shaped_random((5,), xp, dtype)
+        return xp.unwrap(a, period=1.2)
+
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_allclose()
+    def test_unwrap_1dim_with_discont_and_period(self, xp, dtype):
+        a = testing.shaped_random((5,), xp, dtype)
+        return xp.unwrap(a, discont=1.0, period=1.2)
+
     @testing.for_all_dtypes(no_complex=True)
     @testing.numpy_cupy_allclose()
     def test_unwrap_2dim_without_axis(self, xp, dtype):
@@ -86,3 +97,15 @@ def test_unwrap_2dim_with_axis(self, xp, dtype):
     def test_unwrap_2dim_with_discont(self, xp, dtype):
         a = testing.shaped_random((4, 5), xp, dtype)
         return xp.unwrap(a, discont=5.0, axis=1)
+
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_allclose()
+    def test_unwrap_2dim_with_period(self, xp, dtype):
+        a = testing.shaped_random((4, 5), xp, dtype)
+        return xp.unwrap(a, axis=1, period=4.5)
+
+    @testing.for_all_dtypes(no_complex=True)
+    @testing.numpy_cupy_allclose()
+    def test_unwrap_2dim_with_discont_and_period(self, xp, dtype):
+        a = testing.shaped_random((4, 5), xp, dtype)
+        return xp.unwrap(a, discont=5.0, axis=1, period=4.5)