00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <pch.h>
00037 #include "Env/Param/ParamDB.h"
00038 #include "DefaultParam.h"
00039 #include "Env/Param/ParamXMLPathReductionMap.h"
00040
00041 using namespace std;
00042 using namespace boost;
00043
00044
00045 namespace Onikiri
00046 {
00047 ParamDB g_paramDB;
00048 }
00049
00050
00051 using namespace Onikiri;
00052
00053 ParamDB::ParamDB()
00054 {
00055 m_initialized = false;
00056 m_userParamPassed = false;
00057 }
00058
00059 ParamDB::~ParamDB()
00060 {
00061
00062 }
00063
00064 bool ParamDB::Initialize( const String& initialPath )
00065 {
00066 if(m_initialized){
00067 THROW_RUNTIME_ERROR( "Initialize() is called more than once." );
00068 }
00069
00070 m_initialPath = initialPath;
00071 m_tree.LoadString( g_defaultParam, true, "DefaultParam" );
00072 m_initialized = true;
00073 return true;
00074 }
00075
00076 void ParamDB::Finalize()
00077 {
00078 }
00079
00080 const vector<ParamXMLTree::InputInfo>&
00081 ParamDB::GetXMLFileNames()
00082 {
00083 return m_tree.GetInputList();
00084 }
00085
00086 String ParamDB::CompletePath( const String& target, const String& basePath )
00087 {
00088 using namespace filesystem;
00089 return
00090 absolute(
00091 path( (const string&)target ),
00092 path( (const string&)basePath )
00093 ).string();
00094 }
00095
00096
00097 String ParamDB::RemoveFileName(const String& path)
00098 {
00099 String ret;
00100 int indexBs = (int)path.rfind( "\\" );
00101 int indexSl = (int)path.rfind( "/" );
00102 int indexPath = indexSl > indexBs ? indexSl : indexBs;
00103 if(indexPath == -1)
00104 ret = "./";
00105 else
00106 ret.assign(path.begin(), path.begin() + indexPath + 1);
00107 return ret;
00108 }
00109
00110
00111 void ParamDB::LoadXMLFile(const String& fileName)
00112 {
00113 const String& fileFullPathName =
00114 CompletePath( fileName, m_initialPath );
00115
00116
00117 ParamXMLTree curTree;
00118 curTree.LoadXMLFile( fileFullPathName, false );
00119
00120
00121 String fileBasePath = RemoveFileName( fileFullPathName );
00122 ParamXMLPath xmlBasePath( "/Session/Import/" );
00123
00124 vector<ParamXMLPath> importedPathList;
00125
00126 for(int i = 0; ;i++){
00127 ParamXMLPath path = xmlBasePath;
00128 path.AddArray( "File", i );
00129 path.AddAttribute( "Path" );
00130
00131 String importFileName;
00132 bool hit = curTree.Get( path, &importFileName );
00133 if( !hit )
00134 break;
00135
00136 importedPathList.push_back( path );
00137
00138 const String& importFullPath =
00139 CompletePath( importFileName, fileBasePath );
00140 LoadXMLFile( importFullPath );
00141 }
00142
00143 AddExternalParameterToList( "FileName", fileName );
00144
00145
00146
00147
00148
00149 m_tree.LoadXMLFile( fileFullPathName, false );
00150 m_isLoaded = true;
00151
00152
00153
00154 for( size_t i = 0; i < importedPathList.size(); i++ ){
00155 String tmpString;
00156 m_tree.Get( importedPathList[i], &tmpString );
00157 }
00158
00159 m_userParamPassed = true;
00160 }
00161
00162
00163 void ParamDB::LoadParameters(const vector<String>& argList)
00164 {
00165 for( vector<String>::const_iterator i = argList.begin() + 1;
00166 i != argList.end();
00167 ++i
00168 ){
00169 const String& arg = *i;
00170
00171 if( arg.rfind(".xml") == arg.size() - 4 ){
00172 LoadXMLFile( arg );
00173 }
00174 else if( arg.find("-x") == 0 ){
00175 ++i;
00176 if(i == argList.end())
00177 THROW_RUNTIME_ERROR("'-x' option requires parameter expression.");
00178 AddParameter( *i );
00179 }
00180 }
00181 m_userParamPassed = true;
00182 }
00183
00184
00185 void ParamDB::AddExternalParameterToList(const String& name, const String& value)
00186 {
00187 ParamXMLTree::NodeArray* inputList =
00188 m_tree.GetNodeArray( "/Session/InputList/Input", true );
00189
00190 ParamXMLTree::NodePtr node = m_tree.CreateNewNode( "Input" );
00191 inputList->push_back( node );
00192
00193 ParamXMLTree::NodePtr attr = m_tree.CreateNewNode( name );
00194 attr->value = value;
00195 attr->accessed = true;
00196 node->attributes[name] = attr;
00197 }
00198
00199
00200 void ParamDB::AddParameter(const String& paramExp)
00201 {
00202 const vector<String>& exp = paramExp.split("=");
00203 if(exp.size() != 2 || exp[0].size() == 0){
00204 THROW_RUNTIME_ERROR(
00205 "'%s' is invalid expressoion.",
00206 paramExp.c_str() );
00207 }
00208
00209
00210 String strPath;
00211 if(exp[0].at(0) == '/')
00212 strPath = exp[0];
00213 else
00214 strPath = String("/Session/") + exp[0];
00215
00216 for( int i = 0; i < g_pathReductionMapSize; i++ ){
00217 String reductionPath = g_pathReductionMap[i].reductionPath;
00218 size_t pos = strPath.find( reductionPath );
00219 if( pos == 0 ){
00220 strPath.replace(
00221 pos, reductionPath.length() ,
00222 g_pathReductionMap[i].fullPath
00223 );
00224 }
00225 }
00226
00227 ParamXMLPath path = strPath;
00228
00229 String value;
00230 if( !m_tree.Get( path, &value ) ){
00231 THROW_RUNTIME_ERROR(
00232 "Parameter passed by command line argument is not valid.\n"
00233 "'%s' is not found in default parameter.\n",
00234 path.ToString().c_str()
00235 );
00236 }
00237
00238 m_tree.LoadValue( path, exp[1] );
00239
00240 AddExternalParameterToList( "Expression", paramExp );
00241 m_userParamPassed = true;
00242 }
00243
00244
00245 void ParamDB::AddUserDefaultParam(const String& xmlString)
00246 {
00247 if( m_userParamPassed ){
00248 THROW_RUNTIME_ERROR(
00249 "Added the user defined default parameter after loading user parameters."
00250 "All user defined default parameter must be added before loading user parameters."
00251 );
00252 }
00253
00254 m_tree.LoadString( xmlString, true, "User" );
00255 }
00256
00257
00258 bool ParamDB::MatchFilterList( const String& str, const std::vector<String>& filterList ) const
00259 {
00260 for( size_t i = 0; i < filterList.size(); i++ ){
00261 if( str.find( filterList[i] ) != String::npos )
00262 return true;
00263 }
00264
00265 return false;
00266 }
00267
00268 void ParamDB::CheckResultXML( const String& path, XMLNodePtr node, int* warningCount )
00269 {
00270 static const int MAX_WARNING_NUM = 8;
00271 if( (*warningCount) > MAX_WARNING_NUM ){
00272 return;
00273 }
00274
00275 for( XMLChildMap::iterator children = node->children.begin();
00276 children != node->children.end();
00277 ++children
00278 ){
00279
00280
00281 XMLNodeArray& siblings = children->second;
00282 for( size_t index = 0; index < siblings.size(); index++ ){
00283
00284 XMLNodePtr sibling = siblings[ index ];
00285
00286
00287 XMLAttributeMap &attr = sibling->attributes;
00288 for( XMLAttributeMap::iterator i = attr.begin();
00289 i != attr.end();
00290 ++i
00291 ){
00292 if( !i->second->accessed && !IsInException() ){
00293 (*warningCount)++;
00294 RUNTIME_WARNING(
00295 "The attribute '%s' have never been accessed. "
00296 "The attribute name may be wrong.",
00297 (path + sibling->name + "/@"+ i->second->name).c_str()
00298 );
00299
00300 if( (*warningCount) > MAX_WARNING_NUM ){
00301 RUNTIME_WARNING( "Too many warnings. Omit subsequent warnings...");
00302
00303 return;
00304 }
00305 }
00306 }
00307
00308 CheckResultXML( path + sibling->name + "/", sibling, warningCount );
00309 }
00310
00311 }
00312 }
00313
00314
00315
00316 bool ParamDB::FilterResultXML( const String& path, XMLNodePtr node, const vector<String>& filterList )
00317 {
00318 if( MatchFilterList( path + node->name, filterList ) ){
00319 return true;
00320 }
00321
00322 bool validNode = false;
00323 for( XMLChildMap::iterator children = node->children.begin();
00324 children != node->children.end();
00325 ){
00326
00327
00328 XMLNodeArray& siblings = children->second;
00329 bool validChild = false;
00330 for( size_t index = 0; index < siblings.size(); index++ ){
00331
00332 XMLNodePtr sibling = siblings[ index ];
00333 if( MatchFilterList( path + sibling->name, filterList ) ){
00334 validChild = true;
00335 continue;
00336 }
00337
00338
00339 XMLAttributeMap &attr = sibling->attributes;
00340 for( XMLAttributeMap::iterator i = attr.begin();
00341 i != attr.end();
00342 ){
00343 if( MatchFilterList( path + i->second->name, filterList ) ){
00344 ++i;
00345 }
00346 else{
00347 i = attr.erase( i );
00348 }
00349 }
00350
00351 bool validChildren = FilterResultXML( path + sibling->name + "/", sibling, filterList );
00352 if( validChildren || attr.size() > 0 ){
00353 validChild = true;
00354 }
00355 }
00356
00357 if( validChild ){
00358 validNode = true;
00359 ++children;
00360 }
00361 else{
00362
00363 children = node->children.erase( children );
00364 }
00365 }
00366
00367 return validNode;
00368 }
00369
00370
00371 String ParamDB::DumpResultXML( const String& level, const String& filter )
00372 {
00373 XMLNodePtr session = m_tree.GetNode( "/Session" );
00374
00375
00376 String currentConfigName =
00377 m_tree.GetNode( "/Session/Simulator/@Configuration" )->value;
00378 XMLNodePtr configNode =
00379 m_tree.GetNode( "/Session/Simulator/Configurations" );
00380 for( XMLChildMap::iterator child = configNode->children.begin();
00381 child != configNode->children.end();
00382 ){
00383 if( child->first == currentConfigName ){
00384 ++child;
00385 }
00386 else{
00387 child = configNode->children.erase( child );
00388 }
00389 }
00390
00391
00392 int warningCount = 0;
00393 CheckResultXML( "/Session/", session, &warningCount );
00394
00395
00396 vector<String> filterList = filter.split( "," );
00397 if( filterList.size() > 0 ){
00398 FilterResultXML( "/Session/", session, filterList );
00399 }
00400
00401 if( level == "Minimum" ){
00402 XMLNodePtr session = m_tree.GetNode( "/Session" );
00403 session->children.erase( "Simulator" );
00404 session->children.erase( "Emulator" );
00405 session->children.erase( "Environment" );
00406 session->children.erase( "Import" );
00407
00408 ParamXMLTree::NodePtr result = m_tree.GetNode( "/Session/Result" );
00409 if( result ){
00410 result->children.erase( "Resource" );
00411 }
00412
00413 return m_tree.ToXMLString();
00414 }
00415 else if( level == "BasicResult" ){
00416 ParamXMLTree::NodePtr session = m_tree.GetNode( "/Session" );
00417 session->children.erase( "Simulator" );
00418 session->children.erase( "Emulator" );
00419 session->children.erase( "Environment" );
00420 session->children.erase( "Import" );
00421
00422 ParamXMLTree::NodePtr res = m_tree.GetNode( "/Session/Result/Resource" );
00423 if( res ){
00424 res->children.erase( "PipelinedExecUnit" );
00425 res->children.erase( "ExecUnit" );
00426 res->children.erase( "MemExecUnit" );
00427 res->children.erase( "Core" );
00428 res->children.erase( "CheckpointMaster" );
00429 res->children.erase( "ExecLatencyInfo" );
00430 res->children.erase( "Thread" );
00431 res->children.erase( "PHT" );
00432 res->children.erase( "Scheduler" );
00433 res->children.erase( "GlobalHistory" );
00434 res->children.erase( "GlobalClock" );
00435 res->children.erase( "RAS" );
00436 }
00437
00438 return m_tree.ToXMLString();
00439 }
00440 else if( level == "Result" ){
00441 ParamXMLTree::NodePtr session = m_tree.GetNode( "/Session" );
00442 session->children.erase( "Simulator" );
00443 session->children.erase( "Emulator" );
00444 session->children.erase( "Environment" );
00445 session->children.erase( "Import" );
00446 return m_tree.ToXMLString();
00447 }
00448 else if( level == "Detail"){
00449 return m_tree.ToXMLString();
00450 }
00451 else{
00452 THROW_RUNTIME_ERROR(
00453 "An unknown ouput level '%s' is specified in the"
00454 "'/Session/Environment/OutputXML/@Level'\n"
00455 "This parameter must be one of the following strings : \n"
00456 "[Detail, BasicResult, Result, Minimum]",
00457 level.c_str()
00458 );
00459 return m_tree.ToXMLString();
00460 }
00461 }
00462
00463
00464 bool ParamDB::GetSourceXMLFile( const ParamXMLPath& parameterPath, String& sourceFile )
00465 {
00466 if(m_isLoaded){
00467 return m_tree.GetSourceXMLFile( parameterPath, sourceFile );
00468 }
00469
00470 return false;
00471 }
00472
00473 void ParamDB::Set( const ParamXMLPath& path, const String& val )
00474 {
00475 m_tree.Set( path, val );
00476 }
00477
00478 bool ParamDB::Get(const ParamXMLPath& path, String* value, bool required)
00479 {
00480 ParamXMLTree::NodeStatus status;
00481 bool ret = m_tree.Get( path, value, &status );
00482
00483 if( !ret && required && status.stRequireDefault ){
00484 THROW_RUNTIME_ERROR(
00485 "error: %s is not found in the default parameters.",
00486 path.ToString().c_str()
00487 );
00488 }
00489
00490 return ret;
00491 }
00492
00493 size_t ParamDB::GetElementCount(const ParamXMLPath& path)
00494 {
00495 ParamXMLTree::NodeArray* nodeArray =
00496 m_tree.GetNodeArray( path );
00497 if( !nodeArray )
00498 return 0;
00499
00500 return nodeArray->size();
00501 }
00502
00503
00504 ParamXMLTree& ParamDB::GetXMLTree()
00505 {
00506 return m_tree;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515 void ParamDB::ToParam( bool* dst, const ParamXMLPath& path, const String& str )
00516 {
00517 ToParamRaw( dst, path, str );
00518 }
00519
00520 void ParamDB::ToParam( String* dst, const ParamXMLPath& path, const String& str )
00521 {
00522 ToParamRaw( dst, path, str );
00523 }
00524
00525 void ParamDB::ToParam( std::string* dst, const ParamXMLPath& path, const String& str )
00526 {
00527 ToParamRaw( dst, path, str );
00528 }