-
Notifications
You must be signed in to change notification settings - Fork 57
fix[next]: Deterministic dace auto optimize #2568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b4d6cba
1f39ce5
f303b26
3965eec
565113f
4da9a84
4e6444e
bbefa5c
0d46651
c273a12
9f1b724
3937fde
1d047df
d8f2efd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| # Debugging indeterministic behavior of dace transformations | ||
|
|
||
| - Enable printing each transformation step, e.g. using | ||
| ``` | ||
| dace.Config.set("progress", value=True) | ||
| ``` | ||
| TODO: introduce new config var that prints the hash instead of hard-coding it. | ||
| - Execute the program in question twice and compare the output. | ||
| - Set a conditonal breakpoint in beginning of the `apply` method of the first pass where the SDFG | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| hash changes with condition `sdfg.hash_sdfg() == <last equal hash>`. | ||
| Note: In case running the previous passes takes a long time it makes sense to serialize the SDFG | ||
| to json (`sdfg.to_json("sdfg(1|2).json")`) and loading it again (see debug script below) to | ||
| ease debugging. In rare cases the serializing and deserializing the sdfg changes the hash. In such | ||
| cases this trick doesn't work and the first location where the hash changes might not be the exact | ||
| location where the indeterministic behavior is. It helps to use a different hash, e.g. | ||
| `content_hash`, but this should be solved in general. | ||
| Note: It makes sense to also place a breakpoint after `DaceTranslator.generate_sdfg` to recognize | ||
| when all executions finished. | ||
| - When the location is found it is usually easy to spot the origin of the indeterminism. Often | ||
| there is a set operation or a symbol is named in an indeterministic way. Use ordered sets and | ||
| deterministic symbol names. | ||
|
|
||
| ## Appendix | ||
|
|
||
| __Debugging sdfg autooptimize__ | ||
|
|
||
| Usage `python debug_auto_optimize_sdfg.py sdfg1.json` | ||
|
|
||
| ```python | ||
| import pickle | ||
| import sys | ||
|
|
||
| import dace | ||
| import json | ||
|
|
||
| from dace import SDFG | ||
|
|
||
| from gt4py.next.program_processors.runners.dace import ( | ||
| lowering as gtx_dace_lowering, | ||
| sdfg_args as gtx_dace_args, | ||
| transformations as gtx_transformations, | ||
| ) | ||
| from dace.utils import print_sdfg_hash | ||
|
|
||
| file = sys.argv[1] | ||
|
|
||
| with open(file) as f: | ||
| data = json.load(f) | ||
| sdfg = dace.SDFG.from_json(data) | ||
| print_sdfg_hash(sdfg) | ||
|
Comment on lines
+47
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is also |
||
|
|
||
| gtx_transformations.gt_auto_optimize( | ||
| sdfg, | ||
| gpu=False, | ||
| constant_symbols={}, | ||
| unit_strides_kind=None, | ||
| ) | ||
| ``` | ||
|
|
||
| __Debugging single sdfg transform__ | ||
|
|
||
| Usage `python debug_single_sdfg_transform.py sdfg1.json` | ||
|
|
||
| ```python | ||
| import pickle | ||
| import sys | ||
|
|
||
| import dace | ||
| import json | ||
|
|
||
| from dace import SDFG | ||
|
|
||
| from gt4py.next.program_processors.runners.dace import ( | ||
| lowering as gtx_dace_lowering, | ||
| sdfg_args as gtx_dace_args, | ||
| transformations as gtx_transformations, | ||
| ) | ||
| from dace.utils import print_sdfg_hash | ||
|
|
||
| transformation = gtx_transformations.MoveDataflowIntoIfBody | ||
| file = sys.argv[1] | ||
|
|
||
| with open(file) as f: | ||
| data = json.load(f) | ||
| sdfg = dace.SDFG.from_json(data) | ||
| print_sdfg_hash(sdfg) | ||
|
|
||
| sdfg.apply_transformations_repeated( | ||
| transformation( | ||
| ignore_upstream_blocks=False, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
| ), | ||
| validate=False, | ||
| validate_all=True, | ||
| ) | ||
| ``` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked at this file and it looks okay, although the |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -266,6 +266,7 @@ def split_node( | |
| # NOTE: Turning them into a string is the best solution is probably the only way | ||
| # to achieve some stability. The only downside is that the order now depends | ||
| # on the specialization level that is used, i.e. if we have numbers or symbols. | ||
| # TODO(tehrengruber): Is this still needed? | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
| split_description = sorted(split_description, key=lambda split: str(split)) | ||
|
|
||
| desc_to_split = node_to_split.desc(sdfg) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,6 +57,7 @@ def set_dace_config( | |
| # NOTE: Each thread maintains its own set of configuration, i.e. `dace.Config` is | ||
| # a thread local variable. This means it is safe to set values that are different | ||
| # for each thread. | ||
| dace.Config.set("progress", value=True) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not meant to be merged, right? |
||
|
|
||
| # We rely on dace cache to avoid recompiling the SDFG. | ||
| # Note that the workflow step with the persistent `FileCache` store | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only give you like ~95% of the cases, as transformation can also run through other means that the patter matcher or can be simple functions that do things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to avoid editing the code and adding this line, you can export an environment variable:
export DACE_progress=1(note the the upper/lower case unfortunately matters)