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