Skip to content
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

Pretty printing #64

Merged
merged 3 commits into from
Jun 25, 2024
Merged

Pretty printing #64

merged 3 commits into from
Jun 25, 2024

Conversation

gdalle
Copy link
Collaborator

@gdalle gdalle commented Jun 25, 2024

Checklist

  • Appropriate tests were added
  • Any code changes were done in a way that does not break public API
  • All documentation related to code changes were updated
  • The new code follows the
    contributor guidelines, in particular the SciML Style Guide and
    COLPRAC.
  • Any new documentation only uses public API

Additional context

Right now every backend type is printed with its type parameters, which yields very long strings (especially with AutoSparse). Since I use those strings in DifferentiationInterface (e.g. as @testset names), I figured it would be nice to make them more user-friendly.

  • Define Base.show for every parametric backend type, in a way that is coherent with the keyword-based constructor. The idea is that users can almost copy-paste string(backend) to construct it.
  • Avoid displaying parameters when they are equal to the default value.
  • Add tests checking that all code printing paths work, but without exact comparison with an expected result

@gdalle
Copy link
Collaborator Author

gdalle commented Jun 25, 2024

Here's a before-after comparison.

Code

using ADTypes

struct FakeSparsityDetector <: ADTypes.AbstractSparsityDetector end
struct FakeColoringAlgorithm <: ADTypes.AbstractColoringAlgorithm end

for backend in [
    # dense
    AutoChainRules(; ruleconfig = :rc),
    AutoDiffractor(),
    AutoEnzyme(),
    AutoEnzyme(mode = :forward),
    AutoFastDifferentiation(),
    AutoFiniteDiff(),
    AutoFiniteDiff(fdtype = :fd, fdjtype = :fdj, fdhtype = :fdh),
    AutoFiniteDifferences(; fdm = :fdm),
    AutoForwardDiff(),
    AutoForwardDiff(chunksize = 3, tag = :tag),
    AutoPolyesterForwardDiff(),
    AutoPolyesterForwardDiff(chunksize = 3, tag = :tag),
    AutoReverseDiff(),
    AutoReverseDiff(compile = true),
    AutoSymbolics(),
    AutoTapir(),
    AutoTapir(safe_mode = false),
    AutoTracker(),
    AutoZygote(),
    # sparse
    AutoSparse(AutoForwardDiff()),
    AutoSparse(
        AutoForwardDiff();
        sparsity_detector = FakeSparsityDetector(),
        coloring_algorithm = FakeColoringAlgorithm()
    )
]
    println(backend)
end

Before

AutoChainRules{Symbol}(:rc)
AutoDiffractor()
AutoEnzyme{Nothing}(nothing)
AutoEnzyme{Symbol}(:forward)
AutoFastDifferentiation()
AutoFiniteDiff{Val{:forward}, Val{:forward}, Val{:hcentral}}(Val{:forward}(), Val{:forward}(), Val{:hcentral}())
AutoFiniteDiff{Symbol, Symbol, Symbol}(:fd, :fdj, :fdh)
AutoFiniteDifferences{Symbol}(:fdm)
AutoForwardDiff{nothing, Nothing}(nothing)
AutoForwardDiff{3, Symbol}(:tag)
AutoPolyesterForwardDiff{nothing, Nothing}(nothing)
AutoPolyesterForwardDiff{3, Symbol}(:tag)
AutoReverseDiff{false}(false)
AutoReverseDiff{true}(true)
AutoSymbolics()
AutoTapir(true)
AutoTapir(false)
AutoTracker()
AutoZygote()
AutoSparse{AutoForwardDiff{nothing, Nothing}, ADTypes.NoSparsityDetector, ADTypes.NoColoringAlgorithm}(AutoForwardDiff{nothing, Nothing}(nothing), ADTypes.NoSparsityDetector(), ADTypes.NoColoringAlgorithm())
AutoSparse{AutoForwardDiff{nothing, Nothing}, FakeSparsityDetector, FakeColoringAlgorithm}(AutoForwardDiff{nothing, Nothing}(nothing), FakeSparsityDetector(), FakeColoringAlgorithm())

After

AutoChainRules(ruleconfig=rc)
AutoDiffractor()
AutoEnzyme()
AutoEnzyme(mode=forward)
AutoFastDifferentiation()
AutoFiniteDiff()
AutoFiniteDiff(fdtype=fd, fdjtype=fdj, fdhtype=fdh)
AutoFiniteDifferences(fdm=fdm)
AutoForwardDiff()
AutoForwardDiff(chunksize=3, tag=tag)
AutoPolyesterForwardDiff()
AutoPolyesterForwardDiff(chunksize=3, tag=tag)
AutoReverseDiff()
AutoReverseDiff(compile=true)
AutoSymbolics()
AutoTapir()
AutoTapir(safe_mode=false)
AutoTracker()
AutoZygote()
AutoSparse(dense_ad=AutoForwardDiff())
AutoSparse(dense_ad=AutoForwardDiff(), sparsity_detector=FakeSparsityDetector(), coloring_algorithm=FakeColoringAlgorithm()))

@ChrisRackauckas
Copy link
Member

The two argument show function is supposed to be round trippable. I don't think that's the case here since for example tag is not defined. You'd need to convert those back to symbols (and only when the input is symbol)

@gdalle
Copy link
Collaborator Author

gdalle commented Jun 25, 2024

You're right, that's an artefact of Symbol interpolation which removes the colon. Any idea how to get around it?

@ChrisRackauckas
Copy link
Member

Directly use the roundtrip property of show, i.e. instead of trying to build a string and printing, do show on the parts as you build it.

julia> a = :s; b = :r;

julia> show(a); print(a)
:ss
julia> print("MyFunction(a = "); show(a); print(")") 
MyFunction(a = :s)

@gdalle
Copy link
Collaborator Author

gdalle commented Jun 25, 2024

The string building is useful to remove useless commas at the end. I found another workaround using repr(object, context=io), is that okay?
Current result:

AutoChainRules(ruleconfig=:rc)
AutoDiffractor()
AutoEnzyme()
AutoEnzyme(mode=:forward)
AutoFastDifferentiation()
AutoFiniteDiff()
AutoFiniteDiff(fdtype=:fd, fdjtype=:fdj, fdhtype=:fdh)
AutoFiniteDifferences(fdm=:fdm)
AutoForwardDiff()
AutoForwardDiff(chunksize=3, tag=:tag)
AutoPolyesterForwardDiff()
AutoPolyesterForwardDiff(chunksize=3, tag=:tag)
AutoReverseDiff()
AutoReverseDiff(compile=true)
AutoSymbolics()
AutoTapir()
AutoTapir(safe_mode=false)
AutoTracker()
AutoZygote()
AutoSparse(dense_ad=AutoForwardDiff())
AutoSparse(dense_ad=AutoForwardDiff(), sparsity_detector=FakeSparsityDetector(), coloring_algorithm=FakeColoringAlgorithm()))

@ChrisRackauckas
Copy link
Member

Yes repr is fine. It just uses show.

@gdalle gdalle merged commit 16f421d into main Jun 25, 2024
4 checks passed
@gdalle gdalle deleted the gd/printing branch June 25, 2024 10:03
@ChrisRackauckas
Copy link
Member

Shit I had just realized this won't round-trip properly because you need to re-wrap the symbols in Vals.

@gdalle
Copy link
Collaborator Author

gdalle commented Jun 25, 2024

In the example printing case I didn't provide Val's to the constructor so they're not showing up. I'll check tomorrow but I think we're good?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants