summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiao Wang <miaowang@google.com>2019-12-23 16:18:11 -0800
committerXusong Wang <xusongw@google.com>2020-01-27 13:06:15 -0800
commit4e0d686495769c0fe1f9b41967a6c9f386c212fd (patch)
tree4a9a42bdc85e39068c42f3fbd0d020ee999a8286
parent7b647483ebc7aeeac3208aa2db0a8e0fda305e6b (diff)
downloadml-4e0d686495769c0fe1f9b41967a6c9f386c212fd.tar.gz
Add tests for sync fence related API.
The following tests are added: - basic validation tests - generated tests for ANeuralNetworksExecution_startComputeWithDependencies. Bug: 142778241 Test: mm Change-Id: I5591db4583e8b752868d06e16874780800d4410e Merged-In: I5591db4583e8b752868d06e16874780800d4410e (cherry picked from commit 688992b3e241dd8936d63c6a21977bfc6b6f0773)
-rw-r--r--nn/runtime/include/NeuralNetworksWrapper.h3
-rw-r--r--nn/runtime/test/TestGenerated.cpp6
-rw-r--r--nn/runtime/test/TestMain.cpp2
-rw-r--r--nn/runtime/test/TestNeuralNetworksWrapper.h16
-rw-r--r--nn/runtime/test/TestTrivialModel.cpp43
-rw-r--r--nn/runtime/test/TestValidation.cpp81
6 files changed, 148 insertions, 3 deletions
diff --git a/nn/runtime/include/NeuralNetworksWrapper.h b/nn/runtime/include/NeuralNetworksWrapper.h
index 7428741fc..69edd1ddb 100644
--- a/nn/runtime/include/NeuralNetworksWrapper.h
+++ b/nn/runtime/include/NeuralNetworksWrapper.h
@@ -328,6 +328,9 @@ class Event {
mEvent = newEvent;
}
+ // Only for use by Execution
+ ANeuralNetworksEvent* getHandle() const { return mEvent; }
+
private:
ANeuralNetworksEvent* mEvent = nullptr;
};
diff --git a/nn/runtime/test/TestGenerated.cpp b/nn/runtime/test/TestGenerated.cpp
index 93603a5eb..5842f0f36 100644
--- a/nn/runtime/test/TestGenerated.cpp
+++ b/nn/runtime/test/TestGenerated.cpp
@@ -488,6 +488,12 @@ TEST_P(GeneratedTests, Burst) {
execute(testModel);
Execution::setComputeMode(oldComputeMode);
}
+
+TEST_P(GeneratedTests, Fenced) {
+ const auto oldComputeMode = Execution::setComputeMode(Execution::ComputeMode::FENCED);
+ execute(testModel);
+ Execution::setComputeMode(oldComputeMode);
+}
#else
TEST_P(GeneratedTests, Test) {
execute(testModel);
diff --git a/nn/runtime/test/TestMain.cpp b/nn/runtime/test/TestMain.cpp
index b75417b09..a4fefae70 100644
--- a/nn/runtime/test/TestMain.cpp
+++ b/nn/runtime/test/TestMain.cpp
@@ -78,6 +78,8 @@ static int test(bool useCpuOnly, Execution::ComputeMode computeMode, bool allowS
return "ComputeMode::ASYNC";
case Execution::ComputeMode::BURST:
return "ComputeMode::BURST";
+ case Execution::ComputeMode::FENCED:
+ return "ComputeMode::FENCED";
}
return "<unknown ComputeMode>";
};
diff --git a/nn/runtime/test/TestNeuralNetworksWrapper.h b/nn/runtime/test/TestNeuralNetworksWrapper.h
index 05e68ace2..3111d148b 100644
--- a/nn/runtime/test/TestNeuralNetworksWrapper.h
+++ b/nn/runtime/test/TestNeuralNetworksWrapper.h
@@ -376,6 +376,18 @@ class Execution {
ANeuralNetworksBurst_free(burst);
return result;
}
+ case ComputeMode::FENCED: {
+ ANeuralNetworksEvent* event = nullptr;
+ Result result =
+ static_cast<Result>(ANeuralNetworksExecution_startComputeWithDependencies(
+ mExecution, nullptr, 0, &event));
+ if (result != Result::NO_ERROR) {
+ return result;
+ }
+ result = static_cast<Result>(ANeuralNetworksEvent_wait(event));
+ ANeuralNetworksEvent_free(event);
+ return result;
+ }
}
return Result::BAD_DATA;
}
@@ -386,7 +398,7 @@ class Execution {
// or
// - use the burst API
// Returns the previous ComputeMode.
- enum class ComputeMode { SYNC, ASYNC, BURST };
+ enum class ComputeMode { SYNC, ASYNC, BURST, FENCED };
static ComputeMode setComputeMode(ComputeMode mode) {
ComputeMode oldComputeMode = mComputeMode;
mComputeMode = mode;
@@ -407,6 +419,8 @@ class Execution {
return result;
}
+ ANeuralNetworksExecution* getHandle() { return mExecution; };
+
private:
ANeuralNetworksCompilation* mCompilation = nullptr;
ANeuralNetworksExecution* mExecution = nullptr;
diff --git a/nn/runtime/test/TestTrivialModel.cpp b/nn/runtime/test/TestTrivialModel.cpp
index 85da1d1f0..557b2aa62 100644
--- a/nn/runtime/test/TestTrivialModel.cpp
+++ b/nn/runtime/test/TestTrivialModel.cpp
@@ -150,6 +150,49 @@ TEST_F(TrivialTest, AddThree) {
ASSERT_EQ(CompareMatrices(expected3b, actual), 0);
}
+TEST_F(TrivialTest, FencedAddThree) {
+ Model modelAdd3;
+ CreateAddThreeTensorModel(&modelAdd3, matrix3);
+ Compilation compilation(&modelAdd3);
+ compilation.finish();
+
+ Matrix3x4 output1, output2;
+ memset(&output1, 0, sizeof(output1));
+ memset(&output2, 0, sizeof(output2));
+
+ // Start the first execution
+ Execution execution1(&compilation);
+ ASSERT_EQ(execution1.setInput(0, matrix1, sizeof(Matrix3x4)), Result::NO_ERROR);
+ ASSERT_EQ(execution1.setInput(1, matrix2, sizeof(Matrix3x4)), Result::NO_ERROR);
+ ASSERT_EQ(execution1.setOutput(0, output1, sizeof(Matrix3x4)), Result::NO_ERROR);
+ ANeuralNetworksEvent* event1;
+ ANeuralNetworksExecution* execution1_handle = execution1.getHandle();
+ ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution1_handle, nullptr, 0,
+ &event1),
+ ANEURALNETWORKS_NO_ERROR);
+
+ // Start the second execution which will wait for the first one.
+ Execution execution2(&compilation);
+ ASSERT_EQ(execution2.setInput(0, matrix1, sizeof(Matrix3x4)), Result::NO_ERROR);
+ ASSERT_EQ(execution2.setInput(1, matrix1, sizeof(Matrix3x4)), Result::NO_ERROR);
+ ASSERT_EQ(execution2.setOutput(0, output2, sizeof(Matrix3x4)), Result::NO_ERROR);
+ ANeuralNetworksEvent* event2;
+ ANeuralNetworksExecution* execution2_handle = execution2.getHandle();
+ ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution2_handle, &event1, 1,
+ &event2),
+ ANEURALNETWORKS_NO_ERROR);
+ // Wait for the second event.
+ ASSERT_EQ(ANeuralNetworksEvent_wait(event2), ANEURALNETWORKS_NO_ERROR);
+
+ // Check the results for both executions.
+ ASSERT_EQ(CompareMatrices(expected3, output1), 0);
+ ASSERT_EQ(CompareMatrices(expected3b, output2), 0);
+
+ // Free the event objects
+ ANeuralNetworksEvent_free(event1);
+ ANeuralNetworksEvent_free(event2);
+}
+
TEST_F(TrivialTest, BroadcastAddTwo) {
Model modelBroadcastAdd2;
OperandType scalarType(Type::INT32, {});
diff --git a/nn/runtime/test/TestValidation.cpp b/nn/runtime/test/TestValidation.cpp
index 89d263c6d..a978589dd 100644
--- a/nn/runtime/test/TestValidation.cpp
+++ b/nn/runtime/test/TestValidation.cpp
@@ -1006,8 +1006,9 @@ TEST_F(ValidationTestCompilation, 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}) {
+ enum class ExecutionType : uint32_t { ASYNC, SYNC, BURST, FENCED };
+ for (auto executionType :
+ {ExecutionType::ASYNC, ExecutionType::SYNC, ExecutionType::BURST, ExecutionType::FENCED}) {
SCOPED_TRACE(static_cast<uint32_t>(executionType));
ANeuralNetworksExecution* execution;
@@ -1068,6 +1069,14 @@ TEST_F(ValidationTestCompilation, ExecutionUsability) {
ANEURALNETWORKS_BAD_STATE);
ANeuralNetworksBurst_free(burst);
}
+
+ // Reuse for fenced execution.
+ {
+ ANeuralNetworksEvent* event;
+ ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution, nullptr,
+ 0, &event),
+ ANEURALNETWORKS_BAD_STATE);
+ }
};
// Compute.
@@ -1097,6 +1106,17 @@ TEST_F(ValidationTestCompilation, ExecutionUsability) {
ANeuralNetworksBurst_free(burst);
break;
}
+ case ExecutionType::FENCED: {
+ ANeuralNetworksEvent* event;
+ ASSERT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution, nullptr,
+ 0, &event),
+ ANEURALNETWORKS_NO_ERROR);
+ testTooLate();
+ ASSERT_EQ(ANeuralNetworksEvent_wait(event), ANEURALNETWORKS_NO_ERROR);
+ testTooLate();
+ ANeuralNetworksEvent_free(event);
+ break;
+ }
default:
FAIL() << "Unreachable";
}
@@ -1511,6 +1531,63 @@ TEST_F(ValidationTestExecution, EventWait) {
EXPECT_EQ(ANeuralNetworksEvent_wait(nullptr), ANEURALNETWORKS_UNEXPECTED_NULL);
}
+TEST_F(ValidationTest, EventCreateFromSyncFenceFd) {
+ ANeuralNetworksEvent* event;
+ EXPECT_EQ(ANeuralNetworksEvent_createFromSyncFenceFd(-1, &event), ANEURALNETWORKS_BAD_DATA);
+ EXPECT_EQ(ANeuralNetworksEvent_createFromSyncFenceFd(1, nullptr),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+}
+
+TEST_F(ValidationTest, EventGetSyncFenceFd) {
+ int sync_fd = -1;
+ EXPECT_EQ(ANeuralNetworksEvent_getSyncFenceFd(nullptr, &sync_fd),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+}
+
+TEST_F(ValidationTestExecution, FencedExecution) {
+ // Create a valid execution and event first.
+ ANeuralNetworksExecution* execution1;
+ EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution1), ANEURALNETWORKS_NO_ERROR);
+ float input0[] = {1.0f, 1.0f}, input1[] = {2.0f, 2.0f}, output0[2];
+ int32_t input2[] = {0};
+ EXPECT_EQ(ANeuralNetworksExecution_setInput(execution1, 0, nullptr, input0, sizeof(input0)),
+ ANEURALNETWORKS_NO_ERROR);
+ EXPECT_EQ(ANeuralNetworksExecution_setInput(execution1, 1, nullptr, input1, sizeof(input1)),
+ ANEURALNETWORKS_NO_ERROR);
+ EXPECT_EQ(ANeuralNetworksExecution_setInput(execution1, 2, nullptr, input2, sizeof(input2)),
+ ANEURALNETWORKS_NO_ERROR);
+ EXPECT_EQ(ANeuralNetworksExecution_setOutput(execution1, 0, nullptr, output0, sizeof(output0)),
+ ANEURALNETWORKS_NO_ERROR);
+ ANeuralNetworksEvent* event1 = nullptr;
+ EXPECT_EQ(
+ ANeuralNetworksExecution_startComputeWithDependencies(execution1, nullptr, 0, &event1),
+ ANEURALNETWORKS_NO_ERROR);
+
+ EXPECT_EQ(ANeuralNetworksEvent_getSyncFenceFd(event1, nullptr),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+
+ // The subsequent execution will wait for the first execution to finish.
+ ANeuralNetworksExecution* execution2;
+ ANeuralNetworksEvent* event2 = nullptr;
+ EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution2), ANEURALNETWORKS_NO_ERROR);
+ EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(nullptr, &event1, 1, &event2),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+ EXPECT_EQ(
+ ANeuralNetworksExecution_startComputeWithDependencies(execution2, nullptr, 1, &event2),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+ EXPECT_EQ(
+ ANeuralNetworksExecution_startComputeWithDependencies(execution2, &event1, 1, nullptr),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+ ANeuralNetworksEvent* wait_for_list[] = {event1, nullptr};
+ EXPECT_EQ(ANeuralNetworksExecution_startComputeWithDependencies(execution2, wait_for_list, 2,
+ &event2),
+ ANEURALNETWORKS_UNEXPECTED_NULL);
+
+ ANeuralNetworksEvent_free(event1);
+ ANeuralNetworksExecution_free(execution1);
+ ANeuralNetworksExecution_free(execution2);
+}
+
TEST_F(ValidationTestExecution, GetOutputOperandRankAndDimensions) {
ANeuralNetworksExecution* execution;
EXPECT_EQ(ANeuralNetworksExecution_create(mCompilation, &execution), ANEURALNETWORKS_NO_ERROR);