📄 syst_graph.cpp
字号:
//
// File = syst_graph.cpp
//
#include <stdlib.h>
#include <fstream>
#include "syst_graph.h"
#include "globals.h"
#include "sigplot.h"
//#include "sig_mgr.h"
//#include "cntl_mgr.h"
//#include "actsysgp.h"
//#include "cmsg.h"
//#include "reinit.h"
#ifdef _DEBUG
extern ofstream *DebugFile;
#endif
extern SignalPlotter SigPlot;
//extern Reinitializer Reinit;
extern int PassNumber;
extern int EnclaveNumber;
extern int EnclaveOffset[10];
extern PracSimModel *ActiveModel;
//============================================
// constructor
SystemGraph::SystemGraph()
{
Sdg_Vert_Descr = new std::vector<sdg_sig_desc_type*>;
Sdg_Edge_Descr = new std::vector<sdg_edge_desc_type*>;
Samp_Intvl = new std::vector<double>;
Block_Size = new std::vector<int>;
Syst_Lev_Models = new std::vector<PracSimModel*>;
Sig_Dep_Graph = new DirectedGraph;
Num_Regular_Sigs = 0;
return;
}
//============================================
// destructor
SystemGraph::~SystemGraph()
{
}
//============================================
void SystemGraph::MergeCurrModelGraph( ModelGraph* curr_mod_graph )
{
std::vector<int> merged_verts;
int num_cmg_verts;
int cmg_vert_num;
int sdg_sig_num;
obj_id_type sdg_sig_id, cmg_sig_id;
SignalKinds_type cmg_vert_kind;
bool node_not_found;
double cmg_samp_intvl;
int cmg_block_size;
//------------------------------------------------------------
// First section of code merges the vertices from the current
// model graph (CMG) into the system dependency graph (SDG)
//
// Check each signal from CSG to see if it's already in SDG
num_cmg_verts = curr_mod_graph->GetNumVerts();
//-----------------------------------------------------
// This loop checks each signal from CMG to see if it's
// already in SDG
for( cmg_vert_num = 0;
cmg_vert_num < num_cmg_verts;
cmg_vert_num++) {
cmg_vert_kind = curr_mod_graph->GetVertexKind(cmg_vert_num);
cmg_sig_id = curr_mod_graph->GetVertexId(cmg_vert_num);
node_not_found = true;
int num_sdg_verts = Sig_Dep_Graph->GetNumVerts();
for( sdg_sig_num = 0;
(sdg_sig_num < num_sdg_verts) & node_not_found;
sdg_sig_num++) {
sdg_sig_id = Sig_Dep_Graph->GetVertexId(sdg_sig_num);
if( sdg_sig_id == cmg_sig_id ) {
//---------------------------------------
// this CMSG signal is already in SDG, so add its
// index (in SDG) to list of merged signals
merged_verts.push_back(sdg_sig_num);
//----------------------------------------
// If sampling rate is undefined for signal in SDG,
// copy value from CMG signal (which may or may not be
// defined). If sampling rate is defined for signal in SDG,
// check to see if there is a different value defined in
// CMG. If there is, a fatal error condition exists.
cmg_samp_intvl = curr_mod_graph->GetSampIntvl(cmg_vert_num);
if(((Sdg_Vert_Descr->at(sdg_sig_num))->samp_intvl) == 0.0) {
((Sdg_Vert_Descr->at(sdg_sig_num))->samp_intvl) = cmg_samp_intvl;
}
else {
if( (cmg_samp_intvl != 0.0) &&
(cmg_samp_intvl !=
((Sdg_Vert_Descr->at(sdg_sig_num))->samp_intvl)) ) {
// -- ERROR --
*DebugFile << "Fatal error -- "
<< "incomsistent sampling rate for signal "
<< ((GenericSignal*)sdg_sig_id)->GetName() << endl;
exit(1);
}
}
//---------------------------------------------------
// If block size is undefined for signal in SDG,
// copy value from CMG signal (which may or may not be
// defined. If block size is defined for signal in SDG,
// check to see if there is a different value in CMG.
// If there is, a fatal error condition exists.
cmg_block_size = curr_mod_graph->GetBlockSize(cmg_vert_num);
if( ((Sdg_Vert_Descr->at(sdg_sig_num))->block_size) == 0 ) {
((Sdg_Vert_Descr->at(sdg_sig_num))->block_size) = cmg_block_size;
}
else {
if( (cmg_block_size != 0 ) &&
(cmg_block_size !=
((Sdg_Vert_Descr->at(sdg_sig_num))->block_size) )) {
// -- ERROR --
*DebugFile << "Fatal error -- "
<< "inconsistent block size for signal "
<< ((GenericSignal*)sdg_sig_id)->GetName() << endl;
exit(1);
}
}
// no need to check remaining SDG signals for this CMSG signal
node_not_found = false;
} // end of if( sdg_sig_id == cmg_sig_id )
} // end of loop over sdg_sig_num
//-----------------------------------------------------
// If loop above completed without a match, we need
// to add CMG vertex to SDG
if( node_not_found ) {
// maybe...we should use the sig_desc_type structure
// in the CMG, then this would become a simple
// structure to structure copy
sdg_sig_desc_type* new_sig_desc = new sdg_sig_desc_type;
new_sig_desc->signal_id =
curr_mod_graph->GetSignalId(cmg_vert_num);
new_sig_desc->block_size =
curr_mod_graph->GetBlockSize(cmg_vert_num);
new_sig_desc->samp_intvl =
curr_mod_graph->GetSampIntvl(cmg_vert_num);
new_sig_desc->kind_of_signal =
curr_mod_graph->GetVertexKind(cmg_vert_num);
if(new_sig_desc->kind_of_signal == SK_REGULAR_SIGNAL) Num_Regular_Sigs++;
Sdg_Vert_Descr->push_back(new_sig_desc);
sdg_sig_num = Sig_Dep_Graph->AddVertex(cmg_sig_id);
merged_verts.push_back(sdg_sig_num);
}
} // end of loop over cmg_vert_num
//----------------------------------------------------------
// at this point we are done adding vertices, and now begin
// to add edges between these vertices as specified in the CMG
//
// new edges in the SDG can only connect to vertices that were
// just added or which matched vertices in the CMG
int sdg_fm_idx, sdg_to_idx;
int cmg_edge_num;
int existing_edge;
bool conn_is_feedback;
obj_id_type cmg_edge_id;
int num_merged_verts;
num_merged_verts = int(merged_verts.size());
for( int cmg_fm_idx = 0;
cmg_fm_idx < num_merged_verts;
cmg_fm_idx++) {
sdg_fm_idx = merged_verts.at(cmg_fm_idx);
conn_is_feedback = curr_mod_graph->ConnIsFeedback(cmg_fm_idx);
for( int cmg_to_idx = 0;
cmg_to_idx < num_merged_verts;
cmg_to_idx++) {
sdg_to_idx = merged_verts.at(cmg_to_idx);
cmg_edge_num = curr_mod_graph->GetEdgeNum(cmg_fm_idx, cmg_to_idx);
if(cmg_edge_num >= 0) {
//---------------------------------
// CMG contains an edge from vertex 'cmg_fm_idx'
// to vertex 'cmg_to_idx'
// See if ASG-SDG already contains an edge between
// the corresponding vertices.
existing_edge =
Sig_Dep_Graph->GetEdgeNum(sdg_fm_idx, sdg_to_idx);
if(existing_edge >= 0 ) {
double cmg_resamp = curr_mod_graph->GetResampRate(cmg_edge_num);
// double sdg_resamp = Sig_Dep_Graph->GetResampRate(existing_edge);
double sdg_resamp = (Sdg_Edge_Descr->at(existing_edge))->resamp_rate;;
if(cmg_resamp != sdg_resamp)
{
// parallel edge exists in ASG-SDG -- not sure how to
// handle -- see old listing for handling of edges
// due to subordinate models
*DebugFile << "parallel edge error" << endl;
*DebugFile << "existing_edge = " << existing_edge << endl;
*DebugFile << "cmg_fm_idx = " << cmg_fm_idx << endl;
*DebugFile << "cmg_to_idx = " << cmg_to_idx << endl;
exit(1);
}
}
//-----------------------------------------
// OK to add edge
cmg_edge_id = curr_mod_graph->GetEdgeId(cmg_edge_num);
Sig_Dep_Graph->AddEdge( cmg_edge_id,
sdg_fm_idx,
sdg_to_idx);
sdg_edge_desc_type* new_edge_desc = new sdg_edge_desc_type;
new_edge_desc->model_id = (PracSimModel*)cmg_edge_id;
new_edge_desc->resamp_rate =
curr_mod_graph->GetResampRate(cmg_edge_num);
new_edge_desc->is_const_intvl =
curr_mod_graph->GetIsConstIntvl(cmg_edge_num);
new_edge_desc->delta_delay =
curr_mod_graph->GetDelay(cmg_edge_num);
Sdg_Edge_Descr->push_back(new_edge_desc);
} // end of if(cmg_edge_num)
} // end of loop over cmg_to_idx
} // end of loop over cmg_fm_idx
return;
}
//========================================================
void SystemGraph::DumpSDGraph(void)
{
int sig_num, sig_num2, edge_num;
GenericSignal *sig_id;
PracSimModel *model_id;
int num_nodes = Sig_Dep_Graph->GetNumVerts();
int num_edges = Sig_Dep_Graph->GetNumEdges();
*DebugFile << "\nIn SystemGraph::DumpSDGraph" << endl;
*DebugFile << "Num_SDG_Nodes = " << num_nodes << endl;
*DebugFile << "Vertices:" << endl;
*DebugFile << "index, Sdg_Vtx_Id, Signal Name, Samp Intvl, "
<< "Block Size" << endl;
for( sig_num = 0; sig_num < num_nodes; sig_num++) {
sig_id = (Sdg_Vert_Descr->at(sig_num))->signal_id;
*DebugFile << sig_num << ") "
<< sig_id << " "
<< sig_id->GetName() << " "
<< (Sdg_Vert_Descr->at(sig_num))->samp_intvl << " "
<< (Sdg_Vert_Descr->at(sig_num))->block_size << endl;
}
*DebugFile << "\nEdges:" << endl;
*DebugFile << "index, SDG edge model, Model Name, Resamp Rate, "
<< "Delay" << endl;
for( edge_num = 0; edge_num < num_edges; edge_num ++) {
model_id = (Sdg_Edge_Descr->at(edge_num))->model_id;
*DebugFile << edge_num << ") "
<< model_id << " "
<< model_id->GetModelName() << ":"
<< model_id->GetInstanceName() << " "
<< (Sdg_Edge_Descr->at(edge_num))->resamp_rate << " "
<< (Sdg_Edge_Descr->at(edge_num))->delta_delay << endl;
}
*DebugFile << "\nAdjacency Matrix:" << endl;
for( sig_num = 0; sig_num < num_nodes; sig_num++) {
for( sig_num2 = 0; sig_num2 < num_nodes; sig_num2++) {
edge_num = Sig_Dep_Graph->GetEdgeNum(sig_num, sig_num2);
if( edge_num >= 0 ) {
*DebugFile << "Edge " << edge_num
<< " connects from vertex " << sig_num
<< " to vertex " << sig_num2 << endl;
}
}
}
}
//===================================================================
void SystemGraph::ResolveSignalParms(void)
{
int sig_num, unsorted_sig_num, base_sig_num, edge_num;
int num_base_sigs_used = 0;
bool base_sig_not_found;
double samp_rate;
int block_size;
GenericSignal *sig_id;
bool is_forward;
int num_nodes = Sig_Dep_Graph->GetNumVerts();
bool *used_as_base = new bool[num_nodes];
for( sig_num = 0; sig_num < num_nodes; sig_num++)
{
used_as_base[sig_num] = false;
}
this->TopoSortSDG();
while(num_base_sigs_used < Num_Regular_Sigs)
{
//---------------------------------------------------------------
// find base signal
base_sig_not_found = true;
for(unsorted_sig_num = 0; unsorted_sig_num < num_nodes; unsorted_sig_num++)
{
sig_num = Sorted_Sig_Nodes[unsorted_sig_num];
sig_id = (Sdg_Vert_Descr->at(sig_num))->signal_id;
samp_rate = (Sdg_Vert_Descr->at(sig_num))->samp_intvl;
if(samp_rate <= 0.0)
{
#ifdef _DEBUG
*DebugFile << sig_id->GetName()
<< " rejected because samp rate <= 0 ( "
<< samp_rate << " )" << endl;
#endif
continue;
}
block_size = (Sdg_Vert_Descr->at(sig_num))->block_size;
if(block_size <= 0.0)
{
#ifdef _DEBUG
*DebugFile << sig_id->GetName()
<< " rejected because block size <= 0 ( "
<< block_size << " )" << endl;
#endif
continue;
}
if(used_as_base[sig_num])
{
#ifdef _DEBUG
*DebugFile << sig_id->GetName()
<< " rejected because already used as base"
<< endl;
#endif
continue;
}
//
// if execution gets to here, we have found a useable base signal
//
base_sig_num = sig_num;
used_as_base[base_sig_num] = true;
num_base_sigs_used++;
base_sig_not_found = false;
break;
} // end of loop over unsorted_sig_num
if(base_sig_not_found)
{
(*DebugFile) << "Unable to find suitable base signal" << endl;
#ifdef _DEBUG
*DebugFile << "The following signals have not"
<< " been used as base signals:" << endl;
for(unsorted_sig_num = 0; unsorted_sig_num < num_nodes; unsorted_sig_num++)
{
sig_num = Sorted_Sig_Nodes[unsorted_sig_num];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -