Salome HOME
Bug correction EDF12462 (2)
authorAnthony Geay <anthony.geay@edf.fr>
Thu, 3 Mar 2016 18:00:06 +0000 (19:00 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 4 Mar 2016 13:13:37 +0000 (14:13 +0100)
src/engine/ForEachLoop.cxx
src/engine/ForEachLoop.hxx
src/evalyfx/YACSEvalYFX.cxx
src/evalyfx/YACSEvalYFX.hxx
src/evalyfx/YACSEvalYFXPattern.cxx
src/evalyfx/YACSEvalYFXPattern.hxx
src/evalyfx_swig/evalyfx.i
src/evalyfx_swig/test2.py [new file with mode: 0644]

index 3b9dec62cb8baa4e7fe63f4971cda31e067cb6ab..303cc1492ceb5aa9f55f25dadd52d5196de7de3f 100644 (file)
@@ -49,6 +49,8 @@ const char ForEachLoop::NAME_OF_SPLITTERNODE[]="splitter";
 
 const int ForEachLoop::NOT_RUNNING_BRANCH_ID=-1;
 
+const char ForEachLoop::INTERCEPTOR_STR[]="_interceptor";
+
 InterceptorInputPort::InterceptorInputPort(const std::string& name, Node *node, TypeCode* type):AnyInputPort(name,node,type),
                                                                                                 DataPort(name,node,type),Port(node),
                                                                                                 _repr(0)
@@ -877,6 +879,12 @@ YACS::Event ForEachLoop::updateStateOnFailedEventFrom(Node *node, const Executor
     }
 }
 
+void ForEachLoop::InterceptorizeNameOfPort(std::string& portName)
+{
+  std::replace_if(portName.begin(), portName.end(), std::bind1st(std::equal_to<char>(), '.'), '_');
+  portName += INTERCEPTOR_STR;
+}
+
 void ForEachLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort *finalTarget, const std::list<ComposedNode *>& pointsOfView)
 {
   DynParaLoop::buildDelegateOf(port,finalTarget,pointsOfView);
@@ -904,12 +912,10 @@ void ForEachLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort
           // the delegated port belongs to a node child of the ForEachLoop.
           // The name of the delegated port contains dots (bloc.node.outport),
           // whereas the name of the out going port shouldn't do.
-          std::string outputPortName = getPortName(port.first);
-          std::replace_if (outputPortName.begin(), outputPortName.end(),
-                           std::bind1st(std::equal_to<char>(), '.'), '_');
-          outputPortName += "_interceptor";
-          AnySplitOutputPort *newPort=new AnySplitOutputPort(outputPortName,this,newTc);
-          InterceptorInputPort *intercptor=new InterceptorInputPort(outputPortName + "_in",this,port.first->edGetType());
+          std::string outputPortName(getPortName(port.first));
+          InterceptorizeNameOfPort(outputPortName);
+          AnySplitOutputPort *newPort(new AnySplitOutputPort(outputPortName,this,newTc));
+          InterceptorInputPort *intercptor(new InterceptorInputPort(outputPortName + "_in",this,port.first->edGetType()));
           intercptor->setRepr(newPort);
           newTc->decrRef();
           newPort->addRepr(port.first,intercptor);
index d70259618bfaf919f7f1e815785d6437d271f25a..efb9888fb4e6bb2df5b175198a7a2f7e4151d039 100644 (file)
@@ -220,6 +220,9 @@ namespace YACS
       void storeOutValsInSeqForOutOfScopeUse(int rank, int branchNb);
     private:
       int getFinishedId();
+    public:
+      static void InterceptorizeNameOfPort(std::string& portName);
+      static const char INTERCEPTOR_STR[];
     };
   }
 } 
index b3fcb25e360b45bab9a8b3ee1ec1ed410e520696..9e7ef2f3ffac51ceb336a8184b068f83df307be3 100644 (file)
@@ -137,11 +137,21 @@ YACSEvalObserver *YACSEvalYFX::getObserver()
   return _pattern->getObserver();
 }
 
+std::string YACSEvalYFX::getStatusOfRunStr() const
+{
+  return _pattern->getStatusOfRunStr();
+}
+
 std::vector<YACSEvalSeqAny *> YACSEvalYFX::getResults() const
 {
   return _pattern->getResults();
 }
 
+std::vector<YACSEvalSeqAny *> YACSEvalYFX::getResultsInCaseOfFailure(std::vector<unsigned int>& passedIds) const
+{
+  return _pattern->getResultsInCaseOfFailure(passedIds);
+}
+
 YACS::ENGINE::Proc *YACSEvalYFX::getUndergroundGeneratedGraph() const
 {
   return _pattern->getUndergroundGeneratedGraph();
index 14dcc957385eb53be04c1561ab2f1da9009dd678..7f723c4bcf7897b6fdf2a7cab88825daa4fbc9f2 100644 (file)
@@ -58,7 +58,9 @@ public:
   YACSEVALYFX_EXPORT bool run(YACSEvalSession *session, int& nbOfBranches);
   YACSEVALYFX_EXPORT void registerObserver(YACSEvalObserver *observer);
   YACSEVALYFX_EXPORT YACSEvalObserver *getObserver();
+  YACSEVALYFX_EXPORT std::string getStatusOfRunStr() const;
   YACSEVALYFX_EXPORT std::vector<YACSEvalSeqAny *> getResults() const;
+  YACSEVALYFX_EXPORT std::vector<YACSEvalSeqAny *> getResultsInCaseOfFailure(std::vector<unsigned int>& passedIds) const;
   //
   YACSEVALYFX_EXPORT YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const;
   YACSEVALYFX_EXPORT void setParallelizeStatus(bool newVal);
index 8e351fed7538636f08c4496550d9ed25630903a4..7afb739d05cb70ed440fefd3d742e2bef8f200c5 100644 (file)
@@ -27,6 +27,7 @@
 #include "ElementaryNode.hxx"
 #include "RuntimeSALOME.hxx"
 #include "Dispatcher.hxx"
+#include "Executor.hxx"
 #include "InputPort.hxx"
 #include "LinkInfo.hxx"
 #include "TypeCode.hxx"
 #include <limits>
 #include <numeric>
 #include <sstream>
+#include <iterator>
 
 const char YACSEvalYFXPattern::DFT_PROC_NAME[]="YFX";
 
+const char YACSEvalYFXPattern::ST_OK[]="ALL_OK";
+
+const char YACSEvalYFXPattern::ST_FAILED[]="SOME_SAMPLES_FAILED_AND_ALL_OF_THEM_FAILED_DETERMINISTICALLY";
+
+const char YACSEvalYFXPattern::ST_ERROR[]="SOME_SAMPLES_FAILED_BUT_IMPOSSIBLE_TO_CONCLUDE_ON_THEM";
+
+const char YACSEvalYFXRunOnlyPattern::FIRST_FE_SUBNODE_NAME[]="Bloc";
+
 const char YACSEvalYFXRunOnlyPattern::GATHER_NODE_NAME[]="__gather__";
 
 std::vector< YACSEvalInputPort *> YACSEvalYFXPattern::getFreeInputPorts() const
@@ -228,6 +238,25 @@ YACSEvalSeqAny *YACSEvalYFXPattern::BuildValueInPort(YACS::ENGINE::InputPyPort *
     throw YACS::Exception("YACSEvalYFXPattern::GetValueInPort : not implemented yet for other than Double and Int !");
 }
 
+YACSEvalSeqAny *YACSEvalYFXPattern::BuildValueFromEngineFrmt(YACS::ENGINE::SequenceAny *data)
+{
+  unsigned int sz(data->size());
+  std::vector<double> eltCpp(sz);
+  for(unsigned int ii=0;ii<sz;ii++)
+    {
+      YACS::ENGINE::AnyPtr elt((*data)[ii]);
+      YACS::ENGINE::Any *eltPtr((YACS::ENGINE::Any *)elt);
+      YACS::ENGINE::AtomAny *eltPtr2(dynamic_cast<YACS::ENGINE::AtomAny *>(eltPtr));
+      if(!eltPtr2)
+        {
+          std::ostringstream oss; oss << "YACSEvalYFXPattern::BuildValueFromEngineFrmt : error at pos #" << ii << " ! It is not an AtomAny !";
+          throw YACS::Exception(oss.str());
+        }
+      eltCpp[ii]=eltPtr2->getDoubleValue();
+    }
+  return new YACSEvalSeqAnyDouble(eltCpp);
+}
+
 void YACSEvalYFXPattern::cleanScheme()
 {
   if(_ownScheme)
@@ -336,7 +365,7 @@ void YACSEvalYFXRunOnlyPattern::generateGraph()
   _generatedGraph->edAddChild(n2);
   _generatedGraph->edAddCFLink(n1,n2);
   //
-  YACS::ENGINE::Bloc *n10(r->createBloc("Bloc"));
+  YACS::ENGINE::Bloc *n10(r->createBloc(FIRST_FE_SUBNODE_NAME));
   n1->edAddChild(n10);
   YACS::ENGINE::InlineNode *n100(r->createScriptNode(YACS::ENGINE::PythonNode::KIND,"__dispatch__"));
   YACS::ENGINE::Node *n101(_runNode->cloneWithoutCompAndContDeepCpy(0,true));
@@ -454,6 +483,41 @@ YACS::ENGINE::Proc *YACSEvalYFXRunOnlyPattern::getUndergroundGeneratedGraph() co
   return _generatedGraph;
 }
 
+std::string YACSEvalYFXRunOnlyPattern::getStatusOfRunStr() const
+{
+  YACS::StatesForNode st(_generatedGraph->getState());
+  switch(st)
+    {
+    case YACS::READY:
+    case YACS::TOLOAD:
+    case YACS::LOADED:
+    case YACS::TOACTIVATE:
+    case YACS::ACTIVATED:
+    case YACS::SUSPENDED:
+    case YACS::PAUSE:
+    case YACS::DISABLED:
+    case YACS::DESACTIVATED:
+      {
+        std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getStatusOfRunStr : Unexpected state \"" << YACS::ENGINE::Node::getStateName(st) << "\" ! Did you invoke run ?";
+        throw YACS::Exception(oss.str());
+      }
+    case YACS::LOADFAILED:
+    case YACS::EXECFAILED:
+    case YACS::ERROR:
+    case YACS::INTERNALERR:
+      return std::string(ST_ERROR);
+    case YACS::FAILED:
+      return std::string(ST_FAILED);
+    case YACS::DONE:
+      return std::string(ST_OK);
+    default:
+      {
+        std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getStatusOfRunStr : unrecognized and managed state \"" << YACS::ENGINE::Node::getStateName(st) << "\" !";
+        throw YACS::Exception(oss.str());
+      }
+    }
+}
+
 std::vector<YACSEvalSeqAny *> YACSEvalYFXRunOnlyPattern::getResults() const
 {
   if(_generatedGraph->getState()!=YACS::DONE)
@@ -478,6 +542,67 @@ std::vector<YACSEvalSeqAny *> YACSEvalYFXRunOnlyPattern::getResults() const
   return ret;
 }
 
+/*!
+ * This method works if run succeeded (true return) and also if graph has failed. Graph failed means soft error of evaluation due to error in evaluation (example 1/0 or a normal throw from one node)
+ * If a more serious error occured (SIGSEGV of a server or internal error in YACS engine, cluster error, loose of connection...) this method will throw an exception to warn the caller that the results may be 
+ */
+std::vector<YACSEvalSeqAny *> YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure(std::vector<unsigned int>& passedIds) const
+{
+  YACS::StatesForNode st(_generatedGraph->getState());
+  if(st==YACS::DONE)
+    {
+      passedIds.clear();
+      std::vector<YACSEvalSeqAny *> ret(getResults());
+      if(!ret.empty())
+        {
+          if(!ret[0])
+            throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure : internal error ! The returned vector has a null pointer at pos #0 !");
+          std::size_t sz(ret[0]->size());
+          passedIds.resize(sz);
+          for(std::size_t i=0;i<sz;i++)
+            passedIds[i]=i;
+        }
+      return ret;
+    }
+  getStatusOfRunStr();// To check that the status is recognized.
+  std::list<YACS::ENGINE::Node *> lns(_generatedGraph->edGetDirectDescendants());
+  YACS::ENGINE::ForEachLoop *fe(0);
+  for(std::list<YACS::ENGINE::Node *>::const_iterator it=lns.begin();it!=lns.end();it++)
+    {
+      fe=dynamic_cast<YACS::ENGINE::ForEachLoop *>(*it);
+      if(fe)
+        break;
+    }
+  if(!fe)
+    throw YACS::Exception("YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure : internal error 2 ! ForEach is not accessible !");
+  //
+  YACS::ENGINE::Executor exe;
+  std::vector<YACS::ENGINE::SequenceAny *> outputs;
+  std::vector<std::string> nameOfOutputs;
+  passedIds=fe->getPassedResults(&exe,outputs,nameOfOutputs);//<- the key invokation is here.
+  std::size_t sz(passedIds.size()),ii(0);
+  std::vector<YACSEvalSeqAny *> ret(_outputsOfInterest.size());
+  for(std::vector<YACSEvalOutputPort *>::const_iterator it=_outputsOfInterest.begin();it!=_outputsOfInterest.end();it++,ii++)
+    {
+      YACS::ENGINE::OutputPort *p((*it)->getUndergroundPtr());
+      std::string st(_runNode->getOutPortName(p));
+      std::ostringstream oss; oss << FIRST_FE_SUBNODE_NAME << '.' << _runNode->getName() << '.' << st;
+      st=oss.str();
+      YACS::ENGINE::ForEachLoop::InterceptorizeNameOfPort(st);
+      std::vector<std::string>::iterator it(std::find(nameOfOutputs.begin(),nameOfOutputs.end(),st));
+      if(it==nameOfOutputs.end())
+        {
+          std::ostringstream oss; oss << "YACSEvalYFXRunOnlyPattern::getResultsInCaseOfFailure : internal error 3 ! Unable to locate interceptor with name " << st << " ! Possibilities are : ";
+          std::copy(nameOfOutputs.begin(),nameOfOutputs.end(),std::ostream_iterator<std::string>(oss," "));
+          oss << " !";
+          throw YACS::Exception(oss.str());
+        }
+      std::size_t pos(std::distance(nameOfOutputs.begin(),it));
+      ret[ii]=BuildValueFromEngineFrmt(outputs[pos]);
+    }
+  return ret;
+}
+
 void YACSEvalYFXRunOnlyPattern::emitStart() const
 {
   YACSEvalObserver *obs(getObserver());
index ea3c4d4fa802fab0c5b4bd88882f970483335666..6db957d0479179a44f9756787f2deaa6bbf167c6 100644 (file)
@@ -38,6 +38,7 @@ namespace YACS
     class ForEachLoop;
     class ComposedNode;
     class InputPyPort;
+    class SequenceAny;
   }
 }
 
