Skip to content

Commit

Permalink
Added at() and percentile() operators
Browse files Browse the repository at this point in the history
  • Loading branch information
cliffburdick committed Aug 28, 2023
1 parent 327361a commit ea70662
Show file tree
Hide file tree
Showing 14 changed files with 680 additions and 5 deletions.
31 changes: 31 additions & 0 deletions docs_input/api/manipulation/selecting/at.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.. _at_func:

at
==

Selects a single value from an operator. Since `at` is a lazily-evaluated operator, it should be used
in situations where `operator()` cannot be used. For instance:

.. code-block:: cpp
(a = b(5)).run();
The code above creates a race condition where `b(5)` is evaluated on the host before launch, but the value may
not be computed from a previous operation. Instead, the `at()` operator can be used to defer the load until
the operation is launched:

.. code-block:: cpp
(a = at(b, 5)).run();
.. doxygenfunction:: at(const Op op, Is... indices)

Examples
~~~~~~~~

.. literalinclude:: ../../../../test/00_operators/OperatorTests.cu
:language: cpp
:start-after: example-begin at-test-1
:end-before: example-end at-test-1
:dedent:

Empty file.
24 changes: 24 additions & 0 deletions docs_input/api/stats/misc/percentile.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. _percentile_func:

percentile
##########

Find the q-th percentile of an input sequence. ``q`` is a value between 0 and 100 representing the percentile. A value
of 0 is equivalent to mean, 100 is max, and 50 is the median when using the ``LINEAR`` method.

.. note::
Multiple q values are not supported yet

Supported methods for interpolation are: LINEAR, HAZEN, WEIBULL, LOWER, HIGHER, MIDPOINT, NEAREST, MEDIAN_UNBIASED, and NORMAL_UNBIASED

.. doxygenfunction:: percentile(const InType &in, unsigned char q, PercentileMethod method = PercentileMethod::LINEAR)
.. doxygenfunction:: percentile(const InType &in, unsigned char q, const int (&dims)[D], PercentileMethod method = PercentileMethod::LINEAR)

Examples
~~~~~~~~

.. literalinclude:: ../../../../test/00_operators/ReductionTests.cu
:language: cpp
:start-after: example-begin percentile-test-1
:end-before: example-end percentile-test-1
:dedent:
1 change: 0 additions & 1 deletion examples/fft_conv.cu
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
}
}


std::cout << "Verification successful" << std::endl;

