1 /*
2  * Copyright (C) 2021 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 #include <android-base/logging.h>
18 
19 #include <functional>
20 #include <utility>
21 
22 #include "ExecutionBuilder.h"
23 #include "NeuralNetworksSupportLibraryImpl.h"
24 #include "Telemetry.h"
25 
26 namespace {
27 
28 using android::nn::ExecutionMode;
29 using android::nn::telemetry::DataClass;
30 using android::nn::telemetry::DiagnosticCompilationInfo;
31 using android::nn::telemetry::DiagnosticExecutionInfo;
32 
castTo(const ANeuralNetworksDiagnosticCompilationInfo * info)33 const DiagnosticCompilationInfo* castTo(const ANeuralNetworksDiagnosticCompilationInfo* info) {
34     CHECK(info != nullptr);
35     return reinterpret_cast<const DiagnosticCompilationInfo*>(info);
36 }
37 
castTo(const ANeuralNetworksDiagnosticExecutionInfo * info)38 const DiagnosticExecutionInfo* castTo(const ANeuralNetworksDiagnosticExecutionInfo* info) {
39     CHECK(info != nullptr);
40     return reinterpret_cast<const DiagnosticExecutionInfo*>(info);
41 }
42 
castFrom(const DiagnosticCompilationInfo * info)43 const ANeuralNetworksDiagnosticCompilationInfo* castFrom(const DiagnosticCompilationInfo* info) {
44     CHECK(info != nullptr);
45     return reinterpret_cast<const ANeuralNetworksDiagnosticCompilationInfo*>(info);
46 }
47 
castFrom(const DiagnosticExecutionInfo * info)48 const ANeuralNetworksDiagnosticExecutionInfo* castFrom(const DiagnosticExecutionInfo* info) {
49     CHECK(info != nullptr);
50     return reinterpret_cast<const ANeuralNetworksDiagnosticExecutionInfo*>(info);
51 }
52 
convert(DataClass dataClass)53 ANeuralNetworksDiagnosticDataClass convert(DataClass dataClass) {
54     switch (dataClass) {
55         case DataClass::UNKNOWN:
56             return ANNDIAG_DATA_CLASS_UNKNOWN;
57         case DataClass::OTHER:
58             return ANNDIAG_DATA_CLASS_OTHER;
59         case DataClass::FLOAT32:
60             return ANNDIAG_DATA_CLASS_FLOAT32;
61         case DataClass::FLOAT16:
62             return ANNDIAG_DATA_CLASS_FLOAT16;
63         case DataClass::QUANT:
64             return ANNDIAG_DATA_CLASS_QUANT;
65         case DataClass::MIXED:
66             return ANNDIAG_DATA_CLASS_MIXED;
67     }
68     LOG(FATAL) << "Unrecognized DataClass " << static_cast<int32_t>(dataClass);
69     return ANNDIAG_DATA_CLASS_UNKNOWN;
70 }
71 
convert(ExecutionMode executionMode)72 ANeuralNetworksDiagnosticExecutionMode convert(ExecutionMode executionMode) {
73     switch (executionMode) {
74         case ExecutionMode::ASYNC:
75             return ANNDIAG_EXECUTION_MODE_ASYNC;
76         case ExecutionMode::SYNC:
77             return ANNDIAG_EXECUTION_MODE_SYNC;
78         case ExecutionMode::BURST:
79             return ANNDIAG_EXECUTION_MODE_BURST;
80         case ExecutionMode::ASYNC_WITH_DEPS:
81             return ANNDIAG_EXECUTION_MODE_ASYNC_WITH_DEPS;
82     }
83     LOG(FATAL) << "Unrecognized ExecutionMode " << static_cast<int32_t>(executionMode);
84     return ANNDIAG_EXECUTION_MODE_UNKNOWN;
85 }
86 
87 }  // namespace
88 
SL_ANeuralNetworksDiagnosticCompilationInfo_getSessionId(const ANeuralNetworksDiagnosticCompilationInfo *)89 int32_t SL_ANeuralNetworksDiagnosticCompilationInfo_getSessionId(
90         const ANeuralNetworksDiagnosticCompilationInfo* /*diagnosticCompilationInfo*/) {
91     return android::nn::telemetry::getSessionId();
92 }
93 
SL_ANeuralNetworksDiagnosticCompilationInfo_getNnApiVersion(const ANeuralNetworksDiagnosticCompilationInfo *)94 int64_t SL_ANeuralNetworksDiagnosticCompilationInfo_getNnApiVersion(
95         const ANeuralNetworksDiagnosticCompilationInfo* /*diagnosticCompilationInfo*/) {
96     return android::nn::DeviceManager::get()->getRuntimeFeatureLevel();
97 }
98 
SL_ANeuralNetworksDiagnosticCompilationInfo_getModelArchHash(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)99 const uint8_t* SL_ANeuralNetworksDiagnosticCompilationInfo_getModelArchHash(
100         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
101     return castTo(diagnosticCompilationInfo)->modelArchHash;
102 }
103 
SL_ANeuralNetworksDiagnosticCompilationInfo_getDeviceIds(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)104 const char* SL_ANeuralNetworksDiagnosticCompilationInfo_getDeviceIds(
105         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
106     return castTo(diagnosticCompilationInfo)->deviceId.c_str();
107 }
108 
SL_ANeuralNetworksDiagnosticCompilationInfo_getErrorCode(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)109 int32_t SL_ANeuralNetworksDiagnosticCompilationInfo_getErrorCode(
110         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
111     return castTo(diagnosticCompilationInfo)->errorCode;
112 }
113 
SL_ANeuralNetworksDiagnosticCompilationInfo_getInputDataClass(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)114 ANeuralNetworksDiagnosticDataClass SL_ANeuralNetworksDiagnosticCompilationInfo_getInputDataClass(
115         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
116     return convert(castTo(diagnosticCompilationInfo)->inputDataClass);
117 }
118 
SL_ANeuralNetworksDiagnosticCompilationInfo_getOutputDataClass(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)119 ANeuralNetworksDiagnosticDataClass SL_ANeuralNetworksDiagnosticCompilationInfo_getOutputDataClass(
120         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
121     return convert(castTo(diagnosticCompilationInfo)->outputDataClass);
122 }
123 
SL_ANeuralNetworksDiagnosticCompilationInfo_getCompilationTimeNanos(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)124 uint64_t SL_ANeuralNetworksDiagnosticCompilationInfo_getCompilationTimeNanos(
125         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
126     return castTo(diagnosticCompilationInfo)->compilationTimeNanos;
127 }
128 
SL_ANeuralNetworksDiagnosticCompilationInfo_isCachingEnabled(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)129 bool SL_ANeuralNetworksDiagnosticCompilationInfo_isCachingEnabled(
130         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
131     return castTo(diagnosticCompilationInfo)->cacheEnabled;
132 }
133 
SL_ANeuralNetworksDiagnosticCompilationInfo_isControlFlowUsed(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)134 bool SL_ANeuralNetworksDiagnosticCompilationInfo_isControlFlowUsed(
135         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
136     return castTo(diagnosticCompilationInfo)->hasControlFlow;
137 }
138 
SL_ANeuralNetworksDiagnosticCompilationInfo_areDynamicTensorsUsed(const ANeuralNetworksDiagnosticCompilationInfo * diagnosticCompilationInfo)139 bool SL_ANeuralNetworksDiagnosticCompilationInfo_areDynamicTensorsUsed(
140         const ANeuralNetworksDiagnosticCompilationInfo* diagnosticCompilationInfo) {
141     return castTo(diagnosticCompilationInfo)->hasDynamicTemporaries;
142 }
143 
SL_ANeuralNetworksDiagnosticExecutionInfo_getSessionId(const ANeuralNetworksDiagnosticExecutionInfo *)144 int32_t SL_ANeuralNetworksDiagnosticExecutionInfo_getSessionId(
145         const ANeuralNetworksDiagnosticExecutionInfo* /*diagnosticExecutionInfo*/) {
146     return android::nn::telemetry::getSessionId();
147 }
148 
SL_ANeuralNetworksDiagnosticExecutionInfo_getNnApiVersion(const ANeuralNetworksDiagnosticExecutionInfo *)149 int64_t SL_ANeuralNetworksDiagnosticExecutionInfo_getNnApiVersion(
150         const ANeuralNetworksDiagnosticExecutionInfo* /*diagnosticExecutionInfo*/) {
151     return android::nn::DeviceManager::get()->getRuntimeFeatureLevel();
152 }
153 
SL_ANeuralNetworksDiagnosticExecutionInfo_getModelArchHash(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)154 const uint8_t* SL_ANeuralNetworksDiagnosticExecutionInfo_getModelArchHash(
155         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
156     return castTo(diagnosticExecutionInfo)->modelArchHash;
157 }
158 
SL_ANeuralNetworksDiagnosticExecutionInfo_getDeviceIds(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)159 const char* SL_ANeuralNetworksDiagnosticExecutionInfo_getDeviceIds(
160         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
161     return castTo(diagnosticExecutionInfo)->deviceId.c_str();
162 }
163 
SL_ANeuralNetworksDiagnosticExecutionInfo_getExecutionMode(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)164 ANeuralNetworksDiagnosticExecutionMode SL_ANeuralNetworksDiagnosticExecutionInfo_getExecutionMode(
165         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
166     return convert(castTo(diagnosticExecutionInfo)->executionMode);
167 }
168 
SL_ANeuralNetworksDiagnosticExecutionInfo_getInputDataClass(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)169 ANeuralNetworksDiagnosticDataClass SL_ANeuralNetworksDiagnosticExecutionInfo_getInputDataClass(
170         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
171     return convert(castTo(diagnosticExecutionInfo)->inputDataClass);
172 }
173 
SL_ANeuralNetworksDiagnosticExecutionInfo_getOutputDataClass(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)174 ANeuralNetworksDiagnosticDataClass SL_ANeuralNetworksDiagnosticExecutionInfo_getOutputDataClass(
175         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
176     return convert(castTo(diagnosticExecutionInfo)->outputDataClass);
177 }
178 
SL_ANeuralNetworksDiagnosticExecutionInfo_getErrorCode(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)179 uint32_t SL_ANeuralNetworksDiagnosticExecutionInfo_getErrorCode(
180         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
181     return castTo(diagnosticExecutionInfo)->errorCode;
182 }
183 
SL_ANeuralNetworksDiagnosticExecutionInfo_getRuntimeExecutionTimeNanos(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)184 uint64_t SL_ANeuralNetworksDiagnosticExecutionInfo_getRuntimeExecutionTimeNanos(
185         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
186     return castTo(diagnosticExecutionInfo)->durationRuntimeNanos;
187 }
188 
SL_ANeuralNetworksDiagnosticExecutionInfo_getDriverExecutionTimeNanos(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)189 uint64_t SL_ANeuralNetworksDiagnosticExecutionInfo_getDriverExecutionTimeNanos(
190         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
191     return castTo(diagnosticExecutionInfo)->durationDriverNanos;
192 }
193 
SL_ANeuralNetworksDiagnosticExecutionInfo_getHardwareExecutionTimeNanos(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)194 uint64_t SL_ANeuralNetworksDiagnosticExecutionInfo_getHardwareExecutionTimeNanos(
195         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
196     return castTo(diagnosticExecutionInfo)->durationHardwareNanos;
197 }
198 
SL_ANeuralNetworksDiagnosticExecutionInfo_isCachingEnabled(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)199 bool SL_ANeuralNetworksDiagnosticExecutionInfo_isCachingEnabled(
200         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
201     return castTo(diagnosticExecutionInfo)->cacheEnabled;
202 }
203 
SL_ANeuralNetworksDiagnosticExecutionInfo_isControlFlowUsed(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)204 bool SL_ANeuralNetworksDiagnosticExecutionInfo_isControlFlowUsed(
205         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
206     return castTo(diagnosticExecutionInfo)->hasControlFlow;
207 }
208 
SL_ANeuralNetworksDiagnosticExecutionInfo_areDynamicTensorsUsed(const ANeuralNetworksDiagnosticExecutionInfo * diagnosticExecutionInfo)209 bool SL_ANeuralNetworksDiagnosticExecutionInfo_areDynamicTensorsUsed(
210         const ANeuralNetworksDiagnosticExecutionInfo* diagnosticExecutionInfo) {
211     return castTo(diagnosticExecutionInfo)->hasDynamicTemporaries;
212 }
213 
SL_ANeuralNetworksDiagnostic_registerCallbacks(ANeuralNetworksDiagnosticCompilationFinishedCallback compilationCallback,ANeuralNetworksDiagnosticExecutionFinishedCallback executionCallback,void * callbackContext)214 void SL_ANeuralNetworksDiagnostic_registerCallbacks(
215         ANeuralNetworksDiagnosticCompilationFinishedCallback compilationCallback,
216         ANeuralNetworksDiagnosticExecutionFinishedCallback executionCallback,
217         void* callbackContext) {
218     using android::nn::telemetry::registerTelemetryCallbacks;
219 
220     std::function<void(const DiagnosticCompilationInfo*)> compilation =
221             [compilationCallback, callbackContext](const DiagnosticCompilationInfo* info) {
222                 compilationCallback(callbackContext, castFrom(info));
223             };
224     std::function<void(const DiagnosticExecutionInfo*)> execution =
225             [executionCallback, callbackContext](const DiagnosticExecutionInfo* info) {
226                 executionCallback(callbackContext, castFrom(info));
227             };
228 
229     registerTelemetryCallbacks(std::move(compilation), std::move(execution));
230 }
231