Coder Social home page Coder Social logo

sequant's People

Contributors

ajay-mk avatar asadchev avatar bimalgaudel avatar cmasteran1 avatar evaleev avatar krzmbrzl avatar nakulteke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sequant's Issues

Forwarding should be double-checked

This is touching on the same topic as #99 but while browsing through the code some more, I found another instance that can potentially invoke undefined behavior:

EvalResultT<NodeT, Le> evaluate_core(NodeT const& n, Le&& lev, Cm&& cm) {
auto h = hash::value(*n);
if (auto ptr = std::forward<Cm>(cm).access(h); ptr) {
#ifdef SEQUANT_EVAL_TRACE
auto const max_c = std::forward<Cm>(cm).max_life(h);

if cm is an rvalue reference, then the first call to std::forward will move from it, leaving cm in an undefined state. Thus, the subsequent access to cm is likely to yield odd results.

In general, the way perfect forwarding is used here, doesn't make sense. Perfect forwarding (and thus taking parameters by universal/forwarding reference) only makes sense, if at some point you'll need a copy of that value or you call another function that takes a universal reference (and thus somewhere down the call chain, a copy will be needed) (or you want to make the function return the parameter as the same type as you took it in).
If you don't need to copy the provided parameter, it makes more sense to simply take it in as a (const) reference.

This should eliminate a couple of uses of universal references and thus the possibility to forward them. For the remaining parts, one has to ask oneself: is the code still valid, if I write std::move here (assuming I got an rvalue reference in) or does this lead to a use-after-move scenario? And only in those places, where moving wouldn't cause issues, can std::forward be safely used.
(Those cases where moving doesn't make sense should already been removed by the "check if we need a copy" rule)

Single-term optimization SegFaults for full contractions

The problem

If single_term_opt is tasked with optimizing a full contraction between three or more tensors, it can/will SegFault.

The concrete example for which I observe the single-term optimization producing a segmentation fault is
$t^{o_1 o_2}{v_1 v_2} f^{v_1}{v_3} \Gamma^{v_2 v_3}_{o_1 o_2}$.
This is part of a stationary energy functional ("Lagrangian") expression (thus the appearance of the unusual full contractions of three tensors).

The last iteration (for finding the optimal contraction order of the binary contraction with the remaining tensor) will find three equivalent possibilities (that are not considered as equivalent due to floating point numerics, but that doesn't matter here), but in each of these cases diffs will be empty as this is a full contraction:

auto scan_parts = [&curr_cost, //
&curr_parts, //
&curr_indices, //
& results = std::as_const(results), //
&idxsz]( //
size_t lpart, size_t rpart) {
auto [commons, //
diffs] = common_indices(results[lpart].indices, //
results[rpart].indices);
auto new_cost = ops_count(idxsz, //
commons, diffs) //
+ results[lpart].flops //
+ results[rpart].flops;
if (new_cost <= curr_cost) {
curr_cost = new_cost;
curr_parts = decltype(curr_parts){lpart, rpart};
curr_indices = std::move(diffs);
}
};

Thus, curr_indices will be empty, causing us to enter

if (curr_indices.empty()) {
// evaluation of a single atomic tensor
curr_result.flops = 0;
curr_result.indices = std::move(nth_tensor_indices[power_pos]);
curr_result.sequence = eval_seq_t{static_cast<int>(power_pos++)};
} else {

which - as the comment indicates - expects to only be entered for "non-contractions" (aka: just evaluating a single tensor on its own). In the described case however, power_pos = 3 as we have already entered this branch for the three individual tensors in our expression. This will then cause
curr_result.indices = std::move(nth_tensor_indices[power_pos]);

to access out-of-bounds as the size of nth_tensor_indices has only three entries.

Possible fix

I would suggest to use a boolean flag to indicate whether or not we are currently looking at a contraction (in which case scan_parts will be called) or an atomic tensor (in which case scan_parts will NOT be called) and then branch on that flag rather than on whether or not we have any external indices.

Based on a quick test, this fixes the issue.

If I haven't overlooked something and you approve of this fix, I will create a PR tomorrow.

Support for AO spaces

  • AO space should have same bitset as the corresponding orthogonal space ... so the difference between the two should be an attribute (AO-specific) bit?

Internal encoding and string type

From e.g.

std::wcout.imbue(std::locale("en_US.UTF-8"));
std::wcerr.imbue(std::locale("en_US.UTF-8"));

I tend to imply that SeQuant wants to use UTF-8. However, in the code you chose to use wide strings (std::wstring), which would instead indicate that you really want to use UTF-16 or UTF-32.

This opens up two questions for me:

  1. What encoding is SeQuant using internally? UTF-8 or UTF-16/UTF-32?
  2. If you're indeed using UTF-8: Why are you using wide strings to represent that? Normally, one would use regular strings for UTF-8 (which would also eliminate the need for having to prefix all string literals with L)

Error in Index transform documentation

The tag_transformed_index argument of the transform function of the Index class is outdated.
Indices with tags cannot be transformed with transform_indices(std::map replacement_map, bool tag_replaced) function of the Tensor class. The tags on indices have to be reset before the transformation.

New bug in open-shell CCSDTQ

Some terms have nan as constant in open-shell spin-traced CCSDTQ, which is a result of product terms added as expected.

& + {{{nan}}{g^{{a⁺_3}{a⁻_3}}_{{a⁺_1}{i⁻_3}}}{t^{{i⁺_1}{i⁻_1}}_{{a⁺_2}{a⁻_3}}}{t^{{i⁺_2}{i⁻_2}{i⁻_3}}_{{a⁺_3}{a⁻_1}{a⁻_2}}}} \\
& + {{{nan}}{g^{{a⁺_3}{a⁻_3}}_{{i⁺_3}{i⁻_3}}}{t^{{i⁺_2}{i⁺_1}{i⁻_1}}_{{a⁺_1}{a⁺_3}{a⁻_3}}}{t^{{i⁺_3}{i⁻_2}{i⁻_3}}_{{a⁺_2}{a⁻_1}{a⁻_2}}}} \\
& + {{{nan}}{g^{{a⁺_3}{a⁻_3}}_{{i⁺_3}{i⁻_3}}}{t^{{i⁺_3}}_{{a⁺_1}}}{t^{{i⁺_1}{i⁻_1}}_{{a⁺_2}{a⁻_3}}}{t^{{i⁺_2}{i⁻_2}{i⁻_3}}_{{a⁺_3}{a⁻_1}{a⁻_2}}}} \\

General tensor indices

Tensor objects (or more generally: anything fulfilling the AbstractTensor concept) are expected to divide their indices into bra and ket indices. There seems to be a connection (at least notation-wise) that bra indices correspond to creator indices and ket indices correspond to annihilator indices.

However, there are situations in which one would want to introduce a tensor object that has indices that are not connected to either a creator or annihilator operator (and would thus neither really fit into the bra or the ket group). Examples of where such tensors may enter are tensor decompositions like e.g. density fitting (resolution of the identity):
$g^{pq}_{rs} \approx B^p_r(Q) B^q_s(Q) - B^p_s(Q) B^q_r(Q)$
where B are the DF tensors and Q is an index in the auxiliary basis that is used for the DF approximation. This kind of decomposition is only performed on the actual (numeric) tensor object and therefore never appears in the second-quantized formalism and thus is not associated with a creator or annihilator.

While to my understanding the assignment of indices in tensor objects is only for notational purposes (when e.g. exporting to LaTeX), it'd be nice to conceptually keep the creator/annihilator association of tensor indices.

Therefore, I am proposing to extend the tensor concept to support general indices (neither creator nor annihilator).

[mbpt] refine F()

need to be able to control whether Fock operator is expressed in terms of composite (f) or natural (h, g, etc.) tensors ...

Default convention is incomplete (w.r.t. index space types)

As far as I can tell, the default QCiFS convention doesn't register all possible index space types.

All types are listed as

static Type nulltype;
static Type frozen_occupied;
static Type inactive_occupied;
static Type active_occupied;
static Type occupied;
static Type active_unoccupied;
static Type inactive_unoccupied;
static Type unoccupied;
static Type all_active;
static Type all;
static Type other_unoccupied;
static Type complete_unoccupied;
static Type complete;
static Type nonnulltype;

whereas the convention (seems to) only defines
IndexSpace::register_instance(declab(L"i"), IndexSpace::active_occupied,
qnattr, do_not_throw);
IndexSpace::register_instance(declab(L"m"), IndexSpace::occupied, qnattr,
do_not_throw);
IndexSpace::register_instance(declab(L"a"), IndexSpace::active_unoccupied,
qnattr, do_not_throw);
IndexSpace::register_instance(declab(L"e"), IndexSpace::unoccupied, qnattr,
do_not_throw);
IndexSpace::register_instance(declab(L"x"), IndexSpace::all_active, qnattr,
do_not_throw);
IndexSpace::register_instance(declab(L"p"), IndexSpace::all, qnattr,
do_not_throw);
IndexSpace::register_instance(declab(L"α'"), IndexSpace::other_unoccupied,
qnattr, do_not_throw);
IndexSpace::register_instance(declab(L"α"), IndexSpace::complete_unoccupied,
qnattr, do_not_throw);
IndexSpace::register_instance(declab(L"κ"), IndexSpace::complete, qnattr,
do_not_throw);

Ignoring the null/non-null space types, the following spaces are not covered by the default convention:

  • frozen_unoccupied
  • inactive_occupied
  • inactive_unoccupied

Maybe these spaces are not part of the QCiFS paper series and have therefore left out, but from a user's point of view, it would be very beneficial, if the default convention would indeed register all existing index space types instead of only a subset of them.

Catch2 needs to be updated

SeQuant still uses an older version of Catch2 that is no longer compatible with more recent glibc versions, because they have changed MINSIGSTKSZ to no longer be a constant expression in v2.35 (and older Catch2 versions use this variable as a constant expression).

The issue is fixed in Catch v2.13.5

As it stands, this causes sequant/unit/build to fail when running the test cases.

Ref.: catchorg/Catch2#2421

canonicalize() does not always place sequant::NormalOperators to the right of sequant::Tensors

While working with Tensors with labels outside the cardinal_tensor_labels list, Canonicalize does not know to put operators after tensors. After some investigation, it seems that TensorNetwork.canonicalize() is never thrown even when it should be (Products that contain anything besides sequant::Tensor). The easy current workaround is to simply add the tensor label to the list. However, it would make sense that sequant::NormalOperators should always be placed to the right of sequant::Tensors since the wick engine requires sequant::NormalOperators to be on the right end of a product.

simplify Expr (via simplify() or at construction)

transformations to perform

  • Constant * Constant = Constant
  • absorb constant in Constant * Product and Product * Constant
  • Product * Product = flattened Product
  • combine multiple instances of summand in Sum, e.g. a + b + a = 2*a + b
  • add up constants in Sum

Memory errors

It seems like SeQuant currently contains code that produces memory errors (reading/writing from/to invalid memory regions).

For instance, if I run valgrind on the srcc example/test, I get

$ valgrind ./srcc
==24997== Memcheck, a memory error detector
==24997== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==24997== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==24997== Command: ./srcc
==24997== 
==24997== Thread 6:
==24997== Invalid read of size 32
==24997==    at 0x4C6C559: __wmemcmp_avx2_movbe (memcmp-avx2-movbe.S:412)
==24997==    by 0x12BAD0: std::char_traits<wchar_t>::compare(wchar_t const*, wchar_t const*, unsigned long) (char_traits.h:513)
==24997==    by 0x12E708: std::basic_string_view<wchar_t, std::char_traits<wchar_t> >::compare(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) const (string_view:315)
==24997==    by 0x12EC93: bool std::operator< <wchar_t, std::char_traits<wchar_t> >(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >, std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) (string_view:591)
==24997==    by 0x193DBD: sequant::TensorNetwork::FullLabelCompare::operator()(sequant::TensorNetwork::Edge const&, std::basic_string_view<wchar_t, std::char_traits<wchar_t> > const&) const (tensor_network.hpp:191)
==24997==    by 0x1A3D21: boost::container::vec_iterator<sequant::TensorNetwork::Edge*, false> boost::container::dtl::flat_tree<sequant::TensorNetwork::Edge, boost::move_detail::identity<sequant::TensorNetwork::Edge>, sequant::TensorNetwork::FullLabelCompare, void>::priv_lower_bound<boost::container::vec_iterator<sequant::TensorNetwork::Edge*, false>, std::basic_string_view<wchar_t, std::char_traits<wchar_t> > >(boost::container::vec_iterator<sequant::TensorNetwork::Edge*, false>, boost::container::vec_iterator<sequant::TensorNetwork::Edge*, false>, std::basic_string_view<wchar_t, std::char_traits<wchar_t> > const&) const (flat_tree.hpp:1533)
==24997==    by 0x19899E: lower_bound<std::basic_string_view<wchar_t> > (flat_tree.hpp:1267)
==24997==    by 0x19899E: boost::container::dtl::enable_if_transparent<sequant::TensorNetwork::FullLabelCompare, std::basic_string_view<wchar_t, std::char_traits<wchar_t> >, boost::container::vec_iterator<sequant::TensorNetwork::Edge*, false> >::type boost::container::dtl::flat_tree<sequant::TensorNetwork::Edge, boost::move_detail::identity<sequant::TensorNetwork::Edge>, sequant::TensorNetwork::FullLabelCompare, void>::find<std::basic_string_view<wchar_t, std::char_traits<wchar_t> > >(std::basic_string_view<wchar_t, std::char_traits<wchar_t> > const&) (flat_tree.hpp:1173)
==24997==    by 0x186C04: sequant::TensorNetwork::init_edges() const::{lambda(sequant::Index const&, int, int)#1}::operator()(sequant::Index const&, int, int) const (tensor_network.cpp:648)
==24997==    by 0x18700E: sequant::TensorNetwork::init_edges() const (tensor_network.cpp:661)
==24997==    by 0x180EC7: sequant::TensorNetwork::canonicalize(std::vector<std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, bool, boost::container::flat_set<sequant::Index, sequant::Index::LabelCompare, void> const*) (tensor_network.cpp:79)
==24997==    by 0x13C7D6: sequant::Product::canonicalize_impl(bool) (expr.cpp:116)
==24997==    by 0x13D040: sequant::Product::canonicalize() (expr.cpp:209)
==24997==  Address 0x4e60c70 is 0 bytes inside a block of size 24 alloc'd
==24997==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==24997==    by 0x1A5019: void std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_construct<wchar_t*>(wchar_t*, wchar_t*, std::forward_iterator_tag) (basic_string.tcc:219)
==24997==    by 0x193908: sequant::Index::Index(sequant::Index const&) (index.hpp:41)
==24997==    by 0x243CEC: sequant::Op<(sequant::Statistics)1>::Op(sequant::Op<(sequant::Statistics)1> const&) (op.hpp:29)
==24997==    by 0x28F4A9: priv_construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:415)
==24997==    by 0x28F4A9: construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:360)
==24997==    by 0x28F4A9: boost::container::dtl::disable_if_memtransfer_copy_constructible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*, sequant::Op<(sequant::Statistics)1>*>::type boost::container::uninitialized_copy_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*) (copy_move_algo.hpp:480)
==24997==    by 0x281D33: void boost::container::copy_assign_range_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type) (copy_move_algo.hpp:1132)
==24997==    by 0x27546F: void boost::container::vector<sequant::Op<(sequant::Statistics)1>, boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, void>::assign<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >(boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::move_detail::disable_if_or<void, boost::move_detail::is_same<boost::move_detail::integral_constant<unsigned int, 1u>, boost::move_detail::integral_constant<unsigned int, 0u> >, boost::move_detail::is_convertible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, unsigned long>, boost::container::dtl::is_input_iterator<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::dtl::has_iterator_category<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >::value>, boost::move_detail::bool_<false> >::type*) (vector.hpp:1284)
==24997==    by 0x2534EA: small_vector (small_vector.hpp:640)
==24997==    by 0x2534EA: sequant::Operator<(sequant::Statistics)1>::Operator(sequant::Operator<(sequant::Statistics)1> const&) (op.hpp:290)
==24997==    by 0x253596: sequant::NormalOperator<(sequant::Statistics)1>::NormalOperator(sequant::NormalOperator<(sequant::Statistics)1> const&) (op.hpp:541)
==24997==    by 0x2E8636: void __gnu_cxx::new_allocator<sequant::NormalOperator<(sequant::Statistics)1> >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (new_allocator.h:162)
==24997==    by 0x2E7A8F: void std::allocator_traits<std::allocator<sequant::NormalOperator<(sequant::Statistics)1> > >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >&, sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (alloc_traits.h:516)
==24997==    by 0x2E6549: std::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1>, std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, sequant::NormalOperator<(sequant::Statistics)1> const&) (shared_ptr_base.h:519)
==24997== 
==24997== Invalid read of size 32
==24997==    at 0x4C6C55D: __wmemcmp_avx2_movbe (memcmp-avx2-movbe.S:413)
==24997==    by 0x12BAD0: std::char_traits<wchar_t>::compare(wchar_t const*, wchar_t const*, unsigned long) (char_traits.h:513)
==24997==    by 0x12E708: std::basic_string_view<wchar_t, std::char_traits<wchar_t> >::compare(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) const (string_view:315)
==24997==    by 0x12EC93: bool std::operator< <wchar_t, std::char_traits<wchar_t> >(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >, std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) (string_view:591)
==24997==    by 0x193E05: sequant::TensorNetwork::FullLabelCompare::operator()(std::basic_string_view<wchar_t, std::char_traits<wchar_t> > const&, sequant::TensorNetwork::Edge const&) const (tensor_network.hpp:194)
==24997==    by 0x198ABD: boost::container::dtl::enable_if_transparent<sequant::TensorNetwork::FullLabelCompare, std::basic_string_view<wchar_t, std::char_traits<wchar_t> >, boost::container::vec_iterator<sequant::TensorNetwork::Edge*, false> >::type boost::container::dtl::flat_tree<sequant::TensorNetwork::Edge, boost::move_detail::identity<sequant::TensorNetwork::Edge>, sequant::TensorNetwork::FullLabelCompare, void>::find<std::basic_string_view<wchar_t, std::char_traits<wchar_t> > >(std::basic_string_view<wchar_t, std::char_traits<wchar_t> > const&) (flat_tree.hpp:1175)
==24997==    by 0x186C04: sequant::TensorNetwork::init_edges() const::{lambda(sequant::Index const&, int, int)#1}::operator()(sequant::Index const&, int, int) const (tensor_network.cpp:648)
==24997==    by 0x18700E: sequant::TensorNetwork::init_edges() const (tensor_network.cpp:661)
==24997==    by 0x180EC7: sequant::TensorNetwork::canonicalize(std::vector<std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >, std::allocator<std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > > > const&, bool, boost::container::flat_set<sequant::Index, sequant::Index::LabelCompare, void> const*) (tensor_network.cpp:79)
==24997==    by 0x13C7D6: sequant::Product::canonicalize_impl(bool) (expr.cpp:116)
==24997==    by 0x13D040: sequant::Product::canonicalize() (expr.cpp:209)
==24997==    by 0x1C4CF4: sequant::canonicalize(sequant::ExprPtr&) (expr_algorithm.hpp:15)
==24997==  Address 0x4e60c70 is 0 bytes inside a block of size 24 alloc'd
==24997==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==24997==    by 0x1A5019: void std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_construct<wchar_t*>(wchar_t*, wchar_t*, std::forward_iterator_tag) (basic_string.tcc:219)
==24997==    by 0x193908: sequant::Index::Index(sequant::Index const&) (index.hpp:41)
==24997==    by 0x243CEC: sequant::Op<(sequant::Statistics)1>::Op(sequant::Op<(sequant::Statistics)1> const&) (op.hpp:29)
==24997==    by 0x28F4A9: priv_construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:415)
==24997==    by 0x28F4A9: construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:360)
==24997==    by 0x28F4A9: boost::container::dtl::disable_if_memtransfer_copy_constructible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*, sequant::Op<(sequant::Statistics)1>*>::type boost::container::uninitialized_copy_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*) (copy_move_algo.hpp:480)
==24997==    by 0x281D33: void boost::container::copy_assign_range_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type) (copy_move_algo.hpp:1132)
==24997==    by 0x27546F: void boost::container::vector<sequant::Op<(sequant::Statistics)1>, boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, void>::assign<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >(boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::move_detail::disable_if_or<void, boost::move_detail::is_same<boost::move_detail::integral_constant<unsigned int, 1u>, boost::move_detail::integral_constant<unsigned int, 0u> >, boost::move_detail::is_convertible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, unsigned long>, boost::container::dtl::is_input_iterator<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::dtl::has_iterator_category<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >::value>, boost::move_detail::bool_<false> >::type*) (vector.hpp:1284)
==24997==    by 0x2534EA: small_vector (small_vector.hpp:640)
==24997==    by 0x2534EA: sequant::Operator<(sequant::Statistics)1>::Operator(sequant::Operator<(sequant::Statistics)1> const&) (op.hpp:290)
==24997==    by 0x253596: sequant::NormalOperator<(sequant::Statistics)1>::NormalOperator(sequant::NormalOperator<(sequant::Statistics)1> const&) (op.hpp:541)
==24997==    by 0x2E8636: void __gnu_cxx::new_allocator<sequant::NormalOperator<(sequant::Statistics)1> >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (new_allocator.h:162)
==24997==    by 0x2E7A8F: void std::allocator_traits<std::allocator<sequant::NormalOperator<(sequant::Statistics)1> > >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >&, sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (alloc_traits.h:516)
==24997==    by 0x2E6549: std::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1>, std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, sequant::NormalOperator<(sequant::Statistics)1> const&) (shared_ptr_base.h:519)
==24997== 
==24997== Invalid read of size 32
==24997==    at 0x4C6C559: __wmemcmp_avx2_movbe (memcmp-avx2-movbe.S:412)
==24997==    by 0x12BAD0: std::char_traits<wchar_t>::compare(wchar_t const*, wchar_t const*, unsigned long) (char_traits.h:513)
==24997==    by 0x12E708: std::basic_string_view<wchar_t, std::char_traits<wchar_t> >::compare(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) const (string_view:315)
==24997==    by 0x12ED69: bool std::operator==<wchar_t, std::char_traits<wchar_t> >(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >, std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) (string_view:537)
==24997==    by 0x12CFAF: sequant::operator<(sequant::Index const&, sequant::Index const&)::{lambda()#1}::operator()() const (index.hpp:558)
==24997==    by 0x12D27C: sequant::operator<(sequant::Index const&, sequant::Index const&) (index.hpp:574)
==24997==    by 0x132CE6: std::less<sequant::Index>::operator()(sequant::Index const&, sequant::Index const&) const (stl_function.h:400)
==24997==    by 0x1B06A3: boost::container::vec_iterator<boost::container::dtl::pair<sequant::Index, sequant::Index>*, true> boost::container::dtl::flat_tree<boost::container::dtl::pair<sequant::Index, sequant::Index>, boost::container::dtl::select1st<sequant::Index>, std::less<sequant::Index>, boost::container::new_allocator<boost::container::dtl::pair<sequant::Index, sequant::Index> > >::priv_lower_bound<boost::container::vec_iterator<boost::container::dtl::pair<sequant::Index, sequant::Index>*, true>, sequant::Index>(boost::container::vec_iterator<boost::container::dtl::pair<sequant::Index, sequant::Index>*, true>, boost::container::vec_iterator<boost::container::dtl::pair<sequant::Index, sequant::Index>*, true>, sequant::Index const&) const (flat_tree.hpp:1533)
==24997==    by 0x21E9B9: lower_bound (flat_tree.hpp:1261)
==24997==    by 0x21E9B9: boost::container::dtl::flat_tree<boost::container::dtl::pair<sequant::Index, sequant::Index>, boost::container::dtl::select1st<sequant::Index>, std::less<sequant::Index>, boost::container::new_allocator<boost::container::dtl::pair<sequant::Index, sequant::Index> > >::find(sequant::Index const&) const (flat_tree.hpp:1160)
==24997==    by 0x21CC3D: find (flat_map.hpp:1318)
==24997==    by 0x21CC3D: bool sequant::Index::transform<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&) (index.hpp:409)
==24997==    by 0x2DCF00: auto sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}::operator()<sequant::Op<(sequant::Statistics)1>&>(sequant::Op<(sequant::Statistics)1>&) const (op.hpp:687)
==24997==    by 0x2E73B0: decltype (((sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&){parm#1})((sequant::Op<(sequant::Statistics)1>&){parm#2})) ranges::invoke_fn::operator()<sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&, sequant::Op<(sequant::Statistics)1>&>(sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&, sequant::Op<(sequant::Statistics)1>&) const (invoke.hpp:141)
==24997==  Address 0x4e60c10 is 0 bytes inside a block of size 24 alloc'd
==24997==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==24997==    by 0x1A5019: void std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_construct<wchar_t*>(wchar_t*, wchar_t*, std::forward_iterator_tag) (basic_string.tcc:219)
==24997==    by 0x193908: sequant::Index::Index(sequant::Index const&) (index.hpp:41)
==24997==    by 0x243CEC: sequant::Op<(sequant::Statistics)1>::Op(sequant::Op<(sequant::Statistics)1> const&) (op.hpp:29)
==24997==    by 0x28F4A9: priv_construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:415)
==24997==    by 0x28F4A9: construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:360)
==24997==    by 0x28F4A9: boost::container::dtl::disable_if_memtransfer_copy_constructible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*, sequant::Op<(sequant::Statistics)1>*>::type boost::container::uninitialized_copy_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*) (copy_move_algo.hpp:480)
==24997==    by 0x281D33: void boost::container::copy_assign_range_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type) (copy_move_algo.hpp:1132)
==24997==    by 0x27546F: void boost::container::vector<sequant::Op<(sequant::Statistics)1>, boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, void>::assign<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >(boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::move_detail::disable_if_or<void, boost::move_detail::is_same<boost::move_detail::integral_constant<unsigned int, 1u>, boost::move_detail::integral_constant<unsigned int, 0u> >, boost::move_detail::is_convertible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, unsigned long>, boost::container::dtl::is_input_iterator<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::dtl::has_iterator_category<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >::value>, boost::move_detail::bool_<false> >::type*) (vector.hpp:1284)
==24997==    by 0x2534EA: small_vector (small_vector.hpp:640)
==24997==    by 0x2534EA: sequant::Operator<(sequant::Statistics)1>::Operator(sequant::Operator<(sequant::Statistics)1> const&) (op.hpp:290)
==24997==    by 0x253596: sequant::NormalOperator<(sequant::Statistics)1>::NormalOperator(sequant::NormalOperator<(sequant::Statistics)1> const&) (op.hpp:541)
==24997==    by 0x2E8636: void __gnu_cxx::new_allocator<sequant::NormalOperator<(sequant::Statistics)1> >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (new_allocator.h:162)
==24997==    by 0x2E7A8F: void std::allocator_traits<std::allocator<sequant::NormalOperator<(sequant::Statistics)1> > >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >&, sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (alloc_traits.h:516)
==24997==    by 0x2E6549: std::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1>, std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, sequant::NormalOperator<(sequant::Statistics)1> const&) (shared_ptr_base.h:519)
==24997== 
==24997== Invalid read of size 32
==24997==    at 0x4C6C55D: __wmemcmp_avx2_movbe (memcmp-avx2-movbe.S:413)
==24997==    by 0x12BAD0: std::char_traits<wchar_t>::compare(wchar_t const*, wchar_t const*, unsigned long) (char_traits.h:513)
==24997==    by 0x12E708: std::basic_string_view<wchar_t, std::char_traits<wchar_t> >::compare(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) const (string_view:315)
==24997==    by 0x12ED69: bool std::operator==<wchar_t, std::char_traits<wchar_t> >(std::basic_string_view<wchar_t, std::char_traits<wchar_t> >, std::basic_string_view<wchar_t, std::char_traits<wchar_t> >) (string_view:537)
==24997==    by 0x12CFAF: sequant::operator<(sequant::Index const&, sequant::Index const&)::{lambda()#1}::operator()() const (index.hpp:558)
==24997==    by 0x12D27C: sequant::operator<(sequant::Index const&, sequant::Index const&) (index.hpp:574)
==24997==    by 0x132CE6: std::less<sequant::Index>::operator()(sequant::Index const&, sequant::Index const&) const (stl_function.h:400)
==24997==    by 0x21EAC7: boost::container::dtl::flat_tree<boost::container::dtl::pair<sequant::Index, sequant::Index>, boost::container::dtl::select1st<sequant::Index>, std::less<sequant::Index>, boost::container::new_allocator<boost::container::dtl::pair<sequant::Index, sequant::Index> > >::find(sequant::Index const&) const (flat_tree.hpp:1163)
==24997==    by 0x21CC3D: find (flat_map.hpp:1318)
==24997==    by 0x21CC3D: bool sequant::Index::transform<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&) (index.hpp:409)
==24997==    by 0x2DCF00: auto sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}::operator()<sequant::Op<(sequant::Statistics)1>&>(sequant::Op<(sequant::Statistics)1>&) const (op.hpp:687)
==24997==    by 0x2E73B0: decltype (((sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&){parm#1})((sequant::Op<(sequant::Statistics)1>&){parm#2})) ranges::invoke_fn::operator()<sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&, sequant::Op<(sequant::Statistics)1>&>(sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&, sequant::Op<(sequant::Statistics)1>&) const (invoke.hpp:141)
==24997==    by 0x2E5B2A: decltype (ranges::invoke(static_cast<sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}&>(*((*this).t_)), static_cast<sequant::Op<(sequant::Statistics)1>&>({parm#1}))) ranges::reference_wrapper<sequant::NormalOperator<(sequant::Statistics)1>::transform_indices<boost::container::flat_map, std::less<sequant::Index>, void>(boost::container::flat_map<sequant::Index, sequant::Index, std::less<sequant::Index>, void> const&)::{lambda(auto:1&&)#1}>::operator()<sequant::Op<(sequant::Statistics)1>&>(sequant::Op<(sequant::Statistics)1>&) const (reference_wrapper.hpp:111)
==24997==  Address 0x4e60c10 is 0 bytes inside a block of size 24 alloc'd
==24997==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==24997==    by 0x1A5019: void std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_construct<wchar_t*>(wchar_t*, wchar_t*, std::forward_iterator_tag) (basic_string.tcc:219)
==24997==    by 0x193908: sequant::Index::Index(sequant::Index const&) (index.hpp:41)
==24997==    by 0x243CEC: sequant::Op<(sequant::Statistics)1>::Op(sequant::Op<(sequant::Statistics)1> const&) (op.hpp:29)
==24997==    by 0x28F4A9: priv_construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:415)
==24997==    by 0x28F4A9: construct<sequant::Op<(sequant::Statistics)1>, const sequant::Op<(sequant::Statistics)1>&> (allocator_traits.hpp:360)
==24997==    by 0x28F4A9: boost::container::dtl::disable_if_memtransfer_copy_constructible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*, sequant::Op<(sequant::Statistics)1>*>::type boost::container::uninitialized_copy_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*) (copy_move_algo.hpp:480)
==24997==    by 0x281D33: void boost::container::copy_assign_range_alloc_n<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, sequant::Op<(sequant::Statistics)1>*>(boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>&, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type, sequant::Op<(sequant::Statistics)1>*, boost::container::allocator_traits<boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void> >::size_type) (copy_move_algo.hpp:1132)
==24997==    by 0x27546F: void boost::container::vector<sequant::Op<(sequant::Statistics)1>, boost::container::small_vector_allocator<sequant::Op<(sequant::Statistics)1>, boost::container::new_allocator<void>, void>, void>::assign<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >(boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::move_detail::disable_if_or<void, boost::move_detail::is_same<boost::move_detail::integral_constant<unsigned int, 1u>, boost::move_detail::integral_constant<unsigned int, 0u> >, boost::move_detail::is_convertible<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, unsigned long>, boost::container::dtl::is_input_iterator<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true>, boost::container::dtl::has_iterator_category<boost::container::vec_iterator<sequant::Op<(sequant::Statistics)1>*, true> >::value>, boost::move_detail::bool_<false> >::type*) (vector.hpp:1284)
==24997==    by 0x2534EA: small_vector (small_vector.hpp:640)
==24997==    by 0x2534EA: sequant::Operator<(sequant::Statistics)1>::Operator(sequant::Operator<(sequant::Statistics)1> const&) (op.hpp:290)
==24997==    by 0x253596: sequant::NormalOperator<(sequant::Statistics)1>::NormalOperator(sequant::NormalOperator<(sequant::Statistics)1> const&) (op.hpp:541)
==24997==    by 0x2E8636: void __gnu_cxx::new_allocator<sequant::NormalOperator<(sequant::Statistics)1> >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (new_allocator.h:162)
==24997==    by 0x2E7A8F: void std::allocator_traits<std::allocator<sequant::NormalOperator<(sequant::Statistics)1> > >::construct<sequant::NormalOperator<(sequant::Statistics)1>, sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >&, sequant::NormalOperator<(sequant::Statistics)1>*, sequant::NormalOperator<(sequant::Statistics)1> const&) (alloc_traits.h:516)
==24997==    by 0x2E6549: std::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1>, std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<sequant::NormalOperator<(sequant::Statistics)1> const&>(std::allocator<sequant::NormalOperator<(sequant::Statistics)1> >, sequant::NormalOperator<(sequant::Statistics)1> const&) (shared_ptr_base.h:519)
==24997== 
CC equations [type=t,rank=1,screen=true,use_topology=true,use_connectivity=true,canonical_only=true] computed in 5.8424059570000004 seconds
R1(expS1) has 8 terms:
CC equations [type=t,rank=2,screen=true,use_topology=true,use_connectivity=true,canonical_only=true] computed in 26.162401677999998 seconds
R1(expS2) has 14 terms:
R2(expS2) has 31 terms:
CC equations [type=t,rank=3,screen=true,use_topology=true,use_connectivity=true,canonical_only=true] computed in 71.338869618999993 seconds
R1(expS3) has 15 terms:
R2(expS3) has 37 terms:
R3(expS3) has 47 terms:
==24997== 
==24997== HEAP SUMMARY:
==24997==     in use at exit: 147,570 bytes in 240 blocks
==24997==   total heap usage: 526,207 allocs, 525,967 frees, 103,217,120 bytes allocated
==24997== 
==24997== LEAK SUMMARY:
==24997==    definitely lost: 0 bytes in 0 blocks
==24997==    indirectly lost: 0 bytes in 0 blocks
==24997==      possibly lost: 0 bytes in 0 blocks
==24997==    still reachable: 147,570 bytes in 240 blocks
==24997==         suppressed: 0 bytes in 0 blocks
==24997== Rerun with --leak-check=full to see details of leaked memory
==24997== 
==24997== For lists of detected and suppressed errors, rerun with: -s
==24997== ERROR SUMMARY: 202903 errors from 4 contexts (suppressed: 0 from 0)

Note in particular the Invalid read of size 32 entry/entries. That probably corresponds to accessing an out-of-bound index into a vector or an array.

Undefined behavior in `sequant::optimize`

auto smands = *expr | transform([&idx2size](auto&& s) {
return optimize(s, std::forward<IdxToSize>(idx2size));
}) | ranges::to_vector;

In the above piece of code, idx2size is a forwarding (aka: universal) reference and therefore std::forward may perform a move operation, if idx2size was passed to the surrounding function as a rvalue reference (aka: a temporary object).
However, this will mean that the first call to optimize will move out of idx2size and then all subsequent iterations in this range-processing will use the moved-from object. However, use-after-move is undefined (or rather: the state of the moved-from state is undefined) and thus this may introduce more or less arbitrary things to occur.

Really, idx2size should be passed along as a regular reference (const reference would probably be even better) in order to avoid the use-after-move issue.

A couple of questions

I would ask y'all a couple of questions that I - so far - have not yet found answers to. Thus, I am hoping that someone of you can help me out here:

  • What are proto indices and what/where are they used?
  • What is the meaning of the MultiProductVacuum?
  • It seems that one has to specify all tensors that are used as a list of "cardinal" tensors, which determines the order of the tensors in the canonical form. Is there something more to the meaning of cardinal tensors and the order in which they are defined? And if the order in the canonical form is all that these are used for, why aren't tensors not explicitly listed in that list simply sorted based on e.g. alphabetic order?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.