Salome HOME
Merge branch 'master' into omu/workloadmanager
[modules/yacs.git] / src / runtime / SalomeHPContainer.cxx
index 12f9ddd614e58e0a0e15965a550109cd9e37a427..2d136da6e0cd6674136e021127568e64a0fc354f 100644 (file)
 #include "SalomeHPComponent.hxx"
 #include "SalomeContainerTmpForHP.hxx"
 #include "AutoLocker.hxx"
-#include "AutoRefCnt.hxx"
 
 #include <algorithm>
+#include <utility>
 
 using namespace YACS::ENGINE;
 
 const char SalomeHPContainer::KIND[]="HPSalome";
 
-SalomeHPContainerBase::SalomeHPContainerBase(SalomeHPContainerVectOfHelper *resShared):_launchModeType(resShared),_shutdownLevel(999)
+SalomeHPContainer::SalomeHPContainer():_shutdownLevel(999)
 {
 }
 
-SalomeHPContainerBase::SalomeHPContainerBase(const SalomeHPContainerBase& other):_shutdownLevel(999),_launchModeType(new SalomeHPContainerVectOfHelper),_initScript(other._initScript)
+SalomeHPContainer::SalomeHPContainer(const SalomeHPContainer& other):_componentNames(other._componentNames),_shutdownLevel(999),_sct(other._sct),_initScript(other._initScript)
 {
 }
 
-SalomeHPContainer *SalomeHPContainerBase::getTheBoss()
+void SalomeHPContainer::assignPG(const PlayGround *pg)
 {
-  HomogeneousPoolContainer *ret(this);
-  while(ret->getDirectFather())
-    ret=ret->getDirectFather();
-  SalomeHPContainer *retC(dynamic_cast<SalomeHPContainer *>(ret));
-  if(!retC)
-    throw Exception("SalomeHPContainerBase::getTheBoss : unexpected type of object !");
-  return retC;
+  HomogeneousPoolContainer::assignPG(pg);
+  int nbOfWorkers(getPG()->getNumberOfWorkers(this->getNumberOfCoresPerWorker()));
+  this->setSizeOfPool(nbOfWorkers);
 }
 
-const SalomeHPContainer *SalomeHPContainerBase::getTheBoss() const
+void SalomeHPContainer::setSizeOfPool(int sz)
 {
-  const HomogeneousPoolContainer *ret(this);
-  while(ret->getDirectFather())
-    ret=ret->getDirectFather();
-  const SalomeHPContainer *retC(dynamic_cast<const SalomeHPContainer *>(ret));
-  if(!retC)
-    throw Exception("SalomeHPContainerBase::getTheBoss : unexpected type of object !");
-  return retC;
+  _launchModeType.resize(sz);
 }
 
-void SalomeHPContainerBase::startInternal(const Task *askingNode, SalomeContainerToolsBase& sct, const std::vector<std::string>& compoNames)
+int SalomeHPContainer::getSizeOfPool() const
 {
-  SalomeContainerMonoHelper *helper(_launchModeType->getHelperOfTaskThreadSafe(askingNode));
-  SalomeContainerTools::Start(compoNames,helper,sct,_shutdownLevel,this,askingNode);
+  return _launchModeType.size();
 }
 
-void SalomeHPContainerBase::shutdown(int level)
+std::size_t SalomeHPContainer::getNumberOfFreePlace() const
 {
-  if(level < _shutdownLevel)
-      return;
-  _shutdownLevel=999;
-  _launchModeType->shutdown();
+  return getPG()->getNumberOfFreePlace(this->getNumberOfCoresPerWorker());
 }
 
