proteinsw.cu 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. // proteinsw.cu
  28. //
  29. #include <nvbio/basic/console.h>
  30. #include <nvbio/basic/timer.h>
  31. #include <nvbio/basic/vector.h>
  32. #include <nvbio/basic/cuda/ldg.h>
  33. #include <nvbio/strings/string.h>
  34. #include <nvbio/strings/alphabet.h>
  35. #include <nvbio/alignment/alignment.h>
  36. #include <nvbio/alignment/batched.h>
  37. #include <thrust/sequence.h>
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. using namespace nvbio;
  41. int8 s_blosum62[] =
  42. {
  43. 4, 0, -2, -1, -2, 0, -2, -1, -1, -1, -1, -2, -4, -1, -1, -1, 1, 0, 0, -3, -2, -2, -1, 0,
  44. 0, 9, -3, -4, -2, -3, -3, -1, -3, -1, -1, -3, -4, -3, -3, -3, -1, -1, -1, -2, -2, -3, -3, -2,
  45. -2, -3, 6, 2, -3, -1, -1, -3, -1, -4, -3, 1, -4, -1, 0, -2, 0, -1, -3, -4, -3, 4, 1, -1,
  46. -1, -4, 2, 5, -3, -2, 0, -3, 1, -3, -2, 0, -4, -1, 2, 0, 0, -1, -2, -3, -2, 1, 4, -1,
  47. -2, -2, -3, -3, 6, -3, -1, 0, -3, 0, 0, -3, -4, -4, -3, -3, -2, -2, -1, 1, 3, -3, -3, -1,
  48. 0, -3, -1, -2, -3, 6, -2, -4, -2, -4, -3, 0, -4, -2, -2, -2, 0, -2, -3, -2, -3, -1, -2, -1,
  49. -2, -3, -1, 0, -1, -2, 8, -3, -1, -3, -2, 1, -4, -2, 0, 0, -1, -2, -3, -2, 2, 0, 0, -1,
  50. -1, -1, -3, -3, 0, -4, -3, 4, -3, 2, 1, -3, -4, -3, -3, -3, -2, -1, 3, -3, -1, -3, -3, -1,
  51. -1, -3, -1, 1, -3, -2, -1, -3, 5, -2, -1, 0, -4, -1, 1, 2, 0, -1, -2, -3, -2, 0, 1, -1,
  52. -1, -1, -4, -3, 0, -4, -3, 2, -2, 4, 2, -3, -4, -3, -2, -2, -2, -1, 1, -2, -1, -4, -3, -1,
  53. -1, -1, -3, -2, 0, -3, -2, 1, -1, 2, 5, -2, -4, -2, 0, -1, -1, -1, 1, -1, -1, -3, -1, -1,
  54. -2, -3, 1, 0, -3, 0, 1, -3, 0, -3, -2, 6, -4, -2, 0, 0, 1, 0, -3, -4, -2, 3, 0, -1,
  55. -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 1, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
  56. -1, -3, -1, -1, -4, -2, -2, -3, -1, -3, -2, -2, -4, 7, -1, -2, -1, -1, -2, -4, -3, -2, -1, -2,
  57. -1, -3, 0, 2, -3, -2, 0, -3, 1, -2, 0, 0, -4, -1, 5, 1, 0, -1, -2, -2, -1, 0, 3, -1,
  58. -1, -3, -2, 0, -3, -2, 0, -3, 2, -2, -1, 0, -4, -2, 1, 5, -1, -1, -3, -3, -2, -1, 0, -1,
  59. 1, -1, 0, 0, -2, 0, -1, -2, 0, -2, -1, 1, -4, -1, 0, -1, 4, 1, -2, -3, -2, 0, 0, 0,
  60. 0, -1, -1, -1, -2, -2, -2, -1, -1, -1, -1, 0, -4, -1, -1, -1, 1, 5, 0, -2, -2, -1, -1, 0,
  61. 0, -1, -3, -2, -1, -3, -3, 3, -2, 1, 1, -3, -4, -2, -2, -3, -2, 0, 4, -3, -1, -3, -2, -1,
  62. -3, -2, -4, -3, 1, -2, -2, -3, -3, -2, -1, -4, -4, -4, -2, -3, -3, -2, -3, 11, 2, -4, -3, -2,
  63. -2, -2, -3, -2, 3, -3, 2, -1, -2, -1, -1, -2, -4, -3, -1, -2, -2, -2, -1, 2, 7, -3, -2, -1,
  64. -2, -3, 4, 1, -3, -1, 0, -3, 0, -4, -3, 3, -4, -2, 0, -1, 0, -1, -3, -4, -3, 4, 1, -1,
  65. -1, -3, 1, 4, -3, -2, 0, -3, 1, -3, -1, 0, -4, -1, 3, 0, 0, -1, -2, -3, -2, 1, 4, -1,
  66. 0, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -4, -2, -1, -1, 0, 0, -1, -2, -1, -1, -1, -1,
  67. };
  68. // A scoring scheme class that will be used in conjunction with the \ref GotohAligner;
  69. //
  70. template <typename matrix_iterator>
  71. struct BlosumScheme
  72. {
  73. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE BlosumScheme(const matrix_iterator m, const int32 gap_open, const int32 gap_ext) :
  74. m_matrix(m), m_gap_open(gap_open), m_gap_ext(gap_ext) {}
  75. // return the maximum match bonus at the given quality score
  76. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE int32 match(const uint8 q = 0) const { return 11; };
  77. // return the substitution score at the given (reference,query) position (r_i,q_j),
  78. // with values (r,q) and quality score qq
  79. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE int32 substitution(
  80. const uint32 r_i, const uint32 q_j,
  81. const uint8 r, const uint8 q,
  82. const uint8 qq = 0) const { return int8( m_matrix[ r + q*24 ] ); };
  83. // return gap open and extension penalties for the pattern (query) and the text (reference)
  84. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE int32 pattern_gap_open() const { return m_gap_open; };
  85. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE int32 pattern_gap_extension() const { return m_gap_ext; };
  86. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE int32 text_gap_open() const { return m_gap_open; };
  87. NVBIO_FORCEINLINE NVBIO_HOST_DEVICE int32 text_gap_extension() const { return m_gap_ext; };
  88. const matrix_iterator m_matrix;
  89. const int32 m_gap_open;
  90. const int32 m_gap_ext;
  91. };
  92. // main test entry point
  93. //
  94. int main(int argc, char* argv[])
  95. {
  96. log_info(stderr, "protein SW... started\n");
  97. const uint32 n_tests = 10;
  98. const uint32 n_strings = 50000;
  99. const uint32 P = 128;
  100. const uint32 T = 1024;
  101. // alloc a device vector for holding the Blosum-62 scoring matrix
  102. nvbio::vector<device_tag,uint8> d_blosum62( 24*24 );
  103. // copy the matrix to the device
  104. thrust::copy( s_blosum62, s_blosum62 + 24*24, d_blosum62.begin() );
  105. // alloc the storage for the host strings
  106. nvbio::vector<host_tag,uint8> h_pattern_strings( P * n_strings );
  107. nvbio::vector<host_tag,uint8> h_text_strings( T * n_strings );
  108. // fill the strings with random characters
  109. LCG_random rand;
  110. for (uint32 i = 0; i < P * n_strings; ++i)
  111. h_pattern_strings[i] = nvbio::min( uint8( rand.next() * 24.0f ), (uint8)23u );
  112. for (uint32 i = 0; i < T * n_strings; ++i)
  113. h_text_strings[i] = nvbio::min( uint8( rand.next() * 24.0f ), (uint8)23u );
  114. // copy to the device
  115. nvbio::vector<device_tag,uint8> d_pattern_strings( h_pattern_strings );
  116. nvbio::vector<device_tag,uint8> d_text_strings( h_text_strings );
  117. nvbio::vector<device_tag,uint32> d_pattern_offsets( n_strings + 1 );
  118. nvbio::vector<device_tag,uint32> d_text_offsets( n_strings + 1 );
  119. // build the string offsets
  120. thrust::sequence( d_pattern_offsets.begin(), d_pattern_offsets.end(), 0u, P );
  121. thrust::sequence( d_text_offsets.begin(), d_text_offsets.end(), 0u, T );
  122. // prepare a vector of alignment sinks
  123. nvbio::vector< device_tag, aln::BestSink< uint32 > > sinks( n_strings );
  124. {
  125. const aln::SimpleGotohScheme scoring( 1, -1, -5, -3 );
  126. Timer timer;
  127. timer.start();
  128. for (uint32 i = 0; i < n_tests; ++i)
  129. {
  130. // and execute the batch alignment, on a GPU device
  131. aln::batch_alignment_score(
  132. aln::make_gotoh_aligner<aln::LOCAL,aln::PatternBlockingTag>( scoring ),
  133. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_pattern_strings ), (const uint32*)raw_pointer( d_pattern_offsets ) ),
  134. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_text_strings ), (const uint32*)raw_pointer( d_text_offsets ) ),
  135. sinks.begin(),
  136. aln::DeviceThreadScheduler(),
  137. P, T );
  138. }
  139. cudaDeviceSynchronize();
  140. timer.stop();
  141. log_info(stderr, " GCUPS (Constant/P): %.1f\n", (1.0e-9f * float(P*T) * float(n_strings) * float(n_tests))/timer.seconds());
  142. }
  143. {
  144. const aln::SimpleGotohScheme scoring( 1, -1, -5, -3 );
  145. Timer timer;
  146. timer.start();
  147. for (uint32 i = 0; i < n_tests; ++i)
  148. {
  149. // and execute the batch alignment, on a GPU device
  150. aln::batch_alignment_score(
  151. aln::make_gotoh_aligner<aln::LOCAL,aln::TextBlockingTag>( scoring ),
  152. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_pattern_strings ), (const uint32*)raw_pointer( d_pattern_offsets ) ),
  153. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_text_strings ), (const uint32*)raw_pointer( d_text_offsets ) ),
  154. sinks.begin(),
  155. aln::DeviceThreadScheduler(),
  156. P, T );
  157. }
  158. cudaDeviceSynchronize();
  159. timer.stop();
  160. log_info(stderr, " GCUPS (Constant/T): %.1f\n", (1.0e-9f * float(P*T) * float(n_strings) * float(n_tests))/timer.seconds());
  161. }
  162. {
  163. const BlosumScheme< cuda::ldg_pointer<uint8> > scoring( cuda::make_ldg_pointer( raw_pointer( d_blosum62 ) ), -5, -3 );
  164. Timer timer;
  165. timer.start();
  166. for (uint32 i = 0; i < n_tests; ++i)
  167. {
  168. // and execute the batch alignment, on a GPU device
  169. aln::batch_alignment_score(
  170. aln::make_gotoh_aligner<aln::LOCAL,aln::PatternBlockingTag>( scoring ),
  171. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_pattern_strings ), (const uint32*)raw_pointer( d_pattern_offsets ) ),
  172. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_text_strings ), (const uint32*)raw_pointer( d_text_offsets ) ),
  173. sinks.begin(),
  174. aln::DeviceThreadBlockScheduler<128,1>(),
  175. P, T );
  176. }
  177. cudaDeviceSynchronize();
  178. timer.stop();
  179. log_info(stderr, " GCUPS (Blosum62/P): %.1f\n", (1.0e-9f * float(P*T) * float(n_strings) * float(n_tests))/timer.seconds());
  180. }
  181. {
  182. const BlosumScheme< cuda::ldg_pointer<uint8> > scoring( cuda::make_ldg_pointer( raw_pointer( d_blosum62 ) ), -5, -3 );
  183. Timer timer;
  184. timer.start();
  185. for (uint32 i = 0; i < n_tests; ++i)
  186. {
  187. // and execute the batch alignment, on a GPU device
  188. aln::batch_alignment_score(
  189. aln::make_gotoh_aligner<aln::LOCAL,aln::TextBlockingTag>( scoring ),
  190. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_pattern_strings ), (const uint32*)raw_pointer( d_pattern_offsets ) ),
  191. make_concatenated_string_set( n_strings, (const uint8*)raw_pointer( d_text_strings ), (const uint32*)raw_pointer( d_text_offsets ) ),
  192. sinks.begin(),
  193. aln::DeviceThreadBlockScheduler<128,1>(),
  194. P, T );
  195. }
  196. cudaDeviceSynchronize();
  197. timer.stop();
  198. log_info(stderr, " GCUPS (Blosum62/T): %.1f\n", (1.0e-9f * float(P*T) * float(n_strings) * float(n_tests))/timer.seconds());
  199. }
  200. log_info(stderr, "protein SW... done\n");
  201. return 0;
  202. }