Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2018 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 "TestCompliance.h"
     18 
     19 #include <gtest/gtest.h>
     20 
     21 #include "ModelBuilder.h"
     22 #include "TestNeuralNetworksWrapper.h"
     23 #include "Utils.h"
     24 
     25 namespace compliance_test {
     26 
     27 using namespace ::android::nn;
     28 using HidlModel = V1_2::Model;
     29 using WrapperModel = test_wrapper::Model;
     30 using WrapperOperandType = test_wrapper::OperandType;
     31 using WrapperType = test_wrapper::Type;
     32 
     33 // Creates a HIDL model from a creator of the wrapper model.
     34 static HidlModel createHidlModel(std::function<void(WrapperModel*)> createModel) {
     35     HidlModel hidlModel;
     36     WrapperModel wrapperModel;
     37     createModel(&wrapperModel);
     38     EXPECT_EQ(wrapperModel.finish(), test_wrapper::Result::NO_ERROR);
     39     ModelBuilder* modelBuilder = reinterpret_cast<ModelBuilder*>(wrapperModel.getHandle());
     40     modelBuilder->setHidlModel(&hidlModel);
     41     return hidlModel;
     42 }
     43 
     44 void ComplianceTest::testAvailableSinceV1_2(std::function<void(WrapperModel*)> createModel) {
     45     HidlModel model = createHidlModel(createModel);
     46     ASSERT_FALSE(compliantWithV1_1(model));
     47     ASSERT_FALSE(compliantWithV1_0(model));
     48 }
     49 
     50 void ComplianceTest::testAvailableSinceV1_1(std::function<void(WrapperModel*)> createModel) {
     51     HidlModel model = createHidlModel(createModel);
     52     ASSERT_TRUE(compliantWithV1_1(model));
     53     ASSERT_FALSE(compliantWithV1_0(model));
     54 }
     55 
     56 void ComplianceTest::testAvailableSinceV1_0(std::function<void(WrapperModel*)> createModel) {
     57     HidlModel model = createHidlModel(createModel);
     58     ASSERT_TRUE(compliantWithV1_1(model));
     59     ASSERT_TRUE(compliantWithV1_0(model));
     60 }
     61 
     62 static const WrapperOperandType kTypeTensorFloat(WrapperType::TENSOR_FLOAT32, {1});
     63 static const WrapperOperandType kTypeTensorFloatRank0(WrapperType::TENSOR_FLOAT32, {});
     64 static const WrapperOperandType kTypeInt32(WrapperType::INT32, {});
     65 
     66 TEST_F(ComplianceTest, Rank0TensorModelInput) {
     67     int32_t act_init = 0;
     68     // A simple ADD operation: op1 ADD op2 = op3, with op1 and op2 of rank 0.
     69     testAvailableSinceV1_2([&act_init](WrapperModel* model) {
     70         auto op1 = model->addOperand(&kTypeTensorFloatRank0);
     71         auto op2 = model->addOperand(&kTypeTensorFloatRank0);
     72         auto act = model->addOperand(&kTypeInt32);
     73         auto op3 = model->addOperand(&kTypeTensorFloat);
     74         model->setOperandValue(act, &act_init, sizeof(act_init));
     75         model->addOperation(ANEURALNETWORKS_ADD, {op1, op2, act}, {op3});
     76         model->identifyInputsAndOutputs({op1, op2}, {op3});
     77         assert(model->isValid());
     78     });
     79 }
     80 
     81 TEST_F(ComplianceTest, Rank0TensorModelOutput) {
     82     int32_t act_init = 0;
     83     // A simple ADD operation: op1 ADD op2 = op3, with op3 of rank 0.
     84     testAvailableSinceV1_2([&act_init](WrapperModel* model) {
     85         auto op1 = model->addOperand(&kTypeTensorFloat);
     86         auto op2 = model->addOperand(&kTypeTensorFloat);
     87         auto act = model->addOperand(&kTypeInt32);
     88         auto op3 = model->addOperand(&kTypeTensorFloatRank0);
     89         model->setOperandValue(act, &act_init, sizeof(act_init));
     90         model->addOperation(ANEURALNETWORKS_ADD, {op1, op2, act}, {op3});
     91         model->identifyInputsAndOutputs({op1, op2}, {op3});
     92         assert(model->isValid());
     93     });
     94 }
     95 
     96 TEST_F(ComplianceTest, Rank0TensorTemporaryVariable) {
     97     int32_t act_init = 0;
     98     // Two ADD operations: op1 ADD op2 = op3, op3 ADD op4 = op5, with op3 of rank 0.
     99     testAvailableSinceV1_2([&act_init](WrapperModel* model) {
    100         auto op1 = model->addOperand(&kTypeTensorFloat);
    101         auto op2 = model->addOperand(&kTypeTensorFloat);
    102         auto op3 = model->addOperand(&kTypeTensorFloatRank0);
    103         auto op4 = model->addOperand(&kTypeTensorFloat);
    104         auto op5 = model->addOperand(&kTypeTensorFloat);
    105         auto act = model->addOperand(&kTypeInt32);
    106         model->setOperandValue(act, &act_init, sizeof(act_init));
    107         model->addOperation(ANEURALNETWORKS_ADD, {op1, op2, act}, {op3});
    108         model->addOperation(ANEURALNETWORKS_ADD, {op3, op4, act}, {op5});
    109         model->identifyInputsAndOutputs({op1, op2, op4}, {op5});
    110         assert(model->isValid());
    111     });
    112 }
    113 
    114 TEST_F(ComplianceTest, HardwareBuffer) {
    115     const size_t memorySize = 20;
    116     AHardwareBuffer_Desc desc{
    117             .width = memorySize,
    118             .height = 1,
    119             .layers = 1,
    120             .format = AHARDWAREBUFFER_FORMAT_BLOB,
    121             .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
    122     };
    123 
    124     AHardwareBuffer* buffer = nullptr;
    125     ASSERT_EQ(AHardwareBuffer_allocate(&desc, &buffer), 0);
    126     test_wrapper::Memory memory(buffer);
    127     ASSERT_TRUE(memory.isValid());
    128 
    129     int32_t act_init = 0;
    130 
    131     // A simple ADD operation: op1 ADD op2 = op3, with op2 using a const hardware buffer.
    132     testAvailableSinceV1_2([&memory, &act_init](WrapperModel* model) {
    133         auto op1 = model->addOperand(&kTypeTensorFloat);
    134         auto op2 = model->addOperand(&kTypeTensorFloat);
    135         auto act = model->addOperand(&kTypeInt32);
    136         auto op3 = model->addOperand(&kTypeTensorFloat);
    137         model->setOperandValueFromMemory(op2, &memory, 0, sizeof(float));
    138         model->setOperandValue(act, &act_init, sizeof(act_init));
    139         model->addOperation(ANEURALNETWORKS_ADD, {op1, op2, act}, {op3});
    140         model->identifyInputsAndOutputs({op1}, {op3});
    141         assert(model->isValid());
    142     });
    143 
    144     AHardwareBuffer_release(buffer);
    145 }
    146 
    147 }  // namespace compliance_test
    148