Dear all,
I'm well aware that there will be outcry, but I've backed off of this
issue for months now due to some very vocal previous responses. But it's
actively preventing the library from growing in several productive ways:
1) C++11 finally guarantees the assumed memory model for std::complex,
and, perhaps more importantly, allows for the direct manipulation of the
real and imaginary components (I really have no idea why this was not
originally supported). With these additions, I feel comfortable getting
rid of the current from-scratch elem::Complex implementation, though,
pragmatically, it should still be a thin wrapper around std::complex
rather than simply a typedef, as:
(a) only float, double, and log double instantiations are considered
legal [1,p.890], and so higher-precision support will need to be
manually handled, and
(b) we might want to support complex datatypes whose base type is a
ring rather than a field, for example, to run a distributed Gemm where
each entry is of type elem::Complex<int> (or perhaps instead 'int'
modulo a prime).
2) Greatly improved random number generation. I find myself wanting to
implement a fast parallel scheme for generating/applying a Haar matrix
as part of an eigensolver scheme, but Elemental still hasn't decided on
how it wants to draw from normal distributions (a while back it did so
via Box-Mueller, which I now realize was a bad idea [2]), and I find it
silly to be manually implementing this when the new standard [1,p.934]
almost certainly provides something better. Furthermore, this avoids the
mess of Windows platforms not providing a C-style double-precision
uniform random-number generator (e.g., drand48()).
3) 'extern' templates [3] can likely be used to accelerate Elemental's
build system by avoiding the need to redundantly instantiate all of
Elemental's template classes within every translation unit. I care about
build system times, and while the current approach is a nice compromise
between the header-only and traditional source-file approaches, there is
obvious value in further decreasing build times.
3) 'auto' [4] and move semantics [5] can both be used to generally
simplify Elemental's syntax. For example, current code such as:
elem::DistMatrix<double> C;
elem::Gemm( NORMAL, NORMAL, 1., A, B, C );
could be replaced with
auto C = elem::Gemm( NORMAL, NORMAL, 1., A, B );
And, while we're on the subject, it would be simple to take this one
step further and add a few more obvious overloads for the usual cases
(i.e., NORMAL as the orientation option and 1 as the scalar coefficient)
to simply write
auto C = elem::Gemm( A, B );
I think that these sorts of syntactic simplifications make a large
difference over time. And this does not require any expression-template
hackery.
4) 'lambda' functions would be very convenient replacements for the
current functor approaches taken by routines such as
elem::RealHermitianFunction [6] and elem::Egorov [7].
5) The addition of '_Pragma' [1,p.30] would allow macros to contain
#pragma statements. This would allow all of the many cases such as [8]
to be simplified from three lines of preprocessor directives to one
concise macro, e.g., PARALLEL_FOR.
6) 'long long int' is guaranteed [9] by C++11, but not C++03, to be at
least 64-bit, which would be useful to set as Elemental's datatype for
storing global matrix dimensions. A regular 32-bit 'int' should stay the
default for local matrix dimensions, at least until MPI makes the switch
itself (but I don't want to get into this tangential point about MPI). I
know that we've extensively discussed this issue in the past, but I like
having 64-bit integers as a built-in datatype.
Is any of these particular items sufficient to justify the migration to
C++11? Probably not. But, in combination, I think that they are. The
migration will likely start in the near future.
Jack
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
[2] http://stackoverflow.com/a/3265174/1119818
[3] https://en.wikipedia.org/wiki/C++11#Extern_template
[4] https://en.wikipedia.org/wiki/C++11#Type_inference
[5] https://en.wikipedia.org/wiki/C++11#Rvalue_references_and_move_constructors
[6]
https://github.com/elemental/Elemental/blob/master/include/elemental/lapack-like/HermitianFunction.hpp
[7]
https://github.com/elemental/Elemental/blob/master/include/elemental/matrices/Egorov.hpp
[8]
https://github.com/elemental/Elemental/blob/master/src/core/dist_matrix/mc_mr.cpp#L485
[9] https://en.wikipedia.org/wiki/C++11#Type_long_long_int