Skip to content

PR: Refactoring PyOP3 Codegen - #5392

Draft
SamSJackson wants to merge 23 commits into
connorjward/pyop3from
SamSJackson/pyop3-mlir
Draft

PR: Refactoring PyOP3 Codegen#5392
SamSJackson wants to merge 23 commits into
connorjward/pyop3from
SamSJackson/pyop3-mlir

Conversation

@SamSJackson

Copy link
Copy Markdown

Refactoring pyop3/lower/

PR presents abstraction in the lower/ design to allow for alternative code generation backends.

Principally, loopy.py has been broken into three separate files:

  • codegen.py - context orchestrator which returns lowered IR back to translation layer

  • context.py - generic class and high-level traversal of axis trees to generate pyop3 expressions.
    (possible that class and traversal has too many responsibilities).

  • loopy.py -implements backend-specific lowering from pyop3 to respective target IRs

This PR serves as a stepping stone to the introduction of MLIR as a code generation backend.
A new mlir.py module will subclass context.py that will construct MLIR from PyOP3 expressions, using xDSL.

- Goal: Create an interface to a code generation context (MLIR or Loopy)
- Status: Interface created, battling PETSc bug before cleaning more.

- Goal: Integrate MLIR for auto-generation
- Status: Was working but transitioning to pyop3->mlir pipeline as
  opposed to pym->mlir. Refactoring process is ongoing.
requirements tracking pyop3 && typing hints
Merged Connor's update with new setup.
Current issue with values loaded into the buffers.
Occurs even while using old lower/loopy.py

Debugging in process.
PyOP3 updates and path traversals reflected in the new lowering
structure
Still need to integrate dtype support for all op3 expressions.
Removed abstractmethod while testing.
@connorjward connorjward added the base:main Run this PR using a main (dev) build label Aug 26, 2026

@connorjward connorjward left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Key point on an initial first pass is I would like to limit the scope of what the context objects know about.

Comment thread pyop3/insn/exec.py

# TODO: handle these - need to build CompilerOptions

codegen: str = "loopy"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please document

Comment thread pyop3/lower/codegen.py
for e in pyop3.collections.as_tuple(ex): # TODO: get rid of this loop
# context manager?
context.set_temporary_shapes(_collect_temporary_shapes(e))
_compile(e, loop_indices, context)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This code is really disgusting but not your problem!

Comment thread pyop3/lower/codegen.py
else:
cs_expr = (insn,)

if compiler_parameters.codegen == "loopy":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think I prefer 'backend' to 'codegen'

Comment thread pyop3/lower/codegen.py
Comment on lines +85 to +89
ContextClass = LoopyCodegenContext
elif compiler_parameters.codegen == "mlir":
raise NotImplementedError("Class is still being implemented.")

context = ContextClass(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
ContextClass = LoopyCodegenContext
elif compiler_parameters.codegen == "mlir":
raise NotImplementedError("Class is still being implemented.")
context = ContextClass(
make_context = LoopyCodegenContext
elif compiler_parameters.codegen == "mlir":
raise NotImplementedError("Class is still being implemented.")
context = make_context(

Comment thread pyop3/lower/context.py
return ctx


# NOTE: Not a big fan of how compile sits in this file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah I would expect to put it in codegen.py. This file can just contain the abstract class.

Comment thread pyop3/lower/loopy.py

return indices

def compile_standalone_function(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When I designed the 'context' class I imagined that it would be entirely independent from any of the pyop3 'language'. It would only see the buffers. For example here I think we could amend the add_function_call to take in more arguments. The visitor for when we hit standalone function can then be

args = [(a.buffer_view, spec.intent) for a, spec in zip(call.arguments, call.argspec, strict=True)]
context.add_function_call(call.function.code, args)

The crucial points are:

  • The context never sees the StandaloneCalledFunction type
  • The visitor for StandaloneCalledFunction can remain generic for different backends

Comment thread pyop3/lower/loopy.py
subkernel = call.function.code.with_entrypoints(frozenset())
self.add_subkernel(subkernel)

def compile_petsc_mat(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same, I'd keep it generic. You can just raise NotImplementedError for non-loopy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

base:main Run this PR using a main (dev) build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants