DragonFly On-Line Manual Pages
TIPS(1) User Contributed Perl Documentation TIPS(1)
NAME
PDL::Tips - Small tidbits of useful arcana. Programming tidbits and
such.
SYNOPSIS
use PDL;
# Whatever happens here.
DESCRIPTION
This page documents useful idioms, helpful hints and tips for using
Perl Data Language v2.0.
Help
Use "help help" within perldl or pdl2 or use the "pdldoc" program from
the command line for access to the PerlDL documentation. HTML versions
of the pages should also be present, in the HtmlDocs/PDL directory of
the PDL distribution. To find this directory, try the following
pdl> foreach ( map{"$_/PDL/HtmlDocs"}@INC ) { p "$_\n" if -d $_ }
Indexing idioms
The following code normalizes a bunch of vectors in $a. This works
regardless of the dimensionality of $a.
$a /= $a->sumover->dummy(0);
What is actually happening?
If you want to see what the code is actually doing, try the command
PDL::Core::set_debugging(1);
somewhere. This spews out a huge amount of debug info for PDL into
STDOUT. Plans for the future include making it possible to redirect the
output, and also making it possible to select mesages with more
precision.
Many of the messages come from "Basic/Core/pdlapi.c" and you can look
at the source to see what is going on.
If you have any extra time to work on these mechanisms, inform the pdl-
porters mailing list.
Memory savings
If you are running recursively something that selects certain indices
of a large piddle, like
while(1) {
$inds = where($a>0);
$a = $a->index($inds);
$b = $b->index($inds);
func($b,$a);
}
If you are not writing to $b, it saves a lot of memory to change this
to
$b = $b->index($inds)->sever;
The new method "sever" is a causes the write-back relation to be
forgotten. It is like copy except it changes the original piddle and
returns it).
Of course, the probably best way to do the above is
$inds = xvals ($a->long);
while(1) {
$inds0 = where($a>0);
$inds1 = $inds->index($inds)->sever;
$a = $a0->index($inds1);
$b = $b->index($inds1)->sever;
func($b,$a);
}
which doesn't save all the temporary instances of $a in memory. See
"mandel.pl" in the Demos subdirectory of the PerlDL distribution for an
example.
PP speed
If you really want to write speedy PP code, the first thing you need to
do is to make sure that your C compiler is allowed to do the necessary
optimizations.
What this means is that you have to allow as many variables as possible
to go into registers:
loop(a) %{
$a() += $COMP(foo_member) * $b()
%}
expands to
for(i=0; i<10000; i++) {
a[i] += __privtrans->foo_member * b[i];
}
is about the worst you can do, since your C compiler is not allowed to
assume that "a" doesn't clobber "foo_member" which completely inhibits
vectorization. Instead, do
float foo = $COMP(foo_member);
loop(a) %{
$a() += foo * $b();
%}
This is not a restriction caused by PP but by ANSI C semantics. Of
course, we could copy the struct into local variables and back but that
could cause very strange things sometimes.
There are many other issues on organizing loops.
We are currently planning to make PP able to do fixed-width things as
well as physical piddles (where looping over the first dimensions would
be cheaper as there are less distinct increments, which might make a
difference on machines with a small number of registers).
AUTHOR
Copyright (C) Tuomas J. Lukka 1997. All rights reserved. Duplication
in the same form and printing a copy for yourself allowed.
perl v5.20.2 2015-05-24 TIPS(1)