spcl / spcl/dace

Restoration of Symbolic Properties

Open
#1,946 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
593
Forks
163
Avg merge
2d 23h
Merged PRs (30d)
60

Description

Restoration of symbolic, i.e. restoration from file/json, property essentially works by relying on `pystr_to_symbolic()` with `simplify` set to `False`.
See `dace/properties.py:1150`:
```python
@staticmethod
def from_string(s):
return pystr_to_symbolic(s, simplify=False)

@staticmethod
def to_string(obj):
# Go through sympy once to reorder factors
return str(pystr_to_symbolic(str(obj), simplify=False))
```
The idea of setting `simplify` to `False` is that the content of the symbol does not change.
However it seems that this is not the case, at least for certain expressions, which sometimes change.
This has sever implication, for example storing an SDFG to disc and restoring it right away will alter the SDFG's hash.

The issue is that expressions of the form `-(a + b) * c` are transformed into `(b - a) * c`, i.e. the minus is moved into the first parentheses, as far as I can tell during restoration, by looking at the content of `serialized_a`.
In my specific case it happens to the expression `-(10*__coarse_i_K_gtx_vertical + vertical_start - Min(vertical_end, 10*__coarse_i_K_gtx_vertical + vertical_start + 10))*(4*Max(283876, horizontal_end) - 4*Min(0, horizontal_start) + 1)`.
This is an expression I found inside a Memlet, to be precise inside the `volume` expression.
In the reproducer below, it is important that `simplify()` is called on the final expression, without it would not have worked.
Note that the Memlet propagation uses `simplify()` during the calculation of the volume.

I wrote this reproducer:
```python
import dace
@dace.properties.make_properties
class Test:
sym = dace.properties.SymbolicProperty(default=0)

def __init__(self, sym):
self.sym = sym

p1 = dace.symbolic.pystr_to_symbolic("10*__coarse_i_K_gtx_vertical + vertical_start")
p2 = dace.symbolic.pystr_to_symbolic("Min(vertical_end, 10*__coarse_i_K_gtx_vertical + vertical_start + 10)")
p3 = dace.symbolic.pystr_to_symbolic("(4*Max(283876, horizontal_end) - 4*Min(0, horizontal_start) + 1)")
# Without `simplify()` it will not work!
pp = dace.symbolic.simplify((p2 - p1 ) * p3)

original_a = Test(pp)
serialized_a = dace.serialize.all_properties_to_json(original_a)
restored_a = Test(0)
dace.serialize.set_properties_from_json(restored_a, serialized_a)

assert str(original_a.sym) == str(restored_a.sym), f"`sym` has chnaged from '{str(original_a.sym)}' to '{str(restored_a.sym)}'"
```

Contributor guide

Open the contributing guide

Research direction

Start by running the reproducer and inspect dace/properties.py:1150, especially the from_string and to_string paths using pystr_to_symbolic(). Compare the original and restored symbolic expressions, then verify that serialization and restoration preserve the expression text and SDFG hash without changing the symbolic form.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.