How to apply multithreading to Bio::SeqIO translate code (Bioperl)?










1














I am translating a fasta nucleotide file into protein sequences by this code



use Bio::SeqIO;
use Getopt::Long;

my ($format,$outfile) = 'fasta';

GetOptions(
'f|format:s' => $format,
'o|out|outfile:s' => $outfile,
);

my $oformat = 'fasta';
$file=$ARGV[0];
chomp $file;

# this implicity uses the <> file stream
my $seqin = Bio::SeqIO->new( -format => $format, -fh => *ARGV);
my $seqout;
if( $outfile )
$seqout = Bio::SeqIO->new( -format => $oformat, -file => ">$outfile" );
else
# defaults to writing to STDOUT
$seqout = Bio::SeqIO->new( -format => $oformat );


while( (my $seq = $seqin->next_seq()) )
my $pseq = $seq->translate();
$seqout->write_seq($pseq);



I implement
threads and threads::shared perl modules to achieve in other cases but I want to apply following code into previous task



use threads;
use threads::shared;
use List::Util qw( sum );
use YAML;
use constant NUM_THREADS =>100;

my @output :shared;

my $chunk_size = @data / NUM_THREADS;

my @threads;
for my $chunk ( 1 .. NUM_THREADS )
my $start = ($chunk - 1) * $chunk_size;
push @threads, threads->create(
&doOperation,
@data,
$start,
($start + $chunk_size - 1),
@output,
);

$_->join for @threads;

sub doOperation
my ($data, $start, $end, $output) = @_;

my $id = threads->tid;

print "$id ";

for my $i ($start .. $end)
print "Thread [$id] processing row $in";


#THIS WHILE SHOULD BE MULTITHREADED



 while( (my $seq = $seqin->next_seq()) ) 
my $pseq = $seq->translate();
$seqout->write_seq($pseq);



#THIS WHILE SHOULD BE MULTITHREADED



 sleep 1 if 0.2 > rand;

print "Thread done.n";
return;

print "n$timen";
my $time = localtime;
print "$timen";


Threads are being created but somehow it can not process the fasta file.
The fisrt code works fine without multi threading.










