← Back to team overview

dolfin team mailing list archive

Re: Reduce number of attributes in dolfin namespace (python)

 

On Saturday 29 March 2008 19:54:47 Anders Logg wrote:
> On Sat, Mar 29, 2008 at 06:17:00PM +0100, Ola Skavhaug wrote:
> > Garth N. Wells skrev den 29/03-2008 følgende:
> > > Johan Hake wrote:
> > > > On Saturday 29 March 2008 15:56:29 Anders Logg wrote:
> > > >> On Sat, Mar 29, 2008 at 02:42:24PM +0100, Joachim B Haga wrote:
> > > >>> I'm just starting finding my way around dolfin, and I think it
> > > >>> would be easier (more discoverable in ipython or
> > > >>> your-ide-of-choice) if the dolfin namespace weren't so cluttered.
> > > >>>
> > > >>> At the moment there are 546 attributes in the dolfin namespace
> > > >>> (with only ublas). I don't know dolfin well enough to say which are
> > > >>> pointless, but I can make some educated guesses:
> > > >>>
> > > >>> - 113 of the functions in the main namespace are called
> > > >>> *_swigregister, and are probably not meant to be called by the
> > > >>> user.
> > > >>>
> > > >>> - A number of functions seem to be "leaked" from c++. Examples:
> > > >>> ios, ios_base, ios_base_sync_with_stdio, ios_base_xalloc, iostream,
> > > >>> istream, istringstream, endl_cb_ptr, ends, ends_cb_ptr.
> > > >>>
> > > >>> - Some utility functions which are not dolfin-specific. Example:
> > > >>> is_empty, tokens(?)
> > > >>>
> > > >>> - Functions that duplicate native python functions or numpy/math
> > > >>>   functions. Examples: ipow, sqr, rand, DOLFIN_PI, Identity
> > > >>>
> > > >>> - Some all-uppercase attributes are constants, other are classes.
> > > >>> Are the constants used? If so, maybe use a submodule (namespace)
> > > >>> for constants? Examples: LINE, TRIANGLE vs. ODE, LU.
> > > >>>
> > > >>> - 20 other 1-2 character attributes. I know some of them are
> > > >>> end-user relevant. Are all? D, a, b, cg, dS, ds, dx, f, i, j, k, l,
> > > >>> m, n, t0, t1, v, v0, v1, v2
> > > >>>   (Side note: the demos use "from dolfin import *". The common
> > > >>> pattern of "for i in N:" will rebind the variable "i" outside the
> > > >>> loop, so this is rather fragile in practice. The fully qualified
> > > >>> variant "dolfin.i" is of course immune to this problem.)
> > > >>>
> > > >>> - 11 cpp_* functions. Are they meant to be called by the user?
> > > >>>
> > > >>> - A few leaks from other modules. Examples: Set (sets.Set), array
> > > >>> (numpy.array)
> > > >>>
> > > >>> - Variables that are probably used internally in the library.
> > > >>>   vecs = [array([ 2.,  0.,  0.]), array([ 0.,  2.,  0.])]
> > > >>>   a = (-1.0, -1.0, -1.0)
> > > >>>   b = (1.0, -1.0, -1.0)
> > > >>>   cg = 0
> > > >>>   alpha = 0.0
> > > >>>
> > > >>> - Class methods that are also exposed directly. Examples:
> > > >>>   MatrixFactory_computeConvectionMatrix
> > > >>> (MatrixFactory.computeConv...) MatrixFactory_computeLoadVector
> > > >>> (MatrixFactory.computeLoad...) MatrixFactory_computeMassMatrix
> > > >>> (MatrixFactory.computeMass...) MatrixFactory_computeStiffnessMatrix
> > > >>> (MatrixFactory.computeStiff...) GraphPartition_*
> > > >>>
> > > >>> - Some non-obvious names. Examples: dolfin_{add,get,set} which
> > > >>> could perhaps be called {add,get,set}_parameter. I was actually
> > > >>> looking for this functionality but didn't find it before compiling
> > > >>> this list :)
> > > >>
> > > >> Good suggestion.
> > > >>
> > > >>> - The 23 methods called ublas_* or uBlas* are an obvious candidate
> > > >>> for a submodule, or are they supposed to be used directly instead
> > > >>> of through GenericMatrix etc? I don't have petsc, but that's
> > > >>> probably another candidate.
> > > >>>
> > > >>>
> > > >>> I could make a patch myself, but I don't know enough about this
> > > >>> stuff to feel comfortable making these decisions (especially since
> > > >>> some of the choices are probably made for c++/python equivalence,
> > > >>> and I don't plan to use the c++ part).
> > > >>>
> > > >>> -j.
> > > >>
> > > >> You are right, there are too many things being imported. This is
> > > >> because we've been lazy and done import * in many places.
> > > >>
> > > >> If you want to make a patch (hg export) or bundle, that would be
> > > >> excellent. Remove as much as you can, as long as it's possible to
> > > >> run the demos.
> > > >
> > > > I agree with Joachim and Anders that the namespace is too cluttered.
> > > > Some are probably easy to remove, eg. all swig_ names and the
> > > > polutions from other packages that is internally used.
> > > >
> > > > But some of the pointed out names are imported from FFC, should we
> > > > eg. place this in dolfin.ffc? In a demo or program you could then
> > > > from dolfin.ffc import *. I would also suggest to modularize the
> > > > actuall dolfin namespace too, a la the c++ modules, eg. put all mesh
> > > > related things in dolfin.mesh aso.
> > > >
> > > > How close is the python interface ment to be to the c++ interface?
> > >
> > > I would like to keep them similar.
>
> Yes, definitely. The two interfaces should be as equal as possible.
> There are some exceptions:
>
> 1. Cases where we need to adapt to how things are done differently in
> C++ and Python, for example iterators:
>
>   for (CellIterator c(mesh); !c.end(); ++c)
>       ...
>
>   for c in cells(mesh):
>       ...
>
> 2. Cases where we can do things easier/better in Python, for example
>
>   u = Function(...)
>   ...
>   print norm(u)
>
> which is not possible in C++.
>
> > > I have a
> > >
> > > > feeling that modularization of namespaces is good practice in python.
> > > > Doing this in a more extensive manner would ofcourse diverge the two
> > > > interfaces with regard to namespaces.
> > >
> > > If we refine the C++ namespace, how hard would it be to reflect this in
> > > the Python code (i.e. can Swig deal with it automatically)? It would be
> > > nice to have dolfin::mesh and dolfin.mesh, dolfin::la and dolfin.la,
> > > etc.

Swig will flatten the namespaces, i.e., any foo::bar() function will be 
included in a swigged python module as module_name.bar()

> > We're in the lucky situation where the dolfin.py and _dolfin.so files are
> > not imported directly, but through the __init__.py file in
> > site-packages/dolfin. Hence, we can make the modularization exactly the
> > way we want. The question is how we want it.
>
> I'm not sure we need to modularize the namespace, so let's keep it
> flat until it's really necessary. My reason for wanting to keep it
> flat is:
>
> 1. There aren't (or shouldn't be) that many things in the namespace
> anyway. Basically, we have a few classes:
>
>     Vector, Matrix, Mesh, FiniteElement, Function, DirichletBC
>
> and a few free functions:
>
>     assemble, solve, plot

I see that, and it would be very nice to get the interface down to these 
names. 

> 2. If you just want the mesh, then do
>
>     from dolfin import Mesh

Another related issue is to modularize the different c++ libraries, as it was 
in the old build system. It will of course take longer time to compile but it 
will help external libraries (e.g., my mesh generator program ;) ) to link to 
only a certain module and not to the whole dolfin library.

This should be quite straight forward to do with dolfin-scons, as we already 
do this for pycc. One dolfin_module-name.pc file will also be created for 
each module, making linking and compiling against a specific module easy.

Johan


Follow ups

References