Merging master

This commit is contained in:
Pherring04 2024-07-16 15:54:55 -05:00
commit b8c3ed74fc
10 changed files with 205 additions and 36 deletions

View File

@ -16,14 +16,27 @@ S_main_${TRICK_HOST_CPU}.exe [trick_version] [sie]
[-u <user_defined_arguments>]
```
- The first argument in the command line must be the simulation input file name. The input file name can be in the form of a full path name but MUST have a RUN_<name> directory immediately above the input file name. By default, all the simulation output is directed to this RUN_<name> directory. The standard <input_file_name> is input.py; however, a simulation could be started from a checkpoint file by substituting chkpnt_<time> in for <input_file_name> for non-Master/Slave and non-Import/Export simulations. For Master/Slave and Import/Export simulations you must have the simulation running, and the simulation must be in a freeze state before reloading a checkpoint.
- The trick_version option will tell what version of Trick built the S_main executable.
- The sie option will generate the smart input editor (SIE) resource file (CP will by default invoke the S_main executable with the sie option to generate this file).
- The '-d' argument is optional and, if specified, starts the simulation in an input file verification mode. In this mode the entire input file is read, echoed to standard out, and then the simulation exits without calling any jobs listed in the S_define file. This mode helps debug input file syntax errors.
- The '-O <output_file_path>' option allows the user to specify the directory to which simulation data log files will be written. If this option is omitted, the RUN_<name> directory is used.
- The '-OO <output_file_path>' option allows the user to specify the directory to which ALL simulation output files will be written. If this option is omitted, the RUN_<name> directory is used.
- The '--read-only-sim' flag can be used to redirect all files written at simulation runtime into the output directory.
- The '-u' option specifies that all remaining arguments are meant to be used by user supplied jobs. All arguments after the -u can be accessed internal to the simulation jobs by calling the get_cmnd_args() function of the executive as illustrated below. In a master/slave simulation, the master's -u args will be passed to the slave.
- The first argument in the command line must be the simulation input file name. The input file name can be in the form of a full path name but MUST have a `RUN_<name>` directory immediately above the input file name. By default, all the simulation output is directed to this `RUN_<name>` directory. The standard `<input_file_name>` is input.py; however, a simulation could be started from a checkpoint file by substituting `chkpnt_<time>` in for `<input_file_name>` for non-Master/Slave and non-Import/Export simulations. For Master/Slave and Import/Export simulations you must have the simulation running, and the simulation must be in a freeze state before reloading a checkpoint.
- The `trick_version` option will tell what version of Trick built the S_main executable.
- The `sie` option will generate the smart input editor (SIE) resource file.
- The `-d` argument is optional and, if specified, starts the simulation in an input file verification mode. In this mode the entire input file is read, echoed to standard out, and then the simulation exits without calling any jobs listed in the S_define file. This mode helps debug input file syntax errors.
- The `-O <output_file_path>` option allows the user to specify the directory to which simulation data log files will be written. If this option is omitted, the `RUN_<name>` directory is used.
- Data Products specification DP_xxx.xml files if generated such as for frame logging are saved in `DP_Product` directory.
- The `-OO <output_file_path>` option allows the user to specify the directory to which ALL simulation output files will be written. If this option is omitted, the `RUN_<name>` directory is used.
- Two subdirectories are automatically created in the designated `<output_file_path>`:
- `DP_Product`
- Data Products sepcification DP_xxx.xml files are saved in this folder.
- `RUN_<name>`
- All simulation output files, excluding DP_xxx.xml files, are saved in this folder. Additionally, the S_sie.resource file is copied to this directory.
- The `--read-only-sim` flag can be used to redirect all files written at simulation runtime into the output directory.
- The `--read-only-sim` flag requires either the `-O` or `-OO` option to be used.
- When the `-O <output_file_path>` option is used and `trick.trick.sie_append_runtime_objs()` is called from the input file, the S_sie.resource file with appended runtime objects is saved in `<output_file_path>`.
- When the `-OO <output_file_path>` option is used and `trick.trick.sie_append_runtime_objs()` is called from the input file, the S_sie.resource file with runtime objects appended is saved in `<output_file_path>/RUN_<name>`.
- If `trick.trick.sie_append_runtime_objs()` is called from the input file, the S_sie.resource file is to be appended with runtime objects.
- When neither the `-O` nor `-OO` option is used, the S_sie.resource file with runtime objects appended is saved in the current directory from which the simulation is executed.
- When the `-O <output_file_path>` option is used without the `--read-only-sim` flag, the S_sie.resource file with runtime objects appended is saved in the current directory from which the simulation is executed.
- When the `-OO <output_file_path>` option is used without the `--read-only-sim` flag, the S_sie.resource file with runtime objects appended is saved in `<output_file_path>/RUN_<name>`.
- The `-u` option specifies that all remaining arguments are meant to be used by user supplied jobs. All arguments after the -u can be accessed internal to the simulation jobs by calling the get_cmnd_args() function of the executive as illustrated below. In a master/slave simulation, the master's `-u` args will be passed to the slave.
The following code example shows how a function can access the command line arguments during execution.

View File

@ -97,7 +97,7 @@ my $template_def = qr/template\s* # keyword template
\s+[_A-Za-z]\w*\s* # class name
/sx ;
my $template_var_def = qr/(?:\:\:)?[_A-Za-z][:\w]*\s* # template name
<[\w\s\*,:<>]*>\s* # template parameters
<[\w\s\*,:<>\[\]]*>\s* # template parameters
[_A-Za-z]\w*\s*(?:[{=].*?)?; # var name ;
/sx ;
@ -337,6 +337,24 @@ sub process_file() {
print OUT "\n$new_contents" ;
print OUT "$contents\n" ;
print OUT $global_template_typedefs ;
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper non-class attribute assingment in input processor.
# _swig_setattr_nondynamic_instance_variable function is added for each class in process_class subroutine.
foreach my $c ( @class_names ) {
if ( ! exists $class_typemap_printed{$c} ) {
my $c_ = $c ;
$c_ =~ s/\:/_/g ;
if ( $c !~ /::/ ) {
print OUT "\n#if SWIG_VERSION > 0x040000\n";
print OUT "%pythoncode %{\n" ;
print OUT " if '$c' in globals():\n";
print OUT " $c.__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n" ;
print OUT "%}\n" ;
print OUT "#endif\n";
}
}
}
# Add a trick_cast_as macro line for each class parsed in the file. These lines must appear at the bottom of the
# file to ensure they are not in a namespace directive and they are after the #define statements they depend on.
undef %class_typemap_printed ;
@ -479,6 +497,9 @@ sub process_template($$) {
my ( $contents_ref , $new_contents_ref ) = @_ ;
my $extracted ;
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
# The function call is inserted after the 1st { of the class template so it is placed at the top
$$contents_ref=~s/{\n/{\n\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n/m;
if ( $$contents_ref =~ s/^(\s*;)//s ) {
$$new_contents_ref .= $1 ;
} else {
@ -603,6 +624,9 @@ sub process_class($$$$$) {
$my_class_contents .= $1 ;
}
# Add _swig_setattr_nondynamic_instance_variable function for raising AttributeError for improper class attribute assingment in input processor
$my_class_content .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
# remove the trailing semicolon because we may append text to the class.
@ -613,6 +637,15 @@ sub process_class($$$$$) {
#print "*** extracted = $extracted ***\n" ;
#print "*** contents = $$contents_ref ***\n" ;
my $save_namespace_content;
if ( $curr_namespace ne "" ) {
my @split_namespaces = split "::", $curr_namespace;
my $sanitized_namespace = $split_namespaces[-1] ;
my @namespace_split = split /namespace\s*$sanitized_namespace/, $$new_contents_ref;
$save_namespace_content = 'namespace ' . $sanitized_namespace . $namespace_split[-1];
$$new_contents_ref = join('namespace ' . $sanitized_namespace, @namespace_split[0 .. $#namespace_split-1]);
}
# SWIG doesn't like "const static". Change it to "static const"
$extracted =~ s/const\s+static/static const/g ;
@ -668,6 +701,10 @@ sub process_class($$$$$) {
my ($template_type_no_sp) = $template_full_type ;
$template_type_no_sp =~ s/\s//g ;
# If the type is qualified, assume it's fully qualified and put the
# %template directive in the global namespace.
# See https://github.com/nasa/trick/issues/768
my $qualified = $template_type_no_sp =~ /^\w+(::)\w+</ ;
#print "*** template_type_no_sp = $template_type_no_sp ***\n" ;
if ( ! exists $processed_templates{$template_type_no_sp} ) {
@ -703,6 +740,7 @@ sub process_class($$$$$) {
$processed_templates{$template_type_no_sp} = 1 ;
}
}
$class_content .= $template_var_def_str ;
}
}
}
@ -758,7 +796,7 @@ sub process_typedef_struct($$$$) {
my ($typedef_struct_string , $contents_ref, $new_contents_ref , $class_names_ref) = @_ ;
my $extracted ;
my ($begin, $tail , $struct_names, @struct_names) ;
my ($tail , $struct_names, @struct_names) ;
#print "*** typedef_struct_string = $typedef_struct_string ***\n" ;
@ -767,7 +805,6 @@ sub process_typedef_struct($$$$) {
$typedef_struct_string =~ s/((?:typedef\s+)?(struct|union)\s* # the words typedef struct|union
([_A-Za-z]\w*)?\s* # optional name
{)//sx ;
$begin = $3 ;
($extracted, $$contents_ref) = extract_bracketed( "{" . $$contents_ref , "{}") ;
#print "*** extracted = $extracted ***\n" ;
@ -782,9 +819,6 @@ sub process_typedef_struct($$$$) {
$struct_names =~ s/\s//g ;
@struct_names = split /,/ , $struct_names ;
if ( $begin ne "" ) {
push @$class_names_ref , $begin ;
}
foreach my $s ( @struct_names ) {
if ( $s !~ /\*/ ) {
push @$class_names_ref , $s ;

View File

@ -9,8 +9,25 @@ LIBRARY DEPENDENCIES:
#include "sim_objects/default_trick_sys.sm"
##include "test_ip/include/ClassOfEverything.hh"
##include "test_ip/include/ArrayTemplate.hh"
##include "test_ip/include/OverloadedVariable.hh"
class ArrayTemplateSimObject : public Trick::SimObject
{
public:
ArrayTemplateSimObject(const ArrayTemplateSimObject&) = delete;
ArrayTemplateSimObject& operator=(const ArrayTemplateSimObject&) = delete;
double a[3];
ArrayTemplate<double[3]> arryTemp;
ArrayTemplateSimObject()
: arryTemp(a)
{
}
};
ArrayTemplateSimObject arry_temp_object;
class testSimObject : public Trick::SimObject {
public:

View File

@ -0,0 +1,37 @@
/**
@file
@verbatim
PURPOSE:
(Test if we can build with arrays as template parameters)
@endverbatim
*******************************************************************************/
#ifndef ARRAY_TEMPLATE_TESTS_HH
#define ARRAY_TEMPLATE_TESTS_HH
// System include files.
#include <string>
#include <iostream>
#include <sstream>
template <class SourceType>
class ArrayTemplate
{
public:
ArrayTemplate(const SourceType& source)
: source(source)
{
}
ArrayTemplate(const ArrayTemplate&) = delete;
ArrayTemplate& operator=(const ArrayTemplate&) = delete;
private:
const SourceType& source;
};
#endif

View File

@ -304,7 +304,7 @@ SIM_test_output_dir:
RUN_test/input.py -OO sim_output --read-only-sim:
returns: 0
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_compiletime_S_sie.resource test/SIM_test_output_dir/S_sie.resource'
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_runtime_S_sie.resource test/SIM_test_output_dir/sim_output/S_sie.resource'
analyze: 'python3 test/SIM_test_output_dir/ref_files/check_file_endings.py test/SIM_test_output_dir/ref_files/ref_runtime_S_sie.resource test/SIM_test_output_dir/sim_output/RUN_test/S_sie.resource'
# The variable server client and SIM_amoeba sometimes fail to connect and need to be retried

View File

@ -253,8 +253,9 @@ int Trick::CommandLineArguments::process_sim_args(int nargs , char **args) {
}
/* Output data directory */
output_dir = user_output_dir = argv[++ii];
if (!strncmp("-OO", argv[ii-1], (size_t) 3)) {
output_dir = output_dir + "/" + run_dir;
}
}
}

View File

@ -713,6 +713,11 @@ int Trick::FrameLog::create_DP_files() {
int Trick::FrameLog::create_DP_Product_dir() {
int ret=0;
DP_dir = "DP_Product";
if (std::string(command_line_args_get_user_output_dir()) != std::string(command_line_args_get_output_dir())) {
if (!std::string(command_line_args_get_user_output_dir()).empty()) {
DP_dir = std::string(command_line_args_get_user_output_dir()) + "/DP_Product";
}
}
ret = mkdir(DP_dir.c_str(), 0777);
if (ret == -1) {
if (errno == EEXIST) {

View File

@ -27,6 +27,26 @@ Trick::Sie::Sie() {
the_sie = this ;
}
void copy_file (const std::string& original_filename, const std::string& copy_filename) {
std::ifstream original;
std::ofstream copy;
original.open(original_filename.c_str(), std::ios::binary);
copy.open(copy_filename.c_str(), std::ios::binary);
copy << original.rdbuf();
original.close();
copy.close();
}
// Helper function for copying S_sie.resource from default dir to output dir
void copy_sie_resource() {
std::string original_sie_filename = std::string(command_line_args_get_default_dir()) + "/" + "S_sie.resource";
std::string copy_sie_filename = std::string(command_line_args_get_output_dir()) + "/" + "S_sie.resource";
copy_file(original_sie_filename, copy_sie_filename);
}
int Trick::Sie::process_sim_args() {
int argc ;
@ -46,13 +66,38 @@ int Trick::Sie::process_sim_args() {
exit(0) ;
}
bool read_only = false;
bool oo_dir = false;
bool o_dir = false;
// Otherwise, go through the rest of the sim args and look for --read-only-sim
for (int i = 1; i < argc; i++) {
if (strcmp("--read-only-sim", argv[i]) == 0) {
if ((strcmp("--read-only-sim", argv[i]) == 0)) {
// Set this flag to move runtime generation of sie into the output directory
move_runtime_generation = true;
read_only = true;
break;
}
}
// Set oo_dir and o_dir flags accordingly
for (int i = 1; i < argc; i++) {
if (strncmp("-OO", argv[i], (size_t) 3) == 0) {
oo_dir = true;
} else if (strncmp("-O", argv[i], (size_t) 2) == 0) {
o_dir = true;
}
}
// If --read-only-sim is provided without either -OO or -O, exit with error message
// For -OO, save S_sie.resource to the output directory with runtime jobs data
if (read_only && !oo_dir && !o_dir) {
std::cerr << "\nERROR: Missing -O or -OO argument with --read-only-sim flag" << std::endl;
exit(1);
} else if (oo_dir) {
copy_sie_resource();
move_runtime_generation = true;
}
}
return(0) ;
@ -158,26 +203,11 @@ void Trick::Sie::sie_print_xml() {
sie_out.close() ;
}
void copy_file (const std::string& original_filename, const std::string& copy_filename) {
std::ifstream original;
std::ofstream copy;
original.open(original_filename.c_str(), std::ios::binary);
copy.open(copy_filename.c_str(), std::ios::binary);
copy << original.rdbuf();
original.close();
copy.close();
}
void Trick::Sie::sie_append_runtime_objs() {
std::fstream sie_out ;
if (move_runtime_generation) {
std::string original_sie_filename = std::string(command_line_args_get_default_dir()) + "/" + "S_sie.resource" ;
std::string copy_sie_filename = std::string(command_line_args_get_output_dir()) + "/" + "S_sie.resource" ;
copy_file(original_sie_filename, copy_sie_filename);
copy_sie_resource();
}
std::string sie_filename = get_runtime_sie_dir() + "/" + "S_sie.resource" ;
@ -223,9 +253,9 @@ void Trick::Sie::sie_append_runtime_objs() {
std::string Trick::Sie::get_runtime_sie_dir() {
if (move_runtime_generation) {
return std::string(command_line_args_get_output_dir()) ;
return std::string(command_line_args_get_output_dir());
} else {
return std::string(command_line_args_get_default_dir()) ;
return std::string(command_line_args_get_default_dir());
}
}

View File

@ -66,3 +66,19 @@ class swig_double {
PyObject * __len__() ;
} ;
%pythoncode %{
#if SWIG_VERSION > 0x040000
def _trick_setattr_nondynamic_instance_variable(set):
def set_instance_attr(self, name, value):
if name == "thisown":
self.this.own(value)
elif name == "this":
set(self, name, value)
else:
msg = f'You cannot add instance attribute \'{name}\' to Trick swig_double'
raise AttributeError(msg)
return set_instance_attr
swig_double.__setattr__ = _trick_setattr_nondynamic_instance_variable(object.__setattr__)
#endif
%}

View File

@ -89,3 +89,19 @@ class swig_int {
PyObject * __bool__() ;
} ;
%pythoncode %{
#if SWIG_VERSION > 0x040000
def _trick_setattr_nondynamic_instance_variable(set):
def set_instance_attr(self, name, value):
if name == "thisown":
self.this.own(value)
elif name == "this":
set(self, name, value)
else:
msg = f'You cannot add instance attribute \'{name}\' to Trick swig_int'
raise AttributeError(msg)
return set_instance_attr
swig_int.__setattr__ = _trick_setattr_nondynamic_instance_variable(object.__setattr__)
#endif
%}