/*************************************************************************** * blitz/array/interlace.cc * * $Id: interlace.cc,v 1.1.1.1 1999-04-09 17:59:03 ansari Exp $ * * Copyright (C) 1997,1998 Todd Veldhuizen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Suggestions: blitz-suggest@cybervision.com * Bugs: blitz-bugs@cybervision.com * * For more information, please see the Blitz++ Home Page: * http://seurat.uwaterloo.ca/blitz/ * *************************************************************************** * $Log: not supported by cvs2svn $ * */ #ifndef BZ_ARRAYINTERLACE_CC #define BZ_ARRAYINTERLACE_CC #ifndef BZ_ARRAY_H #error must be included via #endif #ifndef BZ_ARRAYSHAPE_H #include #endif BZ_NAMESPACE(blitz) /* * This header provides two collections of routines: * * interlaceArrays(shape, A1, A2, ...); * allocateArrays(shape, A1, A2, ...); * * interlaceArrays allocates a set of arrays so that their data is * interlaced. For example, * * Array A, B; * interlaceArrays(shape(10,10), A, B); * * sets up the array storage so that A(0,0) is followed by B(0,0) in * memory; then A(0,1) and B(0,1), and so on. * * The allocateArrays() routines may or may not interlace the data, * depending on whether interlacing is advantageous for the architecture. * This is controlled by the setting of BZ_INTERLACE_ARRAYS in * . */ // Warning: Can't instantiate TinyVector because causes // conflict between TinyVector::operator=(T) and // TinyVector::operator=(Range) // NEEDS_WORK -- also shape for up to N=11 // NEEDS_WORK -- shape(Range r1, Range r2, ...) (return TinyVector) // maybe use Domain objects // NEEDS_WORK -- doesn't make a lot of sense for user to provide a // GeneralArrayStorage template void makeInterlacedArray(Array& mainArray, Array& subarray, int slice) { Array tmp = mainArray(Range::all(), slice); subarray.reference(tmp); } template void makeInterlacedArray(Array& mainArray, Array& subarray, int slice) { Array tmp = mainArray(Range::all(), Range::all(), slice); subarray.reference(tmp); } template void makeInterlacedArray(Array& mainArray, Array& subarray, int slice) { Array tmp = mainArray(Range::all(), Range::all(), Range::all(), slice); subarray.reference(tmp); } // These routines always allocate interlaced arrays template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2) { GeneralArrayStorage storage; Array array(shape, 2, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3) { GeneralArrayStorage storage; Array array(shape, 3, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4) { GeneralArrayStorage storage; Array array(shape, 4, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5) { GeneralArrayStorage storage; Array array(shape, 5, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6) { GeneralArrayStorage storage; Array array(shape, 6, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); makeInterlacedArray(array, a6, 5); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7) { GeneralArrayStorage storage; Array array(shape, 7, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); makeInterlacedArray(array, a6, 5); makeInterlacedArray(array, a7, 6); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8) { GeneralArrayStorage storage; Array array(shape, 8, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); makeInterlacedArray(array, a6, 5); makeInterlacedArray(array, a7, 6); makeInterlacedArray(array, a8, 7); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8, Array& a9) { GeneralArrayStorage storage; Array array(shape, 9, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); makeInterlacedArray(array, a6, 5); makeInterlacedArray(array, a7, 6); makeInterlacedArray(array, a8, 7); makeInterlacedArray(array, a9, 8); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8, Array& a9, Array& a10) { GeneralArrayStorage storage; Array array(shape, 10, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); makeInterlacedArray(array, a6, 5); makeInterlacedArray(array, a7, 6); makeInterlacedArray(array, a8, 7); makeInterlacedArray(array, a9, 8); makeInterlacedArray(array, a10, 9); } template void interlaceArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8, Array& a9, Array& a10, Array& a11) { GeneralArrayStorage storage; Array array(shape, 11, storage); makeInterlacedArray(array, a1, 0); makeInterlacedArray(array, a2, 1); makeInterlacedArray(array, a3, 2); makeInterlacedArray(array, a4, 3); makeInterlacedArray(array, a5, 4); makeInterlacedArray(array, a6, 5); makeInterlacedArray(array, a7, 6); makeInterlacedArray(array, a8, 7); makeInterlacedArray(array, a9, 8); makeInterlacedArray(array, a10, 9); makeInterlacedArray(array, a11, 10); } // NEEDS_WORK -- make `storage' a parameter in these routines // Will be tricky: have to convert GeneralArrayStorage to // GeneralArrayStorage // These routines may or may not interlace arrays, depending on // whether it is advantageous for this platform. template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2); #else a1.resize(shape); a2.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5, a6); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); a6.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5, a6, a7); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); a6.resize(shape); a7.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5, a6, a7, a8); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); a6.resize(shape); a7.resize(shape); a8.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8, Array& a9) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5, a6, a7, a8, a9); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); a6.resize(shape); a7.resize(shape); a8.resize(shape); a9.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8, Array& a9, Array& a10) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); a6.resize(shape); a7.resize(shape); a8.resize(shape); a9.resize(shape); a10.resize(shape); #endif } template void allocateArrays(const TinyVector& shape, Array& a1, Array& a2, Array& a3, Array& a4, Array& a5, Array& a6, Array& a7, Array& a8, Array& a9, Array& a10, Array& a11) { #ifdef BZ_INTERLACE_ARRAYS interlaceArrays(shape, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); #else a1.resize(shape); a2.resize(shape); a3.resize(shape); a4.resize(shape); a5.resize(shape); a6.resize(shape); a7.resize(shape); a8.resize(shape); a9.resize(shape); a10.resize(shape); a11.resize(shape); #endif } // NEEDS_WORK -- allocateArrays for TinyVector // This constructor is used to create interlaced arrays. template Array::Array(const TinyVector& shape, int lastExtent, const GeneralArrayStorage& storage) : storage_(storage) { // Create an array with the given shape, plus an extra dimension // for the number of arrays being allocated. This extra dimension // must have minor storage order. if (ordering(0) == 0) { // Column major storage order (or something like it) length_[0] = lastExtent; storage_.setBase(0,0); for (int i=1; i < N_rank; ++i) length_[i] = shape[i-1]; } else if (ordering(0) == N_rank-1) { // Row major storage order (or something like it) for (int i=0; i < N_rank-1; ++i) length_[i] = shape[i]; length_[N_rank-1] = lastExtent; storage_.setBase(N_rank-1, 0); } else { BZPRECHECK(0, "Used allocateArrays() with a peculiar storage format"); } setupStorage(N_rank-1); } // NEEDS_WORK -- see note about TinyVector in #if 0 template Array::Array(const TinyVector& shape, int lastExtent, const GeneralArrayStorage& storage) : storage_(storage) { #ifdef BZ_DEBUG for (int i=0; i < N_rank; ++i) BZPRECHECK(shape[i].isAscendingContiguous(), "In call to allocateArrays(), a Range object is not ascending" << endl << "contiguous: " << shape[i] << endl); #endif if (ordering(0) == 0) { // Column major storage order (or something like it) length_[0] = lastExtent; storage_.setBase(0,0); for (int i=1; i < N_rank; ++i) { length_[i] = shape[i-1].length(); storage_.setBase(i, shape[i-1].first()); } } else if (ordering(0) == N_rank-1) { // Row major storage order (or something like it) for (int i=0; i < N_rank-1; ++i) { length_[i] = shape[i]; storage_.setBase(i, shape[i].first()); } length_[N_rank-1] = lastExtent; storage_.setBase(N_rank-1, 0); } else { BZPRECHECK(0, "Used allocateArrays() with a peculiar storage format"); } setupStorage(N_rank-1); } #endif BZ_NAMESPACE_END #endif // BZ_ARRAYINTER_CC