Skip to content

Commit

Permalink
- initial commit for GraphvizDump template
Browse files Browse the repository at this point in the history
- new debug-flag: +d=graphvizDump
  - this activates additional graphical output (as *.dot files) for backend dumps (currently only +d=dumpinitialsystem is supported)
  - this is currently only useable with small/simple models

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@18386 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
lochel committed Dec 3, 2013
1 parent 9245adb commit ec2632d
Show file tree
Hide file tree
Showing 9 changed files with 663 additions and 5 deletions.
42 changes: 41 additions & 1 deletion Compiler/BackEnd/BackendDump.mo
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ encapsulated package BackendDump
public import BackendDAE;
public import DAE;
public import HashSet;
public import Tpl;

protected import Absyn;
protected import BackendDAETransform;
Expand All @@ -66,6 +67,7 @@ protected import DumpHTML;
protected import Expression;
protected import ExpressionDump;
protected import Flags;
protected import GraphvizDump;
protected import IOStream;
protected import List;
protected import SCode;
Expand Down Expand Up @@ -432,6 +434,43 @@ algorithm
end matchcontinue;
end printSparsityPattern;

// =============================================================================
// section for all graphviz* functions
//
// =============================================================================

public function graphvizBackendDAE
input BackendDAE.BackendDAE inBackendDAE;
input String inFileNameSuffix;
protected
BackendDAE.BackendDAE dae;
BackendDAE.EqSystems eqSystems;
String fileNamePrefix;
String buffer;
algorithm
dae := setIncidenceMatrix(inBackendDAE);
Tpl.tplNoret2(GraphvizDump.dumpBackendDAE, dae, inFileNameSuffix);
end graphvizBackendDAE;

protected function setIncidenceMatrix
input BackendDAE.BackendDAE inBackendDAE;
output BackendDAE.BackendDAE outBackendDAE;
protected
BackendDAE.EqSystems eqSystems;
BackendDAE.Shared shared;
algorithm
BackendDAE.DAE(eqSystems, shared) := inBackendDAE;
eqSystems := List.map(eqSystems, setIncidenceMatrix1);
outBackendDAE := BackendDAE.DAE(eqSystems, shared);
end setIncidenceMatrix;

protected function setIncidenceMatrix1
input BackendDAE.EqSystem inEqSystem;
output BackendDAE.EqSystem outEqSystem;
algorithm
(outEqSystem, _, _) := BackendDAEUtil.getIncidenceMatrix(inEqSystem, BackendDAE.NORMAL(), NONE());
end setIncidenceMatrix1;

// =============================================================================
// section for all dump* functions
//
Expand Down Expand Up @@ -3201,6 +3240,7 @@ algorithm
_:=
matchcontinue (inTpl)
local
BackendDAE.BackendDAE dae;
BackendDAE.EqSystems eqs;
BackendDAE.Shared shared;
String str,strlow,headerline;
Expand All @@ -3221,7 +3261,7 @@ algorithm
then
();

case ((headerline,BackendDAE.DAE(eqs,shared)))
case ((headerline,dae as BackendDAE.DAE(eqs,shared)))
equation
print(headerline); print(":\n");
List.map_0(eqs,printEqSystem);
Expand Down
1 change: 1 addition & 0 deletions Compiler/BackEnd/Initialization.mo
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ algorithm
// simplify system
(initdae, Util.SUCCESS()) = BackendDAEUtil.postOptimizeDAE(initdae, pastOptModules, matchingAlgorithm, daeHandler);
Debug.fcall2(Flags.DUMP_INITIAL_SYSTEM, BackendDump.dumpBackendDAE, initdae, "solved initial system");
Debug.bcall2(Flags.isSet(Flags.DUMP_INITIAL_SYSTEM) and Flags.isSet(Flags.ADDITIONAL_GRAPHVIZ_DUMP), BackendDump.graphvizBackendDAE, initdae, "initialization");

// warn about selected default initial conditions
b = List.isNotEmpty(dumpVars);
Expand Down
1 change: 1 addition & 0 deletions Compiler/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ CodegenUtil.mo \
CodegenXML.mo \
DAEDumpTpl.mo \
ExpressionDumpTpl.mo \
GraphvizDump.mo \
NFInstDumpTpl.mo \
SCodeDumpTpl.mo \
SimCodeDump.mo \
Expand Down
7 changes: 7 additions & 0 deletions Compiler/Template/CodegenC.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ package CodegenC
import interface SimCodeTV;
import CodegenUtil.*;

