Skip to content

[Feature] Two-way python bridge with limited MAPL support in Python#4369

Merged
tclune merged 19 commits intodevelopfrom
fdeconinck/feat/python_bridge
Feb 26, 2026
Merged

[Feature] Two-way python bridge with limited MAPL support in Python#4369
tclune merged 19 commits intodevelopfrom
fdeconinck/feat/python_bridge

Conversation

@FlorianDeconinck
Copy link
Contributor

@FlorianDeconinck FlorianDeconinck commented Feb 6, 2026

Types of change(s)

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Trivial change (affects only documentation or cleanup)
  • Refactor (no functional changes, no api changes)

Checklist

  • Tested this change with a run of GEOSgcm
  • Ran the Unit Tests (make tests)

Description

This PR aims at solving the "90%" case of Python integration has it as been seen lately at GMAO. The main features are:

  • One liner to drop into python, with dynamic package load (with a simple structure for user to hook in)
  • MAPL/ESMF states pass-through with a limited API to pull memory down in Python
  • Tooling for common Python operations (ongoing, more to come)

The entire API is heavily #ifdef by a flag at compile time BUILD_PYTHONBRIDGE - by default the functions are passthroughs.

Review points

@tclune / @atrayano: it was non-trivial for me to find a spot where I could initialize the system with the atmospheric grid. I ended up calling in GEOSAgcm_GridComp (see sister PR). This is only needed because right now the bridge back to MAPL gives me the pointer "blind", without sizes and rank. So I am giving the GRID to users so we can tool down.
A better version would be to augment the "MAPLpy" bridge to get shape and ranks, but I'd like to see that in a subsequent version so we can stress test this bridge first.

@mathomp4: I ended up not feeding the add_definitions upstream like we talked about. I kept it within the MAPL.python_bridge cmakelist and forwarded the API there. This looks cleaner and achieve the "opt-in by default" behavior we wanted.

@pchakraborty: You should find the design quite familiar. It's a CFFI bridge, like we've done before. The trick relies in the _get_code_object_from_package_name where I dynamically load the user given module and search for a CODE object. The README spells it out with some code. The rest is marshalling up & down memory via void*.

@FlorianDeconinck FlorianDeconinck requested a review from a team as a code owner February 6, 2026 16:50
@FlorianDeconinck FlorianDeconinck added 🎁 New Feature This is a new feature 0 Diff Trivial The changes in this pull request are trivially zero-diff (documentation, build failure, &c.) labels Feb 6, 2026
@mathomp4 mathomp4 added 0 Diff The changes in this pull request have verified to be zero-diff with the target branch. and removed 0 Diff Trivial The changes in this pull request are trivially zero-diff (documentation, build failure, &c.) labels Feb 6, 2026
@tclune tclune requested review from pchakraborty and tclune February 6, 2026 18:07
@tclune
Copy link
Collaborator

tclune commented Feb 6, 2026

We will have a meeting this afternoon to take a quick look. A deeper dive will wait until next week.

@FlorianDeconinck
Copy link
Contributor Author

Python API updated to simplify retrieving memory. Now you can do

MAPLPy = get_MAPLPy()
T = MAPLPy.get_pointer("T", state=import_state, dtype=np.float32, dims=MAPLPy.grid_dims)

and you get Fortran memory mapping in T, while T is a numpy array.

@mathomp4
Copy link
Member

mathomp4 commented Feb 9, 2026

Well, that coupled CI failure is weird. I'm re-running it.

@FlorianDeconinck
Copy link
Contributor Author

With the latest round of Python work I believe we have reached MVP - review away!

@mathomp4
Copy link
Member

mathomp4 commented Feb 9, 2026

I tested with NAG by hand and it's happy too.

Copy link
Collaborator

@tclune tclune left a comment

Choose a reason for hiding this comment

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

There are a few naming convention changes that I think would be good. (There will be more for MAPL3 issues, but we can handle those later.)

Biggest question is where the bridge is initialized?

@FlorianDeconinck
Copy link
Contributor Author

@tclune aptly pointed out the file naming is a bit random, I am going to a pass to clarify it all

@FlorianDeconinck
Copy link
Contributor Author

@pchakraborty : renaming and file move to Python has been done, ready for re-review

@mathomp4 : installed into Python/ seems to be a-ok

image

@tclune
Copy link
Collaborator

tclune commented Feb 24, 2026

Can we resolve the remaining comments and get this merged?

@FlorianDeconinck
Copy link
Contributor Author

Can we resolve the remaining comments and get this merged?

Ready for merge on my side.

@tclune tclune merged commit ddd6b40 into develop Feb 26, 2026
36 of 40 checks passed
@tclune tclune deleted the fdeconinck/feat/python_bridge branch February 26, 2026 16:04
@tclune
Copy link
Collaborator

tclune commented Feb 26, 2026

Yay - done for now!

@FlorianDeconinck
Copy link
Contributor Author

Thank you everyone

darianboggs pushed a commit that referenced this pull request Feb 26, 2026
…4369)

* Python bridge original code + README

* Exposing `MAPL.python_bridge` to larger `MAPL` + forward API

* Fix bad import when opt-out of the bridge + clean up

* Update CHANGELOG

* Defend `ieee` checks against odd compiler faults.
Restrict it to known SIGFPE issue on numpy import

* Evolve API to get a 1 call to MAPL_GetPointer within Python

* Add `associated` check leading to buffer being `None`
Docstrings

* Export init/finalize user code hooks
Replace GridComp by MaplComp

* Fix ABC use for user code base class
Add a larger bypass IEEE importer with other packages used in DSL

* Fix MAPLPy user API memory retrieval

* Expose `GetResource` to `MAPLPy`

* Expose basic grid infos

* Add hook for RUN with `INTERNAL` state

* Expose `named_run_with_internal` to public API

* Fixing implicit `stdlib.h` import for uptight apple-clang

* Rename files & move under the `Python` directory

* Rename MAPL_PythonBridge -> PythonBridge

---------

Co-authored-by: Tom Clune <thomas.l.clune@nasa.gov>
darianboggs pushed a commit that referenced this pull request Mar 4, 2026
…4369)

* Python bridge original code + README

* Exposing `MAPL.python_bridge` to larger `MAPL` + forward API

* Fix bad import when opt-out of the bridge + clean up

* Update CHANGELOG

* Defend `ieee` checks against odd compiler faults.
Restrict it to known SIGFPE issue on numpy import

* Evolve API to get a 1 call to MAPL_GetPointer within Python

* Add `associated` check leading to buffer being `None`
Docstrings

* Export init/finalize user code hooks
Replace GridComp by MaplComp

* Fix ABC use for user code base class
Add a larger bypass IEEE importer with other packages used in DSL

* Fix MAPLPy user API memory retrieval

* Expose `GetResource` to `MAPLPy`

* Expose basic grid infos

* Add hook for RUN with `INTERNAL` state

* Expose `named_run_with_internal` to public API

* Fixing implicit `stdlib.h` import for uptight apple-clang

* Rename files & move under the `Python` directory

* Rename MAPL_PythonBridge -> PythonBridge

---------

Co-authored-by: Tom Clune <thomas.l.clune@nasa.gov>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

0 Diff The changes in this pull request have verified to be zero-diff with the target branch. 🎁 New Feature This is a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants