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