implementation: continued pre-processing section; added cache to ExpressionProcessing.jl to improve performance
Some checks are pending
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.10) (push) Waiting to run
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.6) (push) Waiting to run
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, pre) (push) Waiting to run
Some checks are pending
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.10) (push) Waiting to run
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, 1.6) (push) Waiting to run
CI / Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} (x64, ubuntu-latest, pre) (push) Waiting to run
This commit is contained in:
parent
b40a06af3f
commit
ad2eab2e0a
|
@ -1,47 +1,56 @@
|
|||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0" version="26.2.9">
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0" version="26.2.14">
|
||||
<diagram name="Page-1" id="6PRo98IcIigsbWnrE1av">
|
||||
<mxGraphModel dx="2595" dy="1618" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<mxGraphModel dx="984" dy="2200" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontFamily=Lucida Console;" edge="1" parent="1" source="Z0Q_i6cja5BoQgUPI0nb-21" target="Z0Q_i6cja5BoQgUPI0nb-26">
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-2" value="<font style="font-size: 15px;">log</font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;" vertex="1" parent="1">
|
||||
<mxGeometry x="140" y="-960" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="3yAczgE19xE4neCjO-Sk-4" target="3yAczgE19xE4neCjO-Sk-10">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-21" value="<font style="font-size: 15px;">log</font>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;" vertex="1" parent="1">
|
||||
<mxGeometry x="-556" y="-550" width="100" height="40" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-4" value="<font face="Lucida Console">1 + x<sub>1</sub> * log(p<sub>1</sub>)</font>" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="130" y="-1200" width="140" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Z0Q_i6cja5BoQgUPI0nb-22" target="Z0Q_i6cja5BoQgUPI0nb-28">
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-5" value="1" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="-1120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-6" value="x<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="-1040" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-7" value="p<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="-960" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-10" value="<font face="Lucida Console">+</font>" style="rounded=0;whiteSpace=wrap;html=1;fontSize=20;" vertex="1" parent="1">
|
||||
<mxGeometry x="140" y="-1120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-13" value="<font face="Lucida Console">*</font>" style="rounded=0;whiteSpace=wrap;html=1;fontSize=20;" vertex="1" parent="1">
|
||||
<mxGeometry x="140" y="-1040" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="3yAczgE19xE4neCjO-Sk-14" target="3yAczgE19xE4neCjO-Sk-13">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-22" value="<font face="Lucida Console">1 + x<sub>1</sub> * log(p<sub>1</sub>)</font>" style="rounded=0;whiteSpace=wrap;html=1;fontSize=12;" vertex="1" parent="1">
|
||||
<mxGeometry x="-730" y="-760" width="140" height="40" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-14" value="" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="-1120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-23" value="1" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="-800" y="-620" width="100" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-25" value="x<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="-700" y="-550" width="100" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-26" value="p<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="-556" y="-480" width="100" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Z0Q_i6cja5BoQgUPI0nb-28" target="Z0Q_i6cja5BoQgUPI0nb-23">
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="3yAczgE19xE4neCjO-Sk-15" target="3yAczgE19xE4neCjO-Sk-2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Z0Q_i6cja5BoQgUPI0nb-28" target="Z0Q_i6cja5BoQgUPI0nb-36">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-15" value="" style="rounded=0;whiteSpace=wrap;html=1;fontFamily=Lucida Console;fontSize=15;" vertex="1" parent="1">
|
||||
<mxGeometry x="220" y="-1040" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-28" value="<font face="Lucida Console">+</font>" style="rounded=0;whiteSpace=wrap;html=1;fontSize=20;" vertex="1" parent="1">
|
||||
<mxGeometry x="-710" y="-690" width="100" height="40" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-21" value="Expression:" style="text;html=1;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="60" y="-1195" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Z0Q_i6cja5BoQgUPI0nb-36" target="Z0Q_i6cja5BoQgUPI0nb-25">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-22" value="Node 1:" style="text;html=1;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="60" y="-1115" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Z0Q_i6cja5BoQgUPI0nb-36" target="Z0Q_i6cja5BoQgUPI0nb-21">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-23" value="Node 2:" style="text;html=1;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="60" y="-1035" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="Z0Q_i6cja5BoQgUPI0nb-36" value="<font face="Lucida Console">*</font>" style="rounded=0;whiteSpace=wrap;html=1;fontSize=20;" vertex="1" parent="1">
|
||||
<mxGeometry x="-626" y="-620" width="100" height="40" as="geometry" />
|
||||
<mxCell id="3yAczgE19xE4neCjO-Sk-24" value="Node 3:" style="text;html=1;align=right;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="60" y="-955" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0" version="26.2.5">
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0" version="26.2.13">
|
||||
<diagram name="Page-1" id="93wPJxm0qDUx-9UJ1EZK">
|
||||
<mxGraphModel dx="1182" dy="655" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<mxGraphModel dx="985" dy="546" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-1" value="X<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-1" value="X<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="265" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-2" value="2" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-2" value="2.5" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="355" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-3" value="+" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-3" value="+" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="445" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-5" value="<div>Type: Variable</div><div>Value: 1</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-5" value="<div>Type: Variable</div><div>Value: 1</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="280" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-6" value="<div>Type: Constant</div><div>Value: 2</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-6" value="<div>Type: Constant</div><div>Value: 2.5</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
|
||||
<mxGeometry x="330" y="280" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-9" value="<div>Type: Operator</div><div>Value: Addition</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-9" value="<div>Type: Operator</div><div>Value: Addition</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
|
||||
<mxGeometry x="420" y="280" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-10" value="X<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-10" value="X<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="80" y="280" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="399UxkHvPDb8lwnND9dC-11" target="399UxkHvPDb8lwnND9dC-5">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="399UxkHvPDb8lwnND9dC-11" target="399UxkHvPDb8lwnND9dC-5" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-11" value="2" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-11" value="2.5" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="160" y="280" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-12" value="+" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxCell id="399UxkHvPDb8lwnND9dC-12" value="+" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
|
||||
<mxGeometry x="120" y="280" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
|
|
40
other/pre-processing_result_impl.drawio
Normal file
40
other/pre-processing_result_impl.drawio
Normal file
|
@ -0,0 +1,40 @@
|
|||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0" version="26.2.14">
|
||||
<diagram name="Page-1" id="RS3gGc-6zrWzfM8RHVPg">
|
||||
<mxGraphModel dx="984" dy="546" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-1" value="X<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="265" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-2" value="2.5" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="365" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-3" value="+" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="465" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-4" value="<div>Type: Variable</div><div>Value: 1</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="280" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-5" value="<div>Type: Constant</div><div>Value: 1075838976</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
||||
<mxGeometry x="330" y="280" width="110" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-6" value="<div>Type: Operator</div><div>Value: 1</div>" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
|
||||
<mxGeometry x="440" y="280" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-7" value="X<sub>1</sub>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="80" y="280" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="rjAdOlqX2aqhqL3wS-0c-9" target="rjAdOlqX2aqhqL3wS-0c-4">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-9" value="2.5" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="280" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rjAdOlqX2aqhqL3wS-0c-10" value="+" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="280" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
|
@ -17,12 +17,16 @@ struct ExpressionElement
|
|||
end
|
||||
|
||||
const PostfixType = Vector{ExpressionElement}
|
||||
|
||||
const cache = Dict{Expr, PostfixType}()
|
||||
"
|
||||
Converts a julia expression to its postfix notation.
|
||||
NOTE: All 64-Bit values will be converted to 32-Bit. Be aware of the lost precision
|
||||
"
|
||||
function expr_to_postfix(expr::Expr)::PostfixType
|
||||
if haskey(cache, expr)
|
||||
return cache[expr]
|
||||
end
|
||||
|
||||
postfix = PostfixType()
|
||||
@inbounds operator = get_operator(expr.args[1])
|
||||
|
||||
|
@ -40,7 +44,8 @@ function expr_to_postfix(expr::Expr)::PostfixType
|
|||
push!(postfix, exprElement)
|
||||
end
|
||||
|
||||
# only add operator if at least 2 values are added. For the case where another expression is added first, we check if we are at the first iteration or not ( j != 2)
|
||||
# only add operator if at least 2 values are added. Needed because e.g. multiple consecutive additions are one subtree with one operator, but multiple operators need to be added to the postfix notation.
|
||||
# For the case where another expression has already been added, we check if we are at the first iteration or not ( j != 2)
|
||||
if length(postfix) >= 2 && j != 2
|
||||
exprElement = convert_to_ExpressionElement(operator)
|
||||
push!(postfix, exprElement)
|
||||
|
|
|
@ -30,12 +30,12 @@ Again, the question arises if the performance of CUDA.jl is sufficient to be use
|
|||
The pre-processing or frontend step is very important. As already explained in Chapter \ref{cha:conceptdesign} it is responsible for ensuring the given expressions are valid and that they are transformed into an intermediate representation. This section aims at explaining how the intermediate representation is implemented, as well as how it is generated from a mathematical expression.
|
||||
|
||||
\subsection{Intermediate Representation}
|
||||
\label{sec:ir}
|
||||
% Talk about how it looks and why it was chosen to look like this
|
||||
The intermediate representation is mainly designed to be lightweight and easily transferrable to the GPU. Since the interpreter is running on the GPU this was a very important consideration. Since the transpilation process is performed on the CPU and is therefore very flexible in terms of the intermediate representation, the focus lied mostly on being efficient for the interpreter.
|
||||
|
||||
The intermediate representation can not take on any form. While it has already been defined that expressions are converted to postfix notation, there are different ways of storing the data. The first logical decision is to create an array where each entry represents a token. On the CPU it would be possible to define each entry to be a pointer to the token object. Each of these objects could be of a different type, for example an object holding a constant value while another object holds an operator. Additionally, each of these objects could include its own logic on what to do when it is encountered during the evaluation process. However, on the GPU, this is not possible, as an array entry must hold a value and not a pointer to another memory location. Furthermore, if this would be possible, it would be a bad idea. As explained in Section \ref{sec:memory_model}, when loading data from memory, larger chunks are retrieved at once. If the data is scattered around the GPUs memory, a lot of unwanted data is transferred. This can be seen in figure \ref{fig:excessive-memory-transfer}, where if the data is stored consecutive, much fewer data operations and much less data in general needs to be transferred.
|
||||
|
||||
% I think this would more belong to concept and design tbh
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{excessive_memory_transfer.png}
|
||||
|
@ -43,28 +43,62 @@ The intermediate representation can not take on any form. While it has already b
|
|||
\label{fig:excessive-memory-transfer}
|
||||
\end{figure}
|
||||
|
||||
Because of this and because the GPU does not allow pointers, another solution is required. Instead of storing pointers to objects of different types in an array, it is possible to store one object with meta information. The object therefore contains the type of the value stored, and the value itself as described in \ref{sec:pre-processing}.
|
||||
% Talk about variables, operators and constants (floats) very different types. Solution -> vars/params Integers as index (TODO: probably change so that instead of type index, have type param and type var?); operators as op_codes (integers) -> reinterpret constants from float to int; now everything can be sent in single object with type information and value
|
||||
Because of this and because the GPU does not allow pointers, another solution is required. Instead of storing pointers to objects of different types in an array, it is possible to store one object with meta information. The object therefore contains the type of the value stored, and the value itself as described in \ref{sec:pre-processing}. The four types that need to be stored in this object, differ significantly in the value they represent.
|
||||
|
||||
Variables and parameters are very simple to store. Because they represent indices to the variable matrix or the parameter vector, this (integer) index can be stored as is in the value property of the object.
|
||||
|
||||
Constants are also very simple, as they represent a single 32-bit floating point value. However, because of the variables and parameters, the value property is already defined as an integer and not as a floating point number. Unlike languages like Python, where every number is a floating point number, in Julia they are different and can therefore not be stored in the same property. Creating a second property only for constants is not feasible, as this would introduce 4 bytes per object that need to be sent to the GPU which most of the time does not contain a value. To avoid sending unnecessary bytes, a mechanism provided by Julia called reinterpret can be used. This allows the bits of a variable of one type, to be treated as the bits of another type. The bits used to represent a floating point value are then interpreted as an integer and can be stored in the same property. On the GPU, the same concept can be applied to interpret the integer value as a floating point value again for further computations. This is also the reason why the original type of the value needs to be stored alongside the value, to correctly interpret the stored bits and in turn correctly evaluate the expressions.
|
||||
|
||||
\subsection{Expressions} % Probably just part of section "Processing" and not its own? Or maybe subsection of "Processing"
|
||||
With the pre-processing step the first modern feature of Julia has been used. As already mentioned, Julia offers extensive support for meta-programming. Julia represents its own code as a data structure, which allows a developer to manipulate the code at runtime. The code is stored in the so-called Expr object as an abstract syntax tree (AST). As a result, mathematical expressions can also be represented as such an Expr object instead of a simple string. This has the major benefit, that these expression can then easily be manipulated by the symbolic regression algorithm, which is the reason why the pre-processing step requires the expressions to be provided as an Expr object and not as a string.
|
||||
|
||||
Another major benefit of the expressions being stored in the Expr object and therefore as an AST, is the included operator precedence. Because it is a tree where the leaves are the constants, variables or parameters (also called terminal symbols) and the nodes are the operators, the correct result will be calculated when evaluating the tree from bottom to top. As seen in Figure \ref{fig:expr-ast} the expression $1 + x_1 \, \log(p_1)$ when parsed as an AST contains the correct operator precedence. First the bottom most subtree $\log(p_1)$ must be evaluated before the multiplication and after that the addition can be evaluated.
|
||||
Operators are very different from variables, parameters and constants. Because they represent an operation, rather than a value, another option is needed to store them. An operator can be mapped to a number, to identify the operation. For example if the addition operator is mapped to the integer number one, if during evaluation, the evaluator comes across an object of type operator and a value of one, it knows which operation it needs to perform. This can be done for all operators which means it is possible to store them in the same object with the same property and only the type must be specified. The mapping of an operator to a value is often called an operation code or opcode, and each operator is represented as one opcode.
|
||||
|
||||
With this, the intermediate representation is defined. Figure \ref{fig:pre-processing-result-impl} shows how a simple expression would look after the pre-processing step.
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=.8\textwidth]{expr_ast.png}
|
||||
\caption{An AST as generated by Julia. Some additional details Julia includes in its AST have been omitted as they are not relevant.}
|
||||
\label{fig:expr-ast}
|
||||
\includegraphics[width=.9\textwidth]{pre-processing_result_impl.png}
|
||||
\caption{The expression $x_1 + 2.5$ after it has been converted to the intermediate representation. Note that the constant value $2.5$ stores a seemingly random value due to it being reinterpreted as an integer.}
|
||||
\label{fig:pre-processing-result-impl}
|
||||
\end{figure}
|
||||
|
||||
|
||||
\subsection{Processing}
|
||||
% because exprs are stored as AST -> from bottom to top create postfix
|
||||
% while conversion -> invalid symbols cannot be parsed -> invalid expr -> stop
|
||||
Because all expressions are already stored as an AST,
|
||||
Now that the intermediate representation has been defined, the processing step can be implemented. This section describes the structure of the expressions and how they are processed. Furthermore, the process of parsing the expressions to ensure their validity and the conversion into the intermediate representation is explained.
|
||||
|
||||
\subsubsection{Expressions}
|
||||
With the pre-processing step the first modern feature of Julia has been used. As already mentioned, Julia offers extensive support for meta-programming which is important for this step. Julia represents its own code as a data structure, which allows a developer to manipulate the code at runtime. The code is stored in the so-called Expr object as an abstract syntax tree (AST) which is the most minimal tree representation of a given expression. As a result, mathematical expressions can also be represented as such an Expr object instead of a simple string. Which is a major benefit, as these expression can then easily be manipulated by the symbolic regression algorithm. This is the main reason why the pre-processing step requires the expressions to be provided as an Expr object instead of a string.
|
||||
|
||||
Another major benefit of the expressions being stored in the Expr object and therefore as an AST, is the included operator precedence. Because it is a tree where the leaves are the constants, variables or parameters (also called terminal symbols) and the nodes are the operators, the correct result will be calculated when evaluating the tree from bottom to top. As seen in Figure \ref{fig:expr-ast} the expression $1 + x_1 \, \log(p_1)$ when parsed as an AST contains the correct operator precedence. First the bottom most subtree $\log(p_1)$ must be evaluated before the multiplication and after that the addition can be evaluated.
|
||||
|
||||
It needs to be mentioned however, that Julia stores the tree as a list of arrays to allow one node to have as many children as needed. For example the expression $1+2+\dots+n$ only contains additions which is a commutative operation, meaning the order of operations is irrelevant. The AST for this expression would contain the operator at the first position in the array and the values at the following positions. This ensures that the AST is as minimal as possible.
|
||||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=.45\textwidth]{expr_ast.png}
|
||||
\caption{The AST for the expression $1 + x_1 \, \log(p_1)$ as generated by Julia. Some additional details Julia includes in its AST have been omitted as they are not relevant.}
|
||||
\label{fig:expr-ast}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Parsing}
|
||||
To convert the AST of an expression into the intermediate representation, a top-down traversal of the tree is required. The steps for this are as follows:
|
||||
|
||||
\begin{enumerate}
|
||||
\item Extract the operator for later use.
|
||||
\item Convert all constants, variables and parameters to the object (expression element) described in Section \ref{sec:ir}.
|
||||
\item Append the expression elements to the postfix expression.
|
||||
\item If the operator is a binary operator and there are more than two expression elements, append the operator after the first two elements and then after each element.
|
||||
\item If a subtree exists, apply all previous steps and append it to the existing postfix expression.
|
||||
\item Append the operator
|
||||
\item Return the generated postfix expression/intermediate representation.
|
||||
\end{enumerate}
|
||||
|
||||
As explained above, a node of a binary operator can have $n$ children. In these cases, additional handling is required to ensure correct conversion. This handling is condensed in step 4 of the list above. Essentially, after the first two elements, the operator must be added and for every following element, the operator must be added as well. The expression $1+2+3+4$ will be converted to the AST $+\,1\,2\,3\,4$ and without step 4, the expression would be $1\,2\,3\,4\,+$. If the operator is added after the first two elements and then after each element, the correct expression $1\,2\,+\,3\,+\,4\,+$ will be generated.
|
||||
|
||||
% talk about the process of parsing.
|
||||
% Include code fragments
|
||||
% probably point out how meta-programming is used (more detailed than above)
|
||||
% talk about how invalid expressions are handled
|
||||
% talk about generation of intermediate representation
|
||||
% especially talk about cache
|
||||
|
||||
|
||||
\section{Interpreter}
|
||||
Talk about how the interpreter has been developed.
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 27 KiB |
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
BIN
thesis/images/pre-processing_result_impl.png
Normal file
BIN
thesis/images/pre-processing_result_impl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
thesis/main.pdf
BIN
thesis/main.pdf
Binary file not shown.
Loading…
Reference in New Issue
Block a user