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 "Sim/Foundation/Resource/Builder/ResourceBuilder.h"
00038
00039 using namespace std;
00040 using namespace boost;
00041 using namespace Onikiri;
00042
00043 static int INVALID_NODE_COUNT = -1;
00044 static int INVALID_NODE_CLUSTER = -1;
00045
00046 static const char g_configNamePath[] = "/Session/Simulator/@Configuration";
00047 static const char g_configRootPath[] = "/Session/Simulator/Configurations/";
00048 static const char g_resultRootPath[] = "/Session/Result/Resource/";
00049
00050 ResourceBuilder::ResNode::ResNode()
00051 {
00052 count = INVALID_NODE_COUNT;
00053 cluster = INVALID_NODE_CLUSTER;
00054 copyCount = INVALID_NODE_COUNT;
00055 external = false;
00056 }
00057
00058 ResourceBuilder::ResourceBuilder()
00059 {
00060 m_rootNode = ResNodePtr( new ResNode() );
00061 }
00062
00063 ResourceBuilder::~ResourceBuilder()
00064 {
00065 Release();
00066 }
00067
00068
00069 void ResourceBuilder::Release()
00070 {
00071 for( size_t i = 0; i < m_instanceList.size(); i++ ){
00072 m_instanceList[i]->Finalize();
00073 }
00074
00075 m_rootNode->children.clear();
00076 m_constMap.clear();
00077
00078 for( size_t i = 0; i < m_instanceList.size(); i++ ){
00079 delete m_instanceList[i];
00080 }
00081 m_instanceList.clear();
00082 }
00083
00084 ParamXMLPath ResourceBuilder::GetConfigurationPath()
00085 {
00086
00087 ParamXMLPath cfgNamePath = g_configNamePath;
00088 String cfgName;
00089 g_paramDB.Get( cfgNamePath, &cfgName );
00090
00091
00092 ParamXMLPath cfgPath = g_configRootPath + cfgName;
00093
00094 XMLNodeArray* copyNodes =
00095 g_paramDB.GetXMLTree().GetNodeArray( cfgPath );
00096
00097 if( copyNodes == NULL ){
00098 THROW_RUNTIME_ERROR(
00099 "The specified configuration '%s' (%s) is not found.",
00100 cfgName.c_str(),
00101 cfgPath.ToString().c_str()
00102 );
00103 }
00104
00105
00106 return cfgPath;
00107 }
00108
00109
00110 void ResourceBuilder::LoadConstantSection( const ParamXMLPath& rootPath )
00111 {
00112 ParamXMLPath constPath = rootPath + "Constant";
00113 ParamXMLTree& tree = g_paramDB.GetXMLTree();
00114
00115 XMLNodePtr constantNode =
00116 tree.GetNode( constPath );
00117
00118 if( constantNode == NULL ){
00119 return;
00120 }
00121
00122 XMLAttributeMap& attributes =
00123 constantNode->attributes;
00124
00125 for( XMLAttributeMap::iterator i = attributes.begin();
00126 i != attributes.end();
00127 ++i
00128 ){
00129 m_constMap[i->first] =
00130 lexical_cast<int>( i->second->value );
00131 i->second->accessed = true;
00132 }
00133
00134 }
00135
00136
00137
00138
00139
00140 void ResourceBuilder::LoadParameterSection( const ParamXMLPath& rootPath )
00141 {
00142 ParamXMLPath parameterBasePath = rootPath + "Parameter";
00143
00144 ParamXMLTree& tree =
00145 g_paramDB.GetXMLTree();
00146
00147 XMLNodePtr xmlParent = tree.GetNode( parameterBasePath );
00148 if( xmlParent == NULL ){
00149 return;
00150 }
00151
00152 for( XMLChildMap::iterator children = xmlParent->children.begin();
00153 children != xmlParent->children.end();
00154 ++children
00155 ){
00156 for( size_t childIndex = 0; childIndex < children->second.size(); childIndex++ ){
00157 XMLNodePtr xmlNode = children->second[childIndex];
00158
00159 ParamXMLPath paramPath = parameterBasePath;
00160 paramPath.AddArray( xmlNode->name, (int)childIndex );
00161 const ParamXMLPath& namePath = paramPath + "@Name";
00162
00163
00164 String name;
00165 bool hit = g_paramDB.Get( namePath.ToString(), &name, false );
00166 if( !hit ){
00167 THROW_RUNTIME_ERROR(
00168 "'%s' does not have 'Name' attribute.\n"
00169 "A node in a 'Parameter' section must have 'Name' attribute.",
00170 paramPath.ToString().c_str()
00171 );
00172 }
00173
00174 ResNodeMap::iterator entry = m_resNodeMap.find( name );
00175 if( entry == m_resNodeMap.end() ){
00176 THROW_RUNTIME_ERROR(
00177 "The node of the name '%s' is not found in the 'Structure' section.\n"
00178 "All nodes in a 'Parameter' section must be defined in a 'Structure' section.\n"
00179 "path: %s",
00180 name.c_str(),
00181 paramPath.ToString().c_str()
00182 );
00183 }
00184
00185 entry->second->paramPath = paramPath.ToString();
00186
00187
00188 ParamXMLPath resultPath = g_resultRootPath;
00189 resultPath.AddArray( xmlNode->name, (int)childIndex );
00190 entry->second->resultPath = resultPath.ToString();
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 int ResourceBuilder::GetStructureNodeValue(
00202 const XMLNodePtr node, const String& attrName )
00203 {
00204 XMLAttributeMap::iterator attr = node->attributes.find( attrName );
00205 if( attr == node->attributes.end() ){
00206 return INVALID_NODE_COUNT;
00207 }
00208
00209 const String& valueStr = attr->second->value;
00210 attr->second->accessed = true;
00211
00212 map<String, int>::iterator i = m_constMap.find( valueStr );
00213 if( i != m_constMap.end() ){
00214 return i->second;
00215 }
00216 else{
00217 return lexical_cast<int>( valueStr );
00218 }
00219 }
00220
00221 String ResourceBuilder::GetStructureNodeString(
00222 const XMLNodePtr node, const String& attrName )
00223 {
00224 XMLAttributeMap::iterator attr = node->attributes.find( attrName );
00225 if( attr != node->attributes.end() ){
00226 attr->second->accessed = true;
00227 return attr->second->value;
00228 }
00229 else{
00230 return "";
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239 void ResourceBuilder::TraverseStructureNode(ResNodePtr resParent, XMLNodePtr xmlParent, int copyCount)
00240 {
00241 for( XMLChildMap::iterator children = xmlParent->children.begin();
00242 children != xmlParent->children.end();
00243 ++children
00244 ){
00245 for( size_t childIndex = 0; childIndex < children->second.size(); childIndex++ ){
00246 XMLNodePtr xmlNode = children->second[childIndex];
00247 ResNodePtr resNode( new ResNode );
00248
00249 const String& type = xmlNode->name;
00250
00251 if( type == "Connection" ){
00252
00253 ResNode::Child child;
00254 child.name = GetStructureNodeString( xmlNode, "Name" );
00255 child.to = GetStructureNodeString( xmlNode, "To" );
00256 resParent->children.push_back( child );
00257 }
00258 else{
00259
00260 resNode->type = type;
00261 resNode->name = GetStructureNodeString( xmlNode, "Name" );
00262 resNode->count = GetStructureNodeValue( xmlNode, "Count" );
00263 resNode->cluster = GetStructureNodeValue( xmlNode, "Cluster" );
00264
00265 if( resNode->count != INVALID_NODE_COUNT){
00266 resNode->copyCount = copyCount;
00267 }
00268
00269
00270
00271 String connectionTo = GetStructureNodeString( xmlNode, "To" );
00272
00273 ResNodeMap::iterator entry = m_resNodeMap.find( resNode->name );
00274 if(entry != m_resNodeMap.end()){
00275
00276 ResNodePtr entryPtr = entry->second;
00277
00278 ResNode::Child child;
00279 child.node = entryPtr;
00280 child.to = connectionTo;
00281 resParent->children.push_back( child );
00282
00283 if( entryPtr->type != resNode->type ){
00284 THROW_RUNTIME_ERROR(
00285 "The node '%s' is re-defined by the different type '%s' in the 'Structure' section.\n"
00286 "The original type of the node is '%s'.",
00287 resNode->name.c_str(),
00288 resNode->type.c_str(),
00289 entryPtr->type.c_str()
00290 );
00291 }
00292
00293 if( entryPtr->count != resNode->count &&
00294 entryPtr->count != INVALID_NODE_COUNT &&
00295 resNode->count != INVALID_NODE_COUNT
00296 ){
00297 THROW_RUNTIME_ERROR(
00298 "The count of '%s' is re-defined in 'Structure' section.",
00299 resNode->name.c_str()
00300 );
00301 }
00302
00303 if( entryPtr->copyCount != resNode->copyCount &&
00304 entryPtr->copyCount != INVALID_NODE_COUNT &&
00305 resNode->copyCount != INVALID_NODE_COUNT
00306 ){
00307 THROW_RUNTIME_ERROR(
00308 "The copy count of '%s' is re-defined in 'Structure' section.",
00309 resNode->name.c_str()
00310 );
00311 }
00312
00313 if( entryPtr->cluster != resNode->cluster && entryPtr->cluster != INVALID_NODE_CLUSTER ){
00314 THROW_RUNTIME_ERROR(
00315 "The cluster of '%s' is re-defined in 'Structure' section.",
00316 resNode->name.c_str()
00317 );
00318 }
00319
00320 if( resNode->count != INVALID_NODE_COUNT ){
00321 entryPtr->count = resNode->count;
00322 }
00323
00324 if( resNode->copyCount != INVALID_NODE_COUNT ){
00325 entryPtr->copyCount = resNode->copyCount;
00326 }
00327
00328 if( resNode->cluster != INVALID_NODE_CLUSTER ){
00329 entryPtr->cluster = resNode->cluster;
00330 }
00331
00332 resNode = entryPtr;
00333 }
00334 else{
00335
00336
00337 m_resNodeMap[resNode->name] = resNode;
00338
00339 ResNode::Child child;
00340 child.node = resNode;
00341 child.to = connectionTo;
00342 resParent->children.push_back( child );
00343 }
00344 }
00345
00346 TraverseStructureNode( resNode, xmlNode, copyCount );
00347 }
00348 }
00349 }
00350
00351
00352
00353 void ResourceBuilder::LoadStructureSection(const ParamXMLPath& structPath)
00354 {
00355 const ParamXMLPath& copyPath = structPath + "/Structure/Copy";
00356
00357 ParamXMLTree& tree =
00358 g_paramDB.GetXMLTree();
00359
00360 XMLNodeArray* copyNodes =
00361 tree.GetNodeArray( copyPath );
00362
00363 if( !copyNodes ){
00364 THROW_RUNTIME_ERROR(
00365 "The 'Structure' node '%s' does not have any copy node.",
00366 (structPath + "Structure").ToString().c_str()
00367 );
00368 }
00369
00370 for( size_t i = 0; i < copyNodes->size(); i++ ){
00371
00372 XMLNodePtr copyNode = copyNodes->at(i);
00373 int copyCount = GetStructureNodeValue( copyNode, "Count" );
00374
00375 if( copyCount == INVALID_NODE_COUNT ){
00376 THROW_RUNTIME_ERROR(
00377 "The 'Copy' node ('%s') does not have a 'Count' attribute.",
00378 copyPath.ToString().c_str()
00379 );
00380 }
00381
00382 TraverseStructureNode( m_rootNode, copyNode, copyCount );
00383 }
00384 }
00385
00386
00387
00388 void ResourceBuilder::ConstructResources()
00389 {
00390 vector<int> tidList;
00391 vector<int> pidList;
00392
00393 for( ResNodeMap::iterator i = m_resNodeMap.begin();
00394 i != m_resNodeMap.end();
00395 ++i
00396 ){
00397 ResNodePtr node = i->second;
00398 int count = node->count;
00399
00400 if( node->external )
00401 continue;
00402
00403 for( int rid = 0; rid < count; rid++ ){
00404
00405 PhysicalResourceNode* res =
00406 m_factory.CreateInstance( node->type );
00407 PhysicalResourceNodeInfo info;
00408
00409 info.name = node->name;
00410 info.typeName = node->type;
00411 info.paramPath = node->paramPath;
00412 info.resultRootPath = node->resultPath;
00413 info.resultPath.SetArray( node->resultPath, "Result", rid );
00414
00415 if( info.paramPath.ToString() == "" ){
00416 THROW_RUNTIME_ERROR(
00417 "The node '%s' does not have its parameter node in the parameter XML.\n"
00418 "A node in the 'Structure' section must have its parameter node "
00419 "in the 'Parameter' section.",
00420 info.name.c_str()
00421 );
00422 }
00423
00424 res->SetInfo( info );
00425 res->SetRID( rid );
00426
00427 node->instances.push_back( res );
00428 m_instanceList.push_back( res );
00429
00430
00431
00432
00433 int copyCount = node->copyCount;
00434 if( copyCount < count ){
00435 THROW_RUNTIME_ERROR(
00436 "The resource count is greater than the copy count.\n"
00437 "Node:%s Copy Count:%d Resouce Count:%d",
00438 info.name.c_str(),
00439 copyCount,
00440 count
00441 );
00442 }
00443 if( copyCount % count != 0 ){
00444 THROW_RUNTIME_ERROR(
00445 "The copy count is not divided by the resource count.\n"
00446 "Copy Count:%d Resouce Count:%d",
00447 info.name.c_str(),
00448 copyCount,
00449 count
00450 );
00451 }
00452 int tidCount = copyCount / count;
00453 res->SetThreadCount( tidCount );
00454 for( int i = 0; i < tidCount; i++ ){
00455 res->SetTID( i, rid*tidCount+i );
00456 }
00457
00458 #if 0
00459
00460 CalculateID( tidList, rid, node->copyCount, node, CALC_ID_THREAD );
00461 res->SetThreadCount( tidList.size() );
00462 for( size_t i = 0; i < tidList.size(); i++ ){
00463 res->SetTID( i, tidList[i] );
00464 }
00465
00466
00467 CalculateID( pidList, rid, m_processCount, node, CALC_ID_PROCESS );
00468 res->SetProcessCount( pidList.size() );
00469 for( size_t i = 0; i < pidList.size(); i++ ){
00470 res->SetPID( i, pidList[i] );
00471 }
00472 #endif
00473 }
00474 }
00475 }
00476
00477
00478 void ResourceBuilder::ConnectResources()
00479 {
00480 PhysicalResourceArray< PhysicalResourceNode > arrayArg;
00481
00482 for( ResNodeMap::iterator i = m_resNodeMap.begin();
00483 i != m_resNodeMap.end();
00484 ++i
00485 ){
00486 vector< ResNode::Child >& children = i->second->children;
00487 vector< PhysicalResourceNode* >& instances = i->second->instances;
00488
00489 for( vector< ResNode::Child >::iterator child = children.begin();
00490 child != children.end();
00491 ++child
00492 ){
00493
00494 ResNodePtr childNode;
00495 if( child->node != NULL ){
00496
00497 childNode = child->node;
00498 }
00499 else{
00500
00501 ResNodeMap::iterator childNodeIterator =
00502 m_resNodeMap.find( child->name );
00503 if( childNodeIterator == m_resNodeMap.end() ){
00504 THROW_RUNTIME_ERROR(
00505 "The node '%s' is not defined. "
00506 "This node is in the '%s'.",
00507 child->name.c_str(),
00508 i->second->name.c_str()
00509 );
00510 }
00511 childNode = childNodeIterator->second;
00512 }
00513
00514 vector< PhysicalResourceNode* >&
00515 childInstances = childNode->instances;
00516
00517 if( instances.size() < childInstances.size() ){
00518
00519 ASSERT( childInstances.size() % instances.size() == 0 );
00520 for( size_t i = 0; i < instances.size(); i++ ){
00521
00522 size_t childrenCount = childInstances.size() / instances.size();
00523 arrayArg.Resize( (int)childrenCount );
00524 for( size_t c = 0; c < childrenCount; c++ ){
00525 arrayArg[(int)c] = childInstances[ i*childrenCount + c ];
00526 }
00527 instances[i]->ConnectResource( arrayArg, childNode->name, child->to, false );
00528 }
00529 }
00530 else{
00531
00532
00533 ASSERT( instances.size() % childInstances.size() == 0 );
00534 for( size_t i = 0; i < instances.size(); i++ ){
00535 arrayArg.Resize( 1 );
00536 size_t childIndex = i*childInstances.size()/instances.size();
00537 arrayArg[0] = childInstances[ childIndex ];
00538 instances[i]->ConnectResource( arrayArg, childNode->name, child->to, false );
00539 }
00540 }
00541 }
00542
00543 }
00544 }
00545
00546
00547 void ResourceBuilder::InitializeNodes( PhysicalResourceNode::InitPhase phase )
00548 {
00549 for( ResNodeMap::iterator i = m_resNodeMap.begin();
00550 i != m_resNodeMap.end();
00551 ++i
00552 ){
00553 ResNodePtr node = i->second;
00554 for( int rid = 0; rid < node->count; rid++ ){
00555 node->instances[rid]->Initialize( phase );
00556 }
00557 }
00558 }
00559
00560
00561 void ResourceBuilder::ValidateConnection()
00562 {
00563 for( ResNodeMap::iterator i = m_resNodeMap.begin();
00564 i != m_resNodeMap.end();
00565 ++i
00566 ){
00567 ResNodePtr node = i->second;
00568 for( int rid = 0; rid < node->count; rid++ ){
00569 node->instances[rid]->ValidateConnection();
00570 }
00571 }
00572 }
00573
00574
00575 void ResourceBuilder::SetExternalResource( ResNode* node )
00576 {
00577 ResNodePtr nodePtr = ResNodePtr( new ResNode() );
00578 *nodePtr = *node;
00579 nodePtr->external = true;
00580 m_resNodeMap[node->name] = nodePtr;
00581 }
00582
00583
00584
00585
00586 void ResourceBuilder::Construct()
00587 {
00588 const ParamXMLPath& cfgPath = GetConfigurationPath();
00589
00590 LoadConstantSection( cfgPath );
00591 LoadStructureSection( cfgPath );
00592 LoadParameterSection( cfgPath );
00593
00594
00595
00596 ConstructResources();
00597 InitializeNodes( PhysicalResourceNode::INIT_PRE_CONNECTION );
00598 ConnectResources();
00599 ValidateConnection();
00600 InitializeNodes( PhysicalResourceNode::INIT_POST_CONNECTION );
00601
00602 }
00603
00604
00605 void ResourceBuilder::Dump()
00606 {
00607 printf("--- ResNode connection : \n");
00608 for( ResNodeMap::iterator i = m_resNodeMap.begin();
00609 i != m_resNodeMap.end();
00610 ++i
00611 ){
00612 printf(
00613 "%s : %s : %d\n",
00614 i->second->type.c_str(),
00615 i->second->name.c_str(),
00616 i->second->count
00617 );
00618
00619 for( size_t j = 0; j < i->second->children.size(); j++ ){
00620 ResNode::Child child = i->second->children[j];
00621 if( child.node != NULL ){
00622 ResNodePtr ptr = child.node;
00623 printf(
00624 " %s : %s : %d\n",
00625 ptr->type.c_str(),
00626 ptr->name.c_str(),
00627 ptr->count
00628 );
00629 }
00630 else{
00631 printf(
00632 " Connection : %s : %s\n",
00633 child.name.c_str(),
00634 child.to.c_str()
00635 );
00636 }
00637 }
00638 }
00639
00640 printf("\n--- Constant list : \n");
00641 for( ConstantMap::iterator i = m_constMap.begin();
00642 i != m_constMap.end();
00643 ++i
00644 ){
00645 printf( "%s : %d\n", i->first.c_str(), i->second );
00646 }
00647
00648 printf("\n--- ResNode list : \n");
00649 for( ResNodeMap::iterator i = m_resNodeMap.begin();
00650 i != m_resNodeMap.end();
00651 ++i
00652 ){
00653 for( size_t j = 0; j < i->second->instances.size(); j++ ){
00654 PhysicalResourceNode* res = i->second->instances[j];
00655 printf( "%s tid(", i->second->name.c_str() );
00656 for( int ti = 0; ti < res->GetThreadCount(); ti++ ){
00657 printf( "%d", res->GetTID( ti ) );
00658 if( ti + 1 < res->GetThreadCount() )
00659 printf(",");
00660 }
00661 printf( ")\n" );
00662
00663
00664
00665
00666
00667
00668
00669 }
00670 }
00671 }
00672
00673