@@ -74,7 +75,9 @@ public:
   virtual bool isLocked() const = 0;
   virtual YACSEvalListOfResources *giveResources() = 0;
   virtual YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const = 0;
+  virtual std::string getStatusOfRunStr() const = 0;
   virtual std::vector<YACSEvalSeqAny *> getResults() const = 0;
+  virtual std::vector<YACSEvalSeqAny *> getResultsInCaseOfFailure(std::vector<unsigned int>& passedIds) const = 0;
   virtual void emitStart() const = 0;
 public:
   static const char DFT_PROC_NAME[];
@@ -86,6 +89,7 @@ protected:
   YACSEvalListOfResources *getResourcesInternal() const { return _res; }
   ResourcesManager_cpp *getCatalogInAppli() const { return _rm; }
   static YACSEvalSeqAny *BuildValueInPort(YACS::ENGINE::InputPyPort *port);
+  static YACSEvalSeqAny *BuildValueFromEngineFrmt(YACS::ENGINE::SequenceAny *data);
 private:
   void cleanScheme();
 private:
@@ -99,6 +103,10 @@ private:
 protected:
   std::vector< YACSEvalInputPort > _inputs;
   std::vector< YACSEvalOutputPort > _outputs;
+public:
+  static const char ST_OK[]; // execution goes to the end without any trouble -> results can be exploited without any problem with getResults and getResultsInCaseOfFailure.
+  static const char ST_FAILED[]; // execution has reached some failed evaluation (normal errors due to incapacity of one node to evaluate) -> results can be exploited without any problem with getResultsInCaseOfFailure
+  static const char ST_ERROR[]; // execution has encountered hard errors (SIGSEGV in a server, internal error in YACS) -> results can be exploited with getResultsInCaseOfFailure but you can't make hypothesis for other ids not in passedIds.
 };
 
 class YACSEvalYFXRunOnlyPattern : public YACSEvalYFXPattern