template test(array<Integer> i, Boolean b) ::=
match b
case true then "true"
else "false"
end match
end test;

template escapeCComments(String stringWithCComments)
"escape the C comments inside a string, replaces them with /* */->(* *)"
::= '<%System.stringReplace(System.stringReplace(stringWithCComments, "/*", "(*"), "*/", "*)")%>'
Expand Down
208 changes: 208 additions & 0 deletions Compiler/Template/GraphvizDump.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package GraphvizDump

import interface GraphvizDumpTV;
import CodegenUtil.*;

template test(array<Integer> i, Boolean b) ::=
match b
case true then "true"
else "false"
end match
end test;

template dumpBackendDAE(BackendDAE.BackendDAE backendDAE, String suffix)
::=
match backendDAE
case dae as BackendDAE.DAE(eqs=eqs, shared=BackendDAE.SHARED(info=info as BackendDAE.EXTRA_INFO(__))) then
let _ = textFile(dumpDependence(dae, suffix), '<%info.fileNamePrefix%>_<%suffix%>_dependence.dot')
let _ = textFile(dumpMatching(dae, suffix), '<%info.fileNamePrefix%>_<%suffix%>_matching.dot')
//let _ = textFile(dumpSorting(dae, suffix), '<%info.fileNamePrefix%>_<%suffix%>_sorting.dot')

//this top-level template always returns an empty result
//since generated texts are written to files directly
''
end match
end dumpBackendDAE;

template dumpDependence(BackendDAE.BackendDAE backendDAE, String suffix)
::=
match backendDAE
case dae as BackendDAE.DAE(eqs=eqs, shared=BackendDAE.SHARED(info=info as BackendDAE.EXTRA_INFO(__))) then
let systems = (eqs |> eqSystem as BackendDAE.EQSYSTEM(__) hasindex clusterID fromindex 1 =>
let varDeclaration = (BackendVariable.varList(eqSystem.orderedVars) |> var as BackendDAE.VAR(__) hasindex varID fromindex 1 =>
'var<%clusterID%>_<%varID%> [label="<%crefStr(var.varName)%>"]'
;separator="\n")
let eqDeclaration = (BackendEquation.equationList(eqSystem.orderedEqs) |> eq hasindex eqID fromindex 1 =>
'eq<%clusterID%>_<%eqID%> [label="<%BackendDump.equationString(eq)%>", shape="box"]'
;separator="\n")
<<
subgraph cluster_<%clusterID%> {
label = "system #<%clusterID%>";
color=white
<%varDeclaration%>
<%eqDeclaration%>
<%dumpDependence2(clusterID, eqSystem.m)%>
}
>>
;separator="\n\n")

<<
digraph G {
label="<%info.fileNamePrefix%> [<%suffix%> - dependence]";
rankdir=LR;
<%systems%>
}
>>
end dumpDependence;

template dumpDependence2(Integer clusterID, Option<BackendDAE.IncidenceMatrix> m)
::=
match m
case SOME(incMatrix) then
let incNodes = (arrayList(incMatrix) |> varList hasindex eqID fromindex 1 =>
let foo = (varList |> varID =>
'var<%clusterID%>_<%varID%> -> eq<%clusterID%>_<%eqID%> [style="dashed", arrowhead="none"];'
;separator="\n")
'<%foo%>'
;separator="\n")
'<%incNodes%>'
else
'// no incidence matrix'
end dumpDependence2;

template dumpMatching(BackendDAE.BackendDAE backendDAE, String suffix)
::=
match backendDAE
case dae as BackendDAE.DAE(eqs=eqs, shared=BackendDAE.SHARED(info=info as BackendDAE.EXTRA_INFO(__))) then
let systems = (eqs |> eqSystem as BackendDAE.EQSYSTEM(__) hasindex clusterID fromindex 1 =>
let varDeclaration = (BackendVariable.varList(eqSystem.orderedVars) |> var as BackendDAE.VAR(__) hasindex varID fromindex 1 =>
'var<%clusterID%>_<%varID%> [label="<%crefStr(var.varName)%>"]'
;separator="\n")
let eqDeclaration = (BackendEquation.equationList(eqSystem.orderedEqs) |> eq hasindex eqID fromindex 1 =>
<<
eq<%clusterID%>_<%eqID%> [label="<%BackendDump.equationString(eq)%>", shape="box"]
>>
;separator="\n")
<<
subgraph cluster_<%clusterID%> {
label = "system #<%clusterID%>";
color=white
<%varDeclaration%>
<%eqDeclaration%>
<%connections(clusterID, eqSystem.matching, eqSystem.m)%>
}
>>
;separator="\n\n")

