I have a network consisting of at least one temporal node
"simple.xdsl"
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!-- This network was created in GeNIe Academic, which can be used for academic teaching and research purposes only -->
<smile version="1.0" id="Network3" numsamples="10000" discsamples="10000">
<nodes>
<cpt id="Node2" dynamic="plate">
<state id="State0" />
<state id="State1" />
<probabilities>0.9 0.1</probabilities>
</cpt>
</nodes>
<dynamic numslices="10">
</dynamic>
<extensions>
<genie version="1.0" app="GeNIe 4.0.2221.0 ACADEMIC" name="Network3">
<plate leftwidth="120" rightwidth="120">69 65 669 365</plate>
<node id="Node2">
<name>Node2</name>
<interior color="e5f6f7" />
<outline color="000080" />
<font color="000000" name="Arial" size="8" />
<position>314 256 362 286</position>
</node>
</genie>
</extensions>
</smile>
To demonstrate that both the wrapper class and the container are needed, the following example code has first one case where DSL_network is directly in a container, then the wrapper class is used without the container, before the wrapper is used with the container
Code: Select all
#include "smile/smile.h"
#include "smile/smile_license.h"
#include <vector>
#include <iostream>
void direct_in_a_vector(){
std::vector<DSL_network> nets;
nets.push_back(DSL_network());
nets[0].ReadFile("simple.xdsl");
nets[0].UpdateBeliefs();
}
class BayesianNetwork{
private:
DSL_network net;
public:
BayesianNetwork(){
net.ReadFile("simple.xdsl");
}
void update(){
net.UpdateBeliefs();
}
};
void in_a_class(){
BayesianNetwork net;
net.update();
}
void class_in_vector(){
std::vector<BayesianNetwork> nets;
nets.push_back(BayesianNetwork());
nets[0].update();
}
int main(){
DSL_errorH().RedirectToFile(stdout);
direct_in_a_vector();
std::cout << "3\n" << std::flush;
in_a_class();
std::cout << "2\n" << std::flush;
class_in_vector();
std::cout << "1\n" << std::flush;
}
Code: Select all
clang++ -std=c++17 -DNDEBUG -O3 test.cpp -o test -I./smile -L./smile -lsmile
Code: Select all
3
2
terminate called after throwing an instance of 'std::length_error'
what(): vector::_M_default_append
Aborted
Code: Select all
3
2
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Compiling it with g++ instead has similar behavior:
Code: Select all
g++ -std=c++17 -DNDEBUG -O3 test.cpp -o test -I./smile -L./smile -lsmile
Code: Select all
3
2
Killed
Code: Select all
3
2
Segmentation fault
The error does not happen if the node is not dynamic/temporal.
I experienced this bug when I made a new project that was based on an earlier one. The same configuration of having a wrapper class and using a container was in both. So I believe that this has worked in either an older version of the library or a different build.
The following build of the smile library is used:
SMILE ACADEMIC version 2.0.8 / 2022-07-29
I'm pretty sure I have the following version.
smile-academic-2.0.8-linux-x64-gcc-7.5
I'm running:
Ubuntu 18.05.6 LTS on wsl on windows 10
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)