Remove doxygen documentation now housed on wiki #189

moved all of the design documentation to the wiki
This commit is contained in:
Alex Lin 2016-08-02 17:50:49 -05:00
parent 6848e31ddc
commit 89fda63293
18 changed files with 0 additions and 1842 deletions

View File

@ -1,7 +0,0 @@
/**
@page LEVEL1 Building a Simulation
*/

View File

@ -1,354 +0,0 @@
/**
@page LEVEL2 convert_swig
The purpose of convert_swig is to create SWIG interface files for the given
C/C++ header file (usually S_source.hh) and each of the header files that it
(recursively) includes. SWIG (Simplified Wrapper and Interface Generator) is
an interface compiler that connects programs written in C and C++ with scripting
languagues such as Perl and Python.
@dot
digraph Call_Graph {
convert_swig -> process_file
process_file -> abs_path
process_file -> base_name
process_file -> dirname
process_file -> process_contents
process_file -> md5hex
process_contents -> process_typedef_struct
process_contents -> process_namespace
process_contents -> process_class
process_namespace -> extract_bracketed
process_namespace -> process_contents
process_class -> extract_bracketed
process_typedef_struct -> extract_bracketed
}
@enddot
In Trick the list of header files to be processed is usually produced by the script
make_swig_makefile.pm, as it's creating Makefile_swig. This list is stored in
the file ".S_library_swig". So, if .S_library_swig exists, we can just open and read it.
Otherwise we need to process S_source.hh to produce the list of header files.
Specifically, we want to generate SWIG interfaces for those header files that are:
\li 1) actual dependencies of S_source.hh, GIVEN THE CURRENT environment and
\li 2) not excluded from ICG processing ( by ICG_NO or ICG_EXCLUDE).
The header files that are actually included are the dependencies we care
about. Keep in mind that the pre-processor and the current ENVIRONMENT
may cause some headers to be conditionally included or excluded. We only
want to generate SWIG interfaces for headers that are ACTUALLY included.
Whereas the pre-processor can (using the gcc -MM option) generate a list
of dependencies that satisfy 1) (above), it can't handle that ICG exclusions.
And, whereas the function get_headers() can generate a list of dependences
which are flagged if they contain ICG_NO, it doesn't handle conditional includes.
So, the strategy that we employ is to generate and then find the
intersection of both lists. Then we eliminate those that are in 1)
$TRICK_HOME/trick_source, or 2) flagged as containing ICG_NO or 3) are
in ICG_EXCLUDE'd directories.
First, create a list headers using the GCC with the -MM option. GCC will
handle conditional inclusion.
Second, create a list where the files are flagged if they contain ICG_NO.
Then we generate the intersection of the two lists and then eliminate the dependencies that:
\li 1) are in $TRICK_HOME/trick_source.
\li 2) contain ICG_NO.
\li 3) are in ICG_EXCLUDE'd directories.
to create the final list of header dependencies that we need to convert into SWIG interfaces.
Next we need to determine which of the files do not have up-to-date SWIG files.
For each header file in final dependency list, if the corresponding SWIG (.i) file
doesn't exist or the header file is newer than the existing SWIG file, then record
that a new SWIG file needs needs to be created. The global hash %out_of_date
represents a list of header files whose corresponding .i files need to be regenerated.
Finally, call process_file() to create SWIG interface files for each of the out_of_date headers.
@section LEVEL3 process_file
@subsection LEVEL4 Synopsis
This subroutine processes S_source.h and each of it's requisite header files to
generate the corresponding SWIG interfaces files.
@subsection LEVEL4 Parameters
<b>sim_ref</b> Is this parameter ever used?
<b>in_file</b> The name of input file, invariably "S_source.hh".
@subsection LEVEL4 Design
This function first reads the contents of <in_file> and each of the header files
that it (recursively) includes into a hash (%file_contents), keyed by the
corresponding filenames. It then converts the contents of the each header whose
corresponding SWIG interface file is out of date into a SWIG interface file.
@subsubsection LEVEL5 "Creating the %file_contents hash"
To create the file_contents hash, we first run the input file through the
C/C++ pre-processor with the -dI option. This creates <b>one</b> file containing
the contents of all of the included header files delimited by "line markers".
The line markers indicate which header file each of content came from.
Preprocessor line markers are of the form: '#' <linenum> <filename> <flags>
They are described in Chapter 9, "Preprocessor Output" of the GCC document,
"Preprocessor Output - The C Preprocessor". Whether in_file is run through
the C or C++ preprocessor depends on its name suffix.
For each line in the ONE big file, check whether it's a linemarker or not.
if it's a linemarker ( telling us where the following content is from)
extract the header filename. This will be our current filecontents hash key.
If it's not a linemarker, then it must be content. So, append it to the string,
whose key is the current file name ($curr_name).
@subsubsection LEVEL5 "Creating SWIG interface files"
The global hash <i>\%out_of_date</i> represents the list of header files whose
corresponding SWIG interface files are out of date. It is generated in the main
part of the convert_swig program.
For each of these out of date header files, we generate a SWIG interface file
from the contents stored in the <i>\%file_contents</i> hash.
First we remove the friend init_attr functions from the headers content.
They don't need to be wrapped.
Then, for each of the #includes in the out_of_date header file
create a corresponding %import directive.
Next, we generate a module name and path for the SWIG interface file. The module
name is generated from an md5 hash of the header file's full name.
Finally we open the SWIG interface file, and in it we:
\li write a %module directive that identifies the module.
\li write a #include directive to include trick_swig interface utilities.
\li write a #include directive to include the header file to which this
interface file corresponds and from which it was derived.
\li create a SWIG interface for each class declared in the corresponding
header file using the %trick_swig_class_typemap() macro. This macro is
defined in swig_class_typedef.i, included by trick_swig.i (see above).
\li Write the SWIG interface code (processed header file) and the header
file contents.
@section LEVEL3 process_contents
@subsection LEVEL4 Synopsis
Process header file contents for use in the corresponding SWIG interface file.
@subsection LEVEL4 Parameters
<b>contents_ref</b>
(IN) reference to header file contents that are to be converted to a SWIG interface.
<b>new_contents_ref</b>
(OUT) SWIG interface code, derived from the header file contents.
<b>curr_namespace</b>
(IN) current namespace.
<b>class_names_ref</b>
(OUT) reference to an array of class and/or struct names encountered when
processing the header file contents.
<b>template_typedefs_ref</b>
(OUT) Series of SWIG %template directives. %template directives create a type in
the target language that corresponds to a C++ template instance.
@subsection LEVEL4 Description
While there's header file content remaining to be processed, repeatedly make the
best match with the following available patterns:
Case of :<br>
<b>typedef</b> <i>existing-type-name new-type-name</i> <b>';'</b><br>
Concatenate the matched text to the SWIG interface text.
Case of :<br>
<b>typedef enum</b> <i>optional-name</i> <b>'{'</b> <i>bracketed-content</i> <b>'}'</b> <i>enum-name</i><b>';'</b><br>
Concatenate the matched text to the SWIG interface text.
Case of :<br>
<b>typedef</b> ( <b>struct</b> | <b>union</b> ) <i>name</i> <b>'{'</b><br>
Call process_typedef_struct() to process the matched text and the bracketed
content of the struct that follows in the header file contents and update the
SWIG interface text accordingly.
Case of :<br>
<b>template '<'</b> <i>template-parameters</i> <b>'>' class</b> <i>class-name</i><br>
then just concatenate the matched text to the SWIG interface text.
Case of:<br>
<b>namespace</b> <i>name</i><br>
then call <i>process_namespace()</i> to process the matched text and the
bracketed content that follows in the header file contents and update the the
SWIG interface text accordingly.
Case of:<br>
( <b>class</b> | <b>struct</b> ) <i>class-name</i> ( <b>'{'</b> | <b>':'</b> )<br>
Call <i>process_class()</i> to process the matched text and the bracketed
that follows in the header file contents and update the the SWIG interface text.
Default:
Match anything that doesn't match the other patterns and concatenate it to the
to the SWIG interface text. Note that (in Perl) <b>*?</b> in the regular
expression <b>(.*?)</b> is a non-greedy quantifier, so it gobbles up text only
until another match can be made.
@section LEVEL3 process_namespace
@subsection LEVEL4 Synopsis
Process namespaces found in a header file for use in the corresponding SWIG
interface file.
@subsection LEVEL4 Parameters
<b>namespace_string</b>
(IN) This is a string of the form: <b>namespace</b> <i>name</i>, that was
extracted from the header file contents. In the contents there should remain the bracketed
content to which this namespace applies.
<b>contents_ref</b>
(IN) This is a reference to the remainder of the header file (following the
above string) to be processed.
<b>new_contents_ref</b>
(OUT) The SWIG code generated so far.
<b>curr_namespace</b>
(IN) current namespace.
<b>class_names_ref</b>
(OUT) reference to an array of class and/or struct names encountered when
processing the header file contents.
<b>template_typedefs_ref</b>
(OUT) Series of SWIG %template directives. %template directives create a type
in the target language that corresponds to a C++ template instance.
@subsection LEVEL4 Description
Extract the name from the <b>namespace_string</b> and append it to the current namespace's name.
Add the <b>namespace_string</b> to the SWIG interface text.
Call extract_bracketed() to extract the contents of the namespace from the header text.
Call process_contents() to convert the extracted namespace contents to a SWIG interface.
Append whatever wasn't matched in process contents to the SWIG interface text.
@section LEVEL3 process_class
@subsection LEVEL4 Synopsis
Process classes declarations found in a header file for use in the corresponding
SWIG interface file.
@subsection LEVEL4 Parameters
<b>class_string</b>
(IN) This is a string of the form:<br>
\li ( <b>class</b> | <b>struct</b> ) <i>class-name</i> ( <b>'{'</b> | <b>':'</b> )<br>
<b>contents_ref</b>
(IN) This is a reference to the remainder of the header file (following the
class_string) to be processed.
<b>new_contents_ref</b>
(OUT) The SWIG code generated so far.
<b>curr_namespace</b>
(IN) current namespace.
<b>class_names_ref</b>
(OUT) reference to an array of class and/or struct names encountered when
processing the header file contents.
<b>template_typedefs_ref</b>
(OUT) Series of SWIG %template directives. %template directives create a type
in the target language that corresponds to a C++ template instance.
@subsection LEVEL4 Description
process_class() processes class declarations with the following steps:
\li Extract the class_name from the class_string.
Add the <b>class_string</b> to the SWIG interface text.
\li Call <b>extract_bracketed()</b> to extract the class contents between '{' and '}'.
\li While there's class content text remaining to be processed,
repeatedly search for data members that match : <b>template_name '<'</b> <i>template-params</i> <b>'>' name ;</b>
For each match, create a SWIG %template directive to create an instanciation
of the specific templated type used by the data member. Add the
SWIG %template directive to the templated typedefs string that
Otherwise append whatever wasn't matched in process contents to
the SWIG interface text.
@section LEVEL3 process_typedef_struct
@subsection LEVEL4 Synopsis
Process a type definition of a struct or union to make it suitable as SWIG
interface code. Extract the struct (or union) name and bracketed contents from
the header file text (typedef_struct_string and contents_ref) . Record the
extracted names in the list referenced by class_names_ref, and then reconsistute
the type definition, via the new_contents_ref.
@subsection LEVEL4 Parameters
<b>typedef_struct_string</b>
(IN) This is a string of the form:<br>
\li <b>typedef struct</b> [ <i>optional-name</i> ] <b>"{"</b> OR<br>
\li <b>typedef union</b> [ <i>optional-name</i> ] <b>"{"</b><br>
<b>contents_ref</b>
(IN) This is a reference to the remainder of the header file (following the
above string) to be processed.
<b>new_contents_ref</b>
(OUT) The SWIG interface code generated so far.
<b>class_names_ref</b>
(OUT) reference to an array of class and/or struct names encountered when
processing the header file contents.
@subsection LEVEL4 Description
process_typedef_struct() processes a type definition of a struct or union
with the following steps:
\li Append the <b>typedef_struct_string</b> to the SWIG interface text
(via <b>new_contents_ref</b>).
\li Extract the optional-name from the typedef_struct_string.
\li Call extract_bracketed() to extract the struct contents from the header
text (via <b>contents_ref</b>), including the right bracket.
\li Extract the one or more typedef'ed names followed by a semi-colon, that
should still be in the header text.
\li Push the optional-name and the typedef'ed names into the class_names list
(via <b>class_names_ref</b>).
\li Append the bracketed struct contents and the one or more typedef'ed names
and the semi-colon that we just extracted to the SWIG interface text.
*/

