Skip to content

Commit

Permalink
code-gen: Simplify switch (#2240)
Browse files Browse the repository at this point in the history
Improves model code generation by collapsing cases with identical statements.

I.e.
```
switch(a)
 case b:
 case c:
  statements;
  break;
```
instead of

```
switch(a)
 case b:
  statements;
  break;
 case c:
  statements;
  break;
```

For my current model of interest, containing many events, this significantly reduces the generated code:

E.g.:
```
 16K my_model/deltasx.cpp
6,6M my_model_old/deltasx.cpp
```

Overall, for this model, I got from 204201 LOC down to 7936 LOC (i.e. -96%).

* ..

* Apply suggestions from code review

Co-authored-by: Dilan Pathirana <[email protected]>

* GHA: test python3.12 (#2179)

Run nightly tests also on python3.12

* Deterministic order of event assignments (#2242)

Ensure event assignments targets are processed in deterministic order.
Otherwise the ordering of state variables may change between subsequent
model imports, which we'd like to avoid.

Closes #2241.

* Fix AMICI hiding all warnings (#2243)

Previously, importing amici would result in all warnings of the program being hidden, due to `logging.captureWarnings(True)`:

```sh
$ python -c "import warnings; warnings.warn('bla');"
<string>:1: UserWarning: bla
$ python -c "import amici; import warnings; warnings.warn('bla');"
$
```

This can't be the desired default.

Changes:
* Default to not capturing warnings
* If warnings are to be captured, at least handle them by amici loggers

Closes ICB-DCM/pyPESTO#1252


---------

Co-authored-by: Dilan Pathirana <[email protected]>
  • Loading branch information
dweindl and dilpath authored Dec 18, 2023
1 parent a3b1c2b commit 0cc43f9
Showing 1 changed file with 27 additions and 12 deletions.
39 changes: 27 additions & 12 deletions python/sdist/amici/cxxcodeprinter.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,9 @@ def get_switch_statement(
indentation_step: Optional[str] = " " * 4,
):
"""
Generate code for switch statement
Generate code for a C++ switch statement.
Generate code for a C++ switch statement with a ``break`` after each case.
:param condition:
Condition for switch
Expand All @@ -321,26 +323,39 @@ def get_switch_statement(
:return:
Code for switch expression as list of strings
"""
lines = []

if not cases:
return lines
return []

indent0 = indentation_level * indentation_step
indent1 = (indentation_level + 1) * indentation_step
indent2 = (indentation_level + 2) * indentation_step

# try to find redundant statements and collapse those cases
# map statements to case expressions
cases_map: dict[tuple[str, ...], list[str]] = {}
for expression, statements in cases.items():
if statements:
lines.extend(
statement_code = tuple(
[
f"{indent1}case {expression}:",
*(f"{indent2}{statement}" for statement in statements),
f"{indent2}break;",
]
)

if lines:
lines.insert(0, f"{indent0}switch({condition}) {{")
lines.append(indent0 + "}")

return lines
case_code = f"{indent1}case {expression}:"

cases_map[statement_code] = cases_map.get(statement_code, []) + [
case_code
]

if not cases_map:
return []

return [
f"{indent0}switch({condition}) {{",
*(
code
for codes in cases_map.items()
for code in itertools.chain.from_iterable(reversed(codes))
),
indent0 + "}",
]

0 comments on commit 0cc43f9

Please sign in to comment.