Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VecOps] RVec 2.0: small buffer optimization based on LLVM SmallVector #7502

Merged
merged 51 commits into from Sep 29, 2021

Conversation

eguiraud
Copy link
Member

@eguiraud eguiraud commented Mar 15, 2021

@eguiraud eguiraud self-assigned this Mar 15, 2021
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-fedora30/cxx14, ROOT-fedora31/noimt, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@ghost
Copy link

ghost commented Mar 15, 2021

DeepCode's analysis on #77efbb found:

  • ⚠️ 2 warnings 👇

Top issues

Description Example fixes
The result of malloc, which may return null flows to the first argument of memcpy. This could result in undefined behavior. Consider adding a check for nullness. Occurrences: 🔧 Example fixes
Memory leak. Memory is never freed if realloc fails to allocate memory. Occurrences: 🔧 Example fixes

👉 View analysis in DeepCode’s Dashboard | Configure the bot

👉 The DeepCode service and API will be deprecated in August, 2021. Here is the information how to migrate. Thank you for using DeepCode 🙏 ❤️ !

If you are using our plugins, you might be interested in their successors: Snyk's JetBrains plugin and Snyk's VS Code plugin.

@phsft-bot
Copy link
Collaborator

Build failed on windows10/cxx14.
Running on null:C:\build\workspace\root-pullrequests-build
See console output.