View File

@ -1,17 +0,0 @@
/**
@page LEVEL1 Data Products
@section LEVEL2 Data
@section LEVEL2 DP Specification Files
@section LEVEL2 Session Files
@section LEVEL2 Overall Architecture
@section LEVEL2 Class Architecture
*/

View File

@ -1,17 +0,0 @@
/**
@page LEVEL1 Introduction
@section LEVEL2 Scope
@section LEVEL2 Concept
@section LEVEL2 Developer/Trick Interface
@section LEVEL2 Simulation Executable and Input/Output
@section LEVEL2 Developer/Data Interface
@section LEVEL2 Communicating With External Processes or Devices
*/

View File

@ -1,45 +0,0 @@
/**
@page design Trick Design
@subpage d01 "1 Introduction"<br>
@subpage d02 "2 Building a Simulation"<br>
@subpage d0201 "2.1 Interface Code Generator"<br>
@subpage d0202 "2.2 Convert Swig"<br>
@subpage d03 "3 Running a Simulation"<br>
@subpage d0301 "3.1 Simulation Executive"<br>
@subpage d0302 "3.2 Scheduled Job Queue"<br>
@subpage d0303 "3.3 Real-Time Synchronization"<br>
@subpage d0304 "3.4 Real-Time Clock"<br>
@subpage d0305 "3.5 Sleep Timer"<br>
@subpage d0306 "3.6 Data Recording"<br>
@subpage d0307 "3.7 Command Line Arguments"<br>
@subpage d0308 "3.8 Monte Carlo and Optimization"<br>
@subpage d0309 "3.9 Integrator"<br>
@subpage d04 "4 Data Products"<br>
*/
// section 1
#include "introduction.dox_in"
// section 2
#include "build_sim.dox_in"
#include "codegen/Interface_Code_Gen/design.dox_in"
#include "convert_swig.dox_in"
// section 3
#include "run_sim.dox_in"
#include "sim_services/Executive/docs/design.dox_in"
#include "sim_services/ScheduledJobQueue/design.dox_in"
#include "sim_services/RealtimeSync/docs/design.dox_in"
#include "sim_services/Clock/docs/design.dox_in"
#include "sim_services/Timer/docs/design.dox_in"
#include "sim_services/DataRecord/docs/design.dox_in"
#include "sim_services/CommandLineArguments/docs/design.dox_in"
#include "sim_services/MonteCarlo/docs/design.dox_in"
#include "sim_services/Integrator/design.dox_in"
// section 4
#include "data_products.dox_in"

View File

@ -1,6 +0,0 @@
/**
@page LEVEL1 Running a Simulation
*/

View File

