NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ldg.h
Go to the documentation of this file.
1 /*
2  * nvbio
3  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #pragma once
29 
30 #if defined(__CUDACC__)
31 #include <cub/cub.cuh>
32 #endif
33 
34 #include <nvbio/basic/types.h>
35 #include <nvbio/basic/iterator.h>
36 
37 namespace nvbio {
38 namespace cuda {
39 
43 template <typename T>
45 {
46  typedef T value_type;
49  typedef value_type* pointer;
50  typedef typename std::iterator_traits<const T*>::difference_type difference_type;
51  typedef std::random_access_iterator_tag iterator_category;
52 
57 
61  ldg_pointer(const T* base) : m_base( base ) {}
62 
66  ldg_pointer(const ldg_pointer& it) : m_base( it.m_base ) {}
67 
71  value_type operator[](const uint32 i) const
72  {
73  #if __CUDA_ARCH__ >= 350
74  return __ldg( m_base + i );
75  #else
76  return m_base[i];
77  #endif
78  }
79 
84  {
85  #if __CUDA_ARCH__ >= 350
86  return __ldg( m_base );
87  #else
88  return *m_base;
89  #endif
90  }
91 
96  {
97  ++m_base;
98  return *this;
99  }
100 
105  {
106  ldg_pointer<T> r( m_base );
107  ++m_base;
108  return r;
109  }
110 
115  {
116  --m_base;
117  return *this;
118  }
119 
124  {
125  ldg_pointer<T> r( m_base );
126  --m_base;
127  return r;
128  }
129 
134  {
135  return ldg_pointer( m_base + i );
136  }
137 
142  {
143  return ldg_pointer( m_base - i );
144  }
145 
150  {
151  m_base += i;
152  return *this;
153  }
154 
159  {
160  m_base -= i;
161  return *this;
162  }
163 
168  {
169  return m_base - it.m_base;
170  }
171 
176  {
177  m_base = it.m_base;
178  return *this;
179  }
180 
181  const T* m_base;
182 };
183 
186 template <typename T>
189 {
190  return ldg_pointer<T>( it );
191 }
192 
193 
198 {
206 };
207 
208 #if defined(__CUDACC__)
209 template <CacheLoadModifier MOD> struct cub_load_mod {};
210 
211 template <> struct cub_load_mod<LOAD_DEFAULT> { static const cub::CacheLoadModifier MOD = cub::LOAD_DEFAULT; };
212 template <> struct cub_load_mod<LOAD_CA> { static const cub::CacheLoadModifier MOD = cub::LOAD_CA; };
213 template <> struct cub_load_mod<LOAD_CG> { static const cub::CacheLoadModifier MOD = cub::LOAD_CG; };
214 template <> struct cub_load_mod<LOAD_CS> { static const cub::CacheLoadModifier MOD = cub::LOAD_CS; };
215 template <> struct cub_load_mod<LOAD_CV> { static const cub::CacheLoadModifier MOD = cub::LOAD_CV; };
216 template <> struct cub_load_mod<LOAD_LDG> { static const cub::CacheLoadModifier MOD = cub::LOAD_LDG; };
217 #endif
218 
222 template <typename T, CacheLoadModifier MOD>
224 {
225  typedef T value_type;
228  typedef value_type* pointer;
229  typedef typename std::iterator_traits<const T*>::difference_type difference_type;
230  typedef std::random_access_iterator_tag iterator_category;
231 
236 
240  load_pointer(const T* base) : m_base( base ) {}
241 
245  load_pointer(const load_pointer& it) : m_base( it.m_base ) {}
246 
250  value_type operator[](const uint32 i) const
251  {
252  #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 350
253  return cub::ThreadLoad<cub_load_mod<MOD>::MOD>( const_cast<T*>(m_base + i) );
254  #else
255  return m_base[i];
256  #endif
257  }
258 
263  {
264  #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 350
265  return cub::ThreadLoad<cub_load_mod<MOD>::MOD>( const_cast<T*>(m_base) );
266  #else
267  return *m_base;
268  #endif
269  }
270 
275  {
276  ++m_base;
277  return *this;
278  }
279 
284  {
286  ++m_base;
287  return r;
288  }
289 
294  {
295  --m_base;
296  return *this;
297  }
298 
303  {
305  --m_base;
306  return r;
307  }
308 
313  {
314  return load_pointer( m_base + i );
315  }
316 
321  {
322  return load_pointer( m_base - i );
323  }
324 
329  {
330  m_base += i;
331  return *this;
332  }
333 
338  {
339  m_base -= i;
340  return *this;
341  }
342 
347  {
348  return m_base - it.m_base;
349  }
350 
355  {
356  m_base = it.m_base;
357  return *this;
358  }
359 
360  const T* m_base;
361 };
362 
365 template <CacheLoadModifier MOD, typename T>
368 {
369  return load_pointer<T,MOD>( it );
370 }
371 
372 } // namespace cuda
373 } // namespace nvbio