aboutsummaryrefslogtreecommitdiff
path: root/arm_compute/core/NEON/kernels/NEMinMaxLocationKernel.h
blob: 83f5afce72a2dda892ae9e0a58e9717a3cb5f1ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * Copyright (c) 2016-2020 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef ARM_COMPUTE_NEMINMAXLOCATIONKERNEL_H
#define ARM_COMPUTE_NEMINMAXLOCATIONKERNEL_H

#include "arm_compute/core/IArray.h"
#include "arm_compute/core/NEON/INEKernel.h"
#include "support/Mutex.h"

#include <cstdint>

namespace arm_compute
{
class ITensor;
using IImage = ITensor;

/** Interface for the kernel to perform min max search on an image. */
class NEMinMaxKernel : public INEKernel
{
public:
    const char *name() const override
    {
        return "NEMinMaxKernel";
    }
    /** Default constructor */
    NEMinMaxKernel();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEMinMaxKernel(const NEMinMaxKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEMinMaxKernel &operator=(const NEMinMaxKernel &) = delete;
    /** Prevent instances of this class from being moved (As this class contains non movable objects) */
    NEMinMaxKernel(NEMinMaxKernel &&) = delete;
    /** Prevent instances of this class from being moved (As this class contains non movable objects) */
    NEMinMaxKernel &operator=(NEMinMaxKernel &&) = delete;
    /** Default destructor */
    ~NEMinMaxKernel() = default;

    /** Initialise the kernel's input and outputs.
     *
     * @param[in]  input Input Image. Data types supported: U8/S16/F32.
     * @param[out] min   Minimum value of image. Data types supported: S32 if input type is U8/S16, F32 if input type is F32.
     * @param[out] max   Maximum value of image. Data types supported: S32 if input type is U8/S16, F32 if input type is F32.
     */
    void configure(const IImage *input, void *min, void *max);
    /** Resets global minimum and maximum. */
    void reset();

    // Inherited methods overridden:
    void run(const Window &window, const ThreadInfo &info) override;

private:
    /** Performs the min/max algorithm on U8 images on a given window.
     *
     * @param win The window to run the algorithm on.
     */
    void minmax_U8(Window win);
    /** Performs the min/max algorithm on S16 images on a given window.
     *
     * @param win The window to run the algorithm on.
     */
    void minmax_S16(Window win);
    /** Performs the min/max algorithm on F32 images on a given window.
     *
     * @param win The window to run the algorithm on.
     */
    void minmax_F32(Window win);
    /** Common signature for all the specialised MinMax functions
     *
     * @param[in] window Region on which to execute the kernel.
     */
    using MinMaxFunction = void (NEMinMaxKernel::*)(Window window);
    /** MinMax function to use for the particular image types passed to configure() */
    MinMaxFunction _func;
    /** Helper to update min/max values **/
    template <typename T>
    void update_min_max(T min, T max);

    const IImage      *_input; /**< Input image. */
    void              *_min;   /**< Minimum value. */
    void              *_max;   /**< Maximum value. */
    arm_compute::Mutex _mtx;   /**< Mutex used for result reduction. */
};

/** Interface for the kernel to find min max locations of an image. */
class NEMinMaxLocationKernel : public INEKernel
{
public:
    const char *name() const override
    {
        return "NEMinMaxLocationKernel";
    }
    /** Default constructor */
    NEMinMaxLocationKernel();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEMinMaxLocationKernel(const NEMinMaxLocationKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEMinMaxLocationKernel &operator=(const NEMinMaxLocationKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEMinMaxLocationKernel(NEMinMaxLocationKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEMinMaxLocationKernel &operator=(NEMinMaxLocationKernel &&) = default;
    /** Default destructor */
    ~NEMinMaxLocationKernel() = default;

    /** Initialise the kernel's input and outputs.
     *
     * @param[in]  input     Input Image. Data types supported: U8/S16/F32.
     * @param[out] min       Minimum value of image. Data types supported: S32 if input type is U8/S16, F32 if input type is F32.
     * @param[out] max       Maximum value of image. Data types supported: S32 if input type is U8/S16, F32 if input type is F32.
     * @param[out] min_loc   Array of minimum value locations.
     * @param[out] max_loc   Array of maximum value locations.
     * @param[out] min_count Number of minimum value encounters.
     * @param[out] max_count Number of maximum value encounters.
     */
    void configure(const IImage *input, void *min, void *max,
                   ICoordinates2DArray *min_loc = nullptr, ICoordinates2DArray *max_loc = nullptr,
                   uint32_t *min_count = nullptr, uint32_t *max_count = nullptr);

    // Inherited methods overridden:
    void run(const Window &window, const ThreadInfo &info) override;
    bool is_parallelisable() const override;

private:
    /** Performs the min/max location algorithm on T type images on a given window.
     *
     * @param win The window to run the algorithm on.
     */
    template <class T, bool count_min, bool count_max, bool loc_min, bool loc_max>
    void minmax_loc(const Window &win);
    /** Common signature for all the specialised MinMaxLoc functions
     *
     * @param[in] window Region on which to execute the kernel.
     */
    using MinMaxLocFunction = void (NEMinMaxLocationKernel::*)(const Window &window);
    /** MinMaxLoc function to use for the particular image types passed to configure() */
    MinMaxLocFunction _func;
    /** Helper to create a function pointer table for the parameterized MinMaxLocation functions. */
    template <class T, typename>
    struct create_func_table;

    const IImage        *_input;     /**< Input image. */
    void                *_min;       /**< Minimum value. */
    void                *_max;       /**< Maximum value. */
    uint32_t            *_min_count; /**< Count of minimum value encounters. */
    uint32_t            *_max_count; /**< Count of maximum value encounters. */
    ICoordinates2DArray *_min_loc;   /**< Locations of minimum values. */
    ICoordinates2DArray *_max_loc;   /**< Locations of maximum values. */
};
} // namespace arm_compute
#endif /*ARM_COMPUTE_NEMINMAXLOCATIONKERNEL_H */