blob: 94ba183ee88f10c820adfde78f57642fa6655edc [file] [log] [blame]
Slava Shklyaev73ee79d2019-05-14 14:15:14 +01001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Xusong Wang7df43062019-08-09 16:38:14 -070017#include "1.0/Utils.h"
18
19#include "MemoryUtils.h"
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010020#include "TestHarness.h"
21
Xusong Wang7df43062019-08-09 16:38:14 -070022#include <android-base/logging.h>
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010023#include <android/hardware/neuralnetworks/1.0/types.h>
Xusong Wang7df43062019-08-09 16:38:14 -070024#include <android/hidl/allocator/1.0/IAllocator.h>
25#include <android/hidl/memory/1.0/IMemory.h>
26#include <hidlmemory/mapping.h>
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010027
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010028#include <vector>
29
30namespace android {
31namespace hardware {
32namespace neuralnetworks {
33
Xusong Wang7df43062019-08-09 16:38:14 -070034using namespace test_helper;
35using ::android::hardware::neuralnetworks::V1_0::DataLocation;
36using ::android::hardware::neuralnetworks::V1_0::Request;
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010037using ::android::hardware::neuralnetworks::V1_0::RequestArgument;
Xusong Wang7df43062019-08-09 16:38:14 -070038using ::android::hidl::memory::V1_0::IMemory;
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010039
Xusong Wang7df43062019-08-09 16:38:14 -070040constexpr uint32_t kInputPoolIndex = 0;
41constexpr uint32_t kOutputPoolIndex = 1;
42
43Request createRequest(const TestModel& testModel) {
44 // Model inputs.
45 hidl_vec<RequestArgument> inputs(testModel.inputIndexes.size());
46 size_t inputSize = 0;
47 for (uint32_t i = 0; i < testModel.inputIndexes.size(); i++) {
48 const auto& op = testModel.operands[testModel.inputIndexes[i]];
49 if (op.data.size() == 0) {
50 // Omitted input.
51 inputs[i] = {.hasNoValue = true};
52 } else {
53 DataLocation loc = {.poolIndex = kInputPoolIndex,
54 .offset = static_cast<uint32_t>(inputSize),
55 .length = static_cast<uint32_t>(op.data.size())};
56 inputSize += op.data.alignedSize();
57 inputs[i] = {.hasNoValue = false, .location = loc, .dimensions = {}};
58 }
59 }
60
61 // Model outputs.
62 hidl_vec<RequestArgument> outputs(testModel.outputIndexes.size());
63 size_t outputSize = 0;
64 for (uint32_t i = 0; i < testModel.outputIndexes.size(); i++) {
65 const auto& op = testModel.operands[testModel.outputIndexes[i]];
66 size_t dataSize = op.data.size();
67 DataLocation loc = {.poolIndex = kOutputPoolIndex,
68 .offset = static_cast<uint32_t>(outputSize),
69 .length = static_cast<uint32_t>(dataSize)};
70 outputSize += op.data.alignedSize();
71 outputs[i] = {.hasNoValue = false, .location = loc, .dimensions = {}};
72 }
73
74 // Allocate memory pools.
75 hidl_vec<hidl_memory> pools = {nn::allocateSharedMemory(inputSize),
76 nn::allocateSharedMemory(outputSize)};
77 CHECK_NE(pools[kInputPoolIndex].size(), 0u);
78 CHECK_NE(pools[kOutputPoolIndex].size(), 0u);
79 sp<IMemory> inputMemory = mapMemory(pools[kInputPoolIndex]);
80 CHECK(inputMemory.get() != nullptr);
81 uint8_t* inputPtr = static_cast<uint8_t*>(static_cast<void*>(inputMemory->getPointer()));
82 CHECK(inputPtr != nullptr);
83
84 // Copy input data to the memory pool.
85 for (uint32_t i = 0; i < testModel.inputIndexes.size(); i++) {
86 const auto& op = testModel.operands[testModel.inputIndexes[i]];
87 if (op.data.size() > 0) {
88 const uint8_t* begin = op.data.get<uint8_t>();
89 const uint8_t* end = begin + op.data.size();
90 std::copy(begin, end, inputPtr + inputs[i].location.offset);
91 }
92 }
93
94 return {.inputs = std::move(inputs), .outputs = std::move(outputs), .pools = std::move(pools)};
Slava Shklyaev73ee79d2019-05-14 14:15:14 +010095}
96
Xusong Wang7df43062019-08-09 16:38:14 -070097std::vector<TestBuffer> getOutputBuffers(const Request& request) {
98 sp<IMemory> outputMemory = mapMemory(request.pools[kOutputPoolIndex]);
99 CHECK(outputMemory.get() != nullptr);
100 uint8_t* outputPtr = static_cast<uint8_t*>(static_cast<void*>(outputMemory->getPointer()));
101 CHECK(outputPtr != nullptr);
102
103 // Copy out output results.
104 std::vector<TestBuffer> outputBuffers;
105 for (const auto& output : request.outputs) {
106 outputBuffers.emplace_back(output.location.length, outputPtr + output.location.offset);
107 }
108
109 return outputBuffers;
Slava Shklyaev73ee79d2019-05-14 14:15:14 +0100110}
111
112} // namespace neuralnetworks
113} // namespace hardware
114} // namespace android