Re: [eigen] Blitz++ vs. Eigen::Tensor?

[ Thread Index | Date Index | More Archives ]

On Wed, Jan 13, 2016 at 1:58 PM, Elizabeth Fischer <rpf2116@xxxxxxxxxxxx> wrote:

This comes out of a discussion we've been having over on the Blitz++ list.  Blitz++ has served a number of well with its blitz::Array, which is similar to Fortran 90 arrays or Numpy's ndarray.  We all like Blitz++ and have had no problems with it --- it's mature, stable software.  However, the original authors have all moved on and it is currently unmaintained.  We are considering whether it is worthwhile to build momentum around maintaining it and making new releases --- or whether we'd be better off using something else.

Eigen::Tensor came up today as being similar to blitz::Array in concept; however, it does not seem to be as mature and might not do all the things we're used to doing with blitz::Array.  I'm trying to better understand Eigen::Tensor, with respect to the things I use Blitz++ for.

1. I frequently use blitz::Array to point into pre-existing memory blocks, memory it does not "own."  That way, I can write algorithms that take a blitz::Array as an argument and know I'll be able to use them in a wide variety of input formats (including data that originated in Fortran 90 or Numpy arrays).  Is Eigen::Tensor able to do this, or does it insist on owning its memory?

You have 2 choices: create a Tensor, which owns its memory, or create a TensorMap, which wrap an existing block of memory that the caller is responsible for managing.

2. Blitz::Array is quite flexible with its dope vector.  You can make an array with any set of strides.  Column major, row major.  Any base on each dimension (0, 1, 17, etc).  Even non-unit strides.  Even non-contiguous array slices.  I use this, for example, to provide compatibility with Fortran..  Any Fortran 90 array can be passed into C++ code and turned into a blitz::Array with exactly the same shape, base, shape, etc.  For example, see:
Passing stuff between C++ and Fortran would be a lot more problematic if the C++ array package does not support all the possibilities supported by Fortran 90.

Once you've created a TensorMap to wrap a contiguous memory buffer, you can call the slice operation to have strided access. It probably not as powerful than what blitz provide, but it's a start. 

3.. Does Eigen::Tensor have a shared memory or shared pointer kind of model?  Blitz++ does --- and I'm not sure whether it's a good idea or not: multiple blitz::Array objects can share the same underlying memory.  The blitz::Array class is essentially a shared_ptr<> plus dope vector.  C++11 has cleaner semantics, and it should be possible to have a core "dumb" array and appropriate smart pointer stuff around it.  I've not figured out how this would work, or whether it would be better in the end than what Blitz++ does

Multiple TensorMap objects can share the same memory buffer. You could also create a memory buffer using a regular tensor, and access its buffer using one or more TensorMaps. For example, you could write something like:
   Eigen::Tensor<float, 2> tensor_that_owns_its_memory(7, 5);
   Eigen::TensorMap<Eigen::Tensor<float, 2> > tensor_that_reuses_existing_storage(, 7, 5);

4. Has someone considered simply using Blitz++ as the basis for Eigen::Tensor?  It looks like the license are basically compatible:
The authors of Blitz++ could probably be convinced to re-license it if that made things easier for the Eigen project.  They're really done with the code and have lost interest in maintaining it.

I looked at Blitz++ before starting to work on the Eigen tensor module, but I couldn't see a way to bring blitz++ to the level of performance we need. It seemed easier to design a new tensor library from scratch to take advantage of multiple cores and/or gpus and extend its API over time rather than trying improve the performance of blitz++.


Mail converted by MHonArc 2.6.19+