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 "NeuralNetworks.h"
18#include "NeuralNetworksOEM.h"
19
20#include <android/sharedmem.h>
21#include <gtest/gtest.h>
22#include <string>
23#include <sys/mman.h>
24
25
26// This file tests all the validations done by the Neural Networks API.
27
28namespace {
29class ValidationTest : public ::testing::Test {
30protected:
31    virtual void SetUp() {}
32};
33
34class ValidationTestModel : public ValidationTest {
35protected:
36    virtual void SetUp() {
37        ValidationTest::SetUp();
38        ASSERT_EQ(ANeuralNetworksModel_create(&mModel), ANEURALNETWORKS_NO_ERROR);
39    }
40    virtual void TearDown() {
41        ANeuralNetworksModel_free(mModel);
42        ValidationTest::TearDown();
43    }
44    ANeuralNetworksModel* mModel = nullptr;
45};
46
47class ValidationTestIdentify : public ValidationTestModel {
48    virtual void SetUp() {
49        ValidationTestModel::SetUp();
50
51        uint32_t dimensions[]{1};
52        ANeuralNetworksOperandType tensorType{.type = ANEURALNETWORKS_TENSOR_FLOAT32,
53                                              .dimensionCount = 1,
54                                              .dimensions = dimensions};
55        ANeuralNetworksOperandType scalarType{.type = ANEURALNETWORKS_INT32,
56                                              .dimensionCount = 0,
57                                              .dimensions = nullptr};
58        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
59        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
60        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &scalarType), ANEURALNETWORKS_NO_ERROR);
61        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
62        uint32_t inList[3]{0, 1, 2};
63        uint32_t outList[1]{3};
64        ASSERT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_ADD, 3, inList, 1,
65                                                    outList),
66                  ANEURALNETWORKS_NO_ERROR);
67    }
68    virtual void TearDown() {
69        ValidationTestModel::TearDown();
70    }
71};
72
73class ValidationTestCompilation : public ValidationTestModel {
74protected:
75    virtual void SetUp() {
76        ValidationTestModel::SetUp();
77
78        uint32_t dimensions[]{1};
79        ANeuralNetworksOperandType tensorType{.type = ANEURALNETWORKS_TENSOR_FLOAT32,
80                                              .dimensionCount = 1,
81                                              .dimensions = dimensions};
82        ANeuralNetworksOperandType scalarType{.type = ANEURALNETWORKS_INT32,
83                                              .dimensionCount = 0,
84                                              .dimensions = nullptr};
85
86        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
87        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
88        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &scalarType), ANEURALNETWORKS_NO_ERROR);
89        ASSERT_EQ(ANeuralNetworksModel_addOperand(mModel, &tensorType), ANEURALNETWORKS_NO_ERROR);
90        uint32_t inList[3]{0, 1, 2};
91        uint32_t outList[1]{3};
92        ASSERT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_ADD, 3, inList, 1,
93                                                    outList),
94                  ANEURALNETWORKS_NO_ERROR);
95        ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 3, inList, 1, outList),
96                  ANEURALNETWORKS_NO_ERROR);
97        ASSERT_EQ(ANeuralNetworksModel_finish(mModel), ANEURALNETWORKS_NO_ERROR);
98
99        ASSERT_EQ(ANeuralNetworksCompilation_create(mModel, &mCompilation),
100                  ANEURALNETWORKS_NO_ERROR);
101    }
102    virtual void TearDown() {
103        ANeuralNetworksCompilation_free(mCompilation);
104        ValidationTestModel::TearDown();
105    }
106    ANeuralNetworksCompilation* mCompilation = nullptr;
107};
108
109class ValidationTestExecution : public ValidationTestCompilation {
110protected:
111    virtual void SetUp() {
112        ValidationTestCompilation::SetUp();
113
114        ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
115
116        ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &mExecution),
117                  ANEURALNETWORKS_NO_ERROR);
118    }
119    virtual void TearDown() {
120        ANeuralNetworksExecution_free(mExecution);
121        ValidationTestCompilation::TearDown();
122    }
123    ANeuralNetworksExecution* mExecution = nullptr;
124};
125
126TEST_F(ValidationTest, CreateModel) {
127    EXPECT_EQ(ANeuralNetworksModel_create(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
128}
129
130TEST_F(ValidationTestModel, AddOperand) {
131    ANeuralNetworksOperandType floatType{
132                .type = ANEURALNETWORKS_FLOAT32, .dimensionCount = 0, .dimensions = nullptr};
133    EXPECT_EQ(ANeuralNetworksModel_addOperand(nullptr, &floatType),
134              ANEURALNETWORKS_UNEXPECTED_NULL);
135    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
136
137    ANeuralNetworksOperandType quant8TypeInvalidScale{
138                .type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
139                .dimensionCount = 0,
140                .dimensions = nullptr,
141                // Scale has to be non-negative
142                .scale = -1.0f,
143                .zeroPoint = 0,
144              };
145    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &quant8TypeInvalidScale),
146              ANEURALNETWORKS_BAD_DATA);
147
148    ANeuralNetworksOperandType quant8TypeInvalidZeroPoint{
149                .type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
150                .dimensionCount = 0,
151                .dimensions = nullptr,
152                .scale = 1.0f,
153                // zeroPoint has to be in [0, 255]
154                .zeroPoint = -1,
155              };
156    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &quant8TypeInvalidZeroPoint),
157              ANEURALNETWORKS_BAD_DATA);
158
159    uint32_t dim = 2;
160    ANeuralNetworksOperandType invalidScalarType{
161                .type = ANEURALNETWORKS_INT32,
162                // scalar types can only 0 dimensions.
163                .dimensionCount = 1,
164                .dimensions = &dim,
165              };
166    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &invalidScalarType),
167              ANEURALNETWORKS_BAD_DATA);
168
169    ANeuralNetworksModel_finish(mModel);
170    // This should fail, as the model is already finished.
171    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType),
172              ANEURALNETWORKS_BAD_STATE);
173}
174
175TEST_F(ValidationTestModel, SetOptionalOperand) {
176    ANeuralNetworksOperandType floatType{
177                .type = ANEURALNETWORKS_FLOAT32, .dimensionCount = 0, .dimensions = nullptr};
178    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
179
180    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, nullptr, 0),
181              ANEURALNETWORKS_NO_ERROR);
182}
183
184TEST_F(ValidationTestModel, SetOperandValue) {
185    ANeuralNetworksOperandType floatType{
186                .type = ANEURALNETWORKS_FLOAT32, .dimensionCount = 0, .dimensions = nullptr};
187    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
188
189    char buffer[20];
190    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(nullptr, 0, buffer, sizeof(buffer)),
191              ANEURALNETWORKS_UNEXPECTED_NULL);
192    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, nullptr, sizeof(buffer)),
193              ANEURALNETWORKS_UNEXPECTED_NULL);
194
195    // This should fail, since buffer is not the size of a float32.
196    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(buffer)),
197              ANEURALNETWORKS_BAD_DATA);
198
199    // This should succeed.
200    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(float)),
201              ANEURALNETWORKS_NO_ERROR);
202
203    // This should fail, as this operand does not exist.
204    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 1, buffer, sizeof(float)),
205              ANEURALNETWORKS_BAD_DATA);
206
207    ANeuralNetworksModel_finish(mModel);
208    // This should fail, as the model is already finished.
209    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(float)),
210              ANEURALNETWORKS_BAD_STATE);
211}
212
213TEST_F(ValidationTestModel, SetOperandValueFromMemory) {
214    uint32_t dimensions[]{1};
215    ANeuralNetworksOperandType floatType{
216                .type = ANEURALNETWORKS_TENSOR_FLOAT32,
217                .dimensionCount = 1,
218                .dimensions = dimensions};
219    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &floatType), ANEURALNETWORKS_NO_ERROR);
220
221    const size_t memorySize = 20;
222    int memoryFd = ASharedMemory_create("nnMemory", memorySize);
223    ASSERT_GT(memoryFd, 0);
224
225    ANeuralNetworksMemory* memory;
226    EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE,
227                                                 memoryFd, 0, &memory),
228              ANEURALNETWORKS_NO_ERROR);
229
230    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(nullptr, 0,
231                                                             memory, 0, sizeof(float)),
232              ANEURALNETWORKS_UNEXPECTED_NULL);
233    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0,
234                                                             nullptr, 0, sizeof(float)),
235              ANEURALNETWORKS_UNEXPECTED_NULL);
236
237    // This should fail, since the operand does not exist.
238    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, -1,
239                                                             memory, 0, sizeof(float)),
240              ANEURALNETWORKS_BAD_DATA);
241
242    // This should fail, since memory is not the size of a float32.
243    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0,
244                                                             memory, 0, memorySize),
245              ANEURALNETWORKS_BAD_DATA);
246
247    // This should fail, as this operand does not exist.
248    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 1,
249                                                             memory, 0, sizeof(float)),
250              ANEURALNETWORKS_BAD_DATA);
251
252    // This should fail, since offset is larger than memorySize.
253    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0,
254                                                             memory, memorySize + 1,
255                                                             sizeof(float)),
256              ANEURALNETWORKS_BAD_DATA);
257
258    // This should fail, since requested size is larger than the memory.
259    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0,
260                                                             memory, memorySize - 3,
261                                                             sizeof(float)),
262              ANEURALNETWORKS_BAD_DATA);
263
264    ANeuralNetworksModel_finish(mModel);
265    // This should fail, as the model is already finished.
266    EXPECT_EQ(ANeuralNetworksModel_setOperandValueFromMemory(mModel, 0,
267                                                             memory, 0,
268                                                             sizeof(float)),
269              ANEURALNETWORKS_BAD_STATE);
270}
271
272
273TEST_F(ValidationTestModel, AddOEMOperand) {
274    ANeuralNetworksOperandType OEMScalarType{
275                .type = ANEURALNETWORKS_OEM_SCALAR, .dimensionCount = 0, .dimensions = nullptr};
276    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMScalarType), ANEURALNETWORKS_NO_ERROR);
277    char buffer[20];
278    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 0, buffer, sizeof(buffer)),
279              ANEURALNETWORKS_NO_ERROR);
280
281    const size_t kByteSizeOfOEMTensor = 4;
282    uint32_t dimensions[]{kByteSizeOfOEMTensor};
283    ANeuralNetworksOperandType OEMTensorType{
284                .type = ANEURALNETWORKS_TENSOR_OEM_BYTE,
285                .dimensionCount = 1,
286                .dimensions = dimensions};
287    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMTensorType), ANEURALNETWORKS_NO_ERROR);
288    EXPECT_EQ(ANeuralNetworksModel_setOperandValue(mModel, 1, buffer, kByteSizeOfOEMTensor),
289              ANEURALNETWORKS_NO_ERROR);
290
291    ANeuralNetworksModel_finish(mModel);
292    // This should fail, as the model is already finished.
293    EXPECT_EQ(ANeuralNetworksModel_addOperand(mModel, &OEMTensorType), ANEURALNETWORKS_BAD_STATE);
294}
295
296TEST_F(ValidationTestModel, AddOperation) {
297    uint32_t input = 0;
298    uint32_t output = 0;
299    EXPECT_EQ(ANeuralNetworksModel_addOperation(nullptr, ANEURALNETWORKS_AVERAGE_POOL_2D, 1, &input,
300                                                1, &output),
301              ANEURALNETWORKS_UNEXPECTED_NULL);
302    EXPECT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_AVERAGE_POOL_2D, 0, nullptr,
303                                                1, &output),
304              ANEURALNETWORKS_UNEXPECTED_NULL);
305    EXPECT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_AVERAGE_POOL_2D, 1, &input,
306                                                0, nullptr),
307              ANEURALNETWORKS_UNEXPECTED_NULL);
308
309    ANeuralNetworksOperationType invalidOp = -1;
310    EXPECT_EQ(ANeuralNetworksModel_addOperation(mModel, invalidOp, 1, &input,
311                                                1, &output),
312              ANEURALNETWORKS_BAD_DATA);
313
314    ANeuralNetworksModel_finish(mModel);
315    // This should fail, as the model is already finished.
316    EXPECT_EQ(ANeuralNetworksModel_addOperation(mModel, ANEURALNETWORKS_AVERAGE_POOL_2D, 1, &input,
317                                                1, &output),
318              ANEURALNETWORKS_BAD_STATE);
319}
320
321TEST_F(ValidationTestModel, IdentifyInputsAndOutputs) {
322    uint32_t input = 0;
323    uint32_t output = 0;
324    EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(nullptr, 1, &input, 1, &output),
325              ANEURALNETWORKS_UNEXPECTED_NULL);
326    EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 0, nullptr, 1, &output),
327              ANEURALNETWORKS_UNEXPECTED_NULL);
328    EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 1, &input, 0, nullptr),
329              ANEURALNETWORKS_UNEXPECTED_NULL);
330
331    ANeuralNetworksModel_finish(mModel);
332    // This should fail, as the model is already finished.
333    EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 1, &input, 1, &output),
334              ANEURALNETWORKS_BAD_STATE);
335}
336
337TEST_F(ValidationTestModel, RelaxComputationFloat32toFloat16) {
338    EXPECT_EQ(ANeuralNetworksModel_relaxComputationFloat32toFloat16(nullptr, true),
339              ANEURALNETWORKS_UNEXPECTED_NULL);
340
341    ANeuralNetworksModel_finish(mModel);
342    // This should fail, as the model is already finished.
343    EXPECT_EQ(ANeuralNetworksModel_relaxComputationFloat32toFloat16(mModel, true),
344              ANEURALNETWORKS_BAD_STATE);
345    EXPECT_EQ(ANeuralNetworksModel_relaxComputationFloat32toFloat16(mModel, false),
346              ANEURALNETWORKS_BAD_STATE);
347}
348
349TEST_F(ValidationTestModel, Finish) {
350    EXPECT_EQ(ANeuralNetworksModel_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
351    EXPECT_EQ(ANeuralNetworksModel_finish(mModel), ANEURALNETWORKS_NO_ERROR);
352    EXPECT_EQ(ANeuralNetworksModel_finish(mModel), ANEURALNETWORKS_BAD_STATE);
353}
354
355TEST_F(ValidationTestModel, CreateCompilation) {
356    ANeuralNetworksCompilation* compilation = nullptr;
357    EXPECT_EQ(ANeuralNetworksCompilation_create(nullptr, &compilation),
358              ANEURALNETWORKS_UNEXPECTED_NULL);
359    EXPECT_EQ(ANeuralNetworksCompilation_create(mModel, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
360    EXPECT_EQ(ANeuralNetworksCompilation_create(mModel, &compilation), ANEURALNETWORKS_BAD_STATE);
361}
362
363TEST_F(ValidationTestIdentify, Ok) {
364    uint32_t inList[3]{0, 1, 2};
365    uint32_t outList[1]{3};
366
367    ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 3, inList, 1, outList),
368              ANEURALNETWORKS_NO_ERROR);
369
370    ASSERT_EQ(ANeuralNetworksModel_finish(mModel), ANEURALNETWORKS_NO_ERROR);
371}
372
373TEST_F(ValidationTestIdentify, InputIsOutput) {
374    uint32_t inList[3]{0, 1, 2};
375    uint32_t outList[2]{3, 0};
376
377    ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 3, inList, 2, outList),
378              ANEURALNETWORKS_BAD_DATA);
379}
380
381TEST_F(ValidationTestIdentify, OutputIsInput) {
382    uint32_t inList[4]{0, 1, 2, 3};
383    uint32_t outList[1]{3};
384
385    ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 4, inList, 1, outList),
386              ANEURALNETWORKS_BAD_DATA);
387}
388
389TEST_F(ValidationTestIdentify, DuplicateInputs) {
390    uint32_t inList[4]{0, 1, 2, 0};
391    uint32_t outList[1]{3};
392
393    ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 4, inList, 1, outList),
394              ANEURALNETWORKS_BAD_DATA);
395}
396
397TEST_F(ValidationTestIdentify, DuplicateOutputs) {
398    uint32_t inList[3]{0, 1, 2};
399    uint32_t outList[2]{3, 3};
400
401    ASSERT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(mModel, 3, inList, 2, outList),
402              ANEURALNETWORKS_BAD_DATA);
403}
404
405TEST_F(ValidationTestCompilation, SetPreference) {
406    EXPECT_EQ(ANeuralNetworksCompilation_setPreference(nullptr, ANEURALNETWORKS_PREFER_LOW_POWER),
407              ANEURALNETWORKS_UNEXPECTED_NULL);
408
409    EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation, 40), ANEURALNETWORKS_BAD_DATA);
410}
411
412TEST_F(ValidationTestCompilation, CreateExecution) {
413    ANeuralNetworksExecution* execution = nullptr;
414    EXPECT_EQ(ANeuralNetworksExecution_create(nullptr, &execution),
415              ANEURALNETWORKS_UNEXPECTED_NULL);
416    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, nullptr),
417              ANEURALNETWORKS_UNEXPECTED_NULL);
418    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution),
419              ANEURALNETWORKS_BAD_STATE);
420}
421
422TEST_F(ValidationTestCompilation, Finish) {
423    EXPECT_EQ(ANeuralNetworksCompilation_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
424    EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR);
425    EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation,
426                                                       ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER),
427              ANEURALNETWORKS_BAD_STATE);
428    EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_BAD_STATE);
429}
430
431TEST_F(ValidationTestExecution, SetInput) {
432    ANeuralNetworksExecution* execution;
433    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
434
435    char buffer[20];
436    EXPECT_EQ(ANeuralNetworksExecution_setInput(nullptr, 0, nullptr, buffer, sizeof(float)),
437              ANEURALNETWORKS_UNEXPECTED_NULL);
438    EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, nullptr, sizeof(float)),
439              ANEURALNETWORKS_UNEXPECTED_NULL);
440
441    // This should fail, since memory is not the size of a float32.
442    EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, buffer, 20),
443              ANEURALNETWORKS_BAD_DATA);
444
445    // This should fail, as this operand does not exist.
446    EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, 999, nullptr, buffer, sizeof(float)),
447              ANEURALNETWORKS_BAD_DATA);
448
449    // This should fail, as this operand does not exist.
450    EXPECT_EQ(ANeuralNetworksExecution_setInput(execution, -1, nullptr, buffer, sizeof(float)),
451              ANEURALNETWORKS_BAD_DATA);
452}
453
454TEST_F(ValidationTestExecution, SetOutput) {
455    ANeuralNetworksExecution* execution;
456    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
457
458    char buffer[20];
459    EXPECT_EQ(ANeuralNetworksExecution_setOutput(nullptr, 0, nullptr, buffer, sizeof(float)),
460              ANEURALNETWORKS_UNEXPECTED_NULL);
461    EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, nullptr, sizeof(float)),
462              ANEURALNETWORKS_UNEXPECTED_NULL);
463
464    // This should fail, since memory is not the size of a float32.
465    EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, buffer, 20),
466              ANEURALNETWORKS_BAD_DATA);
467
468    // This should fail, as this operand does not exist.
469    EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, 999, nullptr, buffer, sizeof(float)),
470              ANEURALNETWORKS_BAD_DATA);
471
472    // This should fail, as this operand does not exist.
473    EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution, -1, nullptr, buffer, sizeof(float)),
474              ANEURALNETWORKS_BAD_DATA);
475}
476
477TEST_F(ValidationTestExecution, SetInputFromMemory) {
478    ANeuralNetworksExecution* execution;
479    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
480
481    const size_t memorySize = 20;
482    int memoryFd = ASharedMemory_create("nnMemory", memorySize);
483    ASSERT_GT(memoryFd, 0);
484
485    ANeuralNetworksMemory* memory;
486    EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE,
487                                                 memoryFd, 0, &memory),
488              ANEURALNETWORKS_NO_ERROR);
489
490    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(nullptr, 0, nullptr,
491                                                          memory, 0, sizeof(float)),
492              ANEURALNETWORKS_UNEXPECTED_NULL);
493    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr,
494                                                          nullptr, 0, sizeof(float)),
495              ANEURALNETWORKS_UNEXPECTED_NULL);
496
497    // This should fail, since the operand does not exist.
498    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 999, nullptr,
499                                                          memory, 0, sizeof(float)),
500              ANEURALNETWORKS_BAD_DATA);
501
502    // This should fail, since the operand does not exist.
503    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, -1, nullptr,
504                                                          memory, 0, sizeof(float)),
505              ANEURALNETWORKS_BAD_DATA);
506
507    // This should fail, since memory is not the size of a float32.
508    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr,
509                                                          memory, 0, memorySize),
510              ANEURALNETWORKS_BAD_DATA);
511
512    // This should fail, since offset is larger than memorySize.
513    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr,
514                                                          memory, memorySize + 1, sizeof(float)),
515              ANEURALNETWORKS_BAD_DATA);
516
517    // This should fail, since requested size is larger than the memory.
518    EXPECT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr,
519                                                          memory, memorySize - 3, sizeof(float)),
520              ANEURALNETWORKS_BAD_DATA);
521}
522
523TEST_F(ValidationTestExecution, SetOutputFromMemory) {
524    ANeuralNetworksExecution* execution;
525    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
526
527    const size_t memorySize = 20;
528    int memoryFd = ASharedMemory_create("nnMemory", memorySize);
529    ASSERT_GT(memoryFd, 0);
530
531    ANeuralNetworksMemory* memory;
532    EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE,
533                                                 memoryFd, 0, &memory),
534              ANEURALNETWORKS_NO_ERROR);
535
536    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(nullptr, 0, nullptr,
537                                                           memory, 0, sizeof(float)),
538              ANEURALNETWORKS_UNEXPECTED_NULL);
539    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr,
540                                                           nullptr, 0, sizeof(float)),
541              ANEURALNETWORKS_UNEXPECTED_NULL);
542
543    // This should fail, since the operand does not exist.
544    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 999, nullptr,
545                                                           memory, 0, sizeof(float)),
546              ANEURALNETWORKS_BAD_DATA);
547
548    // This should fail, since the operand does not exist.
549    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, -1, nullptr,
550                                                           memory, 0, sizeof(float)),
551              ANEURALNETWORKS_BAD_DATA);
552
553    // This should fail, since memory is not the size of a float32.
554    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr,
555                                                           memory, 0, memorySize),
556              ANEURALNETWORKS_BAD_DATA);
557
558    // This should fail, since offset is larger than memorySize.
559    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr,
560                                                           memory, memorySize + 1, sizeof(float)),
561              ANEURALNETWORKS_BAD_DATA);
562
563    // This should fail, since requested size is larger than the memory.
564    EXPECT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr,
565                                                           memory, memorySize - 3, sizeof(float)),
566              ANEURALNETWORKS_BAD_DATA);
567}
568
569TEST_F(ValidationTestExecution, StartCompute) {
570    ANeuralNetworksExecution* execution;
571    EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);
572
573    ANeuralNetworksEvent* event;
574    EXPECT_EQ(ANeuralNetworksExecution_startCompute(nullptr, &event),
575              ANEURALNETWORKS_UNEXPECTED_NULL);
576    EXPECT_EQ(ANeuralNetworksExecution_startCompute(execution, nullptr),
577              ANEURALNETWORKS_UNEXPECTED_NULL);
578}
579
580TEST_F(ValidationTestExecution, EventWait) {
581    EXPECT_EQ(ANeuralNetworksEvent_wait(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
582}
583}  // namespace
584