summaryrefslogtreecommitdiff
path: root/nn/runtime/test/TestFree.cpp
diff options
context:
space:
mode:
authorDavid Gross <dgross@google.com>2019-08-07 12:12:12 -0700
committerDavid Gross <dgross@google.com>2019-08-07 12:12:12 -0700
commit9ce80efa23fb0a598163b564411e560128684721 (patch)
treee0de066abea8c0a552d090c9acb0e14f4120cd01 /nn/runtime/test/TestFree.cpp
parentcf0d030ea1f617a370565c439b2037d596f05093 (diff)
downloadml-9ce80efa23fb0a598163b564411e560128684721.tar.gz
Audit object lifetime management: Fix documentation, add tests, add defensive code
When we designed the API, we documented that ANeuralNetworksExecution_free could be called on an ANeuralNetworksExecution with an execution in flight, but we never implemented support for that, so the behavior would have been undefined. This CL changes the documentation to forbid this and adds some defensive code to detect an attempt to free an in-flight execution and respond by logging an error and ignoring the free. Other documentation changes: - Fix typo in ANeuralNetworksCompilation_free - Clarify use of ANeuralNetworksEvent_free - Clarify use of ANeuralNetworksExecution_free - Clarify use of ANeuralNetworksMemory_free Adds tests to confirm that we can ANeuralNetworks*_free() nullptr or unfinished object without crashing. Test: NeuralNetworksTest_static Test: To verify that we gracefully handle ANeuralNetworksExecution_free with an execution in flight, added "sleep(5)" after ExecutionBuilder field mStarted is set to true; modified test IntrospectionControlTest.SimpleAddModel to add ANeuralNetworksExecution_free between ANeuralNetworksExecution_startCompute and ANeuralNetworksEvent_wait; ran "NeuralNetworksTest_static --gtest_filter=IntrospectionControlTest.SimpleAddModel 1024"; and verified that test passes and that logcat contains expected message. Bug: 123242704 Bug: 129494032 Change-Id: I59183c70b4f5794fdc122cfbc50ffd383ae066c3
Diffstat (limited to 'nn/runtime/test/TestFree.cpp')
-rw-r--r--nn/runtime/test/TestFree.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/nn/runtime/test/TestFree.cpp b/nn/runtime/test/TestFree.cpp
new file mode 100644
index 000000000..dedf55e58
--- /dev/null
+++ b/nn/runtime/test/TestFree.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This file tests that various abnormal uses of ANeuralNetworks*_free() don't crash.
+//
+// Limitation: It doesn't set various combinations of properties on objects before
+// freeing those objects.
+
+#include "NeuralNetworks.h"
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+namespace {
+
+ANeuralNetworksModel* createUnfinishedModel() {
+ ANeuralNetworksModel* model = nullptr;
+ EXPECT_EQ(ANeuralNetworksModel_create(&model), ANEURALNETWORKS_NO_ERROR);
+
+ uint32_t dimensions[] = {1};
+ ANeuralNetworksOperandType type = {
+ .type = ANEURALNETWORKS_TENSOR_FLOAT32, .dimensionCount = 1, .dimensions = dimensions};
+ EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &type), ANEURALNETWORKS_NO_ERROR);
+ EXPECT_EQ(ANeuralNetworksModel_addOperand(model, &type), ANEURALNETWORKS_NO_ERROR);
+
+ const uint32_t inList[]{0};
+ const uint32_t outList[]{1};
+ EXPECT_EQ(
+ ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_FLOOR, 1, inList, 1, outList),
+ ANEURALNETWORKS_NO_ERROR);
+ EXPECT_EQ(ANeuralNetworksModel_identifyInputsAndOutputs(model, 1, inList, 1, outList),
+ ANEURALNETWORKS_NO_ERROR);
+
+ return model;
+}
+
+ANeuralNetworksModel* createFinishedModel() {
+ ANeuralNetworksModel* const model = createUnfinishedModel();
+ EXPECT_EQ(ANeuralNetworksModel_finish(model), ANEURALNETWORKS_NO_ERROR);
+ return model;
+}
+
+std::vector<ANeuralNetworksDevice*> createDeviceList() {
+ std::vector<ANeuralNetworksDevice*> devices;
+
+ uint32_t numDevices = 0;
+ EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
+ for (uint32_t devIndex = 0; devIndex < numDevices; ++devIndex) {
+ ANeuralNetworksDevice* device = nullptr;
+ const int getDeviceStatus = ANeuralNetworks_getDevice(devIndex, &device);
+ EXPECT_EQ(getDeviceStatus, ANEURALNETWORKS_NO_ERROR);
+ if (getDeviceStatus == ANEURALNETWORKS_NO_ERROR) {
+ devices.push_back(device);
+ }
+ }
+
+ return devices;
+}
+
+TEST(Free, Null) {
+ ANeuralNetworksBurst_free(nullptr);
+ ANeuralNetworksCompilation_free(nullptr);
+ ANeuralNetworksEvent_free(nullptr);
+ ANeuralNetworksExecution_free(nullptr);
+ ANeuralNetworksMemory_free(nullptr);
+ ANeuralNetworksModel_free(nullptr);
+}
+
+TEST(Free, UnfinishedModel) {
+ ANeuralNetworksModel* const model = createUnfinishedModel();
+ ANeuralNetworksModel_free(model);
+}
+
+TEST(Free, UnfinishedCompilation) {
+ ANeuralNetworksModel* const model = createFinishedModel();
+
+ ANeuralNetworksCompilation* compilation = nullptr;
+ ASSERT_EQ(ANeuralNetworksCompilation_create(model, &compilation), ANEURALNETWORKS_NO_ERROR);
+ ANeuralNetworksCompilation_free(compilation);
+
+ ANeuralNetworksModel_free(model);
+}
+
+TEST(Free, UnfinishedCompilationForDevices) {
+ ANeuralNetworksModel* const model = createFinishedModel();
+
+ const auto devices = createDeviceList();
+
+ ANeuralNetworksCompilation* compilation = nullptr;
+ ASSERT_EQ(ANeuralNetworksCompilation_createForDevices(model, devices.data(), devices.size(),
+ &compilation),
+ ANEURALNETWORKS_NO_ERROR);
+ ANeuralNetworksCompilation_free(compilation);
+
+ ANeuralNetworksModel_free(model);
+}
+
+TEST(Free, UnscheduledExecution) {
+ ANeuralNetworksModel* const model = createFinishedModel();
+
+ ANeuralNetworksCompilation* compilation = nullptr;
+ ASSERT_EQ(ANeuralNetworksCompilation_create(model, &compilation), ANEURALNETWORKS_NO_ERROR);
+ ASSERT_EQ(ANeuralNetworksCompilation_finish(compilation), ANEURALNETWORKS_NO_ERROR);
+
+ ANeuralNetworksExecution* execution = nullptr;
+ ASSERT_EQ(ANeuralNetworksExecution_create(compilation, &execution), ANEURALNETWORKS_NO_ERROR);
+ ANeuralNetworksExecution_free(execution);
+
+ ANeuralNetworksCompilation_free(compilation);
+
+ ANeuralNetworksModel_free(model);
+}
+
+} // namespace