]> SALOME platform Git repositories - modules/yacs.git/commitdiff
Salome HOME
Fix on using two connections on ports inside two levels of foreach nodes.
authorOvidiu Mircescu <ovidiu.mircescu@edf.fr>
Mon, 10 Aug 2015 14:19:01 +0000 (16:19 +0200)
committerOvidiu Mircescu <ovidiu.mircescu@edf.fr>
Mon, 10 Aug 2015 14:19:01 +0000 (16:19 +0200)
There was a crush when trying to run a schema which contains two levels of
nested foreach nodes when an output port was connected to nodes of different
levels of imbrication.

src/engine/Bloc.cxx
src/engine/ForEachLoop.cxx
src/engine/OptimizerLoop.cxx
src/engine/Test/engineIntegrationTest.cxx
src/yacsloader/Test/YacsLoaderTest.cxx
src/yacsloader/samples/foreach8.xml [new file with mode: 0644]
src/yacsloader_swig/Test/testSaveLoadRun.py

index d0e762426bb51de6da865a7a07f7b9d432e18faa..a2def0cc07362bb94de240404912ed9422839db1 100644 (file)
@@ -59,7 +59,10 @@ Bloc::Bloc(const Bloc& other, ComposedNode *father, bool editionOnly):StaticDefi
     {
       OutPort* pout = iter2->first;
       InPort* pin = iter2->second;
-      edAddLink(getOutPort(other.getPortName(pout)),getInPort(other.getPortName(pin)));
+      if(&other == getLowestCommonAncestor(pout->getNode(), pin->getNode()))
+      {
+        edAddLink(getOutPort(other.getPortName(pout)),getInPort(other.getPortName(pin)));
+      }
     }
 }
 
index 97e5f56da1dc4cbd75cf93d9b3c639ec320c3808..ec235621c0efe4116efcefb8e4f18a6f3ff02d0f 100644 (file)
@@ -27,6 +27,7 @@
 #include <iostream>
 #include <iomanip>
 #include <sstream>
+#include <algorithm>    // std::replace_if
 
 //#define _DEVDEBUG_
 #include "YacsTrace.hxx"
