Test and Document STL Checkpointing (#1355)

* Updates SIM_stl to include checkpoint writing and checkpoint restore, as well as adding more data structures to test
* Thoroughly tests supported STL types with MM_stl_checkpoint and MM_stl_restore
* Adds an option to enable or disable STL restore in accessible interfaces and changes default to true
* Updates documentation on STL checkpointing to clearly state limitations and known bugs
This commit is contained in:
Jacqueline Deans 2022-10-07 08:37:09 -05:00 committed by GitHub
parent 540bc7d96f
commit f19ba7df78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 3245 additions and 100 deletions

View File

@ -23,6 +23,14 @@ trick.checkpoint_cpu(<cpu_num>)
trick.checkpoint_safestore_set_enabled(True|False)
# Set the safestore checkpoint period. default 9x10e18
trick.checkpoint_safestore(<period>)
# Load a checkpoint
trick.load_checkpoint(<filename>)
# Load a checkpoint without restoring STLs
trick.load_checkpoint(<filename>, False)
# Force the load_checkpoint job to run immediately
trick.load_checkpoint_job()
```
[Continue to Memory Manager](memory_manager/MemoryManager)

View File

@ -1,9 +0,0 @@
| [Home](/trick) → [Documentation Home](../Documentation-Home) → [Simulation Capabilities](Simulation-Capabilities) → STL Checkpointing |
|------------------------------------------------------------------|
Trick does not currently support checkpointing C++ Standard Template Library (STL) types, although we working on it.
For those data-structures you intend to checkpoint, you should avoid using STLs.
[Continue to Threads](Threads)

View File

@ -0,0 +1,130 @@
| [Home](/trick) → [Documentation Home](../Documentation-Home) → [Simulation Capabilities](Simulation-Capabilities) → Using STLs in Trick Sims |
|------------------------------------------------------------------|
# Standard Template Libraries (STL) in Trick
STLs may be used in models. However, STL variables (currently) are not data recordable, visible in the variable server, nor directly accessible in the input file. Some STLs can be checkpointed: array, vector, list, deque, set, multiset, map, multimap, stack, queue, priority_queue, pair.
STL classes cannot be directly registered with the memory manager, but they can be processed by the checkpoint agent when nested inside normal C++ classes (including sim objects).
STL checkpoint restore may slow down the default data jobs of some sims. STL restore is on by default. To turn off STL restore:
If using memory manager through the C interface:
```
int TMM_set_stl_restore (int on_off);
```
If using the memory manager through the C++ interface, set the default or pass a parameter to your read_checkpoint function of choice:
```
int set_restore_stls_default (bool on);
int read_checkpoint( std::istream* in_s, bool do_restore_stls = restore_stls_default);
int read_checkpoint_from_string( const char* s, bool do_restore_stls = restore_stls_default );
int init_from_checkpoint( std::istream* in_s, bool do_restore_stls = restore_stls_default);
```
If using the checkpoint restart C interface:
```
int load_checkpoint_stls( const char * file_name, int with_stls ) ;
```
## What works:
To checkpoint an STL, it **must** be a member of a class or struct.
```
class AnyClass {
std::vector<int> vec;
}
```
Declare an instance of this class with the memory manager in the usual way:
```
AnyClass * my_class = tmm->declare_var("AnyClass my_alloc");
```
If it is in a class that is nested in a `sim_object`, it will be registered with the memory manager automatically.
You can nest an arbitrary amount of STLs, they will all be checkpointed as long as
the base is a member of a class that is registered with the memory manager. There
are a some [**limitations**](#limitations) and exceptions due to [**bugs**](#known_bugs) at the moment (but hopefully not forever!)
```
class AnyClass {
std::pair<std::vector<std::map.......>>
}
```
<a id=limitations></a>
## Limitations
The STL checkpointing feature can only handle simple types, pointers, and nested STL types.
### An STL type within a user defined type within an STL will fail to checkpoint.
For example: a user defined class with an STL in it:
```
class VectorWrapper {
int a;
std::vector<int> vec;
}
```
An outer class (which is registered with the memory manager, like a member of a sim_object or something that has been explicitly declared) that has an STL container of these objects:
```
class MyObject {
std::vector<VectorWrapper> vec_user_defined;
}
```
If MyObject is populated, it will be able to checkpoint and restore without throwing an error, and all the `VectorWrapper` objects will be present, but `vec` will not be restored (`a` will restore successfully). The contents of `vec` are never written out to the checkpoint file.
If `MyObject` instead has a vector of pointers to `VectorWrapper`, and each `VectorWrapper` is registered with the memory manager, `vec` will checkpoint and restore successfully.
```
class MyObject {
std::vector<VectorWrapper *> vec_user_defined_ptr;
}
```
### You cannot directly create or register an external stl with the memory manager, you will get a parser error.
STLs can't register it with the memory manager, so there's no way for the checkpoint to know where the memory is.
```
class AnyClass {
std::vector<int> *anything;
}
class AnyClass {
std::pair<int,int>[5];
}
memorymanager->declare_var("std::vector<int> my_vector_allocation");
std::vector<int> my_vector;
memorymanager->declare_var_extern(&my_vector, "std::vector<int> my_vector_allocation");
```
<a id=known-bugs></a>
## Known bugs
The types in an std::pair cannot be sequence STL types (vector, queue, stack, etc).
```
// This will fail to checkpoint
std::pair<int, std::vector<int>>
```
The types inside an std::set cannot be any STL types (excluding strings).
```
// This will fail to compile
std::set<std::vector<int>>
```
These bugs are being worked on.
[Continue to Threads](Threads)

View File

@ -247,6 +247,19 @@ namespace Trick {
*/
virtual void load_checkpoint(std::string file_name) ;
/**
@brief @userdesc Command to load a checkpoint file. (Calls the preload_checkpoint jobs, calls the MemoryManager restore_managed_memory
method, then calls the restart jobs.)
This is invoked when the user clicks the "Load ASCII Chkpnt" button on the sim control panel.
@par Python Usage:
@code trick.load_checkpoint("<file_name>") @endcode
@param file_name - file to read checkpoint data from
@param stl_restore_on - toggle whether to restore STLs
@return always 0
*/
virtual void load_checkpoint(std::string file_name, bool stl_restore_on) ;
/**
@brief @userdesc Command to load a checkpoint file. (Calls the preload_checkpoint jobs, calls the MemoryManager restore_managed_memory
method, then calls the restart jobs.)

View File

@ -51,6 +51,8 @@ int checkpoint_objects( const char * file_name, const char * objects ) ;
/* load_checkpoint call accessible from C code */
int load_checkpoint( const char * file_name ) ;
int load_checkpoint_stls( const char * file_name, int with_stls ) ;
int load_checkpoint_job() ;
void * get_address( const char * var_name ) ;

View File

@ -371,32 +371,32 @@ namespace Trick {
Restore a checkpoint from the given stream.
@param in_s - input stream.
*/
int read_checkpoint( std::istream* in_s, bool do_restore_stls=false);
int read_checkpoint( std::istream* in_s, bool do_restore_stls = restore_stls_default);
/**
Read a checkpoint from the file of the given name.
@param filename - name of the checkpoint file to be read.
*/
int read_checkpoint( const char* filename);
int read_checkpoint( const char* filename, bool do_restore_stls = restore_stls_default);
/**
Read a checkpoint from the given string.
@param s - string containing the checkpoint info.
*/
int read_checkpoint_from_string( const char* s );
int read_checkpoint_from_string( const char* s, bool do_restore_stls = restore_stls_default );
/**
Delete all TRICK_LOCAL variables and clear all TRICK_EXTERN variables. Then read
and restore the checkpoint from the given stream.
@param in_s - input stream.
*/
int init_from_checkpoint( std::istream* in_s);
int init_from_checkpoint( std::istream* in_s, bool do_restore_stls = restore_stls_default);
/**
Delete all TRICK_LOCAL variables and clear all TRICK_EXTERN variables. Then read
and restore the checkpoint of the given filename.
*/
int init_from_checkpoint( const char* filename);
int init_from_checkpoint( const char* filename, bool do_restore_stls = restore_stls_default);
/**
Deallocate the memory for all TRICK_LOCAL variables and then forget about them.
@ -662,6 +662,10 @@ namespace Trick {
void write_JSON_alloc_info( std::ostream& s, ALLOC_INFO *alloc_info) ;
void write_JSON_alloc_list( std::ostream& s, int start_ix, int num) ;
int set_restore_stls_default (bool on);
static bool restore_stls_default; /**< -- true = restore STL variables on checkpoint restore if user does not specify option. false = don't */
private:
static int instance_count; /**< -- Number of instances of MemoryManager. Not allowed to exceed 1.*/

View File

@ -317,17 +317,18 @@ int checkpoint_map_stl_sk_sd(STL & in_map , std::string object_name , std::strin
/* copy the contents of the map the 2 arrays */
for ( iter = in_map.begin() , ii = 0 ; iter != in_map.end() ; iter++ , ii++ ) {
std::ostringstream sub_elements ;
std::stringstream sub_elements ;
sub_elements << object_name << "_" << var_name << "_keys_" << ii ;
keys[ii] = sub_elements.str() ;
std::ostringstream index_string ;
std::stringstream index_string ;
index_string << ii ;
checkpoint_stl( const_cast<typename STL::key_type &>(iter->first) ,
object_name + "_" + var_name + "_keys", index_string.str() ) ;
sub_elements << object_name << "_" << var_name << "_data_" << ii ;
items[ii] = sub_elements.str() ;
std::stringstream sub_elements_data;
sub_elements_data << object_name << "_" << var_name << "_data_" << ii ;
items[ii] = sub_elements_data.str() ;
checkpoint_stl( iter->second ,
object_name + "_" + var_name + "_data", index_string.str() ) ;

View File

@ -50,12 +50,14 @@ void TMM_delete_extern_var_a( void* address);
void TMM_delete_extern_var_n( const char* var_name );
void TMM_write_checkpoint( const char* filename) ;
int TMM_read_checkpoint( const char* filename);
int TMM_read_checkpoint_from_string( const char* str);
int TMM_init_from_checkpoint( const char* filename);
int TMM_add_shared_library_symbols( const char* filename);
int TMM_set_stl_restore (int on_off);
REF2* ref_attributes(const char* name);
int ref_var(REF2* R, char* name);

View File

@ -1,17 +1,7 @@
def main():
#trick.echo_jobs_on()
#trick.sim_control_panel_set_enabled(True)
#trick.real_time_enable()
#trick.itimer_enable()
trick.checkpoint_pre_init(True)
#trick.checkpoint_post_init(True)
#trick.checkpoint_end(True)
#trick.freeze(2.0)
trick.exec_set_software_frame(0.10)
trick.exec_set_freeze_frame(0.10)

View File

@ -0,0 +1,15 @@
import trick
def main():
trick.exec_set_job_onoff("the_object.stlc.addData", 1, True)
trick.exec_set_job_onoff("the_object.stlc.test", 1, False)
trick.exec_set_job_onoff("the_object.stlc.print", 1, False)
trick.add_read( 0.5, 'trick.checkpoint("chkpnt_in")')
trick.exec_set_freeze_frame(0.10)
trick.stop(1.0)
if __name__ == "__main__":
main()

View File

@ -1,12 +1,20 @@
import trick
from trick.unit_test import *
def main():
trick.checkpoint_post_init(True)
trick.checkpoint_end(True)
trick.load_checkpoint("RUN_test/chkpnt_in")
trick.load_checkpoint_job()
# Data recording HDF5 test
trick.exec_set_freeze_frame(0.10)
trick.stop(5.0)
trick.exec_set_job_onoff("the_object.stlc.addData", 1, False)
trick.exec_set_job_onoff("the_object.stlc.test", 1, True)
trick.exec_set_job_onoff("the_object.stlc.print", 1, False)
trick_utest.unit_tests.enable()
trick_utest.unit_tests.set_file_name( os.getenv("TRICK_HOME") + "/trick_test/SIM_stl.xml" )
trick_utest.unit_tests.set_test_name( "STLCheckpointTest" )
trick.stop(1.0)
if __name__ == "__main__":
main()

View File

@ -8,10 +8,15 @@ class theSimObject : public Trick::SimObject {
STLCheckpoint stlc ;
/** Constructor to add the jobs */
theSimObject() : stlc("Petunia") {
(1.0, "scheduled") stlc.speak() ;
theSimObject() : stlc() {
("initialization") stlc.addData();
(1.0, "scheduled") stlc.test () ;
(1.0, "scheduled") stlc.print () ;
}
} ;
theSimObject the_object ;

View File

@ -2,4 +2,18 @@
TRICK_CFLAGS += -I./models
TRICK_CXXFLAGS += -I./models
#TRICK_CXXFLAGS += -std=c++11
TRICK_CXXFLAGS += -std=c++11
test: setup
# This is a workaround so that the sim runs with RUN_test/setup.py before the actual unit test run.
# setup.py adds hardcoded data to the sim and dumps a checkpoint, and unit_test.py loads that checkpoint and checks all the values.
setup: T_main_${TRICK_HOST_CPU}.exe
echo "Running Setup Job"
./T_main_${TRICK_HOST_CPU}.exe RUN_test/setup.py
clean: checkpoint_clean
checkpoint_clean:
rm -f RUN_test/chkpnt_in

View File

@ -1,19 +1,34 @@
#include "sim_services/Message/include/message_proto.h"
#include "STLCheckpoint.hh"
#include "trick/memorymanager_c_intf.h"
#include <iostream>
#include <vector>
#include "sim_services/UnitTest/include/trick_tests.h"
/* These 2 constructors add different data to an STLCheckpoint. */
STLCheckpoint::STLCheckpoint() {
return ;
}
STLCheckpoint::STLCheckpoint(std::string in_name) :
vector_vector_double(4, std::vector<double>(3)) ,
vector_vector_vector_double(5, std::vector<std::vector<double> >(4, std::vector<double>(3)))
{
template <typename T>
void compare_data_structures_with_top(T a, T b, std::string test_name) {
const char *test_suite = "STLCheckpoint";
name = in_name ;
TRICK_EXPECT_EQ(a.size(), b.size(), test_suite, test_name.c_str());
while (!a.empty()) {
TRICK_EXPECT_EQ(a.top(), b.top(), test_suite, test_name.c_str());
a.pop();
b.pop();
}
}
int STLCheckpoint::addData() {
dataJobRun = true;
vector_vector_double = std::vector< std::vector< double > >(4, std::vector<double>(3));
vector_vector_vector_double = std::vector< std::vector< std::vector< double > > >(5, std::vector<std::vector<double> >(4, std::vector<double>(3)));
std::cout << "Adding hardcoded data to sim" << std::endl;
double_map[44.4] = 444.4 ;
double_map[55.5] = 555.5 ;
@ -55,15 +70,24 @@ STLCheckpoint::STLCheckpoint(std::string in_name) :
v.push_back(60) ;
common_multiples.insert(std::pair< std::pair< int, int >, std::vector< int > >(p,v)) ;
p.first = 3 ;
p.second = 7 ;
v.clear() ;
v.push_back(21) ;
v.push_back(42) ;
v.push_back(84) ;
v.push_back(168) ;
common_multiples.insert(std::pair< std::pair< int, int >, std::vector< int > >(p,v)) ;
string_map[std::string("sister")] = std::string("Lisa") ;
string_map[std::string("dog")] = std::string("Santa's Little Helper") ;
int_multimap.insert(std::pair<int, int>(44,444)) ;
int_multimap.insert(std::pair<int, int>(55,555)) ;
int_multimap.insert(std::pair<int, int>(66,666)) ;
int_multimap.insert(std::pair<int, int>(44,444)) ;
int_multimap.insert(std::pair<int, int>(55,555)) ;
int_multimap.insert(std::pair<int, int>(66,666)) ;
int_multimap.insert(std::pair<int, int>(44,4444)) ;
int_multimap.insert(std::pair<int, int>(55,5555)) ;
int_multimap.insert(std::pair<int, int>(66,6666)) ;
string_key_multimap.insert(std::pair<std::string, int>("four", 4)) ;
string_key_multimap.insert(std::pair<std::string, int>("five", 5)) ;
@ -118,6 +142,23 @@ STLCheckpoint::STLCheckpoint(std::string in_name) :
string_set.insert("abc") ;
string_set.insert("def") ;
// for (int j = 0; j < 5; j++) {
// std::vector<int> temp;
// for (int i = j; i < 10; i++) {
// temp.push_back(i);
// }
// vector_set.insert(temp);
// }
for (int j = 0; j < 5; j++) {
std::vector<int> temp;
for (int i = j; i < 10; i++) {
temp.push_back(i);
}
vector_queue.push(temp);
}
long_multiset.insert(8000) ;
long_multiset.insert(4000) ;
long_multiset.insert(4000) ;
@ -141,8 +182,10 @@ STLCheckpoint::STLCheckpoint(std::string in_name) :
string_stack.push("with the bigger") ;
string_stack.push("Gee Bees") ;
stack_vector_int.push(v) ;
stack_vector_int.push(v) ;
std::vector<int> temp_v1 = {1, 2, 3, 4};
std::vector<int> temp_v2 = {5, 6, 7, 8};
stack_vector_int.push(temp_v1) ;
stack_vector_int.push(temp_v2) ;
int_queue.push(1) ;
int_queue.push(2) ;
@ -164,11 +207,11 @@ STLCheckpoint::STLCheckpoint(std::string in_name) :
string_priority_queue.push("an") ;
string_priority_queue.push("iPhone 4") ;
queue_vector_int.push(v) ;
queue_vector_int.push(v) ;
queue_vector_int.push(temp_v1) ;
queue_vector_int.push(temp_v2) ;
priority_queue_vector_int.push(v) ;
priority_queue_vector_int.push(v) ;
priority_queue_vector_int.push(temp_v1) ;
priority_queue_vector_int.push(temp_v2) ;
int_pair.first = 10 ;
int_pair.second = 20 ;
@ -197,6 +240,27 @@ STLCheckpoint::STLCheckpoint(std::string in_name) :
pair_pair_pair.second.first = 53 ;
pair_pair_pair.second.second = 54 ;
int_vec_pair.first = 5;
int_vec_pair.second.push_back(5);
int_vec_pair.second.push_back(10);
int_vec_pair.second.push_back(15);
int_vec_pair.second.push_back(20);
vec_int_pair.second = 5;
vec_int_pair.first.push_back(5);
vec_int_pair.first.push_back(10);
vec_int_pair.first.push_back(15);
vec_int_pair.first.push_back(20);
vec_vec_pair.first.push_back(5);
vec_vec_pair.first.push_back(10);
vec_vec_pair.first.push_back(15);
vec_vec_pair.first.push_back(20);
vec_vec_pair.second.push_back(5);
vec_vec_pair.second.push_back(10);
vec_vec_pair.second.push_back(15);
vec_vec_pair.second.push_back(20);
vector_vector_double[0][0] = 100 ;
vector_vector_double[0][1] = 101 ;
vector_vector_double[0][2] = 102 ;
@ -275,30 +339,363 @@ STLCheckpoint::STLCheckpoint(std::string in_name) :
vector_vector_vector_double[4][3][1] = 4010 ;
vector_vector_vector_double[4][3][2] = 4011 ;
return ;
for (int i = 0; i < 10; i++) {
UserClass temp;
for (int j = 0; j < 5; j++) {
temp.a[j] = i+j;
}
temp.b = 8888888888;
temp.c = "Here is a test string";
// We'll just make a pointer to the same stuff
UserClass * user_class_ptr = (UserClass *) TMM_declare_var_s("UserClass");
for (int j = 0; j < 5; j++) {
user_class_ptr->a[j] = i+j;
}
user_class_ptr->b = 8888888888;
user_class_ptr->c = "Here is a test string";
temp.d = user_class_ptr;
vec_user_simple.emplace_back(temp);
}
for (int i = 0; i < 10; i++) {
SimpleWrapper temp_wrapper;
temp_wrapper.a = 888;
for (int j = i; j < i+10; j++) {
temp_wrapper.vec.push_back(j);
}
vec_user_defined.emplace_back(temp_wrapper);
}
for (int i = 0; i < 10; i++) {
SimpleWrapper * temp_wrapper = (SimpleWrapper *) TMM_declare_var_s("SimpleWrapper");
temp_wrapper->a = 888;
for (int j = i; j < i+10; j++) {
temp_wrapper->vec.push_back(j);
}
vec_user_defined_ptr.push_back(temp_wrapper);
}
return 0;
}
int STLCheckpoint::speak() {
//message_publish(1,"Quack!\n") ;
//message_publish(1,"double_vector: %f %f %f\n", double_vector[0], double_vector[1], double_vector[2]) ;
//message_publish(1,"vector_vector_double[1]: %f %f %f\n",
// vector_vector_double[1][0], vector_vector_double[1][1], vector_vector_double[1][2]) ;
//message_publish(1,"vector_vector_vector_double[4][2]: %f %f %f\n",
// vector_vector_vector_double[4][2][0], vector_vector_vector_double[4][2][1], vector_vector_vector_double[4][2][2]) ;
//message_publish(1,"string_vector[0]: %s\n", string_vector[0].c_str()) ;
//message_publish(1,"map_int_vector_int[1][1] = %d\n", map_int_vector_int[1][1]) ;
//message_publish(1,"gcd = %d\n", gcd[std::pair<int, int >(24,30)]) ;
//message_publish(1,"common_multiples = %d\n", common_multiples[std::pair<int, int >(3,5)][1]) ;
//message_publish(1,"common_multiples = %d\n", common_multiples[std::pair<int, int >(3,5)][1]) ;
//message_publish(1,"int_pair_int_int.second.second = %d\n", int_pair_int_int.second.second) ;
//message_publish(1,"pair_int_int_int.first.second = %d\n", pair_int_int_int.first.second) ;
//message_publish(1,"pair_pair_pair.second.first = %d\n", pair_pair_pair.second.first) ;
//message_publish(1,"int_queue.front = %d\n", int_queue.front()) ;
//message_publish(1,"int_priority_queue.top = %d\n", int_priority_queue.top()) ;
//message_publish(1,"uint_stack.top = %d\n", uint_stack.top()) ;
//message_publish(1,"queue_vector_int.front()[3] = %d\n", queue_vector_int.front()[3]) ;
//message_publish(1,"priority_queue_vector_int.top()[2] = %d\n", priority_queue_vector_int.top()[2]) ;
int STLCheckpoint::print() {
message_publish(1,"Quack!\n") ;
message_publish(1, "Double vector size: %d", double_vector.size() );
message_publish(1,"double_vector: %f %f %f\n", double_vector[0], double_vector[1], double_vector[2]) ;
message_publish(1,"vector_vector_double[1]: %f %f %f\n",
vector_vector_double[1][0], vector_vector_double[1][1], vector_vector_double[1][2]) ;
message_publish(1,"vector_vector_vector_double[4][2]: %f %f %f\n",
vector_vector_vector_double[4][2][0], vector_vector_vector_double[4][2][1], vector_vector_vector_double[4][2][2]) ;
message_publish(1,"string_vector[0]: %s\n", string_vector[0].c_str()) ;
message_publish(1,"map_int_vector_int[1][1] = %d\n", map_int_vector_int[1][1]) ;
message_publish(1,"gcd = %d\n", gcd[std::pair<int, int >(24,30)]) ;
message_publish(1,"common_multiples = %d\n", common_multiples[std::pair<int, int >(3,5)][1]) ;
message_publish(1,"common_multiples = %d\n", common_multiples[std::pair<int, int >(3,5)][1]) ;
message_publish(1,"int_pair_int_int.second.second = %d\n", int_pair_int_int.second.second) ;
message_publish(1,"pair_int_int_int.first.second = %d\n", pair_int_int_int.first.second) ;
message_publish(1,"pair_pair_pair.second.first = %d\n", pair_pair_pair.second.first) ;
message_publish(1,"int_queue.front = %d\n", int_queue.front()) ;
message_publish(1,"int_priority_queue.top = %d\n", int_priority_queue.top()) ;
message_publish(1,"uint_stack.top = %d\n", uint_stack.top()) ;
message_publish(1,"queue_vector_int.front()[3] = %d\n", queue_vector_int.front()[3]) ;
message_publish(1,"priority_queue_vector_int.top()[2] = %d\n", priority_queue_vector_int.top()[2]) ;
message_publish(1,"stack_vector_int.top()[1] = %d\n", stack_vector_int.top()[1]) ;
return 0 ;
}
int STLCheckpoint::test() {
std::cout << "Running test jobs" << std::endl;
const char *test_suite = "STLCheckpoint";
TRICK_EXPECT_EQ( double_vector.size(), 3, test_suite, "double_vector size");
TRICK_EXPECT_EQ( double_vector[0], 4, test_suite, "double_vector[0]");
TRICK_EXPECT_EQ( double_vector[1], 5, test_suite, "double_vector[1]");
TRICK_EXPECT_EQ( double_vector[2], 6, test_suite, "double_vector[2]");
TRICK_EXPECT_EQ( vector_vector_double[1][0], 103, test_suite, "vector_vector_double[1][0]");
TRICK_EXPECT_EQ( vector_vector_double[1][1], 104, test_suite, "vector_vector_double[1][1]");
TRICK_EXPECT_EQ( vector_vector_double[1][2], 105, test_suite, "vector_vector_double[1][2]");
TRICK_EXPECT_EQ( vector_vector_vector_double[4][2][0], 4006, test_suite, "vector_vector_vector_double[4][2][0]");
TRICK_EXPECT_EQ( vector_vector_vector_double[4][2][1], 4007, test_suite, "vector_vector_vector_double[4][2][1]");
TRICK_EXPECT_EQ( vector_vector_vector_double[4][2][2], 4008, test_suite, "vector_vector_vector_double[4][2][2]");
TRICK_EXPECT_EQ( string_vector[0], std::string("It"), test_suite, "string_vector");
TRICK_EXPECT_EQ( double_map[44.4], 444.4, test_suite, "double_map[44.4]" );
TRICK_EXPECT_EQ( string_data_map[7], std::string("seiben"), test_suite, "string_data_map[7]" );
TRICK_EXPECT_EQ( string_data_map[9], std::string("neun") , test_suite, "string_data_map[9]");
std::vector< int > v ;
v.push_back(2) ;
v.push_back(4) ;
v.push_back(6) ;
v.push_back(8) ;
TRICK_EXPECT_EQ( map_int_vector_int[1], v, test_suite, "map_int_vector_int[1]");
std::pair< int , int > p ;
p.first = 24 ;
p.second = 30 ;
TRICK_EXPECT_EQ(gcd[p], 6, test_suite, "gcd[p]" );
p.first = 50 ;
p.second = 60 ;
std::pair< int , int > q ;
q.first = 70 ;
q.second = 80 ;
TRICK_EXPECT_EQ( map_pair_pair[p], q, test_suite, "map_pair_pair[p]" );
p.first = 3 ;
p.second = 5 ;
v.clear() ;
v.push_back(15) ;
v.push_back(30) ;
v.push_back(45) ;
v.push_back(60) ;
TRICK_EXPECT_EQ( common_multiples[p], v, test_suite, "common_multiples" );
p.first = 3 ;
p.second = 7 ;
v.clear() ;
v.push_back(21) ;
v.push_back(42) ;
v.push_back(84) ;
v.push_back(168) ;
TRICK_EXPECT_EQ( common_multiples[p], v, test_suite, "common_multiples" );
TRICK_EXPECT_EQ( string_map["sister"], "Lisa", test_suite, "string_map[sister]" );
TRICK_EXPECT_EQ( string_map["dog"], "Santa's Little Helper", test_suite, "string_map[dog]" );
// The easiest way to test the multimaps is to just rebuild copies and compare
std::multimap<int, int> int_multimap_copy;
int_multimap_copy.insert(std::pair<int, int>(44,444)) ;
int_multimap_copy.insert(std::pair<int, int>(55,555)) ;
int_multimap_copy.insert(std::pair<int, int>(66,666)) ;
int_multimap_copy.insert(std::pair<int, int>(44,4444)) ;
int_multimap_copy.insert(std::pair<int, int>(55,5555)) ;
int_multimap_copy.insert(std::pair<int, int>(66,6666)) ;
TRICK_EXPECT_EQ(int_multimap, int_multimap_copy , test_suite, "int_multimap");
int_multimap_copy.insert(std::pair<int, int>(66,66666)) ;
TRICK_EXPECT_NE(int_multimap, int_multimap_copy , test_suite, "int_multimap_fail");
std::multimap<std::string, int> string_key_multimap_copy;
string_key_multimap_copy.insert(std::pair<std::string, int>("four", 4)) ;
string_key_multimap_copy.insert(std::pair<std::string, int>("five", 5)) ;
string_key_multimap_copy.insert(std::pair<std::string, int>("six", 6)) ;
string_key_multimap_copy.insert(std::pair<std::string, int>("four", 44)) ;
string_key_multimap_copy.insert(std::pair<std::string, int>("five", 55)) ;
string_key_multimap_copy.insert(std::pair<std::string, int>("six", 66)) ;
TRICK_EXPECT_EQ(string_key_multimap, string_key_multimap_copy , test_suite, "string_key_multimap");
std::multimap<int, std::string> string_data_multimap_copy;
string_data_multimap_copy.insert(std::pair<int, std::string>(7, "seiben")) ;
string_data_multimap_copy.insert(std::pair<int, std::string>(8, "acht")) ;
string_data_multimap_copy.insert(std::pair<int, std::string>(9, "neun")) ;
string_data_multimap_copy.insert(std::pair<int, std::string>(7, "seven")) ;
string_data_multimap_copy.insert(std::pair<int, std::string>(8, "eight")) ;
string_data_multimap_copy.insert(std::pair<int, std::string>(9, "nine")) ;
TRICK_EXPECT_EQ(string_data_multimap, string_data_multimap_copy , test_suite, "string_data_multimap");
std::multimap<std::string, std::string> string_multimap_copy;
string_multimap_copy.insert(std::pair<std::string, std::string>("sister","Lisa")) ;
string_multimap_copy.insert(std::pair<std::string, std::string>("dog","Santa's Little Helper")) ;
string_multimap_copy.insert(std::pair<std::string, std::string>("sister","Meg")) ;
string_multimap_copy.insert(std::pair<std::string, std::string>("dog","Brian")) ;
TRICK_EXPECT_EQ(string_multimap, string_multimap_copy , test_suite, "string_multimap");
// TODO: fix this case
// TRICK_EXPECT_EQ(vec_user_defined.size(), 10, test_suite, "vec_user_defined");
// for (int i = 0; i < vec_user_defined.size(); i++) {
// TRICK_EXPECT_EQ(vec_user_defined[i].vec.size(), 10, test_suite, "vec_user_defined");
// TRICK_EXPECT_EQ(vec_user_defined[i].a, 888, test_suite, "vec_user_defined");
// for (int j = i; j < i+vec_user_defined[i].vec.size(); j++) {
// TRICK_EXPECT_EQ(vec_user_defined[i].vec[j-i], j, test_suite, "vec_user_defined");
// }
// }
TRICK_EXPECT_EQ(vec_user_defined_ptr.size(), 10, test_suite, "vec_user_defined_ptr");
for (int i = 0; i < vec_user_defined_ptr.size(); i++) {
TRICK_EXPECT_EQ(vec_user_defined_ptr[i]->vec.size(), 10, test_suite, "vec_user_defined_ptr");
TRICK_EXPECT_EQ(vec_user_defined_ptr[i]->a, 888, test_suite, "vec_user_defined_ptr");
std::vector<int> test_vec;
for (int j = i; j < i+vec_user_defined_ptr[i]->vec.size(); j++) {
test_vec.push_back(j);
}
TRICK_EXPECT_EQ(vec_user_defined_ptr[i]->vec, test_vec, test_suite, "vec_user_defined_ptr");
}
std::vector<std::string> string_vector_copy = {"It", "has", "the", "Wi-Fies"};
TRICK_EXPECT_EQ(string_vector, string_vector_copy, test_suite, "string_vector");
std::list<short> short_list_copy = {400, 401, 402};
int list_index = 0;
TRICK_EXPECT_EQ(short_list, short_list_copy, test_suite, "short_list");
std::list<std::string> string_list_copy = {"I", "don't", "care"};
TRICK_EXPECT_EQ(string_list, string_list_copy, test_suite, "string_list");
std::deque<float> float_deque_copy = {98.7, 65.4, 32.1};
TRICK_EXPECT_EQ(float_deque, float_deque_copy, test_suite, "float_deque");
std::deque<std::string> string_deque_copy = {"Welcome", "to", "PhoneMart"};
TRICK_EXPECT_EQ(string_deque, string_deque_copy, test_suite, "string_deque");
std::set<int> int_set_copy = {8000, 4000, 2000, 1000};
TRICK_EXPECT_EQ(int_set, int_set_copy, test_suite, "int_set");
std::set<std::string> string_set_copy = {"efg", "abc", "def"};
TRICK_EXPECT_EQ(string_set, string_set_copy, test_suite, "string_set");
std::queue<std::vector<int>> vector_queue_copy;
for (int j = 0; j < 5; j++) {
std::vector<int> temp;
for (int i = j; i < 10; i++) {
temp.push_back(i);
}
vector_queue_copy.push(temp);
}
TRICK_EXPECT_EQ(vector_queue, vector_queue_copy, test_suite, "vector_queue");
std::multiset<long> long_multiset_copy = {8000, 4000, 4000, 2000, 1000};
TRICK_EXPECT_EQ(long_multiset, long_multiset_copy, test_suite, "long_multiset");
std::multiset<std::string> string_multiset_copy = {"efg", "abc", "def", "efg", "abc", "def"};
TRICK_EXPECT_EQ(string_multiset, string_multiset_copy, test_suite, "string_multiset");
std::stack<unsigned int> uint_stack_copy;
uint_stack_copy.push(1) ;
uint_stack_copy.push(2) ;
uint_stack_copy.push(3) ;
uint_stack_copy.push(4) ;
TRICK_EXPECT_EQ(uint_stack, uint_stack_copy, test_suite, "uint_stack");
std::stack<std::string> string_stack_copy;
string_stack_copy.push("I") ;
string_stack_copy.push("want the one") ;
string_stack_copy.push("with the bigger") ;
string_stack_copy.push("Gee Bees") ;
TRICK_EXPECT_EQ(string_stack, string_stack_copy, test_suite, "string_stack");
std::stack<std::vector<int>> stack_vector_int_copy;
std::vector<int> temp_v1 = {1, 2, 3, 4};
std::vector<int> temp_v2 = {5, 6, 7, 8};
stack_vector_int_copy.emplace(temp_v1) ;
stack_vector_int_copy.emplace(temp_v2) ;
TRICK_EXPECT_EQ(stack_vector_int, stack_vector_int_copy, test_suite, "stack_vector_int");
std::queue<int> int_queue_copy;
int_queue_copy.push(1) ;
int_queue_copy.push(2) ;
int_queue_copy.push(3) ;
int_queue_copy.push(4) ;
TRICK_EXPECT_EQ(int_queue, int_queue_copy, test_suite, "int_queue");
std::queue<std::string> string_queue_copy;
string_queue_copy.push("I") ;
string_queue_copy.push("want") ;
string_queue_copy.push("an") ;
string_queue_copy.push("iPhone 4") ;
TRICK_EXPECT_EQ(string_queue, string_queue_copy, test_suite, "string_queue");
// Why doesn't priority_queue have the == operator but literally everything else does >:(
std::priority_queue<int> int_priority_queue_copy;
int_priority_queue_copy.push(3) ;
int_priority_queue_copy.push(2) ;
int_priority_queue_copy.push(4) ;
int_priority_queue_copy.push(1) ;
compare_data_structures_with_top(int_priority_queue_copy, int_priority_queue, "int_priority_queue");
std::priority_queue<std::string> string_priority_queue_copy;
string_priority_queue_copy.push("I") ;
string_priority_queue_copy.push("want") ;
string_priority_queue_copy.push("an") ;
string_priority_queue_copy.push("iPhone 4") ;
compare_data_structures_with_top(string_priority_queue_copy, string_priority_queue, "string_priority_queue");
std::queue<std::vector<int>> queue_vector_int_copy;
queue_vector_int_copy.emplace(temp_v1) ;
queue_vector_int_copy.emplace(temp_v2) ;
TRICK_EXPECT_EQ(queue_vector_int, queue_vector_int_copy, test_suite, "queue_vector_int");
std::priority_queue<std::vector<int>> priority_queue_vector_int_copy;
priority_queue_vector_int_copy.emplace(temp_v1) ;
priority_queue_vector_int_copy.emplace(temp_v2) ;
compare_data_structures_with_top(priority_queue_vector_int_copy, priority_queue_vector_int, "priority_queue_vector_int");
std::pair<int,int> int_pair_copy(10,20);
TRICK_EXPECT_EQ(int_pair, int_pair_copy, test_suite, "int_pair");
std::pair< std::string , int > string_first_pair_copy ("string first", 25);
TRICK_EXPECT_EQ(string_first_pair, string_first_pair_copy, test_suite, "string_first_pair");
std::pair< int , std::string > string_second_pair_copy (25, "string second");
TRICK_EXPECT_EQ(string_second_pair_copy, string_second_pair, test_suite, "string_second_pair");
std::pair< std::string , std::string > string_pair_copy ("pair first string", "pair second string");
TRICK_EXPECT_EQ(string_pair_copy, string_pair, test_suite, "string_pair");
std::pair< int , std::pair< int, int > > int_pair_int_int_copy;
int_pair_int_int_copy.first = 200 ;
p.first = 10 ;
p.second = 20 ;
int_pair_int_int_copy.second = p ;
TRICK_EXPECT_EQ(int_pair_int_int_copy, int_pair_int_int, test_suite, "int_pair_int_int");
std::pair< std::pair< int, int > , int > pair_int_int_int_copy;
p.first = 15 ;
p.second = 12 ;
pair_int_int_int_copy.first = p ;
pair_int_int_int_copy.second = 180 ;
TRICK_EXPECT_EQ(pair_int_int_int_copy, pair_int_int_int, test_suite, "pair_int_int_int");
std::pair< std::pair< int, int > , std::pair< int, int > > pair_pair_pair_copy ;
pair_pair_pair_copy.first.first = 51 ;
pair_pair_pair_copy.first.second = 52 ;
pair_pair_pair_copy.second.first = 53 ;
pair_pair_pair_copy.second.second = 54 ;
TRICK_EXPECT_EQ(pair_pair_pair_copy, pair_pair_pair, test_suite, "pair_pair_pair");
// TODO: fix this case
// Check all the int/vec combo pairs together, for laziness
// TRICK_EXPECT_EQ(int_vec_pair.first, 5, test_suite, "int_vec_pair.first");
// TRICK_EXPECT_EQ(vec_int_pair.second, 5, test_suite, "vec_int_pair.second");
// TRICK_EXPECT_EQ(int_vec_pair.second.size(), 4, test_suite, "int_vec_pair.second.size");
// TRICK_EXPECT_EQ(vec_int_pair.first.size(), 4, test_suite, "vec_int_pair.first.size");
// TRICK_EXPECT_EQ(vec_vec_pair.first.size(), 4, test_suite, "vec_vec_pair.first.size");
// TRICK_EXPECT_EQ(vec_vec_pair.second.size(), 4, test_suite, "vec_vec_pair.second.size");
// for (int i = 0; i < int_vec_pair.second.size(); i++) {
// TRICK_EXPECT_EQ(int_vec_pair.second[i], (i+1)*5, test_suite, "int_vec_pair.second elems");
// TRICK_EXPECT_EQ(vec_int_pair.first[i], (i+1)*5, test_suite, "vec_int_pair.first elems");
// TRICK_EXPECT_EQ(vec_vec_pair.first[i], (i+1)*5, test_suite, "vec_vec_pair.first elems");
// TRICK_EXPECT_EQ(vec_vec_pair.second[i], (i+1)*5, test_suite, "vec_vec_pair.second elems");
// }
TRICK_EXPECT_EQ(vec_user_simple.size(), 10, test_suite, "vec_user_simple")
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
TRICK_EXPECT_EQ(vec_user_simple[i].a[j], i+j, test_suite, "vec_user_simple");
TRICK_EXPECT_EQ(vec_user_simple[i].d->a[j], i+j, test_suite, "vec_user_simple");
}
TRICK_EXPECT_EQ(vec_user_simple[i].b, 8888888888, test_suite, "vec_user_simple");
TRICK_EXPECT_EQ(vec_user_simple[i].d->b, 8888888888, test_suite, "vec_user_simple");
TRICK_EXPECT_EQ(vec_user_simple[i].c, "Here is a test string", test_suite, "vec_user_simple");
TRICK_EXPECT_EQ(vec_user_simple[i].d->c, "Here is a test string", test_suite, "vec_user_simple");
}
}

View File

@ -18,13 +18,31 @@
#include <queue>
#include <utility>
class SimpleWrapper {
public:
int a;
std::vector<int> vec;
};
class UserClass {
public:
int a[5];
long long b;
std::string c;
UserClass * d;
};
class STLCheckpoint {
public:
STLCheckpoint() ;
STLCheckpoint(std::string in_name) ;
int speak() ;
int addData() ;
int print() ;
int test() ;
bool dataJobRun;
std::string name ;
@ -54,6 +72,10 @@ class STLCheckpoint {
std::set< int > int_set ;
std::set< std::string > string_set ;
// std::set< std::vector<int> > vector_set;
std::queue< std::vector<int> > vector_queue;
std::multiset< long > long_multiset ;
std::multiset< std::string > string_multiset ;
@ -76,6 +98,10 @@ class STLCheckpoint {
std::pair< int , std::string > string_second_pair ;
std::pair< std::string , std::string > string_pair ;
std::pair< int, std::vector<int> > int_vec_pair;
std::pair< std::vector<int>, int > vec_int_pair;
std::pair< std::vector<int>, std::vector<int> > vec_vec_pair;
std::pair< int , std::pair< int, int > > int_pair_int_int ;
std::pair< std::pair< int, int > , int > pair_int_int_int ;
@ -84,6 +110,12 @@ class STLCheckpoint {
std::vector< std::vector< double > > vector_vector_double ;
std::vector< std::vector< std::vector< double > > > vector_vector_vector_double ;
//std::vector< std::list< double > > vector_list_double ;
std::vector<UserClass> vec_user_simple;
std::vector<SimpleWrapper> vec_user_defined;
std::vector<SimpleWrapper *> vec_user_defined_ptr;
} ;
#endif

View File

@ -38,6 +38,9 @@ SIMS_TO_COMPILE_AND_RUN = \
SIM_threads \
SIM_trickified
# SIM_stls will run twice. First run is RUN_test/setup.py, which is added as a dependency to test in its S_overrides.mk file
# The second run is the normal RUN_test/unit_test.py which is run through this makefile.
# Sims with problems, no purpose, or maybe shouldn't be a test
# SIM_leaks ( should be deleted )
# SIM_dynamic_sim_object ( not running, class won't instantiate )

View File

@ -296,6 +296,11 @@ void Trick::CheckPointRestart::load_checkpoint(std::string file_name) {
load_checkpoint_file_name = file_name ;
}
void Trick::CheckPointRestart::load_checkpoint(std::string file_name, bool stls_on) {
trick_MM->set_restore_stls_default(stls_on);
load_checkpoint(file_name);
}
int Trick::CheckPointRestart::load_checkpoint_job() {
JobData * curr_job ;

View File

@ -158,6 +158,30 @@ extern "C" int load_checkpoint( const char * file_name ) {
}
/**
* @relates Trick::CheckPointRestart
* @copydoc Trick::CheckPointRestart::load_checkpoint
*/
extern "C" int load_checkpoint_stls( const char * file_name, int on_off ) {
the_cpr->load_checkpoint(std::string(file_name), (bool) on_off) ;
return(0) ;
}
/**
* @relates Trick::CheckPointRestart
* @copydoc Trick::CheckPointRestart::load_checkpoint
*/
extern "C" int load_checkpoint_objects( const char * file_name ) {
the_cpr->load_checkpoint(std::string(file_name)) ;
return(0) ;
}
/**
* @relates Trick::CheckPointRestart
* @copydoc Trick::CheckPointRestart::load_checkpoint_job

View File

@ -7,7 +7,7 @@ Trick::MemoryManager * trick_MM = NULL;
// CLASS VARIABLE INITIALIZATION
int Trick::MemoryManager::instance_count = 0;
bool Trick::MemoryManager::restore_stls_default = true;
// CONSTRUCTOR
Trick::MemoryManager::MemoryManager()

View File

@ -364,7 +364,7 @@ extern "C" void TMM_write_checkpoint(const char* filename) {
*/
extern "C" int TMM_read_checkpoint(const char* filename) {
if (trick_MM != NULL) {
return ( trick_MM->read_checkpoint( filename));
return ( trick_MM->read_checkpoint( filename ));
} else {
Trick::MemoryManager::emitError("TMM_read_checkpoint() called before MemoryManager instantiation.\n") ;
return(1);
@ -377,7 +377,7 @@ extern "C" int TMM_read_checkpoint(const char* filename) {
*/
extern "C" int TMM_read_checkpoint_from_string(const char* str) {
if (trick_MM != NULL) {
return ( trick_MM->read_checkpoint_from_string( str));
return ( trick_MM->read_checkpoint_from_string( str ));
} else {
Trick::MemoryManager::emitError("TMM_read_checkpoint_from_string() called before MemoryManager instantiation.\n") ;
return(1);
@ -390,13 +390,22 @@ extern "C" int TMM_read_checkpoint_from_string(const char* str) {
*/
extern "C" int TMM_init_from_checkpoint(const char* filename) {
if (trick_MM != NULL) {
return ( trick_MM->init_from_checkpoint( filename));
return ( trick_MM->init_from_checkpoint( filename ));
} else {
Trick::MemoryManager::emitError("TMM_init_from_checkpoint() called before MemoryManager instantiation.\n") ;
return(1);
}
}
extern "C" int TMM_set_stl_restore (int on_off) {
if (trick_MM != NULL) {
return ( trick_MM->set_restore_stls_default( (bool) on_off ));
} else {
Trick::MemoryManager::emitError("TMM_set_stl_restore() called before MemoryManager instantiation.\n") ;
return(1);
}
}
/**
@relates Trick::MemoryManager
This is the C Language version of Trick::MemoryManager::add_shared_library_symbols( filename).

View File

@ -7,7 +7,12 @@
#include "trick/MemoryManager.hh"
#include "trick/ClassicCheckPointAgent.hh"
int Trick::MemoryManager::read_checkpoint( std::istream *is, bool do_restore_stls /* default is false */) {
int Trick::MemoryManager::set_restore_stls_default (bool on_off) {
restore_stls_default = on_off;
return 0;
}
int Trick::MemoryManager::read_checkpoint( std::istream *is, bool do_restore_stl) {
ALLOC_INFO_MAP::iterator pos;
ALLOC_INFO* alloc_info;
@ -23,7 +28,7 @@ int Trick::MemoryManager::read_checkpoint( std::istream *is, bool do_restore_stl
// Search for stls and restore them
if(do_restore_stls) {
if(do_restore_stl) {
for ( pos=alloc_info_map.begin() ; pos!=alloc_info_map.end() ; pos++ ) {
restore_stls(pos->second) ;
}
@ -59,12 +64,12 @@ int Trick::MemoryManager::read_checkpoint( std::istream *is, bool do_restore_stl
return(0);
}
int Trick::MemoryManager::read_checkpoint(const char* filename ) {
int Trick::MemoryManager::read_checkpoint( const char* filename, bool restore_stls ) {
// Create a stream from the named file.
std::ifstream infile(filename , std::ios::in);
if (infile.is_open()) {
return ( read_checkpoint( &infile, true )) ;
return ( read_checkpoint( &infile, restore_stls )) ;
} else {
std::stringstream message;
message << "Couldn't open \"" << filename << "\"." ;
@ -73,7 +78,7 @@ int Trick::MemoryManager::read_checkpoint(const char* filename ) {
return 1;
}
int Trick::MemoryManager::read_checkpoint_from_string(const char* s ) {
int Trick::MemoryManager::read_checkpoint_from_string(const char* s, bool restore_stls ) {
// Create a stream from the string argument.
std::stringstream ss;
@ -86,14 +91,14 @@ int Trick::MemoryManager::read_checkpoint_from_string(const char* s ) {
*/
ss << ";" ;
}
return ( read_checkpoint( &ss ));
return ( read_checkpoint( &ss, restore_stls));
} else {
emitError("Checkpoint string is NULL.") ;
}
return 1;
}
int Trick::MemoryManager::init_from_checkpoint( std::istream *is) {
int Trick::MemoryManager::init_from_checkpoint(const char* filename, bool restore_stls ) {
if (debug_level) {
std::cout << std::endl << "Initializing from checkpoint" << std::endl;
@ -108,7 +113,8 @@ int Trick::MemoryManager::init_from_checkpoint( std::istream *is) {
std::cout.flush();
}
read_checkpoint( is);
read_checkpoint( filename, restore_stls);
if (debug_level) {
std::cout << std::endl << "Initialization from checkpoint finished." << std::endl;
@ -118,7 +124,7 @@ int Trick::MemoryManager::init_from_checkpoint( std::istream *is) {
return 0 ;
}
int Trick::MemoryManager::init_from_checkpoint(const char* filename ) {
int Trick::MemoryManager::init_from_checkpoint( std::istream *is, bool restore_stls) {
if (debug_level) {
std::cout << std::endl << "Initializing from checkpoint" << std::endl;
@ -128,12 +134,7 @@ int Trick::MemoryManager::init_from_checkpoint(const char* filename ) {
reset_memory();
if (debug_level) {
std::cout << std::endl << "- Reading checkpoint." << std::endl;
std::cout.flush();
}
read_checkpoint( filename);
read_checkpoint( is, restore_stls );
if (debug_level) {
std::cout << std::endl << "Initialization from checkpoint finished." << std::endl;

View File

@ -18,3 +18,5 @@ MM_strdup_unittest
MM_write_checkpoint
MM_write_checkpoint_hexfloat
MM_write_var_unittest
MM_stl_checkpoint
MM_stl_restore

View File

@ -262,8 +262,74 @@ TEST_F(MM_read_checkpoint, 2D_char_array) {
EXPECT_EQ(result, 0);
}
}
TEST_F(MM_read_checkpoint, WrappedStl) {
memmgr->read_checkpoint_from_string(
"VectorWrapper my_vec;"
"int my_vec_vec[4];"
"clear_all_vars();"
"my_vec_vec = "
"{10, 20, 30, 40};");
VectorWrapper * vector = (VectorWrapper *) memmgr->ref_attributes("my_vec")->address;
ASSERT_EQ(vector->vec.size(), 4);
for (int i = 0; i < 4; i++) {
EXPECT_EQ(vector->vec[i], (i+1)*10);
}
}
TEST_F(MM_read_checkpoint, WrappedStlPreDeclared) {
VectorWrapper * vector = (VectorWrapper *) memmgr->declare_var("VectorWrapper my_vec");
memmgr->read_checkpoint_from_string(
"int my_vec_vec[4];"
"clear_all_vars();"
"my_vec_vec = "
"{10, 20, 30, 40};");
ASSERT_EQ(vector->vec.size(), 4);
for (int i = 0; i < 4; i++) {
EXPECT_EQ(vector->vec[i], (i+1)*10);
}
}
TEST_F(MM_read_checkpoint, encapsulated_stl_test) {
// std::vector<int> my_vector;
Foo * my_foo_ptr = (Foo *) memmgr->declare_var("Foo my_foo");
memmgr->read_checkpoint_from_string(
"int my_foo_c[3];"
"my_foo.a = 5;"
"my_foo.b = 5.5;"
"my_foo_c = {1, 2, 3, 4};"
);
EXPECT_EQ(my_foo_ptr->a, 5);
EXPECT_EQ(my_foo_ptr->b, 5.5);
ASSERT_EQ(my_foo_ptr->c.size(), 3);
EXPECT_EQ(my_foo_ptr->c[0], 1);
EXPECT_EQ(my_foo_ptr->c[1], 2);
EXPECT_EQ(my_foo_ptr->c[2], 3);
}
TEST_F(MM_read_checkpoint, encapsulated_stl_test_stl_disabled) {
// std::vector<int> my_vector;
Foo * my_foo_ptr = (Foo *) memmgr->declare_var("Foo my_foo");
memmgr->read_checkpoint_from_string(
"int my_foo_c[3];"
"my_foo.a = 5;"
"my_foo.b = 5.5;"
"my_foo_c = {1, 2, 3, 4};", false);
EXPECT_EQ(my_foo_ptr->a, 5);
EXPECT_EQ(my_foo_ptr->b, 5.5);
// c should not be restored
ASSERT_EQ(my_foo_ptr->c.size(), 0);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,98 @@
#include <map>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <array>
#include <string>
#include <iostream>
class UserClassStl {
public:
int a;
std::vector<int> vec;
};
class UserClass {
public:
UserClass () : d(NULL) {}
int a[5];
long long b;
std::string c;
UserClass * d = NULL;
bool operator== (const UserClass& other) const {
for (int i = 0; i < 5; i++) {
if (a[i] != other.a[i])
return false;
}
if (d == NULL ^ other.d == NULL) return false;
return b == other.b && c == other.c && (d == NULL || *d == *(other.d));
}
bool operator != (const UserClass& other) const {
return !(*this == other);
}
};
class STLTestbed {
public:
// This class is intended to test the checkpoint, restore, and delete functions for each of the supported STL types.
// These live in the include/trick directory in checkpoint_<containername>.hh
// Each STL type has its own implementation of each function, so they must be tested separately.
// In addition, if the template argument is another STL container, a separate implementation is enabled to
// support recursion. (intrinsic:i vs stl:s in var names here)
// Therefore, each of the 11 supported types presents 3 * 2^(num template args) implementations to test,
// plus strings and pairs are sometimes handled strangely so those should probably be included here too
std::vector<int> i_vec;
std::vector<std::vector<int>> i_s_vec;
std::vector<std::pair<int,int>> s_vec;
std::vector<std::string> string_vec;
std::pair<double,float> i_i_pair;
std::pair<double,std::queue<bool>> i_s_pair;
std::pair<std::queue<bool>,double> s_i_pair;
std::pair<std::vector<int>,std::stack<float>> s_s_pair;
std::pair<double,std::vector<bool>> i_v_pair;
std::pair<std::pair<int,int>, int> pair_pair;
std::map<int, double> i_i_map;
std::map<int, std::stack<std::string>> i_s_map;
std::map<std::set<int>, std::string> s_i_map;
std::map<std::pair<int,int>, std::vector<int>> s_s_map;
std::queue<int> i_queue;
std::queue<std::pair<int,double>> s_queue;
std::queue<std::list<float>> nested_list_queue;
std::stack<long long> i_stack;
std::stack<std::pair<short,double>> s_stack;
std::stack<std::list<float>> nested_list_stack;
std::set<char> i_set;
// These fail in CP right now
// std::set <std::pair<int,int>> s_set;
// std::set<std::map<int,int>> nested_map_set;
// this one will as well, if we put any STL containers in there
std::multiset<int> i_multiset;
std::array<char, 10> i_array;
std::array<std::pair<int,int>, 10> pair_array;
std::array<std::string, 10> string_array;
std::array<std::vector<int>, 10> vec_array;
std::vector<UserClass> vec_user_defined;
// This does not currently work in the unit tests
std::vector<UserClassStl> vec_user_defined_stl;
std::array<std::map<std::pair<int, int>,std::vector<std::stack<std::string>>>, 5> recursive_nightmare;
};

View File

@ -95,4 +95,60 @@ void validate_alloc_info(Trick::MemoryManager *memmgr,
validate_alloc_info(alloc_info, test_var, trick_type, type_name, var_name, num, num_index, extent);
}
// This one is for anything integral
// char, short, int, long, long long
template <typename T, typename std::enable_if<!std::is_floating_point<T>::value>::type* = nullptr>
T random() {
return (T) (rand() % 1000);
}
// This should just catch bools
// Template specialization!
template<>
bool random<bool> () {
return (bool) (rand() & 1);
}
// This is for floats and doubles
template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
T random() {
T divisor = (T) rand();
// for this one in 2 billion chance
if (divisor == 0) {
divisor += 1;
}
return ((T) rand()) / divisor;
}
// This should just catch strings
// Template specialization!
template<>
std::string random<std::string> () {
static const char characters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz .,-=_+/?!@#$%^&*()<>\\\"\'\n\t\r";
static const int max_string_len = 32;
std::string random_str;;
int len = rand() % max_string_len;
for (int j = 0; j < len; j++) {
random_str += characters[rand() % sizeof(characters)];
}
return random_str;
}
// generate some random data
template <typename T>
std::vector<T> get_test_data(int num) {
std::vector<T> ret;
for (int i = 0; i < num; i++) {
ret.push_back(random<T>());
}
return ret;
}
#endif

View File

@ -2,6 +2,7 @@
PURPOSE: (Testing)
*/
#include <string>
#include <vector>
typedef struct {
unsigned int a :3;
@ -93,3 +94,26 @@ class UDT7 {
char B[32][4];
};
class Foo {
public:
int a;
double b;
std::vector<int> c;
};
class VectorWrapper {
public:
int operator[] (int index) {
return vec[index];
}
void push_back(int val) {
vec.push_back(val);
}
int size() {
return vec.size();
}
std::vector<int> vec;
};

View File

@ -1104,3 +1104,30 @@ TEST_F(MM_write_checkpoint, ptr_to_array_of_ptrs_to_objects ) {
EXPECT_EQ( udt7_p->udt3pp[2]->b , 8);
}
TEST_F(MM_write_checkpoint, WrappedStl ) {
VectorWrapper * vector = (VectorWrapper *) memmgr->declare_var("VectorWrapper vec_allocation");
vector->push_back(10);
vector->push_back(20);
vector->push_back(30);
vector->push_back(40);
std::stringstream ss;
memmgr->write_checkpoint(ss, "vec_allocation");
std::string result= ss.str();
ASSERT_NE (result.size(), 0);
EXPECT_EQ( strcmp_IgnoringWhiteSpace(
"// Variable Declarations."
"VectorWrapper vec_allocation;"
"int vec_allocation_vec[4];"
"// Clear all allocations to 0."
"clear_all_vars();"
"// Variable Assignments."
"// STL: vec_allocation.vec"
"vec_allocation_vec = "
"{10, 20, 30, 40};", result.c_str()), 0);
}

View File

@ -1,6 +1,8 @@
/*
PURPOSE: (Testing)
*/
#include <vector>
#include <stdlib.h>
typedef enum {
JANUARY = 1, FEBRUARY = 2, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
@ -42,3 +44,21 @@ class UDT7 {
double A;
UDT3** udt3pp;
};
class VectorWrapper {
public:
int operator[] (int index) {
return vec[index];
}
void push_back(int val) {
vec.push_back(val);
}
int size() {
return vec.size();
}
private:
std::vector<int> vec;
};

View File

@ -14,10 +14,21 @@ TRICK_SYSTEM_CXXFLAGS := $(subst -isystem,-I,$(TRICK_SYSTEM_CXXFLAGS))
#TRICK_SYSTEM_LDFLAGS += ${COVERAGE_FLAGS}
# Flags passed to the preprocessor.
TRICK_CPPFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra ${COVERAGE_FLAGS} -std=c++11 ${TRICK_SYSTEM_CXXFLAGS}
TRICK_CPPFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra -Wno-sign-compare ${COVERAGE_FLAGS} -std=c++11 ${TRICK_SYSTEM_CXXFLAGS}
TRICK_LIBS = -L${TRICK_LIB_DIR} -ltrick_mm -ltrick_units -ltrick -ltrick_mm -ltrick_units -ltrick
TRICK_EXEC_LINK_LIBS += -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main -lpthread
# This is supposed to be a development hack so that I don't have to clean rebuild Trick every time I change the stl_checkpoint files.
# This should be deleted before it is merged into master.
STL_CHECKPOINT_FILES = checkpoint_pair.hh \
checkpoint_sequence_stl.hh \
checkpoint_map.hh \
checkpoint_queue.hh \
checkpoint_stack.hh
STL_CHECKPOINT_DEPS = $(addprefix $(TRICK_HOME)/include/trick/, $(STL_CHECKPOINT_FILES))
# All tests produced by this Makefile. Remember to add new tests you
# created to the list.
TESTS = MM_creation_unittest \
@ -37,7 +48,9 @@ TESTS = MM_creation_unittest \
MM_write_checkpoint_hexfloat \
MM_get_enumerated\
MM_ref_name_from_address \
Bitfield_tests
Bitfield_tests \
MM_stl_checkpoint \
MM_stl_restore
#OTHER_OBJECTS = ../../include/object_${TRICK_HOST_CPU}/io_JobData.o \
# ../../include/object_${TRICK_HOST_CPU}/io_SimObject.o
@ -65,6 +78,9 @@ test: $(TESTS)
./MM_get_enumerated --gtest_output=xml:${TRICK_HOME}/trick_test/MM_get_enumerated.xml
./MM_ref_name_from_address --gtest_output=xml:${TRICK_HOME}/trick_test/MM_ref_name_from_address.xml
./Bitfield_tests --gtest_output=xml:${TRICK_HOME}/trick_test/Bitfield_tests.xml
./MM_stl_checkpoint --gtest_output=xml:${TRICK_HOME}/trick_test/MM_stl_checkpoint.xml
./MM_stl_restore --gtest_output=xml:${TRICK_HOME}/trick_test/MM_stl_restore.xml
code-coverage: test
# Give rid of any old code-coverage HTML we may have.
@ -112,6 +128,10 @@ io_MM_ref_name_from_address.o : MM_ref_name_from_address.hh
${TRICK_HOME}/bin/trick-ICG -sim_services -o ./io_src $(TRICK_CPPFLAGS) $<
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c io_src/io_MM_ref_name_from_address.cpp
io_MM_stl_testbed.o : MM_stl_testbed.hh
${TRICK_HOME}/bin/trick-ICG -sim_services -o ./io_src $(TRICK_CPPFLAGS) $<
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c io_src/io_MM_stl_testbed.cpp
MM_creation_unittest.o : MM_creation_unittest.cc
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c $<
@ -166,6 +186,12 @@ MM_write_checkpoint_hexfloat.o : MM_write_checkpoint_hexfloat.cc
Bitfield_tests.o : Bitfield_tests.cpp
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c $<
MM_stl_restore.o : MM_stl_restore.cc MM_stl_testbed.hh MM_test.hh $(STL_CHECKPOINT_DEPS)
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c $<
MM_stl_checkpoint.o : MM_stl_checkpoint.cc MM_stl_testbed.hh MM_test.hh $(STL_CHECKPOINT_DEPS)
$(TRICK_CXX) $(TRICK_CPPFLAGS) -c $<
MM_creation_unittest : MM_creation_unittest.o
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
@ -219,3 +245,9 @@ MM_write_checkpoint_hexfloat : MM_write_checkpoint_hexfloat.o io_MM_write_checkp
Bitfield_tests : Bitfield_tests.o
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
MM_stl_restore : MM_stl_restore.o io_MM_stl_testbed.o
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
MM_stl_checkpoint : MM_stl_checkpoint.o io_MM_stl_testbed.o
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)