NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
packedstream.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 #include <nvbio/basic/types.h>
31 #include <nvbio/basic/numbers.h>
33 #include <nvbio/basic/iterator.h>
34 #if defined(__CUDACC__)
35 #include <nvbio/basic/cuda/arch.h>
36 #endif
37 
38 #if defined(BIG_ENDIAN)
39 #undef BIG_ENDIAN
40 #endif
41 
42 namespace nvbio {
43 
84 
87 
95 
96 // forward declaration
97 //
98 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
100 
103 template <typename T> struct stream_traits
104 {
106  typedef char symbol_type;
107 
108  static const uint32 SYMBOL_SIZE = 8u;
109  static const uint32 SYMBOL_COUNT = 256u;
110 };
111 
114 template <typename T> struct stream_traits<T*>
115 {
117  typedef T symbol_type;
118 
119  static const uint32 SYMBOL_SIZE = uint32( 8u * sizeof(T) );
120  static const uint32 SYMBOL_COUNT = uint32( (uint64(1u) << SYMBOL_SIZE) - 1u );
121 };
122 
125 template <typename T> struct stream_traits<const T*>
126 {
128  typedef T symbol_type;
129 
130  static const uint32 SYMBOL_SIZE = uint32( 8u * sizeof(T) );
131  static const uint32 SYMBOL_COUNT = uint32( (uint64(1u) << SYMBOL_SIZE) - 1u );
132 };
133 
137 template <typename Stream>
139 {
140  typedef typename Stream::symbol_type Symbol;
141  typedef typename Stream::symbol_type symbol_type;
142  typedef symbol_type value_type;
143  typedef typename Stream::index_type index_type;
144  typedef typename Stream::sindex_type sindex_type;
145 
149  : m_stream( stream ) {}
150 
154  : m_stream( ref.m_stream ) {}
155 
159 
163 
166  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE operator Symbol() const;
167 
168  Stream m_stream;
169 };
170 
173 template <typename Stream> struct to_const< PackedStreamRef<Stream> >
174 {
176 };
177 
190 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType = uint32>
192 {
194 
197  typedef typename std::iterator_traits<InputStream>::value_type storage_type;
198 
199  static const uint32 SYMBOL_SIZE = SYMBOL_SIZE_T;
200  static const uint32 SYMBOL_COUNT = 1u << SYMBOL_SIZE;
201  static const uint32 SYMBOL_MASK = SYMBOL_COUNT - 1u;
202  static const uint32 BIG_ENDIAN = BIG_ENDIAN_T;
204 
205  static const uint32 WORD_SIZE = uint32( sizeof(storage_type) );
206  static const uint32 SYMBOLS_PER_WORD = (8u * WORD_SIZE) / SYMBOL_SIZE;
208 
209  typedef InputStream stream_type;
210  typedef InputStream storage_iterator;
211  typedef Symbol symbol_type;
213  typedef Symbol const_reference;
214  typedef reference* pointer;
215  typedef typename std::iterator_traits<InputStream>::iterator_category iterator_category;
216  typedef symbol_type value_type;
219  typedef This iterator;
222 
226 
229  template <typename UInputStream>
230  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE explicit PackedStream(const UInputStream stream, const index_type index = 0) : m_stream( static_cast<InputStream>(stream) ), m_index( index ) {}
231 
234  template <typename UInputStream, typename USymbol>
236  m_stream( static_cast<InputStream>( other.stream() ) ), m_index( other.index() ) {}
237 
241 
244  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE Symbol operator[] (const index_type i) const { return get(i); }
247  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE reference operator[] (const index_type i) { return reference( *this + i ); }
248 
251  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE Symbol get() const { return get(0); }
252 
255  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE void set(const Symbol s) { set( 0, s ); }
256 
259  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE Symbol get(const index_type i) const;
260 
263  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE void set(const index_type i, const Symbol s);
264 
268 
272  InputStream stream() const { return m_stream; }
273 
277  index_type index() const { return m_index; }
278 
281  template <typename UInputStream, typename USymbol>
284  {
285  m_stream = static_cast<InputStream>( other.stream() );
286  m_index = other.m_index;
287  return *this;
288  }
289 
293 
297 
301 
305 
309 
313 
317 
321 
325 
326 private:
327  InputStream m_stream;
328  index_type m_index;
329 };
330 
334 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
336  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it1,
337  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it2);
338 
342 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
344  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it1,
345  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it2);
346 
350 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
352  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it1,
353  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it2);
354 
358 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
360  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it1,
361  const PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType>& it2);
362 
366 template <typename InputIterator, typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
368 void assign(
369  const IndexType input_len,
370  const InputIterator input_string,
371  PackedStream<InputStream,Symbol,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType> packed_string);
372 
376 template <typename InputStream, typename SymbolType, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
377 struct stream_traits< PackedStream<InputStream,SymbolType,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType> >
378 {
379  typedef IndexType index_type;
380  typedef SymbolType symbol_type;
381 
384 };
385 
389 template <typename InputStream, typename SymbolType, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
390 struct iterator_traits< PackedStream<InputStream,SymbolType,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType> > : public std::iterator_traits< PackedStream<InputStream,SymbolType,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType> >
391 {
393 
397  typedef typename iterator::pointer pointer;
398  typedef typename iterator::reference reference;
400 };
401 
417 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType = uint32>
418 struct ForwardPackedStream
419 {
421 
422  static const uint32 SYMBOL_SIZE = SYMBOL_SIZE_T;
423  static const uint32 SYMBOL_COUNT = 1u << SYMBOL_SIZE;
424  static const uint32 SYMBOL_MASK = SYMBOL_COUNT - 1u;
425  static const uint32 BIG_ENDIAN = BIG_ENDIAN_T;
427 
430  typedef typename std::iterator_traits<InputStream>::value_type storage_type;
431 
432  static const uint32 WORD_SIZE = uint32( sizeof(storage_type) );
433  static const uint32 SYMBOLS_PER_WORD = (8u * WORD_SIZE) / SYMBOL_SIZE;
435 
436  typedef InputStream stream_type;
437  typedef InputStream storage_iterator;
438  typedef Symbol symbol_type;
440  typedef Symbol const_reference;
441  typedef reference* pointer;
442  typedef typename std::iterator_traits<InputStream>::iterator_category iterator_category;
443  typedef symbol_type value_type;
446  typedef This iterator;
449 
453 
456  template <typename UInputStream>
457  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE explicit ForwardPackedStream(const UInputStream stream, const index_type index = 0) :
458  m_stream( static_cast<InputStream>(stream) ), m_index( index )
459  {
460  rebase();
461  }
462 
465  template <typename UInputStream, typename USymbol>
467  m_stream( static_cast<InputStream>( other.stream() ) ), m_index( other.index() ), m_word( other.m_word ), m_word_index( other.m_word_index ), m_word_offset( other.m_word_offset ) {}
468 
471  template <typename UInputStream, typename USymbol>
473  m_stream( static_cast<InputStream>( other.stream() ) ), m_index( other.index() )
474  {
475  rebase();
476  }
477 
481 
484  NVBIO_FORCEINLINE NVBIO_HOST_DEVICE Symbol get() const;
485 
489 
493  InputStream stream() const { return m_stream; }
494 
498  index_type index() const { return m_index; }
499 
502  template <typename UInputStream, typename USymbol>
505  {
506  m_stream = static_cast<InputStream>( other.stream() );
507  m_index = other.m_index;
508  m_word = other.m_word;
509  m_word_index = other.m_word_index;
511  return *this;
512  }
513 
517 
521 
525 
529 
533 
537 
541 
545 
549 
553 
554 public:
555  InputStream m_stream;
556  index_type m_index;
560 };
561 
565 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
569 
573 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
577 
581 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
585 
589 template <typename InputStream, typename Symbol, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
593 
597 template <typename InputStream, typename SymbolType, uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
598 struct stream_traits< ForwardPackedStream<InputStream,SymbolType,SYMBOL_SIZE_T,BIG_ENDIAN_T,IndexType> >
599 {
600  typedef IndexType index_type;
601  typedef SymbolType symbol_type;
602 
605 };
606 
610 template <typename IteratorType>
612 {
614  typedef value_type* pointer;
616  typedef typename std::iterator_traits<IteratorType>::difference_type difference_type;
617  //typedef typename std::iterator_traits<IteratorType>::distance_type distance_type;
618  typedef typename std::iterator_traits<IteratorType>::iterator_category iterator_category;
619 
624 
628  uint4_as_uint32_iterator(const IteratorType it) : m_it( it ) {}
629 
634  {
635  const uint32 c = i & 3u;
636  const uint32 w = i >> 2;
637  return nvbio::comp( m_it[w], c );
638  }
639 
640  IteratorType m_it;
641 };
642 
654 template <uint32 BLOCKDIM, uint32 BITS, bool BIG_ENDIAN, typename InStreamIterator, typename OutStreamIterator>
656 void transpose_packed_streams(const uint32 stride, const uint32 N, const uint32 in_offset, const InStreamIterator in_stream, OutStreamIterator out_stream);
657 
660 
661 } // namespace nvbio
662 
663 namespace std {
664 
667 template <typename Stream>
668 void swap(
671 {
672  typename nvbio::PackedStreamRef<Stream>::value_type tmp = ref1;
673 
674  ref1 = ref2;
675  ref2 = tmp;
676 }
677 
678 template <typename InputStream, typename SymbolType, nvbio::uint32 SYMBOL_SIZE_T, bool BIG_ENDIAN_T, typename IndexType>
682 {
684 
685  *it1 = *it2;
686  *it2 = tmp;
687 }
688 
689 } // std
690