@ -1,109 +0,0 @@
/**
@page LEVEL2 Interface Code Generator Design
The Interface Code Generator (ICG) creates class/struct layout information, called
attributes, used to convert string variable names to simulation memory
addresses. The attributes are used with several of Trick's services
including checkpointing, data recording, and the variable server.
ICG execution is divided into 2 parts.
-# Executing the Clang C++ frontend to parse all header files and extract
class/struct information.
-# Print class/struct information as attributes in input/output source code.
@section LEVEL3 Clang C++ Frontend
ICG uses the Clang frontend. Clang is a C/C++ frontend to the LLVM compiler.
Clang and LLVM provide libraries that allow developers to create their own tools
using the compiler. ICG calls the clang parser to process the header
files and converts the source text into a tree form called an abstract syntax tree
(AST). Clang completely handles all textual parsing. ICG provides classes to
provide input parameters to the compiler and to extract the information out of the
AST.
@section LEVEL4 Parser Setup
The frontend has some parameters that must be set in order for the parser to
execute.
@section LEVEL5 Parsing Language
The S_source.hh file where parsing begins is written in C++. The frontend is set to
parse C++.
@section LEVEL5 Target Architecture
The frontend requires a target architecture set. ICG does not pass the AST to the
next stage of compiler tools after the frontend, so it doesn't matter what the
target architecture is set to. Setting the target to the the default architecture
works.
@section LEVEL4 Preprocessor
The frontend includes a preprocessor. The preprocessor handles include and define
statements. ICG provides a pair of classes that interact with the clang preprocesor.
The HeaderSearchDirs class to provide the preprocessor with include search
directories and default defines. The CommentSaver class saves all comments parsed
by the preprocessor. These classes are used throughout the rest of ICG execution.
@section LEVEL5 HeaderSearchDirs
The HeaderSearchDirs manages the header search directories used by the preprocessor
and provides an interface for querying the inclusion status of a directory. Since
this class is closely related to the preprocessor, it also handles define macros.
The HeaderSearchDirs class provides a list of include search directories to the
clang preprocessor. There are two types of include directories, system include
directories and user provided directories. Both types must be supplied to the
preprocessor.
The system include directories are retrieved by running the TRICK_CPPC compiler
in verbose preprocessor mode with no input code. When the compiler is run
in this mode, it prints the system include directories built into the compiler.
This class parses that output for the system include directories and feeds the
list into the preprocessor.
The user include directories are retrieved from the command line when executing
ICG. Typically ICG is called with the TRICK_CXXFLAGS environment variable
included as an argument. TRICK_CXXFLAGS may include -I<include_dir> strings.
These include directories are parsed from the command line and fed to the
preprocessor.
This class parses the TRICK_ICG_EXCLUDE environment variable and manages a list
of directories ICG should not write any output source code.
The HeaderSearchDirs class provides boolean responses to questions to whether a
path is in a user directory or is in an TRICK_ICG_EXCLUDE directory.
@section LEVEL5 CommentSaver
The CommentSaver class saves comments found in user code and provides an iterface
for retrieving comments based on file name/line number. The class also provides
an interface to retrieving several fields from a Trick header comment including
the ICG and ICG_EXCLUDE_TYPES fields.
The clang preprocessor includes a comment handler interface. ICG uses
this interface to attach the CommentSaver class. Each comment handled by this
class is stored in a map indexed by file name and line number.
@section LEVEL4 Abstract Syntax Tree (AST) Traversal
Traversing the resulting AST is bulk of ICG's work. The clang compiler provides
an interface allowing ICG to attach handlers to process interesting events during
code parsing. In this case, ICG only attaches a handler when clang is finished
parsing the entire input file, called HandleTranslationUnit.
When HandleTranslationUnit is start parsing the AST searching for top level
declarations we want to process. From the top level recursively calls
tree parsers that specialize in extracting information about typedefs,
classes and structs, fields within each class/struct, and enumerations.
The following diagram shows the recursive class instantiation sequence as well
as the data returned to the caller.
@section LEVEL3 Writing Class/Struct Attributes
*/

View File

@ -1,50 +0,0 @@
/**
@page LEVEL2 Real-Time Clock Design
@section LEVEL3 Base Real-Time Clock
The base Clock object provides an interface for the following operations. The
base Clock does not implement the following operations.
-# Initializing the clock hardware
-# Resetting the clock (setting the reference time)
-# Getting the current real time
-# Spinning on the clock<br>
Spinning on the clock means to continually check the clock waiting for real-time to
catch up to the desired simulation elapsed time.
-# Stopping the clock
@section LEVEL3 Gettimeofday Clock
The GetTimeOfDayClock is a clock object that derives from the the Base Real-Time Clock. The
GetTimeOfDayClock uses system clock as the real-time clock.
The GetTimeOfDayClock implements the interface laid out by the base clock class
@section LEVEL4 Initializing the Clock
@copydetails Trick::GetTimeOfDayClock::clock_init()
Trick::GetTimeOfDayClock::clock_init()
@section LEVEL4 Resetting the Clock (setting the reference time)
@copydetails Trick::GetTimeOfDayClock::clock_reset()
Trick::GetTimeOfDayClock::clock_reset()
@section LEVEL4 Getting the Current Real Time
@copydetails Trick::GetTimeOfDayClock::clock_time()
Trick::GetTimeOfDayClock::clock_time()
@section LEVEL4 Spinning on the Clock
@copydetails Trick::GetTimeOfDayClock::clock_spin()
Trick::GetTimeOfDayClock::clock_spin()
@section LEVEL4 Stopping the Clock
@copydetails Trick::GetTimeOfDayClock::clock_stop()
Trick::GetTimeOfDayClock::clock_stop()
*/

View File

@ -1,32 +0,0 @@
/**
@page LEVEL2 Command Line Arguments Design
@section LEVEL3 Processing the Command Line Arguments
The main routine of the Command Line Arguments object is called by the
main program and the command line arguments of the main program are sent in
to the routine. This routine copies the command line arguments and saves
them for all of the other Trick core classes to use. It also processes the
command line arguments to retrieve to output_dir, the input_file, the
default_dir, and the cmdline_name.
@copydetails Trick::CommandLineArguments::process_sim_args(int nargs , char **args)
Trick::CommandLineArguments::process_sim_args(int nargs , char **args)
@section LEVEL3 Timestamping the Output Directory
Before Simulation Initialization is complete the user may choose to
timestamp the output directory.
@copydetails Trick::CommandLineArguments::output_dir_timestamed_on()
Trick::CommandLineArguments::output_dir_timestamed_on()
@section LEVEL3 Removing Timestamping the Output Directory
@copydetails Trick::CommandLineArguments::output_dir_timestamed_off()
Trick::CommandLineArguments::output_dir_timestamed_off()
*/

View File

