1

Topic: shared_ptr

I am about to submit simplified FieldManager code, that is based on shared_ptr implementation. The advantage is that one can register managed fields ans well as newly alocated fields without taking care of ownership, shared_ptr will take care.
The problem is that shared_ptr support is part of recent c++ standard, so I have made this implementation optional, until it will be tested on different platforms and compilers. By default this option is inactive. Everyone is welcome to try it and report any problem.
The shared_ptr implementation can be turned on by setting -DFIELDMANAGER_USE_SHARED_PTR compiler flag when running cmake.

Re: shared_ptr

Hi!

Enabling -DFIELDMANAGER_USE_SHARED_PTR works fine for me. I use OpenSUSE 12.3 and compile with gcc.

I would also be interested to use some c++11 features, e.g. the auto keyword. Unfortunately, not all features are supported by all compilers yet. However, some "lighter" features like auto and decltype seem to be supported by the most popular compilers:
http://cpprocks.com/c11-compiler-suppor … ang-intel/

Perhaps we could start using some of the c++11 features, but stay away from features that are not yet fully supported?

/Erik

Re: shared_ptr

And I would like to use:

initializer lists
for range loops
forward declared enums
lambda expressions
<chrono> and probably a few other things from the upgraded standard library.

Re: shared_ptr

I've experimented a little with initializer_list, and I love it.
It would replace setValues with a shorter, nicer, syntax. It's also faster (performance wise, .

Compare

   IntArray x;
   x = {1,2,3};
   x.setValues(3,  1, 2, 3);

and there are other cool sideeffects, like being able to inline an intarray for convenience

   // old way
   FloatArray coords(3);
   coords.setValues(3,  0.5, 1.5, 2.0);
   myFunction(coords, someresults);
  // New way
  myFunction({0.5, 1.5, 2.0}, someresults);

even *better*, one can also do this for matrices, with the syntax as familiar.

   FloatMatrix x = {{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}};

(i opted to stay with the column major order here, for consistency).

Re: shared_ptr

In Visual Studio 2013 they have finally implemented some more features from C++11.

* initializer_list
* for range loops
* shared_ptr
* chrono

