From a96ab7407df1945ab377d3fe510c377a7895ffda Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Tue, 11 Feb 2020 14:27:02 +0000 Subject: [PATCH] Add NNAPI loop timeout API Bug: 145906499 Bug: 136735929 Test: NNT_static Change-Id: Ie40c248b174964676985403f9f1a5127b408a00a Merged-In: Ie40c248b174964676985403f9f1a5127b408a00a (cherry picked from commit f034bf9c9225cb82dab9dc7e3398915e88133df6) --- current.txt | 4 +- neuralnetworks/1.3/IPreparedModel.hal | 41 +++++++++++++++++-- neuralnetworks/1.3/types.hal | 11 +++++ neuralnetworks/1.3/types.t | 11 +++++ .../vts/functional/GeneratedTestHarness.cpp | 6 +-- .../vts/functional/QualityOfServiceTests.cpp | 4 +- .../1.3/vts/functional/ValidateRequest.cpp | 8 ++-- .../vts/functional/VtsHalNeuralnetworks.cpp | 2 +- 8 files changed, 72 insertions(+), 15 deletions(-) diff --git a/current.txt b/current.txt index bcba882857..3e09aa309c 100644 --- a/current.txt +++ b/current.txt @@ -628,9 +628,9 @@ ddcf89cd8ee2df0d32aee55050826446fb64f7aafde0a7cd946c64f61b1a364c android.hardwar 9db064ee44268a876be0367ff771e618362d39ec603b6ecab17e1575725fcd87 android.hardware.neuralnetworks@1.3::IDevice 4167dc3ad35e9cd0d2057d4868c7675ae2c3c9d05bbd614c1f5dccfa5fd68797 android.hardware.neuralnetworks@1.3::IExecutionCallback 2fa3679ad7c94b5e88724adcd560c561041068a4ca565c63830e68101988746a android.hardware.neuralnetworks@1.3::IFencedExecutionCallback -237b23b126a66f3432658020fed78cdd06ba6297459436fe6bae0ba753370833 android.hardware.neuralnetworks@1.3::IPreparedModel +43088ffc71945b463a7279262cfe2e290f6ed2f15d3fd6032798a3be299fb08f android.hardware.neuralnetworks@1.3::IPreparedModel 0439a1fbbec7f16e5e4c653d85ac685d51bfafbae15b8f8cca530acdd7d6a8ce android.hardware.neuralnetworks@1.3::IPreparedModelCallback -5e2a14b40dc11da9d478185838f4401b652739922d14cecea0a0ce4c1359fe21 android.hardware.neuralnetworks@1.3::types +306fda32ac969fd51d75d066352cadcb769944ec4823be4cdd3f86fdb9e97511 android.hardware.neuralnetworks@1.3::types 3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant 44445b8a03d7b9e68b2fbd954672c18a8fce9e32851b0692f4f4ab3407f86ecb android.hardware.wifi.supplicant@1.3::ISupplicantStaIface diff --git a/neuralnetworks/1.3/IPreparedModel.hal b/neuralnetworks/1.3/IPreparedModel.hal index d645de789c..4ce3691d14 100644 --- a/neuralnetworks/1.3/IPreparedModel.hal +++ b/neuralnetworks/1.3/IPreparedModel.hal @@ -92,6 +92,17 @@ interface IPreparedModel extends @1.2::IPreparedModel { * @param deadline The time by which the execution must complete. If the * execution cannot be finished by the deadline, the * execution must be aborted. + * @param loopTimeoutDuration The maximum amount of time that should be spent + * executing a {@link OperationType::WHILE} + * operation. If a loop condition model does not + * output false within this duration, the + * execution must be aborted. If the model + * contains a {@link OperationType::WHILE} + * operation and no loop timeout duration is + * provided, the maximum amount of time is {@link + * LoopTimeoutDurationNs::DEFAULT}. When + * provided, the duration must not exceed {@link + * LoopTimeoutDurationNs::MAXIMUM}. * @param callback A callback object used to return the error status of * the execution, shape information of model output operands, and * duration of execution. The callback object's notify function must @@ -111,7 +122,7 @@ interface IPreparedModel extends @1.2::IPreparedModel { * driver */ execute_1_3(Request request, MeasureTiming measure, OptionalTimePoint deadline, - IExecutionCallback callback) + OptionalTimeoutDuration loopTimeoutDuration, IExecutionCallback callback) generates (ErrorStatus status); /** @@ -163,6 +174,17 @@ interface IPreparedModel extends @1.2::IPreparedModel { * @param deadline The time by which the execution must complete. If the * execution cannot be finished by the deadline, the * execution must be aborted. + * @param loopTimeoutDuration The maximum amount of time that should be spent + * executing a {@link OperationType::WHILE} + * operation. If a loop condition model does not + * output false within this duration, the + * execution must be aborted. If the model + * contains a {@link OperationType::WHILE} + * operation and no loop timeout duration is + * provided, the maximum amount of time is {@link + * LoopTimeoutDurationNs::DEFAULT}. When + * provided, the duration must not exceed {@link + * LoopTimeoutDurationNs::MAXIMUM}. * @return status Error status of the execution, must be: * - NONE if execution is performed successfully * - DEVICE_UNAVAILABLE if driver is offline or busy @@ -187,7 +209,8 @@ interface IPreparedModel extends @1.2::IPreparedModel { * measurement is not available. */ executeSynchronously_1_3(Request request, MeasureTiming measure, - OptionalTimePoint deadline) + OptionalTimePoint deadline, + OptionalTimeoutDuration loopTimeoutDuration) generates (ErrorStatus status, vec outputShapes, Timing timing); @@ -243,6 +266,17 @@ interface IPreparedModel extends @1.2::IPreparedModel { * @param deadline The time by which the execution must complete. If the * execution cannot be finished by the deadline, the * execution must be aborted. + * @param loopTimeoutDuration The maximum amount of time that should be spent + * executing a {@link OperationType::WHILE} + * operation. If a loop condition model does not + * output false within this duration, the + * execution must be aborted. If the model + * contains a {@link OperationType::WHILE} + * operation and no loop timeout duration is + * provided, the maximum amount of time is {@link + * LoopTimeoutDurationNs::DEFAULT}. When + * provided, the duration must not exceed {@link + * LoopTimeoutDurationNs::MAXIMUM}. * @param duration The length of time within which the execution must * complete after all sync fences in waitFor are signaled. If the * execution cannot be finished within the duration, the execution @@ -264,6 +298,7 @@ interface IPreparedModel extends @1.2::IPreparedModel { * and error status when the execution is completed. */ executeFenced(Request request, vec waitFor, MeasureTiming measure, - OptionalTimePoint deadline, OptionalTimeoutDuration duration) + OptionalTimePoint deadline, OptionalTimeoutDuration loopTimeoutDuration, + OptionalTimeoutDuration duration) generates (ErrorStatus status, handle syncFence, IFencedExecutionCallback callback); }; diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal index 8ee867c676..a808a2e512 100644 --- a/neuralnetworks/1.3/types.hal +++ b/neuralnetworks/1.3/types.hal @@ -5671,3 +5671,14 @@ enum ErrorStatus : @1.0::ErrorStatus { */ RESOURCE_EXHAUSTED_PERSISTENT, }; + +/** + * Each {@link OperationType::WHILE} operation in the model has an implicit + * execution timeout duration associated with it ("loop timeout duration"). + * This duration is configurable on a per-execution basis and must not exceed + * 15 seconds. The default value is 2 seconds. + */ +enum LoopTimeoutDurationNs : uint64_t { + DEFAULT = 2000000000, + MAXIMUM = 15000000000, +}; diff --git a/neuralnetworks/1.3/types.t b/neuralnetworks/1.3/types.t index c663a60dee..0a6e45e487 100644 --- a/neuralnetworks/1.3/types.t +++ b/neuralnetworks/1.3/types.t @@ -598,3 +598,14 @@ enum ErrorStatus : @1.0::ErrorStatus { */ RESOURCE_EXHAUSTED_PERSISTENT, }; + +/** + * Each {@link OperationType::WHILE} operation in the model has an implicit + * execution timeout duration associated with it ("loop timeout duration"). + * This duration is configurable on a per-execution basis and must not exceed + * 15 seconds. The default value is 2 seconds. + */ +enum LoopTimeoutDurationNs : uint64_t { + DEFAULT = 2000000000, + MAXIMUM = 15000000000, +}; diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp index 404c2a1e03..89edfb713c 100644 --- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp @@ -496,7 +496,7 @@ static std::vector getOutputBuffers(const TestModel& testModel, cons static Return ExecutePreparedModel(const sp& preparedModel, const Request& request, MeasureTiming measure, sp& callback) { - return preparedModel->execute_1_3(request, measure, {}, callback); + return preparedModel->execute_1_3(request, measure, {}, {}, callback); } static Return ExecutePreparedModel(const sp& preparedModel, const Request& request, MeasureTiming measure, @@ -504,7 +504,7 @@ static Return ExecutePreparedModel(const sp& prepar Timing* timing) { ErrorStatus result; Return ret = preparedModel->executeSynchronously_1_3( - request, measure, {}, + request, measure, {}, {}, [&result, outputShapes, timing](ErrorStatus error, const hidl_vec& shapes, const Timing& time) { result = error; @@ -612,7 +612,7 @@ void EvaluatePreparedModel(const sp& device, const sp& hidl_handle syncFenceHandle; sp fencedCallback; Return ret = preparedModel->executeFenced( - request, {}, testConfig.measureTiming, {}, {}, + request, {}, testConfig.measureTiming, {}, {}, {}, [&result, &syncFenceHandle, &fencedCallback]( ErrorStatus error, const hidl_handle& handle, const sp& callback) { diff --git a/neuralnetworks/1.3/vts/functional/QualityOfServiceTests.cpp b/neuralnetworks/1.3/vts/functional/QualityOfServiceTests.cpp index 8271135344..fccc612574 100644 --- a/neuralnetworks/1.3/vts/functional/QualityOfServiceTests.cpp +++ b/neuralnetworks/1.3/vts/functional/QualityOfServiceTests.cpp @@ -171,7 +171,7 @@ static MaybeResults executeAsynchronously(const sp& preparedMode // launch execution const sp callback = new ExecutionCallback(); - Return ret = preparedModel->execute_1_3(request, measure, deadline, callback); + Return ret = preparedModel->execute_1_3(request, measure, deadline, {}, callback); EXPECT_TRUE(ret.isOk()); EXPECT_EQ(ErrorStatus::NONE, ret.withDefault(ErrorStatus::GENERAL_FAILURE)); if (!ret.isOk() || ret != ErrorStatus::NONE) return std::nullopt; @@ -198,7 +198,7 @@ static MaybeResults executeSynchronously(const sp& preparedModel // run execution const Return ret = - preparedModel->executeSynchronously_1_3(request, measure, deadline, cb); + preparedModel->executeSynchronously_1_3(request, measure, deadline, {}, cb); EXPECT_TRUE(ret.isOk()); if (!ret.isOk()) return std::nullopt; diff --git a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp index 2a4269f3d4..20f4fe2c00 100644 --- a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp +++ b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp @@ -70,7 +70,7 @@ static void validate(const sp& preparedModel, const std::string& sp executionCallback = new ExecutionCallback(); Return executeLaunchStatus = - preparedModel->execute_1_3(request, measure, deadline, executionCallback); + preparedModel->execute_1_3(request, measure, deadline, {}, executionCallback); ASSERT_TRUE(executeLaunchStatus.isOk()); ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, static_cast(executeLaunchStatus)); @@ -88,7 +88,7 @@ static void validate(const sp& preparedModel, const std::string& SCOPED_TRACE(message + " [executeSynchronously_1_3]"); Return executeStatus = preparedModel->executeSynchronously_1_3( - request, measure, deadline, + request, measure, deadline, {}, [](ErrorStatus error, const hidl_vec& outputShapes, const Timing& timing) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); @@ -143,7 +143,7 @@ static void validate(const sp& preparedModel, const std::string& { SCOPED_TRACE(message + " [executeFenced]"); Return ret = - preparedModel->executeFenced(request, {}, MeasureTiming::NO, deadline, {}, + preparedModel->executeFenced(request, {}, MeasureTiming::NO, deadline, {}, {}, [](ErrorStatus error, const hidl_handle& handle, const sp& callback) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error); @@ -196,7 +196,7 @@ void validateRequest(const sp& preparedModel, const Request& req void validateRequestFailure(const sp& preparedModel, const Request& request) { SCOPED_TRACE("Expecting request to fail [executeSynchronously_1_3]"); Return executeStatus = preparedModel->executeSynchronously_1_3( - request, MeasureTiming::NO, {}, + request, MeasureTiming::NO, {}, {}, [](ErrorStatus error, const hidl_vec& outputShapes, const Timing& timing) { ASSERT_NE(ErrorStatus::NONE, error); EXPECT_EQ(outputShapes.size(), 0); diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp index 9a87569b46..16341dafc7 100644 --- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp +++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp @@ -137,7 +137,7 @@ void validateBurst(const sp& preparedModel, const V1_0::Request& void validateExecuteFenced(const sp& preparedModel, const Request& request) { SCOPED_TRACE("Expecting request to fail [executeFenced]"); Return ret_null = preparedModel->executeFenced( - request, {hidl_handle(nullptr)}, V1_2::MeasureTiming::NO, {}, {}, + request, {hidl_handle(nullptr)}, V1_2::MeasureTiming::NO, {}, {}, {}, [](ErrorStatus error, const hidl_handle& handle, const sp& callback) { ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, error);