@ -1,290 +0,0 @@
/**
@page LEVEL2 Data Recording Design
The data recording design consists of 3 object types working together. At the bottom
level are the data recording groups. The data recording groups contain the user
specified variables to record, the frequency and the format to write the data in.
Each data recording group is associated with a buffering technique object. These objects
determine when the data recording groups write their data. Finally at the top is the
data recording dispatcher. The dispatcher holds the list of all the buffering techniques
and serves as a single calling point for the simulation executive to fire off all
data recording group activities.
@section LEVEL3 DataRecordGroup
The first objects are a set of DataRecordGroups. The DataRecordGroups are
responsible for copying simulation data into a temporary memory buffer
while the simulation is running. The DataRecordGroups also are responsible
for formatting the simulation data into a recording format.
A base DataRecordGroup object provides functions common to all recording
groups and provides an interface for the specific recording formats to follow.
The base DataRecordGroup derives from the SimObject class. This allows
new data recording groups to be added and removed from the scheduler as
other SimObjects.
The base class provides the following common functions:
-# Common initialization of a data record group.
-# Common copying of simulation data to memory buffers.
The base class provides function definitions for the specific formats to define:
-# Format specific initialization
-# Format specific write data from memory buffer to disk
-# Format specific shutdown of data recording files.
@section LEVEL4 DataRecordGroup Common Initialization
Initialization of a DataRecord group is handled in three phases.
The first is during the construction of the object. New data recording group
objects are typically created within the run input file read in during simulation
initialization.
@copydetails Trick::DataRecordGroup::DataRecordGroup(string)
Trick::DataRecordGroup::DataRecordGroup(string)
The second part of a DataRecordGroup initialization is supplied by the user.
The user typically sets these in the run input file read in during simulation
initialization. Typicically the user will:
-# Add variables to be recorded.
-# Add variables to be added to the changes watch list.
-# Assign a different recording frequency.
-# Change the amount of memory data record is to allocate for memory buffers
The third part of initialization occurs at the end of simulation initialization.
During this phase all data recording groups finish their initialization. Format
specific initialization is also called during this phase.
@copydetails Trick::DataRecordGroup::init()
Trick::DataRecordGroup::init()
@section LEVEL4 DataRecordGroup Common Copy Simulation Data
This routine copies simulation data into a large buffer which will be written to
disk when commanded by the DataRecordDispatcher. Copying the simulation off into
a buffer allows the simulation to continue executing and data recording to use
a separate thread of execution to write the data to disk. The following algorithm
-# Return if data recording is not enabled.
-# If the recording frequency is to record on parameter changes
-# For each change parameter compare the current value against the previous frame value.
-# If the value has changed mark the change_detected flag true
-# Copy the current value to the previous frame value.
-# If the recording frequency is set to always or the change_detected flag is true
-# If the recording frequency is to record on parameter changes step
-# Copy to memory the previous value with the current time stamp
-# If the copy memory pointer is at the end of the buffer, set the pointer to the
beginning of the buffer
-# Copy to memory the current value with the current time stamp
@section LEVEL4 Data Recording Specific Formats Routines
@section LEVEL5 ASCII Recording
@copydoc Trick::DRAscii
Trick::DRAscii
@section LEVEL6 ASCII Initialization
@copydetails Trick::DRAscii::format_specific_init()
Trick::DRAscii::format_specific_init()
@section LEVEL6 ASCII Write Data
@copydetails Trick::DRAscii::write_data()
Trick::DRAscii::write_data()
@section LEVEL6 ASCII Shutdown
@copydetails Trick::DRAscii::shutdown()
Trick::DRAscii::shutdown()
@section LEVEL5 Binary Recording
@copydoc Trick::DRBinary
Trick::DRBinary
@section LEVEL6 Binary Initialization
@copydetails Trick::DRBinary::format_specific_init()
Trick::DRBinary::format_specific_init()
@section LEVEL6 Binary Write Data
@copydetails Trick::DRBinary::write_data()
Trick::DRBinary::write_data()
@section LEVEL6 Binary Shutdown
@copydetails Trick::DRBinary::shutdown()
Trick::DRBinary::shutdown()
@section LEVEL5 HDF5 Recording
@copydoc Trick::DRHDF5
Trick::DRHDF5
@section LEVEL6 HDF5 Initialization
@copydetails Trick::DRHDF5::format_specific_init()
Trick::DRHDF5::format_specific_init()
@section LEVEL6 HDF5 Write Data
@copydetails Trick::DRHDF5::write_data()
Trick::DRHDF5::write_data()
@section LEVEL6 HDF5 Shutdown
@copydetails Trick::DRHDF5::shutdown()
Trick::DRHDF5::shutdown()
@section LEVEL3 DataRecordBuffering
The second objects are a set of DataRecordBuffering objects. These objects
are responsible for writing the copied simulation data to disk. There are
three techniques to write data to disk.
A base DataRecordBuffering object provides a common interface for each of
the buffering techniques. The common object provides routines for. These
base routines may be overridded by the specific buffering techniques.
-# Processing simulation arguments
-# Initialization
-# Adding a data recording group
The base DataRecordBuffering provides hooks for:
-# Processing data at the end of each software frame
-# Processing data at shutdown.
An empty initialization routine is provided by the base object if the
specific buffering techniques do not require a specialized initialization routine.
The buffering classes do not write the data themselves, rather they call the data record
groups write_data routines to do the writing.
The 3 specific buffereing techniques are
-# Write directly to disk immediately.
-# Use a thread to write data to disk asynchronously
-# Do not write data until simulation shutdown. Allow data copying to
overwrite data stored in the memory buffer.
@section LEVEL4 DataRecordBuffering Base Routines
@section LEVEL5 DataRecordBuffering Process Simulation Arguments
@copydetails Trick::DataRecordBuffering::process_sim_args()
Trick::DataRecordBuffering::process_sim_args()
@section LEVEL5 DataRecordBuffering Initialization
@copydetails Trick::DataRecordBuffering::init()
Trick::DataRecordBuffering::init()
@section LEVEL5 DataRecordBuffering Adding a Recording Group
@copydetails Trick::DataRecordBuffering::add_group()
Trick::DataRecordBuffering::add_group()
@section LEVEL4 DataRecordDisk
This buffering technique calls all of the data record write_data routines in the
main simulation thread of execution.
@section LEVEL5 DataRecordDisk End of Frame Processing
@copydetails Trick::DataRecordDisk::write_data()
Trick::DataRecordDisk::write_data()
@section LEVEL5 DataRecordDisk Shutdown Processing
@copydetails Trick::DataRecordDisk::shutdown()
Trick::DataRecordDisk::shutdown()
@section LEVEL4 DataRecordRing
This buffering technique does not call the write_data routines during runtime. Only
at shutdown does the write_data routines get called. The last contents of the memory
buffer are then dumped to disk.
@section LEVEL5 DataRecordRing End of Frame Processing
@copydetails Trick::DataRecordRing::write_data()
Trick::DataRecordRing::write_data()
@section LEVEL5 DataRecordRing Shutdown Processing
@copydetails Trick::DataRecordRing::shutdown()
Trick::DataRecordRing::shutdown()
@section LEVEL4 DataRecordThreaded
This buffering technique uses a separate thread to write data to disk. The main
thread of execution attempts to signal the thread at the end of each frame. The
thread calls the group write_data routines when signaled.
@section LEVEL5 DataRecordThreaded Writer
@copydetails Trick::DataRecordThreaded::drt_writer()
Trick::DataRecordThreaded::drt_writer()
@section LEVEL5 DataRecordThreaded End of Frame Processing
@copydetails Trick::DataRecordThreaded::write_data()
Trick::DataRecordThreaded::write_data()
@section LEVEL5 DataRecordThreaded Shutdown Processing
@copydetails Trick::DataRecordThreaded::shutdown()
Trick::DataRecordThreaded::shutdown()
@section LEVEL3 DataRecordDispatcher
The third object is the DataRecordDispatcher. The DataRecordDispatcher
calls each data recording buffering object's end of frame and shutdown
jobs. It serves as a single entry point for all data recording activities.
The dispatcher is intended to be the only data recording object called by
the %Trick scheduler. The dispatcher contains routines to
-# Process simulation arguments
-# Add data recording group
-# Initialization
-# End of Frame processing
-# Shutdown
@section LEVEL4 DataRecordDispatcher Process Simulation Arguments
@copydetails Trick::DataRecordDispatcher::process_sim_args()
Trick::DataRecordDispatcher::process_sim_args()
@section LEVEL4 DataRecordDispatcher Add Data Recording Group
When a data recording group is added to the DataRecordDispatcher the group is
tied to the requested buffering technique.
@copydetails Trick::DataRecordDispatcher::add_group()
Trick::DataRecordDispatcher::add_group()
@section LEVEL4 DataRecordDispatcher Initialization
@copydetails Trick::DataRecordDispatcher::init()
Trick::DataRecordDispatcher::init()
@section LEVEL4 DataRecordDispatcher End of Frame Processing
@copydetails Trick::DataRecordDispatcher::write_data()
Trick::DataRecordDispatcher::write_data()
@section LEVEL4 DataRecordDispatcher Shutdown
@copydetails Trick::DataRecordDispatcher::shutdown()
Trick::DataRecordDispatcher::shutdown()
*/

View File

