Skip to content

Commit

Permalink
Various Bugfixes (#179)
Browse files Browse the repository at this point in the history
* Fix exporting to PDF

Closes #177

* Fix arrays not showing up in sidebar

Closes #156

* Avoid crashing the renderer on bad layouts

* Fix SM layouter for some irregular / irreducible CF

* Fixes

* Allow initialization with different contents container

* Fix for Jupyter

* Add support for direct struct member accesses on access nodes
  • Loading branch information
phschaad authored Oct 31, 2024
1 parent d097691 commit a92dc6d
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/layouter/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ function layoutControlFlowRegion(
// Fall back to dagre for anything that cannot be laid out with
// the vertical layout (e.g., irreducible control flow).
try {
SMLayouter.layoutDagreCompat(g, sdfg.start_block?.toString());
SMLayouter.layoutDagreCompat(g, cfg.start_block?.toString());
} catch (_ignored) {
dagre.layout(g);
}
Expand Down
17 changes: 17 additions & 0 deletions src/layouter/state_machine/sm_layouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,23 @@ export class SMLayouter {
'The following edges were not routed:',
unrouted
);
// To avoid crashing, simply straight-route these edges.
for (const edge of unrouted) {
const srcNode = this.graph.get((edge as any).src);
const dstNode = this.graph.get((edge as any).dst);
if (!srcNode || !dstNode)
throw Error('Unrouted edge may not be straight-routed.');
edge.points = [
{
x: srcNode.x,
y: srcNode.y + (srcNode.height / 2),
},
{
x: dstNode.x,
y: dstNode.y - (dstNode.height / 2),
},
];
}
}
}

Expand Down
58 changes: 53 additions & 5 deletions src/renderer/renderer_elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2099,6 +2099,35 @@ export class Connector extends SDFGElement {

export class AccessNode extends SDFGNode {

public getDesc(): any {
const name = this.data.node.attributes.data;
const nameParts = name.split('.');
if (nameParts.length > 1) {
let desc = this.sdfg.attributes._arrays[nameParts[0]];
let i = 1;
while (i < nameParts.length) {
if (!desc.attributes?.members)
return undefined;
const nextName = nameParts[i];
let foundDesc = undefined;
for (const mbr of desc.attributes.members) {
if (mbr[0] == nextName) {
foundDesc = mbr[1];
break;
}
}
if (foundDesc)
desc = foundDesc;
else
return undefined;
i++;
}
return desc;
} else {
return this.sdfg.attributes._arrays[nameParts[0]];
}
}

public draw(
renderer: SDFGRenderer, ctx: CanvasRenderingContext2D,
_mousepos?: Point2D
Expand All @@ -2110,7 +2139,7 @@ export class AccessNode extends SDFGNode {
ctx.strokeStyle = this.strokeStyle(renderer);

const name = this.data.node.attributes.data;
const nodedesc = this.sdfg.attributes._arrays[name];
const nodedesc = this.getDesc();
// Streams have dashed edges
if (nodedesc && nodedesc.type === 'Stream')
ctx.setLineDash([5, 3]);
Expand Down Expand Up @@ -2217,9 +2246,7 @@ export class AccessNode extends SDFGNode {

public tooltip(container: HTMLElement): void {
super.tooltip(container);
const nodedesc = this.sdfg.attributes._arrays[
this.data.node.attributes.data
];
const nodedesc = this.getDesc();
if (nodedesc)
return;
container.classList.add('sdfvtooltip--error');
Expand Down Expand Up @@ -3485,7 +3512,28 @@ function drawOctagon(
function drawEllipse(
ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number
): void {
ctx.ellipse(x + w / 2, y + h / 2, w / 2, h / 2, 0, 0, 2 * Math.PI);
if ((ctx as any).pdf) {
// The PDF rendering context does not have an `ellipse` function. As
// such, we revert back to the non-GPU-accelerated method of drawing
// ellipses that we used up to and including commit 2ceba1d.
// Adapted from https://stackoverflow.com/a/2173084/6489142
const kappa = .5522848
const ox = (w / 2) * kappa;
const oy = (h / 2) * kappa;
const xe = x + w;
const ye = y + h;
const xm = x + (w / 2);
const ym = y + (h / 2);
ctx.moveTo(x, ym);
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
} else {
// When drawing on a regular canvas, use the built-in method of drawing
// ellipses to utilize GPU acceleration where available.
ctx.ellipse(x + w / 2, y + h / 2, w / 2, h / 2, 0, 0, 2 * Math.PI);
}
}

function drawTrapezoid(
Expand Down
5 changes: 3 additions & 2 deletions src/sdfv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,11 @@ export class WebSDFV extends SDFV {
public setSDFG(
sdfg: JsonSDFG | null = null,
userTransform: DOMMatrix | null = null,
debugDraw: boolean = false
debugDraw: boolean = false,
contents_container_id: string = 'contents'
): void {
this.renderer?.destroy();
const container = document.getElementById('contents');
const container = document.getElementById(contents_container_id);
if (container && sdfg) {
const renderer = new SDFGRenderer(
sdfg, container, this, null, userTransform, debugDraw, null,
Expand Down
37 changes: 34 additions & 3 deletions src/sdfv_ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Edge,
Memlet,
NestedSDFG,
SDFG,
SDFGElement,
} from './renderer/renderer_elements';
import type { DagreGraph, SDFGRenderer } from './renderer/renderer';
Expand Down Expand Up @@ -198,9 +199,7 @@ export class SDFVWebUI implements ISDFVUserInterface {

// If access node, add array information too
if (elem instanceof AccessNode) {
const sdfg_array = elem.sdfg.attributes._arrays[
elem.attributes().data
];
const sdfg_array = elem.getDesc();
contents.append($('<br>'));
contents.append($('<h4>', {
text: sdfg_array.type + ' properties:',
Expand Down Expand Up @@ -235,6 +234,10 @@ export class SDFVWebUI implements ISDFVUserInterface {
switch (attr[0]) {
case 'layout':
case 'sdfg':
case '_arrays':
case 'orig_sdfg':
case 'transformation_hist':
case 'position':
continue;
default:
contents.append($('<b>', {
Expand All @@ -250,6 +253,34 @@ export class SDFVWebUI implements ISDFVUserInterface {
}
}
}

// For SDFGs and nested SDFGs, add information about the SDFG's data
// descriptors.
let descriptors = undefined;
if (elem instanceof SDFG)
descriptors = elem.attributes()._arrays;
else if (elem instanceof NestedSDFG)
descriptors = elem.attributes().sdfg.attributes._arrays;

if (descriptors) {
contents.append($('<hr>'));
contents.append($('<b>', {
html: 'Data containers:&nbsp;&nbsp;',
}));
contents.append($('<hr>'));
for (const desc in descriptors) {
contents.append($('<b>', {
html: desc + ':&nbsp;&nbsp;',
}));
contents.append($('<span>', {
html: sdfg_property_to_string(
descriptors[desc], renderer.view_settings()
),
}));
contents.append($('<br>'));
}
contents.append($('<hr>'));
}
}

}
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const jupyterConfig = {
output: {
filename: '[name]_jupyter.js',
path: path.resolve(__dirname, 'dist'),
publicPath: path.resolve(__dirname, 'dist'),
},
plugins: [
new webpack.ProvidePlugin({
Expand Down

0 comments on commit a92dc6d

Please sign in to comment.