forked from google-coral/libedgetpu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdevice_buffer_mapper.h
175 lines (146 loc) · 6.24 KB
/
device_buffer_mapper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright 2019 Google LLC
//
// 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 DARWINN_DRIVER_DEVICE_BUFFER_MAPPER_H_
#define DARWINN_DRIVER_DEVICE_BUFFER_MAPPER_H_
#include <functional>
#include <vector>
#include "api/buffer.h"
#include "driver/device_buffer.h"
#include "driver/memory/address_space.h"
#include "driver/memory/dma_direction.h"
#include "port/logging.h"
#include "port/status.h"
#include "port/status_macros.h"
#include "port/statusor.h"
namespace platforms {
namespace darwinn {
namespace driver {
// Thread-unsafe.
// Maps request-specific Buffers to DeviceBuffers, and keeps track of
// DeviceBuffers. These include: input, output, instruction and scratch.
// Note that parameters are mapped and owned by ExecutableReference.
class DeviceBufferMapper {
public:
explicit DeviceBufferMapper(AddressSpace* address_space);
~DeviceBufferMapper() = default;
// This class is neither copyable nor movable.
DeviceBufferMapper(const DeviceBufferMapper&) = delete;
DeviceBufferMapper& operator=(const DeviceBufferMapper&) = delete;
// Unmaps all per-request buffers. It is safe to call this method for cleanup
// even if DeviceBuffers are partially mapped.
util::Status UnmapAll();
// Maps given buffers to DeviceBuffers.
util::Status MapInputs(const Buffer::NamedMap& buffers);
util::Status MapOutputs(const Buffer::NamedMap& buffers);
util::Status MapScratch(const Buffer& buffer);
util::Status MapInstructions(const std::vector<Buffer>& buffers);
// Returns mapped DeviceBuffers.
const DeviceBuffer::NamedMap& GetInputDeviceBuffers() const {
return inputs_;
}
const DeviceBuffer::NamedMap& GetOutputDeviceBuffers() const {
return outputs_;
}
const DeviceBuffer& GetScratchDeviceBuffer() const { return scratch_; }
const std::vector<DeviceBuffer>& GetInstructionDeviceBuffers() const {
return instructions_;
}
// Returns mapped DeviceBuffer for given argument.
const DeviceBuffer& GetInputDeviceBuffer(const std::string& name,
int batch) const {
return inputs_.at(name)[batch];
}
const DeviceBuffer& GetOutputDeviceBuffer(const std::string& name,
int batch) const {
return outputs_.at(name)[batch];
}
const DeviceBuffer& GetInstructionDeviceBuffer(int chunk_id) const {
DCHECK_LT(chunk_id, instructions_.size());
return instructions_[chunk_id];
}
private:
// Convenience function that wraps AddressSpace#Map() handling invalid
// buffers.
util::StatusOr<DeviceBuffer> Map(const Buffer& buffer,
DmaDirection direction);
// Convenience function that wraps AddressSpace#UnmapMemory() handling invalid
// buffers.
util::Status Unmap(DeviceBuffer buffer);
// Helper function to map multiple buffers, merging adjacent buffers.
// - Fills user_buffers with a map of device buffers that directly correspond
// to the passed in buffers. Data parallel elements are represented as
// separate entries, even if the memory is contiguous. These device buffers
// are suitable for use in the instruction linking process.
// - Fills mapped_buffers with the merged list of device buffers that actually
// got mapped. These are the device buffers that need to be unmapped later.
util::Status MapMultiple(const Buffer::NamedMap& buffers,
DmaDirection direction,
/*out*/ DeviceBuffer::NamedMap& user_buffers,
/*out*/ std::vector<DeviceBuffer>& mapped_buffers);
// Helper function to unmap multiple buffers. All passed in buffers will be
// invalidated by this call.
util::Status UnmapMultiple(std::vector<DeviceBuffer>& device_buffers);
// Address space used for mapping.
AddressSpace* const address_space_;
// Scratch buffer. Could be invalid.
DeviceBuffer scratch_;
// Input/output buffers.
// input/output[layer_name][batch_id] = DeviceBuffer
DeviceBuffer::NamedMap inputs_;
DeviceBuffer::NamedMap outputs_;
// Actual mappings that were created, after coalescing adjacent buffers. These
// are the mappings that need to be unmapped at the end of the request.
std::vector<DeviceBuffer> input_mappings_;
std::vector<DeviceBuffer> output_mappings_;
// Instruction buffers.
std::vector<DeviceBuffer> instructions_;
// Actual mappings that were created for instructions, after coalescing
// adjacent buffers.
std::vector<DeviceBuffer> instruction_mappings_;
};
// Holds a mapped device buffer as well as a callback for unmapping.
class MappedDeviceBuffer {
public:
MappedDeviceBuffer() = default;
MappedDeviceBuffer(
const DeviceBuffer& device_buffer,
const std::function<util::Status(const DeviceBuffer&)>& unmapper)
: device_buffer_(device_buffer),
unmap_(std::bind(unmapper, device_buffer)) {}
~MappedDeviceBuffer() {
// We should have unmapped the buffer at this moment.
CHECK(!unmap_);
}
// This type is not copyable; we can't have the same device buffer unmapped
// more than once.
MappedDeviceBuffer(const MappedDeviceBuffer&) = delete;
MappedDeviceBuffer& operator=(const MappedDeviceBuffer&) = delete;
// This type is movable.
MappedDeviceBuffer(MappedDeviceBuffer&& other) = default;
MappedDeviceBuffer& operator=(MappedDeviceBuffer&& other) = default;
const DeviceBuffer& device_buffer() const { return device_buffer_; }
// Unmaps the associated DeviceBuffer using the given unmapper.
util::Status Unmap() {
if (unmap_) RETURN_IF_ERROR(unmap_());
unmap_ = nullptr;
return util::Status(); // OK.
}
private:
DeviceBuffer device_buffer_;
std::function<util::Status()> unmap_;
};
} // namespace driver
} // namespace darwinn
} // namespace platforms
#endif // DARWINN_DRIVER_DEVICE_BUFFER_MAPPER_H_