should exist, and I think we should strongly consider VS2013 as a requirement in order to use these.
Intel Compiler 14.0 should also be good, but version 13.0 only has "partial" support for initializer_list (I don't know what that means in practice).

Re: shared_ptr

I implemented support for breaking really long input lines in the input files by "escaping" the newline with a \ character at the end of the lines.

For example;

SimpleVitrificationMaterial 1 d 0. vitrificationTime 2.0 \
E 3 130000. 9500. 9500.   G 3 4500. 4500. 4500.  nu 3 0.45 0.3 0.3  alpha 3 2e-8 32e-6 32e-6 \
E_r 3 130000. 165. 165.   G_r 3 41. 44. 44.  nu_r 3 0.098 0.345 0.345  alpha_r 3 2e-8 64e-6 64e-6

This is great for things like the layered cross-section, which tends to have very long input lines.

This used 2 functions for std::string which surprisingly was first introduced in C++11 STL. std::string::pop_back() and std::string::back()

Re: shared_ptr

I added flags for enabling c++11 now.

I also added a test file so that people can check to see if they have the features necessary for C++11 in their compiler.

Post's attachments

cpp11test.c 544 b, 2 downloads since 2014-02-14 

You don't have the permssions to download the attachments of this post.

Re: shared_ptr

I made a commit on changing the timer class, making it use the new standardized <chrono> objects. It lets us cut down on the cross-platform differences in the code, as such things often are sources of errors.

As far as I can see, chrono should work with all compilers, but, of course, it is hard to be certain.

If anyone is having unfixable problems with this commit, reverting it might be necessary.

------------------

Variadic macros are in also mandatory in the C++11 standard. Should be fine with MSVC, GCC, Clang, Intel, and any other C++11 compliant compiler.



Please let me know if anyone is having problems with these changes, and we can take a look at fixing or reverting the changes.

Re: shared_ptr

I cannot get it working.

Initially I got the error:
[  0%] Building CXX object src/fm/CMakeFiles/fm.dir/fluidmodel.C.o
error: invalid value 'c++11' in '-std=c++11'

After updating my compiler I still get the error:

src/oofemlib/floatarray.h:50:11: fatal error: 'initializer_list' file not found
#include <initializer_list>

Re: shared_ptr

Hi gustel,
Could you please tell me what compiler you are using?
Including version information.

Re: shared_ptr

I had problems with

clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin11.4.0
Thread model: posix

However, I tried today with gcc47 which works. So, problem resolved.

Re: shared_ptr

Hi gustel
clang 3.3 really ought to work as well.
As far as I can find, even clang 3.2 used the -std=c++11 flag, and I can at least test with clang 3.2 and confirm that it works there.


Perhaps it just needed a fresh-configuration from cmake?
If you have the opportunity, please do check with reconfiguring with cmake using clang++  from an empty directory.

Re: shared_ptr

If I use in a new folder

cmake -DCMAKE_CXX_COMPILER=clang++ ~/oofem

It gives me

-- The CXX compiler identification is Clang 3.3.0
-- Check for working CXX compiler: /opt/local/bin/clang++
-- Check for working CXX compiler: /opt/local/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found PythonInterp: /opt/local/bin/python2.7 (found suitable version "2.7.6", minimum required is "2.7")
-- Looking for C++ include strings.h
-- Looking for C++ include strings.h - found
-- Looking for C++ include unistd.h
-- Looking for C++ include unistd.h - found
-- Looking for C++ include execinfo.h
-- Looking for C++ include execinfo.h - found
-- Looking for strncasecmp
-- Looking for strncasecmp - found
-- Looking for access
-- Looking for access - found
-- Looking for cbrt
-- Looking for cbrt - found
-- Looking for isnan
-- Looking for isnan - not found
-- Performing Test HAVE_MACRO_VA_ARGS
-- Performing Test HAVE_MACRO_VA_ARGS - Success
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Found Doxygen: /opt/local/bin/doxygen (found version "1.8.3.1")
-- Configuring done
-- Generating done

If I then make, I get

src/oofemlib/floatarray.h:50:11: fatal error: 'initializer_list' file not
      found
#include <initializer_list>
          ^
1 error generated.
make[2]: *** [src/fm/CMakeFiles/fm.dir/fluidmodel.C.o] Error 1
make[1]: *** [src/fm/CMakeFiles/fm.dir/all] Error 2
make: *** [all] Error 2

Re: shared_ptr

Thank you gustel.

I did some testing, and it seems one needs to add "-stdlib=libc++" to the compiler flags for older versions of clang. At least clang 3.5 works without modification as the standard library it uses has all the c++11 stuff anyway.

BUT! here comes the second problem. It seems libc++ doesn't have strncasecmp. At least that's where it ends for me. I'll work some more and hopefully I'll be able to improve this situation.

Re: shared_ptr

I've gotten rid of the need for strncasecmp now in order to enable using libc++
It was used in 3 places;

1. Domain type; I'm hoping to remove this completely (no default dof ids), but it should work with just strncmp anyway since all strings are converted to lowercase by oofemtxtdatareader.

2. OOFEG commands; Just typing the command in lower case (which is likely what one would do anyway), so this change doesn't matter much.

3. Classfactory; Everything should be converted to lowercase already, but just to be sure i convert them all to lower case (again) anyway inside each function call. This should be faster than using strncasecmp anyway, so it is all good.

Re: shared_ptr

Borek,
I noticed you fixed some things I missed when I tried to clear out the (unnecessary) check for HAVE_MACRO_VA_ARGS.
The C++11 standard actually incorporates variadic macros.
This, of course, doesn't mean that every compiler actually supports it yet, but as far as I can tell, all modern compilers do (i.e. GCC, Clang, Intel, VS).
These compilers have probably even supported variadic macros since before c++11.

Was the cause for your fix just a silly compilation error that I caused (since I missed some places), or do you know of a compiler that actually doesn't support variadic macros?

17

Re: shared_ptr

I had to fix this, as the server, which hosts oofem.org and where the nightly builds are made, is running Debian with quite old compiler (g++ 4.7.2). This server runs many applications, so upgrades are rather limited only to security fixes.

Re: shared_ptr

Yes, but 4.7  should definitely support variadic macros (even 4.3 should have them).
The build error was almost certainly just because I mistake in my changes (seems like i forgot to modify logger.C and oofemcfg.h.in). I just didn't notice it myself since it probably appears only if you do a new/clean configuration.
Since the test was removed from the cmakelists.txt so it would always (incorrectly) end up undefined in oofemcfg.h now, but it seems error.h works and the ifdef has been removed from that.


I pushed some new changes now, hopefully correcting my previous mistake.
(also, are the nightly build emails still bouncing for me? I never saw this error)


----------------


Unrelated to those changes, I also took the opportunity to merge the two loggers we have, since there were some silly redundancies with the log level parameter and the two different loggers. Much clearer with one logger, which uses different streams for different output.
A GUI might even want to point the output for each different log level to a seperate window, or in some ways modify them. For now, it's still just warnings/errors/fatals that are seperated from the rest.

Re: shared_ptr

I have some related changes (that i pushed to a new branch "new_logger").

1.
there has been some minor problems with printing errors. A sideeffect of having to many macros and it's hard to know which one to use.

2.
having to type out the classname or function name is just awful. They are often wrong (copy-paste mistakes).
I modified the macros and logger to pretty-print that automatically.


3.
the "error" and "warning" functions was duplicating a lot of code unnecessarily.
Also required a maximum error length (though it was very generous).
I have extracted the unique part of those functions and replaced with a much simpler function  (that is the pretty-printed function name).
I call this new function "errorInfo" and it's used for both error and warnings. I implemented it in a few classes that where missing it.


4.
_error and _warning is very unsafe as MACRO names. We should stick to namespaced names like OOFEM_ERROR.


5.
_proc is no longer needed either. All compilers have at least some macro that defines the function name. C99 dictates __func__, which  MSVC ignores, but they have __FUNCTION__ instead.
We might need to add another #ifdef-check there, but it should be safe to assume that we can easily fix that.




Now there are 2 sets of macros in error.h
E.g.
OOFEM_ERROR <-- Now the most expressive version. Use if possible.
and
OOFEM_SIMPLE_ERROR   <-- For C code and things that doesn't have classes. Use if OOFEM_ERROR won't work there.

I chose the shorter name for the one that uses "errorInfo", since it is much much more common.


This change was massive, simple due to there being so very many OOFEM_ERROR* and WARNING calls in the code already, but almost all of it are trivial 1 line changes.
I put them in a new branch anyway, it's called "new_logger".

Example of output:

Code:
OOFEM_ERROR("Some message here");


Output:
_______________________________________________________

Error: (/home/micket/projects/oofem/src/sm/linearstatic.C:296)
In LinearStatic::solveYourselfAt:
Some message here
_______________________________________________________




Code:
OOFEM_SIMPLE_ERROR("Some message here");


Output:
_______________________________________________________

Error: (/home/micket/projects/oofem/src/sm/linearstatic.C:296)
In solveYourselfAt:
Some message here
_______________________________________________________

Re: shared_ptr

I've gone through all the build configurations I could think off, and the new_logger branch seems to work fine now.

I probably also fixed several errors that were not caused by the Logger. Some changes related to the nodal recovery model that had not been fixed for OOFEG, and some too some trickier circular inclusions due to ScalarFunction and oofegGraphicContext.
These are all fixed in the new_logger branch now.
I will be merging it into master this week if there are no objections.

21

Re: shared_ptr

I experience some problems with the last commits:
I use ubuntu 12.04 with default g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3.
1) no emplace method used in dynamicinputrecord:

/home/bp/oofem.git/src/oofemlib/dynamicinputrecord.C: In member function ‘virtual void oofem::DynamicInputRecord::setField(std::initializer_list<double>, oofem::InputFieldType)’:
/home/bp/oofem.git/src/oofemlib/dynamicinputrecord.C:326:26: error: ‘class std::map<std::basic_string<char>, oofem::FloatArray>’ has no member named ‘emplace’

I have replaced this (not committted) by:

void DynamicInputRecord :: setField(std :: initializer_list< double > item, InputFieldType id)
{
  //this->floatArrayRecord.emplace(id, item);
  this->floatArrayRecord.insert(std::make_pair(id, FloatArray(item)));
}

2) more serious problem:

In file included from /usr/include/c++/4.6/random:38:0,
                 from /usr/include/c++/4.6/bits/stl_algo.h:67,
                 from /usr/include/c++/4.6/algorithm:63,
                 from /home/bp/oofem.git/src/oofemlib/floatmatrix.h:50,
                 from /home/bp/oofem.git/src/oofemlib/sparsemtrx.h:40,
                 from /home/bp/oofem.git/src/oofemlib/iml/imlsolver.h:39,
                 from /home/bp/oofem.git/src/oofemlib/iml/imlsolver.C:38:
/usr/include/c++/4.6/cmath:96:16: error: ‘template<class _Tp> typename __gnu_cxx::__enable_if<std::__is_integer<_Tp>::__value, double>::__type std::abs(_Tp)’ conflicts with previous using declaration ‘template<class Real> Real abs(Real)’

