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

Add a compiler and tracer, each creating OpPrograms #557

Merged
merged 17 commits into from
Oct 4, 2021
Merged

Add a compiler and tracer, each creating OpPrograms #557

merged 17 commits into from
Oct 4, 2021

Conversation

fritzo
Copy link
Member

@fritzo fritzo commented Sep 26, 2021

Addresses pyro-ppl/pyro#2929
pair coded with @eb8680

This aims to work around backend jit issues and improve speed of Funsor used in Pyro. The approach is to first perform symbolic computations among Funsors, then lower to simple Funsor expressions, then compile the lowered Funsor expression to a straight-line program involving only backend ops, then optionally convert to Python code. The final program depends only on funsor.ops. This eliminates interpreter overhead, but does not eliminate op dispatch overhead.

The immediate application is to speed up Pyro's AutoGaussian guide pyro-ppl/pyro#2929, but this will also require symbolic Gaussians #556.

Tasks

  • compile lowered funsors to Funsor-free programs
  • lower Contraction to Binary
  • trace simple op graphs
  • support tuples in compile_function() for functions with multiple outputs (e.g. forward filter backward precondition).

Tasks deferred to follow-up PRs

  • lower bound variables, maybe via Lambda or ops.einsum? E.g. to eliminate the bound variable i:
    Variable("f", Reals[3])["i"].reduce(ops.add, "i")  ⟶  Variable("f", Reals[3]).sum(0)
  • fix contraction to use funsor.ops internally (not opt_einsum with direct backends), or make opt_einsum an op or sth
  • fix Gaussian to use funsor.ops internally
  • support tuples in trace_function() to support multiple outputs

Tested

  • unit tests for compile_funsor()
  • unit tests for trace_function()

@eb8680
Copy link
Member

eb8680 commented Sep 26, 2021

Looks great, and definitely feasible in some form. What about tracing individual funsor.Ops rather than Funsor terms/rewrite rules? The interface might a bit more awkward, but we could have a very low-overhead untyped graph representation that way.

@eb8680
Copy link
Member

eb8680 commented Sep 26, 2021

I guess that approach would require strict use of funsor.ops for every eager computation in every pattern, which is probably not realistic or desirable.

@fritzo
Copy link
Member Author

fritzo commented Sep 26, 2021

What about tracing individual funsor.Ops

🤔 Interesting, I guess that would avoid both a lowering stage and the need to refactor Gaussian to be symbolic.

strict use of funsor.ops for every eager computation

Yes, I guess we'd need to manually desugar all math e.g. x + y --> ops.add(x, y), even in Gaussian, which IMO would make math less maintainable. It might actually be easier to refactor Gaussian to be symbolic. I wonder if funsor.syntax could help, since it desugars to use funsor.ops 😬

@eb8680
Copy link
Member

eb8680 commented Sep 26, 2021

We could also experiment with torch.fx for even lower level tracing, which would save us having to change a bunch of Funsor code. That would make this module specific to the PyTorch backend for now, but that doesn't seem so bad since it's currently our only use case.

Refactoring Gaussian seems worthwhile regardless of how we go about this, but would be lower priority.

@fritzo
Copy link
Member Author

fritzo commented Sep 26, 2021

@eb8680 WDYT about merging this partial implementation (w/o lower() support for bound variables), and simultaneously working on all the solutions you proposed: this funsor.compiler (this PR and subsequent pair coding sessions), an op-level funsor.ops.trace module, and torch.fx (would this be a backend?)?

funsor/ops/op.py Outdated Show resolved Hide resolved
@fritzo fritzo changed the title Add a compiler from Funsors to straight-line op programs Add a compiler and tracer, each creating OpPrograms Sep 27, 2021
Copy link
Member

@eb8680 eb8680 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good per zoom review

@eb8680 eb8680 merged commit dbb2989 into master Oct 4, 2021
@eb8680 eb8680 deleted the vm branch October 4, 2021 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants