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
14static const int extra_pad = 512;
15
16
17/*! \brief fill host and device memory with the selected byte
18 *
19 * \param byte to fill
20 *
21 */
22void 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
33bool 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 */
64void HeapMemory::setAlignment(size_t align)
65{
66 this->alignement = align;
67}
68
69/*! \brief Destroy the internal memory
70 *
71 *
72 */
73void 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 */
89bool 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 */
103bool 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 */
123bool 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
153size_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 */
167bool 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
218void * 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 */
228void * 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
239const void * HeapMemory::getPointer() const
240{
241 return dm;
242}
243