This happens when one compiles with iml support on. The iml defines its abs template function that conflicts with the one defined in cmath.
Do not have time to solve it. Perhaps these c++11 features should be developped and tested in separate branch more carefully, as it seems that one struggles with it from time to time. We should support default compiler versions that come with recent linux distributions.
-----
Edit1: Fixed and commited problem in dynamicinputrecord and gmres.h to git repo.
Edit2: Now fm/scctest01.in will fail (executed when iml is on), not sure waht caused the problem, but most likely not due to my fix in gmres.h
Edit3: Found that the commit (b6032b41e0243df6a0a34b0928115f3af1b261d0) is ok for ssctest01.in (The commit itself will not compile). Seems that the problem is in the following commits.
Edit4: Foundthat the commit (90035814b888e45995dccfaa3fbc39408214d80f) is ok as well.
Edit5: The problem of failing scctest01.in is in the big one (9fe8946b63c0dfeb2059a92ea7e013c5b061547f). Unfortunately its too big to easily spot the problem.

Re: shared_ptr

Sorry, scctest was my fault, it slipped through because I committed more than I intended.
It is fixed now.

I'll make a new branch for my future changes.

23

Re: shared_ptr

Upgraded g++ to 4.8.3, which fixes the recent compile related errors.
However, I think its good idea to proceed with only those c++ features, that are supported by the default compilers in recent versions of major linux distributions (Ubuntu, Debian, etc) at least.

Re: shared_ptr

Hi Borek,

I haven't tried to use any really exotic features from C++11, and the only things i can think of is 5 things:
* for-each loops + auto
* initializer_lists
* r-value references + move
and possibly some stuff from the updated STL, like unique_ptr/shared_ptr and other random functions they added.


I've tried out the code in OpenSUSE (currently at gcc 4.8.1) and Debian, and never saw any compilations issues.
It is hard to know exactly what is generally supported or not, so I don't know what the offending code might have been.

Re: shared_ptr

Erik told me he will fix the constexpr-stuff he accidentally added. I will merge those with oofem.org as soon as i have time.