-SalomeHPContainerBase::SalomeHPContainerBase(SalomeHPContainerVectOfHelper *resShared, bool isRefEaten):_launchModeType(resShared)
+class PairVecIterator : public std::iterator<
+                        std::input_iterator_tag,     // iterator_category
+                        std::pair<const Task *,std::size_t>,                    // value_type
+                        long,                        // difference_type
+                        const std::pair<const Task *,std::size_t>*,             // pointer
+                        std::pair<const Task *,std::size_t> > // reference
 {
-  if(!isRefEaten)
-    if(_launchModeType.isNotNull())
-      _launchModeType->incrRef();
-}
+  const std::vector< const Task *> *_v0;
+  const std::vector<std::size_t> *_v1;
+  std::size_t _num;
+public:
+  explicit PairVecIterator(const std::vector< const Task * > *v0, const std::vector<std::size_t> *v1, const std::size_t num) : _v0(v0),_v1(v1),_num(num) { }
+  PairVecIterator& operator++() { _num++; return *this; }
+  bool operator==(PairVecIterator other) const { return _num == other._num; }
+  bool operator!=(PairVecIterator other) const { return !(*this == other); }
+  reference operator*() const { return std::pair<const Task *,std::size_t>((*_v0)[_num],(*_v1)[_num]); }
+};
 
-bool SalomeHPContainerBase::isAlreadyStarted(const Task *askingNode) const
+void SalomeHPContainer::allocateFor(const std::vector<const Task *>& nodes)
 {
-  const SalomeContainerMonoHelper *helper(_launchModeType->getHelperOfTaskThreadSafe(askingNode));
-  return helper->isAlreadyStarted(askingNode);
+  std::vector<std::size_t> workerIdsAllocated(getPG()->allocateFor(nodes.size(),this->getNumberOfCoresPerWorker()));
+  std::vector<std::pair<const Task *,std::size_t>> nodesAndIds(PairVecIterator(&nodes,&workerIdsAllocated,0),PairVecIterator(&nodes,&workerIdsAllocated,nodes.size()));
+  _launchModeType.allocateForCrude(nodesAndIds);
 }
 
-void SalomeHPContainerBase::release(const Task *node)
+void SalomeHPContainer::release(const Task *node)
 {
-  _launchModeType->release(node);
+  std::size_t workerId(_launchModeType.release(node));
+  getPG()->release(workerId,this->getNumberOfCoresPerWorker());
 }
 
-void SalomeHPContainerBase::lock()
+SalomeHPContainer::~SalomeHPContainer()
 {
-  _launchModeType->lock();
 }
 
-void SalomeHPContainerBase::unLock()
+std::string SalomeHPContainer::getKind() const
 {
-  _launchModeType->unLock();
+  return KIND;
 }
 
-void SalomeHPContainerBase::setSizeOfPool(int sz)
+std::string SalomeHPContainer::getDiscreminantStrOfThis(const Task *askingNode) const
 {
-  _launchModeType->resize(sz);
+  YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(this,askingNode));
+  return tmpCont->getDiscreminantStrOfThis(askingNode);
 }
 
-int SalomeHPContainerBase::getSizeOfPool() const
+bool SalomeHPContainer::isAlreadyStarted(const Task *askingNode) const
 {
-  return _launchModeType->size();
+  const SalomeContainerMonoHelper *helper(_launchModeType.getHelperOfTaskThreadSafe(this,askingNode));
+  return helper->isAlreadyStarted(askingNode);
 }
 
-void SalomeHPContainerBase::setProperty(const std::string& name,const std::string& value)
+void SalomeHPContainer::start(const Task *askingNode) 
 {
-  if(name==AOC_ENTRY)//no sense to set it ! It is always true ! ignore it !
-    return ;
-  else if(name==SIZE_OF_POOL_KEY)
-    {
-      std::istringstream iss(value);
-      int val(0);
-      iss >> val;
-      setSizeOfPool(val);
-    }
-  else if(name==INITIALIZE_SCRIPT_KEY)
-    {
-      _initScript=value;
-    }
-  else
-    getTheBoss()->getContainerInfo().setProperty(name,value);
+  SalomeContainerMonoHelper *helper(_launchModeType.getHelperOfTaskThreadSafe(this,askingNode));
+  SalomeContainerToolsDecorator sctDeco(&_sct,this->getPG(),&_launchModeType,askingNode,this->getNumberOfCoresPerWorker());
+  SalomeContainerTools::Start(_componentNames,helper,_sct,_shutdownLevel,this,askingNode);
 }
 