@ -1,216 +0,0 @@
/**
@page LEVEL2 Scheduler Design
The scheduler design is divided based on the mode of the simulation. The modes are
Pre-Initialization, Initialization, Run, Freeze, and Shutdown.
The scheduler routines are called directly by a main program in a simulation.
A typical main program calls the following scheduler routines.
-# Call add_sim_object() for each sim_object to be added to the scheduler.
-# Call init() to initialize the simulation.
-# Call loop() to run the cyclic jobs of the simulation. loop() contains the
code for the Run and Freeze modes of operation.
-# Call shutdown() to shutdown the simulation.
@dot
digraph finite_state_machine {
rankdir=LR ;
size="12,5"
node [shape = doublecircle]; Initialization Shutdown;
node [shape = circle] ;
Initialization -> Run [ label = "no errors" ] ;
Initialization -> Shutdown [ label = "error condition" ];
Freeze -> Run [ label = "exec_command = RunCmd" ] ;
Run -> Freeze [ label = "exec_command = FreezeCmd" ] ;
Freeze -> Shutdown [ label = "exec_command = ExitCmd\nor error condition" ] ;
Run -> Shutdown [ label = "exec_command = ExitCmd\nor error condition" ] ;
}
@enddot
<center>Figure 1: Simulation Mode Finite State Machine</center>
Listed below are the various modes of operation and scheduler responsibilities within each.
@section LEVEL3 Pre-Initialization
During Pre-Initialization the simulation tells the Executive scheduler which SimObjects
are to be included in this simulation run. The auto-generated initialization routine
in S_source.cpp calls add_sim_object() for each sim_object instantiated in the S_define file.
@section LEVEL4 Adding Simulation Objects
In Pre-Initialization the auto-generated initialization routine calls add_sim_object()
for each sim_object instantiated in the S_define file. Each add_sim_object() will add
its jobs to the scheduing queues in order of SimObject instantiation.
@copydetails Trick::Executive::add_sim_object(Trick::SimObject * in_object , const char * in_name )
Trick::Executive::add_sim_object(Trick::SimObject * in_object , const char * in_name )
@section LEVEL4 Adding List of Jobs to Scheduling Queue
Each add_jobs_to_queue() will call add_job_to_queue() to add an individual job to the scheduler queue.
@copydetails Trick::Executive::add_jobs_to_queue(Trick::SimObject *, bool)
Trick::Executive::add_jobs_to_queue(Trick::SimObject *, bool)
@section LEVEL4 Adding Individual Job to Scheduling Queue
Adds an individual job to the scheduler queues.
@copydetails Trick::Executive::add_job_to_queue(Trick::JobData *)
Trick::Executive::add_job_to_queue(Trick::JobData *)
@section LEVEL3 Initialization Mode
During initialization mode the scheduler readies the simulation for running. This includes
calling SimObject initialization jobs as well as initializing scheduler timers. The Executive
provides the routine to call all default data and initialization class jobs as well as provides
jobs to initialize specific parts of the Executive itself. The initialization jobs include
-# Executive Initialization
-# Initialize default signal handlers
-# Process Simulation arguments
-# Post Initialization signal handler assignment
-# Write the S_job_execution File
-# Write the S_run_summary file which describes the simulation build environment
-# Check if all jobs in all SimObjects are handled by a scheduler.
-# Create scheduler threads
@section LEVEL4 Executive Initialization
This routine is typically called by the simulation main program. This routine initializes the
scheduler itself as well as calls the initialization routines for all the math models.
@copydetails Trick::Executive::init()
Trick::Executive::init()
@section LEVEL4 Initialize Default Signal Handlers
@copydetails Trick::Executive::init_signal_handlers()
Trick::Executive::init_signal_handlers()
@section LEVEL4 Process Simulation Arguments
@copydetails Trick::Executive::process_sim_args()
Trick::Executive::process_sim_args()
@section LEVEL4 Post Initialization Signal Handler Assignment
@copydetails Trick::Executive::post_init_signal_handlers()
Trick::Executive::post_init_signal_handlers()
@section LEVEL4 Write the S_job_execution File
The S_job_execution file contains all of the jobs currently scheduled in the Executive. The file
lists the jobs in order in the queues and shows the job name, id, class, phase, cycle time, start time, and
end time.
@copydetails Trick::Executive::write_s_job_execution()
Trick::Executive::write_s_job_execution()
@section LEVEL4 Write the S_run_summary File
@copydetails Trick::Executive::write_s_run_summary()
Trick::Executive::write_s_run_summary()
@section LEVEL3 Run Mode
After initialization the simulation enters the run/freeze loop. A single loop to handle jobs for
both modes are integrated to provide easy entry and exit points from one loop to the other.
During Run mode the executive/scheduler advances simulation time.
The scheduler calls the runtime cyclic jobs when simulation time equals the next call
time of the job. The scheduler has a software frame time. Users may specify override
the default software frame of 1 second. When the simulation time equals the next software
frame time, the scheduler calls end of software frame jobs.
Multiple threads may have been spawned to execute the Run mode jobs. Threads may be specified
as synchronous or asynchronous. Synchronous threads are synchronized to the main scheduler
thread at the start of each time step. Asynchronous threads are further divided into two types
Asynchronous and Asynchronous Must Finish (AMF) threads. Asynchronous threads are never
synchronized to the main scheduler thread once started. If an asynchronous thread completes
execution of all of its jobs, the jobs are started again at the next time step. AMF threads
are only synchronized to the main scheduler thread at a user specified thread specific
frequency.
At the beginning of Run mode the number of threads of execution is checked.
If there is only one thread of execution, a simplified run loop where
multi-thread dependency checks are removed is executed. Otherwise a
multi-threaded aware loop is called.
There are 5 routines suppoprting Run mode.
-# Loop Entry Point
-# Single Thread Loop
-# Multi Thread Main Thread Loop
-# Multi Thread Child Thread Loop
-# Advance Simulation Time
@section LEVEL4 Loop Entry Point
The loop entry point determines if the simulation is multi threaded or not. It calls the corresponding
loop to do the actual work.
@copydetails Trick::Executive::loop()
Trick::Executive::loop()
@section LEVEL4 Single Thread Loop
Called by loop(). Calls jobs in the main thread.
@copydetails Trick::Executive::loop_single_thread()
Trick::Executive::loop_single_thread()
@section LEVEL4 Multi Thread Main Thread Loop
Called by loop(). Coordinates scheduled job calls for the main thread and all child threads.
@copydetails Trick::Executive::loop_multi_thread()
Trick::Executive::loop_multi_thread()
@section LEVEL4 Multi Thread Child Thread Loop
Child threads are signalled by the main thread to execute their jobs.
@copydetails Trick::Threads::child()
Trick::Threads::child()
@section LEVEL4 Advance Sim Time
The Executive advances simulation time during each time step with a system_advance_sim_time class
job. This job advances time to the next lowest job call time.
@copydetails Trick::Executive::advance_sim_time()
Trick::Executive::advance_sim_time()
@section LEVEL3 Freeze Mode
During Freeze mode, simulation elapsed time does not advance. The scheduler enters a
loop that calls all freeze jobs at a monotonic frequency. Jobs may be called to start
freeze mode as well as when exiting freeze mode. All freeze mode jobs are executed within
the main thread.
@copydetails Trick::Executive::freeze_loop()
Trick::Executive::freeze_loop()
@section LEVEL3 Shutdown Mode
During Shutdown mode the scheduler waits for asynchronous jobs to finish if so directed.
The scheduler then calls shutdown jobs. The scheduler prints the reason for simulation
termination.
@copydetails Trick::Executive::shutdown()
Trick::Executive::shutdown()
@section LEVEL3 Signal Handling
Active through all modes, the scheduler assigns signal handlers to attempt a graceful
shutdown in case of a signal being thrown.
@copydetails Trick::Executive::signal_handler()
Trick::Executive::signal_handler()
*/

View File

