Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#prettier config
.prettierrc

# Logs
logs
*.log
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "packages/rendure"]
path = packages/rendure
url = git@github.com:spcl/rendure.git
20 changes: 18 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ <h3 id="sidebar-header">
Load Memory Footprint File
</button>
</div>
<div class="col-auto">
<input
type="file"
accept=".json"
id="allocation-report-file-input"
style="display: none"
/>
<button
id="load-allocation-report-btn"
class="btn btn-sm btn-light"
disabled="disabled"
onclick="document.getElementById('allocation-report-file-input').click();"
>
Load Allocation Report
</button>
</div>
<div class="col-auto" id="diff-view-btn-container">
<input type="file"
accept=".sdfg,.json,.sdfgz,.sdfg.gz"
Expand Down Expand Up @@ -114,7 +130,7 @@ <h3 id="sidebar-header">
<textarea id="advsearch" style="font-family: monospace"
class="form-control mb-2">(graph, element) => {
// Create a predicate that returns true for a match
// For example, finding transient arrays below
// For example, finding transient arrays below
if (element && element.data.node) {
let arrname = element.data.node.attributes.data;
if (arrname) {
Expand Down Expand Up @@ -148,4 +164,4 @@ <h3 id="sidebar-header">
</div>
</body>

</html>
</html>
1 change: 1 addition & 0 deletions packages/rendure
Submodule rendure added at 336512
165 changes: 165 additions & 0 deletions src/overlays/allocation_overlay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import {
SDFGNode,
SDFGElement,
Edge,
ControlFlowBlock,
} from '../renderer/sdfg/sdfg_elements';
import { SDFGRenderer } from '../renderer/sdfg/sdfg_renderer';
import $ from 'jquery';
import { OverlayType } from '../types';
import { GenericSdfgOverlay } from './common/generic_sdfg_overlay';
import { KELLY_COLORS } from 'rendure/dist/utils/colors';

export class AllocationOverlay extends GenericSdfgOverlay {

public static readonly type: OverlayType = OverlayType.NODE;
public readonly olClass: typeof GenericSdfgOverlay = AllocationOverlay;

private AllocationMap: Record<string, string[]> = {};
private AllocationMapReversed: Record<string, string[]> = {};
private FocusedNodes: string[] = [];

//maps from AccessNodes uid to coloring in overlay
private colorMap: Record<string, number> = {};

public constructor(renderer: SDFGRenderer) {
super(renderer);

this.refresh();
}

public refresh(): void {
this.renderer.drawAsync();
}

public setAllocationMap(map: Record<string, string[]>) {
this.AllocationMap = map;
this.AllocationMapReversed = {};
for (const [dataContainer, nodes] of Object.entries(map)) {
for (const node of nodes) {
if (!Object.keys(this.AllocationMapReversed).includes(node))
this.AllocationMapReversed[node] = [];
this.AllocationMapReversed[node].push(dataContainer)
}
}
}

private createLegendItem(
color: string,
label: string,
OnRemove: (id: string) => void
) {
const item = $('<div>', {
class: 'legend-item',
css: {
'display': 'flex',
'align-items': 'center',
}
});

$('<span>', {
class: 'legend-circle',
css: {
'width': '16px',
'height': '16px',
'border-radius': '50%',
'background-color': color,
}
}).appendTo(item);

$('<span>', {
class: 'legend-label',
text: label
}).appendTo(item);

$('<button>', {
text: 'x',
css: {
'cursor': 'pointer',
'border': 'none',
'border-radius': '4px',
'font-size': '16px'
},
click: function () {
item.remove();
OnRemove(label)
}
}).appendTo(item)
return item;
}

public setFocusedNode(node: any) {
if (typeof node === 'string' && !this.FocusedNodes.includes(node)) {
// add node to allocation legend
if(this.renderer.ui?.allocationLegend !== undefined) {
this.createLegendItem(
'#' + KELLY_COLORS[this.FocusedNodes.length].toString(16),
node,
(id) => {
const index = this.FocusedNodes.indexOf(id);
if(index > -1)
this.FocusedNodes.splice(index, 1);
this.refresh()
}
).appendTo(this.renderer.ui.allocationLegend)
}
this.FocusedNodes.push(node);

this.refresh();
}
}

public hasKey(node: any) {
return typeof node === 'string' &&
Object.keys(this.AllocationMap).includes(node);
}



public shadeElem(elem: SDFGElement): void {
if (
Object.keys(this.AllocationMapReversed).includes(elem.guid) &&
this.AllocationMapReversed[elem.guid].filter(
dc => this.FocusedNodes.includes(dc)
).length >= 2 &&
this.AllocationMapReversed[elem.guid].length > 1
) {
elem.shade('#FF0000');
} else {
for (const [index, dataContainer] of this.FocusedNodes.entries()) {
const color = KELLY_COLORS[index];
if (elem.guid === dataContainer) {
const factor = 0.6;
const darkerColor =
(
(((color >> 16) & 0xFF) * factor) << 16 |
(((color >> 8) & 0xFF) * factor) << 8 |
((color & 0xFF) * factor)
) >>> 0;
elem.shade('#' + darkerColor.toString(16));
} else if (
Object.keys(this.AllocationMap).includes(dataContainer)
) {
if (this.AllocationMap[dataContainer].includes(elem.guid))
elem.shade('#' + KELLY_COLORS[index].toString(16));
}
}
}
}

protected shadeBlock(block: ControlFlowBlock, ..._args: any[]): void {
this.shadeElem(block);
}

protected shadeNode(node: SDFGNode, ..._args: any[]): void {
this.shadeElem(node);
}

protected shadeEdge(edge: Edge, ..._args: any[]): void {
this.shadeElem(edge);
}

public draw(): void {
this.shadeSDFG();
}
}
20 changes: 19 additions & 1 deletion src/renderer/sdfg/sdfg_renderer_ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import { MemoryVolumeOverlay } from '../../overlays/memory_volume_overlay';
import { cfgToDotGraph } from '../../utils/sdfg/dotgraph';
import { ModeButtons } from '../../types';
import { SDFGElementType } from './sdfg_elements';
import { AllocationOverlay } from '../../overlays/allocation_overlay';
import { Position } from 'monaco-editor';


export type SDFGRendererUIFeature = (
'settings' | 'overlaysMenu' | 'collapse' | 'expand' | 'addMode' |
'panMode' | 'moveMode' | 'boxSelectMode' | 'cutoutSelection' | 'localView'
'panMode' | 'moveMode' | 'boxSelectMode' | 'cutoutSelection' |
'localView' | 'allocationLegend' //does this make sense? QUESTION
) | RendererUIFeature;

export class SDFGRendererUI extends RendererUI {
Expand All @@ -32,6 +35,7 @@ export class SDFGRendererUI extends RendererUI {
public readonly panModeBtn?: JQuery<HTMLButtonElement>;
public readonly moveModeBtn?: JQuery<HTMLButtonElement>;
public readonly addModeButtons: JQuery<HTMLButtonElement>[] = [];
public allocationLegend?: JQuery<HTMLDivElement>;
private modeBtnSelectedBGColor: string = '#CCCCCC';

public constructor(
Expand All @@ -56,6 +60,7 @@ export class SDFGRendererUI extends RendererUI {
boxSelectMode: true,
cutoutSelection: true,
localView: true,
allocationLegend: true,
}
) {
_featuresMask.minimap = SDFVSettings.get<boolean>('minimap');
Expand Down Expand Up @@ -398,6 +403,19 @@ export class SDFGRendererUI extends RendererUI {
}).appendTo(this.toolbar) as JQuery<HTMLButtonElement>;
}

// Allocation overlay legend
if (this._featuresMask.allocationLegend) {
this.allocationLegend = $('<div>', {
id: 'allocation-legend',
css: {
'display': 'flex',
'flex-direction': 'column',
'position': 'absolute',
'bottom': '10px',
'left': '10px'
},
}).appendTo(this.container) as JQuery<HTMLDivElement>;
}
// Exit previewing mode.
if (this.renderer.inVSCode) {
const exitPreviewBtn = $('<button>', {
Expand Down
44 changes: 41 additions & 3 deletions src/sdfv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,32 @@ import type { LViewRenderer } from './local_view/lview_renderer';
import {
RuntimeMicroSecondsOverlay,
} from './overlays/runtime_micro_seconds_overlay';
import type { SDFGRenderer } from './renderer/sdfg/sdfg_renderer';
import type { ISDFVUserInterface } from './sdfv_ui';
import { doForAllJsonSDFGElements } from './utils/sdfg/traversal';
import { OverlayManager } from './overlay_manager';
import { DagreGraph, SDFGRenderer } from './renderer/sdfg/sdfg_renderer';
import {
ConditionalBlock,
SDFG,
SDFGElement,
State,
} from './renderer/sdfg/sdfg_elements';
import { htmlSanitize } from './utils/sanitization';
import {
checkCompatLoad,
checkCompatSave,
parseSDFG,
stringifySDFG,
} from './utils/sdfg/json_serializer';
import { SDFVSettings } from './utils/sdfv_settings';
import { DiffMap } from './sdfg_diff_viewer';
import { ISDFVUserInterface } from './sdfv_ui';
import { GenericSdfgOverlay } from './overlays/common/generic_sdfg_overlay';
import { JsonSDFG, ModeButtons } from './types';
import {
doForAllJsonSDFGElements,
traverseSDFGScopes,
} from './utils/sdfg/traversal';
import { showErrorModal } from './utils/utils';
import { AllocationOverlay } from './overlays/allocation_overlay';


export interface ISDFV {
Expand Down Expand Up @@ -121,6 +144,21 @@ export abstract class SDFV extends EventEmitter implements ISDFV {
renderer.drawAsync();
}

public onLoadedAllocationReport(
report: Record<string, string[]>,
renderer?: SDFGRenderer,
): void {
renderer = this.renderer;
if (!renderer?.overlayManager.isOverlayActive(AllocationOverlay))
renderer?.overlayManager.registerOverlay(AllocationOverlay);

const ol = renderer?.overlayManager.getOverlay(AllocationOverlay);
if (ol && ol instanceof AllocationOverlay) {
ol.setAllocationMap(report);
ol.refresh();
}
}

public abstract outline(): void;

public setRenderer(renderer?: SDFGRenderer): void {
Expand Down
2 changes: 2 additions & 0 deletions src/sdfv_ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import type { SDFGElement } from './renderer/sdfg/sdfg_elements';
import type { DagreGraph, SDFGRenderer } from './renderer/sdfg/sdfg_renderer';
import { JsonSDFG, JsonSDFGDataDesc } from './types';
import { AllocationOverlay } from './overlays/allocation_overlay';


export interface ISDFVUserInterface {
Expand Down
Loading