Boost logo

Boost :

From: Randy Roberts (rroberts_at_[hidden])
Date: 2000-12-08 17:14:25


--- In boost_at_[hidden], Ronald Garcia <rgarcia4_at_c...> wrote:
> At certain times it is necessary to work with both "C" style and
> "Fortran" style arrays, especially when interfacing with fortran
which
> (IMHO) is unfortunately necessary at times. I think that given the
> right abstractions, code to support a fortran view of arrays can
also
> support arbitrary dimension permutations without greatly affecting
the
> complexity of the code.
>
> Since not everyone is going to need altered views of arrays, simple
> abstractions that provide enough hooks to implement an altered view
> as an extension of the base library would suffice and provide great
> flexibility at what should be a minimal cost in complexity. This
> mechanism could also be a way of providing a flattened view of
arrays
> if the standard iterators iterate across N-1 dimensional subarrays,
> which I think is the way to go.

I think the important thing to realize here, is that us poor sm*cks
who have to work with legacy F77 code not just need a Fortran **view**
of an array, we need access to a pointer to the contiguous,
Fortran-ordered array data.

There are two problems with a Fortran view approach to this problem...

First, if the view causes a copy of the data into a Fortran-ordered
array (it really isn't a view, is it), then we may be faced with large
copying overheads in both space and time.

Second, if we were only to have a Fortran view of the array with
iterators that gallop through the strided generalized slices of an
underlying C-ordered C-style array, then there is no way to obtain
from this iterator a pointer to a contiguous Fortran-ordered array.
One would have to use something akin to std::copy(,,) into a temporary
buffer, and we are right back to the large copying overheads in both
space and time.

I have played with N-dimensional arrays, and have delegated the
storage order to a separate class. This class would also be
responsible for which iterators to use, e.g.

// C ordering could use a simple T* iterator
// for both array level and all sub-array's

template <typename T, int N>
struct C_ordering
{
   typedef T* iterator;
   typedef C_ordering<T,N-1> SubOrdering;

   // ...
   // Include methods to create sub-array's SubOrdering, etc.
};

// The case of the sub-array F77 ordering would need a more
// complex striding iterator.

template <typename T, int N, int Norig=N>
struct F77_ordering
{
   typedef SomethingMoreComplex<T,N,Norig> iterator;
   typedef F77_ordering<T,N-1,Norig> SubOrdering;

   // ...
   // Include methods to create sub-array's SubOrdering, etc.
};

// The case of the array level F77 ordering could use a simple
// T* iterator into the entire C-array

template <typename T, int N>
struct F77_ordering<T,N,N>
{
   typedef T* iterator;
   typedef F77_ordering<T,N-1,N> SubOrdering;

   // ...
   // Include methods to create sub-array's SubOrdering, etc.
};

template <typename T, int N, class Ordering = C_ordering<T,N> >
class array : public Ordering
{
public:

   typedef typename Ordering::iterator iterator;
   // ...

private:

   typedef sub_array<T,N-1,typename Ordering::SubOrdering>
the_sub_array;

   T *data;
};

typedef array< double, 3, F77_ordering<double,3> > f77_array3_double;

The common code would be placed in array and sub_array, and defer
order-based decisions to the Ordering Strategy/Policy.

I wasn't planning on coming up with a working demonstration of this
technique unless there was enough interest in pursuing this.

Let me know.

Randy

--
Randy M. Roberts          |    "His men would follow him anywhere,
rsqrd_at_[hidden]            |     but only out of morbid curiosity."
work: (505)665-4285       |            -- a performance review

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk