Add 1.2 NN HAL interface for dynamic output shape.
Let notify_1_2() notify output shapes.
Document unspecified dimensions and rank.
Bug: 73506513
Bug: 77234888
Test: NeuralNetworksTest_static
Test: VtsHalNeuralnetworksV1_xTargetTest with 1.2 sample driver
Change-Id: I01108913212d9f4aa47daf2f293ea19259925865
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 3b4eb21..b5a8607 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -89,13 +89,24 @@
sp<ExecutionCallback>& callback) {
return preparedModel->execute_1_2(request, callback);
}
-static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>&, const Request&) {
+static Return<ErrorStatus> ExecutePreparedModel(sp<V1_0::IPreparedModel>&, const Request&,
+ hidl_vec<OutputShape>*) {
ADD_FAILURE() << "asking for synchronous execution at V1_0";
return ErrorStatus::GENERAL_FAILURE;
}
static Return<ErrorStatus> ExecutePreparedModel(sp<V1_2::IPreparedModel>& preparedModel,
- const Request& request) {
- return preparedModel->executeSynchronously(request);
+ const Request& request,
+ hidl_vec<OutputShape>* outputShapes) {
+ ErrorStatus result;
+ Return<void> ret = preparedModel->executeSynchronously(
+ request, [&result, &outputShapes](ErrorStatus error, const hidl_vec<OutputShape>& shapes) {
+ result = error;
+ *outputShapes = shapes;
+ });
+ if (!ret.isOk()) {
+ return ErrorStatus::GENERAL_FAILURE;
+ }
+ return result;
}
enum class Synchronously { NO, YES };
const float kDefaultAtol = 1e-5f;
@@ -197,6 +208,8 @@
inputMemory->commit();
outputMemory->commit();
+ ErrorStatus executionStatus;
+ hidl_vec<OutputShape> outputShapes;
if (sync == Synchronously::NO) {
SCOPED_TRACE("asynchronous");
@@ -211,18 +224,24 @@
// retrieve execution status
executionCallback->wait();
- ErrorStatus executionReturnStatus = executionCallback->getStatus();
- EXPECT_EQ(ErrorStatus::NONE, executionReturnStatus);
+ executionStatus = executionCallback->getStatus();
+ outputShapes = executionCallback->getOutputShapes();
} else {
SCOPED_TRACE("synchronous");
// execute
- Return<ErrorStatus> executionStatus = ExecutePreparedModel(
- preparedModel, {.inputs = inputs_info, .outputs = outputs_info, .pools = pools});
- ASSERT_TRUE(executionStatus.isOk());
- EXPECT_EQ(ErrorStatus::NONE, static_cast<ErrorStatus>(executionStatus));
+ Return<ErrorStatus> executionReturnStatus = ExecutePreparedModel(
+ preparedModel, {.inputs = inputs_info, .outputs = outputs_info, .pools = pools},
+ &outputShapes);
+ ASSERT_TRUE(executionReturnStatus.isOk());
+ executionStatus = static_cast<ErrorStatus>(executionReturnStatus);
}
+ ASSERT_EQ(ErrorStatus::NONE, executionStatus);
+ // TODO(xusongw): Check if the returned output shapes match with expectation once the
+ // sample driver implementation of dynamic output shape is finished.
+ ASSERT_EQ(outputShapes.size(), 0);
+
// validate results
outputMemory->read();
copy_back(&test, outputs_info, outputPtr);