-std::string SalomeHPContainerBase::getProperty(const std::string& name) const
+void SalomeHPContainer::shutdown(int level)
 {
-  if(name==AOC_ENTRY)
-    {
-      return std::string("1");
-    }
-  else if(name==SIZE_OF_POOL_KEY)
-    {
-      std::ostringstream oss; oss << getSizeOfPool();
-      return oss.str();
-    }
-  else if(name==INITIALIZE_SCRIPT_KEY)
+  if(level < _shutdownLevel)
+      return;
+  _shutdownLevel=999;
+  for(std::size_t i=0;i<_launchModeType.size();i++)
     {
-      return _initScript;
+      SalomeContainerMonoHelper *helper(_launchModeType.at(i));
+      helper->shutdown();
     }
-  else
-    return getTheBoss()->getContainerInfo().getProperty(name);
 }
 
-std::map<std::string,std::string> SalomeHPContainerBase::getProperties() const
+std::string SalomeHPContainer::getPlacementId(const Task *askingNode) const
 {
-  std::map<std::string,std::string> ret(getTheBoss()->getContainerInfo().getProperties());
-  std::ostringstream oss; oss << getSizeOfPool();
-  ret[SIZE_OF_POOL_KEY]=oss.str();
-  if(!_initScript.empty())
-    ret[INITIALIZE_SCRIPT_KEY]=_initScript;
-  return ret;
-}
-
-void SalomeHPContainerBase::clearProperties()
-{
-  _initScript.clear();
-  getTheBoss()->getContainerInfo().clearProperties();
-}
-
-std::string SalomeHPContainerBase::getPlacementId(const Task *askingNode) const
-{
-  const SalomeContainerMonoHelper *helper(0);
+  const SalomeContainerMonoHelper *helper(nullptr);
   {
-    YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainerBase *>(this));
-    helper=_launchModeType->getHelperOfTask(askingNode);
+    std::lock_guard<std::mutex> lg(getPG()->getLocker());
+    helper=_launchModeType.getHelperOfTask(askingNode);
   }
   return SalomeContainerTools::GetPlacementId(helper,this,askingNode);
 }
 
-std::string SalomeHPContainerBase::getFullPlacementId(const Task *askingNode) const
+std::string SalomeHPContainer::getFullPlacementId(const Task *askingNode) const
 {
-  const SalomeContainerMonoHelper *helper(0);
+  const SalomeContainerMonoHelper *helper(nullptr);
   {
-    YACS::BASES::AutoLocker<Container> alckCont(const_cast<SalomeHPContainerBase *>(this));
-    helper=_launchModeType->getHelperOfTask(askingNode);
+    std::lock_guard<std::mutex> lg(getPG()->getLocker());
+    helper=_launchModeType.getHelperOfTask(askingNode);
   }
   return SalomeContainerTools::GetFullPlacementId(helper,this,askingNode);
 }
 
