How to apply multithreading to Bio::SeqIO translate code (Bioperl)?
up vote
1
down vote
favorite
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
add a comment |
up vote
1
down vote
favorite
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
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
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
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
multithreading perl bioperl
edited Nov 12 at 9:01
asked Nov 12 at 7:30
BioDeveloper
3242521
3242521
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
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.
Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
– BioDeveloper
Nov 13 at 5:05
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
up vote
2
down vote
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.
Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
– BioDeveloper
Nov 13 at 5:05
add a comment |
up vote
2
down vote
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.
Thanks, good piece of advice @Sobrique . I will try to make it work with remaining code.
– BioDeveloper
Nov 13 at 5:05
add a comment |
up vote
2
down vote
up vote
2
down vote
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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