dolfin team mailing list archive
-
dolfin team
-
Mailing list archive
-
Message #02805
Re: array(), getRow() etc
On Fri, 2006-06-30 at 16:00 +0200, Anders Logg wrote:
> On Fri, Jun 30, 2006 at 03:08:45PM +0200, Garth N. Wells wrote:
> > On Fri, 2006-06-30 at 12:29 +0200, Anders Logg wrote:
> > > On Fri, Jun 30, 2006 at 08:48:59AM +0200, Anders Logg wrote:
> > > > On Fri, Jun 30, 2006 at 12:32:25AM +0200, Garth N. Wells wrote:
> > > > > On Thu, 2006-06-29 at 20:20 +0200, Anders Logg wrote:
> > > > > > I've started trying to remove the PETSc ifdefs from the ODE solvers,
> > > > > > but ran into some problems. The ODE solver uses the calls
> > > > > >
> > > > > > Vector x;
> > > > > > real* xx = x.array();
> > > > > > // operate on xx
> > > > > > x.restore(xx);
> > > > > >
> > > > > > This is supported only by PETSc vectors.
> > > > > >
> > > > > > There are a couple of different solutions:
> > > > > >
> > > > > > 1. Don't use Vector::array().
> > > > > >
> > > > > > 2. Add Vector::array() to uBlas vectors.
> > > > > >
> > > > > > 3. Do 2 and add it to GenericVector as well.
> > > > > >
> > > > > > Any thoughts? I have a feeling 1 is the best solution, but it's also
> > > > > > the one that requires the most work (for me to rewrite the ODE
> > > > > > solvers).
> > > > > >
> > > > >
> > > > > I think that option 1 is best. I don't like options 2 & 3 as they take
> > > > > away the advantages of using uBlas. What exactly do you do with the
> > > > > Vector::array() in ode?
> > > >
> > > > The solution is (for some of the solvers) stored as a Vector u, but when
> > > > calling the user-supplied right-hand side f(u, t), the argument is
> > > > given as a plain C array since the user will often want to do a lot of
> > > > indexing of the vector in the definition of the right-hand side and I
> > > > suspect indexing is slow for PETSc vectors.
> > > >
> > > > > How fast are the PETSc functions VecGetValues
> > > > > and VecSetValue, and how much time is involved in calling
> > > > > VecAssemblyBegin() and VecAssemblyEnd() (which are currently called
> > > > > after every set)? I use Vector::array in the Cahn-Hilliard solver to do
> > > > > things like take the log of each term. Not sure how to do this
> > > > > efficiently without using array which will work for both PETSc and uBlas
> > > > > types.
> > > >
> > > > I'll make a small test to see how slow it really is.
> > >
> > > Here are some results. The timings are for setting and then accessing
> > > all elements in a vector of size 10000:
> > >
> > > Setting values in PETSc vector: 0.0708
> > > Accessing values in PETSc vector: 0.00031
> > > Setting values in uBlas vector: 1.42e-05
> > > Accessing values in uBlas vector: 4.6e-06
> > > Setting values in STL vector: 1.41e-05
> > > Accessing values in STL vector: 4.7e-06
> > > Setting values in C array: 1.4e-05
> > > Accessing values in C array: 1.41e-05
> > >
> > > Some conclusions:
> > >
> > > - Setting and accessing values element-wise in a PETSc array
> > > is terribly slow
> > >
> > > - uBlas, STL vector and C array are equally fast, don't know
> > > why access for C array is slower
> > >
> >
> > When I was first testing uBlas I saw that C arrays were often a bit
> > slower. I didn't understand why either.
> >
> >
> > > It seems the natural is to modify the interface for the ODE solver from
> > >
> > > void f(const real u[], real t, real y[]);
> > >
> > > to
> > >
> > > void f(const DenseVector& u, real t, DenseVector& y);
> > >
> > > Since the ODE solvers are currently not parallel anyway, I might as
> > > well use DenseVector in combination with the uBlas solvers. This
> > > should speed up the ODE solvers for small systems as well.
> > >
> >
> > For the future, it might be possible to create a uBlas vector that
> > addresses the array returned by PETScVector::array(). It's important
> > that we find a solution for manipulating array elements efficiently and
> > cleanly.
>
> DenseVector seems like a good option. It's the fastest and it works
> with some of the solvers.
>
> Maybe the array() should be special for the PETSc vector since that's
> the only place where it's needed?
>
> > > Garth, we need to extend the new uBlas solvers you added so that they
> > > work with a VirtualMatrix, that is, something which provides the
> > > function
> > >
> > > void mult(const DenseVector& x, DenseVector& y) const;
> > >
> > > Would that be much work to add?
> > >
> >
> > Should be OK.
>
> ok, I might try to fix it.
>
I've had a quick look, and the only things that needs to be done are
1. Template the uBlasKrylovSolver solve functions,
template <class M >
uint solve(const M& A, DenseVector& x, const DenseVector& b);
I wanted to do this anyway as the solvers can also work with dense
matrices.
2. Add a function uBlasSparseMatrix::mult_plus(const x, y) to compute y
+= Ax
3. Use A.mult(x, y) in place of axpy_prod(A, x, y, true) and
A.mult_plus(x,y) in place of axpy_prod(A, x, y, false) in
uBlasKrylovSolver.
4. Make the uBlasKrylovSolver::mult() functions templates so that they
can accept ublas_vector. The alternative is to use Densevector in place
of ublas_vector in uBlasKrylovSolver. I didn't do this originally as the
DenseVector constructor calls clear() which is not needed and does
involve some overhead.
4. Add the class uBlasVirtualMatrix.
5. Generalise the preconditioner.
Garth
> /Anders
References
-
array(), getRow() etc
From: Anders Logg, 2006-06-29
-
Re: array(), getRow() etc
From: Garth N. Wells, 2006-06-29
-
Re: array(), getRow() etc
From: Anders Logg, 2006-06-30
-
Re: array(), getRow() etc
From: Anders Logg, 2006-06-30
-
Re: array(), getRow() etc
From: Garth N. Wells, 2006-06-30