Skip to content

Commit

Permalink
Compatibility with new SDFG changes (#132)
Browse files Browse the repository at this point in the history
* Improve compatibility with hierarchical SDFGs

* Adapt to SDFG_list refactor

* Update eslint rule

* Backwards compatbility
  • Loading branch information
phschaad authored Feb 23, 2024
1 parent e4a9a5a commit d686768
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 64 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module.exports = {
"argsIgnorePattern": "^_",
},
],
"@typescript-eslint/no-unsafe-declaration-merging": "warn",
"@typescript-eslint/no-var-requires": "warn",
"semi": "error",
"no-useless-escape": "off",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@spcl/sdfv",
"version": "1.1.5",
"version": "1.1.6",
"description": "A standalone viewer for SDFGs",
"homepage": "https://github.com/spcl/dace-webclient",
"main": "out/index.js",
Expand Down
4 changes: 2 additions & 2 deletions samples/example.sdfg
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@
}
],
"edges": [],
"sdfg_list_id": 0,
"start_state": 0,
"cfg_list_id": 0,
"start_block": 0,
"dace_version": "0.13.3"
}
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ export interface JsonSDFGState extends JsonSDFGBlock {

export type JsonSDFG = {
type: string,
start_state: number,
sdfg_list_id: number,
start_block: number,
cfg_list_id: number,
attributes: any,
edges: any[], // TODO
nodes: any[], // TODO
Expand Down
2 changes: 1 addition & 1 deletion src/overlays/memory_location_overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export class MemoryLocationOverlay extends GenericSdfgOverlay {
if (node instanceof SDFGNode) {
if (node.data?.node?.scope_entry !== undefined &&
node.parent_id !== null) {
scopeNode = node.sdfg.nodes[node.parent_id].nodes[
scopeNode = node.parentElem?.data.state.nodes[
node.data.node.scope_entry
];
parentId = node.parent_id;
Expand Down
10 changes: 5 additions & 5 deletions src/renderer/canvas_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
getPositioningInfo,
initialize_positioning_info,
} from '../utils/sdfg/sdfg_utils';
import { SDFGRenderer, SDFGListType } from './renderer';
import { SDFGRenderer, CFGListType } from './renderer';
import { DagreSDFG, intersectRect, Point2D } from '../index';

const animation_duration = 1000;
Expand Down Expand Up @@ -322,7 +322,7 @@ export class CanvasManager {
* @param {*} old_mousepos Old mouse position in canvas coordinates
* @param {*} new_mousepos New mouse position in canvas coordinates
* @param {*} entire_graph Reference to the entire graph
* @param {*} sdfg_list List of SDFGs and nested SDFGs
* @param {*} cfg_list List of CFGs in this SDFG
* @param {*} state_parent_list List of parent elements to SDFG states
* @param {*} drag_start Drag starting event, undefined if no drag
* @param {*} update_position_info Whether to update positioning information
Expand All @@ -334,7 +334,7 @@ export class CanvasManager {
old_mousepos: Point2D,
new_mousepos: Point2D,
entire_graph: DagreSDFG,
sdfg_list: SDFGListType,
cfg_list: CFGListType,
state_parent_list: any[],
drag_start: any,
update_position_info: boolean = true,
Expand All @@ -348,7 +348,7 @@ export class CanvasManager {
const in_edges: any[] = [];

// Find the parent graph in the list of available SDFGs
let parent_graph = sdfg_list[el.sdfg.sdfg_list_id];
let parent_graph = cfg_list[el.sdfg.cfg_list_id];
let parent_element: SDFGElement | null = null;

if (
Expand All @@ -359,7 +359,7 @@ export class CanvasManager {
// we're currently in a nested SDFG. If we're also moving a state,
// this means that its parent element is found in the list of
// parents to states (state_parent_list)
parent_element = state_parent_list[el.sdfg.sdfg_list_id];
parent_element = state_parent_list[el.sdfg.cfg_list_id];
} else if (el.parent_id !== null && parent_graph) {
// If the parent_id isn't null and there is a parent graph, we can
// look up the parent node via the element's parent_id
Expand Down
59 changes: 31 additions & 28 deletions src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Point2D,
SDFVTooltipFunc,
SimpleRect,
checkCompatSave,
stringify_sdfg
} from '../index';
import { SMLayouter } from '../layouter/state_machine/sm_layouter';
Expand Down Expand Up @@ -71,7 +72,7 @@ declare const vscode: any | null;

type SDFGElementGroup = 'states' | 'nodes' | 'edges' | 'isedges';
// If type is explicitly set, dagre typecheck fails with integer node ids
export type SDFGListType = any[];//{ [key: number]: DagreSDFG };
export type CFGListType = any[];//{ [key: number]: DagreSDFG };

function check_valid_add_position(
type: SDFGElementType | null,
Expand Down Expand Up @@ -127,7 +128,7 @@ export interface SDFGRenderer {

export class SDFGRenderer extends EventEmitter {

protected sdfg_list: any = {};
protected cfg_list: any = {};
protected graph: DagreSDFG | null = null;
// Parent-pointing SDFG tree.
protected sdfg_tree: { [key: number]: number } = {};
Expand Down Expand Up @@ -993,8 +994,8 @@ export class SDFGRenderer extends EventEmitter {
(otype: SDFGElementGroup, odict: any, obj: any) => {
if (obj.type === SDFGElementType.NestedSDFG &&
obj.attributes.sdfg)
this.sdfg_tree[obj.attributes.sdfg.sdfg_list_id] =
odict.sdfg.sdfg_list_id;
this.sdfg_tree[obj.attributes.sdfg.cfg_list_id] =
odict.sdfg.cfg_list_id;
}
);
}
Expand Down Expand Up @@ -1063,9 +1064,9 @@ export class SDFGRenderer extends EventEmitter {
if (!this.ctx)
throw new Error('No context found while performing layouting');

this.sdfg_list = {};
this.cfg_list = {};
this.graph = relayoutStateMachine(
this.ctx, this.sdfg, this.sdfg, this.sdfg_list,
this.ctx, this.sdfg, this.sdfg, this.cfg_list,
this.state_parent_list, !SDFVSettings.showAccessNodes, undefined
);
this.onresize();
Expand Down Expand Up @@ -1130,7 +1131,7 @@ export class SDFGRenderer extends EventEmitter {
this.canvas_manager?.translate_element(
node, { x: node.x, y: node.y },
{ x: node.x + dx, y: node.y + dy }, this.graph,
this.sdfg_list, this.state_parent_list, undefined, false
this.cfg_list, this.state_parent_list, undefined, false
);
}

Expand Down Expand Up @@ -1163,7 +1164,7 @@ export class SDFGRenderer extends EventEmitter {
if (this.graph)
this.canvas_manager?.translate_element(
edge, { x: 0, y: 0 },
{ x: 0, y: 0 }, this.graph, this.sdfg_list,
{ x: 0, y: 0 }, this.graph, this.cfg_list,
this.state_parent_list, undefined, false, false,
final_pos_d
);
Expand Down Expand Up @@ -1365,8 +1366,10 @@ export class SDFGRenderer extends EventEmitter {

public save_sdfg(): void {
const name = this.sdfg.attributes.name;
const contents = 'data:text/json;charset=utf-8,' +
encodeURIComponent(stringify_sdfg(this.sdfg));
const sdfgString = stringify_sdfg(checkCompatSave(this.sdfg));
const contents = 'data:text/json;charset=utf-8,' + encodeURIComponent(
sdfgString
);
this.save(name + '.sdfg', contents);
}

Expand Down Expand Up @@ -1913,7 +1916,7 @@ export class SDFGRenderer extends EventEmitter {
traverseRecursive(
node.data.graph,
node.attributes().sdfg.attributes.name,
node.attributes().sdfg.sdfg_list_id
node.attributes().sdfg.cfg_list_id
);
}
// Connectors
Expand Down Expand Up @@ -1984,7 +1987,7 @@ export class SDFGRenderer extends EventEmitter {

// Start with top-level SDFG.
traverseRecursive(
this.graph, this.sdfg.attributes.name, this.sdfg.sdfg_list_id
this.graph, this.sdfg.attributes.name, this.sdfg.cfg_list_id
);
}

Expand Down Expand Up @@ -2322,7 +2325,7 @@ export class SDFGRenderer extends EventEmitter {
// Do not move connectors (individually)
if (el instanceof Connector)
return false;
const list_id = el.sdfg.sdfg_list_id;
const list_id = el.sdfg.cfg_list_id;

// Do not move element individually if it is
// moved together with a nested SDFG
Expand All @@ -2337,7 +2340,7 @@ export class SDFGRenderer extends EventEmitter {
// Do not move element individually if it is
// moved together with its parent state
const state_parent =
this.sdfg_list[list_id].node(
this.cfg_list[list_id].node(
el.parent_id!.toString()
);
if (state_parent &&
Expand All @@ -2357,7 +2360,7 @@ export class SDFGRenderer extends EventEmitter {
if (old_mousepos)
this.canvas_manager?.translate_element(
el, old_mousepos, this.mousepos,
this.graph, this.sdfg_list,
this.graph, this.cfg_list,
this.state_parent_list,
this.drag_start,
true,
Expand Down Expand Up @@ -2577,7 +2580,7 @@ export class SDFGRenderer extends EventEmitter {
// nested sdfg
if (intersected && obj instanceof AccessNode) {
traverseSDFGScopes(
this.sdfg_list[obj.sdfg.sdfg_list_id],
this.cfg_list[obj.sdfg.cfg_list_id],
(node: any) => {
// If node is a state, then visit sub-scope
if (node instanceof State)
Expand Down Expand Up @@ -2894,7 +2897,7 @@ export class SDFGRenderer extends EventEmitter {
// Move it to original position
this.canvas_manager?.translate_element(
edge_el, { x: 0, y: 0 }, { x: 0, y: 0 },
this.graph, this.sdfg_list,
this.graph, this.cfg_list,
this.state_parent_list, undefined, false, false,
new_points
);
Expand All @@ -2916,7 +2919,7 @@ export class SDFGRenderer extends EventEmitter {
this.canvas_manager?.translate_element(
el, { x: el.x, y: el.y },
{ x: new_x, y: new_y }, this.graph,
this.sdfg_list, this.state_parent_list,
this.cfg_list, this.state_parent_list,
undefined, false, false, undefined
);

Expand Down Expand Up @@ -3159,15 +3162,15 @@ export class SDFGRenderer extends EventEmitter {
*/
// Collect nodes and states
const sdfgs: Set<number> = new Set<number>();
const sdfg_list: { [key: string]: JsonSDFG } = {};
const cfg_list: { [key: string]: JsonSDFG } = {};
const states: { [key: string]: Array<number> } = {};
const nodes: { [key: string]: Array<number> } = {};
for (const elem of this.selected_elements) {
// Ignore edges and connectors
if (elem instanceof Edge || elem instanceof Connector)
continue;
const sdfg_id = elem.sdfg.sdfg_list_id;
sdfg_list[sdfg_id] = elem.sdfg;
const sdfg_id = elem.sdfg.cfg_list_id;
cfg_list[sdfg_id] = elem.sdfg;
sdfgs.add(sdfg_id);
let state_id: number = -1;
if (elem.parent_id !== null) {
Expand Down Expand Up @@ -3203,20 +3206,20 @@ export class SDFGRenderer extends EventEmitter {
// Find root SDFG and root state (if possible)
const root_sdfg_id = find_root_sdfg(sdfgs, this.sdfg_tree);
if (root_sdfg_id !== null) {
const root_sdfg = sdfg_list[root_sdfg_id];
const root_sdfg = cfg_list[root_sdfg_id];

// For every participating state, filter out irrelevant nodes and
// memlets.
for (const nkey of Object.keys(nodes)) {
const [sdfg_id, state_id] = JSON.parse(nkey);
const sdfg = sdfg_list[sdfg_id];
const sdfg = cfg_list[sdfg_id];
delete_sdfg_nodes(sdfg, state_id, nodes[nkey], true);
}

// For every participating SDFG, filter out irrelevant states and
// interstate edges.
for (const sdfg_id of Object.keys(states)) {
const sdfg = sdfg_list[sdfg_id];
const sdfg = cfg_list[sdfg_id];
delete_sdfg_states(sdfg, states[sdfg_id], true);
}

Expand Down Expand Up @@ -3301,7 +3304,7 @@ type StateMachineType = {

function relayoutStateMachine(
ctx: CanvasRenderingContext2D, stateMachine: StateMachineType,
sdfg: JsonSDFG, sdfgList: SDFGListType, stateParentList: any[],
sdfg: JsonSDFG, sdfgList: CFGListType, stateParentList: any[],
omitAccessNodes: boolean, parent?: SDFGElement
): DagreSDFG {
const BLOCK_MARGIN = 3 * SDFV.LINEHEIGHT;
Expand Down Expand Up @@ -3408,7 +3411,7 @@ function relayoutStateMachine(
// 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_state?.toString());
SMLayouter.layoutDagreCompat(g, sdfg.start_block?.toString());
} catch (_ignored) {
dagre.layout(g);
}
Expand Down Expand Up @@ -3481,7 +3484,7 @@ function relayoutStateMachine(
(g as any).height = bb.height;

// Add SDFG to global store.
sdfgList[sdfg.sdfg_list_id] = g;
sdfgList[sdfg.cfg_list_id] = g;

return g;
}
Expand Down Expand Up @@ -3578,7 +3581,7 @@ function relayoutSDFGState(
if ((node.type === SDFGElementType.NestedSDFG ||
node.type === SDFGElementType.ExternalNestedSDFG) &&
node.attributes.sdfg && node.attributes.sdfg.type !== 'SDFGShell')
stateParentList[node.attributes.sdfg.sdfg_list_id] = obj;
stateParentList[node.attributes.sdfg.cfg_list_id] = obj;

// Add input connectors.
let i = 0;
Expand Down
6 changes: 3 additions & 3 deletions src/renderer/renderer_elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1685,7 +1685,7 @@ export class ScopeNode extends SDFGNode {
public schedule_label(): string {
let attrs = this.attributes();
if (this.scopeend() && this.parent_id !== null) {
const entry = this.sdfg.nodes[this.parent_id].nodes[
const entry = this.parentElem?.data.state.nodes[
this.data.node.scope_entry
];
if (entry !== undefined)
Expand Down Expand Up @@ -1715,7 +1715,7 @@ export class ScopeNode extends SDFGNode {

let attrs = this.attributes();
if (this.scopeend() && this.parent_id !== null) {
const entry = this.sdfg.nodes[this.parent_id].nodes[
const entry = this.parentElem?.data.state.nodes[
this.data.node.scope_entry
];
if (entry !== undefined)
Expand Down Expand Up @@ -1753,7 +1753,7 @@ export class ScopeNode extends SDFGNode {

let result = '';
if (this.scopeend() && this.parent_id !== null) {
const entry = this.sdfg.nodes[this.parent_id].nodes[
const entry = this.parentElem?.data.state.nodes[
this.data.node.scope_entry
];
if (entry !== undefined)
Expand Down
Loading

0 comments on commit d686768

Please sign in to comment.