@ -1,118 +0,0 @@
/**
* @anchor IntegratorPage
* @page LEVEL2 Integrators
*
* Integration is a numerical process of accumulating change. It is commonly used to propagate simulation states from one
* time step to the next.
*
* Trick's integration scheme helps a simulation developer to perform integration, using one of many well-known integration
* algorithms or to define his own.
*
* To do this, Trick defines two job classes specifically for integration:
* 1) Derivative Class Job
* 2) Integration Class Job
*
* At initialization time, the job scheduler runs all derivative jobs once. During run-time, Derivative and Integration class
* jobs are then alternately executed one or more times at the top of the rate group frame. The integration algorithm chosen
* by the user determines the number of times that they are executed per frame. For example, for Runge-Kutta 2 they will
* alternately be called 2 times.
*
* @section LEVEL3 Derivative Class Job
*
* The user implements derivative class job functions which are expected to calculate derivatives (to be integrated). Derivative
* job functions may pass any number of arguments. They may also be written to return any value. Their return value is irrelevant
* to the scheduler. The unique feature of a derivative class job is how it's scheduled. It is always called right before
* integration class job(s) in the same sim_object.
*
*@section LEVEL3 Integrator Class Job
*
* The user also implements integration class jobs functions which are expected to integrate the derivatives calculated by the
* derivative class jobs in the same sim object. Like derivative job functions, integration job functions may take any number
* of arguments. But, the return value of an integration function is significant.
*
* A non-zero return value tells the job scheduler ( see exec_scheduled_modules(), in S_source.c) that integration is not yet
* complete, and that the derivative and integration class job functions should again be called for the current (t) frame.
* A zero return value means that integration is complete for the current frame.
*
* @section LEVEL3 Integrator integrate() Function Interface
*
* To aid in the implementation of an integration job function, Trick provides the integrate() function:
*
int integrate() ;
*
* The Integrator object stores the input (derivative) values to be integrated, intermediate values, and the resultant
* (integrated) values.
*
* To use <I>integrate()</I>, the user is expected to:
-# Declare an IntegLoop in the S_define with the frequency the integration/derivative jobs.
-# Call getIntegrator(< Integration Algorithm >, <# of variables to integrate>) in the input file for each IntegLoop.
-# In the integration class job:<BR>
i. Populate the Integrator object with the state-values:
load_state( <state variable>, ..., NULL);
ii. and state-derivative values:
load_deriv( <state deriv variable>, ..., NULL);
iii. call the Trick <I>integrate()</I> function:
<int> = integrate();
iv. unload the results from:
unload_state(<state variable, ..., NULL);
v. and return the integer value returned from the <I>integrate()</I> function.
*
* Each time <I>integrate()</I> is called it will make progress in its estimate of the new state.
*
* That progress is recorded in the element Integrator->state_ws. After calling <I>integrate()</I>, a non-zero value
* in Integrator->intermediate_step, indicates that the integration is not yet complete; that <I>integrate()</I> needs
* to be called again. A zero value in Integartor->intermediate_step means that integration is done. The integration algorithms
* available are listed in the table below.
*
<table>
<tr><th>Integration Algorithm</th></tr>
<tr><td>Euler</td></tr>
<tr><td>Euler_Cromer</td></tr>
<tr><td>Nystrom_Lear_2</td></tr>
<tr><td>Runge_Kutta_2</td></tr>
<tr><td>Modified_Midpoint_4</td></tr>
<tr><td>Runge_Kutta_4</td></tr>
<tr><td>Runge_Kutta_Gill_4</td></tr>
<tr><td>Runge_Kutta_Fehlberg_45</td></tr>
<tr><td>Runge_Kutta_Fehlberg_78</td></tr>
<tr><td>ABM_Method</td></tr>
</table>
*
*@section LEVEL3 Derivative and Integration Class Job Scheduling
*
* Derivative and Integration class jobs are scheduled/called by the IntegLoop Scheduler to which they are assigned.
*
* A new IntegLoopScheduler class is created for each IntegLoop defined in the S_define. The sim_objects that are
* assigned to the IntegLoopScheduler are added to the scheduler with a call to <I>add_sim_object()</I>. Each
* IntegLoopScheduler is registered with the Executive when the default_data class jobs are run. Also, <I>rebuild_jobs()</I>
* is called to add jobs to the proper queue for each sim_object assigned to the IntegLoopScheduler during default_data
* class jobs. When the initialization class jobs are run, all of the derivative class jobs will be run at time equals 0.
* Based on the user-defined fequency, the Executive calls the appropriate IntegLoopScheduler <I>integrate()</I> function.
* @section LEVEL4 IntegLoopScheduler Integrate() Function Design
*
* The following happens for each IntegLoopScheduler <I>integrate()</I> function call:
* - All pre-integration class jobs are called.
* - If the variable first_step_deriv is TRUE, then all derivative class jobs are called.
* - Call all integration class jobs, each integration class job will be called repeatedly until the specific integration
* algorithm returns a zero value.
* - Call all derivative class jobs.
* - Call the dynamic_event class jobs.
*
* @section LEVEL3 Integration Algorithms
*
* The specific Integrators that Trick supports are listed in the above table. Each of these integration algorithms
* is well known in the world of numerical methods and therefore will not be described. The implementation of the
* algorithms are included in Trick release packages, but are not maintained by Trick. The ER7 division maintains
* an er7_utils configuration that contains the integrator code that is used by Trick.
* @see Trick::Integrator
*
*/

View File

@ -1,204 +0,0 @@
/**
@page LEVEL2 Trick Master/Slave Synchronization Design
Master/Slave synchronization is an optional class when running simulations.
Master/Slave synchronization synchronizes a master simulation to one or more slave
simulations. While synchronized, the master controls the overall simulation
mode as well as the current simulation time for all simulations. The set of
simulations may change mode if one of the simulations in the set freezes or exits
unexpectedly.
Master/Slave syncrhonization uses the Trick::MSConnect class for communications.
The MSConnect class is an abstract base class that defines functions for
connecting the simulations together and passing the simulation mode and
simulation time between simulations. The Trick::MSSocket class derives from the
Trick::MSConnect class, and uses sockets as the transport medium for master/slave communications.
@section LEVEL3 Master
The master simulation starts slave simulations during initialization. At the
end of each software frame during Run mode and at the end of each freeze frame
during Freeze mode the master reads the mode of all connected slave simulations.
The master will determine the mode of the simulations for the next frame
according to the slave modes and the master mode. The new mode and the
current simulation time is sent to the slaves.
Master/Slave synchronization is divided into code based on the mode of the
simulation. The modes are Initialization, Run, Freeze, and Shutdown.
Master/Slave functions are designed to be called from the S_define file.
Listed below are the various modes of operation and the Master
responsibilities within each.
@par Initialization -- Master
During Initialization slave connections are allocated and defined. Default
values to start each slave using ssh are set when a slave connection is
allocated. At the mimimum a slave must define a remote machine, the path
to the simulation executive, and a Trick::MSConnect class to use for
communications with the slave. Users may also define the remote shell to use,
a simulation executable name, a remote run directory, and additional user arguments
to pass to the slave. The allocation and definition of the slave
connections are typically done through Trick's input processor, but may also be
done in default_data or initialization jobs.
At the end of the scheduler initialization phase the master starts the slaves.
For each slave the master creates a slave startup command and executes the
slave startup command. This is how the slave startup command is created:
-# If the MSConnect class is not defined, return an error.
[@anchor d_master_init_0 d_master_init_0]
-# Begin the slave startup command with the slave remote shell.
[@anchor d_master_init_1 d_master_init_1]
-# Add the remote display environment variable to the startup command if
one was defined.
[@anchor d_master_init_2 d_master_init_2]
-# Add a cd command to the slave simulation path directory to the slave starup
command.
[@anchor d_master_init_3 d_master_init_3]
-# Add the S_main executable name to the slave startup command.
[@anchor d_master_init_4 d_master_init_4]
-# Add the Run Input File to the slave startup command.
[@anchor d_master_init_5 d_master_init_5]
-# Add additional user arguments to the slave startup command.
[@anchor d_master_init_6 d_master_init_6]
-# Execute the slave startup command.
[@anchor d_master_init_7 d_master_init_7]
The master sends its software frame to each slave.
@par Run -- Master
During Run mode the master reads the simulation mode of each slave. The
master determines the new simulation mode and sends the new mode and the
current simulation time to the slaves.
-# For each slave
-# Read the simulation command of the slave.
[@anchor d_master_run_0 d_master_run_0]
-# If the master mode command is not ExitCmd take action if the slave
returns the following:
-# If the slave command was not readable, returned ErrorCmd, and:
-# Terminate the sim if sync_error_terminate == true.
[@anchor d_master_run_1 d_master_run_1]
-# Deactivate the slave if sync_error_terminate == false.
[@anchor d_master_run_2 d_master_run_2]
-# If the slave command is ExitCmd:
-# Terminate the sim if sync_error_terminate == true.
[@anchor d_master_run_3 d_master_run_3]
-# Deactivate the slave if sync_error_terminate == false.
[@anchor d_master_run_4 d_master_run_4]
-# If the slave command is FreezeCmd:
-# Freeze the master sim
[@anchor d_master_run_5 d_master_run_5]
After gathering the simulation command from all of the slaves, send the
command to all of the slaves.
-# For each slave
-# Write the simulation time to the slave.
[@anchor d_master_run_0 d_master_run_0]
-# Write the simulation mode command to the slave.
[@anchor d_master_run_0 d_master_run_0]
@par Freeze -- Master
Upon entering freeze mode the master turns off sync_time_limit because while
in freeze, master/slave communications may not be regular and periodic.
[@anchor d_master_freeze_0 d_master_freeze_0]
At the end of each freeze frame call Trick::Master::end_of_frame() to perform the same
synchronization as in run mode.
[@anchor d_master_freeze_1 d_master_freeze_1]
When exiting freeze mode the master sets sync_time_limit back to the user
set value ready for running again.
[@anchor d_master_freeze_2 d_master_freeze_2]
@par Shutdown -- Master
The master tells the slaves that it is shutting down.
-# For each slave
-# Write the simulation time to the slave.
[@anchor d_master_shutdown_0 d_master_shutdown_0]
-# Write the simulation mode command ExitCmd to the slave.
[@anchor d_master_shutdown_0 d_master_shutdown_0]
@section LEVEL3 Slave
At the end of each software frame during Run mode and at the end of each
freeze frame during Freeze mode slave simulations send the master the current
mode of the slave. The slaves wait for the new mode and simulation time from
the master.
@par Initialization -- Slave
The Trick::Slave class is enabled by calling the MSConnect::process_sim_args()
routine. If the MSConnect::process_sim_args() finds command line arguments
specifying this simulation is a slave, then the Trick::Slave is enabled.
At the end of the scheduler initialization phase the slave connects to the
master.
-# Call Trick::MSConnect::connect() to connect the slave to the master.
[@anchor d_slave_init_0 d_slave_init_0]
-# Search for a RealtimeSync class. If one exists, turn the object off.
[@anchor d_slave_init_1 d_slave_init_1]
-# Search for a Master class. If one exists, turn the object off.
[@anchor d_slave_init_2 d_slave_init_2]
-# Read and set the slave's software frame from the master.
@par Run -- Slave
In Run mode the slave writes its next executive command to the master. The
master will return the overall next simulation mode to the slave. The slave
will also read the current simulation time from the master.
-# Write the simulation command to the master.
[@anchor d_slave_run_0 d_slave_run_0]
-# Read the simulation time from the master.
[@anchor d_slave_run_1 d_slave_run_1]
-# if the simulation time read was not successful:
-# Terminate the sim if sync_error_terminate == true.
[@anchor d_slave_run_2 d_slave_run_2]
-# Disable master/slave communication and command the sim to freeze if sync_error_terminate == false.
[@anchor d_slave_run_3 d_slave_run_3]
-# If the simulation time read was successful set the slave simulation
time to the time of the master.
[@anchor d_slave_run_4 d_slave_run_4]
-# Read the simulation command from the master.
[@anchor d_slave_run_5 d_slave_run_5]
-# If the simulation command was not successful:
-# Terminate the sim if sync_error_terminate == true.
[@anchor d_slave_run_6 d_slave_run_6]
-# Disable master/slave communication and command the sim to freeze if sync_error_terminate == false.
[@anchor d_slave_run_7 d_slave_run_7]
-# If the simulation command read was successful set the slave simulation
command to the command of the master.
[@anchor d_slave_run_8 d_slave_run_8]
@par Freeze -- Slave
Upon entering freeze mode the slave turns off sync_time_limit because while
in freeze, master/slave communications may not be regular and periodic.
[@anchor d_slave_freeze_0 d_slave_freeze_0]
At the end of each freeze frame call Trick::Slave::end_of_frame() to perform the same
synchronization as in run mode.
[@anchor d_slave_freeze_1 d_slave_freeze_1]
When exiting freeze mode the slave sets sync_time_limit back to the user
set value ready for running again.
[@anchor d_slave_freeze_2 d_slave_freeze_2]
@par Shutdown -- Slave
If a slave is shutting down, inform the master that it is exiting.
[@anchor d_slave_shutdown_0 d_slave_shutdown_0]
*/

