STL vector and numpy types in PyROOT

Thanks. I’ve added a bug report regarding this issue:

1 Like

Hi @LeWhoo,

This is something I have seen in the past, in principle there is support for proper, direct conversion of numpy arrays into std::vector only for flat arrays. Unfortunately, the reproducer you wrote does not work even in upstream cppyy:

$: conda activate cppyy-bare
$: conda list
# packages in environment at /home/vpadulan/programs/mambaforge/envs/cppyy-bare:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       2_gnu    conda-forge
binutils                  2.39                 hdd6e379_1    conda-forge
binutils_impl_linux-64    2.39                 he00db2b_1    conda-forge
binutils_linux-64         2.39                h5fc0e48_13    conda-forge
bzip2                     1.0.8                h7f98852_4    conda-forge
c-compiler                1.5.2                h0b41bf4_0    conda-forge
ca-certificates           2023.5.7             hbcca054_0    conda-forge
cppyy                     2.4.2           py310h2efb557_1    conda-forge
cppyy-backend             1.14.10         py310hdf3cbec_0    conda-forge
cppyy-cling               6.27.1          py310h07cc95c_0    conda-forge
cpycppyy                  1.12.12         py310hdf3cbec_0    conda-forge
cxx-compiler              1.5.2                hf52228f_0    conda-forge
gcc                       11.3.0              h02d0930_13    conda-forge
gcc_impl_linux-64         11.3.0              hab1b70f_19    conda-forge
gcc_linux-64              11.3.0              he6f903b_13    conda-forge
gxx                       11.3.0              h02d0930_13    conda-forge
gxx_impl_linux-64         11.3.0              hab1b70f_19    conda-forge
gxx_linux-64              11.3.0              hc203a17_13    conda-forge
kernel-headers_linux-64   2.6.32              he073ed8_15    conda-forge
ld_impl_linux-64          2.39                 hcc3a1bd_1    conda-forge
libffi                    3.4.2                h7f98852_5    conda-forge
libgcc-devel_linux-64     11.3.0              h210ce93_19    conda-forge
libgcc-ng                 12.2.0              h65d4601_19    conda-forge
libgomp                   12.2.0              h65d4601_19    conda-forge
libllvm9                  9.0.1           default_hc23dcda_7    conda-forge
libnsl                    2.0.0                h7f98852_0    conda-forge
libsanitizer              11.3.0              h239ccf8_19    conda-forge
libsqlite                 3.41.2               h2797004_1    conda-forge
libstdcxx-devel_linux-64  11.3.0              h210ce93_19    conda-forge
libstdcxx-ng              12.2.0              h46fd767_19    conda-forge
libuuid                   2.38.1               h0b41bf4_0    conda-forge
libzlib                   1.2.13               h166bdaf_4    conda-forge
ncurses                   6.3                  h27087fc_1    conda-forge
numpy                     1.24.3          py310ha4c1d20_0    conda-forge
openssl                   3.1.0                hd590300_3    conda-forge
pip                       23.1.2             pyhd8ed1ab_0    conda-forge
python                    3.10.10         he550d4f_0_cpython    conda-forge
python_abi                3.10                    3_cp310    conda-forge
readline                  8.2                  h8228510_1    conda-forge
setuptools                67.7.2             pyhd8ed1ab_0    conda-forge
sysroot_linux-64          2.12                he073ed8_15    conda-forge
tk                        8.6.12               h27826a3_0    conda-forge
tzdata                    2023c                h71feb2d_0    conda-forge
wheel                     0.40.0             pyhd8ed1ab_0    conda-forge
xz                        5.2.6                h166bdaf_0    conda-forge
# repro.py
import cppyy
import numpy as np
b = np.arange(2*2, dtype=np.uint32).reshape(2,2)
a = cppyy.gbl.std.vector["std::vector<unsigned int>"](b)
$: python repro.py
Traceback (most recent call last):
  File "/home/vpadulan/projects/rootcode/github-issues/github-12718/repro_cppyy.py", line 4, in <module>
    a = cppyy.gbl.std.vector["std::vector<unsigned int>"](b)
TypeError: Template method resolution failed:
  none of the 9 overloaded methods succeeded. Full details:
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(std::initializer_list<std::vector<std::vector<unsigned int> >::value_type> __l, const std::vector<std::vector<unsigned int> >::allocator_type& __a = std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::allocator_type()) =>
    TypeError: could not convert argument 1 (buffer itemsize (4) does not match expected size (24))
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(std::vector<std::vector<unsigned int> >&& __rv, const std::vector<std::vector<unsigned int> >::allocator_type& __m) =>
    TypeError: takes at least 2 arguments (1 given)
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(std::vector<std::vector<unsigned int> >&&) =>
    TypeError: could not convert argument 1
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(const std::vector<std::vector<unsigned int> >& __x, const std::vector<std::vector<unsigned int> >::allocator_type& __a) =>
    TypeError: takes at least 2 arguments (1 given)
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(const std::vector<std::vector<unsigned int> >::allocator_type& __a) =>
    TypeError: could not convert argument 1
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(const std::vector<std::vector<unsigned int> >& __x) =>
    TypeError: could not convert argument 1
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >() =>
    TypeError: takes at most 0 arguments (1 given)
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(std::vector<char>::size_type __n, const std::vector<std::vector<unsigned int> >::value_type& __value, const std::vector<std::vector<unsigned int> >::allocator_type& __a = std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::allocator_type()) =>
    TypeError: takes at least 2 arguments (1 given)
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >(std::vector<char>::size_type __n, const std::vector<std::vector<unsigned int> >::allocator_type& __a = std::vector<std::vector<unsigned int, std::allocator<unsigned int> >, std::allocator<std::vector<unsigned int, std::allocator<unsigned int> > > >::allocator_type()) =>
    TypeError: could not convert argument 1 (an integer is required)
  vector<std::vector<unsigned int> >::vector<std::vector<unsigned int> >() =>
    TypeError: takes at most 0 arguments (1 given)

I am especially suspicious of

    TypeError: could not convert argument 1 (buffer itemsize (4) does not match expected size (24))

I will try to address this but at this point there is no clear answer.

Cheers,
Vincenzo

Interesting, especially that @wlav above reported that it worked for him in cppyy. I hope it can be fixed. Meanwhile, in my class that basically makes std::vector pretend it is a list or a numpy array, I manually do something like:

        if (isinstance(value, list) and self.basic_vec_type.split()[-1] == "float") or isinstance(value, np.ndarray):
            if self.ndim == 1: value = array.array(cpp_to_array_typecodes[self.basic_vec_type], value)
            if self.ndim == 2: value = [array.array(cpp_to_array_typecodes[self.basic_vec_type], el) for el in value]
            if self.ndim == 3: value = [[array.array(cpp_to_array_typecodes[self.basic_vec_type], el1) for el1 in el] for el in value]

so manual looping with the use of the array.array. Ugly, but…

@LeWhoo … I did say that, and I mean that …

$ cat repro_cppyy.py
# repro.py
import cppyy
import numpy as np
b = np.arange(2*2, dtype=np.uint32).reshape(2,2)
a = cppyy.gbl.std.vector["std::vector<unsigned int>"](b)

print(b, a, sep='\n')   # <- added
$ python repro_cppyy.py
[[0 1]
 [2 3]]
{ { 0, 1 }, { 2, 3 } }

Runs fine on both Mac and Linux (I’m too lazy to check on Windows atm.).

1 Like

This topic was automatically closed after 10 days. New replies are no longer allowed.