1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
=head1 NAME
PDL::Internals - description of the current internals
=head1 DESCRIPTION
=head2 Intro
This document explains various aspects of the current implementation
of PDL. If you just want to use PDL for something, you definitely
do not need to read this. Even if you want to interface your C routines
to PDL or create new PDL::PP functions, you do not need to read this
(though it may be informative). This document is primarily
intended for people interested in debugging or changing the internals
of PDL. To read this, a good understanding of the C language
and programming and data structures in general is required, as well
as some perl understanding. If you read through this document
and understand all of it and are able to point what any part of
this document refers to in the PDL core sources and additionally
struggle to understand PDL::PP, you will be awarded the title
"PDL Guru" (of course, the current version of this document
is so incomplete that this is not yet the case).
B<Warning:> If it seems that this document has gotten out of date,
please inform the PerlDL developers email list (address in the README
file) about it. This may well happen.
=head2 Piddles
Currently, a pdl data object is a hash ref which contains the element
PDL, which is a pointer to a pdl structure, as well as some other fields.
The file Core.pm uses some of these fields and the file pdlhash.c converts
these to C when necessary.
The pdl struct is defined in pdl.h and the meanings of the fields
are
=over 8
=item magicno
A magic number, used to check whether something really is a piddle
when debugging.
=item state
Various flags about the state of the pdl, such as whether the parents
of this pdl have been altered at some point.
=item trans
Where this pdl was obtained from. This pointer may be null, in which
case this pdl is not getting any dataflow from anywhere.
Note, however that being non-null does not mean that data is flowing:
$a = pdl 2,3,4; $b = pdl 4,5,6;
$c = $a + $b; # Note: no dataflow (not asked for)
here, the trans field in $c contains a pointer to a transformation.
Only when $a or $b is changed, is the transformation destroyed and
the field cleared. To see whether data is flowing, check the flags
field of the trans struct.
=item vafftrans
This is intended for speeding up e.g. the chaining of affine
transformations. See C<pdlapi.c> for the code handling this.
Also, C<slices.pd> defines some things with / for this.
=item sv
Pointer to the hash object. May be null if this pdl does not have
a perl counterpart.
=item datasv, data
The field datasv is a pointer to the perl SV containing the data string.
These may be null before the pdl is finally physicalized.
=item nvals
How many values there are in data
=item datatype
The type of the data stored in the data vector.
=item dims, ndims
The dimensions of this pdl. Remember to physicalize the pdl before using.
=item dimincs
As an optimization, an increment for each dimension is stored here.
In contrast to previous alpha versions, these are required to correspond
exactly do dims. If you want to optimize for affine transformations,
use the trans or vtrans.
=item threadids, nthreadids
This is where the threading tags are stored. The way this works
is that ndims and dims hold I<all> dimensions of the pdl, including
threaded dimensions. The real dimensions of the pdl extend from 0 to
threadids[0]-1, the thread dimensions with id 0 extend from
threadids[0] to threadids[1]-1 and the thread dimensions with the last id
extend from threadids[nthreadids-1] to threadids[nthreadids]-1.
For example, if a pdl has dimensions (2,3,4,5) (= 120 elements)
and nthreadids==2 and threadids={1,3,4}, there is one "real" dimensions
with size 2, two dimensions with threadid 0 (3 and 4) and the dimensions
with size 5 has threadid 1.
=item progenitor, future_me
See the section on families below
=item children
The children of this pdl i.e. where data is flowing to from this pdl.
=item living_for
XXX Not quite clear right now. Has to do with families
=item def_*
To avoid mallocs, there is a suitable amount of space already allocated
for each pointer in this pdl, with the ideology that if you have more
than six-dimensional data you must be willing to settle for a little
more overhead.
=item magic
If this pdl is magical (e.g. if it is bound to something), this
pointer is non-null and you must call the appropriate magic-handling
routines when using the pdl.
=item hdrsv
A ``header'' SV * that can be set and accessed from outside.
Can be used to include any perl object in a piddle.
=head2 Transformations
Each transformation has a virtual table which contains
various information about that transformation. Usually
transformations are generated with PDL::PP so it's better to see
that documentation.
=head2 Freeing
Currently, not much is freed, especially when dataflow is done.
This is bound to change pretty soon.
=head2 Threading
The file pdlthread.c handles most of the threading matters.
The threading is encapsulated in the structure pdlthread.h.
=head1 AUTHOR
Copyright(C) 1997 Tuomas J. Lukka (lukka@fas.harvard.edu).
Redistribution in the same form is allowed but reprinting requires
a permission from the author.
|