aboutsummaryrefslogtreecommitdiff
path: root/src/core/NEON/kernels/arm_conv/depthwise/depthwise_implementation_constraints.hpp
blob: b4814bef928f985a2a5e9d139602adac85f27557 (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
/*
 * Copyright (c) 2021 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.
 */

/* Utilities for constructing functions which constrain which kernels are
 * selected for a given depthwise problem.
 *
 * It is expected that this will be included in the files which list the
 * available kernels. To avoid multiple definitions, an anonymous namespace is
 * used.
 */

#pragma once

#include "arm_gemm.hpp"
#include "depthwise.hpp"

namespace arm_conv
{
namespace depthwise
{
namespace
{

template <class OutputStage>
using ConstraintFn = std::function<bool(const DepthwiseArgs &, const OutputStage &)>;

using GenericConstraintFn = std::function<bool(const DepthwiseArgs &, const void *)>;

GenericConstraintFn make_constraint(const GenericConstraintFn &f) __attribute__ ((unused));
GenericConstraintFn make_constraint(const GenericConstraintFn &f)
{
  return f;
}

template <typename ... Fs>
GenericConstraintFn make_constraint(const GenericConstraintFn &f, Fs ... fs)
{
  return [f, fs...] (const DepthwiseArgs &args, const void *os) -> bool {
    return f(args, os) && make_constraint(fs...)(args, os);
  };
}

template <typename OutputStage=Nothing, typename ... Fs>
ConstraintFn<OutputStage> constraint(Fs ... fs)
{
  return [fs...] (const DepthwiseArgs &args, const OutputStage &os) -> bool {
    return make_constraint(fs...)(args, &os);
  };
}

// Some useful constraints
template <class Strategy>
bool is_supported(const DepthwiseArgs &args, const void *)
{
  return ((args.kernel_rows == Strategy::kernel_rows) &&
          (args.kernel_cols == Strategy::kernel_cols) &&
          (args.stride_rows == Strategy::stride_rows) &&
          (args.stride_cols == Strategy::stride_cols));
}

bool cpu_has_dot_product(const DepthwiseArgs &args, const void *) __attribute__ ((unused));
bool cpu_has_dot_product(const DepthwiseArgs &args, const void *)
{
  return args.cpu_info->has_dotprod();
}

bool has_no_channel_multiplier(const DepthwiseArgs &args, const void *) __attribute__ ((unused));
bool has_no_channel_multiplier(const DepthwiseArgs &args, const void *)
{
  return args.channel_multiplier == 1;
}

bool qp_has_no_left_shift(const DepthwiseArgs &args, const void *_qp) __attribute__ ((unused));
bool qp_has_no_left_shift(const DepthwiseArgs &, const void *_qp)
{
  const auto qp = static_cast<const arm_gemm::Requantize32 *>(_qp);
  return qp->per_channel_requant ?
    (qp->per_channel_left_shifts == nullptr) :
    (qp->per_layer_left_shift == 0);
}

}  // namespace
}  // namespace depthwise
}  // namespace arm_conv