New approach to array typemaps

Registered by Anders Logg

We are struggling with the increasing complexity of the SWIG typemaps, especially for arrays. It is difficult to map std::vector to NumPy arrays since std::vector is not flexible enough.

A "new" approach (which we have used before) is to create a simple array class that we design especially for use with NumPy.
Then it will be easier to design the required typmaps for this sepcific class, and move all the troubles to the C++ side where more developers have the necessary skills.

Blueprint information

Status:
Complete
Approver:
None
Priority:
Essential
Drafter:
None
Direction:
Needs approval
Assignee:
None
Definition:
Approved
Series goal:
None
Implementation:
Implemented
Milestone target:
milestone icon 0.9.7
Started by
Garth Wells
Completed by
Garth Wells

Related branches

Sprints

Whiteboard

GNW: Is this now complete?

Requirements:

- Can be initialised with a fixed length (default zero)
- Can be initialised with an array of known length
- Can be indexed using [] (with range checking?)
- Have a size() function
- Can be resized (no need to preserve data)
- Can return plain pointer to underlying data
- Data ownership can be changed
- Size of underlying data can be updated
- Have an array() function (added in the SWIG layer) that returns a NumPy array representation of the Array. Called from the Python side this function should only return a view of the data.

* Typemaps now exists for:

  foo(const Array<{int,uint,double}> & bar)
  Array<{int,uint,double}> foo();

* directorin typemaps now excist for:
  foo([const] Array<{double}> & bar)

* Typemaps can be instantiated for non const in typemaps by running:

     IN_NUMPY_TYPEMAP_FOR_DOLFIN_ARRAY

  For the specific types and argument names.

* If we disalow an Array that is passed from the Python interface using a NumPy array we can safely wrap all non const Array<Foo>& too. For cases when a resize might be expected we should use std::vector<Foo>& and wrap it to a argout typemap. Like it is now in for example the Intersection interface.

* Cleanup (remove?) the std::vector typemaps.
   -> We cannot remove all std::vector typemaps.
        |-> We still use std::vector<Foo*> typemaps.They might be changed with Array, but it will not be easier.
        |-> std::vector<Foo>& argout typemaps are useful to pass data out from intersection detectors and like.

Things left to consider:
* Consider which other foo* or std::vector<foo> methods should be using Array<foo>
  -> GenericFoo.{get,set} in the la interface?
  -> Expression(std::vector<uint> value_shape)?
  -> GenericMatrix.{get,set}row?

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.