View File

@ -1,91 +0,0 @@
/**
* @anchor MonteCarloPage
* @page LEVEL2 Monte Carlo and Optimization
*
* Monte Carlo is the process of iteratively calling a simulation over a set of predetermined or auto-generated inputs.
* Trick has designed its Monte Carlo capability to run distributed.
*
* @section LEVEL3 Structure
* In particular, Monte Carlo is designed after a "master/slave" model. The master is in charge of creating slaves and
* tasking them to work. There may be any number of slaves distributed over a network. Master and slave communicate through
* sockets. Theoretically, a master and slave need not have the same file system. Each slave is responsible for requesting
* work, accomplishing work and reporting results. The work at hand is running a single simulation iteratively over an input
* space.
*
* @subsection LEVEL4 The Master
* The master is the command center of a Monte Carlo simulation. The master tasks slaves to run the simulation with a given
* set of inputs. The master will task slaves to run in parallel. The master is responsible for keeping the slaves as busy as
* possible. To keep things running smoothly, the master is designed to reassign work when a slave is either dead or running
* too slowly. the master is only in charge of tasking work. The master does not run the simulation itself. The master will
* continue issuing work to the slaves until it is satisfied all simulation runs are complete.
*
* The master's life cycle consists of the following:
*
* - Initialize
* - While there are unresolved runs:
* - Spawn any uninitialized slaves.
* - Dispatch runs to ready slaves.
* - Resolve run based on slave's exit status.
* - Receive results from finished slave's child.
* - Check for timeouts.
* - Shutdown the slaves and terminate.
*
* @see Trick::MonteCarlo
*
* @anchor MonteCarloSlaves
* @subsection LEVEL4 Slaves
*
* A slave consists of a parent and fork()ed children. A slave parent spawns a child using the fork() system call. A
* slave child runs the simulation in its own address space. Only one child exists at a time in a slave. Per slave,
* simulation execution is sequential.
*
* A slave is responsible for requesting work from the master, running a Trick simulation with inputs given by the master,
* dumping recorded data to disk and informing the master when it is finished running its task.
*
* The slave's life cycle consists of the following:
*
* - Initialize
* - Connect to and inform the master of the port over which the slave is listening for dispatches.
* - Until the connection to the master is lost or the master commands a shutdown:
* - Wait for a new dispatch.
* - Process the dispatch.
* - Slave fork()s child.
* - Child runs simulation with varied input.
* - Write the run number processed to the master at child shutdown.
* - Write the exit status to the master.
* - Run the shutdown jobs and terminate.
*
* @see Trick::MonteSlave
*
* @section LEVEL3 Simulation Inputs
*
* The goal of Monte Carlo is to run the simulation over a set of inputs. The inputs that the master passes to the slaves
* are either generated by a statistical algorithm or they are hard-coded by the user in a data file. Inputs may also be
* generated exclusively by user calculations.
*
* @section LEVEL3 Monte Carlo Output
*
* For each simulation run within a Monte Carlo suite of runs, a directory called "MONTE_<name>" is created. Slave output
* is directed to this "MONTE_" directory. Trick recorded data is written in a set of "RUN_" directories within the parent
* "MONTE_" directory. Along with recorded data, stdout, stderr, and send_hs files are written. A file that contains the
* summary of all runs is written to the "MONTE_" directory.
*
* @section LEVEL3 Data Processing
*
* The trick_dp is desinged to understand "MONTE_" directories. When choosing to plot a "MONTE_" directory, trick_dp
* will overlay all curves from each "RUN_" directory within the parent "MONTE_" directory. The plot widget has built
* in features that allow the developer to distinguish what curve goes with what simulation run.
*
* @section LEVEL3 Optimization
*
* Optimization is made possible by creating a framework whereby the developer can change simulation inputs based on
* simulation results. Trick offers a set of job classes that allow the developer to enter the Monte Carlo loop and
* thereby enter the decision making on-the-fly. No canned optimization is available.
*
* This special set of job classes work in concert together in master and slaves. Trick schedules jobs within the master
* at critical points so that they may create inputs to send to the slave as well as receive results from the slave.
* Slave jobs are scheduled to receive simulation inputs from the master as well as send simulation results back to the
* master.
*
* The jobs are specified in the S_define. The jobs are created by the developer.
*/

View File

