Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Preparation to reuse future common dpctl f/w in functions from vm extension #1868

Merged
merged 21 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a8e2afb
Preparation to reuse common dpctl f/w for VM functions
antonwolfy Jun 4, 2024
a61d4e8
PoC to decouple abs implementation to separate source file
antonwolfy Jun 4, 2024
ed57483
Reuse typedef for function poiter from dpctl.tensor
antonwolfy Jun 4, 2024
71d745d
Define populating vectors by a separate macro
antonwolfy Jun 5, 2024
c2ea834
Move implementation of utility functions from headers to source to re…
antonwolfy Jun 5, 2024
7eb99d8
Separated implementation of acos function
antonwolfy Jun 5, 2024
2418e84
Separated implementation of acosh function
antonwolfy Jun 5, 2024
7748331
Use function to simplify strides from dpctl tensor headers
antonwolfy Jun 5, 2024
f9fbbce
PoC to decouple add implementation to separate source file
antonwolfy Jun 5, 2024
1d16fc3
Separated implementation of asin function
antonwolfy Jun 5, 2024
d2f31e5
Separated implementation of asinh function
antonwolfy Jun 5, 2024
d63fcff
Separated implementation of atan, atan2, atanh functions
antonwolfy Jun 5, 2024
ef195da
Resolve issue with calling MKL function for undefined types
antonwolfy Jun 6, 2024
a76d5e2
Separated implementation of cbrt, ceil, conj, cos and cosh functions
antonwolfy Jun 7, 2024
31b916f
Separated implementation of div, exp, exp2, expm1, floor and hypot fu…
antonwolfy Jun 7, 2024
616186e
Separated implementation of ln, log1p, log2 and log10 functions
antonwolfy Jun 7, 2024
3cd6f2d
Separated implementation of mul, pow, rint, sin and sinh functions
antonwolfy Jun 7, 2024
8c8b9aa
Separated implementation of sqr, sqrt, sub, tan, tanh and trunc funct…
antonwolfy Jun 10, 2024
fda9ec4
Removed unused header with types matrix
antonwolfy Jun 11, 2024
49ffe40
Remove unused functions
antonwolfy Jun 11, 2024
c565600
Use passing by reference in unary and binary funcs
antonwolfy Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//*****************************************************************************
// Copyright (c) 2024, 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 "dpctl4pybind11.hpp"

#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <sycl/sycl.hpp>

#include "elementwise_functions_type_utils.hpp"

// dpctl tensor headers
#include "utils/type_dispatch.hpp"

namespace py = pybind11;
namespace td_ns = dpctl::tensor::type_dispatch;

namespace dpnp::extensions::py_internal::type_utils
{
py::dtype _dtype_from_typenum(td_ns::typenum_t dst_typenum_t)
{
switch (dst_typenum_t) {
case td_ns::typenum_t::BOOL:
return py::dtype("?");
case td_ns::typenum_t::INT8:
return py::dtype("i1");
case td_ns::typenum_t::UINT8:
return py::dtype("u1");
case td_ns::typenum_t::INT16:
return py::dtype("i2");
case td_ns::typenum_t::UINT16:
return py::dtype("u2");
case td_ns::typenum_t::INT32:
return py::dtype("i4");
case td_ns::typenum_t::UINT32:
return py::dtype("u4");
case td_ns::typenum_t::INT64:
return py::dtype("i8");
case td_ns::typenum_t::UINT64:
return py::dtype("u8");
case td_ns::typenum_t::HALF:
return py::dtype("f2");
case td_ns::typenum_t::FLOAT:
return py::dtype("f4");
case td_ns::typenum_t::DOUBLE:
return py::dtype("f8");
case td_ns::typenum_t::CFLOAT:
return py::dtype("c8");
case td_ns::typenum_t::CDOUBLE:
return py::dtype("c16");
default:
throw py::value_error("Unrecognized dst_typeid");
}
}

int _result_typeid(int arg_typeid, const int *fn_output_id)
{
if (arg_typeid < 0 || arg_typeid >= td_ns::num_types) {
throw py::value_error("Input typeid " + std::to_string(arg_typeid) +
" is outside of expected bounds.");
}

return fn_output_id[arg_typeid];
}
} // namespace dpnp::extensions::py_internal::type_utils
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//*****************************************************************************
// Copyright (c) 2024, 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 "dpctl4pybind11.hpp"
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