CUDA_CHECK_LAST_ERROR();
Expand Down
6 changes: 3 additions & 3 deletions include/matx/core/make_tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ auto make_tensor( const index_t (&shape)[RANK],
* @param stream cuda stream to allocate in (only applicable to async allocations)
**/
template <typename TensorType, std::enable_if_t< is_tensor_view_v<TensorType>, bool> = true>
void make_tensor( TensorType &tensor,
const index_t (&shape)[TensorType::Rank()],
matxMemorySpace_t space = MATX_MANAGED_MEMORY,
void make_tensor( TensorType &tensor,
const index_t (&shape)[TensorType::Rank()],
matxMemorySpace_t space = MATX_MANAGED_MEMORY,
cudaStream_t stream = 0) {
MATX_NVTX_START("", matx::MATX_NVTX_LOG_API)

Expand Down
81 changes: 81 additions & 0 deletions include/matx/operators/at.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
////////////////////////////////////////////////////////////////////////////////
// BSD 3-Clause License
//
// Copyright (c) 2021, NVIDIA 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:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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 "matx/operators/base_operator.h"

namespace matx
{

/**
* Returns the current tensor index for the given dimension.
*/
namespace detail {
template <typename Op, typename... Is>
class AtOp : public BaseOp<AtOp<Op, Is...>>
{
private:
Op op_;
std::array<index_t, sizeof...(Is)> idx_;

public:
using matxop = bool;
using scalar_type = typename Op::scalar_type;

__MATX_INLINE__ std::string str() const { return "at()"; }
__MATX_INLINE__ AtOp(Op op, Is... is) : op_(op), idx_{is...} {};

template <typename... Is2>
__MATX_INLINE__ __MATX_DEVICE__ __MATX_HOST__ auto operator()([[maybe_unused]] Is2... indices) const
{
return mapply(op_, idx_);
}

static __MATX_INLINE__ constexpr __MATX_HOST__ __MATX_DEVICE__ int32_t Rank()
{
return 0;
}

constexpr __MATX_INLINE__ __MATX_HOST__ __MATX_DEVICE__ index_t Size([[maybe_unused]] int dim) const
{
return index_t(0);
}
};
}


template <typename Op, typename... Is, std::enable_if_t<((std::is_integral_v<Is>) && ...), bool> = true>
__MATX_INLINE__ auto at(const Op op, Is... indices) {
return detail::AtOp(op, indices...);
}
} // end namespace matx
7 changes: 6 additions & 1 deletion include/matx/operators/flatten.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ namespace matx
template <typename T1>
auto __MATX_INLINE__ flatten(const T1 &a)
{
return detail::FlattenOp<T1>(a);
if constexpr (T1::Rank() <= 1) {
return a;
}
else {
return detail::FlattenOp<T1>(a);
}
};

} // end namespace matx
2 changes: 2 additions & 0 deletions include/matx/operators/operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "matx/operators/binary_operators.h"

#include "matx/operators/ambgfun.h"
#include "matx/operators/at.h"
#include "matx/operators/cart2sph.h"
#include "matx/operators/collapse.h"
#include "matx/operators/concat.h"
Expand Down Expand Up @@ -73,6 +74,7 @@
#include "matx/operators/legendre.h"
#include "matx/operators/lu.h"
#include "matx/operators/matmul.h"
#include "matx/operators/percentile.h"
#include "matx/operators/permute.h"
#include "matx/operators/planar.h"
#include "matx/operators/qr.h"
Expand Down
160 changes: 160 additions & 0 deletions include/matx/operators/percentile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
////////////////////////////////////////////////////////////////////////////////
// BSD 3-Clause License
//
// Copyright (c) 2021, NVIDIA 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:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// 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 "matx/core/type_utils.h"
#include "matx/operators/base_operator.h"
#include "matx/operators/permute.h"
#include "matx/transforms/percentile.h"

namespace matx {


namespace detail {
template<typename OpA, int ORank>
class PercentileOp : public BaseOp<PercentileOp<OpA,ORank>>
{
private:
OpA a_;
uint32_t q_;
PercentileMethod method_;
std::array<index_t, ORank> out_dims_;
mutable matx::tensor_t<typename remove_cvref_t<OpA>::scalar_type, ORank> tmp_out_;

public:
using matxop = bool;
using scalar_type = typename remove_cvref_t<OpA>::scalar_type;
using matx_transform_op = bool;
using prod_xform_op = bool;

__MATX_INLINE__ std::string str() const { return "percentile(" + get_type_str(a_) + ")"; }
__MATX_INLINE__ PercentileOp(OpA a, unsigned char q, PercentileMethod method) : a_(a), q_(q), method_(method) {
for (int r = 0; r < ORank; r++) {
out_dims_[r] = (r == ORank - 1) ? 1 : a_.Size(r);
}
};

template <typename... Is>
__MATX_INLINE__ __MATX_DEVICE__ __MATX_HOST__ auto operator()(Is... indices) const {
return tmp_out_(indices...);
};

template <typename Out, typename Executor>
void Exec(Out &&out, Executor &&ex) const {
percentile_impl(std::get<0>(out), a_, q_, method_, ex);
}

static __MATX_INLINE__ constexpr __MATX_HOST__ __MATX_DEVICE__ int32_t Rank()
{
return ORank;
}

template <typename ShapeType, typename Executor>
__MATX_INLINE__ void PreRun([[maybe_unused]] ShapeType &&shape, Executor &&ex) const noexcept
{
if constexpr (is_matx_op<OpA>()) {
a_.PreRun(std::forward<ShapeType>(shape), std::forward<Executor>(ex));
}

if constexpr (is_device_executor_v<Executor>) {
make_tensor(tmp_out_, out_dims_, MATX_ASYNC_DEVICE_MEMORY, ex.getStream());
}
else {
make_tensor(tmp_out_, out_dims_, MATX_HOST_MEMORY);
}

Exec(std::make_tuple(tmp_out_), std::forward<Executor>(ex));
}

constexpr __MATX_INLINE__ __MATX_HOST__ __MATX_DEVICE__ index_t Size(int dim) const
{
return out_dims_[dim];
}

};
}

/**
* Compute product of numbers along axes
*
* Returns a tensor representing the product of all items in the reduction
*
* @tparam InType
* Input data type
* @tparam D
* Num of dimensions to reduce over
*
* @param in
* Input data to reduce
* @param q
* Percentile to compute (between 0-100)
* @param dims
* Array containing dimensions to compute over
* @param method
* Method of interpolation
* @returns Operator with reduced values of prod-reduce computed
*/
template <typename InType, int D>
__MATX_INLINE__ auto percentile(const InType &in, unsigned char q, const int (&dims)[D], PercentileMethod method = PercentileMethod::LINEAR)
{
static_assert(D < InType::Rank(), "reduction dimensions must be <= Rank of input");
MATX_ASSERT_STR(q < 100, matxInvalidParameter, "Percentile must be < 100");
auto perm = detail::getPermuteDims<InType::Rank()>(dims);
auto permop = permute(in, perm);

return detail::PercentileOp<decltype(permop), InType::Rank() - D>(permop, q, method);
}

/**
* Compute product of numbers
*
* Returns a tensor representing the product of all items in the reduction
*
* @tparam InType
* Input data type
*
* @param in
* Input data to reduce
* @param q
* Percentile to compute (between 0-100)
* @param method
* Method of interpolation
* @returns Operator with reduced values of prod-reduce computed
*/
template <typename InType>
__MATX_INLINE__ auto percentile(const InType &in, unsigned char q, PercentileMethod method = PercentileMethod::LINEAR)
{
return detail::PercentileOp<decltype(in), 0>(in, q, method);
}

}
Loading

0 comments on commit ea70662

Please sign in to comment.