@@ -115,12 +123,15 @@ public:
   bool isLocked() const;
   YACSEvalListOfResources *giveResources();
   YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const;
+  std::string getStatusOfRunStr() const;
   std::vector<YACSEvalSeqAny *> getResults() const;
+  std::vector<YACSEvalSeqAny *> getResultsInCaseOfFailure(std::vector<unsigned int>& passedIds) const;
   void emitStart() const;
   //
   YACS::ENGINE::ForEachLoop *getUndergroundForEach() const { return _FEInGeneratedGraph; }
   static bool IsMatching(YACS::ENGINE::Proc *scheme, YACS::ENGINE::ComposedNode *& runNode);
 public:
+  static const char FIRST_FE_SUBNODE_NAME[];
   static const char GATHER_NODE_NAME[];
 private:
   void buildInputPorts();
index 89668a64e699ec03b41877d64b0fde50366730c7..21286547071e888c20a7e5a3d21aab129e3c945e 100644 (file)
@@ -75,6 +75,15 @@ static void convertPyToIntArr(PyObject *pyLi, std::vector<int>& arr)
     }
 }
 
+static PyObject *convertToPyToInt(const std::vector<unsigned int>& arr)
+{
+  std::size_t sz(arr.size());
+  PyObject *ret(PyList_New(sz));
+  for(std::size_t i=0;i<sz;i++)
+    PyList_SetItem(ret,i,PyInt_FromLong(arr[i]));
+  return ret;
+}
+
 static void convertPyToDblArr(PyObject *pyLi, std::vector<double>& arr)
 {
   if(PyList_Check(pyLi))
@@ -114,6 +123,40 @@ static void convertPyToDblArr(PyObject *pyLi, std::vector<double>& arr)
       throw YACS::Exception("convertPyToNewIntArr3 : not a list nor a tuple");
     }
 }