-std::map<std::string,std::string> SalomeHPContainerBase::getResourceProperties(const std::string& name) const
-{
-  return getTheBoss()->getResourceProperties(name);
-}
-
-void SalomeHPContainerBase::addComponentName(const std::string& name)
-{
-  getTheBoss()->addComponentNameSpe(name);
-}
-
-void SalomeHPContainerBase::checkCapabilityToDealWith(const ComponentInstance *inst) const throw(YACS::Exception)
-{
-  getTheBoss()->checkCapabilityToDealWith(inst);
-}
-
-YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> SalomeHPContainerBase::decorate(YACS::BASES::AutoConstRefCnt<PartDefinition> pd)
-{
-  YACS::BASES::AutoRefCnt<HomogeneousPoolContainer> ret(new SalomeHPContainerShared(pd,_launchModeType,this));
-  return ret;
-}
-
-Engines::Container_var SalomeHPContainerBase::getContainerPtr(const Task *askingNode) const
-{
-  const SalomeContainerMonoHelper *helper(0);
-  {
-    YACS::BASES::AutoLocker<SalomeHPContainerBase> alck(const_cast<SalomeHPContainerBase *>(this));
-    helper=_launchModeType->getHelperOfTask(askingNode);
-  }
-  return helper->getContainer(NULL);
-}
-
-std::vector<std::string> SalomeHPContainerBase::getKernelContainerNames() const
-{
-  return _launchModeType->getKernelContainerNames();
-}
-
-////////////////
-
-SalomeHPContainer::SalomeHPContainer():SalomeHPContainerBase(new SalomeHPContainerVectOfHelper)
-{
-}
-
-SalomeHPContainer::SalomeHPContainer(const SalomeHPContainer& other):SalomeHPContainerBase(other),_sct(other._sct),_componentNames(other._componentNames)
-{
-}
-
-std::size_t SalomeHPContainer::getNumberOfFreePlace() const
-{
-  return _launchModeType->getNumberOfFreePlace();
-}
-
-void SalomeHPContainer::allocateFor(const std::vector<const Task *>& nodes)
-{
-  _launchModeType->allocateFor(nodes);
-}
-
-SalomeHPContainer::~SalomeHPContainer()
-{
-}
-
-std::string SalomeHPContainer::getKind() const
-{
-  return KIND;
-}
-
-std::string SalomeHPContainer::getDiscreminantStrOfThis(const Task *askingNode) const
-{
-  YACS::BASES::AutoCppPtr<SalomeContainerTmpForHP> tmpCont(SalomeContainerTmpForHP::BuildFrom(this,askingNode));
-  return tmpCont->getDiscreminantStrOfThis(askingNode);
-}
-
-void SalomeHPContainer::start(const Task *askingNode) throw(YACS::Exception)
-{
-  startInternal(askingNode,_sct,_componentNames);
-}
-
 /*!
  * It is not a bug here ! clone for homogeneous container is not supposed to be copied !
  */
@@ -275,100 +164,82 @@ Container *SalomeHPContainer::cloneAlways() const
   return new SalomeHPContainer(*this);
 }
 
-int SalomeHPContainer::getNumberOfCoresPerWorker() const
-{
-  return _sct.getNumberOfCoresPerWorker();
-}
-
-std::map<std::string,std::string> SalomeHPContainer::getResourcePropertiesSpe(const std::string& name) const
-{
-  return _sct.getResourceProperties(name);
-}
-
-void SalomeHPContainer::addComponentNameSpe(const std::string& name)
-{
-  _componentNames.push_back(name);
-}
-
-void SalomeHPContainer::checkCapabilityToDealWithSpe(const ComponentInstance *inst) const throw(YACS::Exception)
-{
-  if(inst->getKind()!=SalomeHPComponent::KIND)
-    throw Exception("SalomeHPContainer::checkCapabilityToDealWithSpe : SalomeContainer is not able to deal with this type of ComponentInstance.");
-}
-
-void SalomeHPContainer::forYourTestsOnly(ForTestOmlyHPContCls *data) const
-{
-  data->setContainerType("HPContainer");
-}
-
-//////////////////////////////////
-
-SalomeHPContainerShared::SalomeHPContainerShared(YACS::BASES::AutoConstRefCnt<PartDefinition> pd, SalomeHPContainerVectOfHelper *resShared, SalomeHPContainerBase *directFather):SalomeHPContainerBase(resShared,false),_pd(pd)
-{
-  if(!directFather)
-    throw Exception("SalomeHPContainerShared : NULL pointer not allowed !");
-  _directFather.takeRef(directFather);
-}
-
-std::string SalomeHPContainerShared::getKind() const
-{
-  return SalomeHPContainer::KIND;
-}
-
-void SalomeHPContainerShared::prepareMaskForExecution() const
+void SalomeHPContainer::setProperty(const std::string& name,const std::string& value)
 {
-  _idsOfKernelContainers=_pd->computeWorkerIdsCovered(getNumberOfCoresPerWorker());
+  if(name==AOC_ENTRY)//no sense to set it ! It is always true ! ignore it !
+    return ;
+  else if(name==SIZE_OF_POOL_KEY)
+    {
+      std::istringstream iss(value);
+      int val(0);
+      iss >> val;
+      setSizeOfPool(val);
+    }
+  else if(name==INITIALIZE_SCRIPT_KEY)
+    {
+      _initScript=value;
+    }
+  else
+    _sct.setProperty(name,value);
 }
 
