A fully working version of the scheduling language with added examples
This commit is contained in:
parent
ec42f74960
commit
ebfd85a666
126 changed files with 7235 additions and 981 deletions
41
transformation/schedule/schedule_lib/README.md
Normal file
41
transformation/schedule/schedule_lib/README.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
## Node Module
|
||||
|
||||
Defines the abstract base Node class for graph-based structures. Each Node is assigned
|
||||
a unique identifier via an external IdGenerator. The class provides an interface for
|
||||
managing execution state and generating DOT graph representations using Jinja2 templates.
|
||||
|
||||
### Class: `Node`
|
||||
|
||||
- **Attributes**
|
||||
- `id: int`: A unique identifier assigned to each instance upon initialization.
|
||||
|
||||
- **Methods**
|
||||
- `get_id`
|
||||
- returns: `int`, The unique node ID
|
||||
|
||||
Retrieves the unique identifier of the node.
|
||||
|
||||
- `generate_stack_frame`
|
||||
- exec_id: `int`, The ID of the execution context.
|
||||
- returns: `None`
|
||||
|
||||
Initializes a new state frame for a specific execution context.
|
||||
Designed to be overridden in subclasses that use execution state.
|
||||
|
||||
- `delete_stack_frame`
|
||||
- exec_id: `int`, The ID of the execution context.
|
||||
- returns: `None`
|
||||
|
||||
Deletes the state frame for a specific execution context.
|
||||
Designed to be overridden in subclasses that use execution state.
|
||||
|
||||
- `generate_dot`
|
||||
- nodes: `list[str]`, A list to append DOT node definitions to.
|
||||
- edges: `list[str]`, A list to append DOT edges definitions to.
|
||||
- visited: `set[str]`, A set of already visited node IDs to avoid duplicates or recursion.
|
||||
- template: `list[str]`, A Jinja2 template used to format the node's DOT representation.
|
||||
- returns: `None`
|
||||
|
||||
Generates the DOT graph representation for this node and its relationships.
|
||||
Must be implemented in subclasses.
|
||||
|
||||
93
transformation/schedule/schedule_lib/Schedule_lib.xml
Normal file
93
transformation/schedule/schedule_lib/Schedule_lib.xml
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<mxlibrary>[
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"start_name\" type=\"Start\" ports_exec_out=\"[&quot;out&quot;]\" ports_data_out=\"[]\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"100\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><mxCell id=\"5\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"exec\" id=\"6\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"5\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 100,
|
||||
"aspect": "fixed",
|
||||
"title": "Start Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"end_name\" type=\"End\" ports_exec_in=\"[&quot;in&quot;]\" ports_data_in=\"[]\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"100\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"exec\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"6\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 100,
|
||||
"aspect": "fixed",
|
||||
"title": "End Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%&#10;%file%&#10;matches: %n%\" placeholders=\"1\" name=\"match_name\" type=\"Match\" file=\"rule_filename.od\" n=\"1\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=60;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"220\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"60\" width=\"160\" height=\"160\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"160\" as=\"geometry\"><mxRectangle width=\"80\" height=\"160\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"data\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"110\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"in\" type=\"exec\" id=\"6\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"7\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"160\" as=\"geometry\"><mxRectangle width=\"80\" height=\"160\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"data\" id=\"8\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"110\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"success\" type=\"exec\" id=\"9\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"fail\" type=\"exec\" id=\"10\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 220,
|
||||
"aspect": "fixed",
|
||||
"title": "Match Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%&#10;%file%\" placeholders=\"1\" name=\"rewrite_name\" type=\"Rewrite\" file=\"rule_filename.od\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry y=\"1.1368683772161603e-13\" width=\"160\" height=\"150\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"110\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"110\" as=\"geometry\"><mxRectangle width=\"80\" height=\"110\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"exec\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"6\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"110\" as=\"geometry\"><mxRectangle width=\"80\" height=\"110\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"exec\" id=\"7\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"in\" type=\"data\" id=\"8\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"-70\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"out\" type=\"data\" id=\"9\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"10\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 150,
|
||||
"aspect": "fixed",
|
||||
"title": "Rewrite Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"action_name\" type=\"Action\" ports_exec_in=\"[&quot;in&quot;]\" ports_exec_out=\"[&quot;out&quot;]\" ports_data_in=\"[]\" ports_data_out=\"[]\" action=\"print(&quot;hello world&quot;)\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"100\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"exec\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"6\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"exec\" id=\"7\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 100,
|
||||
"aspect": "fixed",
|
||||
"title": "Action Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"modify_name\" type=\"Modify\" rename=\"{&quot;t&quot;:&quot;transition&quot;}\" delete=\"[]\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"100\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"data\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"6\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"data\" id=\"7\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 100,
|
||||
"aspect": "fixed",
|
||||
"title": "Modify Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"merge_name\" type=\"Merge\" ports_data_in=\"[&quot;input1&quot;, &quot;input2&quot;]\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"150\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"110\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"110\" as=\"geometry\"><mxRectangle width=\"80\" height=\"110\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"input1\" type=\"data\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"input2\" type=\"data\" id=\"6\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"7\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"110\" as=\"geometry\"><mxRectangle width=\"80\" height=\"110\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"data\" id=\"8\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 150,
|
||||
"aspect": "fixed",
|
||||
"title": "Merge Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"store_name\" type=\"Store\" ports=\"[&quot;input1&quot;]\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"200\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"160\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"160\" as=\"geometry\"><mxRectangle width=\"80\" height=\"160\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"exec\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"input1\" type=\"exec\" id=\"6\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"input1\" type=\"data\" id=\"7\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"110\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"8\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"160\" as=\"geometry\"><mxRectangle width=\"80\" height=\"160\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"data\" id=\"9\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"8\"><mxGeometry x=\"10\" y=\"110\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"out\" type=\"exec\" id=\"10\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"8\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"input1\" type=\"exec\" id=\"11\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"8\"><mxGeometry x=\"10\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 200,
|
||||
"aspect": "fixed",
|
||||
"title": "Store Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"loop_name\" type=\"Loop\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"200\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"160\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"160\" as=\"geometry\"><mxRectangle width=\"80\" height=\"160\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"data\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"110\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"in\" type=\"exec\" id=\"6\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"7\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"160\" as=\"geometry\"><mxRectangle width=\"80\" height=\"160\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"data\" id=\"8\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"110\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"it\" type=\"exec\" id=\"9\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"out\" type=\"exec\" id=\"10\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"7\"><mxGeometry x=\"10\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 200,
|
||||
"aspect": "fixed",
|
||||
"title": "Loop Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%&#10;%file%\" placeholders=\"1\" name=\"schedule_name\" type=\"Schedule\" file=\"schedule_page-name\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"100\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"60\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"exec\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"6\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"60\" as=\"geometry\"><mxRectangle width=\"80\" height=\"60\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"exec\" id=\"7\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 100,
|
||||
"aspect": "fixed",
|
||||
"title": "Schedule Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"%name%: %type%\" placeholders=\"1\" name=\"print_name\" type=\"Print\" event=\"False\" custom=\"{{ data }}\" id=\"2\"><mxCell style=\"shape=table;childLayout=tableLayout;startSize=40;collapsible=0;recursiveResize=1;expand=0;fontStyle=1;editable=1;movable=1;resizable=1;rotatable=0;deletable=1;locked=0;connectable=0;allowArrows=0;pointerEvents=0;perimeter=rectanglePerimeter;rounded=1;container=1;dropTarget=0;swimlaneHead=1;swimlaneBody=1;top=1;noLabel=0;autosize=0;resizeHeight=0;spacing=2;metaEdit=1;resizeWidth=0;arcSize=10;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"160\" height=\"150\" as=\"geometry\"/></mxCell></object><mxCell id=\"3\" value=\"\" style=\"shape=tableRow;horizontal=0;swimlaneHead=0;swimlaneBody=0;top=0;left=0;strokeColor=inherit;bottom=0;right=0;dropTarget=0;fontStyle=0;fillColor=none;points=[[0,0.5],[1,0.5]];startSize=0;collapsible=0;recursiveResize=1;expand=0;rounded=0;allowArrows=0;connectable=0;autosize=1;resizeHeight=1;rotatable=0;\" vertex=\"1\" parent=\"2\"><mxGeometry y=\"40\" width=\"160\" height=\"110\" as=\"geometry\"/></mxCell><mxCell id=\"4\" value=\"Input\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=60;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry width=\"80\" height=\"110\" as=\"geometry\"><mxRectangle width=\"80\" height=\"110\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"in\" type=\"exec\" id=\"5\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"4\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><mxCell id=\"6\" value=\"Output\" style=\"swimlane;swimlaneHead=0;swimlaneBody=0;fontStyle=0;strokeColor=inherit;connectable=0;fillColor=none;startSize=40;collapsible=0;recursiveResize=1;expand=0;allowArrows=0;autosize=1;rotatable=0;noLabel=1;overflow=hidden;swimlaneLine=0;editable=0;\" vertex=\"1\" parent=\"3\"><mxGeometry x=\"80\" width=\"80\" height=\"110\" as=\"geometry\"><mxRectangle width=\"80\" height=\"110\" as=\"alternateBounds\"/></mxGeometry></mxCell><object label=\"out\" type=\"exec\" id=\"7\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"10\" y=\"10\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object><object label=\"in\" type=\"data\" id=\"8\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"6\"><mxGeometry x=\"-70\" y=\"60\" width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 160,
|
||||
"h": 150,
|
||||
"aspect": "fixed",
|
||||
"title": "Print Node"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"out\" type=\"exec\" id=\"2\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 60,
|
||||
"h": 40,
|
||||
"aspect": "fixed",
|
||||
"title": "Exec Gate"
|
||||
},
|
||||
{
|
||||
"xml": "<mxGraphModel><root><mxCell id=\"0\"/><mxCell id=\"1\" parent=\"0\"/><object label=\"in\" type=\"data\" id=\"2\"><mxCell style=\"rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;\" vertex=\"1\" parent=\"1\"><mxGeometry width=\"60\" height=\"40\" as=\"geometry\"/></mxCell></object></root></mxGraphModel>",
|
||||
"w": 60,
|
||||
"h": 40,
|
||||
"aspect": "fixed",
|
||||
"title": "Data Gate"
|
||||
}
|
||||
]</mxlibrary>
|
||||
31
transformation/schedule/schedule_lib/__init__.py
Normal file
31
transformation/schedule/schedule_lib/__init__.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from .action import Action
|
||||
from .data_node import DataNode
|
||||
from .end import End
|
||||
from .exec_node import ExecNode
|
||||
from .loop import Loop
|
||||
from .match import Match
|
||||
from .merge import Merge
|
||||
from .modify import Modify
|
||||
from .null_node import NullNode
|
||||
from .print import Print
|
||||
from .rewrite import Rewrite
|
||||
from .start import Start
|
||||
from .store import Store
|
||||
from .sub_schedule import SubSchedule
|
||||
|
||||
__all__ = [
|
||||
"Action",
|
||||
"DataNode",
|
||||
"End",
|
||||
"ExecNode",
|
||||
"Loop",
|
||||
"Match",
|
||||
"Merge",
|
||||
"Modify",
|
||||
"NullNode",
|
||||
"Rewrite",
|
||||
"Print",
|
||||
"Start",
|
||||
"Store",
|
||||
"SubSchedule",
|
||||
]
|
||||
106
transformation/schedule/schedule_lib/action.py
Normal file
106
transformation/schedule/schedule_lib/action.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
from typing import List, override, Type
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode
|
||||
|
||||
class ActionState:
|
||||
def __init__(self):
|
||||
self.var = {"output_gate": "out"}
|
||||
|
||||
class Action(ExecNode, DataNode):
|
||||
def __init__(
|
||||
self,
|
||||
ports_exec_in: list[str],
|
||||
ports_exec_out: list[str],
|
||||
ports_data_in: list[str],
|
||||
ports_data_out: list[str],
|
||||
code: str = "",
|
||||
init: str = "",
|
||||
) -> None:
|
||||
self.gates: tuple[list[str], list[str], list[str], list[str]] = (ports_exec_in, ports_exec_out, ports_data_in, ports_data_out)
|
||||
super().__init__()
|
||||
self.state: dict[int, ActionState] = {}
|
||||
self.var_globals = {}
|
||||
self.code = code
|
||||
self.init = init
|
||||
|
||||
@override
|
||||
def get_exec_input_gates(self) -> list[str]:
|
||||
return self.gates[0]
|
||||
|
||||
@override
|
||||
def get_exec_output_gates(self) -> list[str]:
|
||||
return self.gates[1]
|
||||
|
||||
@override
|
||||
def get_data_input_gates(self) -> list[str]:
|
||||
return self.gates[2]
|
||||
|
||||
@override
|
||||
def get_data_output_gates(self) -> list[str]:
|
||||
return self.gates[3]
|
||||
|
||||
@override
|
||||
def nextState(self, exec_id: int) -> tuple["ExecNode", str]:
|
||||
state = self.get_state(exec_id)
|
||||
return self.next_node[state.var["output_gate"]]
|
||||
|
||||
def get_state(self, exec_id) -> ActionState:
|
||||
return self.state[exec_id]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state[exec_id] = (state := ActionState())
|
||||
if self.init:
|
||||
exec (self.init, {"var": state.var}, {"globals": self.var_globals})
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state.pop(exec_id)
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
state = self.get_state(exec_id)
|
||||
exec(
|
||||
self.code,
|
||||
{
|
||||
"api": od,
|
||||
"var": state.var,
|
||||
"data_in": {port: value.get_data(exec_id) for port, value in self.data_in.items() if value is not None},
|
||||
"data_out": {port: value.get_data(exec_id) for port, value in self.data_out.items() if value is not None},
|
||||
"globals": self.var_globals,
|
||||
},
|
||||
)
|
||||
for gate, d in self.data_out.items():
|
||||
DataNode.input_event(self, gate, exec_id)
|
||||
return None
|
||||
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
return
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"action",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
ExecNode.generate_dot(self, nodes, edges, visited, template)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
83
transformation/schedule/schedule_lib/data.py
Normal file
83
transformation/schedule/schedule_lib/data.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
from symtable import Class
|
||||
from typing import Any, Generator, Callable, Iterator, TYPE_CHECKING, override
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from transformation.schedule.schedule_lib import DataNode
|
||||
|
||||
|
||||
class DataState:
|
||||
def __init__(self, data: Any):
|
||||
self.data: list[dict[Any, Any]] = []
|
||||
|
||||
class Data:
|
||||
__slots__ = ("state", "_parent")
|
||||
|
||||
def __init__(self, parent: "DataNode") -> None:
|
||||
self.state: dict[int, DataState] = dict()
|
||||
self._parent = parent
|
||||
|
||||
def __dir__(self):
|
||||
return [attr for attr in super().__dir__() if attr != "_super"]
|
||||
|
||||
def get_data(self, exec_id: int) -> list[dict[str, str]]:
|
||||
state = self.get_state(exec_id)
|
||||
return state.data
|
||||
|
||||
def get_state(self, exec_id) -> DataState:
|
||||
return self.state[exec_id]
|
||||
|
||||
def store_data(self, exec_id: int, data_gen: Generator, n: int) -> bool:
|
||||
state = self.get_state(exec_id)
|
||||
state.data.clear()
|
||||
if n == 0:
|
||||
return True
|
||||
i: int = 0
|
||||
while (match := next(data_gen, None)) is not None:
|
||||
state.data.append(match)
|
||||
i += 1
|
||||
if i >= n:
|
||||
break
|
||||
else:
|
||||
if n == float("inf"):
|
||||
return bool(len(state.data))
|
||||
state.data.clear()
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_parent(self) -> "DataNode":
|
||||
return self._parent
|
||||
|
||||
def replace(self, exec_id: int, data: list[dict[str, str]]) -> None:
|
||||
state = self.get_state(exec_id)
|
||||
state.data.clear()
|
||||
state.data.extend(data)
|
||||
|
||||
def append(self, exec_id: int, data: dict[str, str]) -> None:
|
||||
self.get_state(exec_id).data.append(data)
|
||||
|
||||
def extend(self, exec_id: int, data: list[dict[str, str]]) -> None:
|
||||
self.get_state(exec_id).data.extend(data)
|
||||
|
||||
def clear(self, exec_id: int) -> None:
|
||||
self.get_state(exec_id).data.clear()
|
||||
|
||||
def pop(self, exec_id: int, index: int =-1) -> Any:
|
||||
return self.get_state(exec_id).data.pop(index)
|
||||
|
||||
def empty(self, exec_id: int) -> bool:
|
||||
return len(self.get_state(exec_id).data) == 0
|
||||
|
||||
def __getitem__(self, index):
|
||||
raise NotImplementedError
|
||||
|
||||
def __iter__(self, exec_id: int) -> Iterator[dict[str, str]]:
|
||||
return self.get_state(exec_id).data.__iter__()
|
||||
|
||||
def __len__(self, exec_id: int) -> int:
|
||||
return self.get_state(exec_id).data.__len__()
|
||||
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
self.state[exec_id] = DataState(exec_id)
|
||||
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
self.state.pop(exec_id)
|
||||
101
transformation/schedule/schedule_lib/data_node.py
Normal file
101
transformation/schedule/schedule_lib/data_node.py
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
from abc import abstractmethod
|
||||
from typing import Any, Generator, List, override
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from .data import Data
|
||||
from .funcs import generate_dot_edge
|
||||
from .node import Node
|
||||
|
||||
|
||||
class DataNodeState:
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
|
||||
class DataNode(Node):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.eventsub: dict[str, list[tuple[DataNode, str]]] = {
|
||||
gate: [] for gate in self.get_data_output_gates()
|
||||
}
|
||||
self.data_out: dict[str, Data] = {
|
||||
name: Data(self) for name in self.get_data_output_gates()
|
||||
}
|
||||
self.data_in: dict[str, Data | None] = {
|
||||
name: None for name in self.get_data_input_gates()
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_data_input_gates() -> List[str]:
|
||||
return ["in"]
|
||||
|
||||
@staticmethod
|
||||
def get_data_output_gates() -> List[str]:
|
||||
return ["out"]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
for d in self.data_out.values():
|
||||
d.generate_stack_frame(exec_id)
|
||||
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().delete_stack_frame(exec_id)
|
||||
for d in self.data_out.values():
|
||||
d.delete_stack_frame(exec_id)
|
||||
|
||||
def connect_data(
|
||||
self, data_node: "DataNode", from_gate: str, to_gate: str, eventsub=True
|
||||
) -> None:
|
||||
if from_gate not in self.get_data_output_gates():
|
||||
raise Exception(f"from_gate {from_gate} is not a valid port")
|
||||
if to_gate not in data_node.get_data_input_gates():
|
||||
raise Exception(f"to_gate {to_gate} is not a valid port")
|
||||
data_node.data_in[to_gate] = self.data_out[from_gate]
|
||||
if eventsub:
|
||||
self.eventsub[from_gate].append((data_node, to_gate))
|
||||
|
||||
def store_data(self, exec_id, data_gen: Generator, port: str, n: int) -> None:
|
||||
self.data_out[port].store_data(exec_id, data_gen, n)
|
||||
for sub, gate in self.eventsub[port]:
|
||||
sub.input_event(gate, exec_id)
|
||||
|
||||
def get_input_data(self, gate: str, exec_id: int) -> list[dict[Any, Any]]:
|
||||
data = self.data_in[gate]
|
||||
if data is None:
|
||||
return [{}]
|
||||
return data.get_data(exec_id)
|
||||
|
||||
@abstractmethod
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
for sub, gate_sub in self.eventsub[gate]:
|
||||
sub.input_event(gate_sub, exec_id)
|
||||
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
for port, data in self.data_in.items():
|
||||
if data is not None:
|
||||
source = data.get_parent()
|
||||
generate_dot_edge(
|
||||
source,
|
||||
self,
|
||||
edges,
|
||||
template,
|
||||
kwargs={
|
||||
"prefix": "d",
|
||||
"from_gate": [
|
||||
port
|
||||
for port, value in source.data_out.items()
|
||||
if value == data
|
||||
][0],
|
||||
"to_gate": port,
|
||||
"color": "green",
|
||||
},
|
||||
)
|
||||
data.get_parent().generate_dot(nodes, edges, visited, template)
|
||||
for gate_form, subs in self.eventsub.items():
|
||||
for sub, gate in subs:
|
||||
sub.generate_dot(nodes, edges, visited, template)
|
||||
80
transformation/schedule/schedule_lib/end.py
Normal file
80
transformation/schedule/schedule_lib/end.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
from typing import List, override, Type
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from . import DataNode
|
||||
from .exec_node import ExecNode
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
|
||||
class EndState:
|
||||
def __init__(self) -> None:
|
||||
self.end_gate: str = ""
|
||||
|
||||
class End(ExecNode, DataNode):
|
||||
@override
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
pass
|
||||
|
||||
def __init__(self, ports_exec: List[str], ports_data: List[str]) -> None:
|
||||
self.ports_exec = ports_exec
|
||||
self.ports_data = ports_data
|
||||
super().__init__()
|
||||
self.state: dict[int, EndState] = {}
|
||||
|
||||
@override
|
||||
def get_exec_input_gates(self):
|
||||
return self.ports_exec
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_exec_output_gates():
|
||||
return []
|
||||
|
||||
@override
|
||||
def get_data_input_gates(self):
|
||||
return self.ports_data
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_data_output_gates():
|
||||
return []
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
state = self.get_state(exec_id)
|
||||
state.end_gate = port
|
||||
return 1, {"exec_gate": state.end_gate, "data_out": {port: data.get_data(exec_id) for port, data in self.data_in.items()}}
|
||||
|
||||
def get_state(self, exec_id) -> EndState:
|
||||
return self.state[exec_id]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state[exec_id] = EndState()
|
||||
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().delete_stack_frame(exec_id)
|
||||
self.state.pop(exec_id)
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": "end",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
}
|
||||
)
|
||||
35
transformation/schedule/schedule_lib/exec_node.py
Normal file
35
transformation/schedule/schedule_lib/exec_node.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
from abc import abstractmethod
|
||||
from api.od import ODAPI
|
||||
from .node import Node
|
||||
|
||||
|
||||
class ExecNode(Node):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
from .null_node import NullNode
|
||||
self.next_node: dict[str, tuple[ExecNode, str]] = {}
|
||||
for port in self.get_exec_output_gates():
|
||||
self.next_node[port] = (NullNode(), "in")
|
||||
|
||||
def nextState(self, exec_id: int) -> tuple["ExecNode", str]:
|
||||
return self.next_node["out"]
|
||||
|
||||
@staticmethod
|
||||
def get_exec_input_gates():
|
||||
return ["in"]
|
||||
|
||||
@staticmethod
|
||||
def get_exec_output_gates():
|
||||
return ["out"]
|
||||
|
||||
def connect(self, next_state: "ExecNode", from_gate: str, to_gate: str) -> None:
|
||||
if from_gate not in self.get_exec_output_gates():
|
||||
raise Exception(f"from_gate {from_gate} is not a valid port")
|
||||
if to_gate not in next_state.get_exec_input_gates():
|
||||
raise Exception(f"to_gate {to_gate} is not a valid port")
|
||||
self.next_node[from_gate] = (next_state, to_gate)
|
||||
|
||||
@abstractmethod
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
return None
|
||||
56
transformation/schedule/schedule_lib/funcs.py
Normal file
56
transformation/schedule/schedule_lib/funcs.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
from typing import Callable, List
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from .singleton import Singleton
|
||||
|
||||
|
||||
class IdGenerator(metaclass=Singleton):
|
||||
exec_id = -1
|
||||
node_id = -1
|
||||
|
||||
@classmethod
|
||||
def generate_node_id(cls) -> int:
|
||||
cls.node_id +=1
|
||||
return cls.node_id
|
||||
|
||||
@classmethod
|
||||
def generate_exec_id(cls) -> int:
|
||||
cls.exec_id += 1
|
||||
return cls.exec_id
|
||||
|
||||
def generate_dot_wrap(func) -> Callable:
|
||||
def wrapper(self, *args, **kwargs) -> str:
|
||||
nodes = []
|
||||
edges = []
|
||||
self.reset_visited()
|
||||
func(self, nodes, edges, *args, **kwargs)
|
||||
return f"digraph G {{\n\t{"\n\t".join(nodes)}\n\t{"\n\t".join(edges)}\n}}"
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def not_visited(func) -> Callable:
|
||||
def wrapper(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], *args, **kwargs
|
||||
) -> None:
|
||||
if self in visited:
|
||||
return
|
||||
visited.add(self)
|
||||
func(self, nodes, edges, visited, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def generate_dot_node(self, nodes: List[str], template: Template, **kwargs) -> None:
|
||||
nodes.append(template.module.__getattribute__("Node")(**{**kwargs, "id": self.id}))
|
||||
|
||||
|
||||
def generate_dot_edge(
|
||||
self, target, edges: List[str], template: Template, kwargs
|
||||
) -> None:
|
||||
edges.append(
|
||||
template.module.__getattribute__("Edge")(
|
||||
**{**kwargs, "from_id": self.id, "to_id": target.id}
|
||||
)
|
||||
)
|
||||
74
transformation/schedule/schedule_lib/loop.py
Normal file
74
transformation/schedule/schedule_lib/loop.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import functools
|
||||
from typing import List, Generator, override, Type
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode
|
||||
from .data_node import Data
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
|
||||
class Loop(ExecNode, DataNode):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.cur_data: Data = Data(self)
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_exec_output_gates():
|
||||
return ["it", "out"]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.cur_data.generate_stack_frame(exec_id)
|
||||
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().delete_stack_frame(exec_id)
|
||||
self.cur_data.delete_stack_frame(exec_id)
|
||||
|
||||
@override
|
||||
def nextState(self, exec_id: int) -> tuple[ExecNode, str]:
|
||||
return self.next_node["out" if self.data_out["out"].empty(exec_id) else "it"]
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
self.data_out["out"].clear(exec_id)
|
||||
|
||||
if not self.cur_data.empty(exec_id):
|
||||
self.data_out["out"].append(exec_id, self.cur_data.pop(exec_id,0))
|
||||
DataNode.input_event(self, "out", exec_id)
|
||||
return None
|
||||
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
self.cur_data.replace(exec_id, self.get_input_data(gate, exec_id))
|
||||
data_o = self.data_out["out"]
|
||||
if data_o.empty(exec_id):
|
||||
return
|
||||
data_o.clear(exec_id)
|
||||
DataNode.input_event(self, "out", exec_id)
|
||||
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"loop",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
ExecNode.generate_dot(self, nodes, edges, visited, template)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
67
transformation/schedule/schedule_lib/match.py
Normal file
67
transformation/schedule/schedule_lib/match.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
from typing import List, override, Type
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from transformation.schedule.rule_executor import RuleExecutor
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
|
||||
class Match(ExecNode, DataNode):
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
pass
|
||||
|
||||
def __init__(self, label: str, n: int | float) -> None:
|
||||
super().__init__()
|
||||
self.label: str = label
|
||||
self.n: int = n
|
||||
self.rule = None
|
||||
self.rule_executer: RuleExecutor | None = None
|
||||
|
||||
@override
|
||||
def nextState(self, exec_id: int) -> tuple[ExecNode, str]:
|
||||
return self.next_node["fail" if self.data_out["out"].empty(exec_id) else "success"]
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_exec_output_gates():
|
||||
return ["success", "fail"]
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
pivot = {}
|
||||
if self.data_in is not None:
|
||||
pivot = self.get_input_data("in", exec_id)[0]
|
||||
# TODO: remove this print
|
||||
print(f"matching: {self.label}\n\tpivot: {pivot}")
|
||||
self.store_data( exec_id,
|
||||
self.rule_executer.match_rule(od.m, self.rule, pivot=pivot), "out", self.n
|
||||
)
|
||||
return None
|
||||
|
||||
def init_rule(self, rule, rule_executer):
|
||||
self.rule = rule
|
||||
self.rule_executer = rule_executer
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"match_{self.n}\n{self.label}",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
ExecNode.generate_dot(self, nodes, edges, visited, template)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
57
transformation/schedule/schedule_lib/merge.py
Normal file
57
transformation/schedule/schedule_lib/merge.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from typing import List, override, Type
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from transformation.schedule.rule_executor import RuleExecutor
|
||||
from . import ExecNode
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode, DataNodeState
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
|
||||
class Merge(DataNode):
|
||||
def __init__(self, ports: list[str]) -> None:
|
||||
self.in_data_ports = ports # ports must be defined before super.__init__
|
||||
super().__init__()
|
||||
self.in_data_ports.reverse()
|
||||
|
||||
@override
|
||||
def get_data_input_gates(self) -> list[str]:
|
||||
return self.in_data_ports
|
||||
|
||||
@override
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
out = self.data_out["out"]
|
||||
b = (not out.empty(exec_id)) and (self.data_in[gate].empty(exec_id))
|
||||
out.clear(exec_id)
|
||||
if b:
|
||||
DataNode.input_event(self, "out", exec_id)
|
||||
return
|
||||
|
||||
# TODO: only first element or all?
|
||||
if any(data.empty(exec_id) for data in self.data_in.values()):
|
||||
return
|
||||
d: dict[str, str] = dict()
|
||||
for gate in self.in_data_ports:
|
||||
for key, value in self.data_in[gate].get_data(exec_id)[0].items():
|
||||
d[key] = value
|
||||
out.append(exec_id, d)
|
||||
DataNode.input_event(self, "out", exec_id)
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"merge",
|
||||
"ports_data": (
|
||||
self.get_data_input_gates()[::-1],
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
49
transformation/schedule/schedule_lib/modify.py
Normal file
49
transformation/schedule/schedule_lib/modify.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
from typing import List, override
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from transformation.schedule.schedule_lib.funcs import not_visited, generate_dot_node
|
||||
from .data_node import DataNode
|
||||
|
||||
|
||||
class Modify(DataNode):
|
||||
def __init__(self, rename: dict[str, str], delete: dict[str, str]) -> None:
|
||||
super().__init__()
|
||||
self.rename: dict[str, str] = rename
|
||||
self.delete: set[str] = set(delete)
|
||||
|
||||
@override
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
data_i = self.get_input_data(gate, exec_id)
|
||||
if len(data_i):
|
||||
self.data_out["out"].clear(exec_id)
|
||||
for data in data_i:
|
||||
self.data_out["out"].append(exec_id,
|
||||
{
|
||||
self.rename.get(key, key): value
|
||||
for key, value in data.items()
|
||||
if key not in self.delete
|
||||
}
|
||||
)
|
||||
else:
|
||||
if self.data_out["out"].empty(exec_id):
|
||||
return
|
||||
super().input_event("out", exec_id)
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"modify",
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
70
transformation/schedule/schedule_lib/node.py
Normal file
70
transformation/schedule/schedule_lib/node.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"""
|
||||
node.py
|
||||
|
||||
Defines the abstract base Node class for graph-based structures. Each Node is assigned
|
||||
a unique identifier via an external IdGenerator. The class provides an interface for
|
||||
managing execution state and generating DOT graph representations.
|
||||
"""
|
||||
|
||||
from abc import abstractmethod
|
||||
from jinja2 import Template
|
||||
from .funcs import IdGenerator
|
||||
|
||||
|
||||
class Node:
|
||||
"""
|
||||
Abstract base class for graph nodes. Each Node has a unique ID and supports
|
||||
context-dependent state management for execution scenarios. Subclasses must
|
||||
implement the DOT graph generation logic.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
Initializes the Node instance with a unique ID.
|
||||
|
||||
Attributes:
|
||||
id (int): A unique identifier assigned by IdGenerator.
|
||||
"""
|
||||
self.id: int = IdGenerator.generate_node_id()
|
||||
|
||||
def get_id(self) -> int:
|
||||
"""
|
||||
Retrieves the unique identifier of the node.
|
||||
|
||||
Returns:
|
||||
int: The unique node ID.
|
||||
"""
|
||||
return self.id
|
||||
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
"""
|
||||
Initializes a new state frame for a specific execution context.
|
||||
Designed to be overridden in subclasses that use execution state.
|
||||
|
||||
Args:
|
||||
exec_id (int): The ID of the execution context.
|
||||
"""
|
||||
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
"""
|
||||
Deletes the state frame for a specific execution context.
|
||||
Designed to be overridden in subclasses that use execution state.
|
||||
|
||||
Args:
|
||||
exec_id (int): The ID of the execution context.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def generate_dot(
|
||||
self, nodes: list[str], edges: list[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
"""
|
||||
Generates the DOT graph representation for this node and its relationships.
|
||||
|
||||
Args:
|
||||
nodes (list[str]): A list to append DOT node definitions to.
|
||||
edges (list[str]): A list to append DOT edge definitions to.
|
||||
visited (set[int]): A set of already visited node IDs to avoid duplicates or recursion.
|
||||
template (Template): A Jinja2 template used to format the node's DOT representation.
|
||||
"""
|
||||
80
transformation/schedule/schedule_lib/null_node.py
Normal file
80
transformation/schedule/schedule_lib/null_node.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
"""
|
||||
null_node.py
|
||||
|
||||
Defines the NullNode class, a no-op singleton execution node used for open execution pins
|
||||
in the object diagram execution graph.
|
||||
"""
|
||||
|
||||
from abc import ABC
|
||||
from typing import List, Type
|
||||
from jinja2 import Template
|
||||
from api.od import ODAPI
|
||||
from .funcs import generate_dot_node
|
||||
from .singleton import Singleton
|
||||
from .exec_node import ExecNode
|
||||
|
||||
class NullNode(ExecNode, metaclass=Singleton):
|
||||
"""
|
||||
A no-op execution node representing a null operation.
|
||||
|
||||
This node is typically used to represent a placeholder or open execution pin.
|
||||
It always returns a fixed result and does not perform any operation.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initializes the NullNode instance.
|
||||
Inherits unique ID and state behavior from ExecNode.
|
||||
"""
|
||||
super().__init__()
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
"""
|
||||
Simulates execution by returning a static result indicating an open pin.
|
||||
|
||||
Args:
|
||||
port (str): The name of the input port.
|
||||
exec_id (int): The current execution ID.
|
||||
od (ODAPI): The Object Diagram API instance providing execution context.
|
||||
|
||||
Returns:
|
||||
tuple[int, str] | None: A tuple (-1, "open pin reached") indicating a no-op.
|
||||
"""
|
||||
return -1, "open pin reached"
|
||||
|
||||
@staticmethod
|
||||
def get_exec_output_gates():
|
||||
"""
|
||||
Returns the list of output gates for execution.
|
||||
|
||||
Returns:
|
||||
list: An empty list, as NullNode has no output gates.
|
||||
"""
|
||||
return []
|
||||
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
"""
|
||||
Generates DOT graph representation for this node if it hasn't been visited.
|
||||
|
||||
Args:
|
||||
nodes (List[str]): A list to accumulate DOT node definitions.
|
||||
edges (List[str]): A list to accumulate DOT edge definitions.
|
||||
visited (set[int]): Set of already visited node IDs to avoid cycles.
|
||||
template (Template): A Jinja2 template used to render the node's DOT representation.
|
||||
"""
|
||||
if self.id in visited:
|
||||
return
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": "null",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
}
|
||||
)
|
||||
60
transformation/schedule/schedule_lib/print.py
Normal file
60
transformation/schedule/schedule_lib/print.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
from typing import List, override
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from transformation.schedule.schedule_lib.funcs import not_visited, generate_dot_node
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode
|
||||
|
||||
|
||||
class Print(ExecNode, DataNode):
|
||||
def __init__(self, label: str = "", custom: str = "") -> None:
|
||||
super().__init__()
|
||||
self.label = label
|
||||
|
||||
if custom:
|
||||
template = Template(custom, trim_blocks=True, lstrip_blocks=True)
|
||||
self._print = (
|
||||
lambda self_, exec_id: print(template.render(data=self.get_input_data("in", exec_id)))
|
||||
).__get__(self, Print)
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_data_output_gates():
|
||||
return []
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
self._print(exec_id)
|
||||
return
|
||||
|
||||
@override
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
if not self.data_in[gate].empty(exec_id):
|
||||
self._print(exec_id)
|
||||
|
||||
def _print(self, exec_id: int) -> None:
|
||||
print(f"{self.label}{self.get_input_data("in", exec_id)}")
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"print",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
ExecNode.generate_dot(self, nodes, edges, visited, template)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
56
transformation/schedule/schedule_lib/rewrite.py
Normal file
56
transformation/schedule/schedule_lib/rewrite.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import functools
|
||||
from typing import List, Type
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
from ..rule_executor import RuleExecutor
|
||||
|
||||
class Rewrite(ExecNode, DataNode):
|
||||
|
||||
def __init__(self, label: str) -> None:
|
||||
super().__init__()
|
||||
self.label = label
|
||||
self.rule = None
|
||||
self.rule_executor: RuleExecutor | None = None
|
||||
|
||||
def init_rule(self, rule, rule_executer):
|
||||
self.rule = rule
|
||||
self.rule_executor = rule_executer
|
||||
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
pivot = {}
|
||||
if self.data_in is not None:
|
||||
pivot = self.get_input_data("in", exec_id)[0]
|
||||
# TODO: remove print
|
||||
print(f"rewrite: {self.label}\n\tpivot: {pivot}")
|
||||
self.store_data( exec_id,
|
||||
self.rule_executor.rewrite_rule(od, self.rule, pivot=pivot), "out", 1
|
||||
)
|
||||
return None
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": "rewrite",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
ExecNode.generate_dot(self, nodes, edges, visited, template)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
9
transformation/schedule/schedule_lib/singleton.py
Normal file
9
transformation/schedule/schedule_lib/singleton.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
from abc import ABCMeta
|
||||
|
||||
class Singleton(ABCMeta):
|
||||
_instances = {}
|
||||
|
||||
def __call__(cls, *args, **kwargs):
|
||||
if cls not in cls._instances:
|
||||
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instances[cls]
|
||||
83
transformation/schedule/schedule_lib/start.py
Normal file
83
transformation/schedule/schedule_lib/start.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
from typing import List, override
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from . import DataNode
|
||||
from .exec_node import ExecNode
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
|
||||
class StartState:
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.start_gate: str = ""
|
||||
|
||||
class Start(ExecNode, DataNode):
|
||||
def __init__(self, ports_exec: List[str], ports_data: List[str]) -> None:
|
||||
self.state: dict[int, StartState] = {}
|
||||
self.ports_exec = ports_exec
|
||||
self.ports_data = ports_data
|
||||
super().__init__()
|
||||
|
||||
def run_init(self, gate: str, exec_id: int, data: dict[str, any]) -> None:
|
||||
state = self.get_state(exec_id)
|
||||
state.start_gate = gate
|
||||
for port, d in data.items():
|
||||
self.data_out[port].replace(exec_id, d)
|
||||
DataNode.input_event(self, port, exec_id)
|
||||
|
||||
def nextState(self, exec_id: int) -> tuple["ExecNode", str]:
|
||||
state = self.get_state(exec_id)
|
||||
return self.next_node[state.start_gate]
|
||||
|
||||
def get_state(self, exec_id) -> StartState:
|
||||
return self.state[exec_id]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state[exec_id] = StartState()
|
||||
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state.pop(exec_id)
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_exec_input_gates():
|
||||
return []
|
||||
|
||||
@override
|
||||
def get_exec_output_gates(self):
|
||||
return self.ports_exec
|
||||
|
||||
@staticmethod
|
||||
@override
|
||||
def get_data_input_gates():
|
||||
return []
|
||||
|
||||
@override
|
||||
def get_data_output_gates(self):
|
||||
return self.ports_data
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": "start",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
}
|
||||
)
|
||||
super().generate_dot(nodes, edges, visited, template)
|
||||
92
transformation/schedule/schedule_lib/store.py
Normal file
92
transformation/schedule/schedule_lib/store.py
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
from typing import List, override
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from .data import Data
|
||||
from .exec_node import ExecNode
|
||||
from .data_node import DataNode
|
||||
from .funcs import not_visited, generate_dot_node
|
||||
|
||||
class StoreState:
|
||||
def __init__(self) -> None:
|
||||
self.last_port: str = "in"
|
||||
|
||||
class Store(ExecNode, DataNode):
|
||||
def __init__(self, ports: list[str]) -> None:
|
||||
self.ports = ports
|
||||
super().__init__()
|
||||
self.state: dict[int, StoreState] = {}
|
||||
self.cur_data: Data = Data(self)
|
||||
|
||||
@override
|
||||
def get_exec_input_gates(self) -> list[str]:
|
||||
return [*self.ports, "in"]
|
||||
|
||||
@override
|
||||
def get_exec_output_gates(self) -> list[str]:
|
||||
return [*self.ports, "out"]
|
||||
|
||||
@override
|
||||
def get_data_input_gates(self) -> list[str]:
|
||||
return self.ports
|
||||
|
||||
@override
|
||||
def nextState(self, exec_id: int) -> tuple[ExecNode, str]:
|
||||
return self.next_node[self.get_state(exec_id).last_port]
|
||||
|
||||
@override
|
||||
def input_event(self, gate: str, exec_id: int) -> None:
|
||||
return
|
||||
|
||||
def get_state(self, exec_id) -> StoreState:
|
||||
return self.state[exec_id]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state[exec_id] = StoreState()
|
||||
self.cur_data.generate_stack_frame(exec_id)
|
||||
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state.pop(exec_id)
|
||||
self.cur_data.delete_stack_frame(exec_id)
|
||||
|
||||
|
||||
@override
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
state = self.get_state(exec_id)
|
||||
if port == "in":
|
||||
self.data_out["out"].replace(exec_id, self.cur_data.get_data(exec_id))
|
||||
self.cur_data.clear(exec_id)
|
||||
DataNode.input_event(self, "out", True)
|
||||
state.last_port = "out"
|
||||
return None
|
||||
self.cur_data.extend(exec_id, self.get_input_data(port, exec_id))
|
||||
state.last_port = port
|
||||
return None
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": f"store",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
},
|
||||
)
|
||||
ExecNode.generate_dot(self, nodes, edges, visited, template)
|
||||
DataNode.generate_dot(self, nodes, edges, visited, template)
|
||||
107
transformation/schedule/schedule_lib/sub_schedule.py
Normal file
107
transformation/schedule/schedule_lib/sub_schedule.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
from typing import List, override, TYPE_CHECKING
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from api.od import ODAPI
|
||||
from . import DataNode
|
||||
from .exec_node import ExecNode
|
||||
from .funcs import not_visited, generate_dot_node, IdGenerator
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..rule_scheduler import RuleSchedular
|
||||
|
||||
|
||||
class ScheduleState:
|
||||
def __init__(self) -> None:
|
||||
self.end_gate: str = ""
|
||||
|
||||
class SubSchedule(ExecNode, DataNode):
|
||||
def __init__(self, schedular: "RuleSchedular", file: str) -> None:
|
||||
self.schedule = schedular._load_schedule(file, _main=False)
|
||||
self.schedular = schedular
|
||||
super().__init__()
|
||||
self.state: dict[int, ScheduleState] = {}
|
||||
|
||||
@override
|
||||
def nextState(self, exec_id: int) -> tuple["ExecNode", str]:
|
||||
return self.next_node[self.get_state(exec_id).end_gate]
|
||||
|
||||
@override
|
||||
def get_exec_input_gates(self) -> "List[ExecNode]":
|
||||
return self.schedule.start.get_exec_output_gates()
|
||||
|
||||
@override
|
||||
def get_exec_output_gates(self) -> "List[ExecNode]":
|
||||
return [*self.schedule.end.get_exec_input_gates()]
|
||||
|
||||
@override
|
||||
def get_data_input_gates(self) -> "List[ExecNode]":
|
||||
return self.schedule.start.get_data_output_gates()
|
||||
|
||||
@override
|
||||
def get_data_output_gates(self) -> "List[ExecNode]":
|
||||
return self.schedule.end.get_data_input_gates()
|
||||
|
||||
def get_state(self, exec_id) -> ScheduleState:
|
||||
return self.state[exec_id]
|
||||
|
||||
@override
|
||||
def generate_stack_frame(self, exec_id: int) -> None:
|
||||
super().generate_stack_frame(exec_id)
|
||||
self.state[exec_id] = ScheduleState()
|
||||
|
||||
@override
|
||||
def delete_stack_frame(self, exec_id: int) -> None:
|
||||
super().delete_stack_frame(exec_id)
|
||||
self.state.pop(exec_id)
|
||||
|
||||
|
||||
@override
|
||||
def execute(self, port: str, exec_id: int, od: ODAPI) -> tuple[int, any] | None:
|
||||
runstatus, result = self.schedular._runner(
|
||||
od,
|
||||
self.schedule,
|
||||
port,
|
||||
IdGenerator.generate_exec_id(),
|
||||
{
|
||||
port: self.get_input_data(port, exec_id)
|
||||
for port, value in self.data_in.items()
|
||||
if value is not None and not value.empty(exec_id)
|
||||
},
|
||||
)
|
||||
if runstatus != 1:
|
||||
return runstatus, result
|
||||
self.get_state(exec_id).end_gate = result["exec_gate"]
|
||||
results_data = result["data_out"]
|
||||
for port, data in self.data_out.items():
|
||||
if port in results_data:
|
||||
self.data_out[port].replace(exec_id, results_data[port])
|
||||
DataNode.input_event(self, port, exec_id)
|
||||
continue
|
||||
|
||||
if not data.empty(exec_id):
|
||||
data.clear(exec_id)
|
||||
DataNode.input_event(self, port, exec_id)
|
||||
return None
|
||||
|
||||
@not_visited
|
||||
def generate_dot(
|
||||
self, nodes: List[str], edges: List[str], visited: set[int], template: Template
|
||||
) -> None:
|
||||
generate_dot_node(
|
||||
self,
|
||||
nodes,
|
||||
template,
|
||||
**{
|
||||
"label": "rrrrrrrrrr",
|
||||
"ports_exec": (
|
||||
self.get_exec_input_gates(),
|
||||
self.get_exec_output_gates(),
|
||||
),
|
||||
"ports_data": (
|
||||
self.get_data_input_gates(),
|
||||
self.get_data_output_gates(),
|
||||
),
|
||||
}
|
||||
)
|
||||
super().generate_dot(nodes, edges, visited, template)
|
||||
Loading…
Add table
Add a link
Reference in a new issue