// dpctl tensor headers
#include "utils/type_dispatch.hpp"

namespace py = pybind11;
namespace td_ns = dpctl::tensor::type_dispatch;

namespace dpnp::extensions::py_internal::type_utils
{
/*! @brief Produce dtype from a type number */
extern py::dtype _dtype_from_typenum(td_ns::typenum_t);

/*! @brief Lookup typeid of the result from typeid of
* argument and the mapping table */
extern int _result_typeid(int, const int *);
} // namespace dpnp::extensions::py_internal::type_utils
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
//*****************************************************************************
// Copyright (c) 2024, 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 "dpctl4pybind11.hpp"

#include <pybind11/pybind11.h>
#include <vector>

#include "simplify_iteration_space.hpp"

// dpctl tensor headers
#include "utils/strided_iters.hpp"

namespace dpnp::extensions::py_internal
{
namespace py = pybind11;
namespace st_ns = dpctl::tensor::strides;

void simplify_iteration_space(int &nd,
const py::ssize_t *const &shape,
std::vector<py::ssize_t> const &src_strides,
std::vector<py::ssize_t> const &dst_strides,
// output
std::vector<py::ssize_t> &simplified_shape,
std::vector<py::ssize_t> &simplified_src_strides,
std::vector<py::ssize_t> &simplified_dst_strides,
py::ssize_t &src_offset,
py::ssize_t &dst_offset)
{
if (nd > 1) {
// Simplify iteration space to reduce dimensionality
// and improve access pattern
simplified_shape.reserve(nd);
simplified_shape.insert(std::begin(simplified_shape), shape,
shape + nd);
assert(simplified_shape.size() == static_cast<size_t>(nd));

simplified_src_strides.reserve(nd);
simplified_src_strides.insert(std::end(simplified_src_strides),
std::begin(src_strides),
std::end(src_strides));
assert(simplified_src_strides.size() == static_cast<size_t>(nd));

simplified_dst_strides.reserve(nd);
simplified_dst_strides.insert(std::end(simplified_dst_strides),
std::begin(dst_strides),
std::end(dst_strides));
assert(simplified_dst_strides.size() == static_cast<size_t>(nd));

int contracted_nd = st_ns::simplify_iteration_two_strides(
nd, simplified_shape.data(), simplified_src_strides.data(),
simplified_dst_strides.data(),
src_offset, // modified by reference
dst_offset // modified by reference
);
simplified_shape.resize(contracted_nd);
simplified_src_strides.resize(contracted_nd);
simplified_dst_strides.resize(contracted_nd);

nd = contracted_nd;
}
else if (nd == 1) {
src_offset = 0;
dst_offset = 0;
// Populate vectors
simplified_shape.reserve(nd);
simplified_shape.push_back(shape[0]);
assert(simplified_shape.size() == static_cast<size_t>(nd));

simplified_src_strides.reserve(nd);
simplified_dst_strides.reserve(nd);

if (src_strides[0] < 0 && dst_strides[0] < 0) {
simplified_src_strides.push_back(-src_strides[0]);
simplified_dst_strides.push_back(-dst_strides[0]);
if (shape[0] > 1) {
src_offset += (shape[0] - 1) * src_strides[0];
dst_offset += (shape[0] - 1) * dst_strides[0];
}
}
else {
simplified_src_strides.push_back(src_strides[0]);
simplified_dst_strides.push_back(dst_strides[0]);
}

assert(simplified_src_strides.size() == static_cast<size_t>(nd));
assert(simplified_dst_strides.size() == static_cast<size_t>(nd));
}
}

void simplify_iteration_space_3(
int &nd,
const py::ssize_t *const &shape,
// src1
std::vector<py::ssize_t> const &src1_strides,
// src2
std::vector<py::ssize_t> const &src2_strides,
// dst
std::vector<py::ssize_t> const &dst_strides,
// output
std::vector<py::ssize_t> &simplified_shape,
std::vector<py::ssize_t> &simplified_src1_strides,
std::vector<py::ssize_t> &simplified_src2_strides,
std::vector<py::ssize_t> &simplified_dst_strides,
py::ssize_t &src1_offset,
py::ssize_t &src2_offset,
py::ssize_t &dst_offset)
{
if (nd > 1) {
// Simplify iteration space to reduce dimensionality
// and improve access pattern
simplified_shape.reserve(nd);
simplified_shape.insert(std::end(simplified_shape), shape, shape + nd);
assert(simplified_shape.size() == static_cast<size_t>(nd));

simplified_src1_strides.reserve(nd);
simplified_src1_strides.insert(std::end(simplified_src1_strides),
std::begin(src1_strides),
std::end(src1_strides));
assert(simplified_src1_strides.size() == static_cast<size_t>(nd));

simplified_src2_strides.reserve(nd);
simplified_src2_strides.insert(std::end(simplified_src2_strides),
std::begin(src2_strides),
std::end(src2_strides));
assert(simplified_src2_strides.size() == static_cast<size_t>(nd));

simplified_dst_strides.reserve(nd);
simplified_dst_strides.insert(std::end(simplified_dst_strides),
std::begin(dst_strides),
std::end(dst_strides));
assert(simplified_dst_strides.size() == static_cast<size_t>(nd));

int contracted_nd = st_ns::simplify_iteration_three_strides(
nd, simplified_shape.data(), simplified_src1_strides.data(),
simplified_src2_strides.data(), simplified_dst_strides.data(),
src1_offset, // modified by reference
src2_offset, // modified by reference
dst_offset // modified by reference
);
simplified_shape.resize(contracted_nd);
simplified_src1_strides.resize(contracted_nd);
simplified_src2_strides.resize(contracted_nd);
simplified_dst_strides.resize(contracted_nd);

nd = contracted_nd;
}
else if (nd == 1) {
src1_offset = 0;
src2_offset = 0;
dst_offset = 0;
// Populate vectors
simplified_shape.reserve(nd);
simplified_shape.push_back(shape[0]);
assert(simplified_shape.size() == static_cast<size_t>(nd));

simplified_src1_strides.reserve(nd);
simplified_src2_strides.reserve(nd);
simplified_dst_strides.reserve(nd);

if ((src1_strides[0] < 0) && (src2_strides[0] < 0) &&
(dst_strides[0] < 0)) {
simplified_src1_strides.push_back(-src1_strides[0]);
simplified_src2_strides.push_back(-src2_strides[0]);
simplified_dst_strides.push_back(-dst_strides[0]);
if (shape[0] > 1) {
src1_offset += src1_strides[0] * (shape[0] - 1);
src2_offset += src2_strides[0] * (shape[0] - 1);
dst_offset += dst_strides[0] * (shape[0] - 1);
}
}
else {
simplified_src1_strides.push_back(src1_strides[0]);
simplified_src2_strides.push_back(src2_strides[0]);
simplified_dst_strides.push_back(dst_strides[0]);
}

assert(simplified_src1_strides.size() == static_cast<size_t>(nd));
assert(simplified_src2_strides.size() == static_cast<size_t>(nd));
assert(simplified_dst_strides.size() == static_cast<size_t>(nd));
}
}
} // namespace dpnp::extensions::py_internal
Loading
Loading