1 /*
2 * Copyright (C) 2017 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 #include <android-base/scopeguard.h>
19 // android/log.h contains __INTRODUCED_IN() macro and must be included before
20 // sharedmem.h
21 #include <android/log.h>
22 #include <android/sharedmem.h>
23 #include <gtest/gtest.h>
24 #include <sys/mman.h>
25
26 #include <algorithm>
27 #include <future>
28 #include <limits>
29 #include <set>
30 #include <string>
31 #include <utility>
32 #include <vector>
33
34 #include "AndroidVersionUtil.h"
35 #include "NeuralNetworks.h"
36 #include "NeuralNetworksOEM.h"
37
38 #ifndef NNTEST_ONLY_PUBLIC_API
39 #include "NeuralNetworksExtensions.h"
40 #include "TypeManager.h"
41 #endif
42
43 // This file tests all the validations done by the Neural Networks API.
44
45 namespace {
46
47 constexpr uint64_t kShortWaitInNanoseconds = 1'000'000'000; // 1 second
48
49 class ValidationTest : public ::testing::Test {
50 protected:
SetUp()51 virtual void SetUp() {}
52 };
53
54 class ValidationTestModel : public ValidationTest {
55 protected:
SetUp()56 virtual void SetUp() {
57 ValidationTest::SetUp();
58 ASSERT_EQ(ANeuralNetworksModel_create(&mModel), ANEURALNETWORKS_NO_ERROR);
59 }
TearDown()60 virtual void TearDown() {
61 ANeuralNetworksModel_free(mModel);
62 ValidationTest::TearDown();
63 }
64
addScalarOperand(int32_t type=ANEURALNETWORKS_INT32)65 uint32_t addScalarOperand(int32_t type = ANEURALNETWORKS_INT32) {
66 ANeuralNetworksOperandType operandType = {
67 .type = type, .dimensionCount = 0, .dimensions = nullptr};
68 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &operandType), ANEURALNETWORKS_NO_ERROR);
69 return mNumOperands++;
70 }
71
addOperand(const ANeuralNetworksOperandType & operandType)72 uint32_t addOperand(const ANeuralNetworksOperandType& operandType) {
73 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &operandType), ANEURALNETWORKS_NO_ERROR);
74 return mNumOperands++;
75 }
76
addTensorOperand(int32_t type=ANEURALNETWORKS_TENSOR_FLOAT32)77 uint32_t addTensorOperand(int32_t type = ANEURALNETWORKS_TENSOR_FLOAT32) {
78 return addTensorOperand(type, {2});
79 }
80
addTensorOperand(int32_t type,const std::vector<uint32_t> & dimensions)81 uint32_t addTensorOperand(int32_t type, const std::vector<uint32_t>& dimensions) {
82 ANeuralNetworksOperandType operandType = {
83 .type = type,
84 .dimensionCount = static_cast<uint32_t>(dimensions.size()),
85 .dimensions = dimensions.data(),
86 };
87 return addOperand(operandType);
88 }
89
addOperation(ANeuralNetworksOperationType type,const std::vector<uint32_t> & inputs,const std::vector<uint32_t> & outputs)90 int addOperation(ANeuralNetworksOperationType type, const std::vector<uint32_t>& inputs,
91 const std::vector<uint32_t>& outputs) {
92 ++mNumOperations;
93 return ANeuralNetworksModel_addOperation(mModel, type, inputs.size(), inputs.data(),
94 outputs.size(), outputs.data());
95 }
identifyInputsAndOutputs(const std::vector<uint32_t> & inputs,const std::vector<uint32_t> & outputs)96 int identifyInputsAndOutputs(const std::vector<uint32_t>& inputs,
97 const std::vector<uint32_t>& outputs) {
98 return ANeuralNetworksModel_identifyInputsAndOutputs(mModel, inputs.size(), inputs.data(),
99 outputs.size(), outputs.data());
100 }
modelFinish()101 int modelFinish() { return ANeuralNetworksModel_finish(mModel); }
102
createModel()103 virtual void createModel() {
104 addTensorOperand();
105 addTensorOperand();
106 addScalarOperand();
107 addTensorOperand();
108 const std::vector<uint32_t> inList = {0, 1, 2};
109 const std::vector<uint32_t> outList = {3};
110 ASSERT_EQ(addOperation(ANEURALNETWORKS_ADD, inList, outList), ANEURALNETWORKS_NO_ERROR);
111 ASSERT_EQ(identifyInputsAndOutputs(inList, outList), ANEURALNETWORKS_NO_ERROR);
112 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_NO_ERROR);
113 }
114
115 uint32_t mNumOperands = 0;
116 uint32_t mNumOperations = 0;
117 ANeuralNetworksModel* mModel = nullptr;
118
119 const uint32_t kDummyDimensionValue = 1;
120 const ANeuralNetworksOperandType kInvalidTensorType1{
121 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
122 // dimensionCount must be consistent with dimensions.
123 .dimensionCount = 1,
124 .dimensions = nullptr,
125 };
126 const ANeuralNetworksOperandType kInvalidTensorType2{
127 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
128 // dimensionCount must be consistent with dimensions.
129 .dimensionCount = 0,
130 .dimensions = &kDummyDimensionValue,
131 };
132 };
133
134 #ifndef NNTEST_ONLY_PUBLIC_API
135 constexpr const char* kTestExtensionName = "com.android.test_extension";
136 constexpr int32_t kTestExtensionTensorType = ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL;
137
138 class ValidationTestModelExtensions : public ValidationTestModel {
139 protected:
SetUp()140 virtual void SetUp() {
141 ValidationTestModel::SetUp();
142 EXPECT_TRUE(::android::nn::TypeManager::get()->forTest_registerExtension({
143 .name = kTestExtensionName,
144 .operandTypes =
145 {
146 {
147 .type = kTestExtensionTensorType,
148 .isTensor = true,
149 .byteSize = 1,
150 },
151 },
152 }));
153 }
154
TearDown()155 virtual void TearDown() {
156 ::android::nn::TypeManager::get()->forTest_reset();
157 ValidationTestModel::TearDown();
158 }
159
getExtensionOperandType(uint16_t typeWithinExtension)160 int32_t getExtensionOperandType(uint16_t typeWithinExtension) {
161 int32_t result;
162 EXPECT_EQ(ANeuralNetworksModel_getExtensionOperandType(mModel, kTestExtensionName,
163 typeWithinExtension, &result),
164 ANEURALNETWORKS_NO_ERROR);
165 return result;
166 }
167 };
168 #endif
169
170 class ValidationTestIdentify : public ValidationTestModel {
SetUp()171 virtual void SetUp() {
172 ValidationTestModel::SetUp();
173
174 uint32_t dimensions[]{1};
175 ANeuralNetworksOperandType tensorType{.type = ANEURALNETWORKS_TENSOR_FLOAT32,
176 .dimensionCount = 1,
177 .dimensions = dimensions};
178 ANeuralNetworksOperandType scalarType{
179 .type = ANEURALNETWORKS_INT32, .dimensionCount = 0, .dimensions = nullptr};
180 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
181 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
182 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &scalarType), ANEURALNETWORKS_NO_ERROR);
183 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
184 ASSERT_EQ(addOperation(ANEURALNETWORKS_ADD, {0, 1, 2}, {3}), ANEURALNETWORKS_NO_ERROR);
185 }
TearDown()186 virtual void TearDown() { ValidationTestModel::TearDown(); }
187 };
188
189 class ValidationTestCompilation : public ValidationTestModel {
190 protected:
SetUp()191 virtual void SetUp() {
192 ValidationTestModel::SetUp();
193 createModel();
194 ASSERT_EQ(ANeuralNetworksCompilation_create(mModel, &mCompilation),
195 ANEURALNETWORKS_NO_ERROR);
196 }
197
TearDown()198 virtual void TearDown() {
199 ANeuralNetworksCompilation_free(mCompilation);
200 ValidationTestModel::TearDown();
201 }
202
203 ANeuralNetworksCompilation* mCompilation = nullptr;
204 };
205
206 class ValidationTestExecution : public ValidationTestCompilation {
207 protected:
SetUp()208 virtual void SetUp() {
209 ValidationTestCompilation::SetUp();
210
211 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
212
213 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &mExecution),
214 ANEURALNETWORKS_NO_ERROR);
215 }
TearDown()216 virtual void TearDown() {
217 ANeuralNetworksExecution_free(mExecution);
218 ValidationTestCompilation::TearDown();
219 }
220 ANeuralNetworksExecution* mExecution = nullptr;
221 };
222
223 class ValidationTestBurst : public ValidationTestExecution {
224 protected:
SetUp()225 virtual void SetUp() {
226 ValidationTestExecution::SetUp();
227
228 ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &mBurst), ANEURALNETWORKS_NO_ERROR);
229 }
TearDown()230 virtual void TearDown() {
231 ANeuralNetworksBurst_free(mBurst);
232 ValidationTestExecution::TearDown();
233 }
234 ANeuralNetworksBurst* mBurst = nullptr;
235 };
236
237 class ValidationTestMemoryDesc : public ValidationTestCompilation {
238 protected:
SetUp()239 virtual void SetUp() {
240 ValidationTestCompilation::SetUp();
241 ASSERT_EQ(ANeuralNetworksMemoryDesc_create(&mDesc), ANEURALNETWORKS_NO_ERROR);
242 }
TearDown()243 virtual void TearDown() {
244 ANeuralNetworksMemoryDesc_free(mDesc);
245 for (auto* memory : mMemories) ANeuralNetworksMemory_free(memory);
246 for (int fd : mFds) close(fd);
247 ValidationTestCompilation::TearDown();
248 }
249
createAshmem(uint32_t size)250 ANeuralNetworksMemory* createAshmem(uint32_t size) {
251 int fd = ASharedMemory_create("nnMemory", size);
252 EXPECT_GT(fd, 0);
253 mFds.push_back(fd);
254 ANeuralNetworksMemory* ashmem = nullptr;
255 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(size, PROT_READ | PROT_WRITE, fd, 0, &ashmem),
256 ANEURALNETWORKS_NO_ERROR);
257 mMemories.push_back(ashmem);
258 return ashmem;
259 }
260
261 ANeuralNetworksMemoryDesc* mDesc = nullptr;
262 std::vector<ANeuralNetworksMemory*> mMemories;
263 std::vector<int> mFds;
264 };
265
266 class ValidationTestExecutionDeviceMemory : public ValidationTest {
267 protected:
SetUp()268 virtual void SetUp() {
269 ValidationTest::SetUp();
270 ASSERT_EQ(ANeuralNetworksModel_create(&mModel), ANEURALNETWORKS_NO_ERROR);
271 createModel(mModel, /*dimensionsUnspecified=*/false, /*isValid=*/true);
272 ASSERT_EQ(ANeuralNetworksCompilation_create(mModel, &mCompilation),
273 ANEURALNETWORKS_NO_ERROR);
274 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
275 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &mExecution),
276 ANEURALNETWORKS_NO_ERROR);
277
278 ASSERT_EQ(ANeuralNetworksModel_create(&mModelDynamic), ANEURALNETWORKS_NO_ERROR);
279 createModel(mModelDynamic, /*dimensionsUnspecified=*/true, /*isValid=*/true);
280 ASSERT_EQ(ANeuralNetworksCompilation_create(mModelDynamic, &mCompilationDynamic),
281 ANEURALNETWORKS_NO_ERROR);
282 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilationDynamic), ANEURALNETWORKS_NO_ERROR);
283 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilationDynamic, &mExecutionDynamic),
284 ANEURALNETWORKS_NO_ERROR);
285
286 ASSERT_EQ(ANeuralNetworksModel_create(&mInitModel), ANEURALNETWORKS_NO_ERROR);
287 createModel(mInitModel, /*dimensionsUnspecified=*/false, /*isValid=*/true);
288 ASSERT_EQ(ANeuralNetworksCompilation_create(mInitModel, &mInitCompilation),
289 ANEURALNETWORKS_NO_ERROR);
290 ASSERT_EQ(ANeuralNetworksCompilation_finish(mInitCompilation), ANEURALNETWORKS_NO_ERROR);
291
292 ASSERT_EQ(ANeuralNetworksModel_create(&mDeinitModel), ANEURALNETWORKS_NO_ERROR);
293 createModel(mDeinitModel, /*dimensionsUnspecified=*/false, /*isValid=*/false);
294 ASSERT_EQ(ANeuralNetworksCompilation_create(mDeinitModel, &mDeinitCompilation),
295 ANEURALNETWORKS_NO_ERROR);
296 ASSERT_EQ(ANeuralNetworksCompilation_finish(mDeinitCompilation), ANEURALNETWORKS_NO_ERROR);
297 }
TearDown()298 virtual void TearDown() {
299 ANeuralNetworksExecution_free(mExecution);
300 ANeuralNetworksCompilation_free(mCompilation);
301 ANeuralNetworksModel_free(mModel);
302 ANeuralNetworksExecution_free(mExecutionDynamic);
303 ANeuralNetworksCompilation_free(mCompilationDynamic);
304 ANeuralNetworksModel_free(mModelDynamic);
305
306 ANeuralNetworksCompilation_free(mInitCompilation);
307 ANeuralNetworksModel_free(mInitModel);
308 ANeuralNetworksCompilation_free(mDeinitCompilation);
309 ANeuralNetworksModel_free(mDeinitModel);
310
311 ValidationTest::TearDown();
312 }
313
addScalarOperand(ANeuralNetworksModel * model)314 void addScalarOperand(ANeuralNetworksModel* model) {
315 ANeuralNetworksOperandType operandType = {
316 .type = ANEURALNETWORKS_INT32, .dimensionCount = 0, .dimensions = nullptr};
317 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &operandType), ANEURALNETWORKS_NO_ERROR);
318 }
319
addTensorOperand(ANeuralNetworksModel * model,bool dimensionsUnspecified)320 void addTensorOperand(ANeuralNetworksModel* model, bool dimensionsUnspecified) {
321 uint32_t dimension = dimensionsUnspecified ? 0 : 1;
322 ANeuralNetworksOperandType operandType = {
323 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
324 .dimensionCount = 1,
325 .dimensions = &dimension,
326 };
327 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &operandType), ANEURALNETWORKS_NO_ERROR);
328 }
329
createModel(ANeuralNetworksModel * model,bool dimensionsUnspecified,bool isValid)330 void createModel(ANeuralNetworksModel* model, bool dimensionsUnspecified, bool isValid) {
331 const float constData = 0;
332 const uint32_t actData = isValid ? 0 : 999;
333
334 addTensorOperand(model, dimensionsUnspecified);
335 addTensorOperand(model, /*dimensionsUnspecified=*/false);
336 addScalarOperand(model);
337 addTensorOperand(model, dimensionsUnspecified);
338
339 ASSERT_EQ(ANeuralNetworksModel_setOperandValue(model, 1, &constData, sizeof(float)),
340 ANEURALNETWORKS_NO_ERROR);
341 ASSERT_EQ(ANeuralNetworksModel_setOperandValue(model, 2, &actData, sizeof(uint32_t)),
342 ANEURALNETWORKS_NO_ERROR);
343
344 uint32_t inList[] = {0, 1, 2}, outList[] = {3};
345 ASSERT_EQ(ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_ADD, 3, inList, 1,
346 outList),
347 ANEURALNETWORKS_NO_ERROR);
348 uint32_t inputList[] = {0}, outputList[] = {3};
349 ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(model, 1, inputList, 1, outputList),
350 ANEURALNETWORKS_NO_ERROR);
351 ASSERT_EQ(ANeuralNetworksModel_finish(model), ANEURALNETWORKS_NO_ERROR);
352 }
353
executeWithMemoryAsInput(ANeuralNetworksCompilation * compilation,ANeuralNetworksMemory * memory,int expectedResult)354 void executeWithMemoryAsInput(ANeuralNetworksCompilation* compilation,
355 ANeuralNetworksMemory* memory, int expectedResult) {
356 float data = 0;
357 ANeuralNetworksExecution* execution = nullptr;
358 ASSERT_EQ(ANeuralNetworksExecution_create(compilation, &execution),
359 ANEURALNETWORKS_NO_ERROR);
360 ASSERT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr, memory, 0, 0),
361 ANEURALNETWORKS_NO_ERROR);
362 ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &data, sizeof(float)),
363 ANEURALNETWORKS_NO_ERROR);
364 ASSERT_EQ(ANeuralNetworksExecution_compute(execution), expectedResult);
365 ANeuralNetworksExecution_free(execution);
366 }
367
executeWithMemoryAsOutput(ANeuralNetworksCompilation * compilation,ANeuralNetworksMemory * memory,int expectedResult)368 void executeWithMemoryAsOutput(ANeuralNetworksCompilation* compilation,
369 ANeuralNetworksMemory* memory, int expectedResult) {
370 const float data = 0;
371 ANeuralNetworksExecution* execution = nullptr;
372 ASSERT_EQ(ANeuralNetworksExecution_create(compilation, &execution),
373 ANEURALNETWORKS_NO_ERROR);
374 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &data, sizeof(float)),
375 ANEURALNETWORKS_NO_ERROR);
376 ASSERT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0, 0),
377 ANEURALNETWORKS_NO_ERROR);
378 ASSERT_EQ(ANeuralNetworksExecution_compute(execution), expectedResult);
379 ANeuralNetworksExecution_free(execution);
380 }
381
382 ANeuralNetworksModel* mModel = nullptr;
383 ANeuralNetworksCompilation* mCompilation = nullptr;
384 ANeuralNetworksExecution* mExecution = nullptr;
385
386 ANeuralNetworksModel* mModelDynamic = nullptr;
387 ANeuralNetworksCompilation* mCompilationDynamic = nullptr;
388 ANeuralNetworksExecution* mExecutionDynamic = nullptr;
389
390 ANeuralNetworksModel* mInitModel = nullptr;
391 ANeuralNetworksCompilation* mInitCompilation = nullptr;
392 ANeuralNetworksModel* mDeinitModel = nullptr;
393 ANeuralNetworksCompilation* mDeinitCompilation = nullptr;
394 };
395
TEST_F(ValidationTest,CreateModel)396 TEST_F(ValidationTest, CreateModel) {
397 EXPECT_EQ(ANeuralNetworksModel_create(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
398 }
399
TEST_F(ValidationTestModel,AddOperand)400 TEST_F(ValidationTestModel, AddOperand) {
401 ANeuralNetworksOperandType floatType{
402 .type = ANEURALNETWORKS_FLOAT32, .dimensionCount = 0, .dimensions = nullptr};
403 EXPECT_EQ(ANeuralNetworksModel_addOperand(nullptr, &floatType),
404 ANEURALNETWORKS_UNEXPECTED_NULL);
405 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
406
407 ANeuralNetworksOperandType quant8TypeInvalidScale{
408 .type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
409 .dimensionCount = 0,
410 .dimensions = nullptr,
411 // Scale has to be non-negative
412 .scale = -1.0f,
413 .zeroPoint = 0,
414 };
415 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &quant8TypeInvalidScale),
416 ANEURALNETWORKS_BAD_DATA);
417
418 ANeuralNetworksOperandType quant8TypeInvalidZeroPoint{
419 .type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
420 .dimensionCount = 0,
421 .dimensions = nullptr,
422 .scale = 1.0f,
423 // zeroPoint has to be in [0, 255]
424 .zeroPoint = -1,
425 };
426 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &quant8TypeInvalidZeroPoint),
427 ANEURALNETWORKS_BAD_DATA);
428
429 const uint32_t dim = 2;
430 ANeuralNetworksOperandType invalidScalarType{
431 .type = ANEURALNETWORKS_INT32,
432 // a scalar type must have 0 dimensions.
433 .dimensionCount = 1,
434 .dimensions = &dim,
435 };
436 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &invalidScalarType),
437 ANEURALNETWORKS_BAD_DATA);
438
439 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &kInvalidTensorType1),
440 ANEURALNETWORKS_BAD_DATA);
441 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &kInvalidTensorType2),
442 ANEURALNETWORKS_BAD_DATA);
443
444 modelFinish();
445 // This should fail, as the model is already finished.
446 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_BAD_STATE);
447 }
448
TEST_F(ValidationTestModel,SetOperandSymmPerChannelQuantParams)449 TEST_F(ValidationTestModel, SetOperandSymmPerChannelQuantParams) {
450 const int32_t operandIndex = addTensorOperand(ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
451
452 float scales[2] = {1.0, 2.0};
453 ANeuralNetworksSymmPerChannelQuantParams channelQuant = {
454 .channelDim = 0,
455 .scaleCount = 2,
456 .scales = scales,
457 };
458
459 EXPECT_EQ(ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(nullptr, operandIndex,
460 &channelQuant),
461 ANEURALNETWORKS_UNEXPECTED_NULL);
462 EXPECT_EQ(
463 ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(mModel, operandIndex, nullptr),
464 ANEURALNETWORKS_UNEXPECTED_NULL);
465 EXPECT_EQ(ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(mModel, operandIndex + 1,
466 &channelQuant),
467 ANEURALNETWORKS_BAD_DATA);
468 EXPECT_EQ(ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(mModel, operandIndex,
469 &channelQuant),
470 ANEURALNETWORKS_NO_ERROR);
471 }
472
473 #ifndef NNTEST_ONLY_PUBLIC_API
TEST_F(ValidationTestModelExtensions,AddOperand_UnknownPrefix)474 TEST_F(ValidationTestModelExtensions, AddOperand_UnknownPrefix) {
475 ANeuralNetworksOperandType type = {.type = -1};
476 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &type), ANEURALNETWORKS_BAD_DATA);
477 }
478
TEST_F(ValidationTestModelExtensions,SetOperandSymmPerChannelQuantParams_ExtensionOperand)479 TEST_F(ValidationTestModelExtensions, SetOperandSymmPerChannelQuantParams_ExtensionOperand) {
480 const int32_t operandIndex =
481 addTensorOperand(getExtensionOperandType(kTestExtensionTensorType));
482
483 float scales[2] = {1.0, 2.0};
484 ANeuralNetworksSymmPerChannelQuantParams channelQuant = {
485 .channelDim = 0,
486 .scaleCount = 2,
487 .scales = scales,
488 };
489
490 EXPECT_EQ(ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(mModel, operandIndex,
491 &channelQuant),
492 ANEURALNETWORKS_BAD_DATA);
493 }
494
TEST_F(ValidationTestModelExtensions,SetOperandExtensionData)495 TEST_F(ValidationTestModelExtensions, SetOperandExtensionData) {
496 const int32_t operandIndex =
497 addTensorOperand(getExtensionOperandType(kTestExtensionTensorType));
498 const int32_t data = 42;
499 const size_t dataLength = sizeof(data);
500 EXPECT_EQ(
501 ANeuralNetworksModel_setOperandExtensionData(nullptr, operandIndex, &data, dataLength),
502 ANEURALNETWORKS_UNEXPECTED_NULL);
503 EXPECT_EQ(
504 ANeuralNetworksModel_setOperandExtensionData(mModel, operandIndex, nullptr, dataLength),
505 ANEURALNETWORKS_UNEXPECTED_NULL);
506 EXPECT_EQ(ANeuralNetworksModel_setOperandExtensionData(mModel, operandIndex, &data, 0),
507 ANEURALNETWORKS_BAD_DATA);
508 EXPECT_EQ(ANeuralNetworksModel_setOperandExtensionData(mModel, operandIndex + 1, &data,
509 dataLength),
510 ANEURALNETWORKS_BAD_DATA);
511 EXPECT_EQ(ANeuralNetworksModel_setOperandExtensionData(mModel, operandIndex, &data, dataLength),
512 ANEURALNETWORKS_NO_ERROR);
513 }
514
TEST_F(ValidationTestModelExtensions,SetOperandExtensionData_Empty)515 TEST_F(ValidationTestModelExtensions, SetOperandExtensionData_Empty) {
516 const int32_t operandIndex =
517 addTensorOperand(getExtensionOperandType(kTestExtensionTensorType));
518 EXPECT_EQ(ANeuralNetworksModel_setOperandExtensionData(mModel, operandIndex, nullptr, 0),
519 ANEURALNETWORKS_NO_ERROR);
520 }
521
TEST_F(ValidationTestModelExtensions,SetOperandExtensionData_NonExtensionOperand)522 TEST_F(ValidationTestModelExtensions, SetOperandExtensionData_NonExtensionOperand) {
523 const int32_t operandIndex = addTensorOperand();
524 const int32_t data = 42;
525 const size_t dataLength = sizeof(data);
526 EXPECT_EQ(ANeuralNetworksModel_setOperandExtensionData(mModel, operandIndex, &data, dataLength),
527 ANEURALNETWORKS_BAD_DATA);
528 }
529
TEST_F(ValidationTestModelExtensions,SetOperandValue_UnspecifiedDimension)530 TEST_F(ValidationTestModelExtensions, SetOperandValue_UnspecifiedDimension) {
531 const uint32_t dimensions[2] = {3, 0};
532 ANeuralNetworksOperandType type = {
533 .type = getExtensionOperandType(kTestExtensionTensorType),
534 .dimensionCount = 2,
535 .dimensions = dimensions,
536 };
537 const int32_t operandIndex = addOperand(type);
538 char buffer[20];
539 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, operandIndex, buffer, sizeof(buffer)),
540 ANEURALNETWORKS_BAD_DATA);
541 }
542
TEST_F(ValidationTestModelExtensions,SetOperandValue_UnspecifiedRank)543 TEST_F(ValidationTestModelExtensions, SetOperandValue_UnspecifiedRank) {
544 ANeuralNetworksOperandType type = {
545 .type = getExtensionOperandType(kTestExtensionTensorType),
546 .dimensionCount = 0,
547 .dimensions = nullptr,
548 };
549 const int32_t operandIndex = addOperand(type);
550 char buffer[20];
551 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, operandIndex, buffer, sizeof(buffer)),
552 ANEURALNETWORKS_BAD_DATA);
553 }
554
TEST_F(ValidationTestModelExtensions,AddOperandDimensionProductOverflow)555 TEST_F(ValidationTestModelExtensions, AddOperandDimensionProductOverflow) {
556 uint32_t dimensions[] = {5, 4, 4, 786433, 5, 3, 16777216, 4, 5};
557 ANeuralNetworksOperandType operandType = {
558 .type = getExtensionOperandType(kTestExtensionTensorType),
559 .dimensionCount = std::size(dimensions),
560 .dimensions = dimensions,
561 };
562 // This should fail, as the operand type's dimension product overflows uint32_t.
563 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &operandType), ANEURALNETWORKS_BAD_DATA);
564 }
565 #endif
566
TEST_F(ValidationTestModel,SetOptionalOperand)567 TEST_F(ValidationTestModel, SetOptionalOperand) {
568 ANeuralNetworksOperandType floatType{
569 .type = ANEURALNETWORKS_FLOAT32, .dimensionCount = 0, .dimensions = nullptr};
570 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
571
572 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, nullptr, 0),
573 ANEURALNETWORKS_NO_ERROR);
574 }
575
TEST_F(ValidationTestModel,SetOperandValue)576 TEST_F(ValidationTestModel, SetOperandValue) {
577 ANeuralNetworksOperandType floatType{
578 .type = ANEURALNETWORKS_FLOAT32, .dimensionCount = 0, .dimensions = nullptr};
579 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
580
581 char buffer[20];
582 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(nullptr, 0, buffer, sizeof(buffer)),
583 ANEURALNETWORKS_UNEXPECTED_NULL);
584 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, nullptr, sizeof(buffer)),
585 ANEURALNETWORKS_UNEXPECTED_NULL);
586
587 // This should fail, because buffer is not the size of a float32.
588 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(buffer)),
589 ANEURALNETWORKS_BAD_DATA);
590
591 // This should succeed.
592 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(float)),
593 ANEURALNETWORKS_NO_ERROR);
594
595 // This should fail, as this operand does not exist.
596 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 1, buffer, sizeof(float)),
597 ANEURALNETWORKS_BAD_DATA);
598
599 modelFinish();
600 // This should fail, as the model is already finished.
601 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(float)),
602 ANEURALNETWORKS_BAD_STATE);
603 }
604
TEST_F(ValidationTestModel,SetOperandValueFromMemory)605 TEST_F(ValidationTestModel, SetOperandValueFromMemory) {
606 uint32_t dimensions[]{1};
607 ANeuralNetworksOperandType floatType{
608 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
609 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
610
611 const size_t memorySize = 20;
612 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
613 ASSERT_GT(memoryFd, 0);
614
615 ANeuralNetworksMemory* memory;
616 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd, 0,
617 &memory),
618 ANEURALNETWORKS_NO_ERROR);
619
620 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(nullptr, 0, memory, 0, sizeof(float)),
621 ANEURALNETWORKS_UNEXPECTED_NULL);
622 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, nullptr, 0, sizeof(float)),
623 ANEURALNETWORKS_UNEXPECTED_NULL);
624
625 // This should fail, because the operand does not exist.
626 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, -1, memory, 0, sizeof(float)),
627 ANEURALNETWORKS_BAD_DATA);
628
629 // This should fail, because memory is not the size of a float32.
630 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, 0, memorySize),
631 ANEURALNETWORKS_BAD_DATA);
632
633 // This should fail, as this operand does not exist.
634 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 1, memory, 0, sizeof(float)),
635 ANEURALNETWORKS_BAD_DATA);
636
637 // This should fail, because offset is larger than memorySize.
638 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, memorySize + 1,
639 sizeof(float)),
640 ANEURALNETWORKS_BAD_DATA);
641
642 // This should fail, because requested size is larger than the memory.
643 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, memorySize - 3,
644 sizeof(float)),
645 ANEURALNETWORKS_BAD_DATA);
646
647 modelFinish();
648 // This should fail, as the model is already finished.
649 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, 0, sizeof(float)),
650 ANEURALNETWORKS_BAD_STATE);
651
652 // close memory
653 ANeuralNetworksMemory_free(memory);
654 close(memoryFd);
655 }
656
TEST_F(ValidationTestModel,SetOperandValueFromAHardwareBuffer)657 TEST_F(ValidationTestModel, SetOperandValueFromAHardwareBuffer) {
658 uint32_t dimensions[]{1};
659 ANeuralNetworksOperandType quant8Type{.type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
660 .dimensionCount = 1,
661 .dimensions = dimensions,
662 .scale = 1.0,
663 .zeroPoint = 0};
664 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &quant8Type), ANEURALNETWORKS_NO_ERROR);
665
666 AHardwareBuffer_Desc desc{
667 .width = 16,
668 .height = 16,
669 .layers = 1,
670 .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
671 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
672 };
673
674 AHardwareBuffer* buffer = nullptr;
675 ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
676
677 ANeuralNetworksMemory* memory;
678 EXPECT_EQ(ANeuralNetworksMemory_createFromAHardwareBuffer(buffer, &memory),
679 ANEURALNETWORKS_NO_ERROR);
680
681 // This should fail, because non-BLOB AHardwareBuffer is not allowed.
682 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, 0, sizeof(uint8_t)),
683 ANEURALNETWORKS_BAD_DATA);
684
685 // close memory
686 ANeuralNetworksMemory_free(memory);
687 AHardwareBuffer_release(buffer);
688 }
689
TEST_F(ValidationTestModel,SetOperandValueFromAHardwareBufferBlob)690 TEST_F(ValidationTestModel, SetOperandValueFromAHardwareBufferBlob) {
691 uint32_t dimensions[]{1};
692 ANeuralNetworksOperandType floatType{
693 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
694 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
695
696 const size_t memorySize = 20;
697 AHardwareBuffer_Desc desc{
698 .width = memorySize,
699 .height = 1,
700 .layers = 1,
701 .format = AHARDWAREBUFFER_FORMAT_BLOB,
702 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
703 };
704
705 AHardwareBuffer* buffer = nullptr;
706 ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
707
708 ANeuralNetworksMemory* memory;
709 EXPECT_EQ(ANeuralNetworksMemory_createFromAHardwareBuffer(buffer, &memory),
710 ANEURALNETWORKS_NO_ERROR);
711
712 // This should fail, because offset is larger than memorySize.
713 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, memorySize + 1,
714 sizeof(float)),
715 ANEURALNETWORKS_BAD_DATA);
716
717 // This should fail, because requested size is larger than the memory.
718 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0, memory, memorySize - 3,
719 sizeof(float)),
720 ANEURALNETWORKS_BAD_DATA);
721
722 // close memory
723 ANeuralNetworksMemory_free(memory);
724 AHardwareBuffer_release(buffer);
725 }
726
TEST_F(ValidationTestModel,SetOperandValueFromModel)727 TEST_F(ValidationTestModel, SetOperandValueFromModel) {
728 uint32_t dimensions[] = {2};
729 ANeuralNetworksOperandType tensorType = {
730 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
731 .dimensionCount = std::size(dimensions),
732 .dimensions = dimensions,
733 };
734 ANeuralNetworksOperandType scalarType = {.type = ANEURALNETWORKS_INT32};
735 ANeuralNetworksOperandType modelType = {.type = ANEURALNETWORKS_MODEL};
736
737 ANeuralNetworksModel* valueModel = nullptr;
738 ASSERT_EQ(ANeuralNetworksModel_create(&valueModel), ANEURALNETWORKS_NO_ERROR);
739 ASSERT_EQ(ANeuralNetworksModel_addOperand(valueModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
740 ASSERT_EQ(ANeuralNetworksModel_addOperand(valueModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
741 ASSERT_EQ(ANeuralNetworksModel_addOperand(valueModel, &scalarType), ANEURALNETWORKS_NO_ERROR);
742 ASSERT_EQ(ANeuralNetworksModel_addOperand(valueModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
743 uint32_t inList[3] = {0, 1, 2};
744 uint32_t outList[1] = {3};
745 ASSERT_EQ(ANeuralNetworksModel_addOperation(valueModel, ANEURALNETWORKS_ADD, 3, inList, 1,
746 outList),
747 ANEURALNETWORKS_NO_ERROR);
748 ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(valueModel, 3, inList, 1, outList),
749 ANEURALNETWORKS_NO_ERROR);
750
751 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &modelType), ANEURALNETWORKS_NO_ERROR);
752
753 // This should fail, as the value model is not finished.
754 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromModel(mModel, 0, valueModel),
755 ANEURALNETWORKS_BAD_STATE);
756 ANeuralNetworksModel_finish(valueModel);
757
758 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromModel(nullptr, 0, valueModel),
759 ANEURALNETWORKS_UNEXPECTED_NULL);
760 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromModel(mModel, 0, nullptr),
761 ANEURALNETWORKS_UNEXPECTED_NULL);
762
763 // This should fail, because the operand does not exist.
764 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromModel(mModel, -1, valueModel),
765 ANEURALNETWORKS_BAD_DATA);
766
767 // This should fail, as this operand does not exist.
768 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromModel(mModel, 1, valueModel),
769 ANEURALNETWORKS_BAD_DATA);
770
771 modelFinish();
772 // This should fail, as the model is already finished.
773 EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromModel(mModel, 0, valueModel),
774 ANEURALNETWORKS_BAD_STATE);
775
776 ANeuralNetworksModel_free(valueModel);
777 }
778
TEST_F(ValidationTestModel,AddOEMOperand)779 TEST_F(ValidationTestModel, AddOEMOperand) {
780 ANeuralNetworksOperandType OEMScalarType{
781 .type = ANEURALNETWORKS_OEM_SCALAR, .dimensionCount = 0, .dimensions = nullptr};
782 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMScalarType), ANEURALNETWORKS_NO_ERROR);
783 char buffer[20];
784 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(buffer)),
785 ANEURALNETWORKS_NO_ERROR);
786
787 const size_t kByteSizeOfOEMTensor = 4;
788 uint32_t dimensions[]{kByteSizeOfOEMTensor};
789 ANeuralNetworksOperandType OEMTensorType{
790 .type = ANEURALNETWORKS_TENSOR_OEM_BYTE, .dimensionCount = 1, .dimensions = dimensions};
791 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMTensorType), ANEURALNETWORKS_NO_ERROR);
792 EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 1, buffer, kByteSizeOfOEMTensor),
793 ANEURALNETWORKS_NO_ERROR);
794
795 modelFinish();
796 // This should fail, as the model is already finished.
797 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMTensorType), ANEURALNETWORKS_BAD_STATE);
798 }
799
TEST_F(ValidationTestModel,AddOperation)800 TEST_F(ValidationTestModel, AddOperation) {
801 uint32_t input = 0;
802 uint32_t output = 0;
803 EXPECT_EQ(ANeuralNetworksModel_addOperation(nullptr, ANEURALNETWORKS_AVERAGE_POOL_2D, 1, &input,
804 1, &output),
805 ANEURALNETWORKS_UNEXPECTED_NULL);
806 EXPECT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_AVERAGE_POOL_2D, 0, nullptr,
807 1, &output),
808 ANEURALNETWORKS_UNEXPECTED_NULL);
809 EXPECT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_AVERAGE_POOL_2D, 1, &input,
810 0, nullptr),
811 ANEURALNETWORKS_UNEXPECTED_NULL);
812
813 ANeuralNetworksOperationType invalidOp = -1;
814 EXPECT_EQ(addOperation(invalidOp, {input}, {output}), ANEURALNETWORKS_BAD_DATA);
815
816 modelFinish();
817 // This should fail, as the model is already finished.
818 EXPECT_EQ(addOperation(ANEURALNETWORKS_AVERAGE_POOL_2D, {input}, {output}),
819 ANEURALNETWORKS_BAD_STATE);
820 }
821
TEST_F(ValidationTestModel,IdentifyInputsAndOutputs)822 TEST_F(ValidationTestModel, IdentifyInputsAndOutputs) {
823 uint32_t input = 0;
824 uint32_t output = 0;
825 EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(nullptr, 1, &input, 1, &output),
826 ANEURALNETWORKS_UNEXPECTED_NULL);
827 EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 0, nullptr, 1, &output),
828 ANEURALNETWORKS_UNEXPECTED_NULL);
829 EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 1, &input, 0, nullptr),
830 ANEURALNETWORKS_UNEXPECTED_NULL);
831
832 createModel();
833 // This should fail, as the model is already finished.
834 EXPECT_EQ(identifyInputsAndOutputs({input}, {output}), ANEURALNETWORKS_BAD_STATE);
835 }
836
TEST_F(ValidationTestModel,RelaxComputationFloat32toFloat16)837 TEST_F(ValidationTestModel, RelaxComputationFloat32toFloat16) {
838 EXPECT_EQ(ANeuralNetworksModel_relaxComputationFloat32toFloat16(nullptr, true),
839 ANEURALNETWORKS_UNEXPECTED_NULL);
840
841 createModel();
842 // This should fail, as the model is already finished.
843 EXPECT_EQ(ANeuralNetworksModel_relaxComputationFloat32toFloat16(mModel, true),
844 ANEURALNETWORKS_BAD_STATE);
845 EXPECT_EQ(ANeuralNetworksModel_relaxComputationFloat32toFloat16(mModel, false),
846 ANEURALNETWORKS_BAD_STATE);
847 }
848
TEST_F(ValidationTestModel,Finish)849 TEST_F(ValidationTestModel, Finish) {
850 EXPECT_EQ(ANeuralNetworksModel_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
851 createModel();
852 EXPECT_EQ(modelFinish(), ANEURALNETWORKS_BAD_STATE);
853 }
854
TEST_F(ValidationTestModel,EmptyModel)855 TEST_F(ValidationTestModel, EmptyModel) {
856 // An empty model is invalid
857 EXPECT_EQ(modelFinish(), ANEURALNETWORKS_BAD_DATA);
858 }
859
TEST_F(ValidationTestModel,CreateCompilation)860 TEST_F(ValidationTestModel, CreateCompilation) {
861 ANeuralNetworksCompilation* compilation = nullptr;
862 EXPECT_EQ(ANeuralNetworksCompilation_create(nullptr, &compilation),
863 ANEURALNETWORKS_UNEXPECTED_NULL);
864 EXPECT_EQ(ANeuralNetworksCompilation_create(mModel, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
865 EXPECT_EQ(ANeuralNetworksCompilation_create(mModel, &compilation), ANEURALNETWORKS_BAD_STATE);
866 }
867
TEST_F(ValidationTestModel,CreateCompilationForDevices)868 TEST_F(ValidationTestModel, CreateCompilationForDevices) {
869 createModel();
870 uint32_t numDevices = 0;
871 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
872
873 if (numDevices > 0) {
874 ANeuralNetworksDevice* device;
875 EXPECT_EQ(ANeuralNetworks_getDevice(0, &device), ANEURALNETWORKS_NO_ERROR);
876 ANeuralNetworksCompilation* compilation = nullptr;
877 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(nullptr, &device, 1, &compilation),
878 ANEURALNETWORKS_UNEXPECTED_NULL);
879 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, &device, 1, nullptr),
880 ANEURALNETWORKS_UNEXPECTED_NULL);
881
882 // empty device list
883 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, &device, 0, &compilation),
884 ANEURALNETWORKS_BAD_DATA);
885
886 // duplicate devices in the list.
887 ANeuralNetworksDevice* invalidDevices[2] = {device, device};
888 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, invalidDevices, 2,
889 &compilation),
890 ANEURALNETWORKS_BAD_DATA);
891 // nullptr in the list.
892 invalidDevices[1] = nullptr;
893 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, invalidDevices, 2,
894 &compilation),
895 ANEURALNETWORKS_UNEXPECTED_NULL);
896 }
897
898 ANeuralNetworksCompilation* compilation = nullptr;
899 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(nullptr, nullptr, 1, &compilation),
900 ANEURALNETWORKS_UNEXPECTED_NULL);
901 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, nullptr, 1, nullptr),
902 ANEURALNETWORKS_UNEXPECTED_NULL);
903 EXPECT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, nullptr, 1, &compilation),
904 ANEURALNETWORKS_UNEXPECTED_NULL);
905 }
906
TEST_F(ValidationTestModel,GetSupportedOperationsForDevices)907 TEST_F(ValidationTestModel, GetSupportedOperationsForDevices) {
908 createModel();
909 uint32_t numDevices = 0;
910 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
911
912 bool supportedOps[20];
913 ASSERT_LE(mNumOperations, sizeof(supportedOps) / sizeof(supportedOps[0]));
914 if (numDevices > 0) {
915 ANeuralNetworksDevice* device;
916 EXPECT_EQ(ANeuralNetworks_getDevice(0, &device), ANEURALNETWORKS_NO_ERROR);
917 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(nullptr, &device, 1,
918 supportedOps),
919 ANEURALNETWORKS_UNEXPECTED_NULL);
920 EXPECT_EQ(
921 ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, &device, 1, nullptr),
922 ANEURALNETWORKS_UNEXPECTED_NULL);
923
924 // empty device list
925 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, &device, 0,
926 supportedOps),
927 ANEURALNETWORKS_BAD_DATA);
928
929 // duplicate devices in the list.
930 ANeuralNetworksDevice* invalidDevices[2] = {device, device};
931 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, invalidDevices, 2,
932 supportedOps),
933 ANEURALNETWORKS_BAD_DATA);
934 // nullptr in the list.
935 invalidDevices[1] = nullptr;
936 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, invalidDevices, 2,
937 supportedOps),
938 ANEURALNETWORKS_UNEXPECTED_NULL);
939 }
940
941 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(nullptr, nullptr, 1,
942 supportedOps),
943 ANEURALNETWORKS_UNEXPECTED_NULL);
944 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, nullptr, 1, nullptr),
945 ANEURALNETWORKS_UNEXPECTED_NULL);
946 EXPECT_EQ(
947 ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, nullptr, 1, supportedOps),
948 ANEURALNETWORKS_UNEXPECTED_NULL);
949 }
950
TEST_F(ValidationTestModel,Cycle)951 TEST_F(ValidationTestModel, Cycle) {
952 uint32_t dimensions[]{1};
953 ANeuralNetworksOperandType tensorType{
954 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
955 ANeuralNetworksOperandType scalarType{
956 .type = ANEURALNETWORKS_INT32, .dimensionCount = 0, .dimensions = nullptr};
957
958 // opnd0 = model input TENSOR_FLOAT32
959 // opnd1 = model input TENSOR_FLOAT32
960 // opnd2 = model input INT32
961 // opnd3 = ADD(opnd0, opnd4, opnd2)
962 // opnd4 = ADD(opnd1, opnd3, opnd2)
963 // opnd5 = ADD(opnd4, opnd0, opnd2) // model output
964 //
965 // +-----+
966 // | |
967 // v |
968 // 3 = ADD(0, 4, 2) |
969 // | |
970 // +----------+ |
971 // | |
972 // v |
973 // 4 = ADD(1, 3, 2) |
974 // | |
975 // +----------------+
976 // |
977 // |
978 // +-------+
979 // |
980 // v
981 // 5 = ADD(4, 0, 2)
982
983 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
984 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
985 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &scalarType), ANEURALNETWORKS_NO_ERROR);
986 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
987 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
988 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
989
990 ASSERT_EQ(addOperation(ANEURALNETWORKS_ADD, {0, 4, 2}, {3}), ANEURALNETWORKS_NO_ERROR);
991 ASSERT_EQ(addOperation(ANEURALNETWORKS_ADD, {1, 3, 2}, {4}), ANEURALNETWORKS_NO_ERROR);
992 ASSERT_EQ(addOperation(ANEURALNETWORKS_ADD, {4, 0, 2}, {5}), ANEURALNETWORKS_NO_ERROR);
993
994 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2}, {5}), ANEURALNETWORKS_NO_ERROR);
995 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_BAD_DATA);
996 }
997
TEST_F(ValidationTestModel,AcyclicReadBeforeWrite)998 TEST_F(ValidationTestModel, AcyclicReadBeforeWrite) {
999 uint32_t dimensions[]{1};
1000 ANeuralNetworksOperandType tensorType{
1001 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
1002
1003 // opnd0 = TENSOR_FLOAT32 // model input
1004 // opnd1 = LOGISTIC(opnd2) // model output
1005 // opnd2 = LOGISTIC(opnd0)
1006 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1007 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1008 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1009
1010 ASSERT_EQ(addOperation(ANEURALNETWORKS_LOGISTIC, {2}, {1}), ANEURALNETWORKS_NO_ERROR);
1011 ASSERT_EQ(addOperation(ANEURALNETWORKS_LOGISTIC, {0}, {2}), ANEURALNETWORKS_NO_ERROR);
1012 ASSERT_EQ(identifyInputsAndOutputs({0}, {1}), ANEURALNETWORKS_NO_ERROR);
1013
1014 // This should succeed, because NN API doesn't require that operations be sorted.
1015 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_NO_ERROR);
1016 }
1017
TEST_F(ValidationTestModel,MissingWrite)1018 TEST_F(ValidationTestModel, MissingWrite) {
1019 uint32_t dimensions[]{1};
1020 ANeuralNetworksOperandType tensorType{
1021 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
1022
1023 // opnd0 = TENSOR_FLOAT32 // model input
1024 // opnd1 = TENSOR_FLOAT32 // never written
1025 // opnd2 = LOGISTIC(opnd1) // model output
1026 // opnd3 = LOGISTIC(opnd0) // model output
1027 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1028 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1029 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1030 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1031
1032 ASSERT_EQ(addOperation(ANEURALNETWORKS_LOGISTIC, {1}, {2}), ANEURALNETWORKS_NO_ERROR);
1033 ASSERT_EQ(addOperation(ANEURALNETWORKS_LOGISTIC, {0}, {3}), ANEURALNETWORKS_NO_ERROR);
1034 ASSERT_EQ(identifyInputsAndOutputs({0}, {2, 3}), ANEURALNETWORKS_NO_ERROR);
1035
1036 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_BAD_DATA);
1037 }
1038
TEST_F(ValidationTestModel,UnwrittenOperand)1039 TEST_F(ValidationTestModel, UnwrittenOperand) {
1040 uint32_t dimensions[]{1};
1041 ANeuralNetworksOperandType tensorType{
1042 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
1043
1044 // opnd0 = TENSOR_FLOAT32 // model input
1045 // opnd1 = TENSOR_FLOAT32 // never written
1046 // opnd2 = LOGISTIC(opnd0) // model output
1047 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1048 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1049 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1050
1051 ASSERT_EQ(addOperation(ANEURALNETWORKS_LOGISTIC, {0}, {2}), ANEURALNETWORKS_NO_ERROR);
1052 ASSERT_EQ(identifyInputsAndOutputs({0}, {2}), ANEURALNETWORKS_NO_ERROR);
1053
1054 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_BAD_DATA);
1055 }
1056
TEST_F(ValidationTestModel,MultipleWrite)1057 TEST_F(ValidationTestModel, MultipleWrite) {
1058 uint32_t dimensions[]{1};
1059 ANeuralNetworksOperandType tensorType{
1060 .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
1061 ANeuralNetworksOperandType scalarType{
1062 .type = ANEURALNETWORKS_INT32, .dimensionCount = 0, .dimensions = nullptr};
1063
1064 // opnd0 = TENSOR_FLOAT32 // model input
1065 // opnd1 = INT32 // model input
1066 // opnd2 = ADD(opnd0, opnd0, opnd1) // model output; do this twice
1067 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1068 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &scalarType), ANEURALNETWORKS_NO_ERROR);
1069 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
1070
1071 for (int i = 0; i < 2; ++i) {
1072 SCOPED_TRACE(i);
1073 ASSERT_EQ(addOperation(ANEURALNETWORKS_ADD, {0, 0, 1}, {2}), ANEURALNETWORKS_NO_ERROR);
1074 }
1075
1076 ASSERT_EQ(identifyInputsAndOutputs({0, 1}, {2}), ANEURALNETWORKS_NO_ERROR);
1077 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_BAD_DATA);
1078 }
1079
TEST_F(ValidationTestIdentify,Ok)1080 TEST_F(ValidationTestIdentify, Ok) {
1081 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2}, {3}), ANEURALNETWORKS_NO_ERROR);
1082 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_NO_ERROR);
1083 }
1084
TEST_F(ValidationTestIdentify,InputIsOutput)1085 TEST_F(ValidationTestIdentify, InputIsOutput) {
1086 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2}, {3, 0}), ANEURALNETWORKS_BAD_DATA);
1087 }
1088
TEST_F(ValidationTestIdentify,OutputIsInput)1089 TEST_F(ValidationTestIdentify, OutputIsInput) {
1090 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2, 3}, {3}), ANEURALNETWORKS_BAD_DATA);
1091 }
1092
TEST_F(ValidationTestIdentify,DuplicateInputs)1093 TEST_F(ValidationTestIdentify, DuplicateInputs) {
1094 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2, 0}, {3}), ANEURALNETWORKS_BAD_DATA);
1095 }
1096
TEST_F(ValidationTestIdentify,DuplicateOutputs)1097 TEST_F(ValidationTestIdentify, DuplicateOutputs) {
1098 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2}, {3, 3}), ANEURALNETWORKS_BAD_DATA);
1099 }
1100
1101 // Also see TEST_F(ValidationTestCompilationForDevices_1, SetPreference)
TEST_F(ValidationTestCompilation,SetPreference)1102 TEST_F(ValidationTestCompilation, SetPreference) {
1103 EXPECT_EQ(ANeuralNetworksCompilation_setPreference(nullptr, ANEURALNETWORKS_PREFER_LOW_POWER),
1104 ANEURALNETWORKS_UNEXPECTED_NULL);
1105
1106 EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation, 40), ANEURALNETWORKS_BAD_DATA);
1107 }
1108
1109 // Also see TEST_F(ValidationTestCompilationForDevices_1, SetCaching)
TEST_F(ValidationTestCompilation,SetCaching)1110 TEST_F(ValidationTestCompilation, SetCaching) {
1111 std::vector<uint8_t> token(ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN, 0);
1112 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(nullptr, "/data/local/tmp", token.data()),
1113 ANEURALNETWORKS_UNEXPECTED_NULL);
1114 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(mCompilation, nullptr, token.data()),
1115 ANEURALNETWORKS_UNEXPECTED_NULL);
1116 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(mCompilation, "/data/local/tmp", nullptr),
1117 ANEURALNETWORKS_UNEXPECTED_NULL);
1118 }
1119
TEST_F(ValidationTestCompilation,SetPriority)1120 TEST_F(ValidationTestCompilation, SetPriority) {
1121 EXPECT_EQ(ANeuralNetworksCompilation_setPriority(nullptr, ANEURALNETWORKS_PRIORITY_DEFAULT),
1122 ANEURALNETWORKS_UNEXPECTED_NULL);
1123
1124 // Test invalid values of priority.
1125 constexpr int kInvalidPriorities[] = {0,
1126 ANEURALNETWORKS_PRIORITY_LOW - 1,
1127 ANEURALNETWORKS_PRIORITY_LOW + 1,
1128 ANEURALNETWORKS_PRIORITY_MEDIUM - 1,
1129 ANEURALNETWORKS_PRIORITY_MEDIUM + 1,
1130 ANEURALNETWORKS_PRIORITY_HIGH - 1,
1131 ANEURALNETWORKS_PRIORITY_HIGH + 1};
1132 for (int invalidPriority : kInvalidPriorities) {
1133 EXPECT_EQ(ANeuralNetworksCompilation_setPriority(mCompilation, invalidPriority),
1134 ANEURALNETWORKS_BAD_DATA);
1135 }
1136 }
1137
1138 // Also see TEST_F(ValidationTestCompilationForDevices_1, SetTimeout)
1139 // Also see TEST_F(ValidationTestCompilationForDevices_2, SetTimeout)
TEST_F(ValidationTestCompilation,SetTimeout)1140 TEST_F(ValidationTestCompilation, SetTimeout) {
1141 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(nullptr, kShortWaitInNanoseconds),
1142 ANEURALNETWORKS_UNEXPECTED_NULL);
1143 // Timeout can only be set on Compilations created from CompilationForDevices with one device
1144 // specified.
1145 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(mCompilation, kShortWaitInNanoseconds),
1146 ANEURALNETWORKS_BAD_DATA);
1147 }
1148
TEST_F(ValidationTestCompilation,GetPreferredMemoryAlignmentAndPadding)1149 TEST_F(ValidationTestCompilation, GetPreferredMemoryAlignmentAndPadding) {
1150 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1151 uint32_t result;
1152
1153 // The following calls should fail, because the compilation has not been finished.
1154 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForInput(mCompilation, 0,
1155 &result),
1156 ANEURALNETWORKS_BAD_STATE);
1157 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForInput(mCompilation, 0,
1158 &result),
1159 ANEURALNETWORKS_BAD_STATE);
1160 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForOutput(mCompilation, 0,
1161 &result),
1162 ANEURALNETWORKS_BAD_STATE);
1163 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForOutput(mCompilation, 0,
1164 &result),
1165 ANEURALNETWORKS_BAD_STATE);
1166
1167 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
1168
1169 // The following calls should fail because of unexpected nullptr.
1170 EXPECT_EQ(
1171 ANeuralNetworksCompilation_getPreferredMemoryAlignmentForInput(nullptr, 0, &result),
1172 ANEURALNETWORKS_UNEXPECTED_NULL);
1173 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForInput(mCompilation, 0,
1174 nullptr),
1175 ANEURALNETWORKS_UNEXPECTED_NULL);
1176 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForInput(nullptr, 0, &result),
1177 ANEURALNETWORKS_UNEXPECTED_NULL);
1178 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForInput(mCompilation, 0,
1179 nullptr),
1180 ANEURALNETWORKS_UNEXPECTED_NULL);
1181 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForOutput(nullptr, 0,
1182 &result),
1183 ANEURALNETWORKS_UNEXPECTED_NULL);
1184 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForOutput(mCompilation, 0,
1185 nullptr),
1186 ANEURALNETWORKS_UNEXPECTED_NULL);
1187 EXPECT_EQ(
1188 ANeuralNetworksCompilation_getPreferredMemoryPaddingForOutput(nullptr, 0, &result),
1189 ANEURALNETWORKS_UNEXPECTED_NULL);
1190 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForOutput(mCompilation, 0,
1191 nullptr),
1192 ANEURALNETWORKS_UNEXPECTED_NULL);
1193
1194 // The following calls should fail, because the index is out of range.
1195 const uint32_t invalidIndex = 1000;
1196 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForInput(
1197 mCompilation, invalidIndex, &result),
1198 ANEURALNETWORKS_BAD_DATA);
1199 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForInput(
1200 mCompilation, invalidIndex, &result),
1201 ANEURALNETWORKS_BAD_DATA);
1202 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForOutput(
1203 mCompilation, invalidIndex, &result),
1204 ANEURALNETWORKS_BAD_DATA);
1205 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForOutput(
1206 mCompilation, invalidIndex, &result),
1207 ANEURALNETWORKS_BAD_DATA);
1208
1209 } else {
1210 GTEST_SKIP();
1211 }
1212 }
1213
1214 // Also see TEST_F(ValidationTestCompilationForDevices_1, CreateExecution)
TEST_F(ValidationTestCompilation,CreateExecution)1215 TEST_F(ValidationTestCompilation, CreateExecution) {
1216 ANeuralNetworksExecution* execution = nullptr;
1217 EXPECT_EQ(ANeuralNetworksExecution_create(nullptr, &execution),
1218 ANEURALNETWORKS_UNEXPECTED_NULL);
1219 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, nullptr),
1220 ANEURALNETWORKS_UNEXPECTED_NULL);
1221 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_BAD_STATE);
1222 }
1223
1224 // Also see TEST_F(ValidationTestCompilationForDevices_1, Finish)
TEST_F(ValidationTestCompilation,Finish)1225 TEST_F(ValidationTestCompilation, Finish) {
1226 EXPECT_EQ(ANeuralNetworksCompilation_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
1227 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
1228 EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation,
1229 ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER),
1230 ANEURALNETWORKS_BAD_STATE);
1231 EXPECT_EQ(
1232 ANeuralNetworksCompilation_setPriority(mCompilation, ANEURALNETWORKS_PRIORITY_DEFAULT),
1233 ANEURALNETWORKS_BAD_STATE);
1234 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(mCompilation, kShortWaitInNanoseconds),
1235 ANEURALNETWORKS_BAD_STATE);
1236 std::vector<uint8_t> token(ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN, 0);
1237 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(mCompilation, "/data/local/tmp", token.data()),
1238 ANEURALNETWORKS_BAD_STATE);
1239 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_BAD_STATE);
1240 }
1241
1242 // Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionSetTimeout)
1243 // Also see TEST_F(ValidationTestCompilationForDevices_2, ExecutionSetTimeout)
TEST_F(ValidationTestCompilation,ExecutionSetTimeout)1244 TEST_F(ValidationTestCompilation, ExecutionSetTimeout) {
1245 EXPECT_EQ(ANeuralNetworksExecution_setTimeout(nullptr, kShortWaitInNanoseconds),
1246 ANEURALNETWORKS_UNEXPECTED_NULL);
1247
1248 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
1249 ANeuralNetworksExecution* execution;
1250 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
1251 // Timeout can only be set on Compilations created from CompilationForDevices with one device
1252 // specified.
1253 EXPECT_EQ(ANeuralNetworksExecution_setTimeout(execution, kShortWaitInNanoseconds),
1254 ANEURALNETWORKS_BAD_DATA);
1255 ANeuralNetworksExecution_free(execution);
1256 }
1257
1258 // Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming)
1259 // Also see TEST_F(ValidationTestCompilationForDevices_2, ExecutionTiming)
TEST_F(ValidationTestCompilation,ExecutionTiming)1260 TEST_F(ValidationTestCompilation, ExecutionTiming) {
1261 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
1262 ANeuralNetworksExecution* execution;
1263 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
1264 // Cannot setMeasureTiming() with Compilation rather than CompilationForDevices.
1265 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false),
1266 ANEURALNETWORKS_BAD_DATA);
1267 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), ANEURALNETWORKS_BAD_DATA);
1268
1269 // close memory
1270 ANeuralNetworksExecution_free(execution);
1271 }
1272
1273 // Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming)
TEST_F(ValidationTestCompilation,ExecutionUsability)1274 TEST_F(ValidationTestCompilation, ExecutionUsability) {
1275 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
1276
1277 enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST, FENCED };
1278 for (auto executionType :
1279 {ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST, ExecutionType::FENCED}) {
1280 for (bool explicitlyDisableReusablility : {false, true}) {
1281 SCOPED_TRACE(static_cast<uint32_t>(executionType));
1282 SCOPED_TRACE(explicitlyDisableReusablility);
1283
1284 ANeuralNetworksExecution* execution;
1285 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
1286 ANEURALNETWORKS_NO_ERROR);
1287
1288 if (explicitlyDisableReusablility) {
1289 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1290 ASSERT_EQ(ANeuralNetworksExecution_setReusable(execution, false),
1291 ANEURALNETWORKS_NO_ERROR);
1292 } else {
1293 ANeuralNetworksExecution_free(execution);
1294 continue;
1295 }
1296 }
1297
1298 // Set inputs and outputs.
1299 float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2];
1300 int in2 = 0;
1301 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)),
1302 ANEURALNETWORKS_NO_ERROR);
1303 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)),
1304 ANEURALNETWORKS_NO_ERROR);
1305 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)),
1306 ANEURALNETWORKS_NO_ERROR);
1307 ASSERT_EQ(
1308 ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)),
1309 ANEURALNETWORKS_NO_ERROR);
1310
1311 const size_t memorySize = std::max(sizeof(in0), sizeof(out0));
1312 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
1313 ASSERT_GT(memoryFd, 0);
1314 ANeuralNetworksMemory* memory;
1315 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE,
1316 memoryFd, 0, &memory),
1317 ANEURALNETWORKS_NO_ERROR);
1318
1319 auto testTooLate = [this, execution, &in0, &out0, memory] {
1320 // Try a bunch of things that are impermissible if the execution has started.
1321
1322 // Set loop timeout.
1323 ASSERT_EQ(
1324 ANeuralNetworksExecution_setLoopTimeout(execution, kShortWaitInNanoseconds),
1325 ANEURALNETWORKS_BAD_STATE);
1326
1327 // Enable/Disable input and output padding.
1328 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1329 ASSERT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(execution, true),
1330 ANEURALNETWORKS_BAD_STATE);
1331 ASSERT_EQ(
1332 ANeuralNetworksExecution_enableInputAndOutputPadding(execution, false),
1333 ANEURALNETWORKS_BAD_STATE);
1334 }
1335
1336 // Set inputs and outputs.
1337 ASSERT_EQ(
1338 ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)),
1339 ANEURALNETWORKS_BAD_STATE);
1340 ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0,
1341 sizeof(out0)),
1342 ANEURALNETWORKS_BAD_STATE);
1343 ASSERT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr, memory,
1344 0, sizeof(in0)),
1345 ANEURALNETWORKS_BAD_STATE);
1346 ASSERT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr,
1347 memory, 0, sizeof(out0)),
1348 ANEURALNETWORKS_BAD_STATE);
1349
1350 // Set reusable.
1351 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1352 ASSERT_EQ(ANeuralNetworksExecution_setReusable(execution, true),
1353 ANEURALNETWORKS_BAD_STATE);
1354 ASSERT_EQ(ANeuralNetworksExecution_setReusable(execution, false),
1355 ANEURALNETWORKS_BAD_STATE);
1356 }
1357
1358 // Reuse for asynchronous execution.
1359 {
1360 ANeuralNetworksEvent* event;
1361 ASSERT_EQ(ANeuralNetworksExecution_startCompute(execution, &event),
1362 ANEURALNETWORKS_BAD_STATE);
1363 }
1364
1365 // Reuse for synchronous execution.
1366 ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_BAD_STATE);
1367
1368 // Reuse for burst execution.
1369 {
1370 ANeuralNetworksBurst* burst;
1371 ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst),
1372 ANEURALNETWORKS_NO_ERROR);
1373 ASSERT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst),
1374 ANEURALNETWORKS_BAD_STATE);
1375 ANeuralNetworksBurst_free(burst);
1376 }
1377
1378 // Reuse for fenced execution.
1379 {
1380 ANeuralNetworksEvent* event;
1381 ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(
1382 execution, nullptr, 0, 0, &event),
1383 ANEURALNETWORKS_BAD_STATE);
1384 }
1385 };
1386
1387 // Compute.
1388 switch (executionType) {
1389 case ExecutionType::ASYNC: {
1390 ANeuralNetworksEvent* event;
1391 ASSERT_EQ(ANeuralNetworksExecution_startCompute(execution, &event),
1392 ANEURALNETWORKS_NO_ERROR);
1393 testTooLate();
1394 ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR);
1395 testTooLate();
1396 ANeuralNetworksEvent_free(event);
1397 break;
1398 }
1399 case ExecutionType::SYNC: {
1400 ASSERT_EQ(ANeuralNetworksExecution_compute(execution),
1401 ANEURALNETWORKS_NO_ERROR);
1402 testTooLate();
1403 break;
1404 }
1405 case ExecutionType::BURST: {
1406 ANeuralNetworksBurst* burst;
1407 ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst),
1408 ANEURALNETWORKS_NO_ERROR);
1409 ASSERT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst),
1410 ANEURALNETWORKS_NO_ERROR);
1411 testTooLate();
1412 ANeuralNetworksBurst_free(burst);
1413 break;
1414 }
1415 case ExecutionType::FENCED: {
1416 ANeuralNetworksEvent* event;
1417 ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(
1418 execution, nullptr, 0, 0, &event),
1419 ANEURALNETWORKS_NO_ERROR);
1420 testTooLate();
1421 ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR);
1422 testTooLate();
1423 ANeuralNetworksEvent_free(event);
1424 break;
1425 }
1426 default:
1427 FAIL() << "Unreachable";
1428 }
1429
1430 // close memory
1431 ANeuralNetworksExecution_free(execution);
1432 ANeuralNetworksMemory_free(memory);
1433 close(memoryFd);
1434 }
1435 }
1436 }
1437
testConcurrentExecution(bool reusable,ANeuralNetworksCompilation * compilation)1438 static void testConcurrentExecution(bool reusable, ANeuralNetworksCompilation* compilation) {
1439 ASSERT_EQ(ANeuralNetworksCompilation_finish(compilation), ANEURALNETWORKS_NO_ERROR);
1440
1441 enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST, FENCED };
1442 const auto compute = [compilation](ExecutionType executionType,
1443 ANeuralNetworksExecution* execution) -> int {
1444 switch (executionType) {
1445 case ExecutionType::ASYNC: {
1446 ANeuralNetworksEvent* event;
1447 int result = ANeuralNetworksExecution_startCompute(execution, &event);
1448 if (result == ANEURALNETWORKS_NO_ERROR) {
1449 result = ANeuralNetworksEvent_wait(event);
1450 }
1451 ANeuralNetworksEvent_free(event);
1452 return result;
1453 }
1454 case ExecutionType::SYNC: {
1455 return ANeuralNetworksExecution_compute(execution);
1456 }
1457 case ExecutionType::BURST: {
1458 ANeuralNetworksBurst* burst;
1459 int result = ANeuralNetworksBurst_create(compilation, &burst);
1460 if (result == ANEURALNETWORKS_NO_ERROR) {
1461 result = ANeuralNetworksExecution_burstCompute(execution, burst);
1462 }
1463 ANeuralNetworksBurst_free(burst);
1464 return result;
1465 }
1466 case ExecutionType::FENCED: {
1467 ANeuralNetworksEvent* event;
1468 int result = ANeuralNetworksExecution_startComputeWithDependencies(
1469 execution, nullptr, 0, 0, &event);
1470 if (result == ANEURALNETWORKS_NO_ERROR) {
1471 result = ANeuralNetworksEvent_wait(event);
1472 }
1473 ANeuralNetworksEvent_free(event);
1474 return result;
1475 }
1476 }
1477 };
1478
1479 const std::vector<ExecutionType> kExecutionTypes = {
1480 ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST, ExecutionType::FENCED};
1481 for (auto executionType1 : kExecutionTypes) {
1482 for (auto executionType2 : kExecutionTypes) {
1483 SCOPED_TRACE(static_cast<uint32_t>(executionType1));
1484 SCOPED_TRACE(static_cast<uint32_t>(executionType2));
1485
1486 ANeuralNetworksExecution* execution;
1487 ASSERT_EQ(ANeuralNetworksExecution_create(compilation, &execution),
1488 ANEURALNETWORKS_NO_ERROR);
1489
1490 float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2];
1491 int in2 = 0;
1492 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)),
1493 ANEURALNETWORKS_NO_ERROR);
1494 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)),
1495 ANEURALNETWORKS_NO_ERROR);
1496 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)),
1497 ANEURALNETWORKS_NO_ERROR);
1498 ASSERT_EQ(
1499 ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)),
1500 ANEURALNETWORKS_NO_ERROR);
1501 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1502 ASSERT_EQ(ANeuralNetworksExecution_setReusable(execution, reusable),
1503 ANEURALNETWORKS_NO_ERROR);
1504 } else {
1505 if (reusable) {
1506 ANeuralNetworksExecution_free(execution);
1507 return;
1508 }
1509 }
1510
1511 // Compute on the same execution concurrently.
1512 auto first = std::async(std::launch::async, [compute, executionType1, execution] {
1513 return compute(executionType1, execution);
1514 });
1515 auto second = std::async(std::launch::async, [compute, executionType2, execution] {
1516 return compute(executionType2, execution);
1517 });
1518 const int result1 = first.get();
1519 const int result2 = second.get();
1520
1521 // At least one result must be ANEURALNETWORKS_NO_ERROR. One may return
1522 // ANEURALNETWORKS_BAD_STATE if the other is already executing.
1523 EXPECT_TRUE(result1 == ANEURALNETWORKS_BAD_STATE ||
1524 result1 == ANEURALNETWORKS_NO_ERROR);
1525 EXPECT_TRUE(result2 == ANEURALNETWORKS_BAD_STATE ||
1526 result2 == ANEURALNETWORKS_NO_ERROR);
1527 EXPECT_TRUE(result1 == ANEURALNETWORKS_NO_ERROR || result2 == ANEURALNETWORKS_NO_ERROR);
1528
1529 // If the execution is not reusable, one result must be ANEURALNETWORKS_BAD_STATE.
1530 if (!reusable) {
1531 EXPECT_TRUE(result1 == ANEURALNETWORKS_BAD_STATE ||
1532 result2 == ANEURALNETWORKS_BAD_STATE);
1533 }
1534
1535 ANeuralNetworksExecution_free(execution);
1536 }
1537 }
1538 }
1539
1540 // Also see TEST_F(ValidationTestBurst, BurstComputeConcurrent)
TEST_F(ValidationTestCompilation,ReusableExecutionConcurrent)1541 TEST_F(ValidationTestCompilation, ReusableExecutionConcurrent) {
1542 testConcurrentExecution(/*reusable=*/true, mCompilation);
1543 }
TEST_F(ValidationTestCompilation,NonReusableExecutionConcurrent)1544 TEST_F(ValidationTestCompilation, NonReusableExecutionConcurrent) {
1545 testConcurrentExecution(/*reusable=*/false, mCompilation);
1546 }
1547
TEST_F(ValidationTestExecution,SetLoopTimeout)1548 TEST_F(ValidationTestExecution, SetLoopTimeout) {
1549 EXPECT_EQ(ANeuralNetworksExecution_setLoopTimeout(nullptr, kShortWaitInNanoseconds),
1550 ANEURALNETWORKS_UNEXPECTED_NULL);
1551 }
1552
TEST_F(ValidationTestExecution,EnableInputAndOutputPadding)1553 TEST_F(ValidationTestExecution, EnableInputAndOutputPadding) {
1554 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1555 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(nullptr, true),
1556 ANEURALNETWORKS_UNEXPECTED_NULL);
1557 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(nullptr, false),
1558 ANEURALNETWORKS_UNEXPECTED_NULL);
1559 } else {
1560 GTEST_SKIP();
1561 }
1562 }
1563
TEST_F(ValidationTestExecution,ExecutionSetReusable)1564 TEST_F(ValidationTestExecution, ExecutionSetReusable) {
1565 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1566 EXPECT_EQ(ANeuralNetworksExecution_setReusable(nullptr, true),
1567 ANEURALNETWORKS_UNEXPECTED_NULL);
1568 EXPECT_EQ(ANeuralNetworksExecution_setReusable(nullptr, false),
1569 ANEURALNETWORKS_UNEXPECTED_NULL);
1570 } else {
1571 GTEST_SKIP();
1572 }
1573 }
1574
TEST_F(ValidationTestExecution,SetInput)1575 TEST_F(ValidationTestExecution, SetInput) {
1576 char buffer[20];
1577 EXPECT_EQ(ANeuralNetworksExecution_setInput(nullptr, 0, nullptr, buffer, sizeof(float)),
1578 ANEURALNETWORKS_UNEXPECTED_NULL);
1579 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, nullptr, sizeof(float)),
1580 ANEURALNETWORKS_UNEXPECTED_NULL);
1581
1582 // This should fail, because memory is not the size of a float32.
1583 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, buffer, 20),
1584 ANEURALNETWORKS_BAD_DATA);
1585
1586 // This should fail, as this operand does not exist.
1587 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 999, nullptr, buffer, sizeof(float)),
1588 ANEURALNETWORKS_BAD_DATA);
1589
1590 // This should fail, as this operand does not exist.
1591 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, -1, nullptr, buffer, sizeof(float)),
1592 ANEURALNETWORKS_BAD_DATA);
1593
1594 // These should fail, because the tensor types are invalid.
1595 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, &kInvalidTensorType1, buffer,
1596 sizeof(float)),
1597 ANEURALNETWORKS_BAD_DATA);
1598 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, &kInvalidTensorType2, buffer,
1599 sizeof(float)),
1600 ANEURALNETWORKS_BAD_DATA);
1601
1602 // Cannot do this twice.
1603 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, buffer, 8),
1604 ANEURALNETWORKS_NO_ERROR);
1605 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, buffer, 8),
1606 ANEURALNETWORKS_BAD_STATE);
1607 }
1608
TEST_F(ValidationTestExecution,SetInputEnablePadding)1609 TEST_F(ValidationTestExecution, SetInputEnablePadding) {
1610 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1611 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(mExecution, true),
1612 ANEURALNETWORKS_NO_ERROR);
1613
1614 // This should fail, because length is less than the size of a float32.
1615 char buffer[20];
1616 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, buffer,
1617 sizeof(float) - 1),
1618 ANEURALNETWORKS_BAD_DATA);
1619 } else {
1620 GTEST_SKIP();
1621 }
1622 }
1623
TEST_F(ValidationTestExecution,SetOutput)1624 TEST_F(ValidationTestExecution, SetOutput) {
1625 char buffer[20];
1626 EXPECT_EQ(ANeuralNetworksExecution_setOutput(nullptr, 0, nullptr, buffer, sizeof(float)),
1627 ANEURALNETWORKS_UNEXPECTED_NULL);
1628 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, nullptr, sizeof(float)),
1629 ANEURALNETWORKS_UNEXPECTED_NULL);
1630
1631 // This should fail, because memory is not the size of a float32.
1632 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, buffer, 20),
1633 ANEURALNETWORKS_BAD_DATA);
1634
1635 // This should fail, as this operand does not exist.
1636 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 999, nullptr, buffer, sizeof(float)),
1637 ANEURALNETWORKS_BAD_DATA);
1638
1639 // This should fail, as this operand does not exist.
1640 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, -1, nullptr, buffer, sizeof(float)),
1641 ANEURALNETWORKS_BAD_DATA);
1642
1643 // These should fail, because the tensor types are invalid.
1644 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, &kInvalidTensorType1, buffer,
1645 sizeof(float)),
1646 ANEURALNETWORKS_BAD_DATA);
1647 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, &kInvalidTensorType2, buffer,
1648 sizeof(float)),
1649 ANEURALNETWORKS_BAD_DATA);
1650
1651 // Cannot do this twice.
1652 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, buffer, 8),
1653 ANEURALNETWORKS_NO_ERROR);
1654 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, buffer, 8),
1655 ANEURALNETWORKS_BAD_STATE);
1656 }
1657
TEST_F(ValidationTestExecution,SetOutputEnablePadding)1658 TEST_F(ValidationTestExecution, SetOutputEnablePadding) {
1659 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1660 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(mExecution, true),
1661 ANEURALNETWORKS_NO_ERROR);
1662
1663 // This should fail, because length is less than the size of a float32.
1664 char buffer[20];
1665 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, buffer,
1666 sizeof(float) - 1),
1667 ANEURALNETWORKS_BAD_DATA);
1668 } else {
1669 GTEST_SKIP();
1670 }
1671 }
1672
TEST_F(ValidationTestExecution,SetInputFromMemory)1673 TEST_F(ValidationTestExecution, SetInputFromMemory) {
1674 const size_t memorySize = 20;
1675 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
1676 ASSERT_GT(memoryFd, 0);
1677
1678 ANeuralNetworksMemory* memory;
1679 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd, 0,
1680 &memory),
1681 ANEURALNETWORKS_NO_ERROR);
1682
1683 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(nullptr, 0, nullptr, memory, 0,
1684 sizeof(float)),
1685 ANEURALNETWORKS_UNEXPECTED_NULL);
1686 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, nullptr, 0,
1687 sizeof(float)),
1688 ANEURALNETWORKS_UNEXPECTED_NULL);
1689
1690 // This should fail, because the operand does not exist.
1691 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 999, nullptr, memory, 0,
1692 sizeof(float)),
1693 ANEURALNETWORKS_BAD_DATA);
1694
1695 // This should fail, because the operand does not exist.
1696 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, -1, nullptr, memory, 0,
1697 sizeof(float)),
1698 ANEURALNETWORKS_BAD_DATA);
1699
1700 // This should fail, because memory is not the size of a float32.
1701 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0,
1702 memorySize),
1703 ANEURALNETWORKS_BAD_DATA);
1704
1705 // This should fail, because offset is larger than memorySize.
1706 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory,
1707 memorySize + 1, sizeof(float)),
1708 ANEURALNETWORKS_BAD_DATA);
1709
1710 // This should fail, because requested size is larger than the memory.
1711 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory,
1712 memorySize - 3, sizeof(float)),
1713 ANEURALNETWORKS_BAD_DATA);
1714
1715 // These should fail, because the tensor types are invalid.
1716 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, &kInvalidTensorType1,
1717 memory, 0, sizeof(float)),
1718 ANEURALNETWORKS_BAD_DATA);
1719 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, &kInvalidTensorType2,
1720 memory, 0, sizeof(float)),
1721 ANEURALNETWORKS_BAD_DATA);
1722
1723 // Cannot do this twice.
1724 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0, 8),
1725 ANEURALNETWORKS_NO_ERROR);
1726 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0, 8),
1727 ANEURALNETWORKS_BAD_STATE);
1728 char buffer[memorySize];
1729 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, buffer, 8),
1730 ANEURALNETWORKS_BAD_STATE);
1731
1732 // close memory
1733 ANeuralNetworksMemory_free(memory);
1734 close(memoryFd);
1735 }
1736
TEST_F(ValidationTestExecution,SetInputFromMemoryEnablePadding)1737 TEST_F(ValidationTestExecution, SetInputFromMemoryEnablePadding) {
1738 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1739 const size_t memorySize = 20;
1740 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
1741 ASSERT_GT(memoryFd, 0);
1742
1743 ANeuralNetworksMemory* memory;
1744 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd,
1745 0, &memory),
1746 ANEURALNETWORKS_NO_ERROR);
1747
1748 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(mExecution, true),
1749 ANEURALNETWORKS_NO_ERROR);
1750
1751 // This should fail, because length is less than the size of a float32.
1752 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0,
1753 sizeof(float) - 1),
1754 ANEURALNETWORKS_BAD_DATA);
1755
1756 // close memory
1757 ANeuralNetworksMemory_free(memory);
1758 close(memoryFd);
1759 } else {
1760 GTEST_SKIP();
1761 }
1762 }
1763
TEST_F(ValidationTestExecution,SetInputFromAHardwareBufferBlob)1764 TEST_F(ValidationTestExecution, SetInputFromAHardwareBufferBlob) {
1765 const size_t memorySize = 20;
1766
1767 AHardwareBuffer_Desc desc{
1768 .width = memorySize,
1769 .height = 1,
1770 .layers = 1,
1771 .format = AHARDWAREBUFFER_FORMAT_BLOB,
1772 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
1773 };
1774
1775 AHardwareBuffer* buffer = nullptr;
1776 ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
1777
1778 ANeuralNetworksMemory* memory;
1779 EXPECT_EQ(ANeuralNetworksMemory_createFromAHardwareBuffer(buffer, &memory),
1780 ANEURALNETWORKS_NO_ERROR);
1781
1782 // This should fail, because memory is not the size of a float32.
1783 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0,
1784 memorySize),
1785 ANEURALNETWORKS_BAD_DATA);
1786
1787 // This should fail, because offset is larger than memorySize.
1788 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory,
1789 memorySize + 1, sizeof(float)),
1790 ANEURALNETWORKS_BAD_DATA);
1791 // This should fail, because requested size is larger than the memory.
1792 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory,
1793 memorySize - 3, sizeof(float)),
1794 ANEURALNETWORKS_BAD_DATA);
1795
1796 // These should fail, because the tensor types are invalid.
1797 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, &kInvalidTensorType1,
1798 memory, 0, sizeof(float)),
1799 ANEURALNETWORKS_BAD_DATA);
1800 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, &kInvalidTensorType2,
1801 memory, 0, sizeof(float)),
1802 ANEURALNETWORKS_BAD_DATA);
1803
1804 // close memory
1805 ANeuralNetworksMemory_free(memory);
1806 AHardwareBuffer_release(buffer);
1807 }
1808
TEST_F(ValidationTestExecution,SetInputFromAHardwareBufferBlobEnablePadding)1809 TEST_F(ValidationTestExecution, SetInputFromAHardwareBufferBlobEnablePadding) {
1810 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1811 const size_t memorySize = 20;
1812
1813 AHardwareBuffer_Desc desc{
1814 .width = memorySize,
1815 .height = 1,
1816 .layers = 1,
1817 .format = AHARDWAREBUFFER_FORMAT_BLOB,
1818 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
1819 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
1820 };
1821
1822 AHardwareBuffer* buffer = nullptr;
1823 ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
1824
1825 ANeuralNetworksMemory* memory;
1826 EXPECT_EQ(ANeuralNetworksMemory_createFromAHardwareBuffer(buffer, &memory),
1827 ANEURALNETWORKS_NO_ERROR);
1828
1829 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(mExecution, true),
1830 ANEURALNETWORKS_NO_ERROR);
1831
1832 // This should fail, because length is less than the size of a float32.
1833 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0,
1834 sizeof(float) - 1),
1835 ANEURALNETWORKS_BAD_DATA);
1836
1837 // close memory
1838 ANeuralNetworksMemory_free(memory);
1839 AHardwareBuffer_release(buffer);
1840 } else {
1841 GTEST_SKIP();
1842 }
1843 }
1844
TEST_F(ValidationTestExecution,SetOutputFromMemory)1845 TEST_F(ValidationTestExecution, SetOutputFromMemory) {
1846 ANeuralNetworksExecution* execution;
1847 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
1848
1849 const size_t memorySize = 20;
1850 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
1851 ASSERT_GT(memoryFd, 0);
1852
1853 ANeuralNetworksMemory* memory;
1854 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd, 0,
1855 &memory),
1856 ANEURALNETWORKS_NO_ERROR);
1857
1858 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(nullptr, 0, nullptr, memory, 0,
1859 sizeof(float)),
1860 ANEURALNETWORKS_UNEXPECTED_NULL);
1861 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, nullptr, 0,
1862 sizeof(float)),
1863 ANEURALNETWORKS_UNEXPECTED_NULL);
1864
1865 // This should fail, because the operand does not exist.
1866 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 999, nullptr, memory, 0,
1867 sizeof(float)),
1868 ANEURALNETWORKS_BAD_DATA);
1869
1870 // This should fail, because the operand does not exist.
1871 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, -1, nullptr, memory, 0,
1872 sizeof(float)),
1873 ANEURALNETWORKS_BAD_DATA);
1874
1875 // This should fail, because memory is not the size of a float32.
1876 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0,
1877 memorySize),
1878 ANEURALNETWORKS_BAD_DATA);
1879
1880 // This should fail, because offset is larger than memorySize.
1881 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory,
1882 memorySize + 1, sizeof(float)),
1883 ANEURALNETWORKS_BAD_DATA);
1884
1885 // This should fail, because requested size is larger than the memory.
1886 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory,
1887 memorySize - 3, sizeof(float)),
1888 ANEURALNETWORKS_BAD_DATA);
1889
1890 // These should fail, because the tensor types are invalid.
1891 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, &kInvalidTensorType1,
1892 memory, 0, sizeof(float)),
1893 ANEURALNETWORKS_BAD_DATA);
1894 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, &kInvalidTensorType2,
1895 memory, 0, sizeof(float)),
1896 ANEURALNETWORKS_BAD_DATA);
1897
1898 // Cannot do this twice.
1899 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0, 8),
1900 ANEURALNETWORKS_NO_ERROR);
1901 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0, 8),
1902 ANEURALNETWORKS_BAD_STATE);
1903 char buffer[memorySize];
1904 EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, buffer, 8),
1905 ANEURALNETWORKS_BAD_STATE);
1906
1907 // close memory
1908 ANeuralNetworksMemory_free(memory);
1909 ANeuralNetworksExecution_free(execution);
1910 close(memoryFd);
1911 }
1912
TEST_F(ValidationTestExecution,SetOutputFromMemoryEnablePadding)1913 TEST_F(ValidationTestExecution, SetOutputFromMemoryEnablePadding) {
1914 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1915 ANeuralNetworksExecution* execution;
1916 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
1917 ANEURALNETWORKS_NO_ERROR);
1918
1919 const size_t memorySize = 20;
1920 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
1921 ASSERT_GT(memoryFd, 0);
1922
1923 ANeuralNetworksMemory* memory;
1924 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd,
1925 0, &memory),
1926 ANEURALNETWORKS_NO_ERROR);
1927
1928 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(mExecution, true),
1929 ANEURALNETWORKS_NO_ERROR);
1930
1931 // This should fail, because length is less than the size of a float32.
1932 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0,
1933 sizeof(float) - 1),
1934 ANEURALNETWORKS_BAD_DATA);
1935
1936 // close memory
1937 ANeuralNetworksMemory_free(memory);
1938 ANeuralNetworksExecution_free(execution);
1939 close(memoryFd);
1940 } else {
1941 GTEST_SKIP();
1942 }
1943 }
1944
TEST_F(ValidationTestExecution,SetOutputFromAHardwareBufferBlob)1945 TEST_F(ValidationTestExecution, SetOutputFromAHardwareBufferBlob) {
1946 const size_t memorySize = 20;
1947
1948 AHardwareBuffer_Desc desc{
1949 .width = memorySize,
1950 .height = 1,
1951 .layers = 1,
1952 .format = AHARDWAREBUFFER_FORMAT_BLOB,
1953 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
1954 };
1955
1956 AHardwareBuffer* buffer = nullptr;
1957 ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
1958
1959 ANeuralNetworksMemory* memory;
1960 EXPECT_EQ(ANeuralNetworksMemory_createFromAHardwareBuffer(buffer, &memory),
1961 ANEURALNETWORKS_NO_ERROR);
1962
1963 // This should fail, because memory is not the size of a float32.
1964 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory, 0,
1965 memorySize),
1966 ANEURALNETWORKS_BAD_DATA);
1967
1968 // This should fail, because offset is larger than memorySize.
1969 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory,
1970 memorySize + 1, sizeof(float)),
1971 ANEURALNETWORKS_BAD_DATA);
1972
1973 // This should fail, because requested size is larger than the memory.
1974 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory,
1975 memorySize - 3, sizeof(float)),
1976 ANEURALNETWORKS_BAD_DATA);
1977
1978 // These should fail, because the tensor types are invalid.
1979 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, &kInvalidTensorType1,
1980 memory, 0, sizeof(float)),
1981 ANEURALNETWORKS_BAD_DATA);
1982 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, &kInvalidTensorType2,
1983 memory, 0, sizeof(float)),
1984 ANEURALNETWORKS_BAD_DATA);
1985
1986 // close memory
1987 ANeuralNetworksMemory_free(memory);
1988 AHardwareBuffer_release(buffer);
1989 }
1990
TEST_F(ValidationTestExecution,SetOutputFromAHardwareBufferBlobEnablePadding)1991 TEST_F(ValidationTestExecution, SetOutputFromAHardwareBufferBlobEnablePadding) {
1992 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
1993 const size_t memorySize = 20;
1994
1995 AHardwareBuffer_Desc desc{
1996 .width = memorySize,
1997 .height = 1,
1998 .layers = 1,
1999 .format = AHARDWAREBUFFER_FORMAT_BLOB,
2000 .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
2001 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
2002 };
2003
2004 AHardwareBuffer* buffer = nullptr;
2005 ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
2006
2007 ANeuralNetworksMemory* memory;
2008 EXPECT_EQ(ANeuralNetworksMemory_createFromAHardwareBuffer(buffer, &memory),
2009 ANEURALNETWORKS_NO_ERROR);
2010
2011 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(mExecution, true),
2012 ANEURALNETWORKS_NO_ERROR);
2013
2014 // This should fail, because length is less than the size of a float32.
2015 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory, 0,
2016 sizeof(float) - 1),
2017 ANEURALNETWORKS_BAD_DATA);
2018
2019 // close memory
2020 ANeuralNetworksMemory_free(memory);
2021 AHardwareBuffer_release(buffer);
2022 } else {
2023 GTEST_SKIP();
2024 }
2025 }
2026
TEST_F(ValidationTestExecution,EnablePaddingAfterSetInputOutput)2027 TEST_F(ValidationTestExecution, EnablePaddingAfterSetInputOutput) {
2028 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
2029 ANeuralNetworksExecution* execution;
2030 char buffer[20];
2031 const size_t memorySize = 20;
2032 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
2033 ASSERT_GT(memoryFd, 0);
2034
2035 ANeuralNetworksMemory* memory;
2036 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd,
2037 0, &memory),
2038 ANEURALNETWORKS_NO_ERROR);
2039
2040 // Enable padding after setInput.
2041 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
2042 ANEURALNETWORKS_NO_ERROR);
2043 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, buffer, 8),
2044 ANEURALNETWORKS_NO_ERROR);
2045 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(execution, true),
2046 ANEURALNETWORKS_BAD_STATE);
2047 ANeuralNetworksExecution_free(execution);
2048
2049 // Enable padding after setInputFromMemory.
2050 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
2051 ANEURALNETWORKS_NO_ERROR);
2052 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr, memory, 0, 8),
2053 ANEURALNETWORKS_NO_ERROR);
2054 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(execution, true),
2055 ANEURALNETWORKS_BAD_STATE);
2056 ANeuralNetworksExecution_free(execution);
2057
2058 // Enable padding after setOutput.
2059 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
2060 ANEURALNETWORKS_NO_ERROR);
2061 EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, buffer, 8),
2062 ANEURALNETWORKS_NO_ERROR);
2063 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(execution, true),
2064 ANEURALNETWORKS_BAD_STATE);
2065 ANeuralNetworksExecution_free(execution);
2066
2067 // Enable padding after setOutputFromMemory.
2068 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
2069 ANEURALNETWORKS_NO_ERROR);
2070 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0, 8),
2071 ANEURALNETWORKS_NO_ERROR);
2072 EXPECT_EQ(ANeuralNetworksExecution_enableInputAndOutputPadding(execution, true),
2073 ANEURALNETWORKS_BAD_STATE);
2074 ANeuralNetworksExecution_free(execution);
2075
2076 // close memory
2077 ANeuralNetworksMemory_free(memory);
2078 close(memoryFd);
2079 } else {
2080 GTEST_SKIP();
2081 }
2082 }
2083
TEST_F(ValidationTestExecutionDeviceMemory,SetInputFromMemory)2084 TEST_F(ValidationTestExecutionDeviceMemory, SetInputFromMemory) {
2085 ANeuralNetworksMemoryDesc* desc;
2086 ASSERT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
2087 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, mCompilation, 0, 1.0f),
2088 ANEURALNETWORKS_NO_ERROR);
2089
2090 // The following output roles are for init/deinit of the device memory.
2091 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, mInitCompilation, 0, 1.0f),
2092 ANEURALNETWORKS_NO_ERROR);
2093 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, mDeinitCompilation, 0, 1.0f),
2094 ANEURALNETWORKS_NO_ERROR);
2095
2096 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
2097
2098 ANeuralNetworksMemory* memory;
2099 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &memory), ANEURALNETWORKS_NO_ERROR);
2100 ANeuralNetworksMemoryDesc_free(desc);
2101
2102 // Uninitialized memory as input.
2103 executeWithMemoryAsInput(mCompilation, memory, ANEURALNETWORKS_OP_FAILED);
2104
2105 // The memory is deinitialized between setInputFromMemory and compute.
2106 {
2107 // Initialize device memory.
2108 executeWithMemoryAsOutput(mInitCompilation, memory, ANEURALNETWORKS_NO_ERROR);
2109
2110 float data = 0;
2111 ANeuralNetworksExecution* execution = nullptr;
2112 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
2113 ANEURALNETWORKS_NO_ERROR);
2114 ASSERT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr, memory, 0, 0),
2115 ANEURALNETWORKS_NO_ERROR);
2116 ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &data, sizeof(float)),
2117 ANEURALNETWORKS_NO_ERROR);
2118
2119 // Deinitialize device memory.
2120 executeWithMemoryAsOutput(mDeinitCompilation, memory, ANEURALNETWORKS_OP_FAILED);
2121
2122 // Uninitialized memory as input at compute time.
2123 ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_OP_FAILED);
2124 ANeuralNetworksExecution_free(execution);
2125 }
2126
2127 // Initialize device memory.
2128 executeWithMemoryAsOutput(mInitCompilation, memory, ANEURALNETWORKS_NO_ERROR);
2129
2130 // Bad offset and length.
2131 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 1, 0),
2132 ANEURALNETWORKS_BAD_DATA);
2133 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0,
2134 sizeof(float)),
2135 ANEURALNETWORKS_BAD_DATA);
2136
2137 // Bad usage -- not configured for this role.
2138 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory, 0, 0),
2139 ANEURALNETWORKS_BAD_DATA);
2140
2141 // Deinitialize device memory.
2142 executeWithMemoryAsOutput(mDeinitCompilation, memory, ANEURALNETWORKS_OP_FAILED);
2143
2144 // Uninitialized memory as input.
2145 executeWithMemoryAsInput(mCompilation, memory, ANEURALNETWORKS_OP_FAILED);
2146
2147 ANeuralNetworksMemory_free(memory);
2148 }
2149
TEST_F(ValidationTestExecutionDeviceMemory,SetOutputFromMemory)2150 TEST_F(ValidationTestExecutionDeviceMemory, SetOutputFromMemory) {
2151 ANeuralNetworksMemoryDesc* desc;
2152 ASSERT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
2153 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, mCompilation, 0, 1.0f),
2154 ANEURALNETWORKS_NO_ERROR);
2155 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
2156
2157 ANeuralNetworksMemory* memory;
2158 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &memory), ANEURALNETWORKS_NO_ERROR);
2159 ANeuralNetworksMemoryDesc_free(desc);
2160
2161 // Bad offset and length.
2162 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory, 1, 0),
2163 ANEURALNETWORKS_BAD_DATA);
2164 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecution, 0, nullptr, memory, 0,
2165 sizeof(float)),
2166 ANEURALNETWORKS_BAD_DATA);
2167
2168 // Bad usage -- not configured for this role.
2169 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecution, 0, nullptr, memory, 0, 0),
2170 ANEURALNETWORKS_BAD_DATA);
2171
2172 ANeuralNetworksMemory_free(memory);
2173 }
2174
TEST_F(ValidationTestExecutionDeviceMemory,SetInputFromMemory_DynamicShape)2175 TEST_F(ValidationTestExecutionDeviceMemory, SetInputFromMemory_DynamicShape) {
2176 uint32_t dimension = 1, badDimension = 2;
2177 ANeuralNetworksOperandType badType = {
2178 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2179 .dimensionCount = 1,
2180 .dimensions = &badDimension,
2181 };
2182
2183 ANeuralNetworksMemoryDesc* desc;
2184 ASSERT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
2185 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, mCompilationDynamic, 0, 1.0f),
2186 ANEURALNETWORKS_NO_ERROR);
2187 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(desc, 1, &dimension),
2188 ANEURALNETWORKS_NO_ERROR);
2189
2190 // The following output role is for init of the device memory.
2191 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, mInitCompilation, 0, 1.0f),
2192 ANEURALNETWORKS_NO_ERROR);
2193
2194 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
2195
2196 ANeuralNetworksMemory* memory;
2197 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &memory), ANEURALNETWORKS_NO_ERROR);
2198 ANeuralNetworksMemoryDesc_free(desc);
2199
2200 // Initialize device memory.
2201 executeWithMemoryAsOutput(mInitCompilation, memory, ANEURALNETWORKS_NO_ERROR);
2202
2203 // Incompatible dimensions between updated type and memory.
2204 EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(mExecutionDynamic, 0, &badType, memory, 0,
2205 0),
2206 ANEURALNETWORKS_BAD_DATA);
2207
2208 ANeuralNetworksMemory_free(memory);
2209 }
2210
TEST_F(ValidationTestExecutionDeviceMemory,SetOutputFromMemory_DynamicShape)2211 TEST_F(ValidationTestExecutionDeviceMemory, SetOutputFromMemory_DynamicShape) {
2212 uint32_t dimension = 1, badDimension = 2;
2213 ANeuralNetworksOperandType badType = {
2214 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2215 .dimensionCount = 1,
2216 .dimensions = &badDimension,
2217 };
2218
2219 ANeuralNetworksMemoryDesc* desc;
2220 ASSERT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
2221 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, mCompilationDynamic, 0, 1.0f),
2222 ANEURALNETWORKS_NO_ERROR);
2223 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(desc, 1, &dimension),
2224 ANEURALNETWORKS_NO_ERROR);
2225 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
2226
2227 ANeuralNetworksMemory* memory;
2228 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &memory), ANEURALNETWORKS_NO_ERROR);
2229 ANeuralNetworksMemoryDesc_free(desc);
2230
2231 // Incompatible dimensions between updated type and memory.
2232 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(mExecutionDynamic, 0, &badType, memory,
2233 0, 0),
2234 ANEURALNETWORKS_BAD_DATA);
2235
2236 ANeuralNetworksMemory_free(memory);
2237 }
2238
TEST_F(ValidationTestExecution,Compute)2239 TEST_F(ValidationTestExecution, Compute) {
2240 EXPECT_EQ(ANeuralNetworksExecution_compute(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2241 }
2242
TEST_F(ValidationTestExecution,StartCompute)2243 TEST_F(ValidationTestExecution, StartCompute) {
2244 ANeuralNetworksExecution* execution;
2245 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
2246
2247 ANeuralNetworksEvent* event;
2248 EXPECT_EQ(ANeuralNetworksExecution_startCompute(nullptr, &event),
2249 ANEURALNETWORKS_UNEXPECTED_NULL);
2250 EXPECT_EQ(ANeuralNetworksExecution_startCompute(execution, nullptr),
2251 ANEURALNETWORKS_UNEXPECTED_NULL);
2252
2253 // close memory
2254 ANeuralNetworksExecution_free(execution);
2255 }
2256
TEST_F(ValidationTestExecution,EventWait)2257 TEST_F(ValidationTestExecution, EventWait) {
2258 EXPECT_EQ(ANeuralNetworksEvent_wait(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2259 }
2260
TEST_F(ValidationTest,EventCreateFromSyncFenceFd)2261 TEST_F(ValidationTest, EventCreateFromSyncFenceFd) {
2262 ANeuralNetworksEvent* event;
2263 EXPECT_EQ(ANeuralNetworksEvent_createFromSyncFenceFd(-1, &event), ANEURALNETWORKS_BAD_DATA);
2264 EXPECT_EQ(ANeuralNetworksEvent_createFromSyncFenceFd(1, nullptr),
2265 ANEURALNETWORKS_UNEXPECTED_NULL);
2266 }
2267
TEST_F(ValidationTest,EventGetSyncFenceFd)2268 TEST_F(ValidationTest, EventGetSyncFenceFd) {
2269 int syncFd = -100;
2270 EXPECT_EQ(ANeuralNetworksEvent_getSyncFenceFd(nullptr, &syncFd),
2271 ANEURALNETWORKS_UNEXPECTED_NULL);
2272 EXPECT_EQ(syncFd, -1);
2273 }
2274
TEST_F(ValidationTestExecution,EventGetSyncFenceFdFromStartCompute)2275 TEST_F(ValidationTestExecution, EventGetSyncFenceFdFromStartCompute) {
2276 // Create a valid execution and event first.
2277 ANeuralNetworksExecution* execution;
2278 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
2279 float input0[] = {1.0f, 1.0f}, input1[] = {2.0f, 2.0f}, output0[2];
2280 int32_t input2[] = {0};
2281 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, input0, sizeof(input0)),
2282 ANEURALNETWORKS_NO_ERROR);
2283 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, input1, sizeof(input1)),
2284 ANEURALNETWORKS_NO_ERROR);
2285 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, input2, sizeof(input2)),
2286 ANEURALNETWORKS_NO_ERROR);
2287 EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, output0, sizeof(output0)),
2288 ANEURALNETWORKS_NO_ERROR);
2289 ANeuralNetworksEvent* event = nullptr;
2290 EXPECT_EQ(ANeuralNetworksExecution_startCompute(execution, &event), ANEURALNETWORKS_NO_ERROR);
2291
2292 // The event from startCompute is not backed by sync fence.
2293 int syncFd = -100;
2294 EXPECT_EQ(ANeuralNetworksEvent_getSyncFenceFd(event, &syncFd), ANEURALNETWORKS_BAD_DATA);
2295 EXPECT_EQ(syncFd, -1);
2296
2297 ANeuralNetworksEvent_free(event);
2298 ANeuralNetworksExecution_free(execution);
2299 }
2300
TEST_F(ValidationTestExecution,FencedExecution)2301 TEST_F(ValidationTestExecution, FencedExecution) {
2302 // Create a valid execution and event first.
2303 ANeuralNetworksExecution* execution1;
2304 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution1), ANEURALNETWORKS_NO_ERROR);
2305 float input0[] = {1.0f, 1.0f}, input1[] = {2.0f, 2.0f}, output0[2];
2306 int32_t input2[] = {0};
2307 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution1, 0, nullptr, input0, sizeof(input0)),
2308 ANEURALNETWORKS_NO_ERROR);
2309 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution1, 1, nullptr, input1, sizeof(input1)),
2310 ANEURALNETWORKS_NO_ERROR);
2311 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution1, 2, nullptr, input2, sizeof(input2)),
2312 ANEURALNETWORKS_NO_ERROR);
2313 EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution1, 0, nullptr, output0, sizeof(output0)),
2314 ANEURALNETWORKS_NO_ERROR);
2315 ANeuralNetworksEvent* event1 = nullptr;
2316 EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution1, nullptr, 0, 0,
2317 &event1),
2318 ANEURALNETWORKS_NO_ERROR);
2319
2320 EXPECT_EQ(ANeuralNetworksEvent_getSyncFenceFd(event1, nullptr),
2321 ANEURALNETWORKS_UNEXPECTED_NULL);
2322
2323 // The event from startComputeWithDependencie may or may not be backed by a sync fence depending
2324 // on the driver implementation.
2325 int syncFd = -100;
2326 int getSyncFdResult = ANeuralNetworksEvent_getSyncFenceFd(event1, &syncFd);
2327 if (getSyncFdResult == ANEURALNETWORKS_NO_ERROR) {
2328 EXPECT_GE(syncFd, 0);
2329 close(syncFd);
2330 } else {
2331 EXPECT_EQ(getSyncFdResult, ANEURALNETWORKS_BAD_DATA);
2332 EXPECT_EQ(syncFd, -1);
2333 }
2334
2335 // The subsequent execution will wait for the first execution to finish.
2336 ANeuralNetworksExecution* execution2;
2337 ANeuralNetworksEvent* event2 = nullptr;
2338 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution2), ANEURALNETWORKS_NO_ERROR);
2339 EXPECT_EQ(
2340 ANeuralNetworksExecution_startComputeWithDependencies(nullptr, &event1, 1, 0, &event2),
2341 ANEURALNETWORKS_UNEXPECTED_NULL);
2342 EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution2, nullptr, 1, 0,
2343 &event2),
2344 ANEURALNETWORKS_UNEXPECTED_NULL);
2345 EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution2, &event1, 1, 0,
2346 nullptr),
2347 ANEURALNETWORKS_UNEXPECTED_NULL);
2348 ANeuralNetworksEvent* wait_for_list[] = {event1, nullptr};
2349 EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution2, wait_for_list, 2, 0,
2350 &event2),
2351 ANEURALNETWORKS_UNEXPECTED_NULL);
2352
2353 ANeuralNetworksEvent_free(event1);
2354 ANeuralNetworksExecution_free(execution1);
2355 ANeuralNetworksExecution_free(execution2);
2356 }
2357
TEST_F(ValidationTestExecution,GetOutputOperandRankAndDimensions)2358 TEST_F(ValidationTestExecution, GetOutputOperandRankAndDimensions) {
2359 ANeuralNetworksExecution* execution;
2360 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
2361
2362 float input0[] = {1.0f, 1.0f}, input1[] = {2.0f, 2.0f}, output0[2];
2363 int32_t input2[] = {0};
2364 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, input0, sizeof(input0)),
2365 ANEURALNETWORKS_NO_ERROR);
2366 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, input1, sizeof(input1)),
2367 ANEURALNETWORKS_NO_ERROR);
2368 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, input2, sizeof(input2)),
2369 ANEURALNETWORKS_NO_ERROR);
2370 EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, output0, sizeof(output0)),
2371 ANEURALNETWORKS_NO_ERROR);
2372
2373 uint32_t rank, dims[4], expectedRank = 1, expectedDims = 2;
2374 // This should fail, because the execution has not yet started to compute.
2375 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandRank(execution, 0, &rank),
2376 ANEURALNETWORKS_BAD_STATE);
2377 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandDimensions(execution, 0, dims),
2378 ANEURALNETWORKS_BAD_STATE);
2379
2380 ANeuralNetworksEvent* event;
2381 EXPECT_EQ(ANeuralNetworksExecution_startCompute(execution, &event), ANEURALNETWORKS_NO_ERROR);
2382 EXPECT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR);
2383
2384 // This should fail, because unexpected nullptr.
2385 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandRank(nullptr, 0, &rank),
2386 ANEURALNETWORKS_UNEXPECTED_NULL);
2387 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandDimensions(nullptr, 0, dims),
2388 ANEURALNETWORKS_UNEXPECTED_NULL);
2389 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandRank(execution, 0, nullptr),
2390 ANEURALNETWORKS_UNEXPECTED_NULL);
2391 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandDimensions(execution, 0, nullptr),
2392 ANEURALNETWORKS_UNEXPECTED_NULL);
2393
2394 // This should fail, because the operand does not exist.
2395 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandRank(execution, -1, &rank),
2396 ANEURALNETWORKS_BAD_DATA);
2397 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandRank(execution, 999, &rank),
2398 ANEURALNETWORKS_BAD_DATA);
2399 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandDimensions(execution, -1, dims),
2400 ANEURALNETWORKS_BAD_DATA);
2401 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandDimensions(execution, 999, dims),
2402 ANEURALNETWORKS_BAD_DATA);
2403
2404 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandRank(execution, 0, &rank),
2405 ANEURALNETWORKS_NO_ERROR);
2406 EXPECT_EQ(ANeuralNetworksExecution_getOutputOperandDimensions(execution, 0, dims),
2407 ANEURALNETWORKS_NO_ERROR);
2408 EXPECT_EQ(rank, expectedRank);
2409 EXPECT_EQ(dims[0], expectedDims);
2410
2411 // close memory
2412 ANeuralNetworksEvent_free(event);
2413 ANeuralNetworksExecution_free(execution);
2414 }
2415
2416 // Regression test for b/146044137.
2417 class ValidationTestDimensionProductOverflow : public ValidationTestExecution {
2418 protected:
createModel()2419 void createModel() override {
2420 uint32_t dimensions[] = {5, 4, 4, 0, 5, 3, 0, 4, 5};
2421 ANeuralNetworksOperandType operandType = {
2422 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2423 .dimensionCount = std::size(dimensions),
2424 .dimensions = dimensions,
2425 };
2426 addOperand(operandType);
2427 addOperand(operandType);
2428 ASSERT_EQ(addOperation(ANEURALNETWORKS_ABS, {0}, {1}), ANEURALNETWORKS_NO_ERROR);
2429 ASSERT_EQ(identifyInputsAndOutputs({0}, {1}), ANEURALNETWORKS_NO_ERROR);
2430 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_NO_ERROR);
2431 }
2432 };
2433
TEST_F(ValidationTestDimensionProductOverflow,SetInputOrOutput)2434 TEST_F(ValidationTestDimensionProductOverflow, SetInputOrOutput) {
2435 uint32_t dimensions[] = {5, 4, 4, 786433, 5, 3, 16777216, 4, 5};
2436 ANeuralNetworksOperandType operandType = {
2437 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2438 .dimensionCount = std::size(dimensions),
2439 .dimensions = dimensions,
2440 };
2441 uint8_t buffer[20];
2442 // This should fail, as the new operand type's dimension product overflows
2443 // uint32_t.
2444 EXPECT_EQ(
2445 ANeuralNetworksExecution_setInput(mExecution, 0, &operandType, buffer, sizeof(buffer)),
2446 ANEURALNETWORKS_BAD_DATA);
2447 EXPECT_EQ(
2448 ANeuralNetworksExecution_setOutput(mExecution, 0, &operandType, buffer, sizeof(buffer)),
2449 ANEURALNETWORKS_BAD_DATA);
2450 }
2451
TEST_F(ValidationTestModel,AddOperandDimensionProductOverflow)2452 TEST_F(ValidationTestModel, AddOperandDimensionProductOverflow) {
2453 uint32_t dimensions[] = {5, 4, 4, 786433, 5, 3, 16777216, 4, 5};
2454 ANeuralNetworksOperandType operandType = {
2455 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2456 .dimensionCount = std::size(dimensions),
2457 .dimensions = dimensions,
2458 };
2459 // This should fail, as the operand type's dimension product overflows uint32_t.
2460 ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &operandType), ANEURALNETWORKS_BAD_DATA);
2461 }
2462
2463 class ValidationTestDimensionProductOverflow2 : public ValidationTestExecution {
2464 protected:
createModel()2465 void createModel() override {
2466 addTensorOperand(ANEURALNETWORKS_TENSOR_FLOAT32, {0, 1});
2467 addTensorOperand(ANEURALNETWORKS_TENSOR_FLOAT32, {0, 1});
2468 addTensorOperand(ANEURALNETWORKS_TENSOR_FLOAT32, {0});
2469 addScalarOperand(ANEURALNETWORKS_INT32);
2470 int32_t activation = 0;
2471 ASSERT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 3, &activation, sizeof(activation)),
2472 ANEURALNETWORKS_NO_ERROR);
2473 addTensorOperand(ANEURALNETWORKS_TENSOR_FLOAT32, {0, 0});
2474 ASSERT_EQ(addOperation(ANEURALNETWORKS_FULLY_CONNECTED, {0, 1, 2, 3}, {4}),
2475 ANEURALNETWORKS_NO_ERROR);
2476 ASSERT_EQ(identifyInputsAndOutputs({0, 1, 2}, {4}), ANEURALNETWORKS_NO_ERROR);
2477 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_NO_ERROR);
2478 }
2479 };
2480
TEST_F(ValidationTestDimensionProductOverflow2,DynamicOutputShapeOverflow)2481 TEST_F(ValidationTestDimensionProductOverflow2, DynamicOutputShapeOverflow) {
2482 constexpr uint32_t kLargeDim = 1 << 16;
2483 std::vector<float> inputData(kLargeDim), outputData(kLargeDim);
2484 const uint32_t inputDims[] = {kLargeDim, 1};
2485 const uint32_t biasDims[] = {kLargeDim};
2486 const ANeuralNetworksOperandType inputType = {
2487 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2488 .dimensionCount = std::size(inputDims),
2489 .dimensions = inputDims,
2490 };
2491 const ANeuralNetworksOperandType biasType = {
2492 .type = ANEURALNETWORKS_TENSOR_FLOAT32,
2493 .dimensionCount = std::size(biasDims),
2494 .dimensions = biasDims,
2495 };
2496 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, &inputType, inputData.data(),
2497 inputData.size() * sizeof(float)),
2498 ANEURALNETWORKS_NO_ERROR);
2499 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 1, &inputType, inputData.data(),
2500 inputData.size() * sizeof(float)),
2501 ANEURALNETWORKS_NO_ERROR);
2502 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 2, &biasType, inputData.data(),
2503 inputData.size() * sizeof(float)),
2504 ANEURALNETWORKS_NO_ERROR);
2505 EXPECT_EQ(ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, outputData.data(),
2506 outputData.size() * sizeof(float)),
2507 ANEURALNETWORKS_NO_ERROR);
2508
2509 // This should fail, because the deduced output data size overflows uint32_t.
2510 EXPECT_NE(ANeuralNetworksExecution_compute(mExecution), ANEURALNETWORKS_NO_ERROR);
2511 }
2512
TEST_F(ValidationTestBurst,BurstComputeNull)2513 TEST_F(ValidationTestBurst, BurstComputeNull) {
2514 EXPECT_EQ(ANeuralNetworksExecution_burstCompute(mExecution, nullptr),
2515 ANEURALNETWORKS_UNEXPECTED_NULL);
2516 EXPECT_EQ(ANeuralNetworksExecution_burstCompute(nullptr, mBurst),
2517 ANEURALNETWORKS_UNEXPECTED_NULL);
2518 }
2519
TEST_F(ValidationTestBurst,BurstComputeBadCompilation)2520 TEST_F(ValidationTestBurst, BurstComputeBadCompilation) {
2521 ANeuralNetworksCompilation* compilation;
2522 ASSERT_EQ(ANeuralNetworksCompilation_create(mModel, &compilation), ANEURALNETWORKS_NO_ERROR);
2523 // NOTE: ANeuralNetworksCompilation_finish not called
2524
2525 ANeuralNetworksBurst* burst;
2526 EXPECT_EQ(ANeuralNetworksBurst_create(compilation, &burst), ANEURALNETWORKS_BAD_STATE);
2527
2528 // close memory
2529 ANeuralNetworksBurst_free(burst);
2530 ANeuralNetworksCompilation_free(compilation);
2531 }
2532
TEST_F(ValidationTestBurst,BurstComputeDifferentCompilations)2533 TEST_F(ValidationTestBurst, BurstComputeDifferentCompilations) {
2534 ANeuralNetworksCompilation* secondCompilation;
2535 ASSERT_EQ(ANeuralNetworksCompilation_create(mModel, &secondCompilation),
2536 ANEURALNETWORKS_NO_ERROR);
2537 ASSERT_EQ(ANeuralNetworksCompilation_finish(secondCompilation), ANEURALNETWORKS_NO_ERROR);
2538
2539 ANeuralNetworksExecution* execution;
2540 EXPECT_EQ(ANeuralNetworksExecution_create(secondCompilation, &execution),
2541 ANEURALNETWORKS_NO_ERROR);
2542
2543 EXPECT_EQ(ANeuralNetworksExecution_burstCompute(execution, mBurst), ANEURALNETWORKS_BAD_DATA);
2544
2545 ANeuralNetworksExecution_free(execution);
2546 ANeuralNetworksCompilation_free(secondCompilation);
2547 }
2548
TEST_F(ValidationTestBurst,BurstComputeConcurrent)2549 TEST_F(ValidationTestBurst, BurstComputeConcurrent) {
2550 ANeuralNetworksExecution* secondExecution;
2551 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &secondExecution),
2552 ANEURALNETWORKS_NO_ERROR);
2553
2554 // set inputs of first execution
2555 float inputA0[] = {1.0f, 1.0f}, inputA1[] = {2.0f, 2.0f}, outputA0[2];
2556 int32_t inputA2[] = {0};
2557 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 0, nullptr, inputA0, sizeof(inputA0)),
2558 ANEURALNETWORKS_NO_ERROR);
2559 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 1, nullptr, inputA1, sizeof(inputA1)),
2560 ANEURALNETWORKS_NO_ERROR);
2561 EXPECT_EQ(ANeuralNetworksExecution_setInput(mExecution, 2, nullptr, inputA2, sizeof(inputA2)),
2562 ANEURALNETWORKS_NO_ERROR);
2563 EXPECT_EQ(
2564 ANeuralNetworksExecution_setOutput(mExecution, 0, nullptr, outputA0, sizeof(outputA0)),
2565 ANEURALNETWORKS_NO_ERROR);
2566
2567 // set inputs of second execution
2568 float inputB0[] = {1.0f, 1.0f}, inputB1[] = {2.0f, 2.0f}, outputB0[2];
2569 int32_t inputB2[] = {0};
2570 EXPECT_EQ(ANeuralNetworksExecution_setInput(secondExecution, 0, nullptr, inputB0,
2571 sizeof(inputB0)),
2572 ANEURALNETWORKS_NO_ERROR);
2573 EXPECT_EQ(ANeuralNetworksExecution_setInput(secondExecution, 1, nullptr, inputB1,
2574 sizeof(inputB1)),
2575 ANEURALNETWORKS_NO_ERROR);
2576 EXPECT_EQ(ANeuralNetworksExecution_setInput(secondExecution, 2, nullptr, inputB2,
2577 sizeof(inputB2)),
2578 ANEURALNETWORKS_NO_ERROR);
2579 EXPECT_EQ(ANeuralNetworksExecution_setOutput(secondExecution, 0, nullptr, outputB0,
2580 sizeof(outputB0)),
2581 ANEURALNETWORKS_NO_ERROR);
2582
2583 // Execute on the same burst concurrently. At least one result must be
2584 // ANEURALNETWORKS_NO_ERROR. One may return ANEURALNETWORKS_BAD_STATE if the
2585 // other is already executing on the burst.
2586 auto first = std::async(std::launch::async, [this] {
2587 return ANeuralNetworksExecution_burstCompute(mExecution, mBurst);
2588 });
2589 auto second = std::async(std::launch::async, [this, secondExecution] {
2590 return ANeuralNetworksExecution_burstCompute(secondExecution, mBurst);
2591 });
2592
2593 const int result1 = first.get();
2594 const int result2 = second.get();
2595 EXPECT_TRUE(result1 == ANEURALNETWORKS_BAD_STATE || result1 == ANEURALNETWORKS_NO_ERROR);
2596 EXPECT_TRUE(result2 == ANEURALNETWORKS_BAD_STATE || result2 == ANEURALNETWORKS_NO_ERROR);
2597 EXPECT_TRUE(result1 == ANEURALNETWORKS_NO_ERROR || result2 == ANEURALNETWORKS_NO_ERROR);
2598
2599 ANeuralNetworksExecution_free(secondExecution);
2600 }
2601
2602 // The burst object maintains a local cache of memory objects. Because the burst
2603 // is intended to live for multiple executions, and because memory might be
2604 // created and freed for each execution, burst includes internal mechanisms to
2605 // purge memory objects from its cache that have been freed by the NNAPI client.
2606 // The following two test cases (FreeMemoryBeforeBurst and
2607 // FreeBurstBeforeMemory) ensure that this internal cleanup is tested in both
2608 // freeing orders.
2609 //
2610 // These two test cases explicitly create a new burst object and a new execution
2611 // object so that the order of freeing can be specified. If these tests instead
2612 // relied on the provided mExecution and mBurst, mBurst would always be freed
2613 // before mExecution.
2614
TEST_F(ValidationTestBurst,FreeMemoryBeforeBurst)2615 TEST_F(ValidationTestBurst, FreeMemoryBeforeBurst) {
2616 ANeuralNetworksBurst* burst;
2617 EXPECT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst), ANEURALNETWORKS_NO_ERROR);
2618
2619 // prepare data for execution
2620 float input0[] = {1.0f, 1.0f}, input1[] = {2.0f, 2.0f}, output0[2];
2621 int32_t input2[] = {0};
2622
2623 const size_t memorySize = sizeof(output0);
2624 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
2625 ASSERT_GT(memoryFd, 0);
2626
2627 ANeuralNetworksMemory* memory;
2628 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd, 0,
2629 &memory),
2630 ANEURALNETWORKS_NO_ERROR);
2631
2632 // create and configure execution
2633 ANeuralNetworksExecution* execution;
2634 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
2635 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, input0, sizeof(input0)),
2636 ANEURALNETWORKS_NO_ERROR);
2637 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, input1, sizeof(input1)),
2638 ANEURALNETWORKS_NO_ERROR);
2639 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, input2, sizeof(input2)),
2640 ANEURALNETWORKS_NO_ERROR);
2641 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0,
2642 sizeof(output0)),
2643 ANEURALNETWORKS_NO_ERROR);
2644
2645 // preform execution to cache memory into burst
2646 EXPECT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst), ANEURALNETWORKS_NO_ERROR);
2647 ANeuralNetworksExecution_free(execution);
2648
2649 // free memory before burst
2650 ANeuralNetworksMemory_free(memory);
2651 ANeuralNetworksBurst_free(burst);
2652
2653 // close memory
2654 close(memoryFd);
2655 }
2656
TEST_F(ValidationTestBurst,FreeBurstBeforeMemory)2657 TEST_F(ValidationTestBurst, FreeBurstBeforeMemory) {
2658 ANeuralNetworksBurst* burst;
2659 EXPECT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst), ANEURALNETWORKS_NO_ERROR);
2660
2661 // prepare data for execution
2662 float input0[] = {1.0f, 1.0f}, input1[] = {2.0f, 2.0f}, output0[2];
2663 int32_t input2[] = {0};
2664 const size_t memorySize = sizeof(output0);
2665 int memoryFd = ASharedMemory_create("nnMemory", memorySize);
2666 ASSERT_GT(memoryFd, 0);
2667
2668 ANeuralNetworksMemory* memory;
2669 EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd, 0,
2670 &memory),
2671 ANEURALNETWORKS_NO_ERROR);
2672
2673 // create and configure execution
2674 ANeuralNetworksExecution* execution;
2675 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
2676 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, input0, sizeof(input0)),
2677 ANEURALNETWORKS_NO_ERROR);
2678 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, input1, sizeof(input1)),
2679 ANEURALNETWORKS_NO_ERROR);
2680 EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, input2, sizeof(input2)),
2681 ANEURALNETWORKS_NO_ERROR);
2682 EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0,
2683 sizeof(output0)),
2684 ANEURALNETWORKS_NO_ERROR);
2685
2686 // preform execution to cache memory into burst
2687 EXPECT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst), ANEURALNETWORKS_NO_ERROR);
2688 ANeuralNetworksExecution_free(execution);
2689
2690 // free burst before memory
2691 ANeuralNetworksBurst_free(burst);
2692 ANeuralNetworksMemory_free(memory);
2693
2694 // close memory
2695 close(memoryFd);
2696 }
2697
TEST(ValidationTestIntrospection,GetNumDevices)2698 TEST(ValidationTestIntrospection, GetNumDevices) {
2699 uint32_t numDevices = 0;
2700 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2701 EXPECT_EQ(ANeuralNetworks_getDeviceCount(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2702 }
2703
TEST(ValidationTestIntrospection,GetDevice)2704 TEST(ValidationTestIntrospection, GetDevice) {
2705 uint32_t numDevices = 0;
2706 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2707
2708 ANeuralNetworksDevice* device = nullptr;
2709 for (uint32_t i = 0; i < numDevices; i++) {
2710 SCOPED_TRACE(i);
2711 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
2712 EXPECT_NE(device, nullptr);
2713 }
2714 EXPECT_EQ(ANeuralNetworks_getDevice(0, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2715 EXPECT_EQ(ANeuralNetworks_getDevice(numDevices, &device), ANEURALNETWORKS_BAD_DATA);
2716 }
2717
deviceStringCheck(std::function<int (const ANeuralNetworksDevice *,const char **)> func)2718 static void deviceStringCheck(std::function<int(const ANeuralNetworksDevice*, const char**)> func) {
2719 uint32_t numDevices = 0;
2720 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2721
2722 const char* buffer;
2723 for (uint32_t i = 0; i < numDevices; i++) {
2724 SCOPED_TRACE(i);
2725 ANeuralNetworksDevice* device;
2726 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
2727 EXPECT_EQ(func(device, &buffer), ANEURALNETWORKS_NO_ERROR);
2728 EXPECT_EQ(func(device, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2729 }
2730 EXPECT_EQ(func(nullptr, &buffer), ANEURALNETWORKS_UNEXPECTED_NULL);
2731 EXPECT_EQ(func(nullptr, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2732 }
2733
TEST(ValidationTestIntrospection,DeviceGetName)2734 TEST(ValidationTestIntrospection, DeviceGetName) {
2735 deviceStringCheck(ANeuralNetworksDevice_getName);
2736 }
2737
TEST(ValidationTestIntrospection,DeviceGetNameUnique)2738 TEST(ValidationTestIntrospection, DeviceGetNameUnique) {
2739 uint32_t numDevices = 0;
2740 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2741
2742 std::set<std::string> deviceNames;
2743 for (uint32_t i = 0; i < numDevices; i++) {
2744 ANeuralNetworksDevice* device = nullptr;
2745 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
2746 const char* buffer = nullptr;
2747 EXPECT_EQ(ANeuralNetworksDevice_getName(device, &buffer), ANEURALNETWORKS_NO_ERROR);
2748 std::string name(buffer);
2749 EXPECT_EQ(deviceNames.count(name), (uint32_t)0);
2750 deviceNames.insert(name);
2751 }
2752 }
2753
TEST(ValidationTestIntrospection,DeviceGetVersion)2754 TEST(ValidationTestIntrospection, DeviceGetVersion) {
2755 deviceStringCheck(ANeuralNetworksDevice_getVersion);
2756 }
2757
TEST(ValidationTestIntrospection,DeviceGetFeatureLevel)2758 TEST(ValidationTestIntrospection, DeviceGetFeatureLevel) {
2759 uint32_t numDevices = 0;
2760 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2761
2762 int64_t featureLevel;
2763 for (uint32_t i = 0; i < numDevices; i++) {
2764 SCOPED_TRACE(i);
2765 ANeuralNetworksDevice* device;
2766 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
2767 EXPECT_EQ(ANeuralNetworksDevice_getFeatureLevel(device, &featureLevel),
2768 ANEURALNETWORKS_NO_ERROR);
2769 EXPECT_EQ(ANeuralNetworksDevice_getFeatureLevel(device, nullptr),
2770 ANEURALNETWORKS_UNEXPECTED_NULL);
2771 }
2772 EXPECT_EQ(ANeuralNetworksDevice_getFeatureLevel(nullptr, &featureLevel),
2773 ANEURALNETWORKS_UNEXPECTED_NULL);
2774 EXPECT_EQ(ANeuralNetworksDevice_getFeatureLevel(nullptr, nullptr),
2775 ANEURALNETWORKS_UNEXPECTED_NULL);
2776 }
2777
TEST(ValidationTestIntrospection,DeviceGetType)2778 TEST(ValidationTestIntrospection, DeviceGetType) {
2779 uint32_t numDevices = 0;
2780 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2781
2782 int32_t validTypes[] = {ANEURALNETWORKS_DEVICE_UNKNOWN, ANEURALNETWORKS_DEVICE_OTHER,
2783 ANEURALNETWORKS_DEVICE_CPU, ANEURALNETWORKS_DEVICE_GPU,
2784 ANEURALNETWORKS_DEVICE_ACCELERATOR};
2785 int32_t deviceType;
2786 for (uint32_t i = 0; i < numDevices; i++) {
2787 SCOPED_TRACE(i);
2788 // Initialize the deviceType to be an invalid type.
2789 deviceType = -1;
2790 ANeuralNetworksDevice* device;
2791 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
2792 EXPECT_EQ(ANeuralNetworksDevice_getType(device, &deviceType), ANEURALNETWORKS_NO_ERROR);
2793 EXPECT_TRUE(std::find(std::begin(validTypes), std::end(validTypes), deviceType) !=
2794 std::end(validTypes));
2795 EXPECT_EQ(ANeuralNetworksDevice_getType(device, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2796 }
2797 EXPECT_EQ(ANeuralNetworksDevice_getType(nullptr, &deviceType), ANEURALNETWORKS_UNEXPECTED_NULL);
2798 EXPECT_EQ(ANeuralNetworksDevice_getType(nullptr, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2799 }
2800
TEST(ValidationTestIntrospection,DeviceWait)2801 TEST(ValidationTestIntrospection, DeviceWait) {
2802 uint32_t numDevices = 0;
2803 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2804
2805 for (uint32_t i = 0; i < numDevices; i++) {
2806 SCOPED_TRACE(i);
2807 ANeuralNetworksDevice* device;
2808 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
2809 EXPECT_EQ(ANeuralNetworksDevice_wait(device), ANEURALNETWORKS_NO_ERROR);
2810 }
2811 EXPECT_EQ(ANeuralNetworksDevice_wait(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2812 }
2813
2814 class ValidationTestCompilationForDevices_1 : public ValidationTestModel {
2815 protected:
SetUp()2816 virtual void SetUp() override {
2817 ValidationTestModel::SetUp();
2818 createModel();
2819
2820 uint32_t numDevices = 0;
2821 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2822
2823 if (numDevices > 0) {
2824 EXPECT_EQ(ANeuralNetworks_getDevice(0, &mDevice), ANEURALNETWORKS_NO_ERROR);
2825 bool supported = false;
2826 ASSERT_EQ(mNumOperations, static_cast<uint32_t>(1));
2827 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, &mDevice, 1,
2828 &supported),
2829 ANEURALNETWORKS_NO_ERROR);
2830 if (supported) {
2831 ASSERT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, &mDevice, 1,
2832 &mCompilation),
2833 ANEURALNETWORKS_NO_ERROR);
2834 }
2835 }
2836 }
2837
TearDown()2838 virtual void TearDown() {
2839 ANeuralNetworksCompilation_free(mCompilation);
2840 ValidationTestModel::TearDown();
2841 }
2842
2843 ANeuralNetworksDevice* mDevice = nullptr;
2844 ANeuralNetworksCompilation* mCompilation = nullptr;
2845 };
2846
2847 // Also see TEST_F(ValidationTestCompilation, SetPreference)
TEST_F(ValidationTestCompilationForDevices_1,SetPreference)2848 TEST_F(ValidationTestCompilationForDevices_1, SetPreference) {
2849 EXPECT_EQ(ANeuralNetworksCompilation_setPreference(nullptr, ANEURALNETWORKS_PREFER_LOW_POWER),
2850 ANEURALNETWORKS_UNEXPECTED_NULL);
2851 if (!mCompilation) {
2852 return;
2853 }
2854 EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation, 40), ANEURALNETWORKS_BAD_DATA);
2855 }
2856
2857 // Also see TEST_F(ValidationTestCompilation, SetCaching)
TEST_F(ValidationTestCompilationForDevices_1,SetCaching)2858 TEST_F(ValidationTestCompilationForDevices_1, SetCaching) {
2859 std::vector<uint8_t> token(ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN, 0);
2860 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(nullptr, "/data/local/tmp", token.data()),
2861 ANEURALNETWORKS_UNEXPECTED_NULL);
2862 if (!mCompilation) {
2863 return;
2864 }
2865 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(mCompilation, nullptr, token.data()),
2866 ANEURALNETWORKS_UNEXPECTED_NULL);
2867 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(mCompilation, "/data/local/tmp", nullptr),
2868 ANEURALNETWORKS_UNEXPECTED_NULL);
2869 }
2870
2871 // Also see TEST_F(ValidationTestCompilation, CreateExecution)
TEST_F(ValidationTestCompilationForDevices_1,CreateExecution)2872 TEST_F(ValidationTestCompilationForDevices_1, CreateExecution) {
2873 ANeuralNetworksExecution* execution = nullptr;
2874 EXPECT_EQ(ANeuralNetworksExecution_create(nullptr, &execution),
2875 ANEURALNETWORKS_UNEXPECTED_NULL);
2876 if (!mCompilation) {
2877 return;
2878 }
2879 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, nullptr),
2880 ANEURALNETWORKS_UNEXPECTED_NULL);
2881 EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_BAD_STATE);
2882 }
2883
2884 // Also see TEST_F(ValidationTestCompilation, Finish)
TEST_F(ValidationTestCompilationForDevices_1,Finish)2885 TEST_F(ValidationTestCompilationForDevices_1, Finish) {
2886 EXPECT_EQ(ANeuralNetworksCompilation_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
2887 if (!mCompilation) {
2888 return;
2889 }
2890 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
2891 EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation,
2892 ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER),
2893 ANEURALNETWORKS_BAD_STATE);
2894 EXPECT_EQ(
2895 ANeuralNetworksCompilation_setPriority(mCompilation, ANEURALNETWORKS_PRIORITY_DEFAULT),
2896 ANEURALNETWORKS_BAD_STATE);
2897 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(mCompilation, kShortWaitInNanoseconds),
2898 ANEURALNETWORKS_BAD_STATE);
2899 std::vector<uint8_t> token(ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN, 0);
2900 EXPECT_EQ(ANeuralNetworksCompilation_setCaching(mCompilation, "/data/local/tmp", token.data()),
2901 ANEURALNETWORKS_BAD_STATE);
2902 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_BAD_STATE);
2903 }
2904
2905 // Also see TEST_F(ValidationTestCompilation, SetTimeout)
2906 // Also see TEST_F(ValidationTestCompilationForDevices_2, SetTimeout)
TEST_F(ValidationTestCompilationForDevices_1,SetTimeout)2907 TEST_F(ValidationTestCompilationForDevices_1, SetTimeout) {
2908 if (!mCompilation) {
2909 return;
2910 }
2911
2912 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(mCompilation, kShortWaitInNanoseconds),
2913 ANEURALNETWORKS_NO_ERROR);
2914
2915 // Attempt to finish
2916 const int n = ANeuralNetworksCompilation_finish(mCompilation);
2917 EXPECT_TRUE(n == ANEURALNETWORKS_NO_ERROR || n == ANEURALNETWORKS_MISSED_DEADLINE_TRANSIENT ||
2918 n == ANEURALNETWORKS_MISSED_DEADLINE_PERSISTENT);
2919 }
2920
TEST_F(ValidationTestCompilationForDevices_1,SetTimeoutMaximum)2921 TEST_F(ValidationTestCompilationForDevices_1, SetTimeoutMaximum) {
2922 if (!mCompilation) {
2923 return;
2924 }
2925
2926 constexpr uint64_t duration = std::numeric_limits<uint64_t>::max();
2927 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(mCompilation, duration),
2928 ANEURALNETWORKS_NO_ERROR);
2929 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
2930 }
2931
2932 class ValidationTestCompilationForDevices_2 : public ValidationTestModel {
2933 protected:
SetUp()2934 virtual void SetUp() override {
2935 ValidationTestModel::SetUp();
2936 createModel();
2937
2938 uint32_t numDevices = 0;
2939 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
2940
2941 if (numDevices > 1) {
2942 EXPECT_EQ(ANeuralNetworks_getDevice(0, &mDevices[0]), ANEURALNETWORKS_NO_ERROR);
2943 EXPECT_EQ(ANeuralNetworks_getDevice(1, &mDevices[1]), ANEURALNETWORKS_NO_ERROR);
2944 bool supported = false;
2945 ASSERT_EQ(mNumOperations, static_cast<uint32_t>(1));
2946 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, mDevices, 2,
2947 &supported),
2948 ANEURALNETWORKS_NO_ERROR);
2949 if (supported) {
2950 ASSERT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, mDevices, 2,
2951 &mCompilation),
2952 ANEURALNETWORKS_NO_ERROR);
2953 }
2954 }
2955 }
2956
TearDown()2957 virtual void TearDown() {
2958 ANeuralNetworksCompilation_free(mCompilation);
2959 ValidationTestModel::TearDown();
2960 }
2961
2962 ANeuralNetworksDevice* mDevices[2] = {nullptr, nullptr};
2963 ANeuralNetworksCompilation* mCompilation = nullptr;
2964 };
2965
2966 // Also see TEST_F(ValidationTestCompilation, SetTimeout)
2967 // Also see TEST_F(ValidationTestCompilationForDevices_1, SetTimeout)
TEST_F(ValidationTestCompilationForDevices_2,SetTimeout)2968 TEST_F(ValidationTestCompilationForDevices_2, SetTimeout) {
2969 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(nullptr, kShortWaitInNanoseconds),
2970 ANEURALNETWORKS_UNEXPECTED_NULL);
2971 if (!mCompilation) {
2972 return;
2973 }
2974 // Timeouts can only be set on Compilations created from CompilationForDevices with one device
2975 // specified.
2976 EXPECT_EQ(ANeuralNetworksCompilation_setTimeout(mCompilation, kShortWaitInNanoseconds),
2977 ANEURALNETWORKS_BAD_DATA);
2978 }
2979
2980 // Also see TEST_F(ValidationTestCompilation, ExecutionSetTimeout)
2981 // Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionSetTimeout)
TEST_F(ValidationTestCompilationForDevices_2,ExecutionSetTimeout)2982 TEST_F(ValidationTestCompilationForDevices_2, ExecutionSetTimeout) {
2983 EXPECT_EQ(ANeuralNetworksExecution_setTimeout(nullptr, kShortWaitInNanoseconds),
2984 ANEURALNETWORKS_UNEXPECTED_NULL);
2985
2986 if (!mCompilation) {
2987 return;
2988 }
2989 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
2990 ANeuralNetworksExecution* execution;
2991 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
2992 // Timeouts can only be set on Compilations created from CompilationForDevices with one device
2993 // specified.
2994 EXPECT_EQ(ANeuralNetworksExecution_setTimeout(execution, kShortWaitInNanoseconds),
2995 ANEURALNETWORKS_BAD_DATA);
2996 ANeuralNetworksExecution_free(execution);
2997 }
2998
2999 // Also see TEST_F(ValidationTestCompilation, ExecutionTiming)
3000 // Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming)
TEST_F(ValidationTestCompilationForDevices_2,ExecutionTiming)3001 TEST_F(ValidationTestCompilationForDevices_2, ExecutionTiming) {
3002 if (!mCompilation) {
3003 return;
3004 }
3005 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3006 ANeuralNetworksExecution* execution;
3007 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
3008 // Cannot setMeasureTiming() if there are two or more devices.
3009 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false),
3010 ANEURALNETWORKS_BAD_DATA);
3011 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), ANEURALNETWORKS_BAD_DATA);
3012
3013 // close memory
3014 ANeuralNetworksExecution_free(execution);
3015 }
3016
3017 class ValidationTestInvalidCompilation : public ValidationTestModel {
3018 protected:
SetUp()3019 virtual void SetUp() override {
3020 ValidationTestModel::SetUp();
3021
3022 // Create a model with an OEM operation
3023 uint32_t dimensions[]{1};
3024 ANeuralNetworksOperandType OEMTensorType{.type = ANEURALNETWORKS_TENSOR_OEM_BYTE,
3025 .dimensionCount = 1,
3026 .dimensions = dimensions};
3027 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMTensorType),
3028 ANEURALNETWORKS_NO_ERROR);
3029 EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMTensorType),
3030 ANEURALNETWORKS_NO_ERROR);
3031 ASSERT_EQ(addOperation(ANEURALNETWORKS_OEM_OPERATION, {0}, {1}), ANEURALNETWORKS_NO_ERROR);
3032 ASSERT_EQ(identifyInputsAndOutputs({0}, {1}), ANEURALNETWORKS_NO_ERROR);
3033 ASSERT_EQ(modelFinish(), ANEURALNETWORKS_NO_ERROR);
3034
3035 // Find a device that cannot handle OEM operation and create compilation on that
3036 uint32_t numDevices = 0;
3037 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
3038 for (uint32_t i = 0; i < numDevices; i++) {
3039 ANeuralNetworksDevice* device;
3040 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
3041 bool supported = false;
3042 EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, &device, 1,
3043 &supported),
3044 ANEURALNETWORKS_NO_ERROR);
3045 if (!supported) {
3046 ASSERT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, &device, 1,
3047 &mInvalidCompilation),
3048 ANEURALNETWORKS_NO_ERROR);
3049 break;
3050 }
3051 }
3052 if (mInvalidCompilation) {
3053 ASSERT_EQ(ANeuralNetworksCompilation_finish(mInvalidCompilation),
3054 ANEURALNETWORKS_BAD_DATA);
3055 }
3056 }
3057
TearDown()3058 virtual void TearDown() {
3059 ANeuralNetworksCompilation_free(mInvalidCompilation);
3060 ValidationTestModel::TearDown();
3061 }
3062
3063 ANeuralNetworksCompilation* mInvalidCompilation = nullptr;
3064 };
3065
TEST_F(ValidationTestInvalidCompilation,GetPreferredMemoryAlignmentAndPadding)3066 TEST_F(ValidationTestInvalidCompilation, GetPreferredMemoryAlignmentAndPadding) {
3067 if (__builtin_available(android __NNAPI_FL5_MIN_ANDROID_API__, *)) {
3068 if (!mInvalidCompilation) {
3069 return;
3070 }
3071 uint32_t result;
3072 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForInput(
3073 mInvalidCompilation, 0, &result),
3074 ANEURALNETWORKS_BAD_STATE);
3075 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForInput(mInvalidCompilation,
3076 0, &result),
3077 ANEURALNETWORKS_BAD_STATE);
3078 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryAlignmentForOutput(
3079 mInvalidCompilation, 0, &result),
3080 ANEURALNETWORKS_BAD_STATE);
3081 EXPECT_EQ(ANeuralNetworksCompilation_getPreferredMemoryPaddingForOutput(mInvalidCompilation,
3082 0, &result),
3083 ANEURALNETWORKS_BAD_STATE);
3084 } else {
3085 GTEST_SKIP();
3086 }
3087 }
3088
TEST_F(ValidationTestInvalidCompilation,CreateExecution)3089 TEST_F(ValidationTestInvalidCompilation, CreateExecution) {
3090 if (!mInvalidCompilation) {
3091 return;
3092 }
3093 ANeuralNetworksExecution* execution = nullptr;
3094 EXPECT_EQ(ANeuralNetworksExecution_create(mInvalidCompilation, &execution),
3095 ANEURALNETWORKS_BAD_STATE);
3096 ANeuralNetworksExecution_free(execution);
3097 }
3098
TEST_F(ValidationTestInvalidCompilation,MemoryDescAddRole)3099 TEST_F(ValidationTestInvalidCompilation, MemoryDescAddRole) {
3100 if (!mInvalidCompilation) {
3101 return;
3102 }
3103 ANeuralNetworksMemoryDesc* desc = nullptr;
3104 ASSERT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3105 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, mInvalidCompilation, 0, 1.0f),
3106 ANEURALNETWORKS_BAD_DATA);
3107 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, mInvalidCompilation, 0, 1.0f),
3108 ANEURALNETWORKS_BAD_DATA);
3109 ANeuralNetworksMemoryDesc_free(desc);
3110 }
3111
3112 // Also see TEST_F(ValidationTestCompilation, ExecutionTiming)
3113 // Also see TEST_F(ValidationTestCompilationForDevices_2, ExecutionTiming)
3114 // Also see TEST_F(ValidationTestCompilation, ExecutionUsability)
TEST_F(ValidationTestCompilationForDevices_1,ExecutionTiming)3115 TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming) {
3116 if (!mCompilation) {
3117 return;
3118 }
3119 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3120
3121 enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST, FENCED };
3122 for (auto executionType :
3123 {ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST, ExecutionType::FENCED}) {
3124 SCOPED_TRACE(static_cast<uint32_t>(executionType));
3125
3126 ANeuralNetworksExecution* execution;
3127 ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
3128 ANEURALNETWORKS_NO_ERROR);
3129
3130 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(nullptr, false),
3131 ANEURALNETWORKS_UNEXPECTED_NULL);
3132 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(nullptr, true),
3133 ANEURALNETWORKS_UNEXPECTED_NULL);
3134 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false),
3135 ANEURALNETWORKS_NO_ERROR);
3136 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true),
3137 ANEURALNETWORKS_NO_ERROR);
3138
3139 float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2];
3140 int in2 = 0;
3141 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)),
3142 ANEURALNETWORKS_NO_ERROR);
3143 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)),
3144 ANEURALNETWORKS_NO_ERROR);
3145 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)),
3146 ANEURALNETWORKS_NO_ERROR);
3147 ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)),
3148 ANEURALNETWORKS_NO_ERROR);
3149
3150 // Cannot getDuration until the execution has finished.
3151 uint64_t duration;
3152 EXPECT_EQ(ANeuralNetworksExecution_getDuration(
3153 execution, ANEURALNETWORKS_DURATION_ON_HARDWARE, &duration),
3154 ANEURALNETWORKS_BAD_STATE);
3155 EXPECT_EQ(ANeuralNetworksExecution_getDuration(
3156 execution, ANEURALNETWORKS_DURATION_IN_DRIVER, &duration),
3157 ANEURALNETWORKS_BAD_STATE);
3158
3159 auto testSetTimeoutTooLate = [execution] {
3160 // Cannot setTimeout if the execution has started.
3161 EXPECT_EQ(ANeuralNetworksExecution_setTimeout(execution, kShortWaitInNanoseconds),
3162 ANEURALNETWORKS_BAD_STATE);
3163 };
3164
3165 auto testMeasureTooLate = [execution] {
3166 // Cannot setMeasureTiming if the execution has started.
3167 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false),
3168 ANEURALNETWORKS_BAD_STATE);
3169 EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true),
3170 ANEURALNETWORKS_BAD_STATE);
3171 };
3172
3173 // Compute.
3174 switch (executionType) {
3175 case ExecutionType::ASYNC: {
3176 ANeuralNetworksEvent* event;
3177 ASSERT_EQ(ANeuralNetworksExecution_startCompute(execution, &event),
3178 ANEURALNETWORKS_NO_ERROR);
3179 testMeasureTooLate();
3180 ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR);
3181 testSetTimeoutTooLate();
3182 testMeasureTooLate();
3183 ANeuralNetworksEvent_free(event);
3184 break;
3185 }
3186 case ExecutionType::SYNC: {
3187 ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_NO_ERROR);
3188 testSetTimeoutTooLate();
3189 testMeasureTooLate();
3190 break;
3191 }
3192 case ExecutionType::BURST: {
3193 ANeuralNetworksBurst* burst;
3194 ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst),
3195 ANEURALNETWORKS_NO_ERROR);
3196 ASSERT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst),
3197 ANEURALNETWORKS_NO_ERROR);
3198 testSetTimeoutTooLate();
3199 testMeasureTooLate();
3200 ANeuralNetworksBurst_free(burst);
3201 break;
3202 }
3203 case ExecutionType::FENCED: {
3204 ANeuralNetworksEvent* event = nullptr;
3205 ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution, nullptr,
3206 0, 0, &event),
3207 ANEURALNETWORKS_NO_ERROR);
3208 testMeasureTooLate();
3209 ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR);
3210 testSetTimeoutTooLate();
3211 testMeasureTooLate();
3212 ANeuralNetworksEvent_free(event);
3213 break;
3214 }
3215 default:
3216 FAIL() << "Unreachable";
3217 }
3218
3219 auto testDuration = [](ANeuralNetworksExecution* e, int32_t durationCode,
3220 bool nullDuration) {
3221 SCOPED_TRACE(e);
3222 SCOPED_TRACE(durationCode);
3223 SCOPED_TRACE(nullDuration);
3224
3225 // Strictly speaking, a duration COULD have this value, but it is
3226 // exceedingly unlikely. We'll use it as an initial value that we expect
3227 // to be modified by getDuration().
3228 const uint64_t kBogusDuration = UINT64_MAX - 1;
3229
3230 uint64_t duration = kBogusDuration;
3231 uint64_t* durationPtr = nullDuration ? nullptr : &duration;
3232
3233 int expectedResultCode = ANEURALNETWORKS_NO_ERROR;
3234 if (e == nullptr | durationPtr == nullptr) {
3235 expectedResultCode = ANEURALNETWORKS_UNEXPECTED_NULL;
3236 } else if (durationCode < 0 ||
3237 durationCode > ANEURALNETWORKS_FENCED_DURATION_IN_DRIVER) {
3238 expectedResultCode = ANEURALNETWORKS_BAD_DATA;
3239 }
3240
3241 EXPECT_EQ(ANeuralNetworksExecution_getDuration(e, durationCode, durationPtr),
3242 expectedResultCode);
3243 if (expectedResultCode == ANEURALNETWORKS_NO_ERROR) {
3244 EXPECT_NE(duration, kBogusDuration);
3245 }
3246 };
3247
3248 std::vector<ANeuralNetworksExecution*> executions = {nullptr, execution};
3249 std::vector<int32_t> durationCodes = {-1,
3250 ANEURALNETWORKS_DURATION_ON_HARDWARE,
3251 ANEURALNETWORKS_DURATION_IN_DRIVER,
3252 ANEURALNETWORKS_FENCED_DURATION_ON_HARDWARE,
3253 ANEURALNETWORKS_FENCED_DURATION_IN_DRIVER,
3254 ANEURALNETWORKS_FENCED_DURATION_IN_DRIVER + 1};
3255 std::vector<bool> nullDurations = {false, true};
3256 for (auto e : executions) {
3257 for (auto d : durationCodes) {
3258 for (auto n : nullDurations) {
3259 testDuration(e, d, n);
3260 }
3261 }
3262 }
3263
3264 // close memory
3265 ANeuralNetworksExecution_free(execution);
3266 }
3267 }
3268
3269 enum class TimeoutDurationType { SHORT, MAXIMUM };
createTimeoutDuration(TimeoutDurationType type)3270 uint64_t createTimeoutDuration(TimeoutDurationType type) {
3271 switch (type) {
3272 case TimeoutDurationType::SHORT:
3273 return kShortWaitInNanoseconds;
3274 case TimeoutDurationType::MAXIMUM:
3275 return std::numeric_limits<uint64_t>::max();
3276 }
3277 LOG(FATAL) << "Invalid TimeoutDurationType: " << static_cast<int>(type);
3278 return 0;
3279 }
3280
runExecutionSetTimeoutTest(ANeuralNetworksCompilation * compilation,TimeoutDurationType timeoutDurationType)3281 void runExecutionSetTimeoutTest(ANeuralNetworksCompilation* compilation,
3282 TimeoutDurationType timeoutDurationType) {
3283 if (!compilation) {
3284 return;
3285 }
3286 ASSERT_EQ(ANeuralNetworksCompilation_finish(compilation), ANEURALNETWORKS_NO_ERROR);
3287
3288 enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST, FENCED };
3289 for (auto executionType :
3290 {ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST, ExecutionType::FENCED}) {
3291 SCOPED_TRACE(static_cast<uint32_t>(executionType));
3292
3293 ANeuralNetworksExecution* execution;
3294 ASSERT_EQ(ANeuralNetworksExecution_create(compilation, &execution),
3295 ANEURALNETWORKS_NO_ERROR);
3296 const auto scoped = android::base::make_scope_guard(
3297 [execution] { ANeuralNetworksExecution_free(execution); });
3298
3299 float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2];
3300 int in2 = 0;
3301 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)),
3302 ANEURALNETWORKS_NO_ERROR);
3303 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)),
3304 ANEURALNETWORKS_NO_ERROR);
3305 ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)),
3306 ANEURALNETWORKS_NO_ERROR);
3307 ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)),
3308 ANEURALNETWORKS_NO_ERROR);
3309
3310 const uint64_t timeoutDuration = createTimeoutDuration(timeoutDurationType);
3311 EXPECT_EQ(ANeuralNetworksExecution_setTimeout(execution, timeoutDuration),
3312 ANEURALNETWORKS_NO_ERROR);
3313
3314 const auto checkResult = [timeoutDurationType](int n) {
3315 switch (timeoutDurationType) {
3316 case TimeoutDurationType::SHORT:
3317 EXPECT_TRUE(n == ANEURALNETWORKS_NO_ERROR ||
3318 n == ANEURALNETWORKS_MISSED_DEADLINE_TRANSIENT ||
3319 n == ANEURALNETWORKS_MISSED_DEADLINE_PERSISTENT);
3320 return;
3321 case TimeoutDurationType::MAXIMUM:
3322 EXPECT_EQ(n, ANEURALNETWORKS_NO_ERROR);
3323 return;
3324 }
3325 LOG(FATAL) << "Invalid TimeoutDurationType: " << static_cast<int>(timeoutDurationType);
3326 };
3327
3328 // Compute.
3329 switch (executionType) {
3330 case ExecutionType::ASYNC: {
3331 ANeuralNetworksEvent* event = nullptr;
3332 EXPECT_EQ(ANeuralNetworksExecution_startCompute(execution, &event),
3333 ANEURALNETWORKS_NO_ERROR);
3334 checkResult(ANeuralNetworksEvent_wait(event));
3335 ANeuralNetworksEvent_free(event);
3336 break;
3337 }
3338 case ExecutionType::SYNC: {
3339 checkResult(ANeuralNetworksExecution_compute(execution));
3340 break;
3341 }
3342 case ExecutionType::BURST: {
3343 ANeuralNetworksBurst* burst;
3344 ASSERT_EQ(ANeuralNetworksBurst_create(compilation, &burst),
3345 ANEURALNETWORKS_NO_ERROR);
3346 checkResult(ANeuralNetworksExecution_burstCompute(execution, burst));
3347 ANeuralNetworksBurst_free(burst);
3348 break;
3349 }
3350 case ExecutionType::FENCED: {
3351 ANeuralNetworksEvent* event = nullptr;
3352 EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution, nullptr,
3353 0, 0, &event),
3354 ANEURALNETWORKS_NO_ERROR);
3355 checkResult(ANeuralNetworksEvent_wait(event));
3356 ANeuralNetworksEvent_free(event);
3357 break;
3358 }
3359 default:
3360 FAIL() << "Unreachable";
3361 }
3362 }
3363 }
3364
3365 // Also see TEST_F(ValidationTestCompilation, ExecutionSetTimeout)
3366 // Also see TEST_F(ValidationTestCompilationForDevices_2, ExecutionSetTimeout)
TEST_F(ValidationTestCompilationForDevices_1,ExecutionSetTimeout)3367 TEST_F(ValidationTestCompilationForDevices_1, ExecutionSetTimeout) {
3368 runExecutionSetTimeoutTest(mCompilation, TimeoutDurationType::SHORT);
3369 }
3370
TEST_F(ValidationTestCompilationForDevices_1,ExecutionSetTimeoutMaximum)3371 TEST_F(ValidationTestCompilationForDevices_1, ExecutionSetTimeoutMaximum) {
3372 runExecutionSetTimeoutTest(mCompilation, TimeoutDurationType::MAXIMUM);
3373 }
3374
TEST_F(ValidationTest,CreateMemoryDesc)3375 TEST_F(ValidationTest, CreateMemoryDesc) {
3376 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
3377 }
3378
TEST_F(ValidationTestMemoryDesc,AddInputRole)3379 TEST_F(ValidationTestMemoryDesc, AddInputRole) {
3380 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(nullptr, mCompilation, 0, 1.0f),
3381 ANEURALNETWORKS_UNEXPECTED_NULL);
3382 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, nullptr, 0, 1.0f),
3383 ANEURALNETWORKS_UNEXPECTED_NULL);
3384
3385 // Unfinished compilation.
3386 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 1.0f),
3387 ANEURALNETWORKS_BAD_DATA);
3388
3389 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3390
3391 // Index out of range.
3392 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 999, 1.0f),
3393 ANEURALNETWORKS_BAD_DATA);
3394
3395 // Invalid frequency.
3396 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 10.0f),
3397 ANEURALNETWORKS_BAD_DATA);
3398 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 0.0f),
3399 ANEURALNETWORKS_BAD_DATA);
3400 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, -1.0f),
3401 ANEURALNETWORKS_BAD_DATA);
3402
3403 // Specify the same operand twice.
3404 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 1.0f),
3405 ANEURALNETWORKS_NO_ERROR);
3406 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 1.0f),
3407 ANEURALNETWORKS_BAD_DATA);
3408
3409 // Attempting to modify a finished descriptor.
3410 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(mDesc), ANEURALNETWORKS_NO_ERROR);
3411 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 1.0f),
3412 ANEURALNETWORKS_BAD_STATE);
3413 }
3414
TEST_F(ValidationTestMemoryDesc,AddOutputRole)3415 TEST_F(ValidationTestMemoryDesc, AddOutputRole) {
3416 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(nullptr, mCompilation, 0, 1.0f),
3417 ANEURALNETWORKS_UNEXPECTED_NULL);
3418 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, nullptr, 0, 1.0f),
3419 ANEURALNETWORKS_UNEXPECTED_NULL);
3420
3421 // Unfinished compilation.
3422 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, 1.0f),
3423 ANEURALNETWORKS_BAD_DATA);
3424
3425 ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3426
3427 // Index out of range.
3428 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 999, 1.0f),
3429 ANEURALNETWORKS_BAD_DATA);
3430
3431 // Invalid frequency.
3432 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, 10.0f),
3433 ANEURALNETWORKS_BAD_DATA);
3434 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, 0.0f),
3435 ANEURALNETWORKS_BAD_DATA);
3436 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, -1.0f),
3437 ANEURALNETWORKS_BAD_DATA);
3438
3439 // Specify the same operand twice.
3440 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, 1.0f),
3441 ANEURALNETWORKS_NO_ERROR);
3442 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, 1.0f),
3443 ANEURALNETWORKS_BAD_DATA);
3444
3445 // Attempting to modify a finished descriptor.
3446 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(mDesc), ANEURALNETWORKS_NO_ERROR);
3447 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(mDesc, mCompilation, 0, 1.0f),
3448 ANEURALNETWORKS_BAD_STATE);
3449 }
3450
3451 // Creates and compiles a single-operation ADD model with the given operand type.
3452 // The caller is responsible to free the returned model and compilation.
3453 static std::pair<ANeuralNetworksModel*, ANeuralNetworksCompilation*>
createAndCompileAddModelWithType(const ANeuralNetworksOperandType & type)3454 createAndCompileAddModelWithType(const ANeuralNetworksOperandType& type) {
3455 // OperandType for activation scalar.
3456 const ANeuralNetworksOperandType actType = {
3457 .type = ANEURALNETWORKS_INT32, .dimensionCount = 0, .dimensions = nullptr};
3458
3459 ANeuralNetworksModel* model;
3460 EXPECT_EQ(ANeuralNetworksModel_create(&model), ANEURALNETWORKS_NO_ERROR);
3461 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &type), ANEURALNETWORKS_NO_ERROR);
3462 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &type), ANEURALNETWORKS_NO_ERROR);
3463 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &actType), ANEURALNETWORKS_NO_ERROR);
3464 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &type), ANEURALNETWORKS_NO_ERROR);
3465
3466 const uint32_t inList[] = {0, 1, 2};
3467 const uint32_t outList[] = {3};
3468 EXPECT_EQ(ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_ADD, 3, inList, 1, outList),
3469 ANEURALNETWORKS_NO_ERROR);
3470 EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(model, 3, inList, 1, outList),
3471 ANEURALNETWORKS_NO_ERROR);
3472 EXPECT_EQ(ANeuralNetworksModel_finish(model), ANEURALNETWORKS_NO_ERROR);
3473
3474 ANeuralNetworksCompilation* compilation;
3475 EXPECT_EQ(ANeuralNetworksCompilation_create(model, &compilation), ANEURALNETWORKS_NO_ERROR);
3476 EXPECT_EQ(ANeuralNetworksCompilation_finish(compilation), ANEURALNETWORKS_NO_ERROR);
3477 return {model, compilation};
3478 }
3479
testIncompatibleOperands(const ANeuralNetworksCompilation * compilation,const ANeuralNetworksOperandType & badType)3480 static void testIncompatibleOperands(const ANeuralNetworksCompilation* compilation,
3481 const ANeuralNetworksOperandType& badType) {
3482 const auto [badModel, badCompilation] = createAndCompileAddModelWithType(badType);
3483 {
3484 ANeuralNetworksMemoryDesc* desc = nullptr;
3485 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3486 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, compilation, 0, 1.0f),
3487 ANEURALNETWORKS_NO_ERROR);
3488 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, badCompilation, 0, 1.0f),
3489 ANEURALNETWORKS_BAD_DATA);
3490 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, badCompilation, 0, 1.0f),
3491 ANEURALNETWORKS_BAD_DATA);
3492 ANeuralNetworksMemoryDesc_free(desc);
3493 }
3494 {
3495 ANeuralNetworksMemoryDesc* desc = nullptr;
3496 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3497 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, compilation, 0, 1.0f),
3498 ANEURALNETWORKS_NO_ERROR);
3499 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, badCompilation, 0, 1.0f),
3500 ANEURALNETWORKS_BAD_DATA);
3501 EXPECT_EQ(ANeuralNetworksMemoryDesc_addOutputRole(desc, badCompilation, 0, 1.0f),
3502 ANEURALNETWORKS_BAD_DATA);
3503 ANeuralNetworksMemoryDesc_free(desc);
3504 }
3505 ANeuralNetworksCompilation_free(badCompilation);
3506 ANeuralNetworksModel_free(badModel);
3507 }
3508
TEST_F(ValidationTestMemoryDesc,OperandMetadata)3509 TEST_F(ValidationTestMemoryDesc, OperandMetadata) {
3510 const uint32_t dimensions[] = {2};
3511 const uint32_t rank = std::size(dimensions);
3512 const ANeuralNetworksOperandType floatBase = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
3513 .dimensionCount = rank,
3514 .dimensions = dimensions,
3515 .scale = 0.0f,
3516 .zeroPoint = 0};
3517 const ANeuralNetworksOperandType quantBase = {.type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
3518 .dimensionCount = rank,
3519 .dimensions = dimensions,
3520 .scale = 1.0f,
3521 .zeroPoint = 0};
3522 const auto [floatModel, floatCompilation] = createAndCompileAddModelWithType(floatBase);
3523 const auto [quantModel, quantCompilation] = createAndCompileAddModelWithType(quantBase);
3524
3525 // Different data type.
3526 {
3527 SCOPED_TRACE("Data type");
3528 ANeuralNetworksOperandType wrongType = floatBase;
3529 wrongType.type = ANEURALNETWORKS_TENSOR_FLOAT16;
3530 testIncompatibleOperands(floatCompilation, wrongType);
3531 }
3532
3533 // Different scale.
3534 {
3535 SCOPED_TRACE("Scale");
3536 ANeuralNetworksOperandType wrongScale = quantBase;
3537 wrongScale.scale = 0.5f;
3538 testIncompatibleOperands(quantCompilation, wrongScale);
3539 }
3540
3541 // Different zero point.
3542 {
3543 SCOPED_TRACE("Zero point");
3544 ANeuralNetworksOperandType wrongZeroPoint = quantBase;
3545 wrongZeroPoint.zeroPoint = 128;
3546 testIncompatibleOperands(quantCompilation, wrongZeroPoint);
3547 }
3548
3549 // Different rank.
3550 {
3551 SCOPED_TRACE("Rank");
3552 const uint32_t badDimensions[] = {2, 1};
3553 const uint32_t badRank = std::size(badDimensions);
3554 ANeuralNetworksOperandType wrongRank = quantBase;
3555 wrongRank.dimensionCount = badRank;
3556 wrongRank.dimensions = badDimensions;
3557 testIncompatibleOperands(quantCompilation, wrongRank);
3558 }
3559
3560 // Different dimensions.
3561 {
3562 SCOPED_TRACE("Dimensions");
3563 const uint32_t badDimensions[] = {1};
3564 ANeuralNetworksOperandType wrongDims = quantBase;
3565 wrongDims.dimensions = badDimensions;
3566 testIncompatibleOperands(quantCompilation, wrongDims);
3567 }
3568
3569 ANeuralNetworksCompilation_free(floatCompilation);
3570 ANeuralNetworksCompilation_free(quantCompilation);
3571 ANeuralNetworksModel_free(floatModel);
3572 ANeuralNetworksModel_free(quantModel);
3573 }
3574
3575 // Creates and compiles a single-operation CONV_2D model with channel quant data type of the given
3576 // scales. The caller is responsible to free the returned model and compilation.
3577 static std::pair<ANeuralNetworksModel*, ANeuralNetworksCompilation*>
createAndCompileChannelQuantConvModel(const std::vector<float> & scales)3578 createAndCompileChannelQuantConvModel(const std::vector<float>& scales) {
3579 const uint32_t numChannels = scales.size();
3580
3581 // OperandType for input and output.
3582 const uint32_t inoutDimensions[] = {1, 16, 16, numChannels};
3583 const ANeuralNetworksOperandType inoutType = {
3584 .type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
3585 .dimensionCount = std::size(inoutDimensions),
3586 .dimensions = inoutDimensions,
3587 .scale = 1.0f,
3588 .zeroPoint = 0,
3589 };
3590
3591 // OperandType for filter.
3592 const uint32_t filterDimensions[] = {numChannels, 3, 3, numChannels};
3593 const ANeuralNetworksOperandType filterType = {
3594 .type = ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL,
3595 .dimensionCount = std::size(filterDimensions),
3596 .dimensions = filterDimensions,
3597 .scale = 0.0f,
3598 .zeroPoint = 0,
3599 };
3600
3601 // OperandType for bias.
3602 const uint32_t biasDimensions[] = {numChannels};
3603 const ANeuralNetworksOperandType biasType = {
3604 .type = ANEURALNETWORKS_TENSOR_INT32,
3605 .dimensionCount = std::size(biasDimensions),
3606 .dimensions = biasDimensions,
3607 .scale = 0.0f,
3608 .zeroPoint = 0,
3609 };
3610
3611 // OperandType for scalars: implicit padding code, strides, activation.
3612 const ANeuralNetworksOperandType scalarType = {
3613 .type = ANEURALNETWORKS_INT32, .dimensionCount = 0, .dimensions = nullptr};
3614
3615 ANeuralNetworksModel* model;
3616 EXPECT_EQ(ANeuralNetworksModel_create(&model), ANEURALNETWORKS_NO_ERROR);
3617 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &inoutType), ANEURALNETWORKS_NO_ERROR);
3618 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &filterType), ANEURALNETWORKS_NO_ERROR);
3619 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &biasType), ANEURALNETWORKS_NO_ERROR);
3620 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &scalarType), ANEURALNETWORKS_NO_ERROR);
3621 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &scalarType), ANEURALNETWORKS_NO_ERROR);
3622 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &scalarType), ANEURALNETWORKS_NO_ERROR);
3623 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &scalarType), ANEURALNETWORKS_NO_ERROR);
3624 EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &inoutType), ANEURALNETWORKS_NO_ERROR);
3625
3626 // Set channel quant parameters for the filter tensor.
3627 const ANeuralNetworksSymmPerChannelQuantParams channelQuant = {
3628 .channelDim = 0,
3629 .scaleCount = numChannels,
3630 .scales = scales.data(),
3631 };
3632 EXPECT_EQ(ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(model, 1, &channelQuant),
3633 ANEURALNETWORKS_NO_ERROR);
3634
3635 const uint32_t inList[] = {0, 1, 2, 3, 4, 5, 6};
3636 const uint32_t outList[] = {7};
3637 EXPECT_EQ(ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_CONV_2D, std::size(inList),
3638 inList, std::size(outList), outList),
3639 ANEURALNETWORKS_NO_ERROR);
3640 EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(model, std::size(inList), inList,
3641 std::size(outList), outList),
3642 ANEURALNETWORKS_NO_ERROR);
3643 EXPECT_EQ(ANeuralNetworksModel_finish(model), ANEURALNETWORKS_NO_ERROR);
3644
3645 ANeuralNetworksCompilation* compilation;
3646 EXPECT_EQ(ANeuralNetworksCompilation_create(model, &compilation), ANEURALNETWORKS_NO_ERROR);
3647 EXPECT_EQ(ANeuralNetworksCompilation_finish(compilation), ANEURALNETWORKS_NO_ERROR);
3648 return {model, compilation};
3649 }
3650
TEST_F(ValidationTestMemoryDesc,ExtraParams)3651 TEST_F(ValidationTestMemoryDesc, ExtraParams) {
3652 // Create two compilations with conflict channel quant scales.
3653 const auto [model1, compilation1] = createAndCompileChannelQuantConvModel({1.0f, 1.0f});
3654 const auto [model2, compilation2] = createAndCompileChannelQuantConvModel({0.5f, 0.5f});
3655
3656 ANeuralNetworksMemoryDesc* desc = nullptr;
3657 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3658 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, compilation1, 1, 1.0f),
3659 ANEURALNETWORKS_NO_ERROR);
3660 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, compilation2, 1, 1.0f),
3661 ANEURALNETWORKS_BAD_DATA);
3662 ANeuralNetworksMemoryDesc_free(desc);
3663
3664 ANeuralNetworksCompilation_free(compilation1);
3665 ANeuralNetworksCompilation_free(compilation2);
3666 ANeuralNetworksModel_free(model1);
3667 ANeuralNetworksModel_free(model2);
3668 }
3669
TEST_F(ValidationTestMemoryDesc,SetDimensions)3670 TEST_F(ValidationTestMemoryDesc, SetDimensions) {
3671 const uint32_t dimensions[] = {2};
3672 const uint32_t badDimensions[] = {3};
3673 const uint32_t rank = std::size(dimensions);
3674 const uint32_t badRankDimensions[] = {2, 1};
3675 const uint32_t badRank = std::size(badRankDimensions);
3676
3677 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(nullptr, rank, dimensions),
3678 ANEURALNETWORKS_UNEXPECTED_NULL);
3679 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, rank, nullptr),
3680 ANEURALNETWORKS_UNEXPECTED_NULL);
3681
3682 // Incompatible dimensions.
3683 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, rank, dimensions),
3684 ANEURALNETWORKS_NO_ERROR);
3685 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, rank, badDimensions),
3686 ANEURALNETWORKS_BAD_DATA);
3687 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, badRank, badRankDimensions),
3688 ANEURALNETWORKS_BAD_DATA);
3689
3690 // Attempting to modify a finished descriptor.
3691 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3692 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 1.0f),
3693 ANEURALNETWORKS_NO_ERROR);
3694 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(mDesc), ANEURALNETWORKS_NO_ERROR);
3695 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, rank, dimensions),
3696 ANEURALNETWORKS_BAD_STATE);
3697 }
3698
TEST_F(ValidationTestMemoryDesc,SetScalarDimensionsBeforeAddRole)3699 TEST_F(ValidationTestMemoryDesc, SetScalarDimensionsBeforeAddRole) {
3700 const uint32_t badDimensions[] = {2};
3701 const uint32_t badRank = std::size(badDimensions);
3702
3703 // Set non-zero rank.
3704 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, badRank, badDimensions),
3705 ANEURALNETWORKS_NO_ERROR);
3706
3707 // This should fail because input2 is a scalar.
3708 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3709 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 2, 1.0f),
3710 ANEURALNETWORKS_BAD_DATA);
3711 }
3712
TEST_F(ValidationTestMemoryDesc,SetScalarDimensionsAfterAddRole)3713 TEST_F(ValidationTestMemoryDesc, SetScalarDimensionsAfterAddRole) {
3714 const uint32_t badDimensions[] = {2};
3715 const uint32_t badRank = std::size(badDimensions);
3716
3717 // Input2 is a scalar.
3718 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3719 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 2, 1.0f),
3720 ANEURALNETWORKS_NO_ERROR);
3721
3722 // This should fail because the rank is not zero.
3723 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, 0, nullptr), ANEURALNETWORKS_NO_ERROR);
3724 EXPECT_EQ(ANeuralNetworksMemoryDesc_setDimensions(mDesc, badRank, badDimensions),
3725 ANEURALNETWORKS_BAD_DATA);
3726 }
3727
TEST_F(ValidationTestMemoryDesc,Finish)3728 TEST_F(ValidationTestMemoryDesc, Finish) {
3729 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
3730
3731 // No usage is specified.
3732 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(mDesc), ANEURALNETWORKS_BAD_DATA);
3733
3734 // Finish an already finished descriptor.
3735 EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
3736 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(mDesc, mCompilation, 0, 1.0f),
3737 ANEURALNETWORKS_NO_ERROR);
3738 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(mDesc), ANEURALNETWORKS_NO_ERROR);
3739 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(mDesc), ANEURALNETWORKS_BAD_STATE);
3740 }
3741
TEST_F(ValidationTestMemoryDesc,CreateMemory)3742 TEST_F(ValidationTestMemoryDesc, CreateMemory) {
3743 ANeuralNetworksMemory* memory = nullptr;
3744 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(nullptr, &memory),
3745 ANEURALNETWORKS_UNEXPECTED_NULL);
3746 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(mDesc, nullptr),
3747 ANEURALNETWORKS_UNEXPECTED_NULL);
3748
3749 // Unfinished descriptor.
3750 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(mDesc, &memory), ANEURALNETWORKS_BAD_STATE);
3751
3752 ANeuralNetworksMemory_free(memory);
3753 }
3754
TEST_F(ValidationTestMemoryDesc,MemoryCopying)3755 TEST_F(ValidationTestMemoryDesc, MemoryCopying) {
3756 uint32_t goodSize = sizeof(float) * 2, badSize1 = sizeof(float), badSize2 = sizeof(float) * 4;
3757 ANeuralNetworksMemory* goodAshmem = createAshmem(goodSize);
3758 ANeuralNetworksMemory* badAshmem1 = createAshmem(badSize1);
3759 ANeuralNetworksMemory* badAshmem2 = createAshmem(badSize2);
3760
3761 const uint32_t goodDimensions[] = {1, 2};
3762 const uint32_t badDimensions1[] = {2};
3763 const uint32_t badDimensions2[] = {2, 1};
3764 const ANeuralNetworksOperandType goodType = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
3765 .dimensionCount = std::size(goodDimensions),
3766 .dimensions = goodDimensions,
3767 .scale = 0.0f,
3768 .zeroPoint = 0};
3769 const ANeuralNetworksOperandType badType1 = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
3770 .dimensionCount = std::size(badDimensions1),
3771 .dimensions = badDimensions1,
3772 .scale = 0.0f,
3773 .zeroPoint = 0};
3774 const ANeuralNetworksOperandType badType2 = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
3775 .dimensionCount = std::size(badDimensions2),
3776 .dimensions = badDimensions2,
3777 .scale = 0.0f,
3778 .zeroPoint = 0};
3779 const auto [goodModel, goodCompilation] = createAndCompileAddModelWithType(goodType);
3780 const auto [badModel1, badCompilation1] = createAndCompileAddModelWithType(badType1);
3781 const auto [badModel2, badCompilation2] = createAndCompileAddModelWithType(badType2);
3782
3783 ANeuralNetworksMemoryDesc* desc = nullptr;
3784 ANeuralNetworksMemory *goodDeviceMemory1 = nullptr, *goodDeviceMemory2 = nullptr;
3785 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3786 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, goodCompilation, 0, 1.0f),
3787 ANEURALNETWORKS_NO_ERROR);
3788 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
3789 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &goodDeviceMemory1),
3790 ANEURALNETWORKS_NO_ERROR);
3791 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &goodDeviceMemory2),
3792 ANEURALNETWORKS_NO_ERROR);
3793 ANeuralNetworksMemoryDesc_free(desc);
3794
3795 ANeuralNetworksMemory* badDeviceMemory1 = nullptr;
3796 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3797 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, badCompilation1, 0, 1.0f),
3798 ANEURALNETWORKS_NO_ERROR);
3799 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
3800 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &badDeviceMemory1),
3801 ANEURALNETWORKS_NO_ERROR);
3802 ANeuralNetworksMemoryDesc_free(desc);
3803
3804 ANeuralNetworksMemory* badDeviceMemory2 = nullptr;
3805 EXPECT_EQ(ANeuralNetworksMemoryDesc_create(&desc), ANEURALNETWORKS_NO_ERROR);
3806 EXPECT_EQ(ANeuralNetworksMemoryDesc_addInputRole(desc, badCompilation2, 0, 1.0f),
3807 ANEURALNETWORKS_NO_ERROR);
3808 EXPECT_EQ(ANeuralNetworksMemoryDesc_finish(desc), ANEURALNETWORKS_NO_ERROR);
3809 EXPECT_EQ(ANeuralNetworksMemory_createFromDesc(desc, &badDeviceMemory2),
3810 ANEURALNETWORKS_NO_ERROR);
3811 ANeuralNetworksMemoryDesc_free(desc);
3812
3813 EXPECT_EQ(ANeuralNetworksMemory_copy(nullptr, goodDeviceMemory1),
3814 ANEURALNETWORKS_UNEXPECTED_NULL);
3815 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory1, nullptr),
3816 ANEURALNETWORKS_UNEXPECTED_NULL);
3817
3818 // Ashmem -> Ashmem
3819 // Bad memory size.
3820 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, badAshmem1), ANEURALNETWORKS_BAD_DATA);
3821 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, badAshmem2), ANEURALNETWORKS_BAD_DATA);
3822 EXPECT_EQ(ANeuralNetworksMemory_copy(badAshmem1, goodAshmem), ANEURALNETWORKS_BAD_DATA);
3823 EXPECT_EQ(ANeuralNetworksMemory_copy(badAshmem2, goodAshmem), ANEURALNETWORKS_BAD_DATA);
3824
3825 // Ashmem -> Device Memory
3826 // Bad memory size.
3827 EXPECT_EQ(ANeuralNetworksMemory_copy(badAshmem1, goodDeviceMemory1), ANEURALNETWORKS_BAD_DATA);
3828 EXPECT_EQ(ANeuralNetworksMemory_copy(badAshmem2, goodDeviceMemory1), ANEURALNETWORKS_BAD_DATA);
3829
3830 // Device Memory -> Ashmem
3831 // Uninitialized source device memory.
3832 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory1, goodAshmem), ANEURALNETWORKS_BAD_DATA);
3833 // Bad memory size.
3834 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, goodDeviceMemory1), ANEURALNETWORKS_NO_ERROR);
3835 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory1, badAshmem1), ANEURALNETWORKS_BAD_DATA);
3836 // Uninitialized source device memory (after a failed copy).
3837 EXPECT_EQ(ANeuralNetworksMemory_copy(badAshmem1, goodDeviceMemory1), ANEURALNETWORKS_BAD_DATA);
3838 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory1, goodAshmem), ANEURALNETWORKS_BAD_DATA);
3839 // Bad memory size.
3840 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, goodDeviceMemory1), ANEURALNETWORKS_NO_ERROR);
3841 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory1, badAshmem2), ANEURALNETWORKS_BAD_DATA);
3842
3843 // Device Memory -> Device Memory
3844 // Uninitialized source device memory.
3845 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory2, goodDeviceMemory1),
3846 ANEURALNETWORKS_BAD_DATA);
3847 // Incompatible rank.
3848 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, badDeviceMemory1), ANEURALNETWORKS_NO_ERROR);
3849 EXPECT_EQ(ANeuralNetworksMemory_copy(badDeviceMemory1, goodDeviceMemory1),
3850 ANEURALNETWORKS_BAD_DATA);
3851 // Incompatible dimensions.
3852 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, badDeviceMemory2), ANEURALNETWORKS_NO_ERROR);
3853 EXPECT_EQ(ANeuralNetworksMemory_copy(badDeviceMemory2, goodDeviceMemory1),
3854 ANEURALNETWORKS_BAD_DATA);
3855 // Deinitialized source device memory.
3856 EXPECT_EQ(ANeuralNetworksMemory_copy(goodAshmem, goodDeviceMemory2), ANEURALNETWORKS_NO_ERROR);
3857 EXPECT_EQ(ANeuralNetworksMemory_copy(badAshmem1, goodDeviceMemory2), ANEURALNETWORKS_BAD_DATA);
3858 EXPECT_EQ(ANeuralNetworksMemory_copy(goodDeviceMemory2, goodDeviceMemory1),
3859 ANEURALNETWORKS_BAD_DATA);
3860
3861 ANeuralNetworksMemory_free(goodDeviceMemory1);
3862 ANeuralNetworksMemory_free(goodDeviceMemory2);
3863 ANeuralNetworksMemory_free(badDeviceMemory1);
3864 ANeuralNetworksMemory_free(badDeviceMemory2);
3865 ANeuralNetworksCompilation_free(goodCompilation);
3866 ANeuralNetworksCompilation_free(badCompilation1);
3867 ANeuralNetworksCompilation_free(badCompilation2);
3868 ANeuralNetworksModel_free(goodModel);
3869 ANeuralNetworksModel_free(badModel1);
3870 ANeuralNetworksModel_free(badModel2);
3871 }
3872
3873 #ifndef NNTEST_ONLY_PUBLIC_API
TEST(ValidationTestDevice,GetExtensionSupport)3874 TEST(ValidationTestDevice, GetExtensionSupport) {
3875 bool result;
3876 EXPECT_EQ(ANeuralNetworksDevice_getExtensionSupport(nullptr, kTestExtensionName, &result),
3877 ANEURALNETWORKS_UNEXPECTED_NULL);
3878
3879 uint32_t numDevices = 0;
3880 EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
3881
3882 for (uint32_t i = 0; i < numDevices; i++) {
3883 SCOPED_TRACE(i);
3884 ANeuralNetworksDevice* device;
3885 EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
3886 EXPECT_EQ(ANeuralNetworksDevice_getExtensionSupport(device, kTestExtensionName, nullptr),
3887 ANEURALNETWORKS_UNEXPECTED_NULL);
3888 EXPECT_EQ(ANeuralNetworksDevice_getExtensionSupport(device, nullptr, &result),
3889 ANEURALNETWORKS_UNEXPECTED_NULL);
3890 EXPECT_EQ(ANeuralNetworksDevice_getExtensionSupport(device, kTestExtensionName, &result),
3891 ANEURALNETWORKS_NO_ERROR);
3892 }
3893 }
3894 #endif
3895
3896 } // namespace
3897