diff options
author | David Gross <dgross@google.com> | 2019-04-08 18:29:00 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-04-08 18:29:00 +0000 |
commit | 92cebc78a042b275a5dac144bd1dc3565750329c (patch) | |
tree | 824c0099ef11ab3e11b832162530b0ad5c6bdc0c /nn/runtime/test/TestValidation.cpp | |
parent | 89a3f062a21e5d0866deabdc7e8e3950351283d3 (diff) | |
parent | 07c3f7520b9062ae68a55372cdefc67c0792c4a0 (diff) | |
download | ml-92cebc78a042b275a5dac144bd1dc3565750329c.tar.gz |
Merge "Finish work on collecting execution duration. Add tests and execution state enforcement."
Diffstat (limited to 'nn/runtime/test/TestValidation.cpp')
-rw-r--r-- | nn/runtime/test/TestValidation.cpp | 351 |
1 files changed, 281 insertions, 70 deletions
diff --git a/nn/runtime/test/TestValidation.cpp b/nn/runtime/test/TestValidation.cpp index c7d8b1298..60c2b43eb 100644 --- a/nn/runtime/test/TestValidation.cpp +++ b/nn/runtime/test/TestValidation.cpp @@ -744,7 +744,7 @@ TEST_F(ValidationTestIdentify, DuplicateOutputs) { ANEURALNETWORKS_BAD_DATA); } -// Also see TEST_F(ValidationTestCompilationForDevices, SetPreference) +// Also see TEST_F(ValidationTestCompilationForDevices_1, SetPreference) TEST_F(ValidationTestCompilation, SetPreference) { EXPECT_EQ(ANeuralNetworksCompilation_setPreference(nullptr, ANEURALNETWORKS_PREFER_LOW_POWER), ANEURALNETWORKS_UNEXPECTED_NULL); @@ -752,7 +752,7 @@ TEST_F(ValidationTestCompilation, SetPreference) { EXPECT_EQ(ANeuralNetworksCompilation_setPreference(mCompilation, 40), ANEURALNETWORKS_BAD_DATA); } -// Also see TEST_F(ValidationTestCompilationForDevices, SetCaching) +// Also see TEST_F(ValidationTestCompilationForDevices_1, SetCaching) TEST_F(ValidationTestCompilation, SetCaching) { std::vector<uint8_t> token(ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN, 0); EXPECT_EQ(ANeuralNetworksCompilation_setCaching(nullptr, "/data/local/tmp", token.data()), @@ -763,7 +763,7 @@ TEST_F(ValidationTestCompilation, SetCaching) { ANEURALNETWORKS_UNEXPECTED_NULL); } -// Also see TEST_F(ValidationTestCompilationForDevices, CreateExecution) +// Also see TEST_F(ValidationTestCompilationForDevices_1, CreateExecution) TEST_F(ValidationTestCompilation, CreateExecution) { ANeuralNetworksExecution* execution = nullptr; EXPECT_EQ(ANeuralNetworksExecution_create(nullptr, &execution), @@ -773,7 +773,7 @@ TEST_F(ValidationTestCompilation, CreateExecution) { EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_BAD_STATE); } -// Also see TEST_F(ValidationTestCompilationForDevices, Finish) +// Also see TEST_F(ValidationTestCompilationForDevices_1, Finish) TEST_F(ValidationTestCompilation, Finish) { EXPECT_EQ(ANeuralNetworksCompilation_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL); EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR); @@ -786,6 +786,119 @@ TEST_F(ValidationTestCompilation, Finish) { EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_BAD_STATE); } +// Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming) +// Also see TEST_F(ValidationTestCompilationForDevices_2, ExecutionTiming) +TEST_F(ValidationTestCompilation, ExecutionTiming) { + ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR); + ANeuralNetworksExecution* execution; + ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR); + // Cannot setMeasureTiming() with Compilation rather than CompilationForDevices. + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false), + ANEURALNETWORKS_BAD_DATA); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), ANEURALNETWORKS_BAD_DATA); +} + +// Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming) +TEST_F(ValidationTestCompilation, ExecutionUsability) { + ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR); + + enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST }; + for (auto executionType : {ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST}) { + SCOPED_TRACE(static_cast<uint32_t>(executionType)); + + ANeuralNetworksExecution* execution; + ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), + ANEURALNETWORKS_NO_ERROR); + + float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2]; + int in2 = 0; + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)), + ANEURALNETWORKS_NO_ERROR); + + const size_t memorySize = std::max(sizeof(in0), sizeof(out0)); + int memoryFd = ASharedMemory_create("nnMemory", memorySize); + ASSERT_GT(memoryFd, 0); + ANeuralNetworksMemory* memory; + EXPECT_EQ(ANeuralNetworksMemory_createFromFd(memorySize, PROT_READ | PROT_WRITE, memoryFd, + 0, &memory), + ANEURALNETWORKS_NO_ERROR); + + auto testTooLate = [this, execution, &in0, &out0, memory] { + // Try a bunch of things that are impermissible if the execution has started. + + // Set inputs and outputs. + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)), + ANEURALNETWORKS_BAD_STATE); + ASSERT_EQ( + ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)), + ANEURALNETWORKS_BAD_STATE); + ASSERT_EQ(ANeuralNetworksExecution_setInputFromMemory(execution, 0, nullptr, memory, 0, + sizeof(in0)), + ANEURALNETWORKS_BAD_STATE); + ASSERT_EQ(ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memory, 0, + sizeof(out0)), + ANEURALNETWORKS_BAD_STATE); + + // Reuse for asynchronous execution. + { + ANeuralNetworksEvent* event; + ASSERT_EQ(ANeuralNetworksExecution_startCompute(execution, &event), + ANEURALNETWORKS_BAD_STATE); + } + + // Reuse for synchronous execution. + ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_BAD_STATE); + + // Reuse for burst execution. + { + ANeuralNetworksBurst* burst; + ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst), + ANEURALNETWORKS_BAD_STATE); + ANeuralNetworksBurst_free(burst); + } + }; + + // Compute. + switch (executionType) { + case ExecutionType::ASYNC: { + ANeuralNetworksEvent* event; + ASSERT_EQ(ANeuralNetworksExecution_startCompute(execution, &event), + ANEURALNETWORKS_NO_ERROR); + testTooLate(); + ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR); + testTooLate(); + ANeuralNetworksEvent_free(event); + break; + } + case ExecutionType::SYNC: { + ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_NO_ERROR); + testTooLate(); + break; + } + case ExecutionType::BURST: { + ANeuralNetworksBurst* burst; + ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst), + ANEURALNETWORKS_NO_ERROR); + testTooLate(); + ANeuralNetworksBurst_free(burst); + break; + } + default: + FAIL() << "Unreachable"; + } + } +} + TEST_F(ValidationTestExecution, SetInput) { char buffer[20]; EXPECT_EQ(ANeuralNetworksExecution_setInput(nullptr, 0, nullptr, buffer, sizeof(float)), @@ -1397,7 +1510,7 @@ TEST(ValidationTestIntrospection, DeviceGetType) { EXPECT_EQ(ANeuralNetworksDevice_getType(nullptr, nullptr), ANEURALNETWORKS_UNEXPECTED_NULL); } -class ValidationTestCompilationForDevices : public ValidationTestModel { +class ValidationTestCompilationForDevices_1 : public ValidationTestModel { protected: virtual void SetUp() override { ValidationTestModel::SetUp(); @@ -1431,7 +1544,7 @@ class ValidationTestCompilationForDevices : public ValidationTestModel { }; // Also see TEST_F(ValidationTestCompilation, SetPreference) -TEST_F(ValidationTestCompilationForDevices, SetPreference) { +TEST_F(ValidationTestCompilationForDevices_1, SetPreference) { EXPECT_EQ(ANeuralNetworksCompilation_setPreference(nullptr, ANEURALNETWORKS_PREFER_LOW_POWER), ANEURALNETWORKS_UNEXPECTED_NULL); if (!mCompilation) { @@ -1441,7 +1554,7 @@ TEST_F(ValidationTestCompilationForDevices, SetPreference) { } // Also see TEST_F(ValidationTestCompilation, SetCaching) -TEST_F(ValidationTestCompilationForDevices, SetCaching) { +TEST_F(ValidationTestCompilationForDevices_1, SetCaching) { std::vector<uint8_t> token(ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN, 0); EXPECT_EQ(ANeuralNetworksCompilation_setCaching(nullptr, "/data/local/tmp", token.data()), ANEURALNETWORKS_UNEXPECTED_NULL); @@ -1455,7 +1568,7 @@ TEST_F(ValidationTestCompilationForDevices, SetCaching) { } // Also see TEST_F(ValidationTestCompilation, CreateExecution) -TEST_F(ValidationTestCompilationForDevices, CreateExecution) { +TEST_F(ValidationTestCompilationForDevices_1, CreateExecution) { ANeuralNetworksExecution* execution = nullptr; EXPECT_EQ(ANeuralNetworksExecution_create(nullptr, &execution), ANEURALNETWORKS_UNEXPECTED_NULL); @@ -1468,7 +1581,7 @@ TEST_F(ValidationTestCompilationForDevices, CreateExecution) { } // Also see TEST_F(ValidationTestCompilation, Finish) -TEST_F(ValidationTestCompilationForDevices, Finish) { +TEST_F(ValidationTestCompilationForDevices_1, Finish) { EXPECT_EQ(ANeuralNetworksCompilation_finish(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL); if (!mCompilation) { return; @@ -1483,6 +1596,55 @@ TEST_F(ValidationTestCompilationForDevices, Finish) { EXPECT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_BAD_STATE); } +class ValidationTestCompilationForDevices_2 : public ValidationTestModel { + protected: + virtual void SetUp() override { + ValidationTestModel::SetUp(); + createModel(); + + uint32_t numDevices = 0; + EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR); + + if (numDevices > 1) { + EXPECT_EQ(ANeuralNetworks_getDevice(0, &mDevices[0]), ANEURALNETWORKS_NO_ERROR); + EXPECT_EQ(ANeuralNetworks_getDevice(1, &mDevices[1]), ANEURALNETWORKS_NO_ERROR); + bool supported = false; + ASSERT_EQ(mNumOperations, static_cast<uint32_t>(1)); + EXPECT_EQ(ANeuralNetworksModel_getSupportedOperationsForDevices(mModel, mDevices, 2, + &supported), + ANEURALNETWORKS_NO_ERROR); + if (supported) { + ASSERT_EQ(ANeuralNetworksCompilation_createForDevices(mModel, mDevices, 2, + &mCompilation), + ANEURALNETWORKS_NO_ERROR); + } + } + } + + virtual void TearDown() { + ANeuralNetworksCompilation_free(mCompilation); + ValidationTestModel::TearDown(); + } + + ANeuralNetworksDevice* mDevices[2] = {nullptr, nullptr}; + ANeuralNetworksCompilation* mCompilation = nullptr; +}; + +// Also see TEST_F(ValidationTestCompilation, ExecutionTiming) +// Also see TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming) +TEST_F(ValidationTestCompilationForDevices_2, ExecutionTiming) { + if (!mCompilation) { + return; + } + ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR); + ANeuralNetworksExecution* execution; + ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR); + // Cannot setMeasureTiming() if there are two or more devices. + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false), + ANEURALNETWORKS_BAD_DATA); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), ANEURALNETWORKS_BAD_DATA); +} + class ValidationTestInvalidCompilation : public ValidationTestModel { protected: virtual void SetUp() override { @@ -1543,79 +1705,128 @@ TEST_F(ValidationTestInvalidCompilation, CreateExecutionWithInvalidCompilation) ANEURALNETWORKS_BAD_STATE); } -TEST_F(ValidationTestCompilationForDevices, ExecutionTiming) { +// Also see TEST_F(ValidationTestCompilation, ExecutionTiming) +// Also see TEST_F(ValidationTestCompilationForDevices_2, ExecutionTiming) +// Also see TEST_F(ValidationTestCompilation, ExecutionUsability) +TEST_F(ValidationTestCompilationForDevices_1, ExecutionTiming) { if (!mCompilation) { return; } ASSERT_EQ(ANeuralNetworksCompilation_finish(mCompilation), ANEURALNETWORKS_NO_ERROR); - // Assume there's a single device. - // TODO: - // - Validate that we fail if there are multiple devices. - // - Validate that we fail if we have Compilation rather than CompilationForDevices. + enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST }; + for (auto executionType : {ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST}) { + SCOPED_TRACE(static_cast<uint32_t>(executionType)); - ANeuralNetworksExecution* execution; - ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR); + ANeuralNetworksExecution* execution; + ASSERT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), + ANEURALNETWORKS_NO_ERROR); - EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(nullptr, false), - ANEURALNETWORKS_UNEXPECTED_NULL); - EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(nullptr, true), - ANEURALNETWORKS_UNEXPECTED_NULL); - EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false), - ANEURALNETWORKS_NO_ERROR); - EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), ANEURALNETWORKS_NO_ERROR); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(nullptr, false), + ANEURALNETWORKS_UNEXPECTED_NULL); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(nullptr, true), + ANEURALNETWORKS_UNEXPECTED_NULL); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false), + ANEURALNETWORKS_NO_ERROR); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), + ANEURALNETWORKS_NO_ERROR); - // TODO: - // - Validate that we cannot setMeasureTiming if the execution has started - // - Validate that we cannot getDuration until the execution has finished + float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2]; + int in2 = 0; + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)), + ANEURALNETWORKS_NO_ERROR); - float in0[] = {0.0f, 0.0f}, in1[] = {1.0f, 1.0f}, out0[2]; - int in2 = 0; - ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 0, nullptr, &in0, sizeof(in0)), - ANEURALNETWORKS_NO_ERROR); - ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 1, nullptr, &in1, sizeof(in1)), - ANEURALNETWORKS_NO_ERROR); - ASSERT_EQ(ANeuralNetworksExecution_setInput(execution, 2, nullptr, &in2, sizeof(in2)), - ANEURALNETWORKS_NO_ERROR); - ASSERT_EQ(ANeuralNetworksExecution_setOutput(execution, 0, nullptr, &out0, sizeof(out0)), - ANEURALNETWORKS_NO_ERROR); - ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_NO_ERROR); - - auto testDuration = [](ANeuralNetworksExecution* e, int32_t durationCode, bool nullDuration) { - SCOPED_TRACE(e); - SCOPED_TRACE(durationCode); - SCOPED_TRACE(nullDuration); - - // Strictly speaking, a duration COULD have this value, but it is - // exceedingly unlikely. We'll use it as an initial value that we expect - // to be modified by getDuration(). - const uint64_t kBogusDuration = UINT64_MAX - 1; - - uint64_t duration = kBogusDuration; - uint64_t* durationPtr = nullDuration ? nullptr : &duration; - - int expectedResultCode = ANEURALNETWORKS_NO_ERROR; - if (e == nullptr | durationPtr == nullptr) { - expectedResultCode = ANEURALNETWORKS_UNEXPECTED_NULL; - } else if (durationCode < 0) { - expectedResultCode = ANEURALNETWORKS_BAD_DATA; - } + // Cannot getDuration until the execution has finished. + uint64_t duration; + EXPECT_EQ(ANeuralNetworksExecution_getDuration( + execution, ANEURALNETWORKS_DURATION_ON_HARDWARE, &duration), + ANEURALNETWORKS_BAD_STATE); + EXPECT_EQ(ANeuralNetworksExecution_getDuration( + execution, ANEURALNETWORKS_DURATION_IN_DRIVER, &duration), + ANEURALNETWORKS_BAD_STATE); + + auto testMeasureTooLate = [execution] { + // Cannot setMeasureTiming if the execution has started. + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, false), + ANEURALNETWORKS_BAD_STATE); + EXPECT_EQ(ANeuralNetworksExecution_setMeasureTiming(execution, true), + ANEURALNETWORKS_BAD_STATE); + }; - EXPECT_EQ(ANeuralNetworksExecution_getDuration(e, durationCode, durationPtr), - expectedResultCode); - if (expectedResultCode == ANEURALNETWORKS_NO_ERROR) { - EXPECT_NE(duration, kBogusDuration); + // Compute. + switch (executionType) { + case ExecutionType::ASYNC: { + ANeuralNetworksEvent* event; + ASSERT_EQ(ANeuralNetworksExecution_startCompute(execution, &event), + ANEURALNETWORKS_NO_ERROR); + testMeasureTooLate(); + ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR); + testMeasureTooLate(); + ANeuralNetworksEvent_free(event); + break; + } + case ExecutionType::SYNC: { + ASSERT_EQ(ANeuralNetworksExecution_compute(execution), ANEURALNETWORKS_NO_ERROR); + testMeasureTooLate(); + break; + } + case ExecutionType::BURST: { + ANeuralNetworksBurst* burst; + ASSERT_EQ(ANeuralNetworksBurst_create(mCompilation, &burst), + ANEURALNETWORKS_NO_ERROR); + ASSERT_EQ(ANeuralNetworksExecution_burstCompute(execution, burst), + ANEURALNETWORKS_NO_ERROR); + testMeasureTooLate(); + ANeuralNetworksBurst_free(burst); + break; + } + default: + FAIL() << "Unreachable"; } - }; - std::vector<ANeuralNetworksExecution*> executions = {nullptr, execution}; - std::vector<int32_t> durationCodes = {-1, ANEURALNETWORKS_DURATION_ON_HARDWARE, - ANEURALNETWORKS_DURATION_IN_DRIVER}; - std::vector<bool> nullDurations = {false, true}; - for (auto e : executions) { - for (auto d : durationCodes) { - for (auto n : nullDurations) { - testDuration(e, d, n); + auto testDuration = [](ANeuralNetworksExecution* e, int32_t durationCode, + bool nullDuration) { + SCOPED_TRACE(e); + SCOPED_TRACE(durationCode); + SCOPED_TRACE(nullDuration); + + // Strictly speaking, a duration COULD have this value, but it is + // exceedingly unlikely. We'll use it as an initial value that we expect + // to be modified by getDuration(). + const uint64_t kBogusDuration = UINT64_MAX - 1; + + uint64_t duration = kBogusDuration; + uint64_t* durationPtr = nullDuration ? nullptr : &duration; + + int expectedResultCode = ANEURALNETWORKS_NO_ERROR; + if (e == nullptr | durationPtr == nullptr) { + expectedResultCode = ANEURALNETWORKS_UNEXPECTED_NULL; + } else if (durationCode < 0) { + expectedResultCode = ANEURALNETWORKS_BAD_DATA; + } + + EXPECT_EQ(ANeuralNetworksExecution_getDuration(e, durationCode, durationPtr), + expectedResultCode); + if (expectedResultCode == ANEURALNETWORKS_NO_ERROR) { + EXPECT_NE(duration, kBogusDuration); + } + }; + + std::vector<ANeuralNetworksExecution*> executions = {nullptr, execution}; + std::vector<int32_t> durationCodes = {-1, ANEURALNETWORKS_DURATION_ON_HARDWARE, + ANEURALNETWORKS_DURATION_IN_DRIVER}; + std::vector<bool> nullDurations = {false, true}; + for (auto e : executions) { + for (auto d : durationCodes) { + for (auto n : nullDurations) { + testDuration(e, d, n); + } } } } |