GraphView::replace() segfault when the replaced node has multiple outputs
The following code crashes:
auto g1 = Sequential({
Producer({16, 3, 512, 512}, "dataProvider"),
Conv(3, 4, {5, 5}, "conv1"),
ReLU(),
PaddedConv(4, 8, {5, 5}, "conv2", {1, 1}, {2, 2, 2, 2}),
ReLU(),
PaddedConv(8, 16, {5, 5}, "conv3", {1, 1}, {2, 2, 2, 2}),
ReLU("relu3"),
PaddedConv(8, 16, {5, 5}, "conv4", {1, 1}, {2, 2, 2, 2}),
ReLU(),
Add(2, "add"),
PaddedConv(8, 16, {5, 5}, "conv5", {1, 1}, {2, 2, 2, 2}),
ReLU(),
Add(2, "add2")
});
g1->getNode("relu3")->addChild(g1->getNode("add"), 0, 1);
g1->getNode("conv5")->addChild(g1->getNode("add2"), 0, 1);
expandMetaOps(g1); // <--- crash hehre
Due to GraphView::replace()
segfault, this is the backtrace:
#0 0x000000000803de43 in __gnu_cxx::__exchange_and_add (__mem=0x9, __val=-1) at /usr/include/c++/9/ext/atomicity.h:49
#1 0x000000000803dea3 in __gnu_cxx::__exchange_and_add_dispatch (__mem=0x9, __val=-1)
at /usr/include/c++/9/ext/atomicity.h:82
#2 0x000000000804278b in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x1)
at /usr/include/c++/9/bits/shared_ptr_base.h:152
#3 0x0000000008072a26 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::operator= (this=0x8611f60, __r=...)
at /usr/include/c++/9/bits/shared_ptr_base.h:749
#4 0x00000000080923af in std::__shared_ptr<Aidge::Node, (__gnu_cxx::_Lock_policy)2>::operator= (this=0x8611f58)
at /usr/include/c++/9/bits/shared_ptr_base.h:1080
#5 0x00000000080923dd in std::shared_ptr<Aidge::Node>::operator= (this=0x8611f58)
at /usr/include/c++/9/bits/shared_ptr.h:103
#6 0x000000000821da6b in std::pair<std::shared_ptr<Aidge::Node>, unsigned short>::operator= (this=0x8611f58, __p=...)
at /usr/include/c++/9/bits/stl_pair.h:383
#7 0x0000000008213763 in Aidge::GraphView::replace (
oldGraph=std::shared_ptr<Aidge::GraphView> (use count 1, weak count 2) = {...},
newGraph=std::shared_ptr<Aidge::GraphView> (use count 1, weak count 3) = {...})
at /mnt/c/Users/ob222806/Desktop/aidge/aidge/aidge_core/src/graph/GraphView.cpp:931
#8 0x00000000083101c9 in Aidge::expandMetaOps (
graph=std::shared_ptr<Aidge::GraphView> (use count 2, weak count 27) = {...}, recursive=false)
at /mnt/c/Users/ob222806/Desktop/aidge/aidge/aidge_core/src/recipes/ExpandMetaOps.cpp:28
Faulty code:
// Children
for (std::size_t i = 0; i < oldOOut.size();) {
std::vector<std::pair<std::shared_ptr<Aidge::Node>, Aidge::IOIndex_t>> outputChild =
oldOOut[i].first -> output(oldOOut[i].second);
if (outputChild.empty()) {
outputChildren[i] = std::pair<std::shared_ptr<Node>, IOIndex_t>({nullptr, gk_IODefaultIndex});
++i;
}
else {
for (const auto& child : outputChild) {
if (oldNodes.find(child.first) == oldNodes.cend()) {
// BOUMBOUMBOUM
outputChildren[i] = child; /// <--- BOUM, i=1 but outputChildren size is 1!
// BOUMBOUMBOUM
++i;
}
}
}
}
Edited by Olivier BICHLER