@@ -466,7 +467,7 @@ ForEachLoop::ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool ed
       {
         AnySplitOutputPort *temp=new AnySplitOutputPort(*(*iter2),this);
         InterceptorInputPort *interc=new InterceptorInputPort(*other._intecptrsForOutGoingPorts[i],this);
-        temp->addRepr(getOutPort((*iter2)->getName()),interc);
+        temp->addRepr(getOutPort(other.getOutPortName((*iter2)->getRepr())),interc);
         interc->setRepr(temp);
         _outGoingPorts.push_back(temp);
         _intecptrsForOutGoingPorts.push_back(interc);
@@ -898,8 +899,16 @@ void ForEachLoop::buildDelegateOf(std::pair<OutPort *, OutPort *>& port, InPort
       else
         {
           TypeCodeSeq *newTc=(TypeCodeSeq *)TypeCode::sequenceTc("","",port.first->edGetType());
-          AnySplitOutputPort *newPort=new AnySplitOutputPort(getPortName(port.first),this,newTc);
-          InterceptorInputPort *intercptor=new InterceptorInputPort(string("intercptr for ")+getPortName(port.first),this,port.first->edGetType());
+          // The out going ports belong to the ForEachLoop, whereas
+          // the delegated port belong 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());
           intercptor->setRepr(newPort);
           newTc->decrRef();
           newPort->addRepr(port.first,intercptor);
index 53c67c7ac5af16203f5bd413720f56d0275e510e..ca4e27f27c2c5934691e4fa8ca59f52aa3977f9b 100644 (file)
@@ -117,6 +117,11 @@ OptimizerLoop::OptimizerLoop(const OptimizerLoop& other, ComposedNode *father, b
   _algoResultPort(other._algoResultPort, this)
 {
   //Don't call setAlgorithm here because it will be called several times if the class is derived. Call it in simpleClone for cloning
+  
+  // Create the links to evalResults port
+  set<OutPort *> fromPortsToReproduce=other._retPortForOutPool.edSetOutPort();
+  for(set<OutPort *>::iterator iter=fromPortsToReproduce.begin();iter!=fromPortsToReproduce.end();iter++)
+    edAddLink(getOutPort(other.getPortName(*iter)),&_retPortForOutPool);
 }
 
 OptimizerLoop::~OptimizerLoop()
index a2026e1d3c3aefb4435214b675428bfe083d0acb..4a29516c5a7762cd517a7725ec7c1c29e4879c25 100644 (file)
@@ -2274,7 +2274,7 @@ void EngineIntegrationTest::testForEachLoop2()
   graph->edAddLink(forEach->edGetSamplePort(),i32);
   graph->edAddLink(o31,n4->edGetInValue1());
   graph->edAddLink(n2->edGetSeqOut(),n4->edGetInValue2());
-  CPPUNIT_ASSERT(dynamic_cast<AnySplitOutputPort *>(graph->getOutputPort("myFE.blocToShakeBaby.T3.o31")));
+  CPPUNIT_ASSERT(graph->getOutputPort("myFE.blocToShakeBaby.T3.o31"));
   int tab[]={12,14,16,18,20};
   vector<int> tabv(tab,tab+5);
   SequenceAnyPtr tmp=SequenceAny::New(tabv);//expected sequence
@@ -2565,6 +2565,7 @@ void EngineIntegrationTest::testForEachLoop5()
   delete graph2;
 }
 
+
 /*!
  * Here a test for OptimizerLoop with an evenemential (or synchronous) algorithm
  */
index 24b712a23ae1d580b4411f836d274eb9acb0f6fe..1150300342d94008c165814b5cc0c8752989cb68 100644 (file)
@@ -661,6 +661,9 @@ void YacsLoaderTest::foreachs()
   ret = driverTest(p, "samples/foreach6.xml");
   CPPUNIT_ASSERT_MESSAGE("Schema: foreach6.xml", ret == 0);
   CPPUNIT_ASSERT_MESSAGE("Schema: foreach6.xml", p->getEffectiveState() == YACS::DONE );
+  ret = driverTest(p, "samples/foreach8.xml");
+  CPPUNIT_ASSERT_MESSAGE("Schema: foreach8.xml", ret == 0);
+  CPPUNIT_ASSERT_MESSAGE("Schema: foreach8.xml", p->getEffectiveState() == YACS::DONE );
   if(getenv("GEOM_ROOT_DIR"))
     {
       std::string geomdir(getenv("GEOM_ROOT_DIR"));
diff --git a/src/yacsloader/samples/foreach8.xml b/src/yacsloader/samples/foreach8.xml
new file mode 100644 (file)
index 0000000..4607c61
--- /dev/null
@@ -0,0 +1,150 @@
+<?xml version='1.0' encoding='iso-8859-1' ?>
+<proc name="schema">
+   <property name="DefaultStudyID" value="1"/>
+   <type name="string" kind="string"/>
+   <struct name="Engines/dataref">
+      <member name="ref" type="string"/>
+   </struct>
+   <type name="bool" kind="bool"/>
+   <sequence name="boolvec" content="bool"/>
+   <type name="double" kind="double"/>
+   <sequence name="dblevec" content="double"/>
+   <objref name="file" id="file"/>
+   <type name="int" kind="int"/>
+   <sequence name="intvec" content="int"/>
+   <struct name="stringpair">
+      <member name="name" type="string"/>
+      <member name="value" type="string"/>
+   </struct>
+   <sequence name="propvec" content="stringpair"/>
+   <objref name="pyobj" id="python:obj:1.0"/>
+   <sequence name="seqboolvec" content="boolvec"/>
+   <sequence name="seqdblevec" content="dblevec"/>
+   <sequence name="seqint" content="int"/>
+   <sequence name="seqintvec" content="intvec"/>
+   <sequence name="stringvec" content="string"/>
+   <sequence name="seqstringvec" content="stringvec"/>
+   <container name="DefaultContainer">
+      <property name="container_kind" value="Salome"/>
+      <property name="attached_on_cloning" value="0"/>
+      <property name="name" value="localhost"/>
+   </container>
+   <foreach name="ForEachLoop_int0" nbranch="2" type="int">
+      <bloc name="Bloc0">
+         <foreach name="ForEachLoop_int1" nbranch="3" type="int">
+            <bloc name="Bloc1">
+               <remote name="PyScript2">
+                  <script><code><![CDATA[o5 = i3 + i4
+]]></code></script>
+                  <load container="DefaultContainer"/>
+                  <inport name="i3" type="int"/>
+                  <inport name="i4" type="int"/>
+                  <outport name="o5" type="int"/>
+               </remote>
+               <inline name="PyScript1">
+                  <script><code><![CDATA[o3=7
+]]></code></script>
+                  <inport name="i2" type="int"/>
+                  <outport name="o3" type="int"/>
+               </inline>
+               <control> <fromnode>PyScript2</fromnode> <tonode>PyScript1</tonode> </control>
+               <datalink control="false">
+                  <fromnode>PyScript2</fromnode> <fromport>o5</fromport>
+                  <tonode>PyScript1</tonode> <toport>i2</toport>
+               </datalink>
+            </bloc>
+         </foreach>
+         <inline name="PostTraitement">
+            <script><code><![CDATA[o3 = 0
+for i in i6:
+    o3 = i + o3
+
+for i in i5:
+    o3 = i + o3
+]]></code></script>
+            <load container="DefaultContainer"/>
+            <inport name="i6" type="intvec"/>
+            <inport name="i5" type="intvec"/>
+            <outport name="o3" type="int"/>
+         </inline>
+         <control> <fromnode>ForEachLoop_int1</fromnode> <tonode>PostTraitement</tonode> </control>
+         <datalink control="false">
+            <fromnode>ForEachLoop_int1</fromnode> <fromport>evalSamples</fromport>
+            <tonode>ForEachLoop_int1.Bloc1.PyScript2</tonode> <toport>i4</toport>
+         </datalink>
+         <datalink control="false">
+            <fromnode>ForEachLoop_int1.Bloc1.PyScript2</fromnode> <fromport>o5</fromport>
+            <tonode>PostTraitement</tonode> <toport>i6</toport>
+         </datalink>
+         <datalink control="false">
+            <fromnode>ForEachLoop_int1.Bloc1.PyScript1</fromnode> <fromport>o3</fromport>
+            <tonode>PostTraitement</tonode> <toport>i5</toport>
+         </datalink>
+      </bloc>
+   </foreach>
+   <outnode name="OutNode">
+      <parameter name="i1" type="intvec"/>
+   </outnode>
+   <control> <fromnode>ForEachLoop_int0</fromnode> <tonode>OutNode</tonode> </control>
+   <datalink control="false">
+      <fromnode>ForEachLoop_int0</fromnode> <fromport>evalSamples</fromport>
+      <tonode>ForEachLoop_int0.Bloc0.ForEachLoop_int1.Bloc1.PyScript2</tonode> <toport>i3</toport>
+   </datalink>
+   <datalink control="false">
+      <fromnode>ForEachLoop_int0.Bloc0.PostTraitement</fromnode> <fromport>o3</fromport>
+      <tonode>OutNode</tonode> <toport>i1</toport>
+   </datalink>
+   <parameter>
+      <tonode>ForEachLoop_int0.Bloc0.ForEachLoop_int1</tonode><toport>nbBranches</toport>
+      <value><int>3</int></value>
+   </parameter>
+   <parameter>
+      <tonode>ForEachLoop_int0.Bloc0.ForEachLoop_int1</tonode><toport>SmplsCollection</toport>
+      <value><array><data>
+<value><int>1</int></value>
+<value><int>2</int></value>
+<value><int>3</int></value>
+<value><int>4</int></value>
+</data></array></value>
+   </parameter>
+   <parameter>
+      <tonode>ForEachLoop_int0.Bloc0.ForEachLoop_int1</tonode><toport>SmplsCollection</toport>
+      <value><array><data>
+<value><int>1</int></value>
+<value><int>2</int></value>
+<value><int>3</int></value>
+<value><int>4</int></value>
+</data></array></value>
+   </parameter>
+   <parameter>
+      <tonode>ForEachLoop_int0</tonode><toport>nbBranches</toport>
+      <value><int>2</int></value>
+   </parameter>
+   <parameter>
+      <tonode>ForEachLoop_int0</tonode><toport>SmplsCollection</toport>
+      <value><array><data>
+<value><int>1</int></value>
+<value><int>2</int></value>
+<value><int>3</int></value>
+<value><int>4</int></value>
+</data></array></value>
+   </parameter>
+   <parameter>
+      <tonode>ForEachLoop_int0</tonode><toport>SmplsCollection</toport>
+      <value><array><data>
+<value><int>1</int></value>
+<value><int>2</int></value>
+<value><int>3</int></value>
+<value><int>4</int></value>
+</data></array></value>
+   </parameter>
+   <presentation name="ForEachLoop_int0.Bloc0.ForEachLoop_int1.Bloc1" x="6" y="88" width="357.75" height="127.75" expanded="1" expx="6" expy="88" expWidth="357.75" expHeight="127.75" shownState="0"/>
+   <presentation name="ForEachLoop_int0.Bloc0.ForEachLoop_int1.Bloc1.PyScript2" x="1.75" y="33.75" width="158" height="90" expanded="1" expx="1.75" expy="33.75" expWidth="158" expHeight="90" shownState="0"/>
+   <presentation name="ForEachLoop_int0.Bloc0.ForEachLoop_int1.Bloc1.PyScript1" x="195.75" y="60.75" width="158" height="63" expanded="1" expx="195.75" expy="60.75" expWidth="158" expHeight="63" shownState="0"/>
+   <presentation name="ForEachLoop_int0.Bloc0" x="6" y="88" width="636.75" height="257.625" expanded="1" expx="6" expy="88" expWidth="636.75" expHeight="257.625" shownState="0"/>
+   <presentation name="ForEachLoop_int0.Bloc0.ForEachLoop_int1" x="1.875" y="33.875" width="367.75" height="219.75" expanded="1" expx="1.875" expy="33.875" expWidth="367.75" expHeight="219.75" shownState="0"/>
+   <presentation name="ForEachLoop_int0" x="4.75" y="32" width="646.75" height="349.625" expanded="1" expx="4.75" expy="32" expWidth="646.75" expHeight="349.625" shownState="0"/>
+   <presentation name="ForEachLoop_int0.Bloc0.PostTraitement" x="474.75" y="138.25" width="158" height="90" expanded="1" expx="474.75" expy="138.25" expWidth="158" expHeight="90" shownState="0"/>
+   <presentation name="OutNode" x="669.5" y="258" width="158" height="63" expanded="1" expx="669.5" expy="258" expWidth="158" expHeight="63" shownState="0"/>
+   <presentation name="__ROOT__" x="0" y="0" width="831.5" height="385.625" expanded="1" expx="0" expy="0" expWidth="831.5" expHeight="385.625" shownState="0"/>
+</proc>
index 5272b62541354d3b911a8eb7378c2a048c3f6a6c..5d0569114e9b2cf4d09e0444604ca18a6ad7c6a1 100755 (executable)
@@ -622,7 +622,7 @@ for i in xrange(nb):
     a,b,c=n1.getPassedResults(ex)
     self.assertEqual(a,range(6))
     self.assertEqual([elt.getPyObj() for elt in b],[[6L, 12L, 16L, 18L, -4L, 10L]])
-    self.assertEqual(c,['n10.o2'])
+    self.assertEqual(c,['n10_o2_interceptor'])
     pass
 
   def test7(self):
@@ -682,7 +682,7 @@ else:
     a,b,c=n1.getPassedResults(ex)
     self.assertEqual(a,range(3))
     self.assertEqual([elt.getPyObj() for elt in b],[[6L,12L,16L]])
-    self.assertEqual(c,['n10.o2'])
+    self.assertEqual(c,['n10_o2_interceptor'])
     pass
 
   def test8(self):
@@ -746,7 +746,7 @@ else:
     a,b,c=n1.getPassedResults(ex)
     self.assertEqual(a,[0,1,2,4,5])
     self.assertEqual([elt.getPyObj() for elt in b],[[6L,12L,16L,-4L,10L]])
-    self.assertEqual(c,['n10.o2'])
+    self.assertEqual(c,['n10_o2_interceptor'])
     
     p.getChildByName("n1").getChildByName("n10").setScript("""
 import time
@@ -768,7 +768,7 @@ else:
     a,b,c=n1.getPassedResults(ex)
     self.assertEqual(a,[1,2,3,4,5])
     self.assertEqual([elt.getPyObj() for elt in b],[[12L,16L,18L,-4L,10L]])
-    self.assertEqual(c,['n10.o2'])
+    self.assertEqual(c,['n10_o2_interceptor'])
     pass
 
   def test9(self):
@@ -834,7 +834,7 @@ else:
     a,b,c=n1.getPassedResults(ex)
     self.assertEqual(a,[0,1,2,4,5])
     self.assertEqual([elt.getPyObj() for elt in b],[[6L,12L,16L,-4L,10L]])
-    self.assertEqual(c,['n10.o2'])
+    self.assertEqual(c,['n10_o2_interceptor'])
     
     p.getChildByName("n1").getChildByName("n10").setScript("""
 import time
@@ -916,7 +916,7 @@ else:
     a,b,c=n1.getPassedResults(ex)
     self.assertEqual(a,[1,3,5,7,9,11])
     self.assertEqual([elt.getPyObj() for elt in b],[[12L,36L,60L,84L,108L,132L]])
-    self.assertEqual(c,['n10.o2'])
+    self.assertEqual(c,['n10_o2_interceptor'])
     
     p.getChildByName("n1").getChildByName("n10").setScript("""
 import time
@@ -1031,6 +1031,86 @@ else:
     self.assertEqual(p.getState(),pilot.DONE)
     self.assertEqual(p.getChildByName("n2").getOutputPort("o4").getPyObj(),[0L,5L,4L,15L,8L,25L,12L,35L,16L,45L,20L,55L])
     pass
+  
+  def test12(self):
+    """ Test of nested ForEachLoop with a port connected inside and outside the loop."""
+    schema = self.r.createProc("schema")
+    ti = schema.getTypeCode("int")
+    tiset = schema.createSequenceTc("", "seqint", ti)
+    tisetseq = schema.createSequenceTc("", "seqintvec", tiset)
+
+    n1 = self.r.createScriptNode("", "PyScript2")
+    n1.edAddInputPort("i3", ti)
+    n1.edAddInputPort("i4", ti)
+    n1.edAddOutputPort("o5", ti)
+    n1.setScript("o5=i3+i4")
+
+    n2 = self.r.createScriptNode("", "PyScript1")
+    n2.edAddInputPort("i2", ti)
+    n2.edAddOutputPort("o3", ti)
+    n2.setScript("o3=i2")
+
+    b1 = self.r.createBloc("Bloc1")
+    b1.edAddChild(n1)
+    b1.edAddChild(n2)
+
+    fe1 = self.r.createForEachLoop("ForEach1", ti)
+    fe1.getInputPort("nbBranches").edInitPy(2)
+    fe1.getInputPort("SmplsCollection").edInitPy([1, 2, 3, 4])
+    fe1.edSetNode(b1)
+
+    n3 = self.r.createScriptNode("", "PostProcessing")
+    n3.edAddInputPort("i7", tiset)
+    n3.edAddInputPort("i5", tiset)
+    n3.edAddOutputPort("o4", ti)
+    n3.setScript("""
+o4 = 0
+for i in i7:
+    o4 = i + o4
+
+for i in i5:
+    o4 = i + o4
+""")
+
+    b0 = self.r.createBloc("Bloc0")
+    b0.edAddChild(fe1)
+    b0.edAddChild(n3)
+
+    fe0 = self.r.createForEachLoop("ForEach1", ti)
+    fe0.getInputPort("nbBranches").edInitPy(2)
+    fe0.getInputPort("SmplsCollection").edInitPy([1, 2, 3, 4])
+    fe0.edSetNode(b0)
+
+    schema.edAddChild(fe0)
+
+    nx = self.r.createScriptNode("", "Result")
+    nx.edAddInputPort("i8", tiset)
+    nx.edAddOutputPort("o6", ti)
+    nx.setScript("""
+o6 = 0
+for i in i8:
+    o6 = i + o6
+""")
+    schema.edAddChild(nx)
+
+    schema.edAddLink(fe1.getOutputPort("evalSamples"), n1.getInputPort("i3"))
+    schema.edAddLink(fe0.getOutputPort("evalSamples"), n1.getInputPort("i4"))
+
+    schema.edAddDFLink(n1.getOutputPort("o5"), n3.getInputPort("i7"))
+    schema.edAddDFLink(n2.getOutputPort("o3"), n3.getInputPort("i5"))
+
+    po5 = fe1.getOutputPort("Bloc1.PyScript2.o5")
+    schema.edAddDFLink(po5, n2.getInputPort("i2"))
+
+    schema.edAddDFLink(n3.getOutputPort("o4"), nx.getInputPort("i8"))
+#    schema.saveSchema("foreach12.xml")
+    
+    e = pilot.ExecutorSwig()
+    e.RunW(schema)
+    self.assertEqual(schema.getState(),pilot.DONE)
+    resVal = schema.getChildByName("Result").getOutputPort("o6").getPyObj()
+    self.assertEqual(resVal, 160)
+    pass
 
   pass