These are chat archives for symengine/symengine

4th
Mar 2016
Isuru Fernando
@isuruf
Mar 04 2016 10:50
@CodeMaxx, RCP is a similar to std::shared_ptr and UniquePtr is similar to std::unique_ptr. Both has its uses
Francesco Biscani
@bluescarni
Mar 04 2016 10:53
I was wondering what the advantages are with respect to the standard smart pointers?
Isuru Fernando
@isuruf
Mar 04 2016 10:56
SymEngine implementation keeps the ref count in the object itself
Francesco Biscani
@bluescarni
Mar 04 2016 10:58
you mean that usual shared_ptr implementations have some form of external storage?
Isuru Fernando
@isuruf
Mar 04 2016 10:59
In a typical implementation, std::shared_ptr holds only two pointers:
the stored pointer (one returned by get());
a pointer to control block.
The control block is a dynamically-allocated object that holds:
either a pointer to the managed object or the managed object itself;
the deleter (type-erased);
the allocator (type-erased);
the number of shared_ptrs that own the managed object;
the number of weak_ptrs that refer to the managed object.
Francesco Biscani
@bluescarni
Mar 04 2016 10:59
ah in that sense, so it avoids an extra allocation
and probably doesn't deal with the weak ptr stuff I imagine?
Isuru Fernando
@isuruf
Mar 04 2016 11:01
Yes
Isuru Fernando
@isuruf
Mar 04 2016 11:21
Also, it's not possible to get a shared_ptr from the object itself.
Ondřej Čertík
@certik
Mar 04 2016 15:45
@bluescarni mainly, our RCP in Release is much faster than shared_ptr. Our RCP in Debug mode is safe, because you can get a Ptr out of it, which is debug time checked for dangling pointers, so the code can't segfault. There is no such thing in the standard shared_ptr.
@CodeMaxx UniquePtr in Release mode is not slow. It should be as fast as manual new/delete.
Francesco Biscani
@bluescarni
Mar 04 2016 15:50
@certik right ok, makes sense. I still think probably you don't really need shared pointer semantics (or at least I don't see the need for it), and that you should be able to get away with std::unique_ptr only
Ondřej Čertík
@certik
Mar 04 2016 15:52
@bluescarni that would make things a lot faster.
Francesco Biscani
@bluescarni
Mar 04 2016 15:52
my general experience is that I'd personally use shared_ptr rather sparingly, possibly only in multithreaded scenarios
but maybe symengine has other needs I am not seeing
Ondřej Čertík
@certik
Mar 04 2016 15:53
I still want to investigate if we can switch to unique_ptr. It would require that we need to do lots of copies.
Francesco Biscani
@bluescarni
Mar 04 2016 15:53
even with move operations in the picture?
Ondřej Čertík
@certik
Mar 04 2016 15:53
Yes.
For example, symbols are allocated once, and then RCP just increments the ref.
with unique_ptr, we would need to make copies in things like expanding (x^y+1)^10
Francesco Biscani
@bluescarni
Mar 04 2016 15:54
so that's a way of implementing a cache, or a flyweight pattern of some sort?
Ondřej Čertík
@certik
Mar 04 2016 15:55
I am not sure.
Francesco Biscani
@bluescarni
Mar 04 2016 15:57
can you modify symbol objects with in-place operations?
or are they immutable?
Ondřej Čertík
@certik
Mar 04 2016 15:57
They are currently immutable.
Why?
Francesco Biscani
@bluescarni
Mar 04 2016 15:58
right ok... I was asking because in the example you gave above I was wondering what happens if I have a shallow copy of one symbol somewhere and you mutate it
Ondřej Čertík
@certik
Mar 04 2016 15:59
You can't mutate it.
Currently in all these expansions, you shuffle pointers around essentially.
Francesco Biscani
@bluescarni
Mar 04 2016 16:00
right, it would be quite a problem if you could mutate them
Ondřej Čertík
@certik
Mar 04 2016 16:00
The other option to be tried is to do copies and allocate using unique_ptr.
One way to emulate the possible speedup is to remove the reference counting from our RCP and never deallocate.
Francesco Biscani
@bluescarni
Mar 04 2016 16:01
if the issue of duplication of information is limited to the symbols, my first instinct would be to keep a global list of symbols and reference to it
Ondřej Čertík
@certik
Mar 04 2016 16:02
Yes, I already implemented it in #719, still needs some work though.
Francesco Biscani
@bluescarni
Mar 04 2016 16:02
it has other problems of course, but at least avoids shared pointer semantics
in piranha I am using something similar, but I am using string addresses for == and != but keeping alphabetical comparison for <
so equality is pretty fast, ordering a bit slower
Isuru Fernando
@isuruf
Mar 04 2016 16:04
There are other considerations. For example, b = x*a+a where a is a Add with lots of terms, then shared_ptrs avoid copying
Francesco Biscani
@bluescarni
Mar 04 2016 16:04
you could also compare pointers but my issue with that is that it introduces nondeterminism between runs
@isuruf right I see
I just think shared_ptr is going to be a problem when you start doing parallel stuff
Isuru Fernando
@isuruf
Mar 04 2016 16:08
parallel refcount increases?
Francesco Biscani
@bluescarni
Mar 04 2016 16:08
they are safe, but they will be a bottleneck if you have contention
because you have essentially a global variable shared between threads
Ondřej Čertík
@certik
Mar 04 2016 16:13
We can try to parallelize some of the matrix algorithms.
Isuru Fernando
@isuruf
Mar 04 2016 16:14
Yes, methods like jacobian can be parallelised
Isuru Fernando
@isuruf
Mar 04 2016 16:20
@certik, can you review #843 and #825?
Isuru Fernando
@isuruf
Mar 04 2016 16:40
This message was deleted
@bluescarni, do you generate lcov reports locally by using a cmake module?
Francesco Biscani
@bluescarni
Mar 04 2016 17:29
@isuruf no I just do it manually at the moment
@isuruf @certik regarding the shared ptr stuff, I am mainly trying to understand why it seems like for a general CAS it's a good idea whereas in many other scenarios they seem often a questionable choice. It might as well be that CAS require in practice shared ptr semantics intrinsically
another possibility that would avoid excessive copying would be copy-on-write
that way the objects would look distinct from on outside view but they would actually just reference each other until you write into them
@isuruf specifically I use the instructions here: http://ltp.sourceforge.net/coverage/lcov.php
Francesco Biscani
@bluescarni
Mar 04 2016 17:34
I am not a big fan of the cognitive load of having to distinguish between shallow and deep copies
Siddharth
@bollu
Mar 04 2016 18:44
I'm writing SymEngine bindings, so I need to know the exact size of the CRCPBasic_C structure
when is WITH_SYMENGINE_RCP defined exactly?
because my Haskell code would have to set the size of the data differently for the FFI when it is defined versus when it is not
@certik : I was hoping you'd know the details of the FFI
Siddharth
@bollu
Mar 04 2016 21:25
@certik: I implemented creating objects from the heap
@certik so you can now create 0, 1, etc
operations shouldn't be much harder
@certik I'd like details on the WITH_SYMENGINE_RCP though. And on what I should do next, since I can clearly get the FFI to work :)
Siddharth
@bollu
Mar 04 2016 21:38
@certik: One more question. For CI for my haskell code, which version of symengine do I build locally on the container? the stable version? or HEAD from symengine/symengine:master?
I think building from some kind of tagged "stable" build is the sanest way