summaryrefslogtreecommitdiff
path: root/nn/runtime/test/TestValidation.cpp
diff options
context:
space:
mode:
authorDavid Gross <dgross@google.com>2019-04-08 18:29:00 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-04-08 18:29:00 +0000
commit92cebc78a042b275a5dac144bd1dc3565750329c (patch)
tree824c0099ef11ab3e11b832162530b0ad5c6bdc0c /nn/runtime/test/TestValidation.cpp
parent89a3f062a21e5d0866deabdc7e8e3950351283d3 (diff)
parent07c3f7520b9062ae68a55372cdefc67c0792c4a0 (diff)
downloadml-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.cpp351
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);
+ }
}
}
}