<<
digraph G {
label="<%info.fileNamePrefix%> [<%suffix%> - matching]";
rankdir=LR;
<%systems%>
}
>>
end dumpMatching;

template connections(Integer clusterID, BackendDAE.Matching matching, Option<BackendDAE.IncidenceMatrix> m)
::=
match m
case SOME(incMatrix) then
match matching
case matching as BackendDAE.MATCHING(ass2=ass2) then
let incNodes = (arrayList(incMatrix) |> varList hasindex eqID fromindex 1 =>
let foo = (varList |> varID =>
if intEq(listGet(arrayList(ass2), eqID), varID) then
'var<%clusterID%>_<%varID%> -> eq<%clusterID%>_<%eqID%> [style="bold", arrowhead="none"];'
else
'var<%clusterID%>_<%varID%> -> eq<%clusterID%>_<%eqID%> [style="dashed", arrowhead="none"];'
;separator="\n")
'<%foo%>'
;separator="\n")
'<%incNodes%>'
else
let incNodes = (arrayList(incMatrix) |> varList hasindex eqID fromindex 1 =>
let foo = (varList |> varID =>
'var<%clusterID%>_<%varID%> -> eq<%clusterID%>_<%eqID%> [style="dashed", arrowhead="none"];'
;separator="\n")
'<%foo%>'
;separator="\n")
<<
// no matching
<%incNodes%>
>>
else
match matching
case matching as BackendDAE.MATCHING(ass2=ass2) then
let matchedNodes = (arrayList(ass2) |> varID hasindex eqID fromindex 1 =>
'var<%clusterID%>_<%varID%> -> eq<%clusterID%>_<%eqID%> [style="bold", arrowhead="none"];'
;separator="\n")
<<
// no incidence matrix
<%matchedNodes%>
>>
else
<<
// no incidence matrix
// no matching
>>
end connections;

template dumpSorting(BackendDAE.BackendDAE backendDAE, String suffix)
::=
match backendDAE
case dae as BackendDAE.DAE(eqs=eqs, shared=BackendDAE.SHARED(info=info as BackendDAE.EXTRA_INFO(__))) then
let systems = (eqs |> eqSystem as BackendDAE.EQSYSTEM(__) hasindex clusterID fromindex 1 =>
let varDeclaration = (BackendVariable.varList(eqSystem.orderedVars) |> var as BackendDAE.VAR(__) hasindex varID fromindex 1 =>
'var<%clusterID%>_<%varID%> [label="<%crefStr(var.varName)%>"]'
;separator="\n")
let eqDeclaration = (BackendEquation.equationList(eqSystem.orderedEqs) |> eq hasindex eqID fromindex 1 =>
'eq<%clusterID%>_<%eqID%> [label="<%BackendDump.equationString(eq)%>", shape="box"]'
;separator="\n")
<<
subgraph cluster_<%clusterID%> {
label = "system #<%clusterID%>";
color=white
<%varDeclaration%>
<%dumpStrongComponent(clusterID, eqSystem.matching)%>
}
>>
;separator="\n\n")

<<
digraph G {
label="<%info.fileNamePrefix%> [<%suffix%> - sorting]";
rankdir=LR;
<%systems%>
}
>>
end dumpSorting;

template dumpStrongComponent(Integer clusterID, BackendDAE.Matching matching)
::=
match matching
case matching as BackendDAE.MATCHING(comps=comps) then
let cmpNodes = (comps |> comp hasindex eqID fromindex 1 =>
match comp
case c as SINGLEEQUATION(__) then
'var<%clusterID%>_<%c.var%>'
case c as EQUATIONSYSTEM(__) then
let foo = (c.vars |> v => 'var<%clusterID%>_<%v%>' ;separator=" <-> ")
'<%foo%>'
else
'asd'
;separator=" -> ")
'<%cmpNodes%>'
end dumpStrongComponent;

end GraphvizDump;

0 comments on commit ec2632d

Please sign in to comment.