Skip to content

Commit

Permalink
Improved Settings and Styling Fixes (#260)
Browse files Browse the repository at this point in the history
* Make the SDFV settings more robust

* CSS improvements

* Drop material icons in favor of material symbols

* Cleanup

* Various bugfixes

* Update metadata

* Address review comments

* Add doc comment
  • Loading branch information
phschaad authored Jun 11, 2024
1 parent da32ff7 commit 42fb884
Show file tree
Hide file tree
Showing 29 changed files with 5,110 additions and 1,788 deletions.
231 changes: 118 additions & 113 deletions backend/dace_vscode/transformations.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Copyright 2020-2024 ETH Zurich and the DaCe-VSCode authors.
# All rights reserved.

from dace import nodes, serialize
from dace import nodes, serialize, config as dc_config
from dace.transformation.transformation import (SubgraphTransformation,
PatternTransformation)
from dace.transformation.pass_pipeline import Pass, Pipeline
from dace.version import __version__ as DACE_VERSION
from dace_vscode import utils
import sys
import traceback
Expand Down Expand Up @@ -42,7 +41,7 @@ def expand_library_node(json_in):
if cfg_id is None:
sdfg.expand_library_nodes()
else:
if DACE_VERSION >= '0.16.0':
if hasattr(sdfg, 'cfg_list'):
context_sdfg = sdfg.cfg_list[cfg_id]
else:
context_sdfg = sdfg.sdfg_list[cfg_id]
Expand Down Expand Up @@ -99,7 +98,7 @@ def reapply_history_until(sdfg_json, index):
try:
transformation = history[i]

if DACE_VERSION >= '0.16.0':
if hasattr(transformation, 'cfg_id'):
target_cfg = original_sdfg.cfg_list[transformation.cfg_id]
transformation._sdfg = (
target_cfg
Expand Down Expand Up @@ -182,7 +181,7 @@ def apply_transformations(sdfg_json, transformation_json_list):
}
try:
if isinstance(transformation, PatternTransformation):
if DACE_VERSION >= '0.16.0':
if hasattr(transformation, 'cfg_id'):
target_cfg = sdfg.cfg_list[transformation.cfg_id]
transformation._sdfg = (
target_cfg.sdfg
Expand Down Expand Up @@ -261,116 +260,122 @@ def get_transformations(sdfg_json, selected_elements, permissive):
return loaded['error']
sdfg = loaded['sdfg']

try:
optimizer = SDFGOptimizer(sdfg)
try:
matches = optimizer.get_pattern_matches(permissive=permissive)
except TypeError:
# Compatibility with versions older than 0.12
matches = optimizer.get_pattern_matches(strict=not permissive)

transformations = []
docstrings = {}
for transformation in matches:
transformations.append(transformation.to_json())
docstrings[type(transformation).__name__] = transformation.__doc__

# Obtain available passes.
with dc_config.set_temporary('testing',
'serialize_all_fields',
value=True):
try:
all_passes = passes.available_passes(False)
for ps in all_passes:
if ps.CATEGORY == 'Helper' or ps.CATEGORY == 'Analysis':
continue
docstrings[ps.__name__] = ps.__doc__
pass_instance = ps()
transformations.append(pass_instance.to_json())
except (NameError, AttributeError):
# Compatibility with legacy versions where no method for getting
# available passes exists.
pass

selected_states = [
utils.sdfg_find_state_from_element(sdfg, n)
for n in selected_elements
if n['type'] == 'state'
]
selected_nodes = [
utils.sdfg_find_node_from_element(sdfg, n)
for n in selected_elements
if n['type'] == 'node'
]
selected_cfg_ids = list(
set(elem['cfgId'] for elem in selected_elements)
)
selected_sdfg = sdfg
if len(selected_cfg_ids) > 1:
optimizer = SDFGOptimizer(sdfg)
try:
matches = optimizer.get_pattern_matches(permissive=permissive)
except TypeError:
# Compatibility with versions older than 0.12
matches = optimizer.get_pattern_matches(strict=not permissive)

transformations = []
docstrings = {}
for transformation in matches:
transformations.append(transformation.to_json())
docstrings[type(transformation).__name__] = \
transformation.__doc__

# Obtain available passes.
try:
all_passes = passes.available_passes(False)
for ps in all_passes:
if ps.CATEGORY == 'Helper' or ps.CATEGORY == 'Analysis':
continue
docstrings[ps.__name__] = ps.__doc__
pass_instance = ps()
transformations.append(pass_instance.to_json())
except (NameError, AttributeError):
# Compatibility with legacy versions where no method for getting
# available passes exists.
pass

selected_states = [
utils.sdfg_find_state_from_element(sdfg, n)
for n in selected_elements
if n['type'] == 'state'
]
selected_nodes = [
utils.sdfg_find_node_from_element(sdfg, n)
for n in selected_elements
if n['type'] == 'node'
]
selected_cfg_ids = list(
set(elem['cfgId'] for elem in selected_elements)
)
selected_sdfg = sdfg
if len(selected_cfg_ids) > 1:
return {
'transformations': transformations,
'docstrings': docstrings,
'warnings': 'More than one CFG selected, ignoring subgraph',
}
elif len(selected_cfg_ids) == 1:
if hasattr(sdfg, 'cfg_list'):
selected_sdfg = sdfg.cfg_list[selected_cfg_ids[0]]
else:
selected_sdfg = sdfg.sdfg_list[selected_cfg_ids[0]]

subgraph = None
if len(selected_states) > 0:
subgraph = SubgraphView(selected_sdfg, selected_states)
else:
violated = False
state = None
for node in selected_nodes:
if state is None:
state = node.state
elif state != node.state:
violated = True
break
if not violated and state is not None:
subgraph = SubgraphView(state, selected_nodes)

if subgraph is not None:
if hasattr(SubgraphTransformation, 'extensions'):
# Compatibility with versions older than 0.12
extensions = SubgraphTransformation.extensions()
else:
extensions = SubgraphTransformation.subclasses_recursive()

for xform in extensions:
# Subgraph transformations are single-state.
if len(selected_states) > 0:
continue
xform_obj = None
try:
xform_obj = xform()
xform_obj.setup_match(subgraph)
except:
# If the above method throws an exception, it might be
# because an older version of dace (<= 0.13.1) is being
# used - attempt to construct subgraph transformations
# using the old API.
xform_obj = xform(subgraph)
try:
if xform_obj.can_be_applied(selected_sdfg, subgraph):
transformations.append(xform_obj.to_json())
docstrings[xform.__name__] = xform_obj.__doc__
except Exception as can_be_applied_exception:
# If something fails here, that is most likely due to a
# transformation bug. Fail gracefully.
print('Warning: ' + xform.__name__ +
' caused an exception')
print(can_be_applied_exception)
print('Most likely a transformation bug, ignoring...')

utils.restore_save_metadata(old_meta)
return {
'transformations': transformations,
'docstrings': docstrings,
'warnings': 'More than one CFG selected, ignoring subgraph',
}
elif len(selected_cfg_ids) == 1:
if DACE_VERSION >= '0.16.0':
selected_sdfg = sdfg.cfg_list[selected_cfg_ids[0]]
else:
selected_sdfg = sdfg.sdfg_list[selected_cfg_ids[0]]

subgraph = None
if len(selected_states) > 0:
subgraph = SubgraphView(selected_sdfg, selected_states)
else:
violated = False
state = None
for node in selected_nodes:
if state is None:
state = node.state
elif state != node.state:
violated = True
break
if not violated and state is not None:
subgraph = SubgraphView(state, selected_nodes)

if subgraph is not None:
if hasattr(SubgraphTransformation, 'extensions'):
# Compatibility with versions older than 0.12
extensions = SubgraphTransformation.extensions()
else:
extensions = SubgraphTransformation.subclasses_recursive()

for xform in extensions:
# Subgraph transformations are single-state.
if len(selected_states) > 0:
continue
xform_obj = None
try:
xform_obj = xform()
xform_obj.setup_match(subgraph)
except:
# If the above method throws an exception, it might be because
# an older version of dace (<= 0.13.1) is being used - attempt
# to construct subgraph transformations using the old API.
xform_obj = xform(subgraph)
try:
if xform_obj.can_be_applied(selected_sdfg, subgraph):
transformations.append(xform_obj.to_json())
docstrings[xform.__name__] = xform_obj.__doc__
except Exception as can_be_applied_exception:
# If something fails here, that is most likely due to a
# transformation bug. Fail gracefully.
print('Warning: ' + xform.__name__ + ' caused an exception')
print(can_be_applied_exception)
print('Most likely a transformation bug, ignoring...')

utils.restore_save_metadata(old_meta)
return {
'transformations': transformations,
'docstrings': docstrings,
}
except Exception as e:
traceback.print_exc()
return {
'error': {
'message': 'Failed to load transformations',
'details': utils.get_exception_message(e),
},
}
except Exception as e:
traceback.print_exc()
return {
'error': {
'message': 'Failed to load transformations',
'details': utils.get_exception_message(e),
},
}
5 changes: 2 additions & 3 deletions backend/dace_vscode/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import traceback

from dace import SDFG, serialize
from dace.version import __version__ as DACE_VERSION

UUID_SEPARATOR = '/'

Expand All @@ -20,7 +19,7 @@ def ids_to_string(cfg_id, state_id=-1, node_id=-1, edge_id=-1):


def sdfg_find_state_from_element(sdfg, element):
if DACE_VERSION >= '0.16.0':
if hasattr(sdfg, 'cfg_list'):
graph = sdfg.cfg_list[element['cfgId']]
else:
graph = sdfg.sdfg_list[element['cfgId']]
Expand All @@ -32,7 +31,7 @@ def sdfg_find_state_from_element(sdfg, element):


def sdfg_find_node_from_element(sdfg, element):
if DACE_VERSION >= '0.16.0':
if hasattr(sdfg, 'cfg_list'):
graph = sdfg.cfg_list[element['cfgId']]
else:
graph = sdfg.sdfg_list[element['cfgId']]
Expand Down
5 changes: 5 additions & 0 deletions backend/run_dace.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
# Then, load the rest of the modules
import aenum
import dace
from dace.version import __version__ as DACE_VERSION

sys.path.append(path.abspath(path.dirname(__file__)))

Expand Down Expand Up @@ -372,6 +373,10 @@ def run_daemon(port):
def _root():
return 'success!'

@daemon.route('/version', methods=['GET'])
def _version():
return str(DACE_VERSION)

@daemon.route('/transformations', methods=['POST'])
def _get_transformations():
request_json = request.get_json()
Expand Down
4 changes: 2 additions & 2 deletions media/components/analysis/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<span style="display:inline-block; vertical-align: middle; line-height: normal;">
Number of histogram buckets:
</span>
<span class="material-icons-outlined"
<span class="material-symbols-outlined"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="Setting to 0 sets the number of buckets to the number of distinct values"
Expand Down Expand Up @@ -190,7 +190,7 @@
</span>
<table id="symbol-table">
</table>
<div id="specialize-btn" class="btn btn-primary">
<div id="specialize-btn" class="btn btn-primary btn-sm">
Specialize SDFG
</div>
</div>
Expand Down
7 changes: 6 additions & 1 deletion media/components/dace/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@
<body>
<div id="contents" class="container-fluid">
<div class="row mb-2">
<div class="col-12">
<div class="col-auto">
<span>
Status:&nbsp;<span id="status-text" class="not-connected">
Not connected
</span>
</span>
</div>
<div class="col-auto">
<span>
DaCe Version:&nbsp;<span id="version-text">N/A</span>
</span>
</div>
</div>
<div class="row mb-2">
<div class="col-12">
Expand Down
Loading

0 comments on commit 42fb884

Please sign in to comment.