implementation: finished interpreter section and started transpiler section
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
c4187a131e
commit
e8e457eae9
|
@ -1,4 +1,4 @@
|
|||
<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">
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0" version="26.2.14">
|
||||
<diagram name="Page-1" id="6PRo98IcIigsbWnrE1av">
|
||||
<mxGraphModel dx="1181" 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">
|
||||
<root>
|
||||
|
@ -14,7 +14,7 @@
|
|||
<mxGeometry x="640" y="60" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-3" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" parent="1" vertex="1">
|
||||
<mxGeometry x="305" y="100" width="10" height="440" as="geometry" />
|
||||
<mxGeometry x="305" y="100" width="10" height="420" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-7" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" parent="1" vertex="1">
|
||||
<mxGeometry x="540" y="170" width="10" height="40" as="geometry" />
|
||||
|
@ -29,7 +29,7 @@
|
|||
<mxPoint x="420" y="255" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-16" value="intermediate_representations" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="hKyrbmUfddmyC9NB2b_t-9" vertex="1" connectable="0">
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-16" value="intermediate_representation" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="hKyrbmUfddmyC9NB2b_t-9" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.008" y="-1" relative="1" as="geometry">
|
||||
<mxPoint y="-9" as="offset" />
|
||||
</mxGeometry>
|
||||
|
@ -42,7 +42,7 @@
|
|||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-11" value="" style="endArrow=none;dashed=1;html=1;rounded=0;" parent="1" target="hKyrbmUfddmyC9NB2b_t-7" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="545" y="540" as="sourcePoint" />
|
||||
<mxPoint x="545" y="520" as="sourcePoint" />
|
||||
<mxPoint x="539.76" y="260" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<mxCell id="hKyrbmUfddmyC9NB2b_t-18" value="<font style="font-size: 9px;">[for each intermediate_representation]</font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="172" y="403" width="120" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-20" value="kernel(intermediate_representation, variables, parameters)" style="html=1;verticalAlign=bottom;endArrow=open;curved=0;rounded=0;endFill=0;" parent="1" edge="1" source="hKyrbmUfddmyC9NB2b_t-3">
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-20" value="kernel(intermediate_representation, variables, parameters)" style="html=1;verticalAlign=bottom;endArrow=open;curved=0;rounded=0;endFill=0;" parent="1" source="hKyrbmUfddmyC9NB2b_t-3" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="320" y="403" as="sourcePoint" />
|
||||
<mxPoint x="685" y="403" as="targetPoint" />
|
||||
|
@ -71,7 +71,7 @@
|
|||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-26" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" parent="1" vertex="1">
|
||||
<mxGeometry x="680" y="460" width="10" height="50" as="geometry" />
|
||||
<mxGeometry x="680" y="460" width="10" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-27" value="read_results()" style="html=1;verticalAlign=bottom;endArrow=block;curved=0;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;" parent="1" source="hKyrbmUfddmyC9NB2b_t-3" target="hKyrbmUfddmyC9NB2b_t-26" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
|
@ -86,7 +86,7 @@
|
|||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-30" value="" style="endArrow=none;dashed=1;html=1;rounded=0;" parent="1" target="hKyrbmUfddmyC9NB2b_t-26" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="685" y="540" as="sourcePoint" />
|
||||
<mxPoint x="685" y="520" as="sourcePoint" />
|
||||
<mxPoint x="710" y="390" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
|
@ -147,7 +147,7 @@
|
|||
<mxPoint x="710" y="330" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-49" value="<div>interpret(expressions,</div><div>variables, parameters)</div>" style="html=1;verticalAlign=bottom;startArrow=circle;startFill=1;endArrow=open;startSize=6;endSize=8;curved=0;rounded=0;" parent="1" edge="1" target="hKyrbmUfddmyC9NB2b_t-3">
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-49" value="<div>interpret(expressions,</div><div>variables, parameters)</div>" style="html=1;verticalAlign=bottom;startArrow=circle;startFill=1;endArrow=open;startSize=6;endSize=8;curved=0;rounded=0;" parent="1" target="hKyrbmUfddmyC9NB2b_t-3" edge="1">
|
||||
<mxGeometry x="0.1057" width="80" relative="1" as="geometry">
|
||||
<mxPoint x="172" y="130" as="sourcePoint" />
|
||||
<mxPoint x="295" y="130" as="targetPoint" />
|
||||
|
@ -155,7 +155,7 @@
|
|||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-50" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="180" y="520" width="20" height="20" as="geometry" />
|
||||
<mxGeometry x="180" y="500" width="20" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="hKyrbmUfddmyC9NB2b_t-51" value="" style="endArrow=open;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endFill=0;" parent="1" source="hKyrbmUfddmyC9NB2b_t-3" target="hKyrbmUfddmyC9NB2b_t-50" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
|
|
168
other/transpiler_sequence_diagram.drawio
Normal file
168
other/transpiler_sequence_diagram.drawio
Normal file
|
@ -0,0 +1,168 @@
|
|||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0" version="26.2.14">
|
||||
<diagram name="Page-1" id="dN1vCd9jYV9B4u8MPVmJ">
|
||||
<mxGraphModel dx="1181" 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">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-1" value="Transpiler" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="260" y="60" width="100" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-2" value="Pre-Processing" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="500" y="60" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-3" value="GPU" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="640" y="60" width="90" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-4" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" vertex="1" parent="1">
|
||||
<mxGeometry x="305" y="100" width="10" height="420" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-5" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" vertex="1" parent="1">
|
||||
<mxGeometry x="540" y="170" width="10" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-6" value="expr_to_postfix(expr): ExpressionElement[]" style="html=1;verticalAlign=bottom;endArrow=block;curved=0;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-4" target="gMhPBGUGI9FZGhFn2pCe-5">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="420" y="185" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-7" value="" style="html=1;verticalAlign=bottom;endArrow=open;endSize=8;curved=0;rounded=0;exitX=0;exitY=1;exitDx=0;exitDy=-5;dashed=1;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-5" target="gMhPBGUGI9FZGhFn2pCe-4">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="420" y="255" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-8" value="intermediate_representation" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="gMhPBGUGI9FZGhFn2pCe-7">
|
||||
<mxGeometry x="-0.008" y="-1" relative="1" as="geometry">
|
||||
<mxPoint y="-9" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-9" value="" style="endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-5" target="gMhPBGUGI9FZGhFn2pCe-2">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="550" y="150" as="sourcePoint" />
|
||||
<mxPoint x="780" y="260" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-11" value="loop" style="shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="170" y="150" width="420" height="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-12" value="<font style="font-size: 9px;">[for each expression]</font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="170" y="180" width="90" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-13" value="loop" style="shape=umlFrame;whiteSpace=wrap;html=1;pointerEvents=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="170" y="370" width="560" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-14" value="<font style="font-size: 9px;">[for each kernel]</font>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="172" y="403" width="68" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-15" value="kernel(variables, parameters)" style="html=1;verticalAlign=bottom;endArrow=open;curved=0;rounded=0;endFill=0;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-4">
|
||||
<mxGeometry x="0.0008" relative="1" as="geometry">
|
||||
<mxPoint x="320" y="403" as="sourcePoint" />
|
||||
<mxPoint x="685" y="403" as="targetPoint" />
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-16" value="" style="endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-24" target="gMhPBGUGI9FZGhFn2pCe-3">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="610" y="250" as="sourcePoint" />
|
||||
<mxPoint x="660" y="200" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-17" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" vertex="1" parent="1">
|
||||
<mxGeometry x="680" y="460" width="10" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-18" value="read_results()" style="html=1;verticalAlign=bottom;endArrow=block;curved=0;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-4" target="gMhPBGUGI9FZGhFn2pCe-17">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="305" y="444" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-19" value="resultMatrix" style="html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;exitX=0;exitY=1;exitDx=0;exitDy=-5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-17" target="gMhPBGUGI9FZGhFn2pCe-4">
|
||||
<mxGeometry x="0.0012" relative="1" as="geometry">
|
||||
<mxPoint x="305" y="494.0000000000001" as="targetPoint" />
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-20" value="" style="endArrow=none;dashed=1;html=1;rounded=0;" edge="1" parent="1" target="gMhPBGUGI9FZGhFn2pCe-17">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="685" y="520" as="sourcePoint" />
|
||||
<mxPoint x="710" y="390" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-21" value="send_data(variables)" style="html=1;verticalAlign=bottom;endArrow=block;curved=0;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-4" target="gMhPBGUGI9FZGhFn2pCe-24">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="720" y="225" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-22" value="" style="html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;exitX=0;exitY=1;exitDx=0;exitDy=-5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-24" target="gMhPBGUGI9FZGhFn2pCe-4">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="720" y="255" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-23" value="" style="endArrow=none;dashed=1;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-27" target="gMhPBGUGI9FZGhFn2pCe-24">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="700" y="349" as="sourcePoint" />
|
||||
<mxPoint x="700" y="120" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-24" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" vertex="1" parent="1">
|
||||
<mxGeometry x="680" y="310" width="10" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-25" value="send_data(parameters)" style="html=1;verticalAlign=bottom;endArrow=block;curved=0;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-4" target="gMhPBGUGI9FZGhFn2pCe-27">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="750" y="288" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-26" value="" style="html=1;verticalAlign=bottom;endArrow=open;dashed=1;endSize=8;curved=0;rounded=0;exitX=0;exitY=1;exitDx=0;exitDy=-5;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-27" target="gMhPBGUGI9FZGhFn2pCe-4">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="750" y="358" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-27" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" vertex="1" parent="1">
|
||||
<mxGeometry x="680" y="340" width="10" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-31" value="" style="endArrow=none;dashed=1;html=1;rounded=0;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-17" target="gMhPBGUGI9FZGhFn2pCe-27">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="685" y="330" as="sourcePoint" />
|
||||
<mxPoint x="710" y="290" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-33" value="<div>transpile(expressions,</div><div>variables, parameters)</div>" style="html=1;verticalAlign=bottom;startArrow=circle;startFill=1;endArrow=open;startSize=6;endSize=8;curved=0;rounded=0;" edge="1" parent="1" target="gMhPBGUGI9FZGhFn2pCe-4">
|
||||
<mxGeometry x="0.1057" width="80" relative="1" as="geometry">
|
||||
<mxPoint x="172" y="130" as="sourcePoint" />
|
||||
<mxPoint x="295" y="130" as="targetPoint" />
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-34" value="" style="ellipse;html=1;shape=endState;fillColor=#000000;strokeColor=default;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="500" width="20" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-35" value="" style="endArrow=open;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endFill=0;" edge="1" parent="1" source="gMhPBGUGI9FZGhFn2pCe-4" target="gMhPBGUGI9FZGhFn2pCe-34">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="230" y="640" as="sourcePoint" />
|
||||
<mxPoint x="280" y="590" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-36" value="resultMatrix" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="gMhPBGUGI9FZGhFn2pCe-35">
|
||||
<mxGeometry x="0.1271" relative="1" as="geometry">
|
||||
<mxPoint x="8" y="-10" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-38" value="" style="endArrow=none;dashed=1;html=1;rounded=0;" edge="1" parent="1" target="gMhPBGUGI9FZGhFn2pCe-5">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="545" y="520" as="sourcePoint" />
|
||||
<mxPoint x="545" y="280" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-53" value="" style="html=1;points=[[0,0,0,0,5],[0,1,0,0,-5],[1,0,0,0,5],[1,1,0,0,-5]];perimeter=orthogonalPerimeter;outlineConnect=0;targetShapes=umlLifeline;portConstraint=eastwest;newEdgeStyle={"curved":0,"rounded":0};" vertex="1" parent="1">
|
||||
<mxGeometry x="310" y="243" width="10" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gMhPBGUGI9FZGhFn2pCe-54" value="transpile(intermediate_representation): Kernel" style="html=1;align=left;spacingLeft=2;endArrow=block;rounded=0;edgeStyle=orthogonalEdgeStyle;curved=0;rounded=0;" edge="1" target="gMhPBGUGI9FZGhFn2pCe-53" parent="1">
|
||||
<mxGeometry x="-0.005" relative="1" as="geometry">
|
||||
<mxPoint x="315" y="223" as="sourcePoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="345" y="253" />
|
||||
</Array>
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
|
@ -11,7 +11,7 @@ Frontend:
|
|||
1.) extend frontend to support ternary operators (basically if the frontend sees a multiplication and an addition it should collapse them to an FMA instruction)
|
||||
|
||||
Transpiler:
|
||||
1.) transpile expression directly from Julia AST -> would save time because no intermediate representation needs to be created (looses step and gains performance, but also makes transpiler itself more complex)
|
||||
1.) transpile expression directly from Julia AST -> would save time because no intermediate representation needs to be created (looses step and gains performance, but also makes transpiler itself more complex; since expressions do not need to be sent to the GPU, the IR theoretically isn't needed)
|
||||
2.) Better register management strategy might be helpful -> look into register pressure etc.
|
||||
|
||||
|
||||
|
|
|
@ -115,12 +115,14 @@ An overview of how these components interact with each other is outlined in Figu
|
|||
\end{figure}
|
||||
|
||||
\subsection{CPU Side}
|
||||
% main loop; kernel transpiled by CUDA.jl into PTX and then executed
|
||||
The interpreter is given all the expressions it needs to interpret as an input. Additionally, it needs the variable matrix as well as the parameters for each expression. All expressions are passed to the interpreter as an array of Expr objects, as they are needed for the pre-processing step or the frontend. The first loop as shown in Figure \ref{fig:interpreter-sequence}, is responsible for sending the expressions to the frontend to be converted into the intermediate representation. After this step, the expressions are in the correct format to be sent to the GPU and the interpretation process can continue.
|
||||
|
||||
\subsubsection{Data Transfer}
|
||||
Before the GPU can start with the interpretation, the data needs to be sent to the GPU. Because the variables are already in matrix form, transferring the data is fairly straightforward. Memory must be allocated in the global memory of the GPU and then be copied from RAM into the allocated memory. Allocating memory and transferring the data to the GPU is handled implicitly by the CuArray type provided by CUDA.jl.
|
||||
|
||||
As the interpreter needs to be optimised for parameter optimisation workloads, this step is actually performed before the interpreter is called. The variables never change, as they represent the observed inputs of a system that needs to be modelled by the symbolic regression algorithm. Therefore, it would be wasteful to re-transmit the variables for each step of the parameter optimisation part. If they are transmitted once and then reused throughout the duration of the parameter optimisation part, a lot of time can be saved. It would even be possible to transfer the data to the GPU before the symbolic regression algorithm starts, saving even more time. However, as this would require a change to the symbolic regression algorithm, the decision has been made to neglect this optimisation. It is still possible to modify the implementation at a later stage with minimal effort, if required.
|
||||
To optimise the interpreter for parameter optimisation workloads, this step is actually performed before the interpreter is called. Although, the diagram includes this transmission for completeness, it is important to note that the variables never change, as they represent the observed inputs of the system that being modelled by the symbolic regression algorithm. Therefore, re-transmitting the variables for each step of the parameter optimisation process would be inefficient. By transmitting the variables once and reusing them throughout the parameter optimisation, significant time can be saved.
|
||||
|
||||
Furthermore, transferring the data to the GPU before the symbolic regression algorithm begins, could save even more time. However, this approach would require modification to the symbolic regression algorithm. Therefore, the decision has been made to neglect this optimisation. Nonetheless, it is still possible to modify the implementation at a later stage with minimal effort, if needed.
|
||||
|
||||
Once the variables are transmitted, the parameters also must be transferred to the GPU. Unlike the variables, the parameters are stored as a vector of vectors. In order to transmit the parameters efficiently, they also need to be put in a matrix form. The matrix needs to be of the form $k \times N$, where $k$ is equal to the length of the longest inner vector and $N$ is equal to the length of the outer vector. This ensures that all values can be stored in the matrix. It also means that if the inner vectors are of different lengths, some extra unnecessary values will be transmitted, but the overall benefit of treating them as a matrix outweighs this drawback. The Program \ref{code:julia_vec-to-mat} shows how this conversion can be implemented. Note that it is required to provide an invalid element. This ensures defined behaviour and helps with finding errors in the code. After the parameters have been brought into matrix form, they can be transferred to the GPU the same way the variables are transferred.
|
||||
|
||||
|
@ -157,8 +159,9 @@ In addition to the already described data that needs to be sent, two more steps
|
|||
\label{fig:memory-layout-data}
|
||||
\end{figure}
|
||||
|
||||
Only raw data can be sent to the GPU, which means that information about the data is missing. The matrices are represented as flat arrays, which means they have lost their column and row information. This information must be sent separately to let the kernel know the dimensions of the expressions, variables and parameters. Otherwise, the kernel does not know at which memory location the second variable set is stored for example. Figure \ref{fig:memory-layout-data} shows how the data is stored without any information about the rows or columns of the matrices. The thick lines help to identify where a new column, and therefore a new set of data begins. However, the GPU has no knowledge of this and therefore the additional information must be transferred to ensure that the data is accessed correctly.
|
||||
Only raw data can be sent to the GPU, which means that information about the data is missing. The matrices are represented as flat arrays, which means they have lost their column and row information. This information must be sent separately to let the kernel know the dimensions of the expressions, variables and parameters. Otherwise, the kernel does not know at which memory location the second variable set is stored, as it does not know how large a single set is for example. Figure \ref{fig:memory-layout-data} shows how the data is stored without any information about the rows or columns of the matrices. The thick lines help to identify where a new column, and therefore a new set of data begins. However, the GPU has no knowledge of this and therefore the additional information must be transferred to ensure that the data is accessed correctly.
|
||||
|
||||
\subsubsection{Kernel Dispatch}
|
||||
Once all the data is present on the GPU, the CPU can dispatch the kernel for each expression. This dispatch requires parameters that specify the number of threads and their organisation into thread blocks. In total, one thread is required for each variable set and therefore the grouping into thread blocks is the primary variable. Taking into account the constraints explained in Section \ref{sec:occupancy}, this grouping needs to be tuned for optimal performance. The specific values alongside the methodology for determining these values will be explained in Chapter \ref{cha:evaluation}.
|
||||
|
||||
In addition, the dispatch parameters also include the pointers to the location of the data allocated and transferred above, as well as the index of the expression to be interpreted. Since all expressions and parameters are sent to the GPU at once, this index ensures that the kernel knows where in memory to find the expression it needs to interpret and which parameter set it needs to use. After the kernel has finished, the result matrix needs to be read from the GPU and passed back to the symbolic regression algorithm.
|
||||
|
@ -176,32 +179,61 @@ Moreover, the global thread ID ensures that excess threads do not perform any wo
|
|||
Afterwards the stack for the interpretation can be created. It is possible to dynamically allocate memory on the GPU, which enables a similar programming model as on the CPU. \textcite{winter_are_2021} have even compared many dynamic memory managers and found, that the performance impact of them is rather small. However, if it is easily possible to use static allocations, it still offers better performance. In the case of this thesis, it is easily possible which is the reason why the stack has been chosen to have a static size. Because it is known that expressions do not exceed 50 tokens, including the operators, the stack size has been set to 25, which should be more than enough to hold the values and partial results, even in the worst case.
|
||||
|
||||
\subsubsection{Main Loop} % MAYBE
|
||||
After everything has been initialised, the main interpreter loop starts interpreting the expression. Because of the intermediate representation, the loop simply traverses the expression from left to right. On each iteration the type of the current token is checked, to decide which operation to perform.
|
||||
Once everything is initialised, the main interpreter loop starts interpreting the expression. Because of the intermediate representation, the loop simply iterates through the expression from left to right. On each iteration the type of the current token is checked, to decide which operation to perform.
|
||||
|
||||
If the current token type corresponds to the \textit{stop} opcode, the interpreter knows that it has finished. This simplicity is the reason why as explained above, this opcode has been introduced.
|
||||
If the current token type matches the \textit{stop} opcode, the interpreter knows that it is finished. This simplicity is the reason why this opcode was introduced, as explained above.
|
||||
|
||||
% make clearer
|
||||
More interestingly is the case, where the current token corresponds to an index to either the variable matrix, or the parameter matrix. If that is the case, then the value of the token is important. To access one of these matrices first, the correct starting index needs to be calculated. As already explained, all information about the layout of the data is lost during transfer. At this stage, the kernel only knows the index of the first element of either of the matrices, the index of the variable set and parameter set, as well as the index of the value inside the current variable set or parameter set. However, it is not known where the boundaries of the sets are and therefore the additionally transferred data about the layout is used in this step to calculate the index of the first element per set. With this calculated index and the index stored in the token, the correct value can be loaded. After the value has been loaded, it is stored at the top of the stack for later use.
|
||||
More interestingly is the case, where the current token corresponds to an index to either the variable matrix, or the parameter matrix. In this case, the token's value is important. To access one of these matrices, the correct starting index of the set must first be calculated. As previously explained, information about the dimensions of the data is lost during transfer. At this stage, the kernel only knows the index of the first element of either matrix, which set to use for this evaluation, and the index of the value within the current set. However, the boundaries of these sets are unknown. Therefore, the additionally transferred data about the dimensions is used in this step to calculate the index of the first element in each set. With this calculated index and the index stored in the token, the correct value can be loaded. After the value has been loaded, it is pushed to the top of the stack for later use.
|
||||
|
||||
% MAYBE:
|
||||
% Algorithm that shows how this calculation works
|
||||
|
||||
Constants work very similar, as the token value is read and added to the top of the stack. However, since constants have been reinterpreted as integers for easy transfer to the GPU, this must be reversed before adding the value to the stack.
|
||||
Constants work very similarly in that the token value is read and added to the top of the stack. However, the constants have been reinterpreted from floating-point values to integers for easy transfer to the GPU. This operation must be reversed before adding the value to the stack as otherwise the wrong values would be used for evaluation.
|
||||
|
||||
Evaluating the expression is happening if the current token is an operator. The value of the token is the opcode, which determines the operation that needs to be performed. If the opcode corresponds to a unary operator, only the top value of the stack needs to be popped for the operation. The operation is then performed on this value and the result is added back to the stack. On the other hand, if the operator corresponds to a binary operator, the top two values need to be popped. These are then used for the operation and the result is again added back to the stack.
|
||||
Evaluating the expression is happening if the current token is an operator. The token's value, which serves as the opcode, determines the operation that needs to be performed. If the opcode represents a unary operator, only the top value of the stack needs to be popped for the operation. The operation is then executed on this value and the result is pushed back to the stack. On the other hand, if the opcode represents a binary operator, the top two values of the stack are popped. These are then used for the operation, and the result is subsequently pushed back onto the stack.
|
||||
|
||||
With this it would also be possible to add support for ternary operators. An example would be a Fused Multiply-Add (FMA) operator. While this operator does not exist in Julia, the frontend can generate it, if it encounters a sub-expression that follows the form $x * y + z$. As this expression performs the multiplication and addition in a single clock cycle instead of two, it would be a feasible optimisation. However, detecting such sub-expressions is more complicated, which is the reason it is not supported in the current implementation.
|
||||
Support for ternary operators could also be easily added. An example of a ternary operator that would help improve performance would be the GPU supported Fused Multiply-Add (FMA) operator. While this operator does not exist in Julia, the frontend can generate it when it encounters a sub-expression of the form $x * y + z$. Since this expression performs the multiplication and addition in a single clock cycle instead of two, it would be a feasible optimisation. However, detecting such sub-expressions is more complicated, which why it is not supported in the current implementation.
|
||||
|
||||
Once the interpreter loop is finished, the result of the evaluation needs to be stored in the result matrix. By using the index of the current expression, as well as the index of the current variable set, the index where the result must be stored can be calculated. The last value on the stack is the result, which will be stored in the result matrix at the calculated location.
|
||||
Once the interpreter loop has finished, the result of the evaluation must be stored in the result matrix. By using the index of the current expression, as well as the index of the current variable set (the global thread ID) it is possible to calculate the index where the result must be stored. The last value on the stack is the result, which is stored in the result matrix at the calculated location.
|
||||
|
||||
\section{Transpiler}
|
||||
Talk about how the transpiler has been developed (probably largest section, because it just has more interesting parts); CPU-side part will be much larger than GPU side
|
||||
% Talk about how the transpiler has been developed (probably largest section, because it just has more interesting parts); CPU-side part will be much larger than GPU side
|
||||
Unlike the interpreter, the transpiler primarily operates on the CPU, with only a minor GPU-based component. This is because the transpiler must generate entire PTX kernels from Julia expressions, rather than simply executing a pre-written kernel like the interpreter. Similar to the interpreter, the CPU side of the transpiler manages communication with both the GPU and the symbolic regression algorithm. This section provides a detailed overview of the transpiler's functionality.
|
||||
|
||||
UML-Ablaufdiagram
|
||||
An overview of how the transpiler interacts with the frontend and GPU is outlined in Figure \ref{fig:transpiler-sequence}. The parts of this figure are explained in detail in the following sections.
|
||||
|
||||
Front-End and Back-End
|
||||
Caching of back-end results
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=.95\textwidth]{transpiler_sequence_diagram.png}
|
||||
\caption{The sequence diagram of the transpiler.}
|
||||
\label{fig:transpiler-sequence}
|
||||
\end{figure}
|
||||
|
||||
PTX code generated and compiled using CUDA.jl (so basically using the driver) and then executed
|
||||
\subsection{CPU Side}
|
||||
% TODO: Finish on Saturday
|
||||
After the transpiler has received the expressions to be transpiled, first they are sent to the frontend for processing. Once they have been processed, the expressions are sent to the transpiler backend which is further explained in Section \ref{sec:transpiler-backend}. The backend is responsible for generating the kernels. The output of the backend are the kernels written as PTX code for all expressions.
|
||||
|
||||
Memory access (global memory and register management especially register management)
|
||||
\subsubsection{Data Transfer}
|
||||
% smaller section as it basically states that it works the same as interpreter
|
||||
% mention that now expressions are not transmitted, as the kernel "is" the expression
|
||||
|
||||
\subsubsection{Kernel Dispatch}
|
||||
% similar to interpreter dispatch with tuning etc.
|
||||
% mention that CUDA.jl is used to instruct the driver to compile the kernel for the specific hardware
|
||||
|
||||
\subsubsection{Transpiler Backend}
|
||||
\label{sec:transpiler-backend}
|
||||
% TODO: Start on Saturday and finish on Sunday (prefferably finish on Saturday)
|
||||
% describe the tanspilation process
|
||||
|
||||
\subsection{GPU Side}
|
||||
% TODO: Finish on Sunday
|
||||
|
||||
|
||||
|
||||
% Front-End and Back-End
|
||||
% Caching of back-end results
|
||||
|
||||
% PTX code generated and compiled using CUDA.jl (so basically using the driver) and then executed
|
||||
|
||||
% Memory access (global memory and register management especially register management)
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 106 KiB |
BIN
thesis/images/transpiler_sequence_diagram.png
Normal file
BIN
thesis/images/transpiler_sequence_diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
BIN
thesis/main.pdf
BIN
thesis/main.pdf
Binary file not shown.
Loading…
Reference in New Issue
Block a user