Loading neuralnetworks/1.3/vts/functional/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ cc_test { "libhidlmemory", "libneuralnetworks_generated_test_harness", "libneuralnetworks_utils", "libsync", ], whole_static_libs: [ "neuralnetworks_generated_V1_0_example", Loading neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp +43 −3 Original line number Diff line number Diff line Loading @@ -29,11 +29,13 @@ #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/IFencedExecutionCallback.h> #include <android/hardware/neuralnetworks/1.3/IPreparedModel.h> #include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.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 <android/sync.h> #include <gtest/gtest.h> #include <hidlmemory/mapping.h> Loading Loading @@ -70,7 +72,7 @@ using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_ namespace { enum class Executor { ASYNC, SYNC, BURST }; enum class Executor { ASYNC, SYNC, BURST, FENCED }; enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT }; Loading Loading @@ -562,6 +564,43 @@ void EvaluatePreparedModel(const sp<IDevice>& device, const sp<IPreparedModel>& break; } case Executor::FENCED: { SCOPED_TRACE("fenced"); ErrorStatus result; hidl_handle sync_fence_handle; sp<IFencedExecutionCallback> fenced_callback; Return<void> ret = preparedModel->executeFenced( request, {}, testConfig.measureTiming, [&result, &sync_fence_handle, &fenced_callback]( ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { result = error; sync_fence_handle = handle; fenced_callback = callback; }); ASSERT_TRUE(ret.isOk()); if (result != ErrorStatus::NONE) { ASSERT_EQ(sync_fence_handle.getNativeHandle(), nullptr); ASSERT_EQ(fenced_callback, nullptr); executionStatus = ErrorStatus::GENERAL_FAILURE; } else if (sync_fence_handle.getNativeHandle()) { constexpr int kInfiniteTimeout = -1; int sync_fd = sync_fence_handle.getNativeHandle()->data[0]; ASSERT_GT(sync_fd, 0); int r = sync_wait(sync_fd, kInfiniteTimeout); ASSERT_GE(r, 0); } if (result == ErrorStatus::NONE) { ASSERT_NE(fenced_callback, nullptr); Return<void> ret = fenced_callback->getExecutionInfo( [&executionStatus, &timing](ErrorStatus error, Timing t) { executionStatus = error; timing = t; }); ASSERT_TRUE(ret.isOk()); } break; } } if (testConfig.outputType != OutputType::FULLY_SPECIFIED && Loading Loading @@ -635,7 +674,7 @@ void EvaluatePreparedModel(const sp<IDevice>& device, const sp<IPreparedModel>& case TestKind::GENERAL: { outputTypesList = {OutputType::FULLY_SPECIFIED}; measureTimingList = {MeasureTiming::NO, MeasureTiming::YES}; executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST}; executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST, Executor::FENCED}; } break; case TestKind::DYNAMIC_SHAPE: { outputTypesList = {OutputType::UNSPECIFIED, OutputType::INSUFFICIENT}; Loading Loading @@ -671,7 +710,8 @@ void EvaluatePreparedCoupledModels(const sp<IDevice>& device, const TestModel& coupledModel) { const std::vector<OutputType> outputTypesList = {OutputType::FULLY_SPECIFIED}; const std::vector<MeasureTiming> measureTimingList = {MeasureTiming::NO, MeasureTiming::YES}; const std::vector<Executor> executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST}; const std::vector<Executor> executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST, Executor::FENCED}; for (const OutputType outputType : outputTypesList) { for (const MeasureTiming measureTiming : measureTimingList) { Loading neuralnetworks/1.3/vts/functional/ValidateRequest.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ #define LOG_TAG "neuralnetworks_hidl_hal_test" #include <android/hardware/neuralnetworks/1.3/IFencedExecutionCallback.h> #include <chrono> #include "1.0/Utils.h" #include "1.3/Callbacks.h" #include "ExecutionBurstController.h" Loading Loading @@ -136,6 +138,22 @@ static void validate(const sp<IPreparedModel>& preparedModel, const std::string& burst->freeMemory(keys.front()); } } // dispatch { SCOPED_TRACE(message + " [executeFenced]"); Return<void> ret = preparedModel->executeFenced( request, {}, MeasureTiming::NO, [](ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { if (error != ErrorStatus::DEVICE_UNAVAILABLE) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); } ASSERT_EQ(handle.getNativeHandle(), nullptr); ASSERT_EQ(callback, nullptr); }); ASSERT_TRUE(ret.isOk()); } } ///////////////////////// REMOVE INPUT //////////////////////////////////// Loading neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,35 @@ void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const Reque // Forward declaration from ValidateBurst.cpp void validateBurst(const sp<IPreparedModel>& preparedModel, const V1_0::Request& request); // Validate sync_fence handles for dispatch with valid input void validateExecuteFenced(const sp<IPreparedModel>& preparedModel, const Request& request) { SCOPED_TRACE("Expecting request to fail [executeFenced]"); Return<void> ret_null = preparedModel->executeFenced(request, {hidl_handle(nullptr)}, V1_2::MeasureTiming::NO, [](ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); ASSERT_EQ(handle.getNativeHandle(), nullptr); ASSERT_EQ(callback, nullptr); }); ASSERT_TRUE(ret_null.isOk()); native_handle_t* nativeHandle = native_handle_create(1, 0); ASSERT_NE(nullptr, nativeHandle); nativeHandle->data[0] = -1; hidl_handle hidlHandle; hidlHandle.setTo(nativeHandle, /*shouldOwn=*/true); Return<void> ret_invalid = preparedModel->executeFenced(request, {hidlHandle}, V1_2::MeasureTiming::NO, [](ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); ASSERT_EQ(handle.getNativeHandle(), nullptr); ASSERT_EQ(callback, nullptr); }); ASSERT_TRUE(ret_invalid.isOk()); } void validateEverything(const sp<IDevice>& device, const Model& model, const Request& request, std::pair<bool, bool> supportsDeadlines) { const auto [prepareModelDeadlineSupported, executionDeadlineSupported] = supportsDeadlines; Loading @@ -144,6 +173,7 @@ void validateEverything(const sp<IDevice>& device, const Model& model, const Req if (preparedModel == nullptr) return; validateRequest(preparedModel, request, executionDeadlineSupported); validateExecuteFenced(preparedModel, request); // TODO(butlermichael): Check if we need to test burst in V1_3 if the interface remains V1_2. ASSERT_TRUE(nn::compliantWithV1_0(request)); Loading Loading
neuralnetworks/1.3/vts/functional/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ cc_test { "libhidlmemory", "libneuralnetworks_generated_test_harness", "libneuralnetworks_utils", "libsync", ], whole_static_libs: [ "neuralnetworks_generated_V1_0_example", Loading
neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp +43 −3 Original line number Diff line number Diff line Loading @@ -29,11 +29,13 @@ #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/IFencedExecutionCallback.h> #include <android/hardware/neuralnetworks/1.3/IPreparedModel.h> #include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.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 <android/sync.h> #include <gtest/gtest.h> #include <hidlmemory/mapping.h> Loading Loading @@ -70,7 +72,7 @@ using HidlToken = hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_ namespace { enum class Executor { ASYNC, SYNC, BURST }; enum class Executor { ASYNC, SYNC, BURST, FENCED }; enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT }; Loading Loading @@ -562,6 +564,43 @@ void EvaluatePreparedModel(const sp<IDevice>& device, const sp<IPreparedModel>& break; } case Executor::FENCED: { SCOPED_TRACE("fenced"); ErrorStatus result; hidl_handle sync_fence_handle; sp<IFencedExecutionCallback> fenced_callback; Return<void> ret = preparedModel->executeFenced( request, {}, testConfig.measureTiming, [&result, &sync_fence_handle, &fenced_callback]( ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { result = error; sync_fence_handle = handle; fenced_callback = callback; }); ASSERT_TRUE(ret.isOk()); if (result != ErrorStatus::NONE) { ASSERT_EQ(sync_fence_handle.getNativeHandle(), nullptr); ASSERT_EQ(fenced_callback, nullptr); executionStatus = ErrorStatus::GENERAL_FAILURE; } else if (sync_fence_handle.getNativeHandle()) { constexpr int kInfiniteTimeout = -1; int sync_fd = sync_fence_handle.getNativeHandle()->data[0]; ASSERT_GT(sync_fd, 0); int r = sync_wait(sync_fd, kInfiniteTimeout); ASSERT_GE(r, 0); } if (result == ErrorStatus::NONE) { ASSERT_NE(fenced_callback, nullptr); Return<void> ret = fenced_callback->getExecutionInfo( [&executionStatus, &timing](ErrorStatus error, Timing t) { executionStatus = error; timing = t; }); ASSERT_TRUE(ret.isOk()); } break; } } if (testConfig.outputType != OutputType::FULLY_SPECIFIED && Loading Loading @@ -635,7 +674,7 @@ void EvaluatePreparedModel(const sp<IDevice>& device, const sp<IPreparedModel>& case TestKind::GENERAL: { outputTypesList = {OutputType::FULLY_SPECIFIED}; measureTimingList = {MeasureTiming::NO, MeasureTiming::YES}; executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST}; executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST, Executor::FENCED}; } break; case TestKind::DYNAMIC_SHAPE: { outputTypesList = {OutputType::UNSPECIFIED, OutputType::INSUFFICIENT}; Loading Loading @@ -671,7 +710,8 @@ void EvaluatePreparedCoupledModels(const sp<IDevice>& device, const TestModel& coupledModel) { const std::vector<OutputType> outputTypesList = {OutputType::FULLY_SPECIFIED}; const std::vector<MeasureTiming> measureTimingList = {MeasureTiming::NO, MeasureTiming::YES}; const std::vector<Executor> executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST}; const std::vector<Executor> executorList = {Executor::ASYNC, Executor::SYNC, Executor::BURST, Executor::FENCED}; for (const OutputType outputType : outputTypesList) { for (const MeasureTiming measureTiming : measureTimingList) { Loading
neuralnetworks/1.3/vts/functional/ValidateRequest.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ #define LOG_TAG "neuralnetworks_hidl_hal_test" #include <android/hardware/neuralnetworks/1.3/IFencedExecutionCallback.h> #include <chrono> #include "1.0/Utils.h" #include "1.3/Callbacks.h" #include "ExecutionBurstController.h" Loading Loading @@ -136,6 +138,22 @@ static void validate(const sp<IPreparedModel>& preparedModel, const std::string& burst->freeMemory(keys.front()); } } // dispatch { SCOPED_TRACE(message + " [executeFenced]"); Return<void> ret = preparedModel->executeFenced( request, {}, MeasureTiming::NO, [](ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { if (error != ErrorStatus::DEVICE_UNAVAILABLE) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); } ASSERT_EQ(handle.getNativeHandle(), nullptr); ASSERT_EQ(callback, nullptr); }); ASSERT_TRUE(ret.isOk()); } } ///////////////////////// REMOVE INPUT //////////////////////////////////// Loading
neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,35 @@ void validateRequestFailure(const sp<IPreparedModel>& preparedModel, const Reque // Forward declaration from ValidateBurst.cpp void validateBurst(const sp<IPreparedModel>& preparedModel, const V1_0::Request& request); // Validate sync_fence handles for dispatch with valid input void validateExecuteFenced(const sp<IPreparedModel>& preparedModel, const Request& request) { SCOPED_TRACE("Expecting request to fail [executeFenced]"); Return<void> ret_null = preparedModel->executeFenced(request, {hidl_handle(nullptr)}, V1_2::MeasureTiming::NO, [](ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); ASSERT_EQ(handle.getNativeHandle(), nullptr); ASSERT_EQ(callback, nullptr); }); ASSERT_TRUE(ret_null.isOk()); native_handle_t* nativeHandle = native_handle_create(1, 0); ASSERT_NE(nullptr, nativeHandle); nativeHandle->data[0] = -1; hidl_handle hidlHandle; hidlHandle.setTo(nativeHandle, /*shouldOwn=*/true); Return<void> ret_invalid = preparedModel->executeFenced(request, {hidlHandle}, V1_2::MeasureTiming::NO, [](ErrorStatus error, const hidl_handle& handle, const sp<IFencedExecutionCallback>& callback) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); ASSERT_EQ(handle.getNativeHandle(), nullptr); ASSERT_EQ(callback, nullptr); }); ASSERT_TRUE(ret_invalid.isOk()); } void validateEverything(const sp<IDevice>& device, const Model& model, const Request& request, std::pair<bool, bool> supportsDeadlines) { const auto [prepareModelDeadlineSupported, executionDeadlineSupported] = supportsDeadlines; Loading @@ -144,6 +173,7 @@ void validateEverything(const sp<IDevice>& device, const Model& model, const Req if (preparedModel == nullptr) return; validateRequest(preparedModel, request, executionDeadlineSupported); validateExecuteFenced(preparedModel, request); // TODO(butlermichael): Check if we need to test burst in V1_3 if the interface remains V1_2. ASSERT_TRUE(nn::compliantWithV1_0(request)); Loading