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 <utility>
21 #include <vector>
22 
23 #include "HalInterfaces.h"
24 #include "NeuralNetworks.h"
25 #include "Utils.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 hal::Operand& operand, const ANeuralNetworksOperandType* type,
42             void* data /* nullptr means HAS_NO_VALUE */, uint32_t length);
43     static std::pair<int, ModelArgumentInfo> createFromMemory(
44             const hal::Operand& operand, const ANeuralNetworksOperandType* type, uint32_t poolIndex,
45             uint32_t offset, uint32_t length);
46 
47     enum State { POINTER, MEMORY, HAS_NO_VALUE, UNSPECIFIED };
48 
state()49     State state() const { return mState; }
50 
unspecified()51     bool unspecified() const { return mState == UNSPECIFIED; }
52 
buffer()53     void* buffer() const {
54         CHECK_EQ(mState, POINTER);
55         return mBuffer;
56     }
57 
dimensions()58     const std::vector<uint32_t>& dimensions() const {
59         CHECK(mState == POINTER || mState == MEMORY);
60         return mDimensions;
61     }
dimensions()62     std::vector<uint32_t>& dimensions() {
63         CHECK(mState == POINTER || mState == MEMORY);
64         return mDimensions;
65     }
66 
isSufficient()67     bool isSufficient() const {
68         CHECK(mState == POINTER || mState == MEMORY);
69         return mIsSufficient;
70     }
isSufficient()71     bool& isSufficient() {
72         CHECK(mState == POINTER || mState == MEMORY);
73         return mIsSufficient;
74     }
75 
length()76     uint32_t length() const {
77         CHECK(mState == POINTER || mState == MEMORY);
78         return mLocationAndLength.length;
79     }
80 
locationAndLength()81     const hal::DataLocation& locationAndLength() const {
82         CHECK_EQ(mState, MEMORY);
83         return mLocationAndLength;
84     }
locationAndLength()85     hal::DataLocation& locationAndLength() {
86         CHECK_EQ(mState, MEMORY);
87         return mLocationAndLength;
88     }
89 
90    private:
91     int updateDimensionInfo(const hal::Operand& operand, const ANeuralNetworksOperandType* newType);
92 
93     // Whether the argument was specified as being in a Memory, as a pointer,
94     // has no value, or has not been specified.
95     // If POINTER then:
96     //   mLocationAndLength.length is valid.
97     //   mDimensions is valid.
98     //   mBuffer is valid.
99     // If MEMORY then:
100     //   mLocationAndLength.{poolIndex, offset, length} is valid.
101     //   mDimensions is valid.
102     State mState = UNSPECIFIED;            // fixed at creation
103     void* mBuffer = nullptr;               // fixed at creation
104     hal::DataLocation mLocationAndLength;  // can be updated after creation
105     std::vector<uint32_t> mDimensions;     // can be updated after creation
106     bool mIsSufficient = true;             // can be updated after creation
107 };
108 
109 // Convert ModelArgumentInfo to HIDL RequestArgument. For pointer arguments, use the location
110 // information in ptrArgsLocations.
111 hal::hidl_vec<hal::RequestArgument> createRequestArguments(
112         const std::vector<ModelArgumentInfo>& argumentInfos,
113         const std::vector<hal::DataLocation>& ptrArgsLocations);
114 
115 }  // namespace nn
116 }  // namespace android
117 
118 #endif  // ANDROID_FRAMEWORKS_ML_NN_RUNTIME_MODEL_ARGUMENT_INFO_H
119