cuda_runtime.hをインクルードするように修正
[cuda.git] / libutils / DeviceMemory.cuh
1 /*
2         Copyright (C) 2012  fmaj7b5.info
3
4         This program is free software: you can redistribute it and/or modify
5         it under the terms of the GNU General Public License as published by
6         the Free Software Foundation, either version 2 of the License, or
7         (at your option) any later version.
8
9         This program is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12         GNU General Public License for more details.
13
14         You should have received a copy of the GNU General Public License
15         along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef FM7b5_DEVICE_MEMORY_CUH
19 #define FM7b5_DEVICE_MEMORY_CUH
20
21 #include <stdexcept>
22 #include <type_traits>
23 #include <cuda.h>
24 #include <cuda_runtime.h>
25
26 #include "MDView.cuh"
27
28 namespace FM7b5
29 {
30         namespace memory
31         {
32                 //! Linear 1-D memory
33                 template <class T>
34                 class Linear
35                 {
36                 public:
37                         typedef T value_type;
38                         typedef typename std::add_pointer<T>::type pointer_type;
39                         typedef typename std::add_const<pointer_type>::type const_pointer_type;
40                         typedef typename std::add_reference<T>::type reference_type;
41
42                         Linear(const size_t count = 0)
43                                 : m_count(count)
44                         {
45                                 m_extent = sizeof(value_type);
46                                 md_data = static_cast<pointer_type>(allocate(m_extent * count));
47                         }
48
49                         ~Linear()
50                         {
51                                 deallocate(md_data);
52                         }
53
54                         void* allocate(const size_t byte)
55                         {
56                                 void* p(nullptr);
57                                 cudaError_t status;
58
59                                 status = cudaMalloc(&p, byte);
60                                 if (status != cudaSuccess) {
61                                         throw std::bad_alloc(cudaGetErrorString(status));
62                                 }
63
64                                 return p;
65                         }
66
67                         void deallocate(void* p)
68                         {
69                                 cudaFree(p);
70                         }
71
72                         void copy_from(const void* const src, const size_t byte)
73                         {
74                                 cudaMemcpy(md_data, src, byte, cudaMemcpyHostToDevice);
75                         }
76
77                         void copy_to(void* const dst, const size_t byte)
78                         {
79                                 cudaMemcpy(dst, md_data, byte, cudaMemcpyDeviceToHost);
80                         }
81
82                         size_t size() const { return m_extent * m_count; }
83                         size_t count() const { return m_count; }
84                         pointer_type data() const { return md_data; }
85
86                         MDView<value_type, 1> ref() const
87                         {
88                                 return MDView<value_type, 1>(md_data, &m_extent);
89                         }
90
91                 protected:
92                         size_t m_extent;
93                         size_t m_count;
94                         pointer_type md_data;
95                 };
96
97                 //! Linear 2-D memory
98                 template <class T>
99                 class LinearPitch
100                 {
101                 public:
102                         typedef T value_type;
103                         typedef typename std::add_pointer<T>::type pointer_type;
104                         typedef typename std::add_const<pointer_type>::type const_pointer_type;
105                         typedef typename std::add_reference<T>::type reference_type;
106
107                         LinearPitch(const size_t width, const size_t height)
108                                 : m_width(width), m_height(height)
109                         {
110                                 md_data = static_cast<pointer_type>(allocate(width, height, &m_extent[0]));
111                                 m_extent[1] = sizeof(value_type);
112                         }
113
114                         ~LinearPitch()
115                         {
116                                 deallocate(md_data);
117                         }
118
119                         void* allocate(const size_t width, const size_t height, size_t* pitch)
120                         {
121                                 void* p(nullptr);
122                                 cudaError_t status;
123
124                                 status = cudaMallocPitch(&p, pitch, sizeof(value_type) * width, height);
125                                 if (status != cudaSuccess) {
126                                         throw std::bad_alloc(cudaGetErrorString(status));
127                                 }
128
129                                 return p;
130                         }
131
132                         void deallocate(void* p)
133                         {
134                                 cudaFree(p);
135                         }
136
137                         void copy_from(const void* const src, const size_t width, const size_t height, size_t spitch = 0)
138                         {
139                                 if (spitch < 1) {
140                                         spitch = width;
141                                 }
142                                 cudaMemcpy2D(md_data, pitch(), src, spitch, width, height, cudaMemcpyHostToDevice);
143                         }
144
145                         void copy_to(void* const dst, const size_t width, const size_t height, size_t dpitch = 0)
146                         {
147                                 if (dpitch < 1) {
148                                         dpitch = width;
149                                 }
150                                 cudaMemcpy2D(dst, dpitch, md_data, pitch(), width, height, cudaMemcpyDeviceToHost);
151                         }
152
153                         size_t size() const { return m_extent[1] * m_height; }
154                         size_t width() const { return m_width; }
155                         size_t height() const { return m_height; }
156                         size_t pitch() const { return m_extent[0]; }
157                         pointer_type data() const { return md_data; }
158
159                         MDView<value_type, 2> ref() const
160                         {
161                                 return MDView<value_type, 2>(md_data, m_extent);
162                         }
163
164                 protected:
165                         size_t m_width;
166                         size_t m_height;
167                         size_t m_extent[2];
168                         pointer_type md_data;
169                 };
170         }
171 }
172
173 #endif /* FM7b5_DEVICE_MEMORY_CUH */