@ -1,100 +0,0 @@
/**
@page LEVEL2 Real-Time Synchronization Design
A simulation is "real-time" when it can consistently and repetitively execute
its scheduled math models to completion within some predetermined interval
time frame for an indefinite period of time. This predetermined interval
time frame is referred to as the real-time frame. In this design the real-time
frame is set equal to the simulation software frame. Real-time is achieved
by periodically pausing simulation execution at the end of each real-time
frame. If simulation execution has not finished by the end of each real-time
frame then this is an overrun. The real-time synchronization capability has
several user settable options when a simulation overruns. If simulation
execution finishes before the real-time frame expires, this is an underrun. If
the simuation is underruning, the real-time synchronization capability allows
the simulation to "sleep" while waiting for the real-time frame to expire.
Real-time synchronization defaults off when initializing the simulation.
To enable real-time synchronization users or models may call enable() at any
time during the simulation. To exit real-time synchronization users or
models may call disable() at any time during the simulation. The actual
entering or exiting real-time happens at the end of the frame.
Listed below are the various modes of operation in a simulation and the
responsibilities of the real-time synchronization class in each.
@section LEVEL3 Pre-Initialization
During pre-initialization the user may specify the behavior of the real-time
synchronization class during overruns and underruns.
- Set real-time synchronization enabled or disabled.
- Set real-time sleep timer enabled or disabled.
- Set the maximum number of consecutive overruns allowed. (default 100,000,000)
- Set the maximum time allowed for single overruns (default 1e37 seconds)
- Set action taken when maximum overruns achieved to freeze/terminate or
terminate immediately (default terminate immediately)
@section LEVEL3 Initialization and Restart
The real-time initialization and restart jobs are designed to be the last
jobs run before exiting initialization or restart mode.
Initialize the underlying hardware.
@copydetails Trick::RealtimeSync::initialize(long long , long long )
Trick::RealtimeSync::initialize(long long , long long )
@section LEVEL3 Start Real-Time
@copydetails Trick::RealtimeSync::initialize(long long , long long )
Trick::RealtimeSync::initialize(long long , long long )
@section LEVEL3 End of Frame
At the end of the real-time frame (also the software frame) the
real-time synchronization class will determine if the simulation is
underruning or overrunning and take actions to keep simulation time
and real-time in sync.
@copydetails Trick::RealtimeSync::rt_monitor( long long )
Trick::RealtimeSync::rt_monitor( long long )
@section LEVEL3 Freeze Mode
@section LEVEL4 Freeze Initialization
During freeze initialization the real-time synchronization class resets the real-time
frame to the freeze frame and restarts the real-time clock and timer.
@copydetails Trick::RealtimeSync::freeze_init( long long )
Trick::RealtimeSync::freeze_init( long long )
@section LEVEL4 Freeze Loop
During freeze loop processing the real-time synchronization pauses the freeze loop.
The pause is released when real-time equals the freeze loop period. No checks are
done for overrunning or underruning a freeze period.
@copydetails Trick::RealtimeSync::freeze_pause( long long )
Trick::RealtimeSync::freeze_pause( long long )
@section LEVEL4 UnFreeze
During unfreeze the real-time synchronization class resets the real-time
frame to the software frame and restarts the real-time clock and timer.
@copydetails Trick::RealtimeSync::unfreeze( long long , long long )
Trick::RealtimeSync::unfreeze( long long , long long )
@section LEVEL3 Shutdown Mode
During shutdow, the real-time synchronization class stops the clock and sleep
timer hardware.
@copydetails Trick::RealtimeSync::shutdown()
Trick::RealtimeSync::shutdown()
*/

View File

@ -1,88 +0,0 @@
/**
@page LEVEL2 ScheduledJobQueue Design
The Scheduler typically calls upon the ScheduledJobQueue to add
a job, find the next job that matches the current sim time, get the next
job call time, and instrument the job queue.
Listed below are the design for each use case of the ScheduledJobQueue.
@section LEVEL3 Adding a job
Adding a job to the queue increases the queue size by 1. Jobs are ordered by
job class, then phase, then sim object id, and finally job_id. The job_id increases
with the ordering of jobs in a sim object.
@copydetails Trick::ScheduledJobQueue::push()
Trick::ScheduledJobQueue::push()
@section LEVEL3 Adding a job ignoring sim object order.
Somethimes To add a job to the queue, Setting the sim object id to a large nnumber effectively
removes the sim object id in the sorting.
@copydetails Trick::ScheduledJobQueue::push_ignore_sim_object()
Trick::ScheduledJobQueue::push_ignore_sim_object()
@section LEVEL3 Find Next Job with Current Sim Time
Advances curr_index to next job in list who's next call time matches the incoming time
argument. If the job is not a system_job as determined by the scheduler, the next job
call time is calculated before returning. (system_jobs set their own next job call time).
Also track the next_job_time which will be used to advance simulation time
at the end of frame.
@copydetails Trick::ScheduledJobQueue::find_next_job()
Trick::ScheduledJobQueue::find_next_job()
@section LEVEL3 Get the Next Job
A simple get the next job in the list.
@copydetails Trick::ScheduledJobQueue::get_next_job()
Trick::ScheduledJobQueue::get_next_job()
@section LEVEL3 Get the next job call time
As the find_next_job routine traverses the queue of jobs searching for jobs that match the
current simulation time step, it also saves the time of the next lowest job
call time. This is the next time step that the scheduler will use when
advancing simulation time.
@copydetails Trick::ScheduledJobQueue::get_next_job_call_time()
Trick::ScheduledJobQueue::get_next_job_call_time()
@section LEVEL3 Test Next Job Call Time
Some job types reschedule themselves and the next job call time are not tested by the find next job routine.
The test next job call time allows these job to check their next call time against the overall next
job call time. If the current job next job call time is lower than the overall job call time, the
overall next job call time is set to the current job's next call time.
@copydetails Trick::ScheduledJobQueue::test_next_job_call_time()
Trick::ScheduledJobQueue::test_next_job_call_time()
@section LEVEL3 Instrument a job before all jobs in the queue
To add an instrumentation job before a job or all jobs in the queue. Requirement [@ref r_exec_instrument_0]
@copydetails Trick::ScheduledJobQueue::instrument_before(JobData * , string , InstrumentationEvent * )
Trick::ScheduledJobQueue::instrument_before(JobData * , string , InstrumentationEvent * )
@section LEVEL3 Instrument a job after all jobs in the queue
To add an instrumentation job after a job or all jobs in the queue. Requirement [@ref r_exec_instrument_2]
@copydetails Trick::ScheduledJobQueue::instrument_after(JobData * , string , InstrumentationEvent * )
Trick::ScheduledJobQueue::instrument_after(JobData * , string , InstrumentationEvent * )
@section LEVEL3 Remove an instrumentation job
To remove an instrumentation job from the queue. Requirement [@ref r_exec_instrument_4]
@copydetails Trick::ScheduledJobQueue::instrument_remove(string , InstrumentationEvent * )
Trick::ScheduledJobQueue::instrument_remove(string , InstrumentationEvent * )
*/

View File

@ -1,92 +0,0 @@
/**
@page LEVEL2 Sleep Timer Design
After all jobs in an execution frame have run, the default behavior (the timer is disabled)
is that the simulation will spin on the clock until real-time has caught up to simulation time.
Enabling the sleep timer gives control to the timer's pause() function, in which it may
release the processor and regain control when the timer elapses.
@section LEVEL3 Base Sleep Timer
The base Timer object provides a common interface for all Timers for the
following functions.
-# Enabling the Timer
-# Disabling the Timer
-# Getting the enabled/disabled status
The base Timer object provides an interface for the following operations. The
base Timer does not implement the following operations.
-# Initializing the Timer hardware
-# Setting the frame time for timer
-# Starting the timer
-# Resetting the timer
-# Pausing for the timer to expire
-# Stopping the timer
-# Shutting down the Timer hardware
@section LEVEL3 ITimer
The ITimer is a Timer object that derives from the the Base Sleep Timer. The
ITimer uses system itimer functionality to allow the simulation to release the
cpu while waiting for the timer to expire. When the itimer expires it uses
the SIGALRM signal to set a semaphore. When the semaphore is set the simulation
wakes up.
The itimer does not expire exactly at the desired period. It actually exipres after
the desired period by up to 1ms. To compensate for the delay we subtract 2ms from
the desired period. The RealtimeSync class "spins" on the clock the remaining
1-2ms the timer does not sleep for.
The ITimer implements the interface laid out by the base Timer class
@section LEVEL4 Initialization
@copydetails Trick::ITimer::init()
Trick::ITimer::init()
@section LEVEL4 Setting the Frame Time
@copydetails Trick::ITimer::set_frame_times()
Trick::ITimer::set_frame_times()
@section LEVEL4 Starting the timer.
@copydetails Trick::ITimer::start()
Trick::ITimer::start()
@section LEVEL4 Restarting the timer.
@copydetails Trick::ITimer::reset()
Trick::ITimer::reset()
@section LEVEL4 Pausing for the Timer to Expire
Pausing for the timer has 2 parts. The first is the signal handler that posts
a semaphore in response to a SIGALRM signal. The signal handler is assigned
to SIGALRM during the initialization routine. The second is the pause routine
that waits for the semaphore to be posted.
@section LEVEL5 Signal Handler
@copydetails Trick::ITimer::it_handler()
Trick::ITimer::it_handler()
@section LEVEL4 Pause for Semaphore
@copydetails Trick::ITimer::pause()
Trick::ITimer::pause()
@section LEVEL4 Stopping the timer.
@copydetails Trick::ITimer::stop()
Trick::ITimer::stop()
@section LEVEL4 Shutting Down the Timer
@copydetails Trick::ITimer::shutdown()
Trick::ITimer::shutdown()
*/

View File

@ -1,6 +0,0 @@
all:
${MAKE} -C ..
clean:
${MAKE} -C .. clean