Trying to debug a threading problem in PDL
can be tedious because the error messages
don't give all the relevant information for the
threading problem. For example, this code for
showing a bug the the inv routine for PDL-2.4.7:
use PDL;
use PDL::NiceSlice;
$a = floor(5*random(3,3)-2);
print $a->info . "\n";
$ainv = $a->inv;
print $a->(,,*1)->info . "\n";
$ainvx1 = $a->(,,*1)->inv;
print $a->(,,*2)->info . "\n";
$ainvx2 = $a->(,,*2)->inv;
Yields the following output (due to
a threading bug in the inv method:
perl threaddiag.pl
PDL: Double D [3,3]
PDL: Double D [3,3,1]
PDL: Double D [3,3,2]
lu_decomp: no longer calling lu_decomp2 at /cygdrive/f/perl/usr_lib/i686-cygwin-thread-multi-64int/PDL/MatrixOps.pm line 808.
PDL: PDL::Slices::index(a,ind,c): Parameter 'ind'
PDL: Mismatched implicit thread dimension 1: should be 3, is 2
Caught at file threaddiag.pl, line 10, pkg main
Not very helpful since the actual threading
problem is from the lu_backsub routine. In
addition to not giving the actual location of
the problem in the error, we're not even
given the pdls involved, their shapes, and
the attempted threading shape so that
a fix could be found.
As is, I usually have to use the debugger
and/or add print statements to output the
needed shapes/dimensions to understand
and resolve a problem.
In addition to improved debugging, a better way to
express or specify threaded operations would be nice.
Quick, what do the following mean and are they
correctly specified? (HINT: lines from new lu_backsub)
(1) $out = $b->dummy(1,$b->dim(0))->index($perm->dummy(1,1))
(2) $out->index($r1)) -= ($lu->($row:$n1,$r1) * $out->($row:$n1))->sumover;
(3) $out->index($r1)) /= $ludiag->index($r1)->dummy(0,1);
If you find this code inpenetrable, incomprehensible, and/or
difficult to write, you are not alone. There has got to be a better
way. A couple of possible directions to investigate:
- Use some sort of semantic tag to label and work with dims
(as in recent perldl list dicussions)
- Implement another way to specify threading operations
(maybe a forall construct, like in F95 or HPF)
- Some form of interactive tool (in Padre) to write and
check these types of constructs
Here is a link to the discussion on semantic
tags:
http://mailman.jach.hawaii.edu/pipermail/perldl/2011-February/004782.html
Maybe we could make name based threading
accessible from the perl level as is done in the
PP code.
A tagdims() routine could be used to assign
IDs to each dimension (or the relevant ones)
of a pdl and slice and dimension operations
could be enhanced to support the ID tags
to disambiguate the threading issues at the
perl level.
A niceslice extension syntax could be added
to allow for dimension tags: (... ;=a-b-c) could
label dim0 as a, dim1 as b, and dim2 as c.
Maybe not the best syntax but you get the
idea....
Better user experience with PDL threading (arguably its most powerful feature) would be of great benefit to PDL users and improve the development environment and reduce the beginner learning curve.