casacore
Loading...
Searching...
No Matches
TiledLineStepper.h
Go to the documentation of this file.
1//# TiledLineStepper.h: Step a Vector cursor optimally through a tiled Lattice
2//# Copyright (C) 1997,1998,1999,2000
3//# Associated Universities, Inc. Washington DC, USA.
4//#
5//# This library is free software; you can redistribute it and/or modify it
6//# under the terms of the GNU Library General Public License as published by
7//# the Free Software Foundation; either version 2 of the License, or (at your
8//# option) any later version.
9//#
10//# This library is distributed in the hope that it will be useful, but WITHOUT
11//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13//# License for more details.
14//#
15//# You should have received a copy of the GNU Library General Public License
16//# along with this library; if not, write to the Free Software Foundation,
17//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18//#
19//# Correspondence concerning AIPS++ should be addressed as follows:
20//# Internet email: casa-feedback@nrao.edu.
21//# Postal address: AIPS++ Project Office
22//# National Radio Astronomy Observatory
23//# 520 Edgemont Road
24//# Charlottesville, VA 22903-2475 USA
25
26#ifndef LATTICES_TILEDLINESTEPPER_H
27#define LATTICES_TILEDLINESTEPPER_H
28
29//# Includes
30#include <casacore/casa/aips.h>
31#include <casacore/lattices/Lattices/LatticeNavigator.h>
32#include <casacore/lattices/Lattices/LatticeIndexer.h>
33#include <casacore/casa/Arrays/IPosition.h>
34
35
36namespace casacore { //# NAMESPACE CASACORE - BEGIN
37
38// <summary>
39// Step a Vector cursor optimally through a tiled Lattice.
40// </summary>
41// <use visibility=export>
42
43// <reviewed reviewer="Peter Barnes" date="1999/10/30" tests="tTiledLineStepper.cc">
44// </reviewed>
45
46// <prerequisite>
47// <li> <linkto class=LatticeNavigator> LatticeNavigator </linkto>
48// </prerequisite>
49
50// <etymology>
51// TiledLineStepper is used to step a Vector cursor optimally through
52// a Lattice that is tiled.
53// </etymology>
54
55// <synopsis>
56// When you wish to traverse a Lattice (say, a PagedArray or an Image) you
57// will usually create a LatticeIterator. Once created, you may attach a
58// LatticeNavigator to the iterator. A TiledLineStepper, is a concrete class
59// derived from the abstract LatticeNavigator that allows you to move
60// a Vector cursor through the Lattice in a way that will minimize the
61// amount of cache memory consumed.
62// <p>
63// Some Lattices (in particular PagedArrays) are stored (on disk) in
64// tiles. For an N-dimensional Lattice a tile is an N-dimensional
65// subsection with fewer elements along each axis. For example a Lattice of
66// shape [512,512,4,32] may have a tile shape of [32,16,4,16], and there
67// will be 16*32*1*2 (=1024) tiles in the entire Lattice. To allow efficient
68// access of the data in a Lattice some tiles are cached in memory. As each
69// tile may consume a fair bit of memory (in this example 128kBytes,
70// assuming each element consumes 4 bytes), it is desirable to minimise the
71// number of tiles held in the cache. But it is also desirable to minimise
72// the number of times a tiles must be read into or written from the
73// cache as this may require a time consuming operation like disk I/O.
74// <p>
75// Now suppose you wanted to traverse a Lattice with a Vector cursor of
76// length 512 pixel aligned along the x-axis. Using a
77// <linkto class=LatticeStepper>LatticeStepper</linkto>, each Vector is
78// retrieved from the Lattice sequentially and without any consideration of
79// the underlying tile shape. What is the optimal cache size for the above
80// example?
81// <p>
82// Suppose we have a cache size of 16 ie., the number of tiles along the
83// x-axis. Then Vectors beginning at positions [0,0,0,0] to [0,15,0,0] will
84// be stored in the cache. But the next Vector beginning at position
85// [0,16,0,0] will flush the cache and read in another 16 tiles. This I/O
86// takes time and will occur 16 times for each plane in the four dimensional
87// Lattice. Further when the cursor moves to position [0,0,1,0] the 16 tiles
88// that where initially in the cache will need to be read again. To avoid
89// all this cache I/O it is better to have a bigger cache.
90// <p>
91// Suppose the cache size is 16*32 (=512) ie., enough tiles to contain an
92// (x,y)-plane. Then the cache size will not be flushed until the cursor is
93// moved to position [0,0,0,16]. Further the cache will never need to read
94// back into memory tiles that had previously been stored in there. The
95// cache is big enough to store tiles until they have been completely
96// used. But this cache is 64MBytes in size, and consumes too much memory
97// for many computers.
98// <p>
99// This where a TiledLineStepper is useful. Because it knows the shape of the
100// tiles in the underlying Lattice it moves the cursor to return all the
101// Vectors in the smallest possible cache of tiles before moving on to the
102// next set of tiles. Using the above example again, the TiledLineStepper will
103// move the beginning of the Vector cursor in the following pattern.
104// <srcblock>
105// [0,0,0,0], [0,1,0,0], [0,2,0,0], ... [0,15,0,0]
106// [0,0,1,0], [0,1,1,0], ... [0,15,1,0],
107// ... [0,15,3,0],
108// [0,0,0,1], ... [0,15,3,15]
109// </srcblock>
110// Moving the Vector cursor through all 16*4*16 (=1024 positions) can be
111// done by caching only 16 tiles in memory (those along the x-axis). Hence
112// the cache size need only be 2MBytes in size. Further once all 1024
113// vectors have been returned it is not necessary to read these 16 tiles
114// back into memory. All the data in those tiles has already been
115// accessed. Using a TiledLineStepper rather than a LatticeStepper has,
116// in this example, resulted in a drop in the required cache size from
117// 64MBytes down to 2MBytes.
118// <p>
119// In constructing a TiledLineStepper, you specify the Lattice shape, the
120// tile shape and the axis the Vector cursor will be aligned with. Specifying
121// an axis=0 will align the cursor with the x-axis and axis=2 will produce a
122// cursor that is along the z-axis. The length of the cursor is always the
123// same as the number of elements in the Lattice along the axis the cursor
124// is aligned with.
125// <br>It is possible to use the function <src>subSection</src> to
126// traverse only a subsection of the lattice.
127// <p>
128// The cursor position can be incremented or decremented to retrieve the next
129// or previous Vector in the Lattice. The position of the next Vector in the
130// Lattice will depend on the tile shape, and is described above. Within a tile
131// the Vector cursor will move first through the x-axis and then the y-axis
132// (assuming we have a cursor oriented along the z-axis). In general the lower
133// dimensions will be exhausted (within a tile) before moving the cursor
134// through higher dimensions. This intra-tile behaviour for cursor movement
135// extends to the inter-tile movement of the cursor between tiles.
136// </synopsis>
137
138// <example>
139// This example is of a global function that will do a 2-D inplace
140// complex Fourier transform of an arbitrary large Lattice (which
141// must have at least two dimensions).
142//
143// A two dimensional transform is done by successive one dimensional
144// transforms along all the rows and then all the columns in the
145// lattice. Scoping is used to destroy iterators once they have been
146// used. This frees up the cache memory associated with the cursor in each
147// iterator.
148//
149// <srcblock>
150// void FFT2DComplex (Lattice<Complex>& cArray,
151// const Bool direction)
152// {
153// const uInt ndim = cArray.ndim();
154// AlwaysAssert(ndim > 1, AipsError);
155// const IPosition latticeShape = cArray.shape();
156// const uInt nx=latticeShape(0);
157// const uInt ny=latticeShape(1);
158// const IPosition tileShape = cArray.niceCursorShape();
159//
160// {
161// TiledLineStepper tsx(latticeShape, tileShape, 0);
162// LatticeIterator<Complex> lix(cArray, tsx);
163// FFTServer<Float,Complex> fftx(IPosition(1, nx));
164// for (lix.reset();!lix.atEnd();lix++) {
165// fftx.fft(lix.rwVectorCursor(), direction);
166// }
167// }
168// {
169// TiledLineStepper tsy(latticeShape, tileShape, 1);
170// LatticeIterator<Complex> liy(cArray, tsy);
171// FFTServer<Float,Complex> ffty(IPosition(1, ny));
172// for (liy.reset();!liy.atEnd();liy++) {
173// ffty.fft(liy.rwVectorCursor(), direction);
174// }
175// }
176// }
177// </srcblock>
178// </example>
179
180// <motivation>
181// Moving through a Lattice by equal sized chunks, and without regard
182// to the nature of the data, is a basic and common procedure.
183// </motivation>
184
185// <todo asof="1997/03/28">
186// <li> Support for Matrix and higher dimensional cursors can be used.
187// </todo>
188
189
191{
192public:
193
194 // Construct a TiledLineStepper by specifying the Lattice shape,
195 // a tile shape and the axis along which the Vector cursor will lie
196 // (0 means the x-axis). Is is nearly always advisable to make the
197 // tileShape identical to the Lattice tileShape. This can be obtained by
198 // <src>lat.niceCursorShape(lat.advisedMaxPixels())</src>
199 // where <src>lat</src> is a Lattice object.
201 const IPosition& tileShape,
202 const uInt axis);
203
204 // The copy constructor uses copy semantics.
206
208
209 // The assignment operator uses copy semantics.
211
212 // Increment operator (postfix or prefix version) - move the cursor
213 // forward one step. Returns True if the cursor was moved.
214 virtual Bool operator++(int);
215
216 // Decrement operator (postfix or prefix version) - move the cursor
217 // backwards one step. Returns True if the cursor was moved.
218 virtual Bool operator--(int);
219
220 // Function to move the cursor to the beginning of the Lattice. Also
221 // resets the number of steps (<src>nsteps</src> function) to zero.
222 virtual void reset();
223
224 // Function which returns "True" if the cursor is at the beginning of the
225 // Lattice, otherwise, returns "False"
226 virtual Bool atStart() const;
227
228 // Function which returns "True" if an attempt has been made to increment
229 // the cursor beyond the end of the Lattice.
230 virtual Bool atEnd() const;
231
232 // Function to return the number of steps (increments & decrements) taken
233 // since construction (or since last reset). This is a running count of
234 // all cursor movement (operator++ or operator--), even though
235 // N-increments followed by N-decrements will always leave the cursor in
236 // the original position.
237 virtual uInt nsteps() const;
238
239 // Function which returns the current position of the beginning of the
240 // cursor. The <src>position</src> function is relative to the origin
241 // in the main Lattice.
242 // <group>
243 virtual IPosition position() const;
244 // </group>
245
246 // Function which returns the current position of the end of the
247 // cursor. The <src>endPosition</src> function is relative to the origin
248 // in the main Lattice.
249 // <group>
250 virtual IPosition endPosition() const;
251 // </group>
252
253 // Functions which returns the shape of the Lattice being iterated
254 // through. <src>latticeShape</src> always returns the shape of the main
255 // Lattice while <src>subLatticeShape</src> returns the shape of any
256 // sub-Lattice defined using the <src>subSection</src> function.
257 // <group>
258 virtual IPosition latticeShape() const;
259 virtual IPosition subLatticeShape() const;
260 // </group>
261
262 // Function which returns the shape of the cursor. This always includes
263 // all axes (ie. it includes degenerates axes)
264 virtual IPosition cursorShape() const;
265
266 // Function which returns the axes of the cursor.
267 virtual IPosition cursorAxes() const;
268
269 // Function which returns the shape of the "tile" the cursor will iterate
270 // through before moving onto the next tile. THIS IS NOT THE SAME AS THE
271 // TILE SHAPE USED BY THE LATTICE. It is nearly the same except that the
272 // axis the cursor is aligned with is replaced by the shape of the Lattice
273 // on that axis. eg., If a Lattice has a shape of [512,512,4,32] and a
274 // tile shape of [32,16,4,16] then <src>tileShape()</src> will return
275 // [512,16,4,16] if the cursor is along the x-axis and [32,512,4,16] if the
276 // cursor is along the y-axis.
278
279 // Function which returns "True" if the increment/decrement operators have
280 // moved the cursor position such that part of the cursor beginning or end
281 // is hanging over the edge of the Lattice. This always returns False.
282 virtual Bool hangOver() const;
283
284 // Functions to specify a "section" of the Lattice to step over. A section
285 // is defined in terms of the Bottom Left Corner (blc), Top Right Corner
286 // (trc), and step size (inc), on ALL of its axes, including degenerate
287 // axes. The step size defaults to one if not specified.
288 // <group>
289 virtual void subSection (const IPosition& blc, const IPosition& trc);
290 virtual void subSection (const IPosition& blc, const IPosition& trc,
291 const IPosition& inc);
292 // </group>
293
294 // Return the bottom left hand corner (blc), top right corner (trc) or
295 // step size (increment) used by the current sub-Lattice. If no
296 // sub-Lattice has been defined (with the <src>subSection</src> function)
297 // these functions return blc=0, trc=latticeShape-1, increment=1, ie. the
298 // entire Lattice.
299 // <group>
300 virtual IPosition blc() const;
301 virtual IPosition trc() const;
302 virtual IPosition increment() const;
303 // </group>
304
305 // Return the axis path.
306 // See <linkto class=LatticeStepper>LatticeStepper</linkto> for a
307 // description and examples.
308 virtual const IPosition& axisPath() const;
309
310 // Function which returns a pointer to dynamic memory of an exact copy
311 // of this instance. The pointer returned by this function must
312 // be deleted externally.
313 virtual LatticeNavigator* clone() const;
314
315 // Function which checks the internal data of this class for correct
316 // dimensionality and consistant values.
317 // Returns True if everything is fine otherwise returns False
318 virtual Bool ok() const;
319
320 // Calculate the cache size (in tiles) for this type of access to a lattice
321 // in the given row of the tiled hypercube.
322 virtual uInt calcCacheSize (const IPosition& cubeShape,
323 const IPosition& tileShape,
324 uInt maxCacheSize, uInt bucketSize) const;
325
326private:
327 // Prevent the default constructor from being used.
329
330
331 IPosition itsBlc; //# Bottom Left Corner
332 IPosition itsTrc; //# Top Right Corner
333 IPosition itsInc; //# Increment
334 LatticeIndexer itsSubSection; //# The current subsection
335 LatticeIndexer itsIndexer; //# For moving within a tile
336 LatticeIndexer itsTiler; //# For moving between tiles
337 IPosition itsIndexerCursorPos; //# The current position of the iterator.
338 IPosition itsTilerCursorPos; //# The current position of the iterator.
339 IPosition itsCursorShape; //# The shape of the cursor for itsIndexer
340 IPosition itsTileShape; //# The tile shape (= itsTiler cursor shape)
341 IPosition itsAxisPath; //# Path for traversing
342 uInt itsNsteps; //# The number of iterator steps taken so far;
343 uInt itsAxis; //# The axis containing the data vector
344 Bool itsEnd; //# Is the cursor beyond the end?
345 Bool itsStart; //# Is the cursor at the beginning?
346};
347
348
349
350} //# NAMESPACE CASACORE - END
351
352#endif
virtual Bool atEnd() const
Function which returns "True" if an attempt has been made to increment the cursor beyond the end of t...
virtual Bool operator++(int)
Increment operator (postfix or prefix version) - move the cursor forward one step.
virtual IPosition blc() const
Return the bottom left hand corner (blc), top right corner (trc) or step size (increment) used by the...
virtual LatticeNavigator * clone() const
Function which returns a pointer to dynamic memory of an exact copy of this instance.
virtual Bool atStart() const
Function which returns "True" if the cursor is at the beginning of the Lattice, otherwise,...
TiledLineStepper(const TiledLineStepper &other)
The copy constructor uses copy semantics.
TiledLineStepper(const IPosition &latticeShape, const IPosition &tileShape, const uInt axis)
Construct a TiledLineStepper by specifying the Lattice shape, a tile shape and the axis along which t...
TiledLineStepper()
Prevent the default constructor from being used.
virtual Bool ok() const
Function which checks the internal data of this class for correct dimensionality and consistant value...
virtual Bool hangOver() const
Function which returns "True" if the increment/decrement operators have moved the cursor position suc...
virtual void subSection(const IPosition &blc, const IPosition &trc, const IPosition &inc)
virtual uInt calcCacheSize(const IPosition &cubeShape, const IPosition &tileShape, uInt maxCacheSize, uInt bucketSize) const
Calculate the cache size (in tiles) for this type of access to a lattice in the given row of the tile...
virtual IPosition trc() const
virtual const IPosition & axisPath() const
Return the axis path.
virtual IPosition position() const
Function which returns the current position of the beginning of the cursor.
virtual IPosition subLatticeShape() const
virtual IPosition cursorAxes() const
Function which returns the axes of the cursor.
virtual IPosition latticeShape() const
Functions which returns the shape of the Lattice being iterated through.
TiledLineStepper & operator=(const TiledLineStepper &other)
The assignment operator uses copy semantics.
virtual uInt nsteps() const
Function to return the number of steps (increments & decrements) taken since construction (or since l...
virtual void subSection(const IPosition &blc, const IPosition &trc)
Functions to specify a "section" of the Lattice to step over.
virtual Bool operator--(int)
Decrement operator (postfix or prefix version) - move the cursor backwards one step.
IPosition tileShape() const
Function which returns the shape of the "tile" the cursor will iterate through before moving onto the...
virtual void reset()
Function to move the cursor to the beginning of the Lattice.
virtual IPosition cursorShape() const
Function which returns the shape of the cursor.
virtual IPosition increment() const
virtual IPosition endPosition() const
Function which returns the current position of the end of the cursor.
this file contains all the compiler specific defines
Definition mainpage.dox:28
unsigned int uInt
Definition aipstype.h:49
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40