-
Notifications
You must be signed in to change notification settings - Fork 1
/
buffer_cache.hpp
155 lines (129 loc) · 5.14 KB
/
buffer_cache.hpp
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
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/.
*
*
* Copyright (c) 2017-2018, Lutz, Clemens <[email protected]>
*/
#ifndef BUFFER_CACHE_HPP
#define BUFFER_CACHE_HPP
#include <cstdint>
#include <vector>
#include <boost/compute/buffer.hpp>
#include <boost/compute/device.hpp>
#include <boost/compute/event.hpp>
#include <boost/compute/command_queue.hpp>
#include <boost/compute/utility/wait_list.hpp>
#include "measurement/measurement.hpp"
namespace Clustering {
/*
* Modes define how objects are treated on access and cache eviction:
*
* ReadWrite: Copied to device on access and copied from device on eviction.
* ReadOnly: Copied to device on access and dropped on eviction.
* Transient: Instantiated on access and dropped on eviction.
*
* Note: Transient mode useful for e.g. pipelines while object is locked in cache.
*/
enum class ObjectMode {
ReadWrite,
ReadOnly,
Transient
};
class BufferCache {
public:
class BufferDesc;
using Buffer = boost::compute::buffer;
using BufferList = std::vector<BufferDesc>;
using Context = boost::compute::context;
using Device = boost::compute::device;
using Event = boost::compute::event;
using Queue = boost::compute::command_queue;
using WaitList = boost::compute::wait_list;
class BufferDesc {
public:
Buffer buffer;
size_t content_length;
size_t buffer_id; /* internal data */
};
/*
* Construct BufferCache with buffer_size in bytes.
*
* buffer_size must not be larger than the smallest pool_size.
*/
BufferCache(size_t buffer_size) :
buffer_size_i(buffer_size)
{}
virtual ~BufferCache()
{}
/*
* Returns buffer size in bytes.
*/
size_t buffer_size() { return buffer_size_i; }
/*
* Returns pool size of the device in bytes.
*/
virtual size_t pool_size(Device device) = 0;
/*
* Add device for BufferCache to manage with pool_size in bytes.
* pool_size must fit into device memory.
*
* Returns 1 if successful, negative value if unsuccessful.
*/
virtual int add_device(Context context, Device device, size_t pool_size) = 0;
/*
* Add data object for buffer cache to manage.
* Note that BufferCache captures the object, but does not manage
* its life-cycle.
*
* Returns new object id (oid).
*/
virtual uint32_t add_object(void *data_object, size_t length, ObjectMode mode = ObjectMode::ReadOnly) = 0;
/*
* Get pointer to previously added data object.
* Does not transfer ownership of object.
*/
virtual void object(uint32_t object_id, void *& data_object, size_t& length) = 0;
/*
* Returns a list devices on which the given range is currently in device memory. Default length is one buffer.
*/
virtual std::vector<Device> where_is(uint32_t /* object_id */, void * /* begin */) { return std::vector<Device>(); };
virtual std::vector<Device> where_is(uint32_t /* object_id */, void * /* begin */, void * /* end */) { return std::vector<Device>(); };
/*
* Get locked device buffer of object at location of pointer.
* Forces asynchronous write if buffer not cached on device.
* User shall unlock buffer after use.
*
* Returns 1 if successful, negative value if unsuccessful.
*/
virtual int get(Queue queue, uint32_t object_id, void *begin, void *end, BufferList& buffers, Event& event, WaitList const& wait_list, Measurement::DataPoint& datapoint) = 0;
/*
* Asynchronously write buffer at offset from host to device and get locked buffer at location of pointer.
* User shall unlock buffer after use.
*
* Returns 1 if successful, negative value if unsucessful.
*/
virtual int write_and_get(Queue queue, uint32_t object_id, void *begin, void *end, BufferList& buffers, Event& event, WaitList const& wait_list, Measurement::DataPoint& datapoint) = 0;
/*
* Asynchronously read buffer at location of pointer from device to host.
*
* Returns 1 if successful, negative value if unsuccessful.
*/
virtual int read(Queue queue, uint32_t object_id, void *begin, void *end, Event& event, WaitList const& wait_list, Measurement::DataPoint& datapoint) = 0;
/*
* Asynchronously write buffer at location of pointer from src device to dst device and get locked buffer at offset.
* dst and src must not be on same device.
*
* Returns 1 if successful, negative value if unsuccessful.
*/
virtual int sync_and_get(Queue dst, Queue src, uint32_t object_id, void *begin, void *end, Event& event, WaitList const& wait_list, Measurement::DataPoint& datapoint) = 0;
/*
* Locking prevents eviction of buffer at location of pointer on device. Necessary during kernel execution.
*/
virtual int unlock(Queue queue, uint32_t object_id, BufferList const& buffers, Event& event, WaitList const& wait_list, Measurement::DataPoint& datapoint) = 0;
protected:
size_t buffer_size_i;
};
} // namespace Clustering
#endif /* BUFFER_CACHE_HPP */