+
+static PyObject *convertVectOfSeqAny(const std::vector<YACSEvalSeqAny *>& retCpp)
+{
+  std::size_t sz(retCpp.size());
+  PyObject *ret(PyList_New(sz));
+  for(std::size_t i=0;i<sz;i++)
+    {
+      YACSEvalSeqAny *elt(retCpp[i]);
+      YACSEvalSeqAnyDouble *elt1(dynamic_cast<YACSEvalSeqAnyDouble *>(elt));
+      YACSEvalSeqAnyInt *elt2(dynamic_cast<YACSEvalSeqAnyInt *>(elt));
+      if(elt1)
+        {
+          std::vector<double> *zeArr(elt1->getInternal());
+          std::size_t sz2(zeArr->size());
+          PyObject *ret2(PyList_New(sz2));
+          for(std::size_t i2=0;i2<sz2;i2++)
+            PyList_SetItem(ret2,i2,PyFloat_FromDouble((*zeArr)[i2]));
+          PyList_SetItem(ret,i,ret2);
+        }
+      else if(elt2)
+        {
+          std::vector<int> *zeArr(elt2->getInternal());
+          std::size_t sz2(zeArr->size());
+          PyObject *ret2(PyList_New(sz2));
+          for(std::size_t i2=0;i2<sz2;i2++)
+            PyList_SetItem(ret2,i2,PyInt_FromLong((*zeArr)[i2]));
+          PyList_SetItem(ret,i,ret2);
+        }
+      else
+        throw YACS::Exception("wrap of YACSEvalYFX.getResults : unrecognized type !");
+      delete elt;
+    }
+  return ret;
+}
 %}
 
 %types(YACSEvalInputPort,YACSEvalOutputPort);
@@ -351,6 +394,7 @@ public:
   bool isLocked() const;
   YACS::ENGINE::Proc *getUndergroundGeneratedGraph() const;
   YACSEvalListOfResources *giveResources();
+  std::string getStatusOfRunStr() const;
   void setParallelizeStatus(bool newVal);
   bool getParallelizeStatus() const;
   //void registerObserver(YACSEvalObserver *observer);
