summaryrefslogtreecommitdiffstats
path: root/neuralnetworks/1.3
diff options
context:
space:
mode:
authorLev Proleev <levp@google.com>2019-10-10 13:54:38 +0000
committerLev Proleev <levp@google.com>2019-10-10 13:54:38 +0000
commit64f9eb4bd5cbc9bf8e3feff3618ca7681fb8b401 (patch)
treeef505a75d7b5e37851f22454dde9acaf20cddd87 /neuralnetworks/1.3
parent543606fb92143dea42c83cb1d08c559957772178 (diff)
downloadplatform_hardware_interfaces-64f9eb4bd5cbc9bf8e3feff3618ca7681fb8b401.tar.gz
platform_hardware_interfaces-64f9eb4bd5cbc9bf8e3feff3618ca7681fb8b401.tar.bz2
platform_hardware_interfaces-64f9eb4bd5cbc9bf8e3feff3618ca7681fb8b401.zip
Revert "Modify NNAPI VTS tests to run on version 1.3"
This reverts commit 543606fb92143dea42c83cb1d08c559957772178. Reason for revert: the topic breaks git_qt-dev-plus-aosp Change-Id: I74859bae687d65d344ed7edc617e1a7d086960a1
Diffstat (limited to 'neuralnetworks/1.3')
-rw-r--r--neuralnetworks/1.3/vts/functional/Android.bp58
-rw-r--r--neuralnetworks/1.3/vts/functional/BasicTests.cpp62
-rw-r--r--neuralnetworks/1.3/vts/functional/Callbacks.cpp143
-rw-r--r--neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp13
-rw-r--r--neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp18
-rw-r--r--neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h19
-rw-r--r--neuralnetworks/1.3/vts/functional/TestAssertions.cpp9
-rw-r--r--neuralnetworks/1.3/vts/functional/ValidateBurst.cpp11
-rw-r--r--neuralnetworks/1.3/vts/functional/ValidateModel.cpp21
-rw-r--r--neuralnetworks/1.3/vts/functional/ValidateRequest.cpp10
-rw-r--r--neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp20
-rw-r--r--neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h19
-rw-r--r--neuralnetworks/1.3/vts/functional/include/1.2/Callbacks.h325
13 files changed, 576 insertions, 152 deletions
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
deleted file mode 100644
index 90ce852e3e..0000000000
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_test {
- name: "VtsHalNeuralNetworksV1_3TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
- srcs: [
- "BasicTests.cpp",
- "CompilationCachingTests.cpp",
- "GeneratedTestHarness.cpp",
- "TestAssertions.cpp",
- "ValidateBurst.cpp",
- "ValidateModel.cpp",
- "ValidateRequest.cpp",
- "VtsHalNeuralnetworks.cpp",
- ],
- shared_libs: [
- "libfmq",
- "libnativewindow",
- ],
- static_libs: [
- "android.hardware.neuralnetworks@1.0",
- "android.hardware.neuralnetworks@1.1",
- "android.hardware.neuralnetworks@1.2",
- "android.hardware.neuralnetworks@1.3",
- "android.hidl.allocator@1.0",
- "android.hidl.memory@1.0",
- "libgmock",
- "libhidlmemory",
- "libneuralnetworks_generated_test_harness",
- "libneuralnetworks_utils",
- "VtsHalNeuralNetworksV1_0_utils",
- "VtsHalNeuralNetworksV1_2Callbacks",
- ],
- whole_static_libs: [
- "neuralnetworks_generated_V1_0_example",
- "neuralnetworks_generated_V1_1_example",
- "neuralnetworks_generated_V1_2_example",
- "neuralnetworks_generated_V1_3_example",
- ],
- header_libs: [
- "libneuralnetworks_headers",
- ],
- test_suites: ["general-tests"],
-}
diff --git a/neuralnetworks/1.3/vts/functional/BasicTests.cpp b/neuralnetworks/1.3/vts/functional/BasicTests.cpp
index b64dc2f61b..8e82c5376e 100644
--- a/neuralnetworks/1.3/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/BasicTests.cpp
@@ -18,14 +18,11 @@
#include "VtsHalNeuralnetworks.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using V1_0::DeviceStatus;
using V1_0::ErrorStatus;
using V1_0::PerformanceInfo;
-using V1_2::Constant;
-using V1_2::DeviceType;
-using V1_2::Extension;
// create device test
TEST_P(NeuralnetworksHidlTest, CreateDevice) {}
@@ -40,7 +37,7 @@ TEST_P(NeuralnetworksHidlTest, StatusTest) {
// initialization
TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) {
using OperandPerformance = Capabilities::OperandPerformance;
- Return<void> ret = kDevice->getCapabilities_1_3([](ErrorStatus status,
+ Return<void> ret = kDevice->getCapabilities_1_2([](ErrorStatus status,
const Capabilities& capabilities) {
EXPECT_EQ(ErrorStatus::NONE, status);
@@ -61,4 +58,57 @@ TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) {
});
EXPECT_TRUE(ret.isOk());
}
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+
+// device version test
+TEST_P(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
+ Return<void> ret =
+ kDevice->getVersionString([](ErrorStatus status, const hidl_string& version) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ EXPECT_LT(0, version.size());
+ });
+ EXPECT_TRUE(ret.isOk());
+}
+
+// device type test
+TEST_P(NeuralnetworksHidlTest, GetDeviceTypeTest) {
+ Return<void> ret = kDevice->getType([](ErrorStatus status, DeviceType type) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ EXPECT_TRUE(type == DeviceType::OTHER || type == DeviceType::CPU ||
+ type == DeviceType::GPU || type == DeviceType::ACCELERATOR);
+ });
+ EXPECT_TRUE(ret.isOk());
+}
+
+// device supported extensions test
+TEST_P(NeuralnetworksHidlTest, GetDeviceSupportedExtensionsTest) {
+ Return<void> ret = kDevice->getSupportedExtensions(
+ [](ErrorStatus status, const hidl_vec<Extension>& extensions) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ for (auto& extension : extensions) {
+ std::string extensionName = extension.name;
+ EXPECT_FALSE(extensionName.empty());
+ for (char c : extensionName) {
+ EXPECT_TRUE(('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_' ||
+ c == '.')
+ << "Extension name contains an illegal character: " << c;
+ }
+ EXPECT_NE(extensionName.find('.'), std::string::npos)
+ << "Extension name must start with the reverse domain name of the "
+ "vendor";
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+}
+
+// getNumberOfCacheFilesNeeded test
+TEST_P(NeuralnetworksHidlTest, getNumberOfCacheFilesNeeded) {
+ Return<void> ret = kDevice->getNumberOfCacheFilesNeeded(
+ [](ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ EXPECT_LE(numModelCache,
+ static_cast<uint32_t>(Constant::MAX_NUMBER_OF_CACHE_FILES));
+ EXPECT_LE(numDataCache, static_cast<uint32_t>(Constant::MAX_NUMBER_OF_CACHE_FILES));
+ });
+ EXPECT_TRUE(ret.isOk());
+}
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/Callbacks.cpp b/neuralnetworks/1.3/vts/functional/Callbacks.cpp
new file mode 100644
index 0000000000..3972ad6ff2
--- /dev/null
+++ b/neuralnetworks/1.3/vts/functional/Callbacks.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Callbacks"
+
+#include "1.2/Callbacks.h"
+
+#include <android-base/logging.h>
+
+#include <limits>
+
+namespace android::hardware::neuralnetworks::V1_2::implementation {
+
+using V1_0::ErrorStatus;
+
+constexpr Timing kNoTiming = {.timeOnDevice = std::numeric_limits<uint64_t>::max(),
+ .timeInDriver = std::numeric_limits<uint64_t>::max()};
+
+// PreparedModelCallback methods begin here
+
+Return<void> PreparedModelCallback::notify(ErrorStatus errorStatus,
+ const sp<V1_0::IPreparedModel>& preparedModel) {
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return Void();
+ }
+
+ // store results and mark as notified
+ mErrorStatus = errorStatus;
+ mPreparedModel = preparedModel;
+ mNotified = true;
+ }
+
+ mCondition.notify_all();
+ return Void();
+}
+
+Return<void> PreparedModelCallback::notify_1_2(ErrorStatus errorStatus,
+ const sp<V1_2::IPreparedModel>& preparedModel) {
+ return notify(errorStatus, preparedModel);
+}
+
+void PreparedModelCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
+}
+
+ErrorStatus PreparedModelCallback::getStatus() const {
+ wait();
+ return mErrorStatus;
+}
+
+sp<V1_0::IPreparedModel> PreparedModelCallback::getPreparedModel() const {
+ wait();
+ return mPreparedModel;
+}
+
+// ExecutionCallback methods begin here
+
+Return<void> ExecutionCallback::notify(ErrorStatus errorStatus) {
+ notifyInternal(errorStatus, {}, kNoTiming);
+ return Void();
+}
+
+Return<void> ExecutionCallback::notify_1_2(ErrorStatus errorStatus,
+ const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) {
+ if (errorStatus == ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+ // outputShapes must not be empty if OUTPUT_INSUFFICIENT_SIZE.
+ if (outputShapes.size() == 0) {
+ LOG(ERROR) << "Notified with empty output shape vector when OUTPUT_INSUFFICIENT_SIZE";
+ notifyInternal(ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
+ return Void();
+ }
+ } else if (errorStatus != ErrorStatus::NONE) {
+ // outputShapes must be empty if errorStatus is neither NONE nor OUTPUT_INSUFFICIENT_SIZE.
+ if (outputShapes.size() != 0) {
+ LOG(ERROR) << "Notified with non-empty output shape vector when error status is "
+ "neither NONE nor OUTPUT_INSUFFICIENT_SIZE";
+ notifyInternal(ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
+ return Void();
+ }
+ }
+ notifyInternal(errorStatus, outputShapes, timing);
+ return Void();
+}
+
+void ExecutionCallback::wait() const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mNotified; });
+}
+
+ErrorStatus ExecutionCallback::getStatus() const {
+ wait();
+ return mErrorStatus;
+}
+
+const std::vector<OutputShape>& ExecutionCallback::getOutputShapes() const {
+ wait();
+ return mOutputShapes;
+}
+
+Timing ExecutionCallback::getTiming() const {
+ wait();
+ return mTiming;
+}
+
+void ExecutionCallback::notifyInternal(ErrorStatus errorStatus,
+ const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) {
+ {
+ std::lock_guard<std::mutex> hold(mMutex);
+
+ // quick-return if object has already been notified
+ if (mNotified) {
+ return;
+ }
+
+ mErrorStatus = errorStatus;
+ mOutputShapes = outputShapes;
+ mTiming = timing;
+ mNotified = true;
+ }
+ mCondition.notify_all();
+}
+
+} // namespace android::hardware::neuralnetworks::V1_2::implementation
diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
index 0ac4738fff..2130a76b75 100644
--- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
@@ -45,15 +45,12 @@ namespace generated_tests::mobilenet_quantized {
const test_helper::TestModel& get_test_model();
} // namespace generated_tests::mobilenet_quantized
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using namespace test_helper;
+using implementation::PreparedModelCallback;
using V1_0::ErrorStatus;
using V1_1::ExecutionPreference;
-using V1_2::Constant;
-using V1_2::IPreparedModel;
-using V1_2::OperationType;
-using V1_2::implementation::PreparedModelCallback;
namespace float32_model {
@@ -305,7 +302,7 @@ class CompilationCachingTestBase : public testing::Test {
// See if the service can handle the model.
bool isModelFullySupported(const Model& model) {
bool fullySupportsModel = false;
- Return<void> supportedCall = kDevice->getSupportedOperations_1_3(
+ Return<void> supportedCall = kDevice->getSupportedOperations_1_2(
model,
[&fullySupportsModel, &model](ErrorStatus status, const hidl_vec<bool>& supported) {
ASSERT_EQ(ErrorStatus::NONE, status);
@@ -326,7 +323,7 @@ class CompilationCachingTestBase : public testing::Test {
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
hidl_array<uint8_t, sizeof(mToken)> cacheToken(mToken);
Return<ErrorStatus> prepareLaunchStatus =
- kDevice->prepareModel_1_3(model, ExecutionPreference::FAST_SINGLE_ANSWER,
+ kDevice->prepareModel_1_2(model, ExecutionPreference::FAST_SINGLE_ANSWER,
modelCache, dataCache, cacheToken, preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(static_cast<ErrorStatus>(prepareLaunchStatus), ErrorStatus::NONE);
@@ -1374,4 +1371,4 @@ INSTANTIATE_TEST_CASE_P(TestCompilationCaching, CompilationCachingSecurityTest,
testing::Range(0U, 10U)),
printCompilationCachingSecurityTest);
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
index 16a7d70fb5..2beec983e0 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp
@@ -27,9 +27,6 @@
#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
-#include <android/hardware/neuralnetworks/1.2/types.h>
-#include <android/hardware/neuralnetworks/1.3/IDevice.h>
-#include <android/hardware/neuralnetworks/1.3/types.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
@@ -47,24 +44,17 @@
#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using namespace test_helper;
using hidl::memory::V1_0::IMemory;
+using implementation::ExecutionCallback;
+using implementation::PreparedModelCallback;
using V1_0::DataLocation;
using V1_0::ErrorStatus;
using V1_0::OperandLifeTime;
using V1_0::Request;
using V1_1::ExecutionPreference;
-using V1_2::Constant;
-using V1_2::IPreparedModel;
-using V1_2::MeasureTiming;
-using V1_2::OperationType;
-using V1_2::OutputShape;
-using V1_2::SymmPerChannelQuantParams;
-using V1_2::Timing;
-using V1_2::implementation::ExecutionCallback;
-using V1_2::implementation::PreparedModelCallback;
using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
@@ -415,4 +405,4 @@ INSTANTIATE_GENERATED_TEST(GeneratedTest,
INSTANTIATE_GENERATED_TEST(DynamicOutputShapeTest,
[](const TestModel& testModel) { return !testModel.expectFailure; });
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
index b9277cfd4a..dfc980c169 100644
--- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
+++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.h
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_3_GENERATED_TEST_HARNESS_H
-#define ANDROID_HARDWARE_NEURALNETWORKS_V1_3_GENERATED_TEST_HARNESS_H
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_H
+#include <android/hardware/neuralnetworks/1.2/IDevice.h>
#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
-#include <android/hardware/neuralnetworks/1.3/IDevice.h>
-#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
#include <functional>
#include <vector>
#include "1.0/Utils.h"
#include "TestHarness.h"
#include "VtsHalNeuralnetworks.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using NamedModel = Named<const test_helper::TestModel*>;
using GeneratedTestParam = std::tuple<NamedDevice, NamedModel>;
@@ -55,12 +55,11 @@ class ValidationTest : public GeneratedTestBase {};
Model createModel(const test_helper::TestModel& testModel);
-void PrepareModel(const sp<IDevice>& device, const Model& model,
- sp<V1_2::IPreparedModel>* preparedModel);
+void PrepareModel(const sp<IDevice>& device, const Model& model, sp<IPreparedModel>* preparedModel);
-void EvaluatePreparedModel(const sp<V1_2::IPreparedModel>& preparedModel,
+void EvaluatePreparedModel(const sp<IPreparedModel>& preparedModel,
const test_helper::TestModel& testModel, bool testDynamicOutputShape);
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
-#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_3_GENERATED_TEST_HARNESS_H
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_GENERATED_TEST_HARNESS_H
diff --git a/neuralnetworks/1.3/vts/functional/TestAssertions.cpp b/neuralnetworks/1.3/vts/functional/TestAssertions.cpp
index 7361078eca..a0aa3c37d1 100644
--- a/neuralnetworks/1.3/vts/functional/TestAssertions.cpp
+++ b/neuralnetworks/1.3/vts/functional/TestAssertions.cpp
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
#include "TestHarness.h"
-namespace android::hardware::neuralnetworks::V1_3 {
+namespace android::hardware::neuralnetworks::V1_2 {
// Make sure that the HIDL enums are compatible with the values defined in
// frameworks/ml/nn/tools/test_generator/test_harness/include/TestHarness.h.
@@ -25,8 +25,6 @@ using namespace test_helper;
#define CHECK_TEST_ENUM(EnumType, enumValue) \
static_assert(static_cast<EnumType>(Test##EnumType::enumValue) == EnumType::enumValue)
-using V1_2::OperationType;
-
CHECK_TEST_ENUM(OperandType, FLOAT32);
CHECK_TEST_ENUM(OperandType, INT32);
CHECK_TEST_ENUM(OperandType, UINT32);
@@ -41,7 +39,6 @@ CHECK_TEST_ENUM(OperandType, FLOAT16);
CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_SYMM_PER_CHANNEL);
CHECK_TEST_ENUM(OperandType, TENSOR_QUANT16_ASYMM);
CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_SYMM);
-CHECK_TEST_ENUM(OperandType, TENSOR_QUANT8_ASYMM_SIGNED);
CHECK_TEST_ENUM(OperationType, ADD);
CHECK_TEST_ENUM(OperationType, AVERAGE_POOL_2D);
@@ -141,4 +138,4 @@ CHECK_TEST_ENUM(OperationType, RESIZE_NEAREST_NEIGHBOR);
#undef CHECK_TEST_ENUM
-} // namespace android::hardware::neuralnetworks::V1_3
+} // namespace android::hardware::neuralnetworks::V1_2
diff --git a/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp b/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
index 95f9f427b2..1d4493d208 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateBurst.cpp
@@ -28,20 +28,13 @@
#include <android-base/logging.h>
#include <cstring>
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using nn::ExecutionBurstController;
using nn::RequestChannelSender;
using nn::ResultChannelReceiver;
using V1_0::ErrorStatus;
using V1_0::Request;
-using V1_2::FmqRequestDatum;
-using V1_2::FmqResultDatum;
-using V1_2::IBurstCallback;
-using V1_2::IBurstContext;
-using V1_2::IPreparedModel;
-using V1_2::MeasureTiming;
-using V1_2::Timing;
using ExecutionBurstCallback = ExecutionBurstController::ExecutionBurstCallback;
// This constant value represents the length of an FMQ that is large enough to
@@ -404,4 +397,4 @@ void validateBurst(const sp<IPreparedModel>& preparedModel, const Request& reque
ASSERT_NO_FATAL_FAILURE(validateBurstSanitized(preparedModel, request));
}
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
index 44b32a9fec..30530beacc 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp
@@ -21,26 +21,21 @@
#include "GeneratedTestHarness.h"
#include "VtsHalNeuralnetworks.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
+using implementation::PreparedModelCallback;
using V1_0::ErrorStatus;
using V1_0::OperandLifeTime;
using V1_1::ExecutionPreference;
-using V1_2::IPreparedModel;
-using V1_2::OperationType;
-using V1_2::OperationTypeRange;
-using V1_2::SymmPerChannelQuantParams;
-using V1_2::implementation::PreparedModelCallback;
-using HidlToken =
- hidl_array<uint8_t, static_cast<uint32_t>(V1_2::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
static void validateGetSupportedOperations(const sp<IDevice>& device, const std::string& message,
const Model& model) {
- SCOPED_TRACE(message + " [getSupportedOperations_1_3]");
+ SCOPED_TRACE(message + " [getSupportedOperations_1_2]");
- Return<void> ret = device->getSupportedOperations_1_3(
+ Return<void> ret = device->getSupportedOperations_1_2(
model, [&](ErrorStatus status, const hidl_vec<bool>&) {
EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status);
});
@@ -49,11 +44,11 @@ static void validateGetSupportedOperations(const sp<IDevice>& device, const std:
static void validatePrepareModel(const sp<IDevice>& device, const std::string& message,
const Model& model, ExecutionPreference preference) {
- SCOPED_TRACE(message + " [prepareModel_1_3]");
+ SCOPED_TRACE(message + " [prepareModel_1_2]");
sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
Return<ErrorStatus> prepareLaunchStatus =
- device->prepareModel_1_3(model, preference, hidl_vec<hidl_handle>(),
+ device->prepareModel_1_2(model, preference, hidl_vec<hidl_handle>(),
hidl_vec<hidl_handle>(), HidlToken(), preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast<ErrorStatus>(prepareLaunchStatus));
@@ -715,4 +710,4 @@ void validateModel(const sp<IDevice>& device, const Model& model) {
mutateExecutionPreferenceTest(device, model);
}
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
index 612212382c..f25ee62617 100644
--- a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp
@@ -24,15 +24,11 @@
#include "Utils.h"
#include "VtsHalNeuralnetworks.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
+using implementation::ExecutionCallback;
using V1_0::ErrorStatus;
using V1_0::Request;
-using V1_2::IPreparedModel;
-using V1_2::MeasureTiming;
-using V1_2::OutputShape;
-using V1_2::Timing;
-using V1_2::implementation::ExecutionCallback;
///////////////////////// UTILITY FUNCTIONS /////////////////////////
@@ -169,4 +165,4 @@ void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const Reque
ASSERT_TRUE(executeStatus.isOk());
}
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
index 4f0e150b32..4fbd0e270f 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp
@@ -26,15 +26,13 @@
#include "GeneratedTestHarness.h"
#include "TestHarness.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
-using HidlToken =
- hidl_array<uint8_t, static_cast<uint32_t>(V1_2::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
+using implementation::PreparedModelCallback;
+using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>;
using V1_0::ErrorStatus;
using V1_0::Request;
using V1_1::ExecutionPreference;
-using V1_2::IPreparedModel;
-using V1_2::implementation::PreparedModelCallback;
// internal helper function
void createPreparedModel(const sp<IDevice>& device, const Model& model,
@@ -44,7 +42,7 @@ void createPreparedModel(const sp<IDevice>& device, const Model& model,
// see if service can handle model
bool fullySupportsModel = false;
- const Return<void> supportedCall = device->getSupportedOperations_1_3(
+ const Return<void> supportedCall = device->getSupportedOperations_1_2(
model, [&fullySupportsModel](ErrorStatus status, const hidl_vec<bool>& supported) {
ASSERT_EQ(ErrorStatus::NONE, status);
ASSERT_NE(0ul, supported.size());
@@ -55,7 +53,7 @@ void createPreparedModel(const sp<IDevice>& device, const Model& model,
// launch prepare model
const sp<PreparedModelCallback> preparedModelCallback = new PreparedModelCallback();
- const Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_3(
+ const Return<ErrorStatus> prepareLaunchStatus = device->prepareModel_1_2(
model, ExecutionPreference::FAST_SINGLE_ANSWER, hidl_vec<hidl_handle>(),
hidl_vec<hidl_handle>(), HidlToken(), preparedModelCallback);
ASSERT_TRUE(prepareLaunchStatus.isOk());
@@ -66,8 +64,8 @@ void createPreparedModel(const sp<IDevice>& device, const Model& model,
const ErrorStatus prepareReturnStatus = preparedModelCallback->getStatus();
*preparedModel = getPreparedModel_1_2(preparedModelCallback);
- // The getSupportedOperations_1_3 call returns a list of operations that are
- // guaranteed not to fail if prepareModel_1_3 is called, and
+ // The getSupportedOperations_1_2 call returns a list of operations that are
+ // guaranteed not to fail if prepareModel_1_2 is called, and
// 'fullySupportsModel' is true i.f.f. the entire model is guaranteed.
// If a driver has any doubt that it can prepare an operation, it must
// return false. So here, if a driver isn't sure if it can support an
@@ -165,9 +163,9 @@ TEST_P(ValidationTest, Test) {
INSTANTIATE_GENERATED_TEST(ValidationTest, [](const test_helper::TestModel&) { return true; });
-sp<IPreparedModel> getPreparedModel_1_2(const sp<PreparedModelCallback>& callback) {
+sp<IPreparedModel> getPreparedModel_1_2(const sp<implementation::PreparedModelCallback>& callback) {
sp<V1_0::IPreparedModel> preparedModelV1_0 = callback->getPreparedModel();
return IPreparedModel::castFrom(preparedModelV1_0).withDefault(nullptr);
}
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
index fc654ce8f0..d01336eccd 100644
--- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.h
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_3_VTS_HAL_NEURALNETWORKS_H
-#define ANDROID_HARDWARE_NEURALNETWORKS_V1_3_VTS_HAL_NEURALNETWORKS_H
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
+#include <android/hardware/neuralnetworks/1.2/IDevice.h>
#include <android/hardware/neuralnetworks/1.2/IPreparedModel.h>
-#include <android/hardware/neuralnetworks/1.3/IDevice.h>
-#include <android/hardware/neuralnetworks/1.3/types.h>
+#include <android/hardware/neuralnetworks/1.2/types.h>
#include <gtest/gtest.h>
#include "1.0/Utils.h"
#include "1.2/Callbacks.h"
-namespace android::hardware::neuralnetworks::V1_3::vts::functional {
+namespace android::hardware::neuralnetworks::V1_2::vts::functional {
using NamedDevice = Named<sp<IDevice>>;
using NeuralnetworksHidlTestParam = NamedDevice;
@@ -47,12 +47,11 @@ std::string printNeuralnetworksHidlTest(
// Create an IPreparedModel object. If the model cannot be prepared,
// "preparedModel" will be nullptr instead.
void createPreparedModel(const sp<IDevice>& device, const Model& model,
- sp<V1_2::IPreparedModel>* preparedModel);
+ sp<IPreparedModel>* preparedModel);
// Utility function to get PreparedModel from callback and downcast to V1_2.
-sp<V1_2::IPreparedModel> getPreparedModel_1_2(
- const sp<V1_2::implementation::PreparedModelCallback>& callback);
+sp<IPreparedModel> getPreparedModel_1_2(const sp<implementation::PreparedModelCallback>& callback);
-} // namespace android::hardware::neuralnetworks::V1_3::vts::functional
+} // namespace android::hardware::neuralnetworks::V1_2::vts::functional
-#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_3_VTS_HAL_NEURALNETWORKS_H
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_VTS_HAL_NEURALNETWORKS_H
diff --git a/neuralnetworks/1.3/vts/functional/include/1.2/Callbacks.h b/neuralnetworks/1.3/vts/functional/include/1.2/Callbacks.h
new file mode 100644
index 0000000000..bf4792cc6b
--- /dev/null
+++ b/neuralnetworks/1.3/vts/functional/include/1.2/Callbacks.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_CALLBACKS_H
+#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_CALLBACKS_H
+
+#include <android-base/thread_annotations.h>
+#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IExecutionCallback.h>
+#include <android/hardware/neuralnetworks/1.2/IPreparedModelCallback.h>
+#include <hidl/Status.h>
+#include <condition_variable>
+#include <mutex>
+
+/*
+ * The Callback classes are used internally by the NeuralNetworks runtime to
+ * synchronize between different threads. An asynchronous task is launched
+ * paired with a callback object. When a client thread requires the output being
+ * generated by the asynchronous task, the client thread can wait for the result
+ * and be blocked until it has completed. Any wait may safely be called
+ * concurrently, even on the same callback object. When the asynchronous task
+ * has finished its workload, it must immediately call "notify*". If the
+ * asynchronous task has failed to launch, the function that tried to launch the
+ * asynchronous task must immediately call "notify*". This "notify*" call
+ * awakens any client threads waiting on the callback object.
+ *
+ * These classes exist to enable synchronization across HIDL. When
+ * synchronization is only required in the same process, consider using
+ * std::future, std::mutex, std::condition_variable, or std::experimental::latch
+ * instead.
+ */
+
+namespace android::hardware::neuralnetworks::V1_2::implementation {
+
+/**
+ * The PreparedModelCallback class is used to receive the error status of
+ * preparing a model as well as the prepared model from a task executing
+ * asynchronously with respect to the runtime. If a calling thread calls wait
+ * or get* on a PreparedModelCallback object and the corresponding asynchronous
+ * task has not finished preparing the model, the calling thread will block
+ * until the asynchronous task has either called notify or notify_1_2.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify* are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IDevice::prepareModel*.
+ */
+class PreparedModelCallback : public IPreparedModelCallback {
+ public:
+ /**
+ * IPreparedModelCallback::notify marks the callback object with the return
+ * status of the asynchronous model preparation along with the prepared
+ * model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * Either IPreparedModelCallback::notify or
+ * IPreparedModelCallback::notify_1_2 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @param preparedModel Returned model that has been prepared for execution,
+ * nullptr if the model was unable to be prepared.
+ */
+ Return<void> notify(V1_0::ErrorStatus status,
+ const sp<V1_0::IPreparedModel>& preparedModel) override;
+
+ /**
+ * IPreparedModelCallback::notify_1_2 marks the callback object with the
+ * return status of the asynchronous model preparation along with the
+ * prepared model, and allows all prior and future wait calls on the
+ * PreparedModelCallback object to proceed.
+ *
+ * Either IPreparedModelCallback::notify or
+ * IPreparedModelCallback::notify_1_2 must be called on a given
+ * PreparedModelCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ * @param preparedModel Returned model that has been prepared for execution,
+ * nullptr if the model was unable to be prepared.
+ */
+ Return<void> notify_1_2(V1_0::ErrorStatus status,
+ const sp<V1_2::IPreparedModel>& preparedModel) override;
+
+ /**
+ * PreparedModelCallback::wait blocks until notify* has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by IDevice::prepareModel*. If IDevice::prepareModel* has not finished
+ * asynchronously preparing the model, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * @return status Error status returned from asynchronously preparing the
+ * model; will be:
+ * - NONE if the asynchronous preparation was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - INVALID_ARGUMENT if the input model is invalid
+ */
+ V1_0::ErrorStatus getStatus() const;
+
+ /**
+ * Retrieves the model that has been prepared for execution from the
+ * asynchronous task launched by IDevice::prepareModel*. If
+ * IDevice::prepareModel* has not finished asynchronously preparing the
+ * model, this call will block until the asynchronous task notifies the
+ * object.
+ *
+ * @return preparedModel Returned model that has been prepared for
+ * execution, nullptr if the model was unable to be prepared.
+ */
+ sp<V1_0::IPreparedModel> getPreparedModel() const;
+
+ private:
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ V1_0::ErrorStatus mErrorStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
+ sp<V1_0::IPreparedModel> mPreparedModel;
+};
+
+/**
+ * The ExecutionCallback class is used to receive the results of the execution
+ * from a task executing asynchronously with respect to the runtime. If a
+ * calling thread calls wait or get* on a ExecutionCallback object and the
+ * corresponding asynchronous task has not finished the execution, the calling
+ * thread will block until the asynchronous task has either called notify or
+ * notify_1_2.
+ *
+ * If the callback object is notified more than once, only the results of the
+ * first call to notify* are used, and the results from subsequent calls are
+ * discarded.
+ *
+ * This callback object is passed as an argument to IPreparedModel::execute*.
+ */
+class ExecutionCallback : public IExecutionCallback {
+ public:
+ /**
+ * IExecutionCallback::notify marks the callback object with the return
+ * status of the asynchronous execution that held this callback and enables
+ * all prior and future wait calls on the ExecutionCallback object to
+ * proceed.
+ *
+ * Either IExecutionCallback::notify or IExecutionCallback::notify_1_2 must
+ * be called on a given ExecutionCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is not large
+ * enough to store the resultant values
+ * - INVALID_ARGUMENT if the input request is invalid
+ */
+ Return<void> notify(V1_0::ErrorStatus status) override;
+
+ /**
+ * IExecutionCallback::notify_1_2 marks the callback object with the results
+ * (error status, dynamic output shapes, and timing information) of the
+ * asynchronous execution that held this callback and enables all prior and
+ * future wait calls on the ExecutionCallback object to proceed.
+ *
+ * Either IExecutionCallback::notify or IExecutionCallback::notify_1_2 must
+ * be called on a given ExecutionCallback object.
+ *
+ * If the callback object is notified more than once, only the results of
+ * the first call to notify* are used, and the results from subsequent calls
+ * are discarded.
+ *
+ * @param status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an unspecified
+ * error
+ * - OUTPUT_INSUFFICIENT_SIZE if at least one output operand buffer is
+ * not large enough to store the corresponding output
+ * - INVALID_ARGUMENT if one of the input arguments to prepareModel is
+ * invalid
+ * @param outputShapes A list of shape information of model output operands.
+ * The index into "outputShapes" corresponds to the index of the output
+ * operand in the Request outputs vector. outputShapes must be empty
+ * unless the status is either NONE or OUTPUT_INSUFFICIENT_SIZE.
+ * @param Timing Duration of execution. Unless MeasureTiming::YES was passed
+ * when launching the execution and status is NONE, all times must be
+ * reported as UINT64_MAX. A driver may choose to report any time as
+ * UINT64_MAX, indicating that particular measurement is not available.
+ */
+ Return<void> notify_1_2(V1_0::ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) override;
+
+ // An overload of the latest notify interface to hide the version from ExecutionBuilder.
+ Return<void> notify(V1_0::ErrorStatus status, const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing) {
+ return notify_1_2(status, outputShapes, timing);
+ }
+
+ /**
+ * ExecutionCallback::wait blocks until notify* has been called on the
+ * callback object.
+ */
+ void wait() const;
+
+ /**
+ * Retrieves the error status returned from the asynchronous task launched
+ * by either IPreparedModel::execute or IPreparedModel::execute_1_2. If
+ * IPreparedModel::execute or IPreparedModel::execute_1_2 has not finished
+ * asynchronously executing, this call will block until the asynchronous
+ * task notifies the object.
+ *
+ * @return status Error status returned from launching the asynchronous task
+ * (if the launch fails) or from the asynchronous task itself (if the
+ * launch succeeds). Must be:
+ * - NONE if the asynchronous execution was successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if the asynchronous task resulted in an unspecified
+ * error
+ * - OUTPUT_INSUFFICIENT_SIZE if at least one output operand buffer is
+ * not large enough to store the corresponding output
+ * - INVALID_ARGUMENT if one of the input arguments to prepareModel is
+ * invalid
+ */
+ V1_0::ErrorStatus getStatus() const;
+
+ /**
+ * Retrieves the output shapes returned from the asynchronous task launched
+ * by IPreparedModel::execute_1_2. If IPreparedModel::execute_1_2 has not
+ * finished asynchronously executing, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * If the asynchronous task was launched by IPreparedModel::execute, an
+ * empty vector will be returned.
+ *
+ * @return outputShapes A list of shape information of model output
+ * operands. The index into "outputShapes" corresponds to the index of
+ * the output operand in the Request outputs vector. outputShapes must
+ * be empty unless the status is either NONE or
+ * OUTPUT_INSUFFICIENT_SIZE. outputShaps may be empty if the status is
+ * NONE and all model output operands are fully-specified at execution
+ * time. outputShapes must have the same number of elements as the
+ * number of model output operands if the status is
+ * OUTPUT_INSUFFICIENT_SIZE, or if the status is NONE and the model has
+ * at least one output operand that is not fully-specified.
+ */
+ const std::vector<OutputShape>& getOutputShapes() const;
+
+ /**
+ * Retrieves the duration of execution of the asynchronous task launched by
+ * IPreparedModel::execute_1_2. If IPreparedModel::execute_1_2 has not
+ * finished asynchronously executing, this call will block until the
+ * asynchronous task notifies the object.
+ *
+ * If the asynchronous task was launched by IPreparedModel::execute, every
+ * time must be UINT64_MAX.
+ *
+ * @return timing Duration of the execution. Every time must be UINT64_MAX
+ * unless the status is NONE.
+ */
+ Timing getTiming() const;
+
+ private:
+ /*
+ * ExecutionCallback::notifyInternal stores the results of the execution
+ * (status, output shapes, and timing information) in the ExecutionCallback
+ * object before any call to wait or get* return. It then enables all prior
+ * and future wait calls on the ExecutionCallback object to proceed.
+ */
+ void notifyInternal(V1_0::ErrorStatus errorStatus, const hidl_vec<OutputShape>& outputShapes,
+ const Timing& timing);
+
+ // members
+ mutable std::mutex mMutex;
+ mutable std::condition_variable mCondition;
+ bool mNotified GUARDED_BY(mMutex) = false;
+ V1_0::ErrorStatus mErrorStatus = V1_0::ErrorStatus::GENERAL_FAILURE;
+ std::vector<OutputShape> mOutputShapes = {};
+ Timing mTiming = {};
+};
+
+} // namespace android::hardware::neuralnetworks::V1_2::implementation
+
+#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_CALLBACKS_H