share|improve this question




























    1














    I am translating a fasta nucleotide file into protein sequences by this code



    use Bio::SeqIO;
    use Getopt::Long;

    my ($format,$outfile) = 'fasta';

    GetOptions(
    'f|format:s' => $format,
    'o|out|outfile:s' => $outfile,
    );

    my $oformat = 'fasta';
    $file=$ARGV[0];
    chomp $file;

    # this implicity uses the <> file stream
    my $seqin = Bio::SeqIO->new( -format => $format, -fh => *ARGV);
    my $seqout;
    if( $outfile )
    $seqout = Bio::SeqIO->new( -format => $oformat, -file => ">$outfile" );
    else
    # defaults to writing to STDOUT
    $seqout = Bio::SeqIO->new( -format => $oformat );


    while( (my $seq = $seqin->next_seq()) )
    my $pseq = $seq->translate();
    $seqout->write_seq($pseq);



    I implement
    threads and threads::shared perl modules to achieve in other cases but I want to apply following code into previous task



    use threads;
    use threads::shared;
    use List::Util qw( sum );
    use YAML;
    use constant NUM_THREADS =>100;

    my @output :shared;

    my $chunk_size = @data / NUM_THREADS;

    my @threads;
    for my $chunk ( 1 .. NUM_THREADS )
    my $start = ($chunk - 1) * $chunk_size;
    push @threads, threads->create(
    &doOperation,
    @data,
    $start,
    ($start + $chunk_size - 1),
    @output,
    );

    $_->join for @threads;

    sub doOperation
    my ($data, $start, $end, $output) = @_;

    my $id = threads->tid;

    print "$id ";

    for my $i ($start .. $end)
    print "Thread [$id] processing row $in";


    #THIS WHILE SHOULD BE MULTITHREADED



     while( (my $seq = $seqin->next_seq()) ) 
    my $pseq = $seq->translate();
    $seqout->write_seq($pseq);



    #THIS WHILE SHOULD BE MULTITHREADED



     sleep 1 if 0.2 > rand;

    print "Thread done.n";
    return;

    print "n$timen";
    my $time = localtime;
    print "$timen";


    Threads are being created but somehow it can not process the fasta file.
    The fisrt code works fine without multi threading.










    share|improve this question


























      1












      1








      1







      I am translating a fasta nucleotide file into protein sequences by this code



      use Bio::SeqIO;
      use Getopt::Long;

      my ($format,$outfile) = 'fasta';

      GetOptions(
      'f|format:s' => $format,
      'o|out|outfile:s' => $outfile,
      );

      my $oformat = 'fasta';
      $file=$ARGV[0];
      chomp $file;

      # this implicity uses the <> file stream
      my $seqin = Bio::SeqIO->new( -format => $format, -fh => *ARGV);
      my $seqout;
      if( $outfile )
      $seqout = Bio::SeqIO->new( -format => $oformat, -file => ">$outfile" );
      else
      # defaults to writing to STDOUT
      $seqout = Bio::SeqIO->new( -format => $oformat );


      while( (my $seq = $seqin->next_seq()) )
      my $pseq = $seq->translate();
      $seqout->write_seq($pseq);



      I implement
      threads and threads::shared perl modules to achieve in other cases but I want to apply following code into previous task



      use threads;
      use threads::shared;
      use List::Util qw( sum );
      use YAML;
      use constant NUM_THREADS =>100;

      my @output :shared;

      my $chunk_size = @data / NUM_THREADS;

      my @threads;
      for my $chunk ( 1 .. NUM_THREADS )
      my $start = ($chunk - 1) * $chunk_size;
      push @threads, threads->create(
      &doOperation,
      @data,
      $start,
      ($start + $chunk_size - 1),
      @output,
      );

      $_->join for @threads;

      sub doOperation
      my ($data, $start, $end, $output) = @_;

      my $id = threads->tid;

      print "$id ";

      for my $i ($start .. $end)
      print "Thread [$id] processing row $in";


      #THIS WHILE SHOULD BE MULTITHREADED



       while( (my $seq = $seqin->next_seq()) ) 
      my $pseq = $seq->translate();
      $seqout->write_seq($pseq);



      #THIS WHILE SHOULD BE MULTITHREADED



       sleep 1 if 0.2 > rand;

      print "Thread done.n";
      return;

      print "n$timen";
      my $time = localtime;
      print "$timen";


      Threads are being created but somehow it can not process the fasta file.
      The fisrt code works fine without multi threading.










      share|improve this question















      I am translating a fasta nucleotide file into protein sequences by this code



      use Bio::SeqIO;
      use Getopt::Long;

      my ($format,$outfile) = 'fasta';

      GetOptions(
      'f|format:s' => $format,
      'o|out|outfile:s' => $outfile,
      );

      my $oformat = 'fasta';
      $file=$ARGV[0];
      chomp $file;

      # this implicity uses the <> file stream
      my $seqin = Bio::SeqIO->new( -format => $format, -fh => *ARGV);
      my $seqout;
      if( $outfile )
      $seqout = Bio::SeqIO->new( -format => $oformat, -file => ">$outfile" );
      else
      # defaults to writing to STDOUT
      $seqout = Bio::SeqIO->new( -format => $oformat );


      while( (my $seq = $seqin->next_seq()) )
      my $pseq = $seq->translate();
      $seqout->write_seq($pseq);



      I implement
      threads and threads::shared perl modules to achieve in other cases but I want to apply following code into previous task



      use threads;
      use threads::shared;
      use List::Util qw( sum );
      use YAML;
      use constant NUM_THREADS =>100;

      my @output :shared;

      my $chunk_size = @data / NUM_THREADS;

      my @threads;
      for my $chunk ( 1 .. NUM_THREADS )
      my $start = ($chunk - 1) * $chunk_size;
      push @threads, threads->create(
      &doOperation,
      @data,
      $start,
      ($start + $chunk_size - 1),
      @output,
      );

      $_->join for @threads;

      sub doOperation
      my ($data, $start, $end, $output) = @_;

      my $id = threads->tid;

      print "$id ";

      for my $i ($start .. $end)
      print "Thread [$id] processing row $in";


      #THIS WHILE SHOULD BE MULTITHREADED



       while( (my $seq = $seqin->next_seq()) ) 
      my $pseq = $seq->translate();
      $seqout->write_seq($pseq);



      #THIS WHILE SHOULD BE MULTITHREADED



       sleep 1 if 0.2 > rand;

      print "Thread done.n";
      return;

      print "n$timen";
      my $time = localtime;
      print "$timen";


      Threads are being created but somehow it can not process the fasta file.
      The fisrt code works fine without multi threading.







      multithreading perl bioperl






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 at 9:01

























      asked Nov 12 at 7:30









      BioDeveloper

      3242521




      3242521






















          1 Answer
          1






          active

          oldest

          votes


















          2














          I'm afraid I'm not going to rewrite your code for you, but I can give you some pointers on how to accomplish threading.



          The thing you need to understand about perl threading is it's not a lightweight thread. You should spawn a number of threads equal to the parallelism, run them off a Thread::Queue and go from there.



          You also need to avoid any non-thread-safe modules - you can use them if you're careful but that usually means instantiating them within the thread with require and import instead of use at the start of the program.



          I would also suggest avoiding trying to do your output IO in parallel - return the thread results and coalesce them (sorting if necessary) in the 'main' thread (or spin off a single writer).



          So I'd go with something like;



          #!/usr/bin/env perl

          use strict;
          use warnings;

          use threads;

          use Thread::Queue;
          use Storable qw ( freeze thaw );

          my $NUM_THREADS = 16; #approx number of cores.

          my $translate_q = Thread::Queue->new;
          my $translate_results_q = Thread::Queue->new;


          sub translate_thread
          while ( my $item = translate_q->dequeue )
          my $seq = thaw $item;
          my $pseq = $seq->translate();
          $translate_results_q->enqueue( freeze $pseq );





          threads->create( &translate_thread ) for 1 .. $NUM_THREADS;

          while ( my $seq => $seqin->next_seq )
          $translate_q->enqueue( freeze($seq) );

          $translate_q->end;

          $_->join for threads->list;
          $translate_results_q->end;

          while ( my $result = $translate_results_q->dequeue )
          my $pseg = thaw($result);



          Note - this won't work as is, because it's missing merging with the rest of your ocde. But hopefully it illustrates how the queue and threading can work to get parallelism?



          You pass around your objects using freeze and thaw from Storable, and use the parallelism to unpack them.



          Don't go too mad on the number of threads - for primarily compute workloads (e.g. no IO) then a number of threads equal to the number of cores is about right. If they'll be blocking on IO, you can increase this number, but going past about double isn't going to do very much.



          You can't really parallelise disk IO efficiently - it just doesn't work like that. So do that in the 'main' thread.






          share|improve this answer




















          • Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
            – BioDeveloper
            Nov 13 at 5:05










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53257579%2fhow-to-apply-multithreading-to-bioseqio-translate-code-bioperl%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          I'm afraid I'm not going to rewrite your code for you, but I can give you some pointers on how to accomplish threading.



          The thing you need to understand about perl threading is it's not a lightweight thread. You should spawn a number of threads equal to the parallelism, run them off a Thread::Queue and go from there.



          You also need to avoid any non-thread-safe modules - you can use them if you're careful but that usually means instantiating them within the thread with require and import instead of use at the start of the program.



          I would also suggest avoiding trying to do your output IO in parallel - return the thread results and coalesce them (sorting if necessary) in the 'main' thread (or spin off a single writer).



          So I'd go with something like;



          #!/usr/bin/env perl

          use strict;
          use warnings;

          use threads;

          use Thread::Queue;
          use Storable qw ( freeze thaw );

          my $NUM_THREADS = 16; #approx number of cores.

          my $translate_q = Thread::Queue->new;
          my $translate_results_q = Thread::Queue->new;


          sub translate_thread
          while ( my $item = translate_q->dequeue )
          my $seq = thaw $item;
          my $pseq = $seq->translate();
          $translate_results_q->enqueue( freeze $pseq );





          threads->create( &translate_thread ) for 1 .. $NUM_THREADS;

          while ( my $seq => $seqin->next_seq )
          $translate_q->enqueue( freeze($seq) );

          $translate_q->end;

          $_->join for threads->list;
          $translate_results_q->end;

          while ( my $result = $translate_results_q->dequeue )
          my $pseg = thaw($result);



          Note - this won't work as is, because it's missing merging with the rest of your ocde. But hopefully it illustrates how the queue and threading can work to get parallelism?



          You pass around your objects using freeze and thaw from Storable, and use the parallelism to unpack them.



          Don't go too mad on the number of threads - for primarily compute workloads (e.g. no IO) then a number of threads equal to the number of cores is about right. If they'll be blocking on IO, you can increase this number, but going past about double isn't going to do very much.



          You can't really parallelise disk IO efficiently - it just doesn't work like that. So do that in the 'main' thread.






          share|improve this answer




















          • Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
            – BioDeveloper
            Nov 13 at 5:05















          2














          I'm afraid I'm not going to rewrite your code for you, but I can give you some pointers on how to accomplish threading.



          The thing you need to understand about perl threading is it's not a lightweight thread. You should spawn a number of threads equal to the parallelism, run them off a Thread::Queue and go from there.



          You also need to avoid any non-thread-safe modules - you can use them if you're careful but that usually means instantiating them within the thread with require and import instead of use at the start of the program.



          I would also suggest avoiding trying to do your output IO in parallel - return the thread results and coalesce them (sorting if necessary) in the 'main' thread (or spin off a single writer).



          So I'd go with something like;



          #!/usr/bin/env perl

          use strict;
          use warnings;

          use threads;

          use Thread::Queue;
          use Storable qw ( freeze thaw );

          my $NUM_THREADS = 16; #approx number of cores.

          my $translate_q = Thread::Queue->new;
          my $translate_results_q = Thread::Queue->new;


          sub translate_thread
          while ( my $item = translate_q->dequeue )
          my $seq = thaw $item;
          my $pseq = $seq->translate();
          $translate_results_q->enqueue( freeze $pseq );





          threads->create( &translate_thread ) for 1 .. $NUM_THREADS;

          while ( my $seq => $seqin->next_seq )
          $translate_q->enqueue( freeze($seq) );

          $translate_q->end;

          $_->join for threads->list;
          $translate_results_q->end;

          while ( my $result = $translate_results_q->dequeue )
          my $pseg = thaw($result);



          Note - this won't work as is, because it's missing merging with the rest of your ocde. But hopefully it illustrates how the queue and threading can work to get parallelism?



          You pass around your objects using freeze and thaw from Storable, and use the parallelism to unpack them.



          Don't go too mad on the number of threads - for primarily compute workloads (e.g. no IO) then a number of threads equal to the number of cores is about right. If they'll be blocking on IO, you can increase this number, but going past about double isn't going to do very much.



          You can't really parallelise disk IO efficiently - it just doesn't work like that. So do that in the 'main' thread.






          share|improve this answer




















          • Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
            – BioDeveloper
            Nov 13 at 5:05













          2












          2








          2






          I'm afraid I'm not going to rewrite your code for you, but I can give you some pointers on how to accomplish threading.



          The thing you need to understand about perl threading is it's not a lightweight thread. You should spawn a number of threads equal to the parallelism, run them off a Thread::Queue and go from there.



          You also need to avoid any non-thread-safe modules - you can use them if you're careful but that usually means instantiating them within the thread with require and import instead of use at the start of the program.



          I would also suggest avoiding trying to do your output IO in parallel - return the thread results and coalesce them (sorting if necessary) in the 'main' thread (or spin off a single writer).



          So I'd go with something like;



          #!/usr/bin/env perl

          use strict;
          use warnings;

          use threads;

          use Thread::Queue;
          use Storable qw ( freeze thaw );

          my $NUM_THREADS = 16; #approx number of cores.

          my $translate_q = Thread::Queue->new;
          my $translate_results_q = Thread::Queue->new;


          sub translate_thread
          while ( my $item = translate_q->dequeue )
          my $seq = thaw $item;
          my $pseq = $seq->translate();
          $translate_results_q->enqueue( freeze $pseq );





          threads->create( &translate_thread ) for 1 .. $NUM_THREADS;

          while ( my $seq => $seqin->next_seq )
          $translate_q->enqueue( freeze($seq) );

          $translate_q->end;

          $_->join for threads->list;
          $translate_results_q->end;

          while ( my $result = $translate_results_q->dequeue )
          my $pseg = thaw($result);



          Note - this won't work as is, because it's missing merging with the rest of your ocde. But hopefully it illustrates how the queue and threading can work to get parallelism?



          You pass around your objects using freeze and thaw from Storable, and use the parallelism to unpack them.



          Don't go too mad on the number of threads - for primarily compute workloads (e.g. no IO) then a number of threads equal to the number of cores is about right. If they'll be blocking on IO, you can increase this number, but going past about double isn't going to do very much.



          You can't really parallelise disk IO efficiently - it just doesn't work like that. So do that in the 'main' thread.






          share|improve this answer












          I'm afraid I'm not going to rewrite your code for you, but I can give you some pointers on how to accomplish threading.



          The thing you need to understand about perl threading is it's not a lightweight thread. You should spawn a number of threads equal to the parallelism, run them off a Thread::Queue and go from there.



          You also need to avoid any non-thread-safe modules - you can use them if you're careful but that usually means instantiating them within the thread with require and import instead of use at the start of the program.



          I would also suggest avoiding trying to do your output IO in parallel - return the thread results and coalesce them (sorting if necessary) in the 'main' thread (or spin off a single writer).



          So I'd go with something like;



          #!/usr/bin/env perl

          use strict;
          use warnings;

          use threads;

          use Thread::Queue;
          use Storable qw ( freeze thaw );

          my $NUM_THREADS = 16; #approx number of cores.

          my $translate_q = Thread::Queue->new;
          my $translate_results_q = Thread::Queue->new;


          sub translate_thread
          while ( my $item = translate_q->dequeue )
          my $seq = thaw $item;
          my $pseq = $seq->translate();
          $translate_results_q->enqueue( freeze $pseq );





          threads->create( &translate_thread ) for 1 .. $NUM_THREADS;

          while ( my $seq => $seqin->next_seq )
          $translate_q->enqueue( freeze($seq) );

          $translate_q->end;

          $_->join for threads->list;
          $translate_results_q->end;

          while ( my $result = $translate_results_q->dequeue )
          my $pseg = thaw($result);



          Note - this won't work as is, because it's missing merging with the rest of your ocde. But hopefully it illustrates how the queue and threading can work to get parallelism?



          You pass around your objects using freeze and thaw from Storable, and use the parallelism to unpack them.



          Don't go too mad on the number of threads - for primarily compute workloads (e.g. no IO) then a number of threads equal to the number of cores is about right. If they'll be blocking on IO, you can increase this number, but going past about double isn't going to do very much.



          You can't really parallelise disk IO efficiently - it just doesn't work like that. So do that in the 'main' thread.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 15:52









          Sobrique

          47.7k54381




          47.7k54381











          • Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
            – BioDeveloper
            Nov 13 at 5:05
















          • Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
            – BioDeveloper
            Nov 13 at 5:05















          Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
          – BioDeveloper
          Nov 13 at 5:05




          Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
          – BioDeveloper
          Nov 13 at 5:05

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53257579%2fhow-to-apply-multithreading-to-bioseqio-translate-code-bioperl%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

          Museum of Modern and Contemporary Art of Trento and Rovereto