Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / doc / yacsloader.dox
1 /*! \page xml_loader XML file loader
2
3 \section toc Table of contents
4
5   - \ref loader_intro
6   - \ref loader_programming
7   - \ref loader_use
8   - \ref loader_file
9
10
11 \section loader_intro Introduction
12
13 The yacs loader is a class that can be used to load a calculation schema
14 in memory by reading and parsing a XML file describing it.
15
16 \section loader_programming Programming with the yacs loader class
17
18 To use the yacs loader class, first create a specific runtime (here a Salome one).
19
20 Then you can create an instance of the yacsloader class and call
21 the load method with the name of the XML file as argument.
22
23 The call to the method will return a calculation schema (instance of the Proc class).
24
25 \code
26 #include "RuntimeSALOME.hxx"
27 #include "parser.hxx"
28
29 YACS::ENGINE::RuntimeSALOME::setRuntime();
30 YACS::YACSLoader loader;
31
32 YACS::ENGINE::Proc* p=loader.load("file.xml");
33
34 \endcode
35
36 You can then dump to a file a graphviz diagram by calling the writeDot
37 method on the schema.
38
39 \code
40 #include <fstream>
41
42 std::ofstream f("proc.dot");
43 p->writeDot(f);
44 f.close();
45 \endcode
46
47 You can display the diagram with: dot -Tpng proc.dot |display.
48
49 And then execute the schema with an Executor.
50
51 \code
52 #include "Executor.hxx"
53
54 YACS::ENGINE::Executor executor;
55 executor.RunW(p);
56 \endcode
57
58 \section loader_use Using the yacs driver
59
60 The driver program is a program that loads a schema file and executes it
61 until its end. It is possible to display the schema state during the 
62 execution by specifying the --display option. An exemple of use is:
63
64 \code
65 driver --display=1 schema.xml
66 \endcode
67
68 Internally, it uses the loader class, the Salome runtime, the standard 
69 executor with all is necessary to catch exceptions.
70
71 \section loader_file Writing a XML file
72
73 To write a XML file describing a calculation schema, you need to define
74 several objects that are listed here :
75
76   - the calculation schema
77   - data types
78   - elementary calculation nodes
79   - connections between nodes
80   - initialization parameters
81   - composed calculation nodes
82
83
84 \subsection loader_schema Defining calculation schema
85 To define a calculation schema, simply open a proc tag
86 \code
87 <proc>
88 </proc>
89 \endcode
90
91 All following definitions must be put betwween these tags.
92
93 \subsection loader_types Defining data types
94 A calculation schema is composed of interconnected calculation nodes.
95 These nodes exchange data through data ports (in and out). The first
96 thing you need to do is to define all types that can be exchanged
97 in the schema. 
98
99 Some types are already defined by the runtime you use. For example, the
100 Salome runtime defines : int, double, string and bool types. It can also
101 define all types used by the declared components. At the moment, the
102 Salome runtime knows nothing about the types used by the declared components
103 so it is mandatory to define all data types except the four basic ones.
104
105 It is possible to define three kind of types : basic, sequence and objref.
106
107 A basic type is an atomic one so it can only be int, double, string and bool.
108 They are already defined so what can be defined is only alias to these types.
109
110 A definition of an alias to the double data type :
111 \code
112 <type name="mydble" kind="double"/>
113 \endcode
114
115 A sequence type is a constructed type that is built on already existing
116 types. A sequence type defines a list of elements. The definition
117 gives the name of the type and the type of the elements of the sequence.
118
119 To define a sequence of double type, add :
120 \code
121 <sequence name="myseqdble" content="double"/>
122 \endcode
123
124 All attributes in the sequence tag are mandatory.
125
126 You can then define a sequence of sequence by :
127 \code
128 <sequence name="myseqseqdble" content="myseqdble"/>
129 \endcode
130
131 An objref data type is an equivalent of a class in object languages.
132 Salome components use objects which have types such as Mesh, Field, ...
133 All these types can be related by inheritance relations.
134
135 Defining a base objref :
136 \code
137 <objref name="mesh"/>
138 \endcode
139
140 Defining a derived objref from mesh :
141 \code
142 <objref name="refinedmesh">
143   <base>mesh</base>
144 </objref>
145 \endcode
146
147 It is possible to derive an objref from multiple base objref and objref names
148 can use name spaces. Just use a / as separator.
149 \code
150 <objref name="myns/mesh"/>
151 \endcode
152 It is useful for Salome components because objref must be mapped to 
153 CORBA types which can use name spaces.
154
155 Finally, it is possible to define a sequence of objref :
156 \code
157 <sequence name="myseqmesh" content="refinedmesh"/>
158 \endcode
159
160 \b RESTRICTION : struct type is not supported
161
162 \subsection loader_nodes Defining elementary calculation nodes
163 The next step is to define calculation nodes : service nodes or inline
164 nodes.
165
166 There are three kinds of inline nodes : script inline node, function
167 inline node and clone inline node, 
168 and three kinds of service nodes : component service node, reference
169 service node and node service node. 
170
171 The definition of all these nodes is described below.
172
173 - Script inline node
174
175 This kind of node corresponds to the execution of a python script with input
176 and output parameters. Input and output parameters are passed to the 
177 script through data ports.
178 A very simple example of an script inline node is :
179 \code
180     <inline name="node1" >
181       <script>
182         <code>p1=10</code>
183       </script>
184       <outport name="p1" type="int"/>
185     </inline>
186 \endcode
187
188 The inline node has a mandatory name as all kind of nodes.
189 The script tag indicates that it is a script inline node.
190 The python script appears in as much lines as necessary between code tags in the script
191 section.
192 If your script contains a lot of "<" or "&" characters - as program code often does - 
193 the XML element can be defined as a CDATA section.
194 A CDATA section starts with "<![CDATA[" and ends with "]]>":
195
196 In the example above the script calculates p1 that is an output parameter.
197 An output data port must then be defined. A output data port is defined
198 in an outport tag with two mandatory attributes : name and type that references
199 an already defined data type.
200 To define an input data port use the inport tag in place of outport.
201
202 Example of an inline node with input and output arguments :
203 \code
204     <inline name="node1" >
205       <script>
206         <code>p1=p1+10</code>
207       </script>
208       <inport name="p1" type="int"/>
209       <outport name="p1" type="int"/>
210     </inline>
211 \endcode
212 Now the calculation node receives p1 as an input argument adds 10 to it
213 and sends it as an output argument.
214
215 - Function inline node
216
217 This kind of node corresponds to the execution of a python function with input
218 and output parameters. Input and output parameters are passed to the 
219 script through data ports.
220 The main difference with the script node is the execution part. The definition
221 of input and output ports is unchanged. In the execution part use the function
222 tag in place of the script tag and add a name (mandatory) which must be the same
223 as that of the function.
224
225 An example of an function inline node is :
226 \code
227     <inline name="node1" >
228       <function name="f">
229         <code>def f(p1):</code>
230         <code>  p1=p1+10</code>
231         <code>  return p1</code>
232       </script>
233       <inport name="p1" type="int"/>
234       <outport name="p1" type="int"/>
235     </inline>
236 \endcode
237
238 - Clone inline node
239
240 This node is a convenience node to avoid repeating an inline definion.
241 It allows to create an inline calculation by using the definition
242 of another inline node. Such a kind of node is defined in a node tag
243 with two mandatory attributes : name (the node name) and type that indicates the name
244 of the already existing inline node to use for the definition. Example :
245
246 \code
247   <node name="node2" type="node1"/>
248 \endcode
249
250 - Reference service node
251
252 A service node corresponds to the execution of a service available from a 
253 calculation server. It can thought of as the execution of an object method.
254 A service node is defined in a service tag in place of the inline tag for
255 the inline node.
256
257 In a reference service node the calculation server is known by its address (which
258 is a string meaningful for the runtime) and is supposed to exists
259 before executing the calculation schema. The service is known by its name.
260 Then the service has input and output arguments that are passed through ports
261 in the same way as the inline nodes.
262 The server address is defined as a string in a ref tag and the service name is 
263 defined in a method tag.
264 Example :
265 \code
266     <service name="node4" >
267         <ref>corbaname:rir:#test.my_context/Echo.Object</ref>
268         <method>echoDouble</method>
269         <inport name="p1" type="double"/>
270         <outport name="p1" type="double"/>
271     </service>
272 \endcode
273
274 The service node node4 is a reference service node because it has a ref
275 section. The address of the calculation server to use is a CORBA address
276 that must be meaningful to the runtime. The service to use is the
277 CORBA operation echoDouble that just gets the input and returns it.
278
279 - Component service node
280
281 This kind of node is similar to the previous one but the server does not
282 exist before the beginning of the execution. It's the runtime that is in charge 
283 of loading the calculation server or component for Salome platform.
284 Instead of defining the address of the server we give the name of the
285 component that will be loaded through the runtime by the platform.
286 This name is given in a component tag in place of the ref tag.
287 Example :
288 \code
289     <service name="node4" >
290         <component>ECHO</component>
291         <method>echoDouble</method>
292         <inport name="p1" type="double"/>
293         <outport name="p1" type="double"/>
294     </service>
295 \endcode
296
297 - Node service node
298
299 It's a special node that gives the possibility to create a service node that calls
300 a service of an already loaded component. To define such a node you need to 
301 indicate the name of an already existing component service node in a node tag
302 in place of the previous component tag.
303
304 A short example is better than a long speech :
305 \code
306     <service name="node5" >
307         <node>node4</node>
308         <method>echoString</method>
309         <inport name="p1" type="string"/>
310         <outport name="p1" type="string"/>
311     </service>
312 \endcode
313 Here, node5 is a service node that executes the echoString service of the
314 component that has been loaded by the component service node node4.
315
316 \subsection loader_connections Defining connections between nodes
317 After having defined all the calculation nodes needed, it is necessary 
318 to connect them to define the order of execution (control flow)
319  and the exchanges of data (data flow).
320
321 - Control flow
322
323 The order of execution is defined by means of control links between
324 nodes.
325 These links are defined in a control tag with subtags fromnode and tonode
326 which give the names of precedent node and following node.
327 Example of control link :
328 \code
329   <control> 
330     <fromnode>node1</fromnode> 
331     <tonode>node2</tonode> 
332   </control>
333 \endcode
334 This control link indicates that execution of node2 must be after complete
335 execution of node1.
336
337 - Data flow
338
339 Exchange of data between nodes is defined by means of data links between 
340 output ports and input ports.
341 These links are defined in a datalink tag with subtags fromnode, tonode, fromport
342 and toport. The output port is specified with the node name and the output port
343 name. It's similar for the input port.
344
345 Example of data link :
346 \code
347   <datalink> 
348     <fromnode>node1</fromnode> <fromport>p1</fromport>
349     <tonode>node2</tonode> <toport>p1</toport>
350   </datalink>
351 \endcode
352 This data link indicates that the output argument p1 of node node1
353 will be sent to node node2 and used as input argument p1.
354 By default, with this datalink definition, a control link is automatically defined between node1 and node2,
355 to ensure a complete execution of node1 before node2 starts.
356 Sometimes, this control link must not be created, for instance with loops (see below).
357 With most simple cases, yacs loader is able to decide to create or not the control link. It is always
358 possible to ask explicitely a data link without control link:
359 \code
360   <datalink control="false"> 
361     <fromnode>node1</fromnode> <fromport>p1</fromport>
362     <tonode>node2</tonode> <toport>p1</toport>
363   </datalink>
364 \endcode
365
366 So, it is equivalent to write:
367 \code
368   <datalink> 
369     <fromnode>node1</fromnode> <fromport>p1</fromport>
370     <tonode>node2</tonode> <toport>p1</toport>
371   </datalink>
372 \endcode
373 Or:
374 \code
375   <control> 
376     <fromnode>node1</fromnode> 
377     <tonode>node2</tonode> 
378   </control>
379   <datalink control="false"> 
380     <fromnode>node1</fromnode> <fromport>p1</fromport>
381     <tonode>node2</tonode> <toport>p1</toport>
382   </datalink>
383 \endcode
384 Control links may be defined implicitely several times without problem.
385
386 \subsection loader_parameters Defining initialization parameters
387 It is possible to initialize directly input ports with constants.
388 This is done with a definition put in a parameter tag with subtags tonode,
389 toport and value.
390 tonode is the name of the node and toport the name of the port to initialize.
391 value gives the constant to use to initialize the port. This constant is 
392 given in XML-RPC coding convention (http://www.xmlrpc.com/).
393
394 Example of parameter initialization :
395 \code
396     <parameter>
397         <tonode>node1</tonode> <toport>p1</toport>
398         <value><string>coucou</string></value>
399     </parameter>
400 \endcode
401
402
403 This parameter initialization indicates that the input argument p1
404 of node1 is initialized with a string constant ("coucou").
405
406 \subsection loader_example1 Putting all this together
407 Now that we are able to define data types, calculation nodes and links, we
408 can define a complete calculation schema with interconnected calculation.
409
410 \code
411   <proc>
412     <inline name="node1" >
413       <script>
414         <code>p1=p1+10</code>
415       </script>
416       <inport name="p1" type="int"/>
417       <outport name="p1" type="int"/>
418     </inline>
419     <inline name="node2" >
420       <script>
421         <code>p1=2*p1</code>
422       </script>
423       <inport name="p1" type="int"/>
424       <outport name="p1" type="int"/>
425     </inline>
426     <service name="node4" >
427         <ref>corbaname:rir:#test.my_context/Echo.Object</ref>
428         <method>echoDouble</method>
429         <inport name="p1" type="double"/>
430         <outport name="p1" type="double"/>
431     </service>
432     <control> 
433       <fromnode>node1</fromnode> <tonode>node2</tonode> 
434     </control>
435     <control> 
436       <fromnode>node1</fromnode> <tonode>node4</tonode> 
437     </control>
438     <datalink> 
439       <fromnode>node1</fromnode> <fromport>p1</fromport>
440       <tonode>node2</tonode> <toport>p1</toport>
441     </datalink>
442     <datalink> 
443       <fromnode>node1</fromnode> <fromport>p1</fromport>
444       <tonode>node4</tonode> <toport>p1</toport>
445     </datalink>
446     <parameter>
447       <tonode>node1</tonode> <toport>p1</toport>
448       <value><int>5</int></value>
449     </parameter>
450   </proc>
451 \endcode
452 We have put together 2 inline nodes and one reference service node
453 with nodes node2 and node4 that will be concurrently executed as can
454 be seen on the control flow diagram below.
455
456 \image html schema.jpeg
457
458 \subsection loader_composed Defining composed calculation nodes
459 The next step is to define composed nodes either to modularize the calculation
460 schema or to introduce control nodes like loop or switch.
461
462 - Using block to modularize the schema
463
464 All the previously defined elements (except the data types) can be put
465 in block nodes. It is easy : create a bloc tag with an attribute name
466 that contains all the definitions and you have a composed node that is
467 a block.
468
469 Example of block :
470 \code
471 <bloc name="b">
472     <inline name="node1" >
473       <script>
474         <code>p1=p1+10</code>
475       </script>
476       <inport name="p1" type="int"/>
477       <outport name="p1" type="int"/>
478     </inline>
479     <service name="node4" >
480         <ref>corbaname:rir:#test.my_context/Echo.Object</ref>
481         <method>echoDouble</method>
482         <inport name="p1" type="double"/>
483         <outport name="p1" type="double"/>
484     </service>
485     <control> 
486       <fromnode>node1</fromnode> <tonode>node4</tonode> 
487     </control>
488     <datalink> 
489       <fromnode>node1</fromnode> <fromport>p1</fromport>
490       <tonode>node4</tonode> <toport>p1</toport>
491     </datalink>
492 </bloc>
493 \endcode
494 This block can now be linked with other nodes of any kind in the same way
495 as elementary nodes.
496 The rules are : it is not possible to set control links that cross the boundary
497 of the block. On the other end, it is possible to set data links that cross
498 this boundary either on input or on output.
499
500 - Defining a For Loop
501
502 If you want to execute a calculation n times, you can use a ForLoop node
503 to define this kind of computation.
504 A for loop is defined in a forloop tag that has 2 attributes : name and nsteps.
505 name is as always the name of the node and nsteps is the number of steps of the 
506 loop. The for loop must contain one and only one node that can be an elementary
507 calculation node or a composed node. It is possible to have a for loop in a for loop, for 
508 example. If you want to put more than one calculation node in a for loop, use
509 a block.
510
511 Example :
512 \code
513     <forloop name="l1" nsteps="5">
514       <inline name="node2" >
515         <script>
516           <code>p1=p1+10</code>
517         </script>
518         <inport name="p1" type="int"/>
519         <outport name="p1" type="int"/>
520       </inline>
521     </forloop >
522 \endcode
523 The rules are the same as for the block node. But inside loops, to be able to perform 
524 iterative computation, it is allowed to link an output port of an internal node 
525 with an input port of a previous node in control flow. The only limitation is that
526 you have to put the node and the data link in a block node as links can't be defined
527 in a forloop section.
528
529 Here is an example :
530 \code
531   <forloop name="l1" nsteps="5">
532     <bloc name="b">
533       <inline name="node2" >
534         <script>
535           <code>p1=p1+10</code>
536         </script>
537         <inport name="p1" type="int"/>
538         <outport name="p1" type="int"/>
539       </inline>
540       <datalink control="false">
541         <fromnode>node2</fromnode> <fromport>p1</fromport>
542         <tonode>node2</tonode> <toport>p1</toport>
543       </datalink>
544     </bloc>
545   </forloop >
546 \endcode
547
548 Last point : it is possible to link the nsteps entry of the for loop
549 with an output port that produces integer data. The input port
550 of the loop has the same name as the attribute (nsteps).
551
552 - Defining a While Loop
553
554 This kind of loop is mainly similar to the for loop. The only difference is that
555 the loop executes as long as a condition is true. A while loop is defined in
556 a whileloop tag and has only one attribute : name as usual.
557 The condition value is set through an input port (which name is condition) 
558 that accepts boolean value.
559
560 Example of a while loop:
561 \code
562   <whileloop name="l1" >
563     <bloc name="b">
564       <inline name="node2" >
565         <script>
566           <code>p1=p1+10</code>
567           <code><![CDATA[  condition=p1 < 40.]]> </code>
568         </script>
569         <inport name="p1" type="int"/>
570         <outport name="p1" type="int"/>
571         <outport name="condition" type="bool"/>
572       </inline>
573       <datalink control="false">
574         <fromnode>node2</fromnode> <fromport>p1</fromport>
575         <tonode>node2</tonode> <toport>p1</toport>
576       </datalink>
577     </bloc>
578   </whileloop >
579   <datalink control="false">
580     <fromnode>l1.b.node2</fromnode> <fromport>condition</fromport>
581     <tonode>l1</tonode> <toport>condition</toport>
582   </datalink>
583   <parameter>
584     <tonode>l1.b.node2</tonode> <toport>p1</toport>
585     <value><int>23</int> </value>
586   </parameter>
587 \endcode
588
589 It is here again possible to define composed node of any kind as internal
590 node to define loops in loops.
591
592 - Defining a Switch Loop
593
594 A switch node is equivalent to a switch C. It has an input port (which name
595 is select) that accepts integer data. According to the value in the select 
596 port one or another case node is selected for execution. Each case is defined
597 in a case tag with one attribute id that must be an integer or default. If no case
598 is defined for the select value the switch node uses the default case.
599 A case can contain one and only one internal node.
600
601 A minimal but almost complete example :
602 \code
603     <inline name="n" >
604         <script>
605             <code>select=3</code>
606         </script>
607         <outport name="select" type="int"/>
608     </inline>
609
610     <switch name="b1">
611       <case id="3">
612         <inline name="n2" >
613           <script><code>print p1</code></script>
614           <inport name="p1" type="double"/>
615           <outport name="p1" type="double"/>
616         </inline>
617       </case>
618       <default>
619         <inline name="n2" >
620           <script><code>print p1</code></script>
621           <inport name="p1" type="double"/>
622           <outport name="p1" type="double"/>
623         </inline>
624       </default>
625     </switch>
626
627     <control> <fromnode>n</fromnode> <tonode>b1</tonode> </control>
628     <datalink> <fromnode>n</fromnode><fromport>select</fromport>
629                <tonode>b1</tonode> <toport>select</toport> </datalink>
630     <parameter>
631         <tonode>b1.3.n2</tonode> <toport>p1</toport>
632         <value><double>54</double> </value>
633     </parameter>
634     <parameter>
635         <tonode>b1.default.n2</tonode> <toport>p1</toport>
636         <value><double>54</double> </value>
637     </parameter>
638 \endcode
639
640
641 */