-/*!
- * It is not a bug here ! clone for homogeneous container is not supposed to be copied !
- */
-Container *SalomeHPContainerShared::clone() const
+std::string SalomeHPContainer::getProperty(const std::string& name) const
 {
-  incrRef();
-  return const_cast<SalomeHPContainerShared*>(this);
+  if(name==AOC_ENTRY)
+    {
+      return std::string("1");
+    }
+  else if(name==SIZE_OF_POOL_KEY)
+    {
+      std::ostringstream oss; oss << getSizeOfPool();
+      return oss.str();
+    }
+  else if(name==INITIALIZE_SCRIPT_KEY)
+    {
+      return _initScript;
+    }
+  else
+    return _sct.getProperty(name);
 }
 
-Container *SalomeHPContainerShared::cloneAlways() const
+void SalomeHPContainer::clearProperties()
 {
-  throw Exception("SalomeHPContainerShared::cloneAlways : you are not supposed to be in this situation ! This type of container has only existence during execution !");
+  _initScript.clear();
+  _sct.clearProperties();
 }
 
-std::string SalomeHPContainerShared::getName() const
+void SalomeHPContainer::addComponentName(const std::string& name)
 {
-  return getTheBoss()->getName();
+  _componentNames.push_back(name);
 }
 
-std::string SalomeHPContainerShared::getDiscreminantStrOfThis(const Task *askingNode) const
+std::map<std::string,std::string> SalomeHPContainer::getProperties() const
 {
-  return getTheBoss()->getDiscreminantStrOfThis(askingNode);
+  std::map<std::string,std::string> ret(_sct.getProperties());
+  std::ostringstream oss; oss << getSizeOfPool();
+  ret[SIZE_OF_POOL_KEY]=oss.str();
+  if(!_initScript.empty())
+    ret[INITIALIZE_SCRIPT_KEY]=_initScript;
+  return ret;
 }
 
-void SalomeHPContainerShared::start(const Task *askingNode) throw(YACS::Exception)
+std::map<std::string,std::string> SalomeHPContainer::getResourceProperties(const std::string& name) const
 {
-  SalomeContainerToolsSpreadOverTheResDecorator sct(&getTheBoss()->getContainerInfo(),_pd->getPlayGround(),_launchModeType,askingNode);
-  startInternal(askingNode,sct,getTheBoss()->getComponentNames());
+  return _sct.getResourceProperties(name);
 }
 
-void SalomeHPContainerShared::allocateFor(const std::vector<const Task *>& nodes)
+void SalomeHPContainer::checkCapabilityToDealWith(const ComponentInstance *inst) const 
 {
-  _launchModeType->allocateForAmong(_idsOfKernelContainers,nodes);
+  if(inst->getKind()!=SalomeHPComponent::KIND)
+    throw Exception("SalomeHPContainer::checkCapabilityToDealWith : SalomeContainer is not able to deal with this type of ComponentInstance.");
 }
 
-std::size_t SalomeHPContainerShared::getNumberOfFreePlace() const
+std::vector<std::string> SalomeHPContainer::getKernelContainerNames() const
 {
-  return _launchModeType->getNumberOfFreePlaceAmong(_idsOfKernelContainers);
+  return _launchModeType.getKernelContainerNames(this);
 }
 
-void SalomeHPContainerShared::forYourTestsOnly(ForTestOmlyHPContCls *data) const
+int SalomeHPContainer::getNumberOfCoresPerWorker() const
 {
-  data->setContainerType("HPContainerShared");
-  data->setPD(_pd);
-  data->setIDS(_idsOfKernelContainers);
+  return _sct.getNumberOfCoresPerWorker();
 }
-
-/*
- * SalomeHPContainerVectOfHelper is an holder of vector of SalomeContainerMonoHelper (holding itself a Kernel Container)
- * SalomeContainerTools is a Engines::ContainerParameters holder. It is the data keeper for GiveContainer invokation.
- * 
- */