telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 1 | // |
| 2 | // Copyright © 2017 Arm Ltd. All rights reserved. |
David Beck | ecb56cd | 2018-09-05 12:52:57 +0100 | [diff] [blame] | 3 | // SPDX-License-Identifier: MIT |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 4 | // |
David Beck | b4540be | 2018-09-24 13:18:27 +0100 | [diff] [blame] | 5 | #include <armnn/LayerSupport.hpp> |
arovir01 | 085f0a4 | 2018-10-08 14:48:19 +0100 | [diff] [blame] | 6 | #include <armnn/Optional.hpp> |
David Beck | 111b5d9 | 2018-11-12 14:59:37 +0000 | [diff] [blame] | 7 | #include <armnn/ILayerSupport.hpp> |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 8 | |
David Beck | 111b5d9 | 2018-11-12 14:59:37 +0000 | [diff] [blame] | 9 | #include <backendsCommon/BackendRegistry.hpp> |
| 10 | #include <backendsCommon/IBackendInternal.hpp> |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 11 | |
| 12 | #include <boost/assert.hpp> |
| 13 | |
| 14 | #include <cstring> |
| 15 | #include <algorithm> |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 16 | #include <unordered_map> |
Éanna Ó Catháin | 4e1e136 | 2018-11-12 11:36:34 +0000 | [diff] [blame] | 17 | #include <armnn/ArmNN.hpp> |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 18 | |
| 19 | namespace armnn |
| 20 | { |
| 21 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 22 | namespace |
| 23 | { |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 24 | /// Helper function to copy a full string to a truncated version. |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 25 | void CopyErrorMessage(char* truncatedString, const char* fullString, size_t maxLength) |
| 26 | { |
| 27 | if(truncatedString != nullptr) |
| 28 | { |
| 29 | size_t copyLength = std::min(maxLength, strlen(fullString)); |
| 30 | std::strncpy(truncatedString, fullString, copyLength); |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 31 | // Ensure null-terminated string. |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 32 | truncatedString[copyLength] = '\0'; |
| 33 | } |
| 34 | } |
| 35 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 36 | } |
| 37 | |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 38 | // Helper macro to avoid code duplication. |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 39 | // Forwards function func to funcRef, funcNeon or funcCl, depending on the value of compute. |
David Beck | 3e9e115 | 2018-10-17 14:17:50 +0100 | [diff] [blame] | 40 | #define FORWARD_LAYER_SUPPORT_FUNC(backendId, func, ...) \ |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 41 | std::string reasonIfUnsupportedFull; \ |
| 42 | bool isSupported; \ |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 43 | try { \ |
David Beck | 111b5d9 | 2018-11-12 14:59:37 +0000 | [diff] [blame] | 44 | auto const& backendRegistry = BackendRegistryInstance(); \ |
| 45 | if (!backendRegistry.IsBackendRegistered(backendId)) \ |
| 46 | { \ |
| 47 | std::stringstream ss; \ |
| 48 | ss << __func__ << " is not supported on " << backendId << " because this backend is not registered."; \ |
| 49 | reasonIfUnsupportedFull = ss.str(); \ |
| 50 | isSupported = false; \ |
| 51 | } \ |
| 52 | else \ |
| 53 | { \ |
| 54 | auto factoryFunc = backendRegistry.GetFactory(backendId); \ |
| 55 | auto backendObject = factoryFunc(); \ |
| 56 | auto layerSupportObject = backendObject->GetLayerSupport(); \ |
| 57 | isSupported = layerSupportObject->func(__VA_ARGS__, Optional<std::string&>(reasonIfUnsupportedFull)); \ |
| 58 | CopyErrorMessage(reasonIfUnsupported, reasonIfUnsupportedFull.c_str(), reasonIfUnsupportedMaxLength); \ |
| 59 | } \ |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 60 | } catch (InvalidArgumentException e) { \ |
| 61 | /* re-throwing with more context information */ \ |
| 62 | throw InvalidArgumentException(e, "Failed to check layer support", CHECK_LOCATION()); \ |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 63 | } \ |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 64 | return isSupported; |
| 65 | |
| 66 | bool CheckTensorDataTypesEqual(const TensorInfo& input0, const TensorInfo& input1) |
| 67 | { |
| 68 | return input0.GetDataType() == input1.GetDataType(); |
| 69 | } |
| 70 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 71 | bool IsActivationSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 72 | const TensorInfo& input, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 73 | const TensorInfo& output, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 74 | const ActivationDescriptor& descriptor, |
| 75 | char* reasonIfUnsupported, |
| 76 | size_t reasonIfUnsupportedMaxLength) |
| 77 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 78 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsActivationSupported, input, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 79 | } |
| 80 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 81 | bool IsAdditionSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 82 | const TensorInfo& input0, |
| 83 | const TensorInfo& input1, |
| 84 | const TensorInfo& output, |
| 85 | char* reasonIfUnsupported, |
| 86 | size_t reasonIfUnsupportedMaxLength) |
| 87 | { |
| 88 | if(!CheckTensorDataTypesEqual(input0, input1)) |
| 89 | { |
| 90 | return false; |
| 91 | } |
| 92 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 93 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsAdditionSupported, input0, input1, output); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 94 | } |
| 95 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 96 | bool IsBatchNormalizationSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 97 | const TensorInfo& input, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 98 | const TensorInfo& output, |
| 99 | const TensorInfo& mean, |
| 100 | const TensorInfo& var, |
| 101 | const TensorInfo& beta, |
| 102 | const TensorInfo& gamma, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 103 | const BatchNormalizationDescriptor& descriptor, |
| 104 | char* reasonIfUnsupported, |
| 105 | size_t reasonIfUnsupportedMaxLength) |
| 106 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 107 | FORWARD_LAYER_SUPPORT_FUNC(backend, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 108 | IsBatchNormalizationSupported, |
| 109 | input, |
| 110 | output, |
| 111 | mean, |
| 112 | var, |
| 113 | beta, |
| 114 | gamma, |
| 115 | descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 116 | } |
| 117 | |
Éanna Ó Catháin | 4e1e136 | 2018-11-12 11:36:34 +0000 | [diff] [blame] | 118 | bool IsBatchToSpaceNdSupported(const BackendId& backend, |
| 119 | const TensorInfo& input, |
| 120 | const TensorInfo& output, |
| 121 | const BatchToSpaceNdDescriptor& descriptor, |
| 122 | char* reasonIfUnsupported, |
| 123 | size_t reasonIfUnsupportedMaxLength) |
| 124 | { |
| 125 | FORWARD_LAYER_SUPPORT_FUNC(backend, |
| 126 | IsBatchToSpaceNdSupported, |
| 127 | input, |
| 128 | output, |
| 129 | descriptor); |
| 130 | } |
| 131 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 132 | bool IsConstantSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 133 | const TensorInfo& output, |
| 134 | char* reasonIfUnsupported, |
| 135 | size_t reasonIfUnsupportedMaxLength) |
| 136 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 137 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsConstantSupported, output); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 138 | } |
| 139 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 140 | bool IsConvertFp16ToFp32Supported(const BackendId& backend, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 141 | const TensorInfo& input, |
| 142 | const TensorInfo& output, |
| 143 | char* reasonIfUnsupported, |
| 144 | size_t reasonIfUnsupportedMaxLength) |
| 145 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 146 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsConvertFp16ToFp32Supported, input, output); |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 147 | } |
| 148 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 149 | bool IsConvertFp32ToFp16Supported(const BackendId& backend, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 150 | const TensorInfo& input, |
| 151 | const TensorInfo& output, |
| 152 | char* reasonIfUnsupported, |
| 153 | size_t reasonIfUnsupportedMaxLength) |
| 154 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 155 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsConvertFp32ToFp16Supported, input, output); |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 156 | } |
| 157 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 158 | bool IsConvolution2dSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 159 | const TensorInfo& input, |
surmeh01 | 3537c2c | 2018-05-18 16:31:43 +0100 | [diff] [blame] | 160 | const TensorInfo& output, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 161 | const Convolution2dDescriptor& descriptor, |
| 162 | const TensorInfo& weights, |
David Beck | 5eec11d | 2018-10-04 15:43:17 +0100 | [diff] [blame] | 163 | const Optional<TensorInfo>& biases, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 164 | char* reasonIfUnsupported, |
| 165 | size_t reasonIfUnsupportedMaxLength) |
| 166 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 167 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsConvolution2dSupported, input, output, descriptor, weights, biases); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 168 | } |
| 169 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 170 | bool IsDivisionSupported(const BackendId& backend, |
Francis Murtagh | e7a86a4 | 2018-08-29 12:42:10 +0100 | [diff] [blame] | 171 | const TensorInfo& input0, |
| 172 | const TensorInfo& input1, |
| 173 | const TensorInfo& output, |
| 174 | char* reasonIfUnsupported, |
| 175 | size_t reasonIfUnsupportedMaxLength) |
| 176 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 177 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsDivisionSupported, input0, input1, output); |
Francis Murtagh | e7a86a4 | 2018-08-29 12:42:10 +0100 | [diff] [blame] | 178 | } |
| 179 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 180 | bool IsSubtractionSupported(const BackendId& backend, |
David Beck | c2044fe | 2018-09-05 15:00:38 +0100 | [diff] [blame] | 181 | const TensorInfo& input0, |
| 182 | const TensorInfo& input1, |
| 183 | const TensorInfo& output, |
| 184 | char* reasonIfUnsupported, |
| 185 | size_t reasonIfUnsupportedMaxLength) |
| 186 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 187 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsSubtractionSupported, input0, input1, output); |
David Beck | c2044fe | 2018-09-05 15:00:38 +0100 | [diff] [blame] | 188 | } |
| 189 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 190 | bool IsDepthwiseConvolutionSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 191 | const TensorInfo& input, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 192 | const TensorInfo& output, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 193 | const DepthwiseConvolution2dDescriptor& descriptor, |
| 194 | const TensorInfo& weights, |
David Beck | 5eec11d | 2018-10-04 15:43:17 +0100 | [diff] [blame] | 195 | const Optional<TensorInfo>& biases, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 196 | char* reasonIfUnsupported, |
| 197 | size_t reasonIfUnsupportedMaxLength) |
| 198 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 199 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsDepthwiseConvolutionSupported, input, output, descriptor, weights, biases); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 200 | } |
| 201 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 202 | bool IsInputSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 203 | const TensorInfo& input, |
| 204 | char* reasonIfUnsupported, |
| 205 | size_t reasonIfUnsupportedMaxLength) |
| 206 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 207 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsInputSupported, input); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 208 | } |
| 209 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 210 | bool IsFullyConnectedSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 211 | const TensorInfo& input, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 212 | const TensorInfo& output, |
| 213 | const TensorInfo& weights, |
| 214 | const TensorInfo& biases, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 215 | const FullyConnectedDescriptor& descriptor, |
| 216 | char* reasonIfUnsupported, |
| 217 | size_t reasonIfUnsupportedMaxLength) |
| 218 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 219 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsFullyConnectedSupported, input, output, weights, biases, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 220 | } |
| 221 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 222 | bool IsL2NormalizationSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 223 | const TensorInfo& input, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 224 | const TensorInfo& output, |
Matteo Martincigh | bcd3c85 | 2018-09-28 14:14:12 +0100 | [diff] [blame] | 225 | const L2NormalizationDescriptor& descriptor, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 226 | char* reasonIfUnsupported, |
| 227 | size_t reasonIfUnsupportedMaxLength) |
| 228 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 229 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsL2NormalizationSupported, input, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 230 | } |
| 231 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 232 | bool IsLstmSupported(const BackendId& backend, const TensorInfo& input, const TensorInfo& outputStateIn, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 233 | const TensorInfo& cellStateIn, const TensorInfo& scratchBuffer, |
| 234 | const TensorInfo& outputStateOut, const TensorInfo& cellStateOut, |
| 235 | const TensorInfo& output, const LstmDescriptor& descriptor, |
| 236 | const TensorInfo& inputToForgetWeights, const TensorInfo& inputToCellWeights, |
| 237 | const TensorInfo& inputToOutputWeights, const TensorInfo& recurrentToForgetWeights, |
| 238 | const TensorInfo& recurrentToCellWeights, const TensorInfo& recurrentToOutputWeights, |
| 239 | const TensorInfo& forgetGateBias, const TensorInfo& cellBias, |
| 240 | const TensorInfo& outputGateBias, const TensorInfo* inputToInputWeights, |
| 241 | const TensorInfo* recurrentToInputWeights, const TensorInfo* cellToInputWeights, |
| 242 | const TensorInfo* inputGateBias, const TensorInfo* projectionWeights, |
| 243 | const TensorInfo* projectionBias, const TensorInfo* cellToForgetWeights, |
| 244 | const TensorInfo* cellToOutputWeights, char* reasonIfUnsupported, |
| 245 | size_t reasonIfUnsupportedMaxLength) |
| 246 | |
| 247 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 248 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsLstmSupported, input, outputStateIn, cellStateIn, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 249 | scratchBuffer, outputStateOut, cellStateOut, |
| 250 | output, descriptor, inputToForgetWeights, inputToCellWeights, |
| 251 | inputToOutputWeights, recurrentToForgetWeights, |
| 252 | recurrentToCellWeights, recurrentToOutputWeights, |
| 253 | forgetGateBias, cellBias, outputGateBias, |
| 254 | inputToInputWeights, recurrentToInputWeights, |
| 255 | cellToInputWeights, inputGateBias, projectionWeights, |
| 256 | projectionBias, cellToForgetWeights, cellToOutputWeights); |
| 257 | } |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 258 | bool IsMergerSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 259 | std::vector<const TensorInfo*> inputs, |
Nikhil Raj | 8599a41 | 2018-11-19 14:51:07 +0000 | [diff] [blame] | 260 | const TensorInfo& output, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 261 | const OriginsDescriptor& descriptor, |
| 262 | char* reasonIfUnsupported, |
| 263 | size_t reasonIfUnsupportedMaxLength) |
| 264 | { |
| 265 | BOOST_ASSERT(inputs.size() > 0); |
Nikhil Raj | 8599a41 | 2018-11-19 14:51:07 +0000 | [diff] [blame] | 266 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsMergerSupported, inputs, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 267 | } |
| 268 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 269 | bool IsMultiplicationSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 270 | const TensorInfo& input0, |
| 271 | const TensorInfo& input1, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 272 | const TensorInfo& output, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 273 | char* reasonIfUnsupported, |
| 274 | size_t reasonIfUnsupportedMaxLength) |
| 275 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 276 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsMultiplicationSupported, input0, input1, output); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 277 | } |
| 278 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 279 | bool IsNormalizationSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 280 | const TensorInfo& input, |
| 281 | const TensorInfo& output, |
| 282 | const NormalizationDescriptor& descriptor, |
| 283 | char* reasonIfUnsupported, |
| 284 | size_t reasonIfUnsupportedMaxLength) |
| 285 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 286 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsNormalizationSupported, input, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 287 | } |
| 288 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 289 | bool IsOutputSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 290 | const TensorInfo& output, |
| 291 | char* reasonIfUnsupported, |
| 292 | size_t reasonIfUnsupportedMaxLength) |
| 293 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 294 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsOutputSupported, output); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 295 | } |
| 296 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 297 | bool IsPermuteSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 298 | const TensorInfo& input, |
| 299 | const TensorInfo& output, |
| 300 | const PermuteDescriptor& descriptor, |
| 301 | char* reasonIfUnsupported, |
| 302 | size_t reasonIfUnsupportedMaxLength) |
| 303 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 304 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsPermuteSupported, input, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 305 | } |
| 306 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 307 | bool IsPooling2dSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 308 | const TensorInfo& input, |
| 309 | const TensorInfo& output, |
| 310 | const Pooling2dDescriptor& descriptor, |
| 311 | char* reasonIfUnsupported, |
| 312 | size_t reasonIfUnsupportedMaxLength) |
| 313 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 314 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsPooling2dSupported, input, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 315 | } |
| 316 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 317 | bool IsResizeBilinearSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 318 | const TensorInfo& input, |
| 319 | char* reasonIfUnsupported, |
| 320 | size_t reasonIfUnsupportedMaxLength) |
| 321 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 322 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsResizeBilinearSupported, input); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 323 | } |
| 324 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 325 | bool IsSoftmaxSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 326 | const TensorInfo& input, |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 327 | const TensorInfo& output, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 328 | const SoftmaxDescriptor& descriptor, |
| 329 | char* reasonIfUnsupported, |
| 330 | size_t reasonIfUnsupportedMaxLength) |
| 331 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 332 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsSoftmaxSupported, input, output, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 333 | } |
| 334 | |
Nattapat Chaimanowong | 207ef9a | 2018-11-02 10:57:25 +0000 | [diff] [blame] | 335 | bool IsSpaceToBatchNdSupported(const BackendId& backend, |
| 336 | const TensorInfo& input, |
| 337 | const TensorInfo& output, |
| 338 | const SpaceToBatchNdDescriptor& descriptor, |
| 339 | char* reasonIfUnsupported, |
| 340 | size_t reasonIfUnsupportedMaxLength) |
| 341 | { |
| 342 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsSpaceToBatchNdSupported, input, output, descriptor); |
| 343 | } |
| 344 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 345 | bool IsSplitterSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 346 | const TensorInfo& input, |
| 347 | const ViewsDescriptor& descriptor, |
| 348 | char* reasonIfUnsupported, |
| 349 | size_t reasonIfUnsupportedMaxLength) |
| 350 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 351 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsSplitterSupported, input, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 352 | } |
| 353 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 354 | bool IsFakeQuantizationSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 355 | const TensorInfo& input, |
| 356 | const FakeQuantizationDescriptor& descriptor, |
| 357 | char* reasonIfUnsupported, |
| 358 | size_t reasonIfUnsupportedMaxLength) |
| 359 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 360 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsFakeQuantizationSupported, input, descriptor); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 361 | } |
| 362 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 363 | bool IsReshapeSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 364 | const TensorInfo& input, |
| 365 | char* reasonIfUnsupported, |
| 366 | size_t reasonIfUnsupportedMaxLength) |
| 367 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 368 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsReshapeSupported, input); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 369 | } |
| 370 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 371 | bool IsFloorSupported(const BackendId& backend, |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 372 | const TensorInfo& input, |
| 373 | const TensorInfo& output, |
| 374 | char* reasonIfUnsupported, |
| 375 | size_t reasonIfUnsupportedMaxLength) |
| 376 | { |
telsoa01 | c577f2c | 2018-08-31 09:22:23 +0100 | [diff] [blame] | 377 | // By definition (that is, regardless of compute device), shapes and data type must match. |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 378 | if (input.GetShape() != output.GetShape() || input.GetDataType() != output.GetDataType()) |
| 379 | { |
| 380 | return false; |
| 381 | } |
| 382 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 383 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsFloorSupported, input, output); |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 384 | } |
| 385 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 386 | bool IsMeanSupported(const BackendId& backend, |
narpra01 | 32b9046 | 2018-09-13 11:07:48 +0100 | [diff] [blame] | 387 | const TensorInfo& input, |
| 388 | const TensorInfo& output, |
| 389 | const MeanDescriptor& descriptor, |
| 390 | char* reasonIfUnsupported, |
| 391 | size_t reasonIfUnsupportedMaxLength) |
| 392 | { |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 393 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsMeanSupported, input, output, descriptor); |
narpra01 | 32b9046 | 2018-09-13 11:07:48 +0100 | [diff] [blame] | 394 | } |
| 395 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 396 | bool IsPadSupported(const BackendId& backend, |
Mohamed Nour Abouelseoud | 5662c20 | 2018-09-24 13:30:09 +0100 | [diff] [blame] | 397 | const TensorInfo& input, |
| 398 | const TensorInfo& output, |
| 399 | const PadDescriptor& descriptor, |
| 400 | char* reasonIfUnsupported, |
| 401 | size_t reasonIfUnsupportedMaxLength) |
| 402 | { |
Nina Drozd | 661dfa7 | 2018-10-02 11:14:17 +0100 | [diff] [blame] | 403 | |
David Beck | 3cc9a62 | 2018-10-12 10:38:31 +0100 | [diff] [blame] | 404 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsPadSupported, input, output, descriptor); |
Mohamed Nour Abouelseoud | 5662c20 | 2018-09-24 13:30:09 +0100 | [diff] [blame] | 405 | } |
| 406 | |
Conor Kennedy | 430b5d8 | 2018-11-14 15:28:28 +0000 | [diff] [blame] | 407 | bool IsStridedSliceSupported(const BackendId& backend, |
| 408 | const TensorInfo& input, |
| 409 | const TensorInfo& output, |
| 410 | const StridedSliceDescriptor& descriptor, |
| 411 | char* reasonIfUnsupported, |
| 412 | size_t reasonIfUnsupportedMaxLength) |
| 413 | { |
| 414 | FORWARD_LAYER_SUPPORT_FUNC(backend, IsStridedSliceSupported, input, output, descriptor); |
| 415 | } |
| 416 | |
telsoa01 | 4fcda01 | 2018-03-09 14:13:49 +0000 | [diff] [blame] | 417 | } |