1 /* 2 * Copyright (C) 2019 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 #ifndef ANDROID_FRAMEWORKS_ML_NN_RUNTIME_MODEL_ARGUMENT_INFO_H 18 #define ANDROID_FRAMEWORKS_ML_NN_RUNTIME_MODEL_ARGUMENT_INFO_H 19 20 #include <LegacyUtils.h> 21 22 #include <utility> 23 #include <vector> 24 25 #include "NeuralNetworks.h" 26 27 namespace android { 28 namespace nn { 29 30 // TODO move length out of DataLocation 31 // 32 // NOTE: The primary usage pattern is that a ModelArgumentInfo instance 33 // is not modified once it is created (unless it is reassigned to). 34 // There are a small number of use cases where it NEEDS to be modified, 35 // and we have a limited number of methods that support this. 36 class ModelArgumentInfo { 37 public: ModelArgumentInfo()38 ModelArgumentInfo() {} 39 40 static std::pair<int, ModelArgumentInfo> createFromPointer( 41 const Operand& operand, const ANeuralNetworksOperandType* type, 42 void* data /* nullptr means HAS_NO_VALUE */, uint32_t length, 43 bool paddingEnabled = true); 44 static std::pair<int, ModelArgumentInfo> createFromMemory( 45 const Operand& operand, const ANeuralNetworksOperandType* type, uint32_t poolIndex, 46 uint32_t offset, uint32_t length, bool paddingEnabled = true); 47 48 enum State { POINTER, MEMORY, HAS_NO_VALUE, UNSPECIFIED }; 49 state()50 State state() const { return mState; } 51 unspecified()52 bool unspecified() const { return mState == UNSPECIFIED; } 53 buffer()54 void* buffer() const { 55 CHECK_EQ(mState, POINTER); 56 return mBuffer; 57 } 58 initialDimensions()59 const std::vector<uint32_t>& initialDimensions() const { 60 CHECK(mState == POINTER || mState == MEMORY); 61 return mInitialDimensions; 62 } dimensions()63 const std::vector<uint32_t>& dimensions() const { 64 CHECK(mState == POINTER || mState == MEMORY); 65 return mDimensions; 66 } dimensions()67 std::vector<uint32_t>& dimensions() { 68 CHECK(mState == POINTER || mState == MEMORY); 69 return mDimensions; 70 } 71 isSufficient()72 bool isSufficient() const { 73 CHECK(mState == POINTER || mState == MEMORY); 74 return mIsSufficient; 75 } isSufficient()76 bool& isSufficient() { 77 CHECK(mState == POINTER || mState == MEMORY); 78 return mIsSufficient; 79 } 80 length()81 uint32_t length() const { 82 CHECK(mState == POINTER || mState == MEMORY); 83 return mLocationAndLength.length; 84 } 85 padding()86 uint32_t padding() const { 87 CHECK(mState == POINTER || mState == MEMORY); 88 return mLocationAndLength.padding; 89 } 90 locationAndLength()91 const DataLocation& locationAndLength() const { 92 CHECK_EQ(mState, MEMORY); 93 return mLocationAndLength; 94 } locationAndLength()95 DataLocation& locationAndLength() { 96 CHECK_EQ(mState, MEMORY); 97 return mLocationAndLength; 98 } 99 100 // Restore updatable properties to creation-time values. reset()101 void reset() { 102 mDimensions = mInitialDimensions; 103 mIsSufficient = true; 104 } 105 106 // Convert ModelArgumentInfo to canonical Request::Argument. Unlike createRequestArguments, 107 // this method will keep the pointer type in the canonical type. 108 Request::Argument createRequestArgument() const; 109 110 private: 111 int updateDimensionInfo(const Operand& operand, const ANeuralNetworksOperandType* newType); 112 113 // Whether the argument was specified as being in a Memory, as a pointer, 114 // has no value, or has not been specified. 115 // If POINTER then: 116 // mLocationAndLength.length is valid. 117 // mBuffer is valid. 118 // If MEMORY then: 119 // mLocationAndLength.{poolIndex, offset, length} is valid. 120 // In both MEMORY and POINTER cases: 121 // mInitialDimensions is valid. 122 // mDimensions is valid. 123 // mIsSufficient is valid. 124 125 // Properties that are fixed at creation. 126 State mState = UNSPECIFIED; 127 void* mBuffer = nullptr; 128 std::vector<uint32_t> mInitialDimensions; 129 // TODO(b/183021356): This field is logically fixed at creation, but actually updated in 130 // StepExecutor::mapInputOrOutput when constructing StepExecutor ModelArgumentInfos from 131 // ExecutionBuilder ModelArgumentInfos. We should find a way to avoid this update. 132 DataLocation mLocationAndLength; 133 134 // Properties that are updatable after creation. 135 std::vector<uint32_t> mDimensions; 136 bool mIsSufficient = true; 137 }; 138 139 // Convert ModelArgumentInfo to canonical Request::Argument. For pointer arguments, use the location 140 // information in ptrArgsLocations. 141 std::vector<Request::Argument> createRequestArguments( 142 const std::vector<ModelArgumentInfo>& argumentInfos, 143 const std::vector<DataLocation>& ptrArgsLocations); 144 145 } // namespace nn 146 } // namespace android 147 148 #endif // ANDROID_FRAMEWORKS_ML_NN_RUNTIME_MODEL_ARGUMENT_INFO_H 149