1 | /* |
2 | * HeapMemory.cpp |
3 | * |
4 | * Created on: Aug 17, 2014 |
5 | * Author: Pietro Incardona |
6 | */ |
7 | |
8 | #include "HeapMemory.hpp" |
9 | #include <cstddef> |
10 | #include <cstring> |
11 | #include <iostream> |
12 | #include <cstdint> |
13 | |
14 | static const int = 512; |
15 | |
16 | |
17 | /*! \brief fill host and device memory with the selected byte |
18 | * |
19 | * \param byte to fill |
20 | * |
21 | */ |
22 | void HeapMemory::fill(unsigned char c) |
23 | { |
24 | memset(dm,c,size()); |
25 | } |
26 | |
27 | /*! \brief Allocate a chunk of memory |
28 | * |
29 | * \param sz size of the chunk of memory to allocate in byte |
30 | * |
31 | */ |
32 | |
33 | bool HeapMemory::allocate(size_t sz) |
34 | { |
35 | //! Allocate the device memory |
36 | if (dm == NULL) |
37 | { |
38 | dmOrig = new byte[sz+alignement+extra_pad]; |
39 | #ifdef GARBAGE_INJECTOR |
40 | memset(dmOrig,0xFF,sz+alignement+extra_pad); |
41 | #endif |
42 | } |
43 | else |
44 | { |
45 | std::cerr << __FILE__ << ":" << __LINE__ << " error memory already allocated\n" ; |
46 | return false; |
47 | } |
48 | |
49 | dm = dmOrig; |
50 | |
51 | // align it, we do not know the size of the element we put 1 |
52 | // and we ignore the align check |
53 | size_t sz_a = sz+alignement; |
54 | align(alignement,1,(void *&)dm,sz_a); |
55 | |
56 | this->sz = sz; |
57 | |
58 | return true; |
59 | } |
60 | |
61 | /*! \brief set the memory block to be aligned by this number |
62 | * |
63 | */ |
64 | void HeapMemory::setAlignment(size_t align) |
65 | { |
66 | this->alignement = align; |
67 | } |
68 | |
69 | /*! \brief Destroy the internal memory |
70 | * |
71 | * |
72 | */ |
73 | void HeapMemory::destroy() |
74 | { |
75 | if (dmOrig != NULL) |
76 | delete [] dmOrig; |
77 | |
78 | sz = 0; |
79 | dm = NULL; |
80 | dmOrig = NULL; |
81 | } |
82 | |
83 | |
84 | /*! \brief copy the data from a pointer |
85 | * |
86 | * |
87 | * \param ptr |
88 | */ |
89 | bool HeapMemory::copyFromPointer(const void * ptr,size_t sz) |
90 | { |
91 | memcpy(dm,ptr,sz); |
92 | |
93 | return true; |
94 | } |
95 | |
96 | /*! \brief copy from device to device |
97 | * |
98 | * copy a piece of memory from device to device |
99 | * |
100 | * \param m from where to copy |
101 | * |
102 | */ |
103 | bool HeapMemory::copyDeviceToDevice(const HeapMemory & m) |
104 | { |
105 | //! The source buffer is too big to copy it |
106 | |
107 | if (m.sz > sz) |
108 | { |
109 | std::cerr << "Error " << __LINE__ << __FILE__ << ": source buffer is too big to copy" ; |
110 | return false; |
111 | } |
112 | |
113 | // Copy the memory from m |
114 | memcpy(dm,m.dm,m.sz); |
115 | return true; |
116 | } |
117 | |
118 | /*! \brief copy the memory |
119 | * |
120 | * \param m a memory interface |
121 | * |
122 | */ |
123 | bool HeapMemory::copy(const memory & m) |
124 | { |
125 | //! Here we try to cast memory into HeapMemory |
126 | const HeapMemory * ofpm = dynamic_cast<const HeapMemory *>(&m); |
127 | |
128 | //! if we fail we get the pointer and simply copy from the pointer |
129 | |
130 | if (ofpm == NULL) |
131 | { |
132 | // copy the memory from device to host and from host to device |
133 | |
134 | return copyFromPointer(m.getPointer(),m.size()); |
135 | } |
136 | else |
137 | { |
138 | // they are the same memory type, use cuda/thrust buffer copy |
139 | |
140 | return copyDeviceToDevice(*ofpm); |
141 | } |
142 | return false; |
143 | } |
144 | |
145 | /*! \brief Get the size of the allocated memory |
146 | * |
147 | * Get the size of the allocated memory |
148 | * |
149 | * \return the size of the allocated memory |
150 | * |
151 | */ |
152 | |
153 | size_t HeapMemory::size() const |
154 | { |
155 | return sz; |
156 | } |
157 | |
158 | /*! \brief Resize the allocated memory |
159 | * |
160 | * Resize the allocated memory, if request is smaller than the allocated memory |
161 | * is not resized |
162 | * |
163 | * \param sz size |
164 | * \return true if the resize operation complete correctly |
165 | * |
166 | */ |
167 | bool HeapMemory::resize(size_t sz) |
168 | { |
169 | // if the allocated memory is enough, do not resize |
170 | if (sz <= HeapMemory::size()) |
171 | return true; |
172 | |
173 | //! Allocate the device memory if not done yet |
174 | |
175 | if (HeapMemory::size() == 0) |
176 | return HeapMemory::allocate(sz); |
177 | |
178 | //! Create a new buffer if sz is bigger than the actual size |
179 | byte * tdm; |
180 | byte * tdmOrig; |
181 | tdmOrig = new byte[sz+alignement+extra_pad]; |
182 | #ifdef GARBAGE_INJECTOR |
183 | memset(tdmOrig,0xFF,sz+alignement+extra_pad); |
184 | #endif |
185 | tdm = tdmOrig; |
186 | |
187 | //! size plus alignment |
188 | size_t sz_a = sz+alignement; |
189 | |
190 | //! align it |
191 | align(alignement,1,(void *&)tdm,sz_a); |
192 | |
193 | //! copy from the old buffer to the new one |
194 | |
195 | memcpy(tdm,dm,HeapMemory::size()); |
196 | |
197 | this->sz = sz; |
198 | |
199 | //! free the old buffer |
200 | |
201 | HeapMemory::destroy(); |
202 | |
203 | //! change to the new buffer |
204 | |
205 | dm = tdm; |
206 | dmOrig = tdmOrig; |
207 | this->sz = sz; |
208 | |
209 | return true; |
210 | } |
211 | |
212 | /*! \brief Return a readable pointer with your data |
213 | * |
214 | * Return a readable pointer with your data |
215 | * |
216 | */ |
217 | |
218 | void * HeapMemory::getDevicePointer() |
219 | { |
220 | return dm; |
221 | } |
222 | |
223 | /*! \brief Return a readable pointer with your data |
224 | * |
225 | * Return a readable pointer with your data |
226 | * |
227 | */ |
228 | void * HeapMemory::getPointer() |
229 | { |
230 | return dm; |
231 | } |
232 | |
233 | /*! \brief Return a readable pointer with your data |
234 | * |
235 | * Return a readable pointer with your data |
236 | * |
237 | */ |
238 | |
239 | const void * HeapMemory::getPointer() const |
240 | { |
241 | return dm; |
242 | } |
243 | |