Skip to content

Commit 3b188ba

Browse files
committed
Added at() and percentile() operators
1 parent 327361a commit 3b188ba

File tree

13 files changed

+611
-5
lines changed

13 files changed

+611
-5
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
.. _at_func:
2+
3+
at
4+
==
5+
6+
Selects a single value from an operator. Since `at` is a lazily-evaluated operator, it should be used
7+
in situations where `operator()` cannot be used. For instance:
8+
9+
.. code-block:: cpp
10+
11+
(a = b(5)).run();
12+
13+
The code above creates a race condition where `b(5)` is evaluated on the host before launch, but the value may
14+
not be computed from a previous operation. Instead, the `at()` operator can be used to defer the load until
15+
the operation is launched:
16+
17+
.. code-block:: cpp
18+
19+
(a = at(b, 5)).run();
20+
21+
.. doxygenfunction:: at(const Op op, Is... indices)
22+
23+
Examples
24+
~~~~~~~~
25+
26+
.. literalinclude:: ../../../../test/00_operators/OperatorTests.cu
27+
:language: cpp
28+
:start-after: example-begin at-test-1
29+
:end-before: example-end at-test-1
30+
:dedent:
31+

docs_input/api/stats/misc/index.rst

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.. _percentile_func:
2+
3+
percentile
4+
##########
5+
6+
Find the q-th percentile of an input sequence. ``q`` is a value between 0 and 100 representing the percentile. A value
7+
of 0 is equivalent to mean, 100 is max, and 50 is the median when using the ``LINEAR`` method.
8+
9+
.. note::
10+
Multiple q values are not supported yet
11+
12+
Supported methods for interpolation are: LINEAR, HAZEN, WEIBULL, LOWER, HIGHER, MIDPOINT, NEAREST, MEDIAN_UNBIASED, and NORMAL_UNBIASED
13+
14+
.. doxygenfunction:: percentile(const InType &in, unsigned char q, PercentileMethod method = PercentileMethod::LINEAR)
15+
.. doxygenfunction:: percentile(const InType &in, unsigned char q, const int (&dims)[D], PercentileMethod method = PercentileMethod::LINEAR)
16+
17+
Examples
18+
~~~~~~~~
19+
20+
.. literalinclude:: ../../../../test/00_operators/ReductionTests.cu
21+
:language: cpp
22+
:start-after: example-begin percentile-test-1
23+
:end-before: example-end percentile-test-1
24+
:dedent:

examples/fft_conv.cu

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
169169
}
170170
}
171171

172-
173172
std::cout << "Verification successful" << std::endl;
174173

175174
CUDA_CHECK_LAST_ERROR();

