Merge lp:~jobh/dolfin/fast-array into lp:~fenics-core/dolfin/trunk
- fast-array
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 6629 |
Proposed branch: | lp:~jobh/dolfin/fast-array |
Merge into: | lp:~fenics-core/dolfin/trunk |
Diff against target: |
680 lines (+116/-168) 18 files modified
dolfin/adaptivity/TimeSeries.cpp (+5/-10) dolfin/adaptivity/TimeSeries.h (+5/-5) dolfin/ale/HarmonicSmoothing.cpp (+1/-1) dolfin/common/Array.h (+68/-115) dolfin/function/Function.cpp (+2/-2) dolfin/graph/ZoltanInterface.cpp (+1/-1) dolfin/io/BinaryFile.cpp (+2/-2) dolfin/io/XMLFunctionData.cpp (+3/-3) dolfin/io/XMLVector.cpp (+1/-1) dolfin/la/EpetraVector.cpp (+2/-2) dolfin/la/MUMPSLUSolver.cpp (+5/-5) dolfin/la/PETScVector.cpp (+4/-4) dolfin/mesh/MeshSmoothing.cpp (+1/-2) dolfin/mesh/SubDomain.cpp (+3/-6) dolfin/swig/common/post.i (+2/-4) dolfin/swig/la/la_get_set_items.i (+2/-2) dolfin/swig/typemaps/array.i (+2/-2) site-packages/dolfin/compilemodules/compilemodule.py (+7/-1) |
To merge this branch: | bzr merge lp:~jobh/dolfin/fast-array |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Registry Administrators | Pending | ||
Review via email:
|
Commit message
Description of the change
Changes Array from shared (using boost::
Creating a shared_array pointer requires heap allocations, and a lot of the time in assemble was spent just wrapping plain pointers in arrays. Furthermore, the shared semantics weren't used -- and if required the Array can be assigned to a shared_ptr.
Since this changes the binary interface to compiled modules, I added an interface version number (apart from the dolfin version number, which has more to do with the release schedule). Therefore instant modules will be recompiled.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Garth Wells (garth-wells) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
In GenericFunction
Assembler:
UFC::update
Expression:
GenericFunction
GenericFunction
ffc_form_xxx
-j.
On 24 February 2012 13:34, Garth Wells <email address hidden> wrote:
> Where in the code were the most Arrays being created?
> --
> https:/
> You are the owner of lp:~jobh/dolfin/fast-array.
>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
On 24 February 2012 13:34, Garth Wells <email address hidden> wrote:
> Where in the code were the most Arrays being created?
>
I wrote:
> In GenericFunction
>
> Assembler:
> UFC::update
> Expression:
>
... and indeed it's the rhs that involves an expression that's faster:
f = Expression("...")
L = f*v*dx
b = assemble(L)
goes from 8.0s on 64x64x64 to 2.7s. This accounts for most (all?) of the
35% speed-up for A and b combined.
-j.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Garth Wells (garth-wells) wrote : | # |
I'm not keen on ownership flags - they were a real mess before and it's been a lot better since we go rid of them.
Would be it be possible to (1) re-use the Array so we avoid dynamic allocation or (2) have an Array-like structure that always owns the data? The class Array was introduced to better interface with Python, but I recall that we later became aware that the Numpy interface has has a flag to prevent resizing, which would make typemaps more robust.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
I'd opine that the easiest would be to make array never own the data,
rather than always own the data. In that way, it can wrap anything.
* TimeSeries returns (owned) Arrays in two places. These could return
references to its own data (const vector<double>&), that would save a copy
(they are currently copied twice, once into an owned Array, then again in
swig into a numpy array). But maybe the amount of data returned is small,
in which case a vector<double> will be fine.
* Can't support resize() without ownership, so everywhere resize is used on
a reference argument should pass a vector<double>& instead. I think this is
a few places only.
At that point, Array will be a plain wrapper of others' data.
As for your (1), it might well be possible (keep a scratch array in the
GenericFunction class perhaps). But the thing is, the shared version was no
more safe. You can't keep a reference to an Array because you don't know if
it's shared or just wrapping data that will be deleted from under you. It
was "shared or borrowed" rather than "owned or borrowed", only without the
flag to tell the cases apart.
-j.
On 24 February 2012 19:37, Garth Wells <email address hidden> wrote:
> I'm not keen on ownership flags - they were a real mess before and it's
> been a lot better since we go rid of them.
>
> Would be it be possible to (1) re-use the Array so we avoid dynamic
> allocation or (2) have an Array-like structure that always owns the data?
> The class Array was introduced to better interface with Python, but I
> recall that we later became aware that the Numpy interface has has a flag
> to prevent resizing, which would make typemaps more robust.
> --
> https:/
> You are the owner of lp:~jobh/dolfin/fast-array.
>
- 6592. By Joachim Haga
-
Compilation fix (initialisation order, with -Wall -Werror)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
> I'd opine that the easiest would be to make array never own the data,
> rather than always own the data. In that way, it can wrap anything.
>
> * TimeSeries returns (owned) Arrays in two places. These could
> return references to its own data (const vector<double>&), that
> would save a copy (they are currently copied twice, once into an
> owned Array, then again in swig into a numpy array). But maybe the
> amount of data returned is small, in which case a vector<double>
> will be fine.
The return of arrays from TimeSeries is typically not performance
critical so a copy is fine (which it already is).
> * Can't support resize() without ownership, so everywhere resize is
> used on a reference argument should pass a vector<double>&
> instead. I think this is a few places only.
>
> At that point, Array will be a plain wrapper of others' data.
>
> As for your (1), it might well be possible (keep a scratch array in
> the GenericFunction class perhaps). But the thing is, the shared
> version was no more safe. You can't keep a reference to an Array
> because you don't know if it's shared or just wrapping data that
> will be deleted from under you. It was "shared or borrowed" rather
> than "owned or borrowed", only without the flag to tell the cases
> apart.
I'm not very happy with our current use of Array. We use std::vector
in some places and Array in other places. I don't remember what the
original intention was with Array. Is the purpose just to be able to
pass shared data as arrays back and forth to Python? Or should it be a
general array class used throughout DOLFIN C++?
If it is just for Python-wrapping, I think we should make it never own
data as Joachim suggests.
--
Anders
> -j.
>
> On 24 February 2012 19:37, Garth Wells <email address hidden> wrote:
>
> > I'm not keen on ownership flags - they were a real mess before and it's
> > been a lot better since we go rid of them.
> >
> > Would be it be possible to (1) re-use the Array so we avoid dynamic
> > allocation or (2) have an Array-like structure that always owns the data?
> > The class Array was introduced to better interface with Python, but I
> > recall that we later became aware that the Numpy interface has has a flag
> > to prevent resizing, which would make typemaps more robust.
> >
>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Garth Wells (garth-wells) wrote : | # |
On 27 February 2012 13:40, Anders Logg <email address hidden> wrote:
> On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
>> I'd opine that the easiest would be to make array never own the data,
>> rather than always own the data. In that way, it can wrap anything.
>>
>> * TimeSeries returns (owned) Arrays in two places. These could
>> return references to its own data (const vector<double>&), that
>> would save a copy (they are currently copied twice, once into an
>> owned Array, then again in swig into a numpy array). But maybe the
>> amount of data returned is small, in which case a vector<double>
>> will be fine.
>
> The return of arrays from TimeSeries is typically not performance
> critical so a copy is fine (which it already is).
>
>> * Can't support resize() without ownership, so everywhere resize is
>> used on a reference argument should pass a vector<double>&
>> instead. I think this is a few places only.
>>
>> At that point, Array will be a plain wrapper of others' data.
>>
>> As for your (1), it might well be possible (keep a scratch array in
>> the GenericFunction class perhaps). But the thing is, the shared
>> version was no more safe. You can't keep a reference to an Array
>> because you don't know if it's shared or just wrapping data that
>> will be deleted from under you. It was "shared or borrowed" rather
>> than "owned or borrowed", only without the flag to tell the cases
>> apart.
>
> I'm not very happy with our current use of Array. We use std::vector
> in some places and Array in other places. I don't remember what the
> original intention was with Array. Is the purpose just to be able to
> pass shared data as arrays back and forth to Python?
Yes.
> Or should it be a
> general array class used throughout DOLFIN C++?
>
No - there is no point in re-inventing std::vector. We should use
std::vector where possible. It's more flexible and can be used with
STL algorithms.
> If it is just for Python-wrapping, I think we should make it never own
> data as Joachim suggests.
>
Memory has to be created somewhere in order to be used, and it has to
be cleaned up.
There are two issues here:
1) Dynamic allocation in order to interface with UFC. Using plain
pointers rather than smart pointers is likely faster, but I think that
it's still not a solution. We should try to avoid these allocations in
loops.
2) We need to re-visit the NumPy interface. If we can create NumPy
arrays of fixed length, then we can just use std::vector, and let the
NumPy array wrap the pointer &x[0]. Maybe Johan Hake can comment on
this?
Garth
> --
> Anders
>
>
>> -j.
>>
>> On 24 February 2012 19:37, Garth Wells <email address hidden> wrote:
>>
>> > I'm not keen on ownership flags - they were a real mess before and it's
>> > been a lot better since we go rid of them.
>> >
>> > Would be it be possible to (1) re-use the Array so we avoid dynamic
>> > allocation or (2) have an Array-like structure that always owns the data?
>> > The class Array was introduced to better interface with Python, but I
>> > recall that we later became aware that the Numpy interface has has a flag
>> > to prevent resizing, which would make typemaps more robust.
>> >
>>
>
> --
> ht...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
>> I'm not very happy with our current use of Array. We use std::vector
>> in some places and Array in other places. I don't remember what the
>> original intention was with Array. Is the purpose just to be able to
>> pass shared data as arrays back and forth to Python?
>
> Yes.
The current usage is:
- As input (Python->C++) it wraps the numpy data.
- As output (C++->Python) the data is copied into a new numpy array.
I don't know off-hand if the input case is a requirement (that C++
modifies the data) or just an optimisation.
>> Or should it be a
>> general array class used throughout DOLFIN C++?
>
> No - there is no point in re-inventing std::vector. We should use
> std::vector where possible. It's more flexible and can be used with
> STL algorithms.
I agree in general, but note that there is no way to make a
std::vector wrap numpy data like in the input case above. An Array --
even if it's just a typedef to std::pair<T*,uint> -- may be nice to
standardise how wrapped data is passed.
> 1) Dynamic allocation in order to interface with UFC. Using plain
> pointers rather than smart pointers is likely faster, but I think that
> it's still not a solution. We should try to avoid these allocations in
> loops.
There is no dynamic allocation of actual data, not before and not now.
There was, however, dynamic allocation of the shared_array reference
count which is heap allocated. That is what this merge request fixes.
-j.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On 02/27/2012 03:01 PM, Garth Wells wrote:
> On 27 February 2012 13:40, Anders Logg<email address hidden> wrote:
>> On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
>>> I'd opine that the easiest would be to make array never own the data,
>>> rather than always own the data. In that way, it can wrap anything.
>>>
>>> * TimeSeries returns (owned) Arrays in two places. These could
>>> return references to its own data (const vector<double>&), that
>>> would save a copy (they are currently copied twice, once into an
>>> owned Array, then again in swig into a numpy array). But maybe the
>>> amount of data returned is small, in which case a vector<double>
>>> will be fine.
>>
>> The return of arrays from TimeSeries is typically not performance
>> critical so a copy is fine (which it already is).
>>
>>> * Can't support resize() without ownership, so everywhere resize is
>>> used on a reference argument should pass a vector<double>&
>>> instead. I think this is a few places only.
>>>
>>> At that point, Array will be a plain wrapper of others' data.
>>>
>>> As for your (1), it might well be possible (keep a scratch array in
>>> the GenericFunction class perhaps). But the thing is, the shared
>>> version was no more safe. You can't keep a reference to an Array
>>> because you don't know if it's shared or just wrapping data that
>>> will be deleted from under you. It was "shared or borrowed" rather
>>> than "owned or borrowed", only without the flag to tell the cases
>>> apart.
>>
>> I'm not very happy with our current use of Array. We use std::vector
>> in some places and Array in other places. I don't remember what the
>> original intention was with Array. Is the purpose just to be able to
>> pass shared data as arrays back and forth to Python?
>
> Yes.
>
>> Or should it be a
>> general array class used throughout DOLFIN C++?
>>
>
> No - there is no point in re-inventing std::vector. We should use
> std::vector where possible. It's more flexible and can be used with
> STL algorithms.
Agree.
>> If it is just for Python-wrapping, I think we should make it never own
>> data as Joachim suggests.
Agree. But we need to go over the interface and check that it makes
sense everywhere. TimeSeries could probably just return a std::vector
which is copied in the Python interface.
> Memory has to be created somewhere in order to be used, and it has to
> be cleaned up.
>
> There are two issues here:
>
> 1) Dynamic allocation in order to interface with UFC. Using plain
> pointers rather than smart pointers is likely faster, but I think that
> it's still not a solution. We should try to avoid these allocations in
> loops.
>
> 2) We need to re-visit the NumPy interface. If we can create NumPy
> arrays of fixed length, then we can just use std::vector, and let the
> NumPy array wrap the pointer&x[0]. Maybe Johan Hake can comment on
> this?
The problem is to pass a NumPy array to the C++ interface when it wants
a std::vector&. Then we need to copy the values. A light weight Array
class fixes that issue.
Wrapping a std::vector& into a Numpy array is possible without copying
by just passing the pointer. This would be similar to what we do today
with th...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Mon, Feb 27, 2012 at 03:32:04PM -0000, Johan Hake wrote:
> On 02/27/2012 03:01 PM, Garth Wells wrote:
> > On 27 February 2012 13:40, Anders Logg<email address hidden> wrote:
> >> On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
> >>> I'd opine that the easiest would be to make array never own the data,
> >>> rather than always own the data. In that way, it can wrap anything.
> >>>
> >>> * TimeSeries returns (owned) Arrays in two places. These could
> >>> return references to its own data (const vector<double>&), that
> >>> would save a copy (they are currently copied twice, once into an
> >>> owned Array, then again in swig into a numpy array). But maybe the
> >>> amount of data returned is small, in which case a vector<double>
> >>> will be fine.
> >>
> >> The return of arrays from TimeSeries is typically not performance
> >> critical so a copy is fine (which it already is).
> >>
> >>> * Can't support resize() without ownership, so everywhere resize is
> >>> used on a reference argument should pass a vector<double>&
> >>> instead. I think this is a few places only.
> >>>
> >>> At that point, Array will be a plain wrapper of others' data.
> >>>
> >>> As for your (1), it might well be possible (keep a scratch array in
> >>> the GenericFunction class perhaps). But the thing is, the shared
> >>> version was no more safe. You can't keep a reference to an Array
> >>> because you don't know if it's shared or just wrapping data that
> >>> will be deleted from under you. It was "shared or borrowed" rather
> >>> than "owned or borrowed", only without the flag to tell the cases
> >>> apart.
> >>
> >> I'm not very happy with our current use of Array. We use std::vector
> >> in some places and Array in other places. I don't remember what the
> >> original intention was with Array. Is the purpose just to be able to
> >> pass shared data as arrays back and forth to Python?
> >
> > Yes.
> >
> >> Or should it be a
> >> general array class used throughout DOLFIN C++?
> >>
> >
> > No - there is no point in re-inventing std::vector. We should use
> > std::vector where possible. It's more flexible and can be used with
> > STL algorithms.
>
> Agree.
>
> >> If it is just for Python-wrapping, I think we should make it never own
> >> data as Joachim suggests.
>
> Agree. But we need to go over the interface and check that it makes
> sense everywhere. TimeSeries could probably just return a
> std::vector which is copied in the Python interface.
Yes, definitely for TimeSeries. Perhaps we could settle for that
everytime we want to pass output data to Python?
Then Array input would essentially be limited to a few particular
callbacks that need to be made efficient (GenericFunctio
--
Anders
> > Memory has to be created somewhere in order to be used, and it has
to
> > be cleaned up.
> >
> > There are two issues here:
> >
> > 1) Dynamic allocation in order to interface with UFC. Using plain
> > pointers rather than smart pointers is likely faster, but I think that
> > it's still not a solution. We should try to avoid these allocations in
> > loops.
> >
> > 2) We need to re-visit the NumPy interface. If we can create NumPy
> > arrays of fixed length,...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Garth Wells (garth-wells) wrote : | # |
On 27 February 2012 17:01, Anders Logg <email address hidden> wrote:
> On Mon, Feb 27, 2012 at 03:32:04PM -0000, Johan Hake wrote:
>> On 02/27/2012 03:01 PM, Garth Wells wrote:
>> > On 27 February 2012 13:40, Anders Logg<email address hidden> Â wrote:
>> >> On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
>> >>> I'd opine that the easiest would be to make array never own the data,
>> >>> rather than always own the data. In that way, it can wrap anything.
>> >>>
>> >>> * TimeSeries returns (owned) Arrays in two places. These could
>> >>> return references to its own data (const vector<double>&), that
>> >>> would save a copy (they are currently copied twice, once into an
>> >>> owned Array, then again in swig into a numpy array). But maybe the
>> >>> amount of data returned is small, in which case a vector<double>
>> >>> will be fine.
>> >>
>> >> The return of arrays from TimeSeries is typically not performance
>> >> critical so a copy is fine (which it already is).
>> >>
>> >>> * Can't support resize() without ownership, so everywhere resize is
>> >>> used on a reference argument should pass a vector<double>&
>> >>> instead. I think this is a few places only.
>> >>>
>> >>> At that point, Array will be a plain wrapper of others' data.
>> >>>
>> >>> As for your (1), it might well be possible (keep a scratch array in
>> >>> the GenericFunction class perhaps). But the thing is, the shared
>> >>> version was no more safe. You can't keep a reference to an Array
>> >>> because you don't know if it's shared or just wrapping data that
>> >>> will be deleted from under you. It was "shared or borrowed" rather
>> >>> than "owned or borrowed", only without the flag to tell the cases
>> >>> apart.
>> >>
>> >> I'm not very happy with our current use of Array. We use std::vector
>> >> in some places and Array in other places. I don't remember what the
>> >> original intention was with Array. Is the purpose just to be able to
>> >> pass shared data as arrays back and forth to Python?
>> >
>> > Yes.
>> >
>> >> Or should it be a
>> >> general array class used throughout DOLFIN C++?
>> >>
>> >
>> > No - there is no point in re-inventing std::vector. We should use
>> > std::vector where possible. It's more flexible and can be used with
>> > STL algorithms.
>>
>> Agree.
>>
>> >> If it is just for Python-wrapping, I think we should make it never own
>> >> data as Joachim suggests.
>>
>> Agree. But we need to go over the interface and check that it makes
>> sense everywhere. TimeSeries could probably just return a
>> std::vector which is copied in the Python interface.
>
> Yes, definitely for TimeSeries. Perhaps we could settle for that
> everytime we want to pass output data to Python?
>
> Then Array input would essentially be limited to a few particular
> callbacks that need to be made efficient (GenericFunctio
>
In the case of GenericFunction
wrapping process, we can prevent resizing on the Python side.
Maybe we can remove Array and support (a) std::vectors via copy and
(b) references to a std::vector with resizing prevented.
Garth
> --
> Anders
>
>
>> > Memory has to be created somewhere in order to be used, ...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Mon, Feb 27, 2012 at 07:52:27PM -0000, Garth Wells wrote:
> On 27 February 2012 17:01, Anders Logg <email address hidden> wrote:
> > On Mon, Feb 27, 2012 at 03:32:04PM -0000, Johan Hake wrote:
> >> On 02/27/2012 03:01 PM, Garth Wells wrote:
> >> > On 27 February 2012 13:40, Anders Logg<email address hidden> Â wrote:
> >> >> On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
> >> >>> I'd opine that the easiest would be to make array never own the data,
> >> >>> rather than always own the data. In that way, it can wrap anything.
> >> >>>
> >> >>> * TimeSeries returns (owned) Arrays in two places. These could
> >> >>> return references to its own data (const vector<double>&), that
> >> >>> would save a copy (they are currently copied twice, once into an
> >> >>> owned Array, then again in swig into a numpy array). But maybe the
> >> >>> amount of data returned is small, in which case a vector<double>
> >> >>> will be fine.
> >> >>
> >> >> The return of arrays from TimeSeries is typically not performance
> >> >> critical so a copy is fine (which it already is).
> >> >>
> >> >>> * Can't support resize() without ownership, so everywhere resize is
> >> >>> used on a reference argument should pass a vector<double>&
> >> >>> instead. I think this is a few places only.
> >> >>>
> >> >>> At that point, Array will be a plain wrapper of others' data.
> >> >>>
> >> >>> As for your (1), it might well be possible (keep a scratch array in
> >> >>> the GenericFunction class perhaps). But the thing is, the shared
> >> >>> version was no more safe. You can't keep a reference to an Array
> >> >>> because you don't know if it's shared or just wrapping data that
> >> >>> will be deleted from under you. It was "shared or borrowed" rather
> >> >>> than "owned or borrowed", only without the flag to tell the cases
> >> >>> apart.
> >> >>
> >> >> I'm not very happy with our current use of Array. We use std::vector
> >> >> in some places and Array in other places. I don't remember what the
> >> >> original intention was with Array. Is the purpose just to be able to
> >> >> pass shared data as arrays back and forth to Python?
> >> >
> >> > Yes.
> >> >
> >> >> Or should it be a
> >> >> general array class used throughout DOLFIN C++?
> >> >>
> >> >
> >> > No - there is no point in re-inventing std::vector. We should use
> >> > std::vector where possible. It's more flexible and can be used with
> >> > STL algorithms.
> >>
> >> Agree.
> >>
> >> >> If it is just for Python-wrapping, I think we should make it never own
> >> >> data as Joachim suggests.
> >>
> >> Agree. But we need to go over the interface and check that it makes
> >> sense everywhere. TimeSeries could probably just return a
> >> std::vector which is copied in the Python interface.
> >
> > Yes, definitely for TimeSeries. Perhaps we could settle for that
> > everytime we want to pass output data to Python?
> >
> > Then Array input would essentially be limited to a few particular
> > callbacks that need to be made efficient (GenericFunctio
> >
>
> In the case of GenericFunction
> the wrapping process, we can prevent resizing on the Python side.
Don't know if that's po...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On 02/27/2012 09:16 PM, Anders Logg wrote:
> On Mon, Feb 27, 2012 at 07:52:27PM -0000, Garth Wells wrote:
>> On 27 February 2012 17:01, Anders Logg<email address hidden> wrote:
>>> On Mon, Feb 27, 2012 at 03:32:04PM -0000, Johan Hake wrote:
>>>> On 02/27/2012 03:01 PM, Garth Wells wrote:
>>>>> On 27 February 2012 13:40, Anders Logg<email address hidden> wrote:
>>>>>> On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
>>>>>>> I'd opine that the easiest would be to make array never own the data,
>>>>>>> rather than always own the data. In that way, it can wrap anything.
>>>>>>>
>>>>>>> * TimeSeries returns (owned) Arrays in two places. These could
>>>>>>> return references to its own data (const vector<double>&), that
>>>>>>> would save a copy (they are currently copied twice, once into an
>>>>>>> owned Array, then again in swig into a numpy array). But maybe the
>>>>>>> amount of data returned is small, in which case a vector<double>
>>>>>>> will be fine.
>>>>>>
>>>>>> The return of arrays from TimeSeries is typically not performance
>>>>>> critical so a copy is fine (which it already is).
>>>>>>
>>>>>>> * Can't support resize() without ownership, so everywhere resize is
>>>>>>> used on a reference argument should pass a vector<double>&
>>>>>>> instead. I think this is a few places only.
>>>>>>>
>>>>>>> At that point, Array will be a plain wrapper of others' data.
>>>>>>>
>>>>>>> As for your (1), it might well be possible (keep a scratch array in
>>>>>>> the GenericFunction class perhaps). But the thing is, the shared
>>>>>>> version was no more safe. You can't keep a reference to an Array
>>>>>>> because you don't know if it's shared or just wrapping data that
>>>>>>> will be deleted from under you. It was "shared or borrowed" rather
>>>>>>> than "owned or borrowed", only without the flag to tell the cases
>>>>>>> apart.
>>>>>>
>>>>>> I'm not very happy with our current use of Array. We use std::vector
>>>>>> in some places and Array in other places. I don't remember what the
>>>>>> original intention was with Array. Is the purpose just to be able to
>>>>>> pass shared data as arrays back and forth to Python?
>>>>>
>>>>> Yes.
>>>>>
>>>>>> Or should it be a
>>>>>> general array class used throughout DOLFIN C++?
>>>>>>
>>>>>
>>>>> No - there is no point in re-inventing std::vector. We should use
>>>>> std::vector where possible. It's more flexible and can be used with
>>>>> STL algorithms.
>>>>
>>>> Agree.
>>>>
>>>>>> If it is just for Python-wrapping, I think we should make it never own
>>>>>> data as Joachim suggests.
>>>>
>>>> Agree. But we need to go over the interface and check that it makes
>>>> sense everywhere. TimeSeries could probably just return a
>>>> std::vector which is copied in the Python interface.
>>>
>>> Yes, definitely for TimeSeries. Perhaps we could settle for that
>>> everytime we want to pass output data to Python?
>>>
>>> Then Array input would essentially be limited to a few particular
>>> callbacks that need to be made efficient (GenericFunctio
>>>
>>
>> In the case of GenericFunction
>> the wrapping process, we can prevent resizing on the Python side.
>
> Don't know if ...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Tue, Feb 28, 2012 at 05:08:11AM +0100, Johan Hake wrote:
> On 02/27/2012 09:16 PM, Anders Logg wrote:
> >On Mon, Feb 27, 2012 at 07:52:27PM -0000, Garth Wells wrote:
> >>On 27 February 2012 17:01, Anders Logg<email address hidden> wrote:
> >>>On Mon, Feb 27, 2012 at 03:32:04PM -0000, Johan Hake wrote:
> >>>>On 02/27/2012 03:01 PM, Garth Wells wrote:
> >>>>>On 27 February 2012 13:40, Anders Logg<email address hidden> wrote:
> >>>>>>On Fri, Feb 24, 2012 at 07:01:57PM -0000, Joachim Haga wrote:
> >>>>>>>I'd opine that the easiest would be to make array never own the data,
> >>>>>>>rather than always own the data. In that way, it can wrap anything.
> >>>>>>>
> >>>>>>>* TimeSeries returns (owned) Arrays in two places. These could
> >>>>>>>return references to its own data (const vector<double>&), that
> >>>>>>>would save a copy (they are currently copied twice, once into an
> >>>>>>>owned Array, then again in swig into a numpy array). But maybe the
> >>>>>>>amount of data returned is small, in which case a vector<double>
> >>>>>>>will be fine.
> >>>>>>
> >>>>>>The return of arrays from TimeSeries is typically not performance
> >>>>>>critical so a copy is fine (which it already is).
> >>>>>>
> >>>>>>>* Can't support resize() without ownership, so everywhere resize is
> >>>>>>>used on a reference argument should pass a vector<double>&
> >>>>>>>instead. I think this is a few places only.
> >>>>>>>
> >>>>>>>At that point, Array will be a plain wrapper of others' data.
> >>>>>>>
> >>>>>>>As for your (1), it might well be possible (keep a scratch array in
> >>>>>>>the GenericFunction class perhaps). But the thing is, the shared
> >>>>>>>version was no more safe. You can't keep a reference to an Array
> >>>>>>>because you don't know if it's shared or just wrapping data that
> >>>>>>>will be deleted from under you. It was "shared or borrowed" rather
> >>>>>>>than "owned or borrowed", only without the flag to tell the cases
> >>>>>>>apart.
> >>>>>>
> >>>>>>I'm not very happy with our current use of Array. We use std::vector
> >>>>>>in some places and Array in other places. I don't remember what the
> >>>>>>original intention was with Array. Is the purpose just to be able to
> >>>>>>pass shared data as arrays back and forth to Python?
> >>>>>
> >>>>>Yes.
> >>>>>
> >>>>>>Or should it be a
> >>>>>>general array class used throughout DOLFIN C++?
> >>>>>>
> >>>>>
> >>>>>No - there is no point in re-inventing std::vector. We should use
> >>>>>std::vector where possible. It's more flexible and can be used with
> >>>>>STL algorithms.
> >>>>
> >>>>Agree.
> >>>>
> >>>>>>If it is just for Python-wrapping, I think we should make it never own
> >>>>>>data as Joachim suggests.
> >>>>
> >>>>Agree. But we need to go over the interface and check that it makes
> >>>>sense everywhere. TimeSeries could probably just return a
> >>>>std::vector which is copied in the Python interface.
> >>>
> >>>Yes, definitely for TimeSeries. Perhaps we could settle for that
> >>>everytime we want to pass output data to Python?
> >>>
> >>>Then Array input would essentially be limited to a few particular
> >>>callbacks that need to be made efficient (GenericFunctio
> >>>
> >>
> >>In the cas...
- 6593. By Joachim Haga
-
Fix missing return statement
- 6594. By Joachim Haga
-
Merge with trunk
- 6595. By Joachim Haga
-
Change TimeSeries interface to return std::vector rather than Array
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
This seems to have stalled without a consensus. Still, I think the improvements are too dramatic to just drop. Assembling a "v*f*dx" RHS on a 64^3 cube (twice):
6.95 s before
2.30 s after
With Garth's suggestion of reusing an Array: 2.54s, but not thread safe without some extra complexity (likely compiler-
I'd like to repeat my argument that my proposed change isn't any less safe than what's there already. The old Array used reference_
Note [*]: It was used implicitly to transfer ownership in the TimeSeries return values. Since there's agreement than an extra copy does no harm there, I've changed those to return std::vector instead.
Then it can be deprecated or redesigned or whatever later, but in the meantime dolfin will be much faster :)
PS. The "interface version" thing seems to not work for all instant files, so instant-clean is still required. How should this be handled?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
I am in favor of applying the patch.
On Tue, Mar 6, 2012 at 12:20 PM, Joachim Haga <email address hidden> wrote:
> This seems to have stalled without a consensus. Still, I think the improvements are too dramatic to just drop. Assembling a "v*f*dx" RHS on a 64^3 cube (twice):
>
> 6.95 s before
> 2.30 s after
>
> With Garth's suggestion of reusing an Array: 2.54s, but not thread safe without some extra complexity (likely compiler-
>
> I'd like to repeat my argument that my proposed change isn't any less safe than what's there already. The old Array used reference_
>
> Note [*]: It was used implicitly to transfer ownership in the TimeSeries return values. Since there's agreement than an extra copy does no harm there, I've changed those to return std::vector instead.
>
> Then it can be deprecated or redesigned or whatever later, but in the meantime dolfin will be much faster :)
>
> PS. The "interface version" thing seems to not work for all instant files, so instant-clean is still required. How should this be handled?
Not sure what is not working, but it should be enough to change the
DOLFIN_
which determines if a modules should be recompiled or not.
Johan
> --
> https:/
> Your team DOLFIN Core Team is requested to review the proposed merge of lp:~jobh/dolfin/fast-array into lp:dolfin.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
I'm also very much in favor.
--
Anders
On Tue, Mar 06, 2012 at 11:53:31AM -0000, Johan Hake wrote:
> I am in favor of applying the patch.
>
> On Tue, Mar 6, 2012 at 12:20 PM, Joachim Haga <email address hidden> wrote:
> > This seems to have stalled without a consensus. Still, I think the improvements are too dramatic to just drop. Assembling a "v*f*dx" RHS on a 64^3 cube (twice):
> >
> > 6.95 s before
> > 2.30 s after
> >
> > With Garth's suggestion of reusing an Array: 2.54s, but not thread safe without some extra complexity (likely compiler-
> >
> > I'd like to repeat my argument that my proposed change isn't any less safe than what's there already. The old Array used reference_
> >
> > Note [*]: It was used implicitly to transfer ownership in the TimeSeries return values. Since there's agreement than an extra copy does no harm there, I've changed those to return std::vector instead.
> >
> > Then it can be deprecated or redesigned or whatever later, but in the meantime dolfin will be much faster :)
> >
> > PS. The "interface version" thing seems to not work for all instant files, so instant-clean is still required. How should this be handled?
>
> Not sure what is not working, but it should be enough to change the
> DOLFIN_
> which determines if a modules should be recompiled or not.
>
> Johan
>
>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Garth Wells (garth-wells) wrote : | # |
On 6 March 2012 12:11, Anders Logg <email address hidden> wrote:
> I'm also very much in favor.
>
I'm happy in principle, but want some clarity on Array. Can we make it
that Array is always a view (i.e., never owns that data), and
therefore cannot be resized? This would clean up some const hacks.
Garth
> --
> Anders
>
> On Tue, Mar 06, 2012 at 11:53:31AM -0000, Johan Hake wrote:
>> I am in favor of applying the patch.
>>
>> On Tue, Mar 6, 2012 at 12:20 PM, Joachim Haga <email address hidden> wrote:
>> > This seems to have stalled without a consensus. Still, I think the improvements are too dramatic to just drop. Assembling a "v*f*dx" RHS on a 64^3 cube (twice):
>> >
>> > 6.95 s before
>> > 2.30 s after
>> >
>> > With Garth's suggestion of reusing an Array: 2.54s, but not thread safe without some extra complexity (likely compiler-
>> >
>> > I'd like to repeat my argument that my proposed change isn't any less safe than what's there already. The old Array used reference_
>> >
>> > Note [*]: It was used implicitly to transfer ownership in the TimeSeries return values. Since there's agreement than an extra copy does no harm there, I've changed those to return std::vector instead.
>> >
>> > Then it can be deprecated or redesigned or whatever later, but in the meantime dolfin will be much faster :)
>> >
>> > PS. The "interface version" thing seems to not work for all instant files, so instant-clean is still required. How should this be handled?
>>
>> Not sure what is not working, but it should be enough to change the
>> DOLFIN_
>> which determines if a modules should be recompiled or not.
>>
>> Johan
>>
>>
>
> --
> https:/
> Your team DOLFIN Core Team is requested to review the proposed merge of lp:~jobh/dolfin/fast-array into lp:dolfin.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Tue, Mar 06, 2012 at 12:28:20PM -0000, Garth Wells wrote:
> On 6 March 2012 12:11, Anders Logg <email address hidden> wrote:
> > I'm also very much in favor.
> >
>
> I'm happy in principle, but want some clarity on Array. Can we make it
> that Array is always a view (i.e., never owns that data), and
> therefore cannot be resized? This would clean up some const hacks.
That's fine with me. And in addition we should limit the use of Array
to just the few places where we need it for passing data through
the SWIG layer without copying.
--
Anders
> Garth
>
> >
> > On Tue, Mar 06, 2012 at 11:53:31AM -0000, Johan Hake wrote:
> >> I am in favor of applying the patch.
> >>
> >> On Tue, Mar 6, 2012 at 12:20 PM, Joachim Haga <email address hidden> wrote:
> >> > This seems to have stalled without a consensus. Still, I think the improvements are too dramatic to just drop. Assembling a "v*f*dx" RHS on a 64^3 cube (twice):
> >> >
> >> > 6.95 s before
> >> > 2.30 s after
> >> >
> >> > With Garth's suggestion of reusing an Array: 2.54s, but not thread safe without some extra complexity (likely compiler-
> >> >
> >> > I'd like to repeat my argument that my proposed change isn't any less safe than what's there already. The old Array used reference_
> >> >
> >> > Note [*]: It was used implicitly to transfer ownership in the TimeSeries return values. Since there's agreement than an extra copy does no harm there, I've changed those to return std::vector instead.
> >> >
> >> > Then it can be deprecated or redesigned or whatever later, but in the meantime dolfin will be much faster :)
> >> >
> >> > PS. The "interface version" thing seems to not work for all instant files, so instant-clean is still required. How should this be handled?
> >>
> >> Not sure what is not working, but it should be enough to change the
> >> DOLFIN_
> >> which determines if a modules should be recompiled or not.
> >>
> >> Johan
> >>
> >>
> >
>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On Tue, Mar 6, 2012 at 1:28 PM, Garth Wells <email address hidden> wrote:
> On 6 March 2012 12:11, Anders Logg <email address hidden> wrote:
>> I'm also very much in favor.
>>
>
> I'm happy in principle, but want some clarity on Array. Can we make it
> that Array is always a view (i.e., never owns that data), and
> therefore cannot be resized? This would clean up some const hacks.
I agree. For all argments needing to be resized should use
std::vector. Not sure where the resize functionality is/was used.
Johan
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
>
> > I'm happy in principle, but want some clarity on Array. Can we make it
> > that Array is always a view (i.e., never owns that data), and
> > therefore cannot be resized? This would clean up some const hacks.
>
> I agree. For all argments needing to be resized should use
> std::vector. Not sure where the resize functionality is/was used.
It is possible (of course). There are quite a few user-exposed interfaces
that need changing (f.x. all the GeneralVector:
would be strange to just change the get methods).
And it may be a lot of grunt work. But I'll have a go at it if you say
that's the way to go (even if it requires change to user code).
-j.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
After looking at la_get_set_items.i: _get_vector_
think I'll punt on this. It's just too much work for an uncertain outcome
(it is quite possible that a lot of complexity has to be added back to deal
with cases like this, making this pointless).
// Returns the values from a Vector.
dolfin:
{
dolfin:
try
{
// Try accessing the value pointer directly [jobh: return borrowed data]
double* data_values = self->data();
values = new dolfin:
}
catch (std::runtime_error e)
{
// We couldn't access the values directly [jobh: return owned data]
values = new dolfin:
self-
}
return *values;
}
On 6 March 2012 15:01, Joachim Berdal Haga <email address hidden> wrote:
> > I'm happy in principle, but want some clarity on Array. Can we make it
>> > that Array is always a view (i.e., never owns that data), and
>> > therefore cannot be resized? This would clean up some const hacks.
>>
>> I agree. For all argments needing to be resized should use
>> std::vector. Not sure where the resize functionality is/was used.
>
>
> It is possible (of course). There are quite a few user-exposed interfaces
> that need changing (f.x. all the GeneralVector:
> would be strange to just change the get methods).
>
> And it may be a lot of grunt work. But I'll have a go at it if you say
> that's the way to go (even if it requires change to user code).
>
> -j.
>
>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Garth Wells (garth-wells) wrote : | # |
On 6 March 2012 15:13, Joachim Haga <email address hidden> wrote:
> After looking at la_get_set_items.i: _get_vector_
> think I'll punt on this. It's just too much work for an uncertain outcome
> (it is quite possible that a lot of complexity has to be added back to deal
> with cases like this, making this pointless).
>
> // Returns the values from a Vector.
> dolfin:
> {
> Â dolfin:
> Â try
> Â {
> Â Â // Try accessing the value pointer directly [jobh: return borrowed data]
> Â Â double* data_values = self->data();
> Â Â values = new dolfin:
> Â }
> Â catch (std::runtime_error e)
> Â {
> Â Â // We couldn't access the values directly [jobh: return owned data]
> Â Â values = new dolfin:
> Â Â self->get_
> Â }
> Â return *values;
> }
>
We should just be able to use std::vector in the C++ interface for this.
Garth
>
> On 6 March 2012 15:01, Joachim Berdal Haga <email address hidden> wrote:
>
>> > I'm happy in principle, but want some clarity on Array. Can we make it
>>> > that Array is always a view (i.e., never owns that data), and
>>> > therefore cannot be resized? This would clean up some const hacks.
>>>
>>> I agree. For all argments needing to be resized should use
>>> std::vector. Not sure where the resize functionality is/was used.
>>
>>
>> It is possible (of course). There are quite a few user-exposed interfaces
>> that need changing (f.x. all the GeneralVector:
>> would be strange to just change the get methods).
>>
>> And it may be a lot of grunt work. But I'll have a go at it if you say
>> that's the way to go (even if it requires change to user code).
>>
>> -j.
>>
>>
>
> --
> https:/
> Your team DOLFIN Core Team is requested to review the proposed merge of lp:~jobh/dolfin/fast-array into lp:dolfin.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Tue, Mar 06, 2012 at 02:10:28PM -0000, Joachim Haga wrote:
> >
> > > I'm happy in principle, but want some clarity on Array. Can we make it
> > > that Array is always a view (i.e., never owns that data), and
> > > therefore cannot be resized? This would clean up some const hacks.
> >
> > I agree. For all argments needing to be resized should use
> > std::vector. Not sure where the resize functionality is/was used.
>
>
> It is possible (of course). There are quite a few user-exposed interfaces
> that need changing (f.x. all the GeneralVector:
> would be strange to just change the get methods).
>
> And it may be a lot of grunt work. But I'll have a go at it if you say
> that's the way to go (even if it requires change to user code).
I suggest we merge this now, and think about cleaning up the use of
Array later.
Just to check: do we break any user interfaces with this patch? I
assume not.
--
Anders
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On Tue, Mar 6, 2012 at 3:10 PM, Joachim Haga <email address hidden> wrote:
>>
>> > I'm happy in principle, but want some clarity on Array. Can we make it
>> > that Array is always a view (i.e., never owns that data), and
>> > therefore cannot be resized? This would clean up some const hacks.
>>
>> I agree. For all argments needing to be resized should use
>> std::vector. Not sure where the resize functionality is/was used.
>
> It is possible (of course). There are quite a few user-exposed interfaces
> that need changing (f.x. all the GeneralVector:
> would be strange to just change the get methods).
I did not anticipate using std::vector for these methods as these
methods assume the user provides arrays with the correct size. It
would cost too much to resize std::vector for these operations. Maybe
we can use Array<double> for these but for now they just work with
NumPy arrays directly.
Johan
> And it may be a lot of grunt work. But I'll have a go at it if you say
> that's the way to go (even if it requires change to user code).
> -j.
>
> --
> https:/
> Your team DOLFIN Core Team is requested to review the proposed merge of lp:~jobh/dolfin/fast-array into lp:dolfin.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On Tue, Mar 6, 2012 at 8:19 PM, Anders Logg <email address hidden> wrote:
> On Tue, Mar 06, 2012 at 02:10:28PM -0000, Joachim Haga wrote:
>> >
>> > > I'm happy in principle, but want some clarity on Array. Can we make it
>> > > that Array is always a view (i.e., never owns that data), and
>> > > therefore cannot be resized? This would clean up some const hacks.
>> >
>> > I agree. For all argments needing to be resized should use
>> > std::vector. Not sure where the resize functionality is/was used.
>>
>>
>> It is possible (of course). There are quite a few user-exposed interfaces
>> that need changing (f.x. all the GeneralVector:
>> would be strange to just change the get methods).
>>
>> And it may be a lot of grunt work. But I'll have a go at it if you say
>> that's the way to go (even if it requires change to user code).
>
> I suggest we merge this now, and think about cleaning up the use of
> Array later.
I agree. I do not have a working DOLFIN right now so I will
unfortunately not be able to do it.
Johan
> Just to check: do we break any user interfaces with this patch? I
> assume not.
>
> --
> Anders
>
> --
> https:/
> Your team DOLFIN Core Team is requested to review the proposed merge of lp:~jobh/dolfin/fast-array into lp:dolfin.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
On Tue, Mar 06, 2012 at 08:16:47PM -0000, Johan Hake wrote:
> On Tue, Mar 6, 2012 at 8:19 PM, Anders Logg <email address hidden> wrote:
> > On Tue, Mar 06, 2012 at 02:10:28PM -0000, Joachim Haga wrote:
> >> >
> >> > > I'm happy in principle, but want some clarity on Array. Can we make it
> >> > > that Array is always a view (i.e., never owns that data), and
> >> > > therefore cannot be resized? This would clean up some const hacks.
> >> >
> >> > I agree. For all argments needing to be resized should use
> >> > std::vector. Not sure where the resize functionality is/was used.
> >>
> >>
> >> It is possible (of course). There are quite a few user-exposed interfaces
> >> that need changing (f.x. all the GeneralVector:
> >> would be strange to just change the get methods).
> >>
> >> And it may be a lot of grunt work. But I'll have a go at it if you say
> >> that's the way to go (even if it requires change to user code).
> >
> > I suggest we merge this now, and think about cleaning up the use of
> > Array later.
>
> I agree. I do not have a working DOLFIN right now so I will
> unfortunately not be able to do it.
I can merge if there are no objections.
--
Anders
> Johan
>
> > Just to check: do we break any user interfaces with this patch? I
> > assume not.
> >
> >
>
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
>
> >> I agree. For all argments needing to be resized should use
> >> std::vector. Not sure where the resize functionality is/was used.
> >
> > It is possible (of course). There are quite a few user-exposed interfaces
> > that need changing (f.x. all the GeneralVector:
> > would be strange to just change the get methods).
>
> I did not anticipate using std::vector for these methods as these
> methods assume the user provides arrays with the correct size. It
> would cost too much to resize std::vector for these operations. Maybe
>
Not sure if we're talking about the same thing? PETScVector:
example uses resize() on the Array& that is passed as parameter.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
On 6 March 2012 21:31, Anders Logg <email address hidden> wrote:
> > > I suggest we merge this now, and think about cleaning up the use of
> > > Array later.
> >
> > I agree. I do not have a working DOLFIN right now so I will
> > unfortunately not be able to do it.
>
> I can merge if there are no objections.
>
Certainly not from me! But hold on a bit, tomorrow morning I will check the
instant issue, and see if it's possible to disable the copy constructor (to
ensure it's not used in unanticipated ways).
-j.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On Tue, Mar 6, 2012 at 10:04 PM, Joachim Haga <email address hidden> wrote:
>>
>> >> I agree. For all argments needing to be resized should use
>> >> std::vector. Not sure where the resize functionality is/was used.
>> >
>> > It is possible (of course). There are quite a few user-exposed interfaces
>> > that need changing (f.x. all the GeneralVector:
>> > would be strange to just change the get methods).
>>
>> I did not anticipate using std::vector for these methods as these
>> methods assume the user provides arrays with the correct size. It
>> would cost too much to resize std::vector for these operations. Maybe
>>
>
> Not sure if we're talking about the same thing? PETScVector:
> example uses resize() on the Array& that is passed as parameter.
You are right. We do not talk about the same thing.
Here I think we should just check that the user pass an Array of the
correct size avoiding resizing.
Johan
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
On 6 March 2012 17:55, Garth Wells <email address hidden> wrote:
> On 6 March 2012 15:13, Joachim Haga <email address hidden> wrote:
> > After looking at la_get_set_items.i: _get_vector_
> > think I'll punt on this. It's just too much work for an uncertain outcome
> > (it is quite possible that a lot of complexity has to be added back to
> deal
> > with cases like this, making this pointless).
> >
> > // Returns the values from a Vector.
> > dolfin:
>
> We should just be able to use std::vector in the C++ interface for this.
>
Hm, yes, I guess an extra copy won't matter that much here. I'll see how it
goes.
-j.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Johan Hake (johan-hake) wrote : | # |
On Tue, Mar 6, 2012 at 10:50 PM, Joachim Haga <email address hidden> wrote:
> On 6 March 2012 17:55, Garth Wells <email address hidden> wrote:
>
>> On 6 March 2012 15:13, Joachim Haga <email address hidden> wrote:
>> > After looking at la_get_set_items.i: _get_vector_
>> > think I'll punt on this. It's just too much work for an uncertain outcome
>> > (it is quite possible that a lot of complexity has to be added back to
>> deal
>> > with cases like this, making this pointless).
>> >
>> > // Returns the values from a Vector.
>> > dolfin:
>>
>> We should just be able to use std::vector in the C++ interface for this.
>>
>
> Hm, yes, I guess an extra copy won't matter that much here. I'll see how it
> goes.
We can change this syntax to:
void _get_vector_
dolfin:
where values now is just a view of a numpy array. In the Python layer
we then create the NumPy array of correct size, call the function and
populate the values.
Johan
- 6596. By Joachim Haga
-
Disable Array copy constructor, remove utility methods that are not used
- 6597. By Joachim Haga
-
Merge with trunk
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
I've now pushed a version which is merged with trunk (the merge wasn't clean so I thought it wise) and has been fully tested. The recent changes are:
- Disable the Array copy constructor, to make it safer (no unanticipated sharing or copying).
- Allow resize() to same size even for un-owned Arrays, it turned out that the ale code used this.
- Remove unused utility methods (Array::zero, Array::min, etc)
It passes all tests after merge. (KrylovSolver and one CGAL demo fail, but that's not new.)
Johan: The interface version I mentioned is something I added to compilemodules.py which changes the hash without changing the visible version. If you think it better to change DOLFIN_
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
I'll merge this later if there are now objections.
--
Anders
On Wed, Mar 07, 2012 at 01:28:34PM -0000, Joachim Haga wrote:
> I've now pushed a version which is merged with trunk (the merge wasn't clean so I thought it wise) and has been fully tested. The recent changes are:
>
> - Disable the Array copy constructor, to make it safer (no unanticipated sharing or copying).
> - Allow resize() to same size even for un-owned Arrays, it turned out that the ale code used this.
> - Remove unused utility methods (Array::zero, Array::min, etc)
>
> It passes all tests after merge. (KrylovSolver and one CGAL demo fail, but that's not new.)
>
> Johan: The interface version I mentioned is something I added to compilemodules.py which changes the hash without changing the visible version. If you think it better to change DOLFIN_
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Anders Logg (logg) wrote : | # |
Merged.
Joachim, could you send a patch for ChangeLog to include one-line
summaries of all your changes. Thanks.
--
Anders
On Wed, Mar 07, 2012 at 01:28:34PM -0000, Joachim Haga wrote:
> I've now pushed a version which is merged with trunk (the merge wasn't clean so I thought it wise) and has been fully tested. The recent changes are:
>
> - Disable the Array copy constructor, to make it safer (no unanticipated sharing or copying).
> - Allow resize() to same size even for un-owned Arrays, it turned out that the ale code used this.
> - Remove unused utility methods (Array::zero, Array::min, etc)
>
> It passes all tests after merge. (KrylovSolver and one CGAL demo fail, but that's not new.)
>
> Johan: The interface version I mentioned is something I added to compilemodules.py which changes the hash without changing the visible version. If you think it better to change DOLFIN_
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Joachim Haga (jobh) wrote : | # |
=== modified file 'ChangeLog'
--- ChangeLog 2012-02-13 21:49:10 +0000
+++ ChangeLog 2012-03-08 12:12:20 +0000
@@ -1,3 +1,8 @@
+ - MPI functionality for distributing values between neighbours
+ - SystemAssembler now works in parallel with topological/
boundary search
+ - New symmetric assembler with ability for stand-alone RHS assemble
+ - Major speed-up of DirichletBC computation and mesh marking
+ - Major speed-up of assembly of functions and expressions
- Major speed-up of mesh topology computation
On 8 March 2012 11:46, Anders Logg <email address hidden> wrote:
> Merged.
>
> Joachim, could you send a patch for ChangeLog to include one-line
> summaries of all your changes. Thanks.
>
> --
> Anders
>
>
> On Wed, Mar 07, 2012 at 01:28:34PM -0000, Joachim Haga wrote:
>> I've now pushed a version which is merged with trunk (the merge wasn't clean so I thought it wise) and has been fully tested. The recent changes are:
>>
>> - Disable the Array copy constructor, to make it safer (no unanticipated sharing or copying).
>> - Allow resize() to same size even for un-owned Arrays, it turned out that the ale code used this.
>> - Remove unused utility methods (Array::zero, Array::min, etc)
>>
>> It passes all tests after merge. (KrylovSolver and one CGAL demo fail, but that's not new.)
>>
>> Johan: The interface version I mentioned is something I added to compilemodules.py which changes the hash without changing the visible version. If you think it better to change DOLFIN_
Preview Diff
1 | === modified file 'dolfin/adaptivity/TimeSeries.cpp' | |||
2 | --- dolfin/adaptivity/TimeSeries.cpp 2012-03-01 12:01:06 +0000 | |||
3 | +++ dolfin/adaptivity/TimeSeries.cpp 2012-03-07 13:15:44 +0000 | |||
4 | @@ -23,6 +23,7 @@ | |||
5 | 23 | #include <sstream> | 23 | #include <sstream> |
6 | 24 | #include <boost/scoped_ptr.hpp> | 24 | #include <boost/scoped_ptr.hpp> |
7 | 25 | 25 | ||
8 | 26 | #include <dolfin/common/constants.h> | ||
9 | 26 | #include <dolfin/io/File.h> | 27 | #include <dolfin/io/File.h> |
10 | 27 | #include <dolfin/io/BinaryFile.h> | 28 | #include <dolfin/io/BinaryFile.h> |
11 | 28 | #include <dolfin/la/GenericVector.h> | 29 | #include <dolfin/la/GenericVector.h> |
12 | @@ -207,20 +208,14 @@ | |||
13 | 207 | file >> mesh; | 208 | file >> mesh; |
14 | 208 | } | 209 | } |
15 | 209 | //----------------------------------------------------------------------------- | 210 | //----------------------------------------------------------------------------- |
17 | 210 | Array<double> TimeSeries::vector_times() const | 211 | std::vector<double> TimeSeries::vector_times() const |
18 | 211 | { | 212 | { |
23 | 212 | Array<double> times(_vector_times.size()); | 213 | return _vector_times; |
20 | 213 | for (uint i = 0; i < _vector_times.size(); i++) | ||
21 | 214 | times[i] = _vector_times[i]; | ||
22 | 215 | return times; | ||
24 | 216 | } | 214 | } |
25 | 217 | //----------------------------------------------------------------------------- | 215 | //----------------------------------------------------------------------------- |
27 | 218 | Array<double> TimeSeries::mesh_times() const | 216 | std::vector<double> TimeSeries::mesh_times() const |
28 | 219 | { | 217 | { |
33 | 220 | Array<double> times(_mesh_times.size()); | 218 | return _mesh_times; |
30 | 221 | for (uint i = 0; i < _mesh_times.size(); i++) | ||
31 | 222 | times[i] = _mesh_times[i]; | ||
32 | 223 | return times; | ||
34 | 224 | } | 219 | } |
35 | 225 | //----------------------------------------------------------------------------- | 220 | //----------------------------------------------------------------------------- |
36 | 226 | void TimeSeries::clear() | 221 | void TimeSeries::clear() |
37 | 227 | 222 | ||
38 | === modified file 'dolfin/adaptivity/TimeSeries.h' | |||
39 | --- dolfin/adaptivity/TimeSeries.h 2011-10-24 04:11:41 +0000 | |||
40 | +++ dolfin/adaptivity/TimeSeries.h 2012-03-07 13:15:44 +0000 | |||
41 | @@ -22,7 +22,7 @@ | |||
42 | 22 | #define __TIME_SERIES_H | 22 | #define __TIME_SERIES_H |
43 | 23 | 23 | ||
44 | 24 | #include <string> | 24 | #include <string> |
46 | 25 | #include <dolfin/common/Array.h> | 25 | #include <vector> |
47 | 26 | #include <dolfin/common/Variable.h> | 26 | #include <dolfin/common/Variable.h> |
48 | 27 | 27 | ||
49 | 28 | namespace dolfin | 28 | namespace dolfin |
50 | @@ -104,16 +104,16 @@ | |||
51 | 104 | /// Return array of sample times for vectors | 104 | /// Return array of sample times for vectors |
52 | 105 | /// | 105 | /// |
53 | 106 | /// *Returns* | 106 | /// *Returns* |
55 | 107 | /// _Array_ <double> | 107 | /// std::vector<double> |
56 | 108 | /// The times. | 108 | /// The times. |
58 | 109 | Array<double> vector_times() const; | 109 | std::vector<double> vector_times() const; |
59 | 110 | 110 | ||
60 | 111 | /// Return array of sample times for meshes | 111 | /// Return array of sample times for meshes |
61 | 112 | /// | 112 | /// |
62 | 113 | /// *Returns* | 113 | /// *Returns* |
64 | 114 | /// _Array_ <double> | 114 | /// std::vector<double> |
65 | 115 | /// The times. | 115 | /// The times. |
67 | 116 | Array<double> mesh_times() const; | 116 | std::vector<double> mesh_times() const; |
68 | 117 | 117 | ||
69 | 118 | /// Clear time series | 118 | /// Clear time series |
70 | 119 | void clear(); | 119 | void clear(); |
71 | 120 | 120 | ||
72 | === modified file 'dolfin/ale/HarmonicSmoothing.cpp' | |||
73 | --- dolfin/ale/HarmonicSmoothing.cpp 2012-02-01 07:31:55 +0000 | |||
74 | +++ dolfin/ale/HarmonicSmoothing.cpp 2012-03-07 13:15:44 +0000 | |||
75 | @@ -108,7 +108,7 @@ | |||
76 | 108 | solve(A, x, b, "gmres", prec); | 108 | solve(A, x, b, "gmres", prec); |
77 | 109 | 109 | ||
78 | 110 | // Get new coordinates | 110 | // Get new coordinates |
80 | 111 | Array<double> _new_coordinates(N, new_coordinates.data().get() + dim*N); | 111 | Array<double> _new_coordinates(N, new_coordinates.data() + dim*N); |
81 | 112 | x.get_local(_new_coordinates); | 112 | x.get_local(_new_coordinates); |
82 | 113 | } | 113 | } |
83 | 114 | 114 | ||
84 | 115 | 115 | ||
85 | === modified file 'dolfin/common/Array.h' | |||
86 | --- dolfin/common/Array.h 2012-03-01 12:01:06 +0000 | |||
87 | +++ dolfin/common/Array.h 2012-03-07 13:15:44 +0000 | |||
88 | @@ -16,9 +16,10 @@ | |||
89 | 16 | // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>. | 16 | // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>. |
90 | 17 | // | 17 | // |
91 | 18 | // Modified by Anders Logg 2010-2011 | 18 | // Modified by Anders Logg 2010-2011 |
92 | 19 | // Modified by Joachim B Haga 2012 | ||
93 | 19 | // | 20 | // |
94 | 20 | // First added: 2009-12-06 | 21 | // First added: 2009-12-06 |
96 | 21 | // Last changed: 2011-11-13 | 22 | // Last changed: 2012-02-23 |
97 | 22 | 23 | ||
98 | 23 | #ifndef __DOLFIN_ARRAY_H | 24 | #ifndef __DOLFIN_ARRAY_H |
99 | 24 | #define __DOLFIN_ARRAY_H | 25 | #define __DOLFIN_ARRAY_H |
100 | @@ -26,8 +27,7 @@ | |||
101 | 26 | #include <sstream> | 27 | #include <sstream> |
102 | 27 | #include <string> | 28 | #include <string> |
103 | 28 | #include <utility> | 29 | #include <utility> |
106 | 29 | #include <boost/shared_array.hpp> | 30 | #include <vector> |
105 | 30 | |||
107 | 31 | 31 | ||
108 | 32 | #include <dolfin/common/constants.h> | 32 | #include <dolfin/common/constants.h> |
109 | 33 | #include <dolfin/common/types.h> | 33 | #include <dolfin/common/types.h> |
110 | @@ -44,55 +44,46 @@ | |||
111 | 44 | 44 | ||
112 | 45 | template <typename T> class Array | 45 | template <typename T> class Array |
113 | 46 | { | 46 | { |
114 | 47 | |||
115 | 47 | public: | 48 | public: |
116 | 48 | 49 | ||
135 | 49 | /// Create empty array | 50 | /// Create an empty array, with ownership. Must be resized or assigned to to be of any use. |
136 | 50 | Array() : _size(0), x(0) {} | 51 | explicit Array() : _size(0), _x(NULL), _owner(true) {} |
137 | 51 | 52 | ||
138 | 52 | /// Create array of size N | 53 | /// Create array of size N. Array has ownership. |
139 | 53 | explicit Array(uint N) : _size(N), x(new T[N]) {} | 54 | explicit Array(uint N) : _size(N), _x(new T[N]), _owner(true) {} |
140 | 54 | 55 | ||
141 | 55 | /// Copy constructor (arg name need to have a different name that 'x') | 56 | /// Create an array wrapping a std::vector. Array does not take ownership. |
142 | 56 | Array(const Array& other) : _size(0), x(0) | 57 | explicit Array(std::vector<T>& vec) : _size(vec.size()), _x(&vec[0]), _owner(false) {} |
143 | 57 | { *this = other; } | 58 | |
144 | 58 | 59 | /// Construct array from a pointer. Array does not take ownership. | |
145 | 59 | /// Construct array from a shared pointer | 60 | Array(uint N, T* x) : _size(N), _x(x), _owner(false) {} |
146 | 60 | Array(uint N, boost::shared_array<T> x) : _size(N), x(x) {} | 61 | |
147 | 61 | 62 | /// Destructor. | |
148 | 62 | /// Construct array from a pointer. Array will not take ownership. | 63 | ~Array() |
131 | 63 | Array(uint N, T* x) : _size(N), x(boost::shared_array<T>(x, NoDeleter())) {} | ||
132 | 64 | |||
133 | 65 | /// Assignment operator | ||
134 | 66 | const Array& operator= (const Array& x) | ||
149 | 67 | { | 64 | { |
171 | 68 | // Resize if necessary | 65 | if (_owner && _x) |
172 | 69 | if (x.empty() && !x.x) | 66 | delete[] _x; |
152 | 70 | { | ||
153 | 71 | this->x.reset(); | ||
154 | 72 | this->_size = 0; | ||
155 | 73 | } | ||
156 | 74 | else if (this->_size != x.size()) | ||
157 | 75 | { | ||
158 | 76 | this->x.reset(new T[x.size()]); | ||
159 | 77 | this->_size = x.size(); | ||
160 | 78 | } | ||
161 | 79 | |||
162 | 80 | // Copy data | ||
163 | 81 | if (_size > 0) | ||
164 | 82 | { | ||
165 | 83 | dolfin_assert(this->x); | ||
166 | 84 | dolfin_assert(x.x); | ||
167 | 85 | std::copy(&x.x[0], &x.x[_size], &this->x[0]); | ||
168 | 86 | } | ||
169 | 87 | |||
170 | 88 | return *this; | ||
173 | 89 | } | 67 | } |
174 | 90 | 68 | ||
177 | 91 | /// Construct array from a pointer. Array will not take ownership. | 69 | /// Resize the array. If the new size if different from the old size, the |
178 | 92 | void update(uint N, T* _x) | 70 | /// Array must be owner; the old contents are then lost. |
179 | 71 | void resize(uint N) | ||
180 | 93 | { | 72 | { |
181 | 73 | if (_size == N) | ||
182 | 74 | return; | ||
183 | 75 | if (!_owner) | ||
184 | 76 | dolfin_error("Array.h", "resize", "Only owned arrays can be resized"); | ||
185 | 77 | if (_x) | ||
186 | 78 | delete[] _x; | ||
187 | 79 | _x = (N == 0 ? NULL : new T[N]); | ||
188 | 94 | _size = N; | 80 | _size = N; |
190 | 95 | x.reset(_x, NoDeleter()); | 81 | } |
191 | 82 | |||
192 | 83 | /// Clear the array (resize to 0). | ||
193 | 84 | void clear() | ||
194 | 85 | { | ||
195 | 86 | resize(0); | ||
196 | 96 | } | 87 | } |
197 | 97 | 88 | ||
198 | 98 | /// Return informal string representation (pretty-print). | 89 | /// Return informal string representation (pretty-print). |
199 | @@ -116,101 +107,64 @@ | |||
200 | 116 | return s.str(); | 107 | return s.str(); |
201 | 117 | } | 108 | } |
202 | 118 | 109 | ||
203 | 119 | /// Clear array | ||
204 | 120 | void clear() | ||
205 | 121 | { | ||
206 | 122 | this->x.reset(); | ||
207 | 123 | this->_size = 0; | ||
208 | 124 | } | ||
209 | 125 | |||
210 | 126 | /// Resize array to size N. If size changes, contents will be destroyed. | ||
211 | 127 | void resize(uint N) | ||
212 | 128 | { | ||
213 | 129 | // Special case | ||
214 | 130 | if (N == _size) | ||
215 | 131 | return; | ||
216 | 132 | |||
217 | 133 | // Special case | ||
218 | 134 | if (N == 0) | ||
219 | 135 | { | ||
220 | 136 | clear(); | ||
221 | 137 | return; | ||
222 | 138 | } | ||
223 | 139 | |||
224 | 140 | // FIXME: Do we want to allow resizing of shared data? | ||
225 | 141 | if (x.unique()) | ||
226 | 142 | { | ||
227 | 143 | _size = N; | ||
228 | 144 | x.reset(new T[N]); | ||
229 | 145 | } | ||
230 | 146 | else | ||
231 | 147 | { | ||
232 | 148 | dolfin_error("Array.h", | ||
233 | 149 | "resize Array", | ||
234 | 150 | "Data is shared"); | ||
235 | 151 | } | ||
236 | 152 | } | ||
237 | 153 | |||
238 | 154 | /// Return true if empty | ||
239 | 155 | bool empty() const | ||
240 | 156 | { return _size == 0; } | ||
241 | 157 | |||
242 | 158 | /// Return size of array | 110 | /// Return size of array |
243 | 159 | uint size() const | 111 | uint size() const |
244 | 160 | { return _size; } | 112 | { return _size; } |
245 | 161 | 113 | ||
246 | 162 | /// Zero array | ||
247 | 163 | void zero() | ||
248 | 164 | { dolfin_assert(x); std::fill(&x[0], &x[_size], 0.0); } | ||
249 | 165 | |||
250 | 166 | /// Set entries which meet (abs(x[i]) < eps) to zero | 114 | /// Set entries which meet (abs(x[i]) < eps) to zero |
251 | 167 | void zero_eps(double eps=DOLFIN_EPS); | 115 | void zero_eps(double eps=DOLFIN_EPS); |
252 | 168 | 116 | ||
253 | 169 | /// Return minimum value of array | ||
254 | 170 | T min() const | ||
255 | 171 | { dolfin_assert(x); return *std::min_element(&x[0], &x[_size]); } | ||
256 | 172 | |||
257 | 173 | /// Return maximum value of array | ||
258 | 174 | T max() const | ||
259 | 175 | { dolfin_assert(x); return *std::max_element(&x[0], &x[_size]); } | ||
260 | 176 | |||
261 | 177 | /// Access value of given entry (const version) | 117 | /// Access value of given entry (const version) |
262 | 178 | const T& operator[] (uint i) const | 118 | const T& operator[] (uint i) const |
264 | 179 | { dolfin_assert(x); dolfin_assert(i < _size); return x[i]; } | 119 | { dolfin_assert(i < _size); return _x[i]; } |
265 | 180 | 120 | ||
266 | 181 | /// Access value of given entry (non-const version) | 121 | /// Access value of given entry (non-const version) |
267 | 182 | T& operator[] (uint i) | 122 | T& operator[] (uint i) |
268 | 123 | { dolfin_assert(i < _size); return _x[i]; } | ||
269 | 124 | |||
270 | 125 | /// Assignment operator. If resize is required, the Array must be owner. | ||
271 | 126 | Array& operator= (const Array& other) | ||
272 | 183 | { | 127 | { |
276 | 184 | dolfin_assert(x); | 128 | resize(other._size); |
277 | 185 | dolfin_assert(i < _size); | 129 | if (_size > 0) |
278 | 186 | return x[i]; | 130 | std::copy(&other._x[0], &other._x[_size], &_x[0]); |
279 | 131 | return *this; | ||
280 | 187 | } | 132 | } |
281 | 188 | 133 | ||
284 | 189 | /// Assign value to all entries | 134 | /// Assignment operator from std::vector. If resize is required, the Array must be owner. |
285 | 190 | const Array<T>& operator= (T& x) | 135 | Array& operator= (const std::vector<T>& other) |
286 | 191 | { | 136 | { |
290 | 192 | dolfin_assert(this->x); | 137 | resize(other.size()); |
291 | 193 | for (uint i = 0; i < _size; ++i) | 138 | if (_size > 0) |
292 | 194 | this->x[i] = x; | 139 | std::copy(&other[0], &other[_size], &_x[0]); |
293 | 195 | return *this; | 140 | return *this; |
294 | 196 | } | 141 | } |
295 | 197 | 142 | ||
296 | 198 | /// Return pointer to data (const version) | 143 | /// Return pointer to data (const version) |
299 | 199 | const boost::shared_array<T> data() const | 144 | const T* data() const |
300 | 200 | { return x; } | 145 | { return _x; } |
301 | 201 | 146 | ||
302 | 202 | /// Return pointer to data (non-const version) | 147 | /// Return pointer to data (non-const version) |
305 | 203 | boost::shared_array<T> data() | 148 | T* data() |
306 | 204 | { return x; } | 149 | { return _x; } |
307 | 150 | |||
308 | 151 | private: | ||
309 | 152 | |||
310 | 153 | /// Disable copy construction, to avoid unanticipated sharing or | ||
311 | 154 | /// copying of data. This means that an Array must always be passed as | ||
312 | 155 | /// reference, or as a (possibly shared) pointer. | ||
313 | 156 | Array(const Array& other) /* leave body undefined */; | ||
314 | 205 | 157 | ||
315 | 206 | private: | 158 | private: |
316 | 207 | 159 | ||
318 | 208 | // Length of array | 160 | /// Length of array |
319 | 209 | uint _size; | 161 | uint _size; |
320 | 210 | 162 | ||
323 | 211 | // Array data | 163 | /// Array data |
324 | 212 | boost::shared_array<T> x; | 164 | T* _x; |
325 | 213 | 165 | ||
326 | 166 | /// True if instance is owner of data | ||
327 | 167 | bool _owner; | ||
328 | 214 | }; | 168 | }; |
329 | 215 | 169 | ||
330 | 216 | template <typename T> | 170 | template <typename T> |
331 | @@ -224,11 +178,10 @@ | |||
332 | 224 | template <> | 178 | template <> |
333 | 225 | inline void Array<double>::zero_eps(double eps) | 179 | inline void Array<double>::zero_eps(double eps) |
334 | 226 | { | 180 | { |
335 | 227 | dolfin_assert(x); | ||
336 | 228 | for (uint i = 0; i < _size; ++i) | 181 | for (uint i = 0; i < _size; ++i) |
337 | 229 | { | 182 | { |
340 | 230 | if (std::abs(x[i]) < eps) | 183 | if (std::abs(_x[i]) < eps) |
341 | 231 | x[i] = 0.0; | 184 | _x[i] = 0.0; |
342 | 232 | } | 185 | } |
343 | 233 | } | 186 | } |
344 | 234 | 187 | ||
345 | 235 | 188 | ||
346 | === modified file 'dolfin/function/Function.cpp' | |||
347 | --- dolfin/function/Function.cpp 2012-03-01 12:01:06 +0000 | |||
348 | +++ dolfin/function/Function.cpp 2012-03-07 13:15:44 +0000 | |||
349 | @@ -315,7 +315,7 @@ | |||
350 | 315 | const Mesh& mesh = *_function_space->mesh(); | 315 | const Mesh& mesh = *_function_space->mesh(); |
351 | 316 | 316 | ||
352 | 317 | // Find the cell that contains x | 317 | // Find the cell that contains x |
354 | 318 | const double* _x = x.data().get(); | 318 | const double* _x = x.data(); |
355 | 319 | const Point point(mesh.geometry().dim(), _x); | 319 | const Point point(mesh.geometry().dim(), _x); |
356 | 320 | int id = mesh.intersected_cell(point); | 320 | int id = mesh.intersected_cell(point); |
357 | 321 | 321 | ||
358 | @@ -440,7 +440,7 @@ | |||
359 | 440 | dolfin_assert(_function_space->mesh()); | 440 | dolfin_assert(_function_space->mesh()); |
360 | 441 | const Mesh& mesh = *_function_space->mesh(); | 441 | const Mesh& mesh = *_function_space->mesh(); |
361 | 442 | 442 | ||
363 | 443 | const double* _x = x.data().get(); | 443 | const double* _x = x.data(); |
364 | 444 | const uint dim = mesh.geometry().dim(); | 444 | const uint dim = mesh.geometry().dim(); |
365 | 445 | const Point point(dim, _x); | 445 | const Point point(dim, _x); |
366 | 446 | 446 | ||
367 | 447 | 447 | ||
368 | === modified file 'dolfin/graph/ZoltanInterface.cpp' | |||
369 | --- dolfin/graph/ZoltanInterface.cpp 2011-11-18 12:14:50 +0000 | |||
370 | +++ dolfin/graph/ZoltanInterface.cpp 2012-03-07 13:15:44 +0000 | |||
371 | @@ -72,7 +72,7 @@ | |||
372 | 72 | // Call Zoltan function to compute coloring | 72 | // Call Zoltan function to compute coloring |
373 | 73 | int num_id = 1; | 73 | int num_id = 1; |
374 | 74 | int rc = zoltan.Color(num_id, graph.size(), &global_ids[0], | 74 | int rc = zoltan.Color(num_id, graph.size(), &global_ids[0], |
376 | 75 | reinterpret_cast<int*>(colors.data().get())); | 75 | reinterpret_cast<int*>(colors.data())); |
377 | 76 | if (rc != ZOLTAN_OK) | 76 | if (rc != ZOLTAN_OK) |
378 | 77 | { | 77 | { |
379 | 78 | dolfin_error("ZoltanInterface.cpp", | 78 | dolfin_error("ZoltanInterface.cpp", |
380 | 79 | 79 | ||
381 | === modified file 'dolfin/io/BinaryFile.cpp' | |||
382 | --- dolfin/io/BinaryFile.cpp 2012-03-01 12:01:06 +0000 | |||
383 | +++ dolfin/io/BinaryFile.cpp 2012-03-07 13:15:44 +0000 | |||
384 | @@ -65,7 +65,7 @@ | |||
385 | 65 | 65 | ||
386 | 66 | const uint n = read_uint(); | 66 | const uint n = read_uint(); |
387 | 67 | Array<double> values(n); | 67 | Array<double> values(n); |
389 | 68 | read_array(n, values.data().get()); | 68 | read_array(n, values.data()); |
390 | 69 | 69 | ||
391 | 70 | vector.resize(n); | 70 | vector.resize(n); |
392 | 71 | vector.set_local(values); | 71 | vector.set_local(values); |
393 | @@ -148,7 +148,7 @@ | |||
394 | 148 | Array<double> values(n); | 148 | Array<double> values(n); |
395 | 149 | vector.get_local(values); | 149 | vector.get_local(values); |
396 | 150 | write_uint(n); | 150 | write_uint(n); |
398 | 151 | write_array(n, values.data().get()); | 151 | write_array(n, values.data()); |
399 | 152 | 152 | ||
400 | 153 | close_write(); | 153 | close_write(); |
401 | 154 | } | 154 | } |
402 | 155 | 155 | ||
403 | === modified file 'dolfin/io/XMLFunctionData.cpp' | |||
404 | --- dolfin/io/XMLFunctionData.cpp 2011-11-18 12:14:50 +0000 | |||
405 | +++ dolfin/io/XMLFunctionData.cpp 2012-03-07 13:15:44 +0000 | |||
406 | @@ -51,8 +51,8 @@ | |||
407 | 51 | const FunctionSpace& V = *u.function_space(); | 51 | const FunctionSpace& V = *u.function_space(); |
408 | 52 | 52 | ||
409 | 53 | std::vector<std::pair<uint, uint> > global_to_cell_dof; | 53 | std::vector<std::pair<uint, uint> > global_to_cell_dof; |
412 | 54 | Array<double> x; | 54 | std::vector<double> x; |
413 | 55 | Array<uint> indices; | 55 | std::vector<uint> indices; |
414 | 56 | 56 | ||
415 | 57 | const uint num_dofs = V.dim(); | 57 | const uint num_dofs = V.dim(); |
416 | 58 | 58 | ||
417 | @@ -115,7 +115,7 @@ | |||
418 | 115 | indices[i] = new_index; | 115 | indices[i] = new_index; |
419 | 116 | } | 116 | } |
420 | 117 | 117 | ||
422 | 118 | vector.set(x.data().get(), x.size(), indices.data().get()); | 118 | vector.set(&x[0], x.size(), &indices[0]); |
423 | 119 | } | 119 | } |
424 | 120 | 120 | ||
425 | 121 | // Finalise vector | 121 | // Finalise vector |
426 | 122 | 122 | ||
427 | === modified file 'dolfin/io/XMLVector.cpp' | |||
428 | --- dolfin/io/XMLVector.cpp 2011-11-18 12:14:50 +0000 | |||
429 | +++ dolfin/io/XMLVector.cpp 2012-03-07 13:15:44 +0000 | |||
430 | @@ -44,7 +44,7 @@ | |||
431 | 44 | read(data, indices, xml_dolfin); | 44 | read(data, indices, xml_dolfin); |
432 | 45 | 45 | ||
433 | 46 | // Set data (GenericVector::apply will be called by calling function) | 46 | // Set data (GenericVector::apply will be called by calling function) |
435 | 47 | x.set(data.data().get(), data.size(), indices.data().get()); | 47 | x.set(data.data(), data.size(), indices.data()); |
436 | 48 | } | 48 | } |
437 | 49 | //----------------------------------------------------------------------------- | 49 | //----------------------------------------------------------------------------- |
438 | 50 | void XMLVector::read(Array<double>& x, Array<uint>& indices, | 50 | void XMLVector::read(Array<double>& x, Array<uint>& indices, |
439 | 51 | 51 | ||
440 | === modified file 'dolfin/la/EpetraVector.cpp' | |||
441 | --- dolfin/la/EpetraVector.cpp 2012-03-01 12:01:06 +0000 | |||
442 | +++ dolfin/la/EpetraVector.cpp 2012-03-07 13:15:44 +0000 | |||
443 | @@ -326,7 +326,7 @@ | |||
444 | 326 | 326 | ||
445 | 327 | values.resize(x->MyLength()); | 327 | values.resize(x->MyLength()); |
446 | 328 | 328 | ||
448 | 329 | const int err = x->ExtractCopy(values.data().get(), 0); | 329 | const int err = x->ExtractCopy(values.data(), 0); |
449 | 330 | if (err!= 0) | 330 | if (err!= 0) |
450 | 331 | { | 331 | { |
451 | 332 | dolfin_error("EpetraVector.cpp", | 332 | dolfin_error("EpetraVector.cpp", |
452 | @@ -470,7 +470,7 @@ | |||
453 | 470 | Epetra_SerialComm serial_comm = f.get_serial_comm(); | 470 | Epetra_SerialComm serial_comm = f.get_serial_comm(); |
454 | 471 | 471 | ||
455 | 472 | // Create map for y | 472 | // Create map for y |
457 | 473 | const int* _indices = reinterpret_cast<const int*>(indices.data().get()); | 473 | const int* _indices = reinterpret_cast<const int*>(indices.data()); |
458 | 474 | Epetra_BlockMap target_map(indices.size(), indices.size(), _indices, 1, 0, serial_comm); | 474 | Epetra_BlockMap target_map(indices.size(), indices.size(), _indices, 1, 0, serial_comm); |
459 | 475 | 475 | ||
460 | 476 | // Reset vector y | 476 | // Reset vector y |
461 | 477 | 477 | ||
462 | === modified file 'dolfin/la/MUMPSLUSolver.cpp' | |||
463 | --- dolfin/la/MUMPSLUSolver.cpp 2011-11-02 16:03:33 +0000 | |||
464 | +++ dolfin/la/MUMPSLUSolver.cpp 2012-03-07 13:15:44 +0000 | |||
465 | @@ -159,7 +159,7 @@ | |||
466 | 159 | // Gather RHS on root process and attach | 159 | // Gather RHS on root process and attach |
467 | 160 | Array<double> _b; | 160 | Array<double> _b; |
468 | 161 | b.gather_on_zero(_b); | 161 | b.gather_on_zero(_b); |
470 | 162 | data.rhs = _b.data().get(); | 162 | data.rhs = _b.data(); |
471 | 163 | 163 | ||
472 | 164 | // Scaling strategy (77 is default) | 164 | // Scaling strategy (77 is default) |
473 | 165 | data.ICNTL(8) = 77; | 165 | data.ICNTL(8) = 77; |
474 | @@ -171,8 +171,8 @@ | |||
475 | 171 | 171 | ||
476 | 172 | // Attach solution data to MUMPS object | 172 | // Attach solution data to MUMPS object |
477 | 173 | data.lsol_loc = local_x_size; | 173 | data.lsol_loc = local_x_size; |
480 | 174 | data.sol_loc = x_local_vals.data().get(); | 174 | data.sol_loc = x_local_vals.data(); |
481 | 175 | data.isol_loc = reinterpret_cast<int*>(x_local_indices.data().get()); | 175 | data.isol_loc = reinterpret_cast<int*>(x_local_indices.data()); |
482 | 176 | 176 | ||
483 | 177 | // Solve problem | 177 | // Solve problem |
484 | 178 | data.job = 3; | 178 | data.job = 3; |
485 | @@ -185,8 +185,8 @@ | |||
486 | 185 | x_local_indices[i]--; | 185 | x_local_indices[i]--; |
487 | 186 | 186 | ||
488 | 187 | // Set x values | 187 | // Set x values |
491 | 188 | x.set(x_local_vals.data().get(), x_local_indices.size(), | 188 | x.set(x_local_vals.data(), x_local_indices.size(), |
492 | 189 | x_local_indices.data().get()); | 189 | x_local_indices.data()); |
493 | 190 | x.apply("insert"); | 190 | x.apply("insert"); |
494 | 191 | 191 | ||
495 | 192 | // Clean up | 192 | // Clean up |
496 | 193 | 193 | ||
497 | === modified file 'dolfin/la/PETScVector.cpp' | |||
498 | --- dolfin/la/PETScVector.cpp 2012-03-01 12:01:06 +0000 | |||
499 | +++ dolfin/la/PETScVector.cpp 2012-03-07 13:15:44 +0000 | |||
500 | @@ -228,7 +228,7 @@ | |||
501 | 228 | for (uint i = 0; i < local_size; ++i) | 228 | for (uint i = 0; i < local_size; ++i) |
502 | 229 | rows[i] = i + n0; | 229 | rows[i] = i + n0; |
503 | 230 | 230 | ||
505 | 231 | VecGetValues(*x, local_size, &rows[0], values.data().get()); | 231 | VecGetValues(*x, local_size, &rows[0], values.data()); |
506 | 232 | } | 232 | } |
507 | 233 | //----------------------------------------------------------------------------- | 233 | //----------------------------------------------------------------------------- |
508 | 234 | void PETScVector::set_local(const Array<double>& values) | 234 | void PETScVector::set_local(const Array<double>& values) |
509 | @@ -251,7 +251,7 @@ | |||
510 | 251 | for (uint i = 0; i < local_size; ++i) | 251 | for (uint i = 0; i < local_size; ++i) |
511 | 252 | rows[i] = i + n0; | 252 | rows[i] = i + n0; |
512 | 253 | 253 | ||
514 | 254 | VecSetValues(*x, local_size, &rows[0], values.data().get(), INSERT_VALUES); | 254 | VecSetValues(*x, local_size, &rows[0], values.data(), INSERT_VALUES); |
515 | 255 | } | 255 | } |
516 | 256 | //----------------------------------------------------------------------------- | 256 | //----------------------------------------------------------------------------- |
517 | 257 | void PETScVector::add_local(const Array<double>& values) | 257 | void PETScVector::add_local(const Array<double>& values) |
518 | @@ -274,7 +274,7 @@ | |||
519 | 274 | for (uint i = 0; i < local_size; ++i) | 274 | for (uint i = 0; i < local_size; ++i) |
520 | 275 | rows[i] = i + n0; | 275 | rows[i] = i + n0; |
521 | 276 | 276 | ||
523 | 277 | VecSetValues(*x, local_size, &rows[0], values.data().get(), ADD_VALUES); | 277 | VecSetValues(*x, local_size, &rows[0], values.data(), ADD_VALUES); |
524 | 278 | } | 278 | } |
525 | 279 | //----------------------------------------------------------------------------- | 279 | //----------------------------------------------------------------------------- |
526 | 280 | void PETScVector::get_local(double* block, uint m, const uint* rows) const | 280 | void PETScVector::get_local(double* block, uint m, const uint* rows) const |
527 | @@ -681,7 +681,7 @@ | |||
528 | 681 | } | 681 | } |
529 | 682 | 682 | ||
530 | 683 | // Prepare data for index sets (global indices) | 683 | // Prepare data for index sets (global indices) |
532 | 684 | const int* global_indices = reinterpret_cast<const int*>(indices.data().get()); | 684 | const int* global_indices = reinterpret_cast<const int*>(indices.data()); |
533 | 685 | 685 | ||
534 | 686 | // Prepare data for index sets (local indices) | 686 | // Prepare data for index sets (local indices) |
535 | 687 | const int n = indices.size(); | 687 | const int n = indices.size(); |
536 | 688 | 688 | ||
537 | === modified file 'dolfin/mesh/MeshSmoothing.cpp' | |||
538 | --- dolfin/mesh/MeshSmoothing.cpp 2011-06-02 19:26:59 +0000 | |||
539 | +++ dolfin/mesh/MeshSmoothing.cpp 2012-03-07 13:15:44 +0000 | |||
540 | @@ -157,13 +157,12 @@ | |||
541 | 157 | BoundaryMesh boundary(mesh); | 157 | BoundaryMesh boundary(mesh); |
542 | 158 | 158 | ||
543 | 159 | const uint dim = mesh.geometry().dim(); | 159 | const uint dim = mesh.geometry().dim(); |
544 | 160 | Array<double> x; | ||
545 | 161 | 160 | ||
546 | 162 | // Smooth boundary | 161 | // Smooth boundary |
547 | 163 | MeshGeometry& geometry = boundary.geometry(); | 162 | MeshGeometry& geometry = boundary.geometry(); |
548 | 164 | for (uint i = 0; i < boundary.num_vertices(); i++) | 163 | for (uint i = 0; i < boundary.num_vertices(); i++) |
549 | 165 | { | 164 | { |
551 | 166 | x.update(dim, geometry.x(i)); | 165 | Array<double> x(dim, geometry.x(i)); |
552 | 167 | sub_domain.snap(x); | 166 | sub_domain.snap(x); |
553 | 168 | } | 167 | } |
554 | 169 | 168 | ||
555 | 170 | 169 | ||
556 | === modified file 'dolfin/mesh/SubDomain.cpp' | |||
557 | --- dolfin/mesh/SubDomain.cpp 2012-03-06 13:55:20 +0000 | |||
558 | +++ dolfin/mesh/SubDomain.cpp 2012-03-07 13:15:44 +0000 | |||
559 | @@ -162,9 +162,6 @@ | |||
560 | 162 | // Extract exterior (non shared) facets markers | 162 | // Extract exterior (non shared) facets markers |
561 | 163 | const MeshFunction<bool>& exterior = mesh.parallel_data().exterior_facet(); | 163 | const MeshFunction<bool>& exterior = mesh.parallel_data().exterior_facet(); |
562 | 164 | 164 | ||
563 | 165 | // Array for vertex coordinate | ||
564 | 166 | Array<double> x; | ||
565 | 167 | |||
566 | 168 | // Speed up the computation by only checking each vertex once (or twice if it | 165 | // Speed up the computation by only checking each vertex once (or twice if it |
567 | 169 | // is on the boundary for some but not all facets). | 166 | // is on the boundary for some but not all facets). |
568 | 170 | RangedIndexSet boundary_visited(mesh.num_vertices()); | 167 | RangedIndexSet boundary_visited(mesh.num_vertices()); |
569 | @@ -197,7 +194,7 @@ | |||
570 | 197 | { | 194 | { |
571 | 198 | if (is_visited.insert(vertex->index())) | 195 | if (is_visited.insert(vertex->index())) |
572 | 199 | { | 196 | { |
574 | 200 | x.update(_geometric_dimension, const_cast<double*>(vertex->x())); | 197 | Array<double> x(_geometric_dimension, const_cast<double*>(vertex->x())); |
575 | 201 | is_inside[vertex->index()] = inside(x, on_boundary); | 198 | is_inside[vertex->index()] = inside(x, on_boundary); |
576 | 202 | } | 199 | } |
577 | 203 | 200 | ||
578 | @@ -212,8 +209,8 @@ | |||
579 | 212 | // Check midpoint (works also in the case when we have a single vertex) | 209 | // Check midpoint (works also in the case when we have a single vertex) |
580 | 213 | if (all_points_inside) | 210 | if (all_points_inside) |
581 | 214 | { | 211 | { |
584 | 215 | x.update(_geometric_dimension, | 212 | Array<double> x(_geometric_dimension, |
585 | 216 | const_cast<double*>(entity->midpoint().coordinates())); | 213 | const_cast<double*>(entity->midpoint().coordinates())); |
586 | 217 | if (!inside(x, on_boundary)) | 214 | if (!inside(x, on_boundary)) |
587 | 218 | all_points_inside = false; | 215 | all_points_inside = false; |
588 | 219 | } | 216 | } |
589 | 220 | 217 | ||
590 | === modified file 'dolfin/swig/common/post.i' | |||
591 | --- dolfin/swig/common/post.i 2012-01-17 22:38:08 +0000 | |||
592 | +++ dolfin/swig/common/post.i 2012-03-07 13:15:44 +0000 | |||
593 | @@ -55,8 +55,6 @@ | |||
594 | 55 | // in any typemaps | 55 | // in any typemaps |
595 | 56 | %feature("valuewrapper") dolfin::Array<TYPE>; | 56 | %feature("valuewrapper") dolfin::Array<TYPE>; |
596 | 57 | 57 | ||
597 | 58 | %ignore dolfin::Array<TYPE>::Array(uint N, boost::shared_array<TYPE> x); | ||
598 | 59 | |||
599 | 60 | // Cannot construct an Array from another Array. | 58 | // Cannot construct an Array from another Array. |
600 | 61 | // Use NumPy Array instead | 59 | // Use NumPy Array instead |
601 | 62 | %ignore dolfin::Array<TYPE>::Array(const Array& other); | 60 | %ignore dolfin::Array<TYPE>::Array(const Array& other); |
602 | @@ -72,7 +70,7 @@ | |||
603 | 72 | void __setitem__(unsigned int i, const TYPE& val) { (*self)[i] = val; } | 70 | void __setitem__(unsigned int i, const TYPE& val) { (*self)[i] = val; } |
604 | 73 | 71 | ||
605 | 74 | PyObject * array(){ | 72 | PyObject * array(){ |
607 | 75 | return %make_numpy_array(1, TYPE_NAME)(self->size(), self->data().get(), true); | 73 | return %make_numpy_array(1, TYPE_NAME)(self->size(), self->data(), true); |
608 | 76 | } | 74 | } |
609 | 77 | 75 | ||
610 | 78 | } | 76 | } |
611 | @@ -83,7 +81,7 @@ | |||
612 | 83 | //----------------------------------------------------------------------------- | 81 | //----------------------------------------------------------------------------- |
613 | 84 | CONST_ARRAY_IGNORES(double) | 82 | CONST_ARRAY_IGNORES(double) |
614 | 85 | ARRAY_EXTENSIONS(double, Double, double) | 83 | ARRAY_EXTENSIONS(double, Double, double) |
616 | 86 | ARRAY_EXTENSIONS(const double, ConstDouble, double) | 84 | //ARRAY_EXTENSIONS(const double, ConstDouble, double) |
617 | 87 | ARRAY_EXTENSIONS(unsigned int, UInt, uint) | 85 | ARRAY_EXTENSIONS(unsigned int, UInt, uint) |
618 | 88 | ARRAY_EXTENSIONS(int, Int, int) | 86 | ARRAY_EXTENSIONS(int, Int, int) |
619 | 89 | 87 | ||
620 | 90 | 88 | ||
621 | === modified file 'dolfin/swig/la/la_get_set_items.i' | |||
622 | --- dolfin/swig/la/la_get_set_items.i 2012-01-17 22:38:08 +0000 | |||
623 | +++ dolfin/swig/la/la_get_set_items.i 2012-03-07 13:15:44 +0000 | |||
624 | @@ -413,10 +413,10 @@ | |||
625 | 413 | dolfin::Array<double>* values = new dolfin::Array<double>(inds->size()); | 413 | dolfin::Array<double>* values = new dolfin::Array<double>(inds->size()); |
626 | 414 | if (row) | 414 | if (row) |
627 | 415 | // If returning a single row | 415 | // If returning a single row |
629 | 416 | self->get(values->data().get(), 1, &single, inds->size(), indices); | 416 | self->get(values->data(), 1, &single, inds->size(), indices); |
630 | 417 | else | 417 | else |
631 | 418 | // If returning a single column | 418 | // If returning a single column |
633 | 419 | self->get(values->data().get(), inds->size(), indices, 1, &single); | 419 | self->get(values->data(), inds->size(), indices, 1, &single); |
634 | 420 | 420 | ||
635 | 421 | // Create the return vector and set the values | 421 | // Create the return vector and set the values |
636 | 422 | boost::shared_ptr<dolfin::GenericVector> return_vec = self->factory().create_vector(); | 422 | boost::shared_ptr<dolfin::GenericVector> return_vec = self->factory().create_vector(); |
637 | 423 | 423 | ||
638 | === modified file 'dolfin/swig/typemaps/array.i' | |||
639 | --- dolfin/swig/typemaps/array.i 2012-01-30 22:44:17 +0000 | |||
640 | +++ dolfin/swig/typemaps/array.i 2012-03-07 13:15:44 +0000 | |||
641 | @@ -90,11 +90,11 @@ | |||
642 | 90 | // Director typemaps for dolfin::Array | 90 | // Director typemaps for dolfin::Array |
643 | 91 | //----------------------------------------------------------------------------- | 91 | //----------------------------------------------------------------------------- |
644 | 92 | %typemap(directorin) const dolfin::Array<double>& { | 92 | %typemap(directorin) const dolfin::Array<double>& { |
646 | 93 | $input = %make_numpy_array(1, double)($1_name.size(), $1_name.data().get(), false); | 93 | $input = %make_numpy_array(1, double)($1_name.size(), $1_name.data(), false); |
647 | 94 | } | 94 | } |
648 | 95 | 95 | ||
649 | 96 | %typemap(directorin) dolfin::Array<double>& { | 96 | %typemap(directorin) dolfin::Array<double>& { |
651 | 97 | $input = %make_numpy_array(1, double)($1_name.size(), $1_name.data().get(), true); | 97 | $input = %make_numpy_array(1, double)($1_name.size(), $1_name.data(), true); |
652 | 98 | } | 98 | } |
653 | 99 | 99 | ||
654 | 100 | //----------------------------------------------------------------------------- | 100 | //----------------------------------------------------------------------------- |
655 | 101 | 101 | ||
656 | === modified file 'site-packages/dolfin/compilemodules/compilemodule.py' | |||
657 | --- site-packages/dolfin/compilemodules/compilemodule.py 2012-01-30 21:20:53 +0000 | |||
658 | +++ site-packages/dolfin/compilemodules/compilemodule.py 2012-03-07 13:15:44 +0000 | |||
659 | @@ -42,6 +42,11 @@ | |||
660 | 42 | "expression_to_code_fragments", | 42 | "expression_to_code_fragments", |
661 | 43 | "math_header"] | 43 | "math_header"] |
662 | 44 | 44 | ||
663 | 45 | # Bump the interface version if anything changes that invalidates cached | ||
664 | 46 | # modules (not required for change in generated code, swig version or dolfin | ||
665 | 47 | # version) | ||
666 | 48 | _interface_version = 0 | ||
667 | 49 | |||
668 | 45 | # A list of supported math builtins | 50 | # A list of supported math builtins |
669 | 46 | _math_builtins = [ | 51 | _math_builtins = [ |
670 | 47 | # cmath functions: | 52 | # cmath functions: |
671 | @@ -416,7 +421,8 @@ | |||
672 | 416 | if module_name is "": | 421 | if module_name is "": |
673 | 417 | module_name = "dolfin_compile_code_%s" % hashlib.md5(repr(code) +\ | 422 | module_name = "dolfin_compile_code_%s" % hashlib.md5(repr(code) +\ |
674 | 418 | instant.get_swig_version() +\ | 423 | instant.get_swig_version() +\ |
676 | 419 | dolfin.__version__).hexdigest() | 424 | dolfin.__version__ +\ |
677 | 425 | str(_interface_version)).hexdigest() | ||
678 | 420 | # Check the handed import files | 426 | # Check the handed import files |
679 | 421 | if dolfin_module_import: | 427 | if dolfin_module_import: |
680 | 422 | interface_files = [] | 428 | interface_files = [] |
Where in the code were the most Arrays being created?