Skip to content

Commit

Permalink
SDFV: Support inclusive range display
Browse files Browse the repository at this point in the history
  • Loading branch information
tbennun committed Mar 23, 2020
1 parent 57d3640 commit 5c7fdce
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 45 deletions.
25 changes: 23 additions & 2 deletions diode/webclient/context_menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ class ContextMenu {
});
}

addCheckableOption(name, checked, onselect, onhover=null) {
this._options.push({
name: name,
checkbox: true,
checked: checked,
func: onselect,
onhover: onhover
});
}

destroy() {
if (!this._cmenu_elem)
return;
Expand Down Expand Up @@ -79,10 +89,21 @@ class ContextMenu {
elem.addEventListener('click', x.func);
elem.classList.add("context_menu_option");

elem.innerText = x.name;
if (x.checkbox) {
let markelem = document.createElement('span');
markelem.classList = x.checked ? 'checkmark_checked' : 'checkmark';
elem.appendChild(markelem);
elem.innerHTML += x.name;
elem.addEventListener('click', elem => {
x.checked = !x.checked;
x.func(elem, x.checked);
});
} else {
elem.innerText = x.name;
elem.addEventListener('click', x.func);
}
cmenu_div.appendChild(elem);
}

}
else {
cmenu_div.innerHTML = this._html_content;
Expand Down
10 changes: 9 additions & 1 deletion diode/webclient/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,9 @@ class SDFGRenderer {
this.tooltip = null;
this.tooltip_container = null;

// View options
this.inclusive_ranges = false;

// Mouse-related fields
this.mousepos = null; // Last position of the mouse pointer (in canvas coordinates)
this.realmousepos = null; // Last position of the mouse pointer (in pixel coordinates)
Expand All @@ -693,6 +696,10 @@ class SDFGRenderer {
}
}

view_settings() {
return {inclusive_ranges: this.inclusive_ranges};
}

// Initializes the DOM
init_elements() {

Expand Down Expand Up @@ -721,8 +728,9 @@ class SDFGRenderer {
cmenu.addOption("Save view as PNG", x => that.save_as_png());
cmenu.addOption("Save view as PDF", x => that.save_as_pdf());
cmenu.addOption("Save all as PDF", x => that.save_as_pdf(true));
cmenu.addCheckableOption("Inclusive ranges", that.inclusive_ranges, (x, checked) => {that.inclusive_ranges = checked;});
that.menu = cmenu;
cmenu.show(rect.left, rect.bottom);
that.menu.show(rect.left, rect.bottom);
};
d.title = 'Menu';
this.toolbar.appendChild(d);
Expand Down
66 changes: 49 additions & 17 deletions diode/webclient/renderer_elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class Edge extends SDFGElement {

let style = this.strokeStyle();
if (style !== 'black')
renderer.tooltip = (c) => this.tooltip(c);
renderer.tooltip = (c) => this.tooltip(c, renderer);
if (this.parent_id == null && style === 'black') { // Interstate edge
style = 'blue';
}
Expand All @@ -224,7 +224,8 @@ class Edge extends SDFGElement {
ctx.strokeStyle = "black";
}

tooltip(container) {
tooltip(container, renderer) {
let dsettings = renderer.view_settings();
let attr = this.attributes();
// Memlet
if (attr.subset !== undefined) {
Expand All @@ -233,15 +234,15 @@ class Edge extends SDFGElement {
return;
}
let contents = attr.data;
contents += sdfg_property_to_string(attr.subset);
contents += sdfg_property_to_string(attr.subset, dsettings);

if (attr.other_subset)
contents += ' -> ' + sdfg_property_to_string(attr.other_subset);
contents += ' -> ' + sdfg_property_to_string(attr.other_subset, dsettings);

if (attr.wcr)
contents += '<br /><b>CR: ' + sdfg_property_to_string(attr.wcr) +'</b>';
contents += '<br /><b>CR: ' + sdfg_property_to_string(attr.wcr, dsettings) +'</b>';

let num_accesses = sdfg_property_to_string(attr.num_accesses);
let num_accesses = sdfg_property_to_string(attr.num_accesses, dsettings);
if (num_accesses == -1)
num_accesses = "<b>Dynamic</b>";

Expand Down Expand Up @@ -324,13 +325,13 @@ class AccessNode extends Node {

let nodedesc = this.sdfg.attributes._arrays[this.data.node.attributes.data];
// Streams have dashed edges
if (nodedesc.type === "Stream") {
if (nodedesc && nodedesc.type === "Stream") {
ctx.setLineDash([5, 3]);
} else {
ctx.setLineDash([1, 0]);
}

if (nodedesc.attributes.transient === false) {
if (nodedesc && nodedesc.attributes.transient === false) {
ctx.lineWidth = 3.0;
} else {
ctx.lineWidth = 1.0;
Expand Down Expand Up @@ -378,23 +379,54 @@ class ScopeNode extends Node {
ctx.fill();
ctx.fillStyle = "black";

let far_label = this.attributes().label;
let far_label = this.far_label();
drawAdaptiveText(ctx, renderer, far_label,
this.close_label(renderer), this.x, this.y,
this.width, this.height,
SCOPE_LOD);
}

far_label() {
let result = this.attributes().label;
if (this.scopeend()) { // Get label from scope entry
let entry = this.sdfg.nodes[this.parent_id].nodes[this.data.node.scope_entry];
if (entry !== undefined)
far_label = entry.attributes.label;
result = entry.attributes.label;
else {
far_label = this.label();
let ind = far_label.indexOf('[');
result = this.data.node.label;
let ind = result.indexOf('[');
if (ind > 0)
far_label = far_label.substring(0, ind);
result = result.substring(0, ind);
}
}
return result;
}

drawAdaptiveText(ctx, renderer, far_label,
this.label(), this.x, this.y,
this.width, this.height,
SCOPE_LOD);
close_label(renderer) {
if (!renderer.inclusive_ranges)
return this.label();

let result = this.far_label();
let attrs = this.attributes();
if (this.scopeend()) {
let entry = this.sdfg.nodes[this.parent_id].nodes[this.data.node.scope_entry];
if (entry !== undefined)
attrs = entry.attributes;
else
return this.label();
}
result += ' [';

if (this instanceof ConsumeEntry || this instanceof ConsumeExit) {
result += attrs.pe_index + '=' + '0..' + (attrs.num_pes - 1).toString();
} else {
for (let i = 0; i < attrs.params.length; ++i) {
result += attrs.params[i] + '=';
result += sdfg_range_elem_to_string(attrs.range.ranges[i], renderer.view_settings()) + ', ';
}
result = result.substring(0, result.length-2); // Remove trailing comma
}
return result + ']';
}
}

Expand Down
56 changes: 33 additions & 23 deletions diode/webclient/sdfg_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,43 @@ function stringify_sdfg(sdfg) {
return JSON.stringify(sdfg, (name, val) => replacer(name, val, sdfg));
}

function sdfg_range_elem_to_string(range, settings=null) {
let preview = '';
if (range.start == range.end && range.step == 1 && range.tile == 1)
preview += sdfg_property_to_string(range.start, settings);
else {
if (settings && settings.inclusive_ranges) {
preview += sdfg_property_to_string(range.start, settings) + '..' +
sdfg_property_to_string(range.end, settings);
} else {
let endp1 = sdfg_property_to_string(range.end, settings) + ' + 1';
// Try to simplify using math.js
try {
endp1 = math.simplify(endp1).toString();
} catch(e) {}

preview += sdfg_property_to_string(range.start, settings) + ':' +
endp1;
}
if (range.step != 1) {
preview += ':' + sdfg_property_to_string(range.step, settings);
if (range.tile != 1)
preview += ':' + sdfg_property_to_string(range.tile, settings);
} else if (range.tile != 1) {
preview += '::' + sdfg_property_to_string(range.tile, settings);
}
}
return preview;
}

// Includes various properties and returns their string representation
function sdfg_property_to_string(prop) {
function sdfg_property_to_string(prop, settings=null) {
if (prop === null) return prop;
if (prop.type === "Indices" || prop.type === "subsets.Indices") {
let indices = prop.indices;
let preview = '[';
for (let index of indices) {
preview += sdfg_property_to_string(index) + ', ';
preview += sdfg_property_to_string(index, settings) + ', ';
}
return preview.slice(0, -2) + ']';
} else if (prop.type === "Range" || prop.type === "subsets.Range") {
Expand All @@ -77,26 +106,7 @@ function sdfg_property_to_string(prop) {
// Generate string from range
let preview = '[';
for (let range of ranges) {
if (range.start == range.end && range.step == 1 && range.tile == 1)
preview += sdfg_property_to_string(range.start);
else {
let endp1 = sdfg_property_to_string(range.end) + ' + 1';
// Try to simplify using math.js
try {
endp1 = math.simplify(endp1).toString();
} catch(e) {}

preview += sdfg_property_to_string(range.start) + ':' +
endp1;
if (range.step != 1) {
preview += ':' + sdfg_property_to_string(range.step);
if (range.tile != 1)
preview += ':' + sdfg_property_to_string(range.tile);
} else if (range.tile != 1) {
preview += '::' + sdfg_property_to_string(range.tile);
}
}
preview += ', ';
preview += sdfg_range_elem_to_string(range, settings) + ', ';
}
return preview.slice(0, -2) + ']';
} else if (prop.language !== undefined && prop.string_data !== undefined) {
Expand All @@ -115,7 +125,7 @@ function sdfg_property_to_string(prop) {
for (let subprop of prop) {
if (!first)
result += ', ';
result += sdfg_property_to_string(subprop);
result += sdfg_property_to_string(subprop, settings);
first = false;
}
return result + ' ]';
Expand Down
58 changes: 58 additions & 0 deletions diode/webclient/sdfv.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin
position: absolute;
background-color: #fdfdfd;
box-shadow: 0 4px 5px 3px rgba(0, 0, 0, 0.2);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

.context_menu_option {
Expand All @@ -50,14 +54,68 @@ h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin
background: rgba(0, 0, 0, 0.1);
}

.context_menu_option input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}

.tooltip {
background: rgba(0, 0, 0, 0.8);
color: white;
font-size: 16px;
font-family: "Segoe UI", Arial, sans-serif;
padding: 2px 5px 2px 5px;
border-radius: 4px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: absolute;
display: none;
}

/* Checkmarks for context menu items */
.checkmark {
position: absolute;
right: 5px;
height: 20px;
width: 20px;
background-color: #eee;
}

.checkmark_checked {
position: absolute;
right: 5px;
height: 20px;
width: 20px;
background-color: #2196F3;
}

.context_menu_option:hover .checkmark {
background-color: #ccc;
}

.checkmark:after {
content: "";
position: absolute;
display: none;
}

.context_menu_option .checkmark_checked:after {
content: "";
position: absolute;
display: block;
left: 6px;
top: 2px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}

4 changes: 2 additions & 2 deletions diode/webclient/sdfv.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ function mouse_event(evtype, event, mousepos, elements, renderer, elem) {
for (let attr of Object.entries(elem.attributes())) {
if (attr[0] === "layout" || attr[0] === "sdfg" || attr[0].startsWith("_meta_")) continue;
html += "<b>" + attr[0] + "</b>:&nbsp;&nbsp;";
html += sdfg_property_to_string(attr[1], attr[0]) + "</p>";
html += sdfg_property_to_string(attr[1], renderer.view_settings()) + "</p>";
}

// If access node, add array information too
Expand All @@ -170,7 +170,7 @@ function mouse_event(evtype, event, mousepos, elements, renderer, elem) {
for (let attr of Object.entries(sdfg_array.attributes)) {
if (attr[0] === "layout" || attr[0] === "sdfg" || attr[0].startsWith("_meta_")) continue;
html += "<b>" + attr[0] + "</b>:&nbsp;&nbsp;";
html += sdfg_property_to_string(attr[1], attr[0]) + "</p>";
html += sdfg_property_to_string(attr[1], renderer.view_settings()) + "</p>";
}
}

Expand Down

0 comments on commit 5c7fdce

Please sign in to comment.