Hi David,
Sorry it's taken me so long to get back to this; I went on vacation the
day I got my program working, and I got sick as soon as I got back.
Anyway, here's a script that can reproduce the recusion limit error (even
under PDL v2.4.11). It starts threads, generates lists of random numbers
and undefs, makes them into piddles using the undef->bad idiom I'd started
out with, takes their averages, and repeats, with evals to catch the
crashes.
I hope 2013 has gotten off to a good start for you.
-- Erich
#!/usr/bin/perl
use 5.014;
use warnings;
use threads;
use Thread::Queue;
use PDL::LiteF;
# Create PDL where input could be undef, using a weird badness idiom
sub pdlify {
my @in = map {ref eq 'ARRAY' ? @$_ : $_} @_;
my @out = map {defined($_) ? pdl($_) : pdl(0)->setbadat(0)} @in;
return cat(@out);
}
# Start threads
my $maxthreads = shift // 2; # take number of threads to start as arg
my $queue = Thread::Queue->new(); # for communicating between threads
my %threads;
foreach (1..$maxthreads) {
my $new = threads->create({'context' => 'list'},\&thread_stuff,$queue);
my $tid = $new->tid();
say "Starting thread $tid";
$threads{$tid} = $new; # %threads stores refs to running threads
}
# Wait for threads to return
while (%threads) {
my $tid = $queue->dequeue(); # read which thread has finished
my ($spot,$rep,$error) = $threads{$tid}->join(); # read return values
if ($error) {
# got an error, so die
die "Thread $tid $spot rep $rep: $error\n";
} else {
# thread finished normally, so remove from set of running threads
delete $threads{$tid};
}
}
say "All $maxthreads threads got through 100,000 iterations without crashing.";
# In each thread, we'll generate lists of 1000 random numbers, some undef,
# make them into piddles, and take their means
sub thread_stuff {
my $queue = shift;
my $tid = threads->tid();
my $reps = 0;
my $exit = sub {
$queue->enqueue($tid); # tell the main program which thread died
return @_; # pass back the error message
};
while ($reps++ < 100_000) {
my (@rawdata,$pdl,$mean);
# make a list of 1000 random values, some will be undef
foreach (1..1000) {
my $x = rand(100);
push @rawdata, ($x > 99 ? undef : $x);
}
# turn the list into a piddle with undef -> BAD
eval {$pdl = pdlify(@rawdata)};
return $exit->('pdlify',$reps,$@) if $@; # note kaboom
# get the mean of the piddle
eval {$mean = $pdl->avg()};
return $exit->('mean',$reps,$@) if $@; # note kaboom
}
return $exit->(); # thread finishing without incident
}
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl