blob: bda43b1986e748fba7e4e466248e6ce0dcc3c31c [file] [log] [blame]
Michael Butlerf76acd02018-03-22 16:37:57 -07001/*
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#define LOG_TAG "neuralnetworks_hidl_hal_test"
18
19#include "VtsHalNeuralnetworks.h"
20
David Gross12ab6c52018-05-14 12:23:04 -070021#include "1.0/Callbacks.h"
22
Michael Butlerbbe5dad2019-08-26 23:55:47 -070023namespace android::hardware::neuralnetworks::V1_0::vts::functional {
Michael Butlerf76acd02018-03-22 16:37:57 -070024
David Gross12ab6c52018-05-14 12:23:04 -070025using implementation::PreparedModelCallback;
26
Michael Butlerf76acd02018-03-22 16:37:57 -070027// create device test
Michael Butler7076f622019-08-29 11:08:25 -070028TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
Michael Butlerf76acd02018-03-22 16:37:57 -070029
30// status test
Michael Butler7076f622019-08-29 11:08:25 -070031TEST_P(NeuralnetworksHidlTest, StatusTest) {
Michael Butlere16af0a2019-08-29 22:17:24 -070032 Return<DeviceStatus> status = kDevice->getStatus();
Michael Butlerf76acd02018-03-22 16:37:57 -070033 ASSERT_TRUE(status.isOk());
34 EXPECT_EQ(DeviceStatus::AVAILABLE, static_cast<DeviceStatus>(status));
35}
36
37// initialization
Michael Butler7076f622019-08-29 11:08:25 -070038TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) {
Michael Butlerf76acd02018-03-22 16:37:57 -070039 Return<void> ret =
Michael Butlere16af0a2019-08-29 22:17:24 -070040 kDevice->getCapabilities([](ErrorStatus status, const Capabilities& capabilities) {
Michael Butlerbbe5dad2019-08-26 23:55:47 -070041 EXPECT_EQ(ErrorStatus::NONE, status);
42 EXPECT_LT(0.0f, capabilities.float32Performance.execTime);
43 EXPECT_LT(0.0f, capabilities.float32Performance.powerUsage);
44 EXPECT_LT(0.0f, capabilities.quantized8Performance.execTime);
45 EXPECT_LT(0.0f, capabilities.quantized8Performance.powerUsage);
46 });
Michael Butlerf76acd02018-03-22 16:37:57 -070047 EXPECT_TRUE(ret.isOk());
48}
49
David Gross12ab6c52018-05-14 12:23:04 -070050// detect cycle
51TEST_P(NeuralnetworksHidlTest, CycleTest) {
52 // opnd0 = TENSOR_FLOAT32 // model input
53 // opnd1 = TENSOR_FLOAT32 // model input
54 // opnd2 = INT32 // model input
55 // opnd3 = ADD(opnd0, opnd4, opnd2)
56 // opnd4 = ADD(opnd1, opnd3, opnd2)
57 // opnd5 = ADD(opnd4, opnd0, opnd2) // model output
58 //
59 // +-----+
60 // | |
61 // v |
62 // 3 = ADD(0, 4, 2) |
63 // | |
64 // +----------+ |
65 // | |
66 // v |
67 // 4 = ADD(1, 3, 2) |
68 // | |
69 // +----------------+
70 // |
71 // |
72 // +-------+
73 // |
74 // v
75 // 5 = ADD(4, 0, 2)
76
77 const std::vector<Operand> operands = {
78 {
79 // operands[0]
80 .type = OperandType::TENSOR_FLOAT32,
81 .dimensions = {1},
82 .numberOfConsumers = 2,
83 .scale = 0.0f,
84 .zeroPoint = 0,
85 .lifetime = OperandLifeTime::MODEL_INPUT,
86 .location = {.poolIndex = 0, .offset = 0, .length = 0},
87 },
88 {
89 // operands[1]
90 .type = OperandType::TENSOR_FLOAT32,
91 .dimensions = {1},
92 .numberOfConsumers = 1,
93 .scale = 0.0f,
94 .zeroPoint = 0,
95 .lifetime = OperandLifeTime::MODEL_INPUT,
96 .location = {.poolIndex = 0, .offset = 0, .length = 0},
97 },
98 {
99 // operands[2]
100 .type = OperandType::INT32,
101 .dimensions = {},
102 .numberOfConsumers = 3,
103 .scale = 0.0f,
104 .zeroPoint = 0,
105 .lifetime = OperandLifeTime::MODEL_INPUT,
106 .location = {.poolIndex = 0, .offset = 0, .length = 0},
107 },
108 {
109 // operands[3]
110 .type = OperandType::TENSOR_FLOAT32,
111 .dimensions = {1},
112 .numberOfConsumers = 1,
113 .scale = 0.0f,
114 .zeroPoint = 0,
115 .lifetime = OperandLifeTime::TEMPORARY_VARIABLE,
116 .location = {.poolIndex = 0, .offset = 0, .length = 0},
117 },
118 {
119 // operands[4]
120 .type = OperandType::TENSOR_FLOAT32,
121 .dimensions = {1},
122 .numberOfConsumers = 2,
123 .scale = 0.0f,
124 .zeroPoint = 0,
125 .lifetime = OperandLifeTime::TEMPORARY_VARIABLE,
126 .location = {.poolIndex = 0, .offset = 0, .length = 0},
127 },
128 {
129 // operands[5]
130 .type = OperandType::TENSOR_FLOAT32,
131 .dimensions = {1},
132 .numberOfConsumers = 0,
133 .scale = 0.0f,
134 .zeroPoint = 0,
135 .lifetime = OperandLifeTime::MODEL_OUTPUT,
136 .location = {.poolIndex = 0, .offset = 0, .length = 0},
137 },
138 };
139
140 const std::vector<Operation> operations = {
141 {.type = OperationType::ADD, .inputs = {0, 4, 2}, .outputs = {3}},
142 {.type = OperationType::ADD, .inputs = {1, 3, 2}, .outputs = {4}},
143 {.type = OperationType::ADD, .inputs = {4, 0, 2}, .outputs = {5}},
144 };
145
146 const Model model = {
147 .operands = operands,
148 .operations = operations,
149 .inputIndexes = {0, 1, 2},
150 .outputIndexes = {5},
151 .operandValues = {},
152 .pools = {},
153 };
154
155 // ensure that getSupportedOperations() checks model validity
156 ErrorStatus supportedOpsErrorStatus = ErrorStatus::GENERAL_FAILURE;
157 Return<void> supportedOpsReturn = kDevice->getSupportedOperations(
158 model, [&model, &supportedOpsErrorStatus](ErrorStatus status,
159 const hidl_vec<bool>& supported) {
160 supportedOpsErrorStatus = status;
161 if (status == ErrorStatus::NONE) {
162 ASSERT_EQ(supported.size(), model.operations.size());
163 }
164 });
165 ASSERT_TRUE(supportedOpsReturn.isOk());
166 ASSERT_EQ(supportedOpsErrorStatus, ErrorStatus::INVALID_ARGUMENT);
167
168 // ensure that prepareModel() checks model validity
169 sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback;
170 Return<ErrorStatus> prepareLaunchReturn = kDevice->prepareModel(model, preparedModelCallback);
171 ASSERT_TRUE(prepareLaunchReturn.isOk());
172 // Note that preparation can fail for reasons other than an
173 // invalid model (invalid model should result in
174 // INVALID_ARGUMENT) -- for example, perhaps not all
175 // operations are supported, or perhaps the device hit some
176 // kind of capacity limit.
177 EXPECT_NE(prepareLaunchReturn, ErrorStatus::NONE);
178 EXPECT_NE(preparedModelCallback->getStatus(), ErrorStatus::NONE);
179 EXPECT_EQ(preparedModelCallback->getPreparedModel(), nullptr);
180}
181
Michael Butlerbbe5dad2019-08-26 23:55:47 -0700182} // namespace android::hardware::neuralnetworks::V1_0::vts::functional