include/matx/core/make_tensor.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ auto make_tensor( const index_t (&shape)[RANK],
7272
* @param stream cuda stream to allocate in (only applicable to async allocations)
7373
**/
7474
template <typename TensorType, std::enable_if_t< is_tensor_view_v<TensorType>, bool> = true>
75-
void make_tensor( TensorType &tensor,
76-
const index_t (&shape)[TensorType::Rank()],
77-
matxMemorySpace_t space = MATX_MANAGED_MEMORY,
75+
void make_tensor( TensorType &tensor,
76+
const index_t (&shape)[TensorType::Rank()],
77+
matxMemorySpace_t space = MATX_MANAGED_MEMORY,
7878
cudaStream_t stream = 0) {
7979
MATX_NVTX_START("", matx::MATX_NVTX_LOG_API)
8080

include/matx/operators/at.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
// BSD 3-Clause License
3+
//
4+
// Copyright (c) 2021, NVIDIA Corporation
5+
// All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// 1. Redistributions of source code must retain the above copyright notice, this
11+
// list of conditions and the following disclaimer.
12+
//
13+
// 2. Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// 3. Neither the name of the copyright holder nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
/////////////////////////////////////////////////////////////////////////////////
32+
33+
#pragma once
34+
35+
#include "matx/operators/base_operator.h"
36+
37+
namespace matx
38+
{
39+
40+
/**
41+
* Returns the current tensor index for the given dimension.
42+
*/
43+
namespace detail {
44+
template <typename Op, typename... Is>
45+
class AtOp : public BaseOp<AtOp<Op, Is...>>
46+
{
47+
private:
48+
Op op_;
49+
std::array<index_t, sizeof...(Is)> idx_;
50+
51+
public:
52+
using matxop = bool;
53+
using scalar_type = typename Op::scalar_type;
54+
55+
__MATX_INLINE__ std::string str() const { return "at()"; }
56+
__MATX_INLINE__ AtOp(Op op, Is... is) : op_(op), idx_{is...} {};
57+
58+
template <typename... Is2>
59+
__MATX_INLINE__ __MATX_DEVICE__ __MATX_HOST__ auto operator()([[maybe_unused]] Is2... indices) const
60+
{
61+
return mapply(op_, idx_);
62+
}
63+
64+
static __MATX_INLINE__ constexpr __MATX_HOST__ __MATX_DEVICE__ int32_t Rank()
65+
{
66+
return 0;
67+
}
68+
69+
constexpr __MATX_INLINE__ __MATX_HOST__ __MATX_DEVICE__ index_t Size([[maybe_unused]] int dim) const
70+
{
71+
return index_t(0);
72+
}
73+
};
74+
}
75+
76+
77+
template <typename Op, typename... Is, std::enable_if_t<((std::is_integral_v<Is>) && ...), bool> = true>
78+
__MATX_INLINE__ auto at(const Op op, Is... indices) {
79+
return detail::AtOp(op, indices...);
80+
}
81+
} // end namespace matx

include/matx/operators/flatten.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,12 @@ namespace matx
103103
template <typename T1>
104104
auto __MATX_INLINE__ flatten(const T1 &a)
105105
{
106-
return detail::FlattenOp<T1>(a);
106+
if constexpr (T1::Rank() <= 1) {
107+
return a;
108+
}
109+
else {
110+
return detail::FlattenOp<T1>(a);
111+
}
107112
};
108113

109114
} // end namespace matx

include/matx/operators/operators.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "matx/operators/binary_operators.h"
3737

3838
#include "matx/operators/ambgfun.h"
39+
#include "matx/operators/at.h"
3940
#include "matx/operators/cart2sph.h"
4041
#include "matx/operators/collapse.h"
4142
#include "matx/operators/concat.h"
@@ -73,6 +74,7 @@
7374
#include "matx/operators/legendre.h"
7475
#include "matx/operators/lu.h"
7576
#include "matx/operators/matmul.h"
77+
#include "matx/operators/percentile.h"
7678
#include "matx/operators/permute.h"
7779
#include "matx/operators/planar.h"
7880
#include "matx/operators/qr.h"
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
// BSD 3-Clause License
3+
//
4+
// Copyright (c) 2021, NVIDIA Corporation
5+
// All rights reserved.
6+
//
7+
// Redistribution and use in source and binary forms, with or without
8+
// modification, are permitted provided that the following conditions are met:
9+
//
10+
// 1. Redistributions of source code must retain the above copyright notice, this
11+
// list of conditions and the following disclaimer.
12+
//
13+
// 2. Redistributions in binary form must reproduce the above copyright notice,
14+
// this list of conditions and the following disclaimer in the documentation
15+
// and/or other materials provided with the distribution.
16+
//
17+
// 3. Neither the name of the copyright holder nor the names of its
18+
// contributors may be used to endorse or promote products derived from
19+
// this software without specific prior written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
/////////////////////////////////////////////////////////////////////////////////
32+
33+
#pragma once
34+
35+
#include "matx/core/type_utils.h"
36+
#include "matx/operators/base_operator.h"
37+
#include "matx/operators/permute.h"
38+
#include "matx/transforms/percentile.h"
39+
40+
namespace matx {
41+
42+
43+
namespace detail {
44+
template<typename OpA, int ORank>
45+
class PercentileOp : public BaseOp<PercentileOp<OpA,ORank>>
46+
{
47+
private:
48+
OpA a_;
49+
uint32_t q_;
50+
PercentileMethod method_;
51+
std::array<index_t, ORank> out_dims_;
52+
mutable matx::tensor_t<typename remove_cvref_t<OpA>::scalar_type, ORank> tmp_out_;
53+
54+
public:
55+
using matxop = bool;
56+
using scalar_type = typename remove_cvref_t<OpA>::scalar_type;
57+
using matx_transform_op = bool;
58+
using prod_xform_op = bool;
59+
60+
__MATX_INLINE__ std::string str() const { return "percentile(" + get_type_str(a_) + ")"; }
61+
__MATX_INLINE__ PercentileOp(OpA a, unsigned char q, PercentileMethod method) : a_(a), q_(q), method_(method) {
62+
for (int r = 0; r < ORank; r++) {
63+
out_dims_[r] = (r == ORank - 1) ? 1 : a_.Size(r);
64+
}
65+
};
66+
67+
template <typename... Is>
68+
__MATX_INLINE__ __MATX_DEVICE__ __MATX_HOST__ auto operator()(Is... indices) const {
69+
return tmp_out_(indices...);
70+
};
71+
72+
template <typename Out, typename Executor>
73+
void Exec(Out &&out, Executor &&ex) const {
74+
percentile_impl(std::get<0>(out), a_, q_, method_, ex);
75+
}
76+
77+
static __MATX_INLINE__ constexpr __MATX_HOST__ __MATX_DEVICE__ int32_t Rank()
78+
{
79+
return ORank;
80+
}
81+
82+
template <typename ShapeType, typename Executor>
83+
__MATX_INLINE__ void PreRun([[maybe_unused]] ShapeType &&shape, Executor &&ex) const noexcept
84+
{
85+
if constexpr (is_matx_op<OpA>()) {
86+
a_.PreRun(std::forward<ShapeType>(shape), std::forward<Executor>(ex));
87+
}
88+
89+
if constexpr (is_device_executor_v<Executor>) {
90+
make_tensor(tmp_out_, out_dims_, MATX_ASYNC_DEVICE_MEMORY, ex.getStream());
91+
}
92+
else {
93+
make_tensor(tmp_out_, out_dims_, MATX_HOST_MEMORY);
94+
}
95+
96+
Exec(std::make_tuple(tmp_out_), std::forward<Executor>(ex));
97+
}
98+
99+
constexpr __MATX_INLINE__ __MATX_HOST__ __MATX_DEVICE__ index_t Size(int dim) const
100+
{
101+
return out_dims_[dim];
102+
}
103+
104+
};
105+
}
106+
107+
/**
108+
* Compute product of numbers along axes
109+
*
110+
* Returns a tensor representing the product of all items in the reduction
111+
*
112+
* @tparam InType
113+
* Input data type
114+
* @tparam D
115+
* Num of dimensions to reduce over
116+
*
117+
* @param in
118+
* Input data to reduce
119+
* @param q
120+
* Percentile to compute (between 0-100)
121+
* @param dims
122+
* Array containing dimensions to compute over
123+
* @param method
124+
* Method of interpolation
125+
* @returns Operator with reduced values of prod-reduce computed
126+
*/
127+
template <typename InType, int D>
128+
__MATX_INLINE__ auto percentile(const InType &in, unsigned char q, const int (&dims)[D], PercentileMethod method = PercentileMethod::LINEAR)
129+
{
130+
static_assert(D < InType::Rank(), "reduction dimensions must be <= Rank of input");
131+
MATX_ASSERT_STR(q < 100, matxInvalidParameter, "Percentile must be < 100");
132+
auto perm = detail::getPermuteDims<InType::Rank()>(dims);
133+
auto permop = permute(in, perm);
134+
135+
return detail::PercentileOp<decltype(permop), InType::Rank() - D>(permop, q, method);
136+
}
137+
138+
/**
139+
* Compute product of numbers
140+
*
141+
* Returns a tensor representing the product of all items in the reduction
142+
*
143+
* @tparam InType
144+
* Input data type
145+
*
146+
* @param in
147+
* Input data to reduce
148+
* @param q
149+
* Percentile to compute (between 0-100)
150+
* @param method
151+
* Method of interpolation
152+
* @returns Operator with reduced values of prod-reduce computed
153+
*/
154+
template <typename InType>
155+
__MATX_INLINE__ auto percentile(const InType &in, unsigned char q, PercentileMethod method = PercentileMethod::LINEAR)
156+
{
157+
return detail::PercentileOp<decltype(in), 0>(in, q, method);
158+
}
159+
160+
}

0 commit comments

Comments
 (0)