GSoC 2025 – Improving Fortran Interfacing in PETSc

Hello everyone,

I’m contributing to PETSc as part of GSoC 2025 under mentorship from @MarDie and @ivanpribec. I’m starting this thread to post weekly updates throughout the summer with progress, open questions and implementation notes here as the work evolves.
I usually post technical questions and discussions on PETSc’s official discord server under fortran-gsoc-2025 channel but I will keep this thread up to date for broader community visibility.
Looking forward to learning more and getting your feedback along the way.

Best regards,
Tapashree

6 Likes

Hi @tapashreepradhan, thanks for the introduction and welcome to the Forum!

Just a quick note: please make sure to keep the broader Fortran-lang community in the loop by posting regular updates and discussions here on Discourse. It’s of course ok to go to PETSc’s Discord for in-depth technical coordination, but Discourse is our main platform for community engagement, visibility, and archival - it helps us all follow, interact, and learn from your work too.

Looking forward to your progress!

1 Like

Weekly Progress Update: As of 16th June 2025

Context and Motivation

This week’s work continues the ongoing effort to modernize and automate the Fortran interface within PETSc (Portable, Extensible Toolkit for Scientific Computation). The primary motivation is to improve the usability and maintainability of PETSc for Fortran users, leverage modern Fortran interoperability features (ISO_C_BINDING, BIND(C)), and reduce the need for manual binding creation.

Readings Done and Concepts Learnt

I have focused on a deeper understanding of Fortran-C interoperability, which is foundational to modernizing PETSc’s Fortran interfaces. Key concepts reviewed include:

  • Standard Fortran and C Interoperability: This core principle dictates that compiled Fortran and C code can interact within the same program, provided one language serves as the main entry point. The goal is to facilitate the use of scientific kernels written in modern Fortran alongside existing C/C++ libraries.

  • ISO_C_BINDING Module: Introduced in Fortran 2003, this standard module is critical for C interoperability. It defines:

    • Kind Constants: Such as C_INT, C_DOUBLE, C_CHAR, which ensure type matching between Fortran and C (e.g., INTEGER(C_INT) in Fortran guarantees it maps to int in C, preventing size/representation mismatches).

    • C-style Pointers: C_PTR for generic C pointers (void *) and C_FUNPTR for C function pointers.

    • Helper Procedures: C_LOC (to get the C address of a Fortran variable) and C_F_POINTER (to associate a Fortran pointer with a C pointer).

  • BIND(C) Attribute: This attribute, applied to Fortran procedures or derived types, is essential for C compatibility. It:

    • Prevents Name Mangling: Ensures the symbol name in the compiled binary is exactly what C expects (e.g., a Fortran SUBROUTINE mysub becomes mysub in the binary, not mysub_).

    • Uses C Calling Conventions: Arguments are typically passed by reference, but the VALUE attribute can enforce pass-by-value, matching C’s default behavior for scalar types.

    • Enables Interoperable Derived Types: Allows Fortran TYPE, BIND(C) to precisely match C struct definitions, provided they contain only interoperable types and no allocatables or pointers.

  • CFI_cdesc_t: A C struct defined by Fortran 2018’s ISO_Fortran_binding.h. This descriptor allows for passing generic Fortran arrays or strings to C in a standard and portable way, simplifying array and string handling.

  • Opaque Handle Management: PETSc frequently uses opaque handles (e.g., Vec, Mat) which are typically passed as INTEGER(KIND=PETSC_FORTRAN_TYPE) in Fortran, corresponding to C pointers. This pattern hides internal C object structures from Fortran, providing encapsulation. While BIND(C) helps with calling conventions, custom handling is still often required for these opaque types and error codes.

  • Fortran-C String Passing: A recurring challenge is how Fortran handles string lengths (often passed as hidden arguments) and how C expects null-terminated strings. Manual conversion and wrapper functions are frequently needed for this.

Merge Requests

Progress this week has been concretized through several Merge Requests (MRs).