Errors:

  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: 'ROOT::VecOps::RVec<TwoFloats>::RVec(const std::vector<TwoFloats,std::allocator<_Ty>> &)': cannot convert argument 1 from 'T *' to 'size_t' [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: with [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: [ [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: _Ty=TwoFloats [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: ] [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: and [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: [ [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: T=TwoFloats [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-15T10:25:21.709Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: ] [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-fedora30/cxx14, ROOT-fedora31/noimt, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Build failed on mac11.0/cxx17.
Running on macphsft20.dyndns.cern.ch:/Users/sftnight/build/workspace/root-pullrequests-build
See console output.

Errors:

  • [2021-03-18T13:23:54.184Z] FAILED: TBB-prefix/src/TBB-stamp/TBB-build lib/libtbb.dylib
  • [2021-03-18T13:23:54.184Z] CMake Error at /Users/sftnight/build/workspace/root-pullrequests-build/build/TBB-prefix/src/TBB-stamp/TBB-build-Release.cmake:49 (message):

@phsft-bot
Copy link
Collaborator

Build failed on ROOT-debian10-i386/cxx14.
Running on pcepsft10.dyndns.cern.ch:/build/workspace/root-pullrequests-build
See console output.

@phsft-bot
Copy link
Collaborator

Build failed on windows10/cxx14.
Running on null:C:\build\workspace\root-pullrequests-build
See console output.

Errors:

  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: 'ROOT::VecOps::RVec<TwoFloats>::RVec(const std::vector<TwoFloats,std::allocator<_Ty>> &)': cannot convert argument 1 from 'T *' to 'size_t' [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: with [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: [ [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: _Ty=TwoFloats [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: ] [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: and [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: [ [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: T=TwoFloats [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]
  • [2021-03-18T17:56:54.785Z] C:\build\workspace\root-pullrequests-build\root\tree\dataframe\inc\ROOT\RDF\RTreeColumnReader.hxx(100,1): error C2664: ] [C:\build\workspace\root-pullrequests-build\build\tree\dataframe\test\dataframe_splitcoll_arrayview.vcxproj]

@eguiraud
Copy link
Member Author

This is a reproducer for the Python failures:

import ROOT
rvec = ROOT.VecOps.RVec("float")()

Stacktrace at the point of crash is:

#0  0x00007ffff726c389 in __gnu_cxx::new_allocator<CPyCppyy::PyCallable*>::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (this=0x7ffff72c93df, __p=0x5f3a3a726f746365) at /usr/include/c++/10.2.0/ext/new_allocator.h:150
150		{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
>>> bt
#0  0x00007ffff726c389 in __gnu_cxx::new_allocator<CPyCppyy::PyCallable*>::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (this=0x7ffff72c93df, __p=0x5f3a3a726f746365) at /usr/include/c++/10.2.0/ext/new_allocator.h:150
#1  0x00007ffff726bf06 in std::allocator_traits<std::allocator<CPyCppyy::PyCallable*> >::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (__a=..., __p=0x5f3a3a726f746365) at /usr/include/c++/10.2.0/bits/alloc_traits.h:512
#2  0x00007ffff726bc7a in std::vector<CPyCppyy::PyCallable*, std::allocator<CPyCppyy::PyCallable*> >::push_back (this=0x7ffff72c93df, __x=@0x7fffffffd630: 0x555559389d80) at /usr/include/c++/10.2.0/bits/stl_vector.h:1192
#3  0x00007ffff72760a9 in CPyCppyy::CPPOverload::AdoptMethod (this=0x7ffff73136e0 <CPyCppyy::CPPOverload_Type>, pc=0x555559389d80) at ../../../../../rvec2/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx:945
#4  0x00007ffff72b3ba6 in CPyCppyy::TemplateProxy::AdoptMethod (this=0x7fffe9222280, pc=0x555559389d80) at ../../../../../rvec2/bindings/pyroot/cppyy/CPyCppyy/src/TemplateProxy.cxx:111
#5  0x00007ffff72a4233 in CPyCppyy::BuildScopeProxyDict (scope=16, pyclass=0x555559379ca0) at ../../../../../rvec2/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx:254
#6  0x00007ffff72a6273 in CPyCppyy::CreateScopeProxy (name="ROOT::VecOps::RVec<float>", parent=0x555558e398c0) at ../../../../../rvec2/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx:676
#7  0x00007ffff72830eb in (anonymous namespace)::MakeCppTemplateClass (args=0x7ffff73ef040) at ../../../../../rvec2/bindings/pyroot/cppyy/CPyCppyy/src/CPyCppyyModule.cxx:368
#8  0x00007ffff7d33a92 in ?? () from /usr/lib/libpython3.9.so.1.0
#9  0x00007ffff7d3298f in PyObject_Call () from /usr/lib/libpython3.9.so.1.0
#10 0x00007ffff7d163da in _PyEval_EvalFrameDefault () from /usr/lib/libpython3.9.so.1.0
#11 0x00007ffff7d0f9ad in ?? () from /usr/lib/libpython3.9.so.1.0
#12 0x00007ffff7d21b0e in _PyFunction_Vectorcall () from /usr/lib/libpython3.9.so.1.0
#13 0x00007ffff7d19735 in _PyObject_FastCallDictTstate () from /usr/lib/libpython3.9.so.1.0
#14 0x00007ffff7d2eaa9 in _PyObject_Call_Prepend () from /usr/lib/libpython3.9.so.1.0
#15 0x00007ffff7e0de7a in ?? () from /usr/lib/libpython3.9.so.1.0
#16 0x00007ffff7d19e6d in _PyObject_MakeTpCall () from /usr/lib/libpython3.9.so.1.0
#17 0x00007ffff7d15b3a in _PyEval_EvalFrameDefault () from /usr/lib/libpython3.9.so.1.0
#18 0x00007ffff7d0f9ad in ?? () from /usr/lib/libpython3.9.so.1.0
#19 0x00007ffff7d0f371 in _PyEval_EvalCodeWithName () from /usr/lib/libpython3.9.so.1.0
#20 0x00007ffff7dd1f83 in PyEval_EvalCode () from /usr/lib/libpython3.9.so.1.0
#21 0x00007ffff7de23dd in ?? () from /usr/lib/libpython3.9.so.1.0
#22 0x00007ffff7dddc7b in ?? () from /usr/lib/libpython3.9.so.1.0
#23 0x00007ffff7c7f20b in ?? () from /usr/lib/libpython3.9.so.1.0
#24 0x00007ffff7c7e5e3 in PyRun_SimpleFileExFlags () from /usr/lib/libpython3.9.so.1.0
#25 0x00007ffff7df3dba in Py_RunMain () from /usr/lib/libpython3.9.so.1.0
#26 0x00007ffff7dc4fa9 in Py_BytesMain () from /usr/lib/libpython3.9.so.1.0
#27 0x00007ffff7a41b25 in __libc_start_main () from /usr/lib/libc.so.6
#28 0x000055555555504e in _start ()

gdb shows some problems in CPyCppyy::CPPOverload::fMethodInfo:

#3  0x00007ffff72760a9 in CPyCppyy::CPPOverload::AdoptMethod (this=0x7ffff73136e0 <CPyCppyy::CPPOverload_Type>, pc=0x555559389d80) at ../../../../../rvec2/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx:945
945	    fMethodInfo->fMethods.push_back(pc);
>>> p *fMethodInfo

and valgrind agrees:

==216976== Invalid write of size 8
==216976==    at 0x5DC0389: void __gnu_cxx::new_allocator<CPyCppyy::PyCallable*>::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&>(CPyCppyy::PyCallable**, CPyCppyy::PyCallable* const&) (new_allocator.h:150)
==216976==    by 0x5DBFF05: void std::allocator_traits<std::allocator<CPyCppyy::PyCallable*> >::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&>(std::allocator<CPyCppyy::PyCallable*>&, CPyCppyy::PyCallable**, CPyCppyy::PyCallable* const&) (alloc_traits.h:512)
==216976==    by 0x5DBFC79: std::vector<CPyCppyy::PyCallable*, std::allocator<CPyCppyy::PyCallable*> >::push_back(CPyCppyy::PyCallable* const&) (stl_vector.h:1192)
==216976==    by 0x5DCA0A8: CPyCppyy::CPPOverload::AdoptMethod(CPyCppyy::PyCallable*) (CPPOverload.cxx:945)
==216976==    by 0x5E07BA5: CPyCppyy::TemplateProxy::AdoptMethod(CPyCppyy::PyCallable*) (TemplateProxy.cxx:111)
==216976==    by 0x5DF8232: CPyCppyy::BuildScopeProxyDict(unsigned long, _object*) (ProxyWrappers.cxx:254)
==216976==    by 0x5DFA272: CPyCppyy::CreateScopeProxy(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, _object*) (ProxyWrappers.cxx:676)
==216976==    by 0x5DD70EA: (anonymous namespace)::MakeCppTemplateClass(_object*, _object*) (CPyCppyyModule.cxx:368)
==216976==    by 0x49B1A91: ??? (in /usr/lib/libpython3.9.so.1.0)
==216976==    by 0x49B098E: PyObject_Call (in /usr/lib/libpython3.9.so.1.0)
==216976==    by 0x49943D9: _PyEval_EvalFrameDefault (in /usr/lib/libpython3.9.so.1.0)
==216976==    by 0x498D9AC: ??? (in /usr/lib/libpython3.9.so.1.0)
==216976==  Address 0x5f3a3a726f746365 is not stack'd, malloc'd or (recently) free'd

@stwunsch
Copy link
Contributor

I've built with clang10 and debug info and rebased on top of master. Then I get following additional info:

[wunsch@portal1 build_native]$ python -c 'import ROOT; rvec = ROOT.VecOps.RVec("float")()'
input_line_14:1:64: error: redefinition of 'is_equal'
namespace __cppyy_internal { template<class C1, class C2> bool is_equal(const C1& c1, const C2& c2) { return (bool)(c1 == c2); } }
                                                               ^
input_line_10:1:64: note: previous definition is here
namespace __cppyy_internal { template<class C1, class C2> bool is_equal(const C1& c1, const C2& c2) { return (bool)(c1 == c2); } }
                                                               ^
input_line_15:1:64: error: redefinition of 'is_not_equal'
namespace __cppyy_internal { template<class C1, class C2> bool is_not_equal(const C1& c1, const C2& c2) { return (bool)(c1 != c2); } }
                                                               ^
input_line_11:1:64: note: previous definition is here
namespace __cppyy_internal { template<class C1, class C2> bool is_not_equal(const C1& c1, const C2& c2) { return (bool)(c1 != c2); } }
                                                               ^
 *** Break *** segmentation violation



===========================================================
There was a crash (kSigSegmentationViolation).
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f0ac351e46c in waitpid () from /lib64/libc.so.6
#1  0x00007f0ac349bf62 in do_system () from /lib64/libc.so.6
#2  0x00007f0abbefaf19 in TUnixSystem::Exec (this=0x193ebd0, shellcmd=0x5886a50 "/work/wunsch/root_rvec/build_native/etc/gdb-backtrace.sh 3925717 1>&2") at /work/wunsch/root_rvec/core/unix/src/TUnixSystem.cxx:2120
#3  0x00007f0abbefba11 in TUnixSystem::StackTrace (this=0x193ebd0) at /work/wunsch/root_rvec/core/unix/src/TUnixSystem.cxx:2411
#4  0x00007f0aa6eb2e91 in (anonymous namespace)::TExceptionHandlerImp::HandleException(int) () from /cvmfs/sft-nightlies.cern.ch/lcg/nightlies/dev3/Mon/ROOT/HEAD/x86_64-centos7-clang10-opt/lib/libcppyy_backend3_8.so
#5  0x00007f0abbf01176 in TUnixSystem::DispatchSignals (this=0x193ebd0, sig=kSigSegmentationViolation) at /work/wunsch/root_rvec/core/unix/src/TUnixSystem.cxx:3644
#6  0x00007f0abbef5f81 in SigHandler (sig=kSigSegmentationViolation) at /work/wunsch/root_rvec/core/unix/src/TUnixSystem.cxx:407
#7  0x00007f0abbf01364 in sighandler (sig=11) at /work/wunsch/root_rvec/core/unix/src/TUnixSystem.cxx:3620
#8  <signal handler called>
#9  0x00007f0abc71ec1c in __gnu_cxx::new_allocator<CPyCppyy::PyCallable*>::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (this=0x7f0abc784120, __p=0x5f746f6f722f6863, __args=
0x7ffeaf819970: 0x58665b0) at /cvmfs/sft.cern.ch/lcg/releases/gcc/9.2.0-afc57/x86_64-centos7/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/ext/new_allocator.h:147
#10 0x00007f0abc71ea1d in std::allocator_traits<std::allocator<CPyCppyy::PyCallable*> >::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (__a=..., __p=0x5f746f6f722f6863, __args=
0x7ffeaf819970: 0x58665b0) at /cvmfs/sft.cern.ch/lcg/releases/gcc/9.2.0-afc57/x86_64-centos7/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/alloc_traits.h:484
#11 0x00007f0abc71e81e in std::vector<CPyCppyy::PyCallable*, std::allocator<CPyCppyy::PyCallable*> >::push_back (this=0x7f0abc784120, __x=
0x7ffeaf819970: 0x58665b0) at /cvmfs/sft.cern.ch/lcg/releases/gcc/9.2.0-afc57/x86_64-centos7/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_vector.h:1189
#12 0x00007f0abc72709f in CPyCppyy::CPPOverload::AdoptMethod (this=0x7f0abc9caed8 <CPyCppyy::CPPOverload_Type>, pc=0x58665b0) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx:945
#13 0x00007f0abc76e7f0 in CPyCppyy::TemplateProxy::AdoptMethod (this=0x7f0aaca317c0, pc=0x58665b0) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/TemplateProxy.cxx:111
#14 0x00007f0abc75ed8c in CPyCppyy::BuildScopeProxyDict (scope=14, pyclass=0x5859310) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx:254
#15 0x00007f0abc75d3de in CPyCppyy::CreateScopeProxy (name=..., parent=0x57021d0) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx:676
#16 0x00007f0abc7378d8 in (anonymous namespace)::MakeCppTemplateClass (args=0x7f0abca483c0) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/CPyCppyyModule.cxx:368
#17 0x00007f0ac440cd1a in cfunction_call_varargs (func=0x7f0abca8aef0, args=0x7f0abca483c0, kwargs=<optimized out>) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Objects/call.c:757
#18 0x00007f0ac440d834 in PyCFunction_Call (func=0x7ffeaf819970, args=0x5f746f6f722f6863, kwargs=0x7ffeaf819970) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Objects/call.c:772
#19 0x00007f0ac44d7b0c in do_call_core (tstate=0x1884330, func=0x7f0abca8aef0, callargs=0x7f0abca483c0, kwdict=0x0) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Python/ceval.c:4983

@eguiraud
Copy link
Member Author

eguiraud commented Mar 23, 2021

That looks like a different error rather than additional info Ah no, the stacktrace is the same! nice!

@stwunsch
Copy link
Contributor

With this patch, you can find out which method causes the issue:

--- a/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx
+++ b/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx
@@ -20,6 +20,7 @@
 #include <algorithm>
 #include <sstream>
 #include <vector>
+#include <iostream>


 namespace CPyCppyy {
@@ -941,6 +942,13 @@ void CPyCppyy::CPPOverload::Set(const std::string& name, std::vector<PyCallable*
 //----------------------------------------------------------------------------
 void CPyCppyy::CPPOverload::AdoptMethod(PyCallable* pc)
 {
+    PyObject_Print(pc->GetPrototype(), stdout, 0);
+    std::cout << std::endl;
+
+    PyObject_Print(pc->GetSignature(), stdout, 0);
+    std::cout << std::endl;
+
+    std::cout << std::endl;
 // Fill in the data of a freshly created method proxy.
     fMethodInfo->fMethods.push_back(pc);
     fMethodInfo->fFlags &= ~CallContext::kIsSorted;

It gets you to the point that you have multiple method with the same signature:

...

'float& ROOT::VecOps::RVec<float>::operator[](unsigned long idx)'
'(unsigned long idx)'

'float& ROOT::VecOps::RVec<float>::operator[](unsigned long idx)'
'(unsigned long idx)'

@eguiraud
Copy link
Member Author

I don't understand, the problem is not the "redefinition of is_equal" ?

@stwunsch
Copy link
Contributor

My best guess is that cppyy sees a method two times and then defines the equal operator in the jit twice. The iteration over the methods happens here (the counter is there to set a breakpoint more easily and continue until the actual critical part happens):

diff --git a/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx b/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx
index 23e7ac8..70b662c 100644
--- a/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx
+++ b/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx
@@ -26,6 +26,7 @@
 #include <set>
 #include <string>
 #include <vector>
+#include <iostream>


 //- data _______________________________________________________________________
@@ -141,6 +142,8 @@ static inline void sync_templates(
     Py_DECREF(pyname);
 }

+static auto counter = 0u;
+
 static int BuildScopeProxyDict(Cppyy::TCppScope_t scope, PyObject* pyclass)
 {
 // Collect methods and data for the given scope, and add them to the given python
@@ -169,6 +172,9 @@ static int BuildScopeProxyDict(Cppyy::TCppScope_t scope, PyObject* pyclass)

     // process the method based on its name
         std::string mtCppName = Cppyy::GetMethodName(method);
+        std::cout << "Counter: " << counter << std::endl;
+        counter++;
+        std::cout << "Method name: " << mtCppName << std::endl;

     // special case trackers
         bool setupSetItem = false;

@stwunsch
Copy link
Contributor

stwunsch commented Mar 23, 2021

More info: The is_equal is jitted on the fly in the method here:
https://github.com/root-project/root/blob/master/bindings/pyroot/cppyy/CPyCppyy/src/Utility.cxx#L301

And this is again called in various places in https://github.com/root-project/root/blob/master/bindings/pyroot/cppyy/CPyCppyy/src/CPPInstance.cxx

And a CPPInstance is one of the core classes :)

I tried to reproduce the doubled function with plain TClass and GetListOfMethods, but there everything seems to be fine.

return *this;
}

using SmallVectorTemplateCommon<T>::operator[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This using declaration may be the culprit? We have a rather complicated past in terms of using declarations and jitting ;)

@stwunsch
Copy link
Contributor

The is_equal issue may be a red herring :/

It's some weirdness which includes inheritance with also a templated method in the derived class.

Here is the most minimal reproducer I could find:

import cppyy

cppyy.cppdef('''
template <typename T>
struct Base {
    T data;
    T& operator[](int idx) { return data; }
};

template <typename T>
struct Vec : public Base<T> {
    T data;

    // we have two options to trigger the issue:

    // 1. Including this line makes it break
    //using Base<T>::operator[];

    // 2. Or including this line
    // Note that you have to derive Vec from Base to make it break!
    T& operator[](int idx) { return data; }

    // Note that you have to have the template here!
    template <typename V>
    T& operator[](T idx) {
        return data;
    }
};
''')

vec = cppyy.gbl.Vec['float']()
print(vec, vec[0])
vec[0] = 42.0
print(vec, vec[0])

And here the stacktrace, which is the same as above:

#9  0x00007f09d1f0bc1c in __gnu_cxx::new_allocator<CPyCppyy::PyCallable*>::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (this=0x7f09d1f71120, __p=0x5f746f6f722f6863, __args=
0x7ffd74585880: 0x5f009c0) at /cvmfs/sft.cern.ch/lcg/releases/gcc/9.2.0-afc57/x86_64-centos7/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/ext/new_allocator.h:147
#10 0x00007f09d1f0ba1d in std::allocator_traits<std::allocator<CPyCppyy::PyCallable*> >::construct<CPyCppyy::PyCallable*, CPyCppyy::PyCallable* const&> (__a=..., __p=0x5f746f6f722f6863, __args=
0x7ffd74585880: 0x5f009c0) at /cvmfs/sft.cern.ch/lcg/releases/gcc/9.2.0-afc57/x86_64-centos7/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/alloc_traits.h:484
#11 0x00007f09d1f0b81e in std::vector<CPyCppyy::PyCallable*, std::allocator<CPyCppyy::PyCallable*> >::push_back (this=0x7f09d1f71120, __x=
0x7ffd74585880: 0x5f009c0) at /cvmfs/sft.cern.ch/lcg/releases/gcc/9.2.0-afc57/x86_64-centos7/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/stl_vector.h:1189
#12 0x00007f09d1f1409f in CPyCppyy::CPPOverload::AdoptMethod (this=0x7f09d21b7ed8 <CPyCppyy::CPPOverload_Type>, pc=0x5f009c0) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx:945
#13 0x00007f09d1f5b7f0 in CPyCppyy::TemplateProxy::AdoptMethod (this=0x7f09c568c490, pc=0x5f009c0) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/TemplateProxy.cxx:111
#14 0x00007f09d1f4bd8c in CPyCppyy::BuildScopeProxyDict (scope=8, pyclass=0x5f31f60) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx:254
#15 0x00007f09d1f4a3de in CPyCppyy::CreateScopeProxy (name=..., parent=0x7f09d223a590) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx:676
#16 0x00007f09d1f248d8 in (anonymous namespace)::MakeCppTemplateClass (args=0x7f09d2237380) at /work/wunsch/root_rvec/bindings/pyroot/cppyy/CPyCppyy/src/CPyCppyyModule.cxx:368
#17 0x00007f09d9bf9d1a in cfunction_call_varargs (func=0x7f09d21fe360, args=0x7f09d2237380, kwargs=<optimized out>) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Objects/call.c:757
#18 0x00007f09d9bfa834 in PyCFunction_Call (func=0x7ffd74585880, args=0x5f746f6f722f6863, kwargs=0x7ffd74585880) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Objects/call.c:772
#19 0x00007f09d9cc4b0c in do_call_core (tstate=0x23ba020, func=0x7f09d21fe360, callargs=0x7f09d2237380, kwdict=0x0) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Python/ceval.c:4983
#20 _PyEval_EvalFrameDefault (f=0x7f09da1609f0, throwflag=<optimized out>) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Python/ceval.c:3559
#21 0x00007f09d9cc8863 in PyEval_EvalFrameEx (f=0x7f09da1609f0, throwflag=0) at /workspace/build/externals/Python-3.8.6/src/Python/3.8.6/Python/ceval.c:741

The previous implementation of the vectorized operator[] was using
emplace_back to add elements to the returned vector. emplace_back
is slightly more complex in RVec 2.0 due to the SBO and compilers
sometimes do not inline it. Instead, spell out the appropriate logic:
for example we know the return vector has sufficient capacity and
we can skip the related checks performed at every emplace_back call.
We define vectorized ones for RVecs that are used instead.
sizeof(void*) is 4, not 8 on 32bit machines.
As a simple standalone component, let's try to reduce its
dependencies to the minimum.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Build failed on ROOT-debian10-i386/cxx14.
Running on pcepsft10.dyndns.cern.ch:/build/workspace/root-pullrequests-build
See console output.

Errors:

  • [2021-09-29T09:13:14.929Z] /home/sftnight/build/workspace/root-pullrequests-build/root/math/vecops/src/RVec.cxx:20:36: error: static assertion failed: wasted space in RVec

@phsft-bot
Copy link
Collaborator

Build failed on windows10/cxx14.
Running on null:C:\build\workspace\root-pullrequests-build
See console output.

Errors:

  • [2021-09-29T09:42:28.418Z] C:\build\workspace\root-pullrequests-build\root\math\vecops\src\RVec.cxx(20,36): error C2338: wasted space in RVec [C:\build\workspace\root-pullrequests-build\build\math\vecops\ROOTVecOps.vcxproj]

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

Copy link
Member

@Axel-Naumann Axel-Naumann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful!

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-debian10-i386/cxx14, ROOT-performance-centos8-multicore/default, ROOT-ubuntu16/nortcxxmod, mac1014/python3, mac11.0/cxx17, windows10/cxx14
How to customize builds

@phsft-bot
Copy link
Collaborator

Build failed on mac11.0/cxx17.
Running on macphsft23.dyndns.cern.ch:/Users/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

@eguiraud eguiraud merged commit 07f313e into root-project:master Sep 29, 2021
@eguiraud eguiraud deleted the rvec_sbo branch September 29, 2021 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet