1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "OperationResolver" 18 19 #include "OperationResolver.h" 20 21 #include "NeuralNetworks.h" 22 23 namespace android { 24 namespace nn { 25 26 #define NN_FORWARD_DECLARE_OPERATION_REGISTRATION_FUNCTION(opType) \ 27 const OperationRegistration* register_##opType(); 28 29 NN_FOR_EACH_OPERATION(NN_FORWARD_DECLARE_OPERATION_REGISTRATION_FUNCTION) 30 31 #undef NN_FORWARD_DECLARE_OPERATION_REGISTRATION_FUNCTION 32 33 NN_OPERATION_IS_NOT_IMPLEMENTED(DEPTH_TO_SPACE); 34 NN_OPERATION_IS_NOT_IMPLEMENTED(EMBEDDING_LOOKUP); 35 NN_OPERATION_IS_NOT_IMPLEMENTED(HASHTABLE_LOOKUP); 36 NN_OPERATION_IS_NOT_IMPLEMENTED(LSH_PROJECTION); 37 NN_OPERATION_IS_NOT_IMPLEMENTED(LSTM); 38 NN_OPERATION_IS_NOT_IMPLEMENTED(RESHAPE); 39 NN_OPERATION_IS_NOT_IMPLEMENTED(RNN); 40 NN_OPERATION_IS_NOT_IMPLEMENTED(SPACE_TO_DEPTH); 41 NN_OPERATION_IS_NOT_IMPLEMENTED(SVDF); 42 NN_OPERATION_IS_NOT_IMPLEMENTED(BATCH_TO_SPACE_ND); 43 NN_OPERATION_IS_NOT_IMPLEMENTED(MEAN); 44 NN_OPERATION_IS_NOT_IMPLEMENTED(PAD); 45 NN_OPERATION_IS_NOT_IMPLEMENTED(SPACE_TO_BATCH_ND); 46 NN_OPERATION_IS_NOT_IMPLEMENTED(ARGMAX); 47 NN_OPERATION_IS_NOT_IMPLEMENTED(ARGMIN); 48 NN_OPERATION_IS_NOT_IMPLEMENTED(BIDIRECTIONAL_SEQUENCE_LSTM); 49 NN_OPERATION_IS_NOT_IMPLEMENTED(CAST); 50 NN_OPERATION_IS_NOT_IMPLEMENTED(EXPAND_DIMS); 51 NN_OPERATION_IS_NOT_IMPLEMENTED(GROUPED_CONV_2D); 52 NN_OPERATION_IS_NOT_IMPLEMENTED(MAXIMUM); 53 NN_OPERATION_IS_NOT_IMPLEMENTED(MINIMUM); 54 NN_OPERATION_IS_NOT_IMPLEMENTED(PAD_V2); 55 NN_OPERATION_IS_NOT_IMPLEMENTED(POW); 56 NN_OPERATION_IS_NOT_IMPLEMENTED(QUANTIZED_16BIT_LSTM); 57 NN_OPERATION_IS_NOT_IMPLEMENTED(RANDOM_MULTINOMIAL); 58 NN_OPERATION_IS_NOT_IMPLEMENTED(SPLIT); 59 NN_OPERATION_IS_NOT_IMPLEMENTED(TILE); 60 NN_OPERATION_IS_NOT_IMPLEMENTED(IF); 61 NN_OPERATION_IS_NOT_IMPLEMENTED(WHILE); 62 NN_OPERATION_IS_NOT_IMPLEMENTED(OEM_OPERATION); 63 BuiltinOperationResolver()64BuiltinOperationResolver::BuiltinOperationResolver() { 65 #define NN_REGISTER_OPERATION_FUNCTION(opType) registerOperation(register_##opType()); 66 67 NN_FOR_EACH_OPERATION(NN_REGISTER_OPERATION_FUNCTION) 68 69 #undef NN_REGISTER_OPERATION_FUNCTION 70 } 71 findOperation(OperationType operationType) const72const OperationRegistration* BuiltinOperationResolver::findOperation( 73 OperationType operationType) const { 74 auto index = static_cast<int32_t>(operationType); 75 if (index >= 0 && index < kNumberOfOperationTypes) { 76 return mRegistrations[index]; 77 } 78 #ifdef NN_EXPERIMENTAL_FEATURE 79 if (index >= kStartOfExperimentalOperations && 80 index < kStartOfExperimentalOperations + kNumberOfExperimentalOperationTypes) { 81 return mExperimentalRegistrations[index - kStartOfExperimentalOperations]; 82 } 83 #endif // NN_EXPERIMENTAL_FEATURE 84 return nullptr; 85 } 86 registerOperation(const OperationRegistration * operationRegistration)87void BuiltinOperationResolver::registerOperation( 88 const OperationRegistration* operationRegistration) { 89 // Some operations (such as IF and WHILE) are not implemented through registration. These 90 // operations call registerOperation with a nullptr, which skips registration. 91 if (operationRegistration == nullptr) { 92 return; 93 } 94 95 auto index = static_cast<int32_t>(operationRegistration->type); 96 97 #ifdef NN_EXPERIMENTAL_FEATURE 98 if (index >= kStartOfExperimentalOperations) { 99 CHECK_LT(index, kStartOfExperimentalOperations + kNumberOfExperimentalOperationTypes); 100 CHECK(mExperimentalRegistrations[index - kStartOfExperimentalOperations] == nullptr); 101 mExperimentalRegistrations[index - kStartOfExperimentalOperations] = operationRegistration; 102 return; 103 } 104 #endif // NN_EXPERIMENTAL_FEATURE 105 106 CHECK_LE(0, index); 107 CHECK_LT(index, kNumberOfOperationTypes); 108 CHECK(mRegistrations[index] == nullptr); 109 mRegistrations[index] = operationRegistration; 110 } 111 112 } // namespace nn 113 } // namespace android 114