MR !8465: PetscObjectNullify Macro (Reviewer)

  • Description: This MR introduced a PetscObjectNullify macro, a single-line preprocessor directive for Fortran users. Its purpose is to reset PETSc object handles (such as Vec, Mat, KSP) back to their initial, unassigned state, which is a specific fix requested by a user.

  • Technical Details: The macro is defined as #define PetscObjectNullify(o) o%v = PETSC_FORTRAN_TYPE_INITIALIZE. This means that PETScObjectNullify(myvec) automatically expands to myvec%vv = PETSC_FORTRAN_TYPE_INITIALIZE, effectively nullifying the Fortran-side handle. This addresses a common need for Fortran clients to manage the lifecycle of PETSc objects more cleanly.

MR !8437: Fortran: Fix HDF5 Attribute Writing Interface (Author)

  • Description: This is a new MR that replaces a previous attempt (#8289) that failed due to a branch naming convention issue. It addresses the missing Fortran binding for writing HDF5 attributes in PETSc, specifically fixing issue #194.

  • Technical Details: The MR focuses on implementing the necessary Fortran interface to allow PETSc users to write HDF5 attributes. A key point of discussion during its development was a suggestion from Barry Smith that these functions could potentially be generated automatically using the existing generatefortranbindings.py infrastructure, rather than requiring manual binding. This suggestion has become a crucial next step to explore.

  • Status: In testing phase, with an automation experiment planned.

MR !8422: Work on Generating Fortran Bindings (Reviewer)

  • Description: This MR is foundational, focusing on automating Fortran binding generation for specific types of C functions. It aims to:

    • Generate Fortran interfaces for C functions that take function pointers as arguments (callbacks) where parameter names end with “Fn” (e.g., createFn, destroyFn). These previously required manual binding creation.
    • Create “bodyless stubs” where feasible, providing the boilerplate C code but no implementation, simplifying subsequent manual completion.
  • Technical Details: The challenge addressed here is the complex handling of function pointers between Fortran and C due to different memory management and calling conventions. This MR is establishing the core automation infrastructure to bridge this gap, paving the way for more automated binding generation.

Impact: Forming a core part of the automation framework.

MR !8469: Automatically Generate Fortran C Stubs for Static Inline Functions in Include Directory (Reviewer)

  • Description: This MR solves the problem of Fortran users needing access to static inline functions (e.g., PetscTime()) that were previously inaccessible in the Fortran interface.

  • Technical Details:

    • Automated Stub Generation: Implemented a system for automatic generation of Fortran C stubs for static inline functions found in PETSc include directories.

    • MANSEC Integration: Added missing MANSEC (manual sections) to some include files. These sections are crucial for the getAPI() tool to correctly determine which PETSc library (e.g., sys, vec) the Fortran stubs belong to, ensuring proper organization.

    • PeNS Macro Introduction: Introduced the PeNS (PETSc Non-Standard) macro for functions that cannot currently be auto-generated due to non-standard arguments. This requires moving PeNS and related macros to public include files, as some static inline functions must be marked with them.

  • Impact: This MR extends the automation framework to a new category of functions. Barry’s work here solved the “easy” static inline functions, and the current task is to extend it to handle more complex cases, such as those with char arguments, that currently require PeNS.

MR !8436: Add Fortran interface for DMShellSetCreateFieldDecomposition (Author)

  • Description: This MR is a replica of a previously closed MR (!8265), which failed due to a # character in the branch name causing GitLab pipeline issues. It provides a Fortran interface for DMShellSetCreateFieldDecomposition.

  • Technical Details: DMShell is PETSc’s mechanism for users to create custom distributed mesh (DM) objects with their own operation implementations. The SetCreateFieldDecomposition function allows users to specify how fields are decomposed for multigrid or domain decomposition methods, which is vital for advanced solver configurations. The Fortran interface for this function enables Fortran users to define these custom decomposition strategies. The code in zdmshellf.c was also cleaned up for clarity in this version.

How the MRs are Building on Top of Each Other

The various Merge Requests discussed are not isolated efforts but are interconnected, progressively building a more robust and automated Fortran binding system in PETSc.

Foundation Layer:

  • !8422 (Barry’s Foundation): This MR is the cornerstone. It establishes the core automation infrastructure for generating Fortran bindings, with a particular focus on functions that accept function pointer arguments ending in “Fn”. This work is critical for handling callback mechanisms, a frequent pattern in PETSc.

Building on Foundation:

  • !8469 (Extending Automation to Static Inlines): This MR directly extends the automation approach introduced in !8422. It applies similar principles to automatically generate Fortran C stubs for static inline functions within PETSc’s include directories. This shows how the foundational work is being generalized to cover more function types.

  • !8437 (Automation Experimentation): While !8437 is currently a manual binding fix for HDF5 attribute writing, Barry’s suggestion to automate it links directly back to the automation capabilities being developed in !8422 and !8469. This MR serves as a potential test case to validate and apply the growing automation framework. The plan is to see if the new tools can replace manual work here, proving their effectiveness.

Independent but Related:

  • !8436 (Callback Interface): This MR manually handles a callback interface for DMShellSetCreateFieldDecomposition. However, it could directly benefit from the advanced function pointer automation being developed in !8422. As the automation capabilities mature, such manual implementations can potentially be replaced by generated code.

Hierarchical View of Interconnected MRs:

This hierarchical approach reflects a strategic effort to build a robust, maintainable, and increasingly automated Fortran interface for PETSc, starting with foundational components and iteratively expanding their scope and application.

8422 (Barry's core foundation for automated Fortran bindings)
   ↓
8469 (Extends automation to static inline functions)
   ↓
8437 automation experiment (to-do list: validate if automation can replace manual work here)
   ↓
Validate approach (confirm automation effectiveness)
   ↓
Apply to 8436 and future callback-based functions (leverage automation for manual interfaces)
   ↓
Reduce manual Fortran binding work across PETSc (overall project goal)

Next Steps:

The immediate next steps are focused on expanding the automated binding generation tooling:

  • Automating char argument function
  • Experiment with HDF5 attribute writing automation

Merge Request Links

5 Likes

Weekly Progress Update: As of 24th June 2025

This week I focused on understanding and automating character argument handling in PETSc’s Fortran bindings.

Concepts learnt

  • PeNS Functions and Character Arguments: PETSc uses PeNS macro to mark non-standard functions that bypass automatic Fortran binding generation. Many contain character arguments (char*, const char[], single char) requiring manual Fortran interfaces.
  • C-fortran String Interoperability: C uses null-terminated strings while Fortran uses space-padded strings with hidden length parameters. PETSc provides FIXCHAR/FREECHAR macros for conversion, handling memory allocation and null termination between languages.
  • PETSc Automation Tools: Went through getAPI.py (function signature parser) and generateFortranBindings.py (binding generator). Current limitations include incomplete character type detection and exclusion of PeNS-marked functions from automation.

Work Done

For automation of fortran bindings generation for functions with char arguments:

  • Extended the getAPI.py to recognize and categorize different character argument types, storing metadata about input/output direction and string vs single character use.
  • Modified the generateFortranBindings.py with templates to automatically generate appropriate Fortran interfaces and C stub functions for each character argument pattern.
  • As proof-of-concept, automated PetscTestFile() bindings that compile correctly and match PETSc’s Fortran conventions, eliminating need for manual binding.
  • Wrote tests verifying generated bindings work correctly for string input/output scenarios.

Merge Requests Status

Active MRs (as author)

  • !8492 - under review
  • !8437 - 1 job failed in stage 3
  • !8436 - 1 job failed in stage 3

Issues Assigned:

  • #1779 - Keep C variable names for Fortran interfaces

Next steps:

  • Resolve the pipeline issues
  • Implement review feedback
  • Work on fixing assigned issue
  • Meeting with mentors to discuss the next incremental step.
4 Likes