octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: some notes about mex support in Octave


From: Paul Kienzle
Subject: Re: some notes about mex support in Octave
Date: Sat, 8 Jul 2006 11:21:34 -0400


On Jul 8, 2006, at 3:45 AM, John W. Eaton wrote:

Paul Kienzle and I were having an off-list discussion about mex
support in Octave.  That seemed appropriate when I thought that
adopting the code from Octave Forge would be relatively quick, even
with my plans to change the implementation of the mxArray
object to be a wrapper around an octave_value object.

I did a fair amount of work on this conversion, but the more I
understand about the way the mxArray object is supposed to be used,
the more I think it is impossible to simply wrap an octave_value
object.  Since the mxArray documentation says that it is perfectly
acceptable to screw around with the dimensions and data separately, I
think there is no way that we can do this on top of octave_value (at
least not given the current implementation of octave_value, and I'm
not really interested in making octave_value less safe just to support
mxArray).

The only alternative I see is to implement mxArray separately to match
the documentation for it, then convert to and from octave_value as
needed (when passing values to/from mex functions and Octave, either
by way of calling the mex function or mexCallMatlab).  These
conversions will require copies of the data, which I know is not
ideal, but I think this is the only way to preserve the semantics of
the mx* functions.

The current mex code makes a copy when getting a value from a mxArray
and again when putting the value back to an octave_value.  This was
expedience on my part --- I was more concerned about getting something
working so that I could use an existing mex file than I was about
performance.

I think we can handle many cases without copying by using the Array
class to do the allocation and fortran_vec() to access the data.
Users do not need to directly manipulate pointers and dimensions
any more than oct-file writers do because they can preallocate an
array of the correct size.  We can still support it by maintaining
a flag that indicates that the pointer and dims no longer reflect
the underlying octave value, but performance will suffer because a
copy will be triggered on return to Octave.

Since this code will be more difficult to write I suggest that
those who care about performance of mex files contribute to the
effort.

Maybe it won't be too hard to do this with templates and some simple
inheritance structure.  All we really have to do is implement a set of
containers.  There are very few actual operations on mxArrays and most
seem to be quite simple.  The mxArray class can be

  class mxArray {
    public:
      ...
    private:
      int class;
      int ndims;
      int *dims;
      char *name;
  };

This will be a virtual base class.  It won't be possible to create an
mxArray object directly.  Only specific derived types can be
constructed.  (And anyway, users will only be able to manipulate these
objects using the mx* functions, same as in Matlab's mex interface).

For numeric data, something like

  template <type T> class mxArray_number : public mxArray {
    public:
      ...
    private:
      T *pr;
      T *pi;
  };

can be instantiated for the logical, char, double, single, and
{u,}int{8,16,32,64} types.

For sparse arrays:

  class mxArray_sparse : public mxArray_number<double> {
    public:
      ...
    private:
      int *ir;
      int *jc;
      int nzmax;
  };

For structs:

  class mxArray_struct : public mxArray {
    public:
      ...
    private:
      int nfields;
      char **fields;
      mxArray **data;
  };

For cells:

  class mxArray_cell : public mxArray {
    public:
      ...
    private:
      mxArray *data;
  };

We leave essentially all memory management to the user, who is
expected to pass pointers around and explicitly use mxDuplicateArray
to make a copies.

I think templates are going to get in our way rather than help.
The data in an mxArray is just void pointer whose interpretation
is determined by the class of the data.  Sparse has additional i,j
indices.  I'm guessing structs are implemented in Matlab as cell
arrays with a name vector for the first dimension.  We would have
to handle them differently to map onto octave structs.

We will add an "mxArray *make_mxArray (void) const" member function to
each specific type in Octave that can be converted to an mxArray.  The
new member funtion will return a newly allocated mxArray object of the
appropriate type.  This way, the conversion will be extensible (at
least as much as is possible given the fixed definition of mxArray).
The octave_base_value class will get a default version that throws an
error, so no changes will be required of existing classes derived from
octave_base_value.

You may want to make the default version attempt a conversion to a
double matrix so that reasonable defaults can happen for extension
types.

Since converting from octave_value <-> mxArray will require a copy,
users who expect to be able to call mxGetPr on the argument to a mex
function and have modifications to that data show up in the mex
function's caller will be disappointed as that will not work.  Then
again, the documentation says that you should not expect it to work in
Matlab either.

Using fortran_vec as I suggested will probably force a copy.  Given
the above semantics I would be tempted to use data() and cast away
the const so that simply querying an input argument to a function
doesn't force a copy.  This may lead to unexpected behaviour, e.g.,
by mutating existing variables but that is a documented property of
the mex interface so caveat emptor.

- Paul



reply via email to

[Prev in Thread] Current Thread [Next in Thread]