summaryrefslogtreecommitdiff
path: root/nn/runtime/test
diff options
context:
space:
mode:
authorXusong Wang <xusongw@google.com>2020-05-01 05:34:27 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-05-01 05:34:27 +0000
commit7ef73c26b5af4f563be3926c0c2070e0871e67da (patch)
treede22f71ad1ee5367fd3de4c37441a230cd7ba1b5 /nn/runtime/test
parente6ed0fc145d449239ad753d8b268a96b928dc830 (diff)
parent7f7e3874339e9ff4fe3bdb24e627f4e0f7edcf97 (diff)
downloadml-7ef73c26b5af4f563be3926c0c2070e0871e67da.tar.gz
Merge "Add internal NNT_static tests for buffer copying." into rvc-dev
Diffstat (limited to 'nn/runtime/test')
-rw-r--r--nn/runtime/test/TestGenerated.cpp47
-rw-r--r--nn/runtime/test/TestMemoryDomain.cpp107
-rw-r--r--nn/runtime/test/TestUtils.h82
3 files changed, 161 insertions, 75 deletions
diff --git a/nn/runtime/test/TestGenerated.cpp b/nn/runtime/test/TestGenerated.cpp
index 60f866cab..cc0b61983 100644
--- a/nn/runtime/test/TestGenerated.cpp
+++ b/nn/runtime/test/TestGenerated.cpp
@@ -15,9 +15,6 @@
*/
#include <android-base/logging.h>
-#include <android-base/mapped_file.h>
-#include <android-base/unique_fd.h>
-#include <android/sharedmem.h>
#include <ftw.h>
#include <gtest/gtest.h>
#include <unistd.h>
@@ -37,6 +34,7 @@
#include "GeneratedTestUtils.h"
#include "TestHarness.h"
#include "TestNeuralNetworksWrapper.h"
+#include "TestUtils.h"
// Systrace is not available from CTS tests due to platform layering
// constraints. We reuse the NNTEST_ONLY_PUBLIC_API flag, as that should also be
@@ -140,49 +138,6 @@ static void computeWithPtrs(const TestModel& testModel, Execution* execution, Re
*result = execution->compute();
}
-// Convenience class to manage the file, mapping, and memory object.
-class TestAshmem {
- public:
- TestAshmem(::android::base::unique_fd fd, std::unique_ptr<::android::base::MappedFile> mapped,
- Memory memory)
- : mFd(std::move(fd)), mMapped(std::move(mapped)), mMemory(std::move(memory)) {}
-
- // Factory function for TestAshmem; prefer this over the raw constructor
- static std::unique_ptr<TestAshmem> createFrom(const TestBuffer& buffer) {
- // Create ashmem-based fd.
- int fd = ASharedMemory_create(nullptr, buffer.size());
- if (fd <= 0) return nullptr;
- ::android::base::unique_fd managedFd(fd);
-
- // Map and populate ashmem.
- auto mappedFile =
- ::android::base::MappedFile::FromFd(fd, 0, buffer.size(), PROT_READ | PROT_WRITE);
- if (!mappedFile) return nullptr;
- memcpy(mappedFile->data(), buffer.get<void>(), buffer.size());
-
- // Create NNAPI memory object.
- Memory memory(buffer.size(), PROT_READ | PROT_WRITE, fd, 0);
- if (!memory.isValid()) return nullptr;
-
- // Store everything in managing class.
- return std::make_unique<TestAshmem>(std::move(managedFd), std::move(mappedFile),
- std::move(memory));
- }
-
- size_t size() { return mMapped->size(); }
- Memory* get() { return &mMemory; }
-
- template <typename Type>
- Type* dataAs() {
- return static_cast<Type*>(static_cast<void*>(mMapped->data()));
- }
-
- private:
- ::android::base::unique_fd mFd;
- std::unique_ptr<::android::base::MappedFile> mMapped;
- Memory mMemory;
-};
-
static ANeuralNetworksMemory* createDeviceMemoryForInput(const Compilation& compilation,
uint32_t index) {
ANeuralNetworksMemoryDesc* desc = nullptr;
diff --git a/nn/runtime/test/TestMemoryDomain.cpp b/nn/runtime/test/TestMemoryDomain.cpp
index 88ca2f4d8..4a9c394ad 100644
--- a/nn/runtime/test/TestMemoryDomain.cpp
+++ b/nn/runtime/test/TestMemoryDomain.cpp
@@ -29,7 +29,9 @@
#include "Manager.h"
#include "Memory.h"
#include "SampleDriver.h"
+#include "SampleDriverFull.h"
#include "TestNeuralNetworksWrapper.h"
+#include "TestUtils.h"
using namespace android::nn;
using namespace hal;
@@ -163,16 +165,10 @@ test_wrapper::Model createTestModel() {
return model;
}
-// Test memory domain with the following parameters
-// - If true, use a V1_2 driver, otherwise, use the latest version;
-// - If true, compile with explicit device list, otherwise, compile in the default way;
-// - The return of the allocate function.
-using MemoryDomainTestParam = std::tuple<bool, bool, AllocateReturn>;
-
-class MemoryDomainTest : public ::testing::TestWithParam<MemoryDomainTestParam> {
+class MemoryDomainTestBase : public ::testing::Test {
protected:
void SetUp() override {
- ::testing::TestWithParam<MemoryDomainTestParam>::SetUp();
+ ::testing::Test::SetUp();
if (DeviceManager::get()->getUseCpuOnly()) {
GTEST_SKIP();
}
@@ -182,28 +178,14 @@ class MemoryDomainTest : public ::testing::TestWithParam<MemoryDomainTestParam>
void TearDown() override {
DeviceManager::get()->forTest_reInitializeDeviceList();
- ::testing::TestWithParam<MemoryDomainTestParam>::TearDown();
- }
-
- // If kUseV1_2Driver, allocateReturn must be AllocateReturn::NOT_SUPPORTED.
- void createAndRegisterDriver(const char* name, std::set<OperationType> supportedOperations,
- AllocateReturn allocateReturn) {
- sp<V1_0::IDevice> driver;
- if (kUseV1_2Driver) {
- CHECK(allocateReturn == AllocateReturn::NOT_SUPPORTED);
- const sp<TestDriverLatest> testDriver =
- new TestDriverLatest(name, supportedOperations, AllocateReturn::NOT_SUPPORTED);
- driver = new V1_2::ADevice(testDriver);
- } else {
- driver = new TestDriverLatest(name, std::move(supportedOperations), allocateReturn);
- }
- DeviceManager::get()->forTest_registerDevice(name, driver);
+ ::testing::Test::TearDown();
}
- // If not kCompileWithExplicitDeviceList, the input argument "deviceNames" is ignored.
+ // If "deviceNames" is not empty, the compilation is created with explicit device list;
+ // otherwise, it is created normally.
test_wrapper::Compilation createCompilation(const std::vector<std::string>& deviceNames) {
test_wrapper::Compilation compilation;
- if (kCompileWithExplicitDeviceList) {
+ if (!deviceNames.empty()) {
// Map device names to ANeuralNetworksDevice.
std::map<std::string, ANeuralNetworksDevice*> deviceMap;
uint32_t numDevices = 0;
@@ -251,14 +233,49 @@ class MemoryDomainTest : public ::testing::TestWithParam<MemoryDomainTestParam>
return {n, test_wrapper::Memory(memory)};
}
+ static const test_wrapper::Model kModel;
+};
+
+const test_wrapper::Model MemoryDomainTestBase::kModel = createTestModel();
+
+// Test memory domain with the following parameters
+// - If true, use a V1_2 driver, otherwise, use the latest version;
+// - If true, compile with explicit device list, otherwise, compile in the default way;
+// - The return of the allocate function.
+using MemoryDomainTestParam = std::tuple<bool, bool, AllocateReturn>;
+
+class MemoryDomainTest : public MemoryDomainTestBase,
+ public ::testing::WithParamInterface<MemoryDomainTestParam> {
+ protected:
+ // If kUseV1_2Driver, allocateReturn must be AllocateReturn::NOT_SUPPORTED.
+ void createAndRegisterDriver(const char* name, std::set<OperationType> supportedOperations,
+ AllocateReturn allocateReturn) {
+ sp<V1_0::IDevice> driver;
+ if (kUseV1_2Driver) {
+ CHECK(allocateReturn == AllocateReturn::NOT_SUPPORTED);
+ const sp<TestDriverLatest> testDriver =
+ new TestDriverLatest(name, supportedOperations, AllocateReturn::NOT_SUPPORTED);
+ driver = new V1_2::ADevice(testDriver);
+ } else {
+ driver = new TestDriverLatest(name, std::move(supportedOperations), allocateReturn);
+ }
+ DeviceManager::get()->forTest_registerDevice(name, driver);
+ }
+
+ // If not kCompileWithExplicitDeviceList, the input argument "deviceNames" is ignored.
+ test_wrapper::Compilation createCompilation(const std::vector<std::string>& deviceNames) {
+ if (kCompileWithExplicitDeviceList) {
+ return MemoryDomainTestBase::createCompilation(deviceNames);
+ } else {
+ return MemoryDomainTestBase::createCompilation({});
+ }
+ }
+
const bool kUseV1_2Driver = std::get<0>(GetParam());
const bool kCompileWithExplicitDeviceList = std::get<1>(GetParam());
const AllocateReturn kAllocateReturn = std::get<2>(GetParam());
- static const test_wrapper::Model kModel;
};
-const test_wrapper::Model MemoryDomainTest::kModel = createTestModel();
-
// Test device memory allocation on a compilation with only a single partition.
TEST_P(MemoryDomainTest, SinglePartition) {
createAndRegisterDriver("test_driver",
@@ -412,4 +429,36 @@ INSTANTIATE_TEST_CASE_P(DeviceVersionV1_2, MemoryDomainTest,
testing::Combine(testing::Values(true), testing::Bool(),
testing::Values(AllocateReturn::NOT_SUPPORTED)));
+class MemoryDomainCopyTest : public MemoryDomainTestBase {};
+
+TEST_F(MemoryDomainCopyTest, MemoryCopyTest) {
+ sp<sample_driver::SampleDriverFull> driver(new sample_driver::SampleDriverFull(
+ "test_driver", {.execTime = 0.1f, .powerUsage = 0.1f}));
+ DeviceManager::get()->forTest_registerDevice("test_driver", driver);
+ auto compilation = createCompilation({"test_driver"});
+ ASSERT_NE(compilation.getHandle(), nullptr);
+
+ // Allocate ashmem.
+ const float initValue1 = 3.14f, initValue2 = 2.72f;
+ auto ashmem1 = TestAshmem::createFrom(&initValue1, sizeof(float));
+ auto ashmem2 = TestAshmem::createFrom(&initValue2, sizeof(float));
+ ASSERT_NE(ashmem1, nullptr);
+ ASSERT_NE(ashmem2, nullptr);
+
+ // Allocate device memories.
+ auto [n1, memory1] = allocateDeviceMemory(compilation, {0}, {});
+ auto [n2, memory2] = allocateDeviceMemory(compilation, {0}, {});
+ ASSERT_EQ(n1, ANEURALNETWORKS_NO_ERROR);
+ ASSERT_EQ(n2, ANEURALNETWORKS_NO_ERROR);
+
+ // Test memory copying: ashmem1 -> memory1 -> memory2 -> ashmem2
+ ASSERT_EQ(ANeuralNetworksMemory_copy(ashmem1->get()->get(), memory1.get()),
+ ANEURALNETWORKS_NO_ERROR);
+ ASSERT_EQ(ANeuralNetworksMemory_copy(memory1.get(), memory2.get()), ANEURALNETWORKS_NO_ERROR);
+ ASSERT_EQ(ANeuralNetworksMemory_copy(memory2.get(), ashmem2->get()->get()),
+ ANEURALNETWORKS_NO_ERROR);
+
+ EXPECT_EQ(ashmem2->dataAs<float>()[0], initValue1);
+}
+
} // namespace
diff --git a/nn/runtime/test/TestUtils.h b/nn/runtime/test/TestUtils.h
new file mode 100644
index 000000000..61f7ef8f5
--- /dev/null
+++ b/nn/runtime/test/TestUtils.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_TEST_UTILS_H
+#define ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_TEST_UTILS_H
+
+#include <android-base/mapped_file.h>
+#include <android-base/unique_fd.h>
+#include <android/sharedmem.h>
+
+#include <memory>
+#include <utility>
+
+#include "TestHarness.h"
+#include "TestNeuralNetworksWrapper.h"
+
+namespace android::nn {
+
+// Convenience class to manage the file, mapping, and memory object.
+class TestAshmem {
+ public:
+ TestAshmem(::android::base::unique_fd fd, std::unique_ptr<::android::base::MappedFile> mapped,
+ test_wrapper::Memory memory)
+ : mFd(std::move(fd)), mMapped(std::move(mapped)), mMemory(std::move(memory)) {}
+
+ // Factory function for TestAshmem; prefer this over the raw constructor
+ static std::unique_ptr<TestAshmem> createFrom(const test_helper::TestBuffer& buffer) {
+ return createFrom(buffer.get<void>(), buffer.size());
+ }
+
+ // Factory function for TestAshmem; prefer this over the raw constructor
+ static std::unique_ptr<TestAshmem> createFrom(const void* data, uint32_t length) {
+ // Create ashmem-based fd.
+ int fd = ASharedMemory_create(nullptr, length);
+ if (fd <= 0) return nullptr;
+ ::android::base::unique_fd managedFd(fd);
+
+ // Map and populate ashmem.
+ auto mappedFile =
+ ::android::base::MappedFile::FromFd(fd, 0, length, PROT_READ | PROT_WRITE);
+ if (!mappedFile) return nullptr;
+ memcpy(mappedFile->data(), data, length);
+
+ // Create NNAPI memory object.
+ test_wrapper::Memory memory(length, PROT_READ | PROT_WRITE, fd, 0);
+ if (!memory.isValid()) return nullptr;
+
+ // Store everything in managing class.
+ return std::make_unique<TestAshmem>(std::move(managedFd), std::move(mappedFile),
+ std::move(memory));
+ }
+
+ size_t size() { return mMapped->size(); }
+ test_wrapper::Memory* get() { return &mMemory; }
+
+ template <typename Type>
+ Type* dataAs() {
+ return static_cast<Type*>(static_cast<void*>(mMapped->data()));
+ }
+
+ private:
+ ::android::base::unique_fd mFd;
+ std::unique_ptr<::android::base::MappedFile> mMapped;
+ test_wrapper::Memory mMemory;
+};
+
+} // namespace android::nn
+
+#endif // ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_TEST_UTILS_H