@@ -409,36 +453,17 @@ public:
        PyObject *getResults() const
        {
          std::vector<YACSEvalSeqAny *> retCpp(self->getResults());
-         std::size_t sz(retCpp.size());
-         PyObject *ret(PyList_New(sz));
-         for(std::size_t i=0;i<sz;i++)
-           {
-             YACSEvalSeqAny *elt(retCpp[i]);
-             YACSEvalSeqAnyDouble *elt1(dynamic_cast<YACSEvalSeqAnyDouble *>(elt));
-             YACSEvalSeqAnyInt *elt2(dynamic_cast<YACSEvalSeqAnyInt *>(elt));
-             if(elt1)
-               {
-                 std::vector<double> *zeArr(elt1->getInternal());
-                 std::size_t sz2(zeArr->size());
-                 PyObject *ret2(PyList_New(sz2));
-                 for(std::size_t i2=0;i2<sz2;i2++)
-                   PyList_SetItem(ret2,i2,PyFloat_FromDouble((*zeArr)[i2]));
-                 PyList_SetItem(ret,i,ret2);
-               }
-             else if(elt2)
-               {
-                 std::vector<int> *zeArr(elt2->getInternal());
-                 std::size_t sz2(zeArr->size());
-                 PyObject *ret2(PyList_New(sz2));
-                 for(std::size_t i2=0;i2<sz2;i2++)
-                   PyList_SetItem(ret2,i2,PyInt_FromLong((*zeArr)[i2]));
-                 PyList_SetItem(ret,i,ret2);
-               }
-             else
-               throw YACS::Exception("wrap of YACSEvalYFX.getResults : unrecognized type !");
-             delete elt;
-           }
-         return ret;
+         return convertVectOfSeqAny(retCpp);
+       }
+
+       PyObject *getResultsInCaseOfFailure() const
+       {
+         std::vector<unsigned int> ret1Cpp;
+         std::vector<YACSEvalSeqAny *> ret0Cpp(self->getResultsInCaseOfFailure(ret1Cpp));
+         PyObject *retPy(PyTuple_New(2));
+         PyTuple_SetItem(retPy,0,convertVectOfSeqAny(ret0Cpp));
+         PyTuple_SetItem(retPy,1,convertToPyToInt(ret1Cpp));
+         return retPy;
        }
 
        PyObject *run(YACSEvalSession *session)
diff --git a/src/evalyfx_swig/test2.py b/src/evalyfx_swig/test2.py
new file mode 100644 (file)
index 0000000..706b170
--- /dev/null
@@ -0,0 +1,49 @@
+# bug revealed by otgui on 8/2/16. Several lock/unlock session. test1.xml is Cogeneration.xml.
+
+def buildScheme(fname):
+    import SALOMERuntime
+    import loader
+    SALOMERuntime.RuntimeSALOME.setRuntime()
+    r=SALOMERuntime.getSALOMERuntime()
+    p0=r.createProc("run")
+    #
+    p=r.createBloc("toto")
+    p0.edAddChild(p)
+    #
+    cont=p0.createContainer("MyWonderfulContainer","Salome")
+    td=p0.createType("double","double")
+    n0=r.createScriptNode("Salome","PyScript0")
+    p.edAddChild(n0)
+    q=n0.edAddInputPort("q",td)
+    ep=n0.edAddOutputPort("ep",td)
+    n0.setScript("ep=1./(4.-q)") # <- force division by 0
+    n0.setExecutionMode("remote")
+    n0.setContainer(cont)
+    p0.saveSchema(fname)
+    pass
+
+fname="test2.xml"
+import evalyfx
+session=evalyfx.YACSEvalSession()
+session.launch()
+buildScheme(fname)
+efx=evalyfx.YACSEvalYFX.BuildFromFile(fname)
+#efx.setParallelizeStatus(False)
+efx.getParams().setStopASAPAfterErrorStatus(False)
+inps=efx.getFreeInputPorts()
+assert(len(inps)==1)
+outps=efx.getFreeOutputPorts()
+inps[0].setSequenceOfValuesToEval([1.,2.,3.,4.,5.,6.])
+efx.lockPortsForEvaluation(inps,outps)
+rss=efx.giveResources()
+rss[0][0].setWantedMachine("localhost")
+a,b=efx.run(session)
+assert(efx.getStatusOfRunStr()=='SOME_SAMPLES_FAILED_AND_ALL_OF_THEM_FAILED_DETERMINISTICALLY')
+c,d=efx.getResultsInCaseOfFailure()
+assert(d==[0,1,2,4,5])# case 3 is not in !
+assert(len(c)==1)
+c=c[0]
+for f,g in zip(c,[0.3333333333333333,0.5,1.0,-1.0,-0.5]):
+    assert(abs(f-g)<1e-12)
+    pass
+