Subject: Re: [ublas] [bindings][lapack] Interface design
From: Thomas Klimpel (Thomas.Klimpel_at_[hidden])
Date: 2008-12-01 19:14:58
Rutger ter Borg wrote:
> * What consistent argument-interface are we going to offer to the user?
> What I mean here, is making the path consistent when extra arguments are
> made available to the user.
This is a good question, but not an easy one. Take geev for example: you can compute
- no eigenvectors
- left eigenvectors only
- right eigenvectors only
- both left and right eigenvectors.
Chris Rodgers recently asked on this mailing list:
> // Question 3: Is this syntax the "correct" way to call geev?
> geev(A4,w4,(matrix<std::complex<double>, column_major>*)NULL,&vecs4,boost::numeric::bindings::lapack::optimal_workspace());
This shows that using a pointer for an optional argument as done by geev creates its own quirks.
The conclusion is that I'm often not even able to design a good interface for a single given routine, so I have little hope to come up with a good design of the argument-interface that applies to all routines. On the other hand, I think one could come up with a good interface for geev, if one just tries hard enough.
> I would prefer agument extension paths which keep the first arguments on the
> same place, like
> gesdd( A, s )
> gesdd( A, s, U, VT )
> gesdd( A, s, U, VT, Jobz )
> gesdd( A, s, U, VT, Jobz, LW )
> gesdd( A, s, U, VT, Jobz, w, iw )
I would also prefer an argument-interface where the meaning of a certain argument-position doesn't change unpredictably.
> I think when having (nearly) automatically generated bindings, this argument
> extension path should be very consistent, otherwise it becomes difficult to
> implement :-).
To be honest, I think the real problem is finding a good intuitive argument-interface. I'm also not sure whether a good argument-interface is necessarily easier to generate automatically than a bad one.
> The benefit is that increased consistency will make the
> library easier to use from a user perspective as well.
> A suggestion for a good set of rules will help here.
I think this is the central point. But it might be necessary to start designing good interfaces for individual routines (with later general guidelines in mind), before formulating general guidelines. Interesting candidates to look at might be geev and heevx, because their current argument-interface is rather suboptimal. Karl's suggestion of using an option object might help finding a good interface for heevx, but I doubt that it will help for geev.
> * The bindings give integer return value(s) in fortran and/or C-style.
> Could this be improved by the introduction of C++ error-handling with
> exceptions, or perhaps even better, implemented by Policies, see, e.g.,
This is a good idea, and might actually be quite important for potential users of the library. And it would allow to translate the info error numbers into meaningful error messages. On the other hand, xerrbla might be called anyway by the lapack routine, without any policy being able to prevent this. (But it should be possible to build lapack in a way that this doesn't happen.)
> * I would like to propose that driver routines and computational routines
> are split into their own files. E.g., GESV and GETRI are to be put in
> gesv.hpp, getri.hpp, etc. I think this makes it easier for a user where to
> find what function.
This another good question. The blas bindings just use blas1, blas2 and blas3 for splitting the computational routines into files. One possibility to split lapack computational routines into files would be based on the operation, stripping the matrix type. So the file xxev.hpp would contain the bindings for geev, ggev, hbev, heev, hpev, sbev, spev, stev and syev. Now it could be argued whether ggev and stev are really related to the other routines, but at least it would be obvious to the user where to find what function.
> Please let me know your thoughts,
I just tried to give you my feedback. Don't let me stop you moving forward, your work looks very promising.