Re: [eigen] Malloc-free dynamic matrices |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Malloc-free dynamic matrices
- From: leon zadorin <leonleon77@xxxxxxxxx>
- Date: Fri, 5 Mar 2010 13:23:46 +1100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=M8vCwYkz2Cvk7tKgrPPl3ULfJ/8ZRaTlnRwyNGSFAR0=; b=tnk6eDvH0JQE+D2WS8WZumPjSNZvh8wwPhjW6GGLh9v0kG5rFfyiTw+pi8aN9tM6fs Zg6g2Q3kTbxU/W3FpI4ybCPcebeSxAiERcZ3OY+COBK5QoZIOJXaQxnMad0Ao/sJlOQL h1MUvY+fJ0hrMGXQJOmP+GgxRrkoUOVweCNqw=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=gv/fB8OeE40Zkw3PbKjH4J1VQ7PBK+JEjOBRUAecGTzqqmYdwVV7LeRjMixMwsmkVK ZMUg23EnN47XZ0j7Lq0FoIsEtgUuorjAZisRXP3z2tB0ZQ+1Gp9how4lvBivdHG7obdk pF3yXNP/fOzYk48oOXQzjN7QAO9oTV179RSFo=
On 3/5/10, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:
> yes there are hundreds of way to achieve these goals without touching
> Matrix, but none of the solutions will be as convenient as having it by
> default directly inside Matrix. For instance, nobody would ever think about
> removing reserve from std::vector! I really don't see any valuable argument
> against doing so.
I am not quite sure if we are talking about the 100% same thing here.
The original poster's very goal (and his code examples) for
'NeverRealloc' appear to be semantically different from the concept of
"reserve".
In fact:
::std::vector<float> v1, v2;
v1.reserve(10), v2.reserve(100);
// populate v1 and v2 with 10 and 100 elements respectively
v1 = v2; // the original poster wants an assertion/error to be
generated -- i.e. by *design* he wants to *never* reallocate -- hence
the "NeverRealloc" option name... -- as per his own code example...
I know that you, later in your email, re-qualify this as an optional
feature -- but if so, to me, this is rather different w.r.t. the
concept of just reserving/caching the memory.
For instance, if we have already started comparing/justifying concepts
of "reserve" in eigen's matrix based on reservation semantics in
::std::vector -- should then one also, conversely, consider having the
'assert/error' option (when re-growth may be needed at the target obj)
for the ::std::vector as well? Of course not... :-)
"Reservation != reallocation" and clumping both into the same context
is not real clear to me.
So, if we are talking about "reservation" -- then *yes*, of course,
such a feature would be convenient in the Matrix obj. -- and it can
lead one on the path for more elaborate caching later on (e.g. not
just reserving-ahead via "reserve" but also having heuristics for
keeping the memory-size from previously-used large resize state
(similar to growth-control for large strings in Mozilla browser
afaik), etc. etc. etc. -- be those ideas reasonable/needed or not :-)
.... but this would be a rather different context for the conversation
as compared to the original's idea of *never* realloc and generating
assertions for the matrix re-growth...
[...]
> And finally, remains the question whether resizing above the pre allocated
> size should be allowed or not. Here it is pretty clear that the default must
> allows that.
[...]
> What do you think?
I agree indeed -- if one does go ahead with the "reserve", then
asserting is not a good idea (at least with a default state... if
ever) -- as "reserve" and "never-realloc" are two *distinct*
*different* semantic points -- otherwise ::std::vector would have
these assertions enforced as well :-)
leon.
> On Thu, Mar 4, 2010 at 3:58 AM, leon zadorin <leonleon77@xxxxxxxxx> wrote:
>
>> On 3/4/10, Márton Danóczy <marton78@xxxxxxxxx> wrote:
>> > On 3 March 2010 15:44, leon zadorin <leonleon77@xxxxxxxxx> wrote:
>> >> double * reserved(aligned_alloc(8192));
>> >>
>> >> // 3x3
>> >> Map<double> m(reserved, 3, 3);
>> >>
>> >> // 10x10 -- resize w/o reallocation -- equivalent to NeverRealloc w/o
>> >> much repatching(?)
>> >> m.remap(reserved, 10, 10);
>> >
>> [...]
>> > Matrix<float, Dynamic, Dynamic, NoRealloc> A, B, C;
>> >
>> > A.reserve(16); A.resize(4,4);
>> > B.reserve(25); B.resize(5,5);
>> > C.reserve(81); C.resize(9,9);
>> >
>> > B=A; //this should work and resize B to 4x4
>> > B=C; //this should raise an assertion failure
>> >
>> > To achieve this behaviour, we do need a dedicated class -- or an
>> > option, such as in the patch.
>>
>> Sure... but not quite -- if we are talking about adding extra
>> "sanity-checking" in the debug builds of an app, and if current API
>> has no such assertions, then some form of changes would be needed.
>>
>> But in such a case, still -- I don't think Benoit was arguing against
>> any changes -- only in favor of smaller/more-elegant ones...
>>
>> Map<> obj. ctor could indeed have an additional arg denoting the max
>> size of the (re)mappable mem (on which it is mapping)... or indeed, as
>> others have alluded to, one could pass an 'array object' instead of
>> just 'float/double *' (given that what you are really trying to
>> 'sanity-check' is the boundary -- and such is not meant to
>> auto-reallocate but to assert -- implying that this should not be
>> happening 'by design') -- so a logical conclusion would be for Map<>
>> to be able to map from a vector/array type (e.g. ::boost::array
>> semantics), then:
>>
>> array a1(25);
>> array a2(81);
>>
>> Map m1(a1, 5, 5);
>>
>> Map m2(a2, 9, 9);
>>
>> m1 = m2; // assertion due to boundary-checking of 'intelligent' arrays....
>>
>> or if constructing/mapping explicitly from "double/float *"
>>
>> double *a1(alloc(25));
>> Map m1(a1, 5, 5, 25); // i.e. additional arg denoting max mappable mem.
>>
>> double *a2(alloc(81));
>> Map m2(a2, 9, 9, 81);
>>
>> m1 = m2; // the same assertion... (ifndef NDEBUG of course)
>>
>> In fact, given that you are only requiring an assertion (not exception
>> throwing), then the actual presence of the above fields (e.g. in the
>> Map class, the 'bounds-keeping' variable could, itself, exist only
>> #ifndef NDEBUG
>> size_t max_mappable_size;
>> #endif
>>
>> Alternatively, as you mentioned -- another class may be used... but,
>> if such is to be the case, then what I was trying to say was that this
>> class feels like being more of a facade design-pattern, not a patch to
>> the existing class:
>>
>> struct blah {
>> double * data;
>> Map m;
>> blah()
>> : data(allocate), m(data, x, y)
>> {
>> }
>> etc. etc. -- like op= with checking for memory-bounds violations...
>> };
>>
>> ... but only if one wants it...
>>
>> from your code-example it looks to me like it really should be subject
>> to an "array" object... or a Map object... as memory-bounds checking
>> is really a question of abstracting the c-style 'arrays' in the first
>> place... ideally...
>>
>> kind regards
>> Leon.
>>
>>
>>
>