Fortran to Python Migration Guide
Move decades-old Fortran numerical code to Python without breaking the math that runs on top of it.
- 8ForgeScore dimensions
- 6Pipeline stages
- Every stageApproval gates
Why teams move off Fortran
Fortran has not lost its numerical strengths, it has lost its ecosystem gravity. The reasons to migrate are practical, not ideological.
The Fortran talent pool is shrinking
Fewer engineers train in Fortran each year while most graduates learn Python. Retaining Fortran maintainers gets harder the longer a codebase sits untouched.
Python's scientific ecosystem now rivals Fortran's numerical strengths
NumPy, SciPy, and pandas give Python the array operations, linear algebra, and visualization that were once Fortran's exclusive territory.
Easier integration with modern ML and data pipelines
ML frameworks and data orchestration tools are Python-first. Keeping simulation logic in Fortran makes it harder to plug into the rest of the stack.
Better tooling across the board
Python has mature debuggers, package managers, and testing frameworks that are more approachable than toolchains built around legacy Fortran projects.
Cross-platform portability
Python runs unmodified across platforms. Fortran codebases often carry compiler-specific extensions and build flags accumulated over decades.
Faster onboarding for new engineers and researchers
New hires and researchers are far likelier to know Python already, which shortens ramp-up and reduces bus-factor risk around a few specialists.
What actually changes under the hood
These differences determine whether a migration preserves correct numerical behavior, not just working syntax.
- 01
1-based vs 0-based array indexing
Fortran indexes arrays from 1, Python and NumPy from 0. Every loop bound and slice must be re-derived, not simply decremented by one.
- 02
Column-major vs row-major memory layout
Fortran stores arrays column-major; NumPy defaults to row-major. Porting requires order='F' or deliberate transposition, or results can be silently wrong.
- 03
Static typing and fixed-size arrays vs dynamic typing
Fortran sizes arrays at compile time, which the compiler uses for checking. Python needs explicit shape and dtype management via NumPy to keep those guarantees.
- 04
COMMON blocks and modules vs Python module state
Fortran 77 shares state through COMMON blocks. Python has no equivalent, so shared state is reorganized into module variables, config objects, or classes.
Array indexing and loops
PROGRAM SCALE_ARRAY
IMPLICIT NONE
INTEGER, PARAMETER :: N = 5
REAL :: A(N)
INTEGER :: I
DO I = 1, N
A(I) = REAL(I) * 2.0
END DO
DO I = 1, N
PRINT *, 'A(', I, ') = ', A(I)
END DO
END PROGRAM SCALE_ARRAYimport numpy as np
N = 5
a = np.empty(N, dtype=np.float64)
for i in range(N):
a[i] = (i + 1) * 2.0
for i in range(N):
print(f'a[{i}] = {a[i]}')
# Vectorized equivalent, idiomatic in NumPy:
# a = (np.arange(1, N + 1) * 2.0)How the migration works
From import to verified output, every step is scored, specified, and tracked.
Import Fortran
Your existing Fortran codebase is ingested as-is, including legacy Fortran 77 and modern Fortran 90+ sources. No prior documentation needed.
ForgeScore assessment
Scored across 8 engineering-health dimensions before you commit to anything, including flags for indexing-sensitive array logic and COMMON block usage.
Approved specification
Numerical logic and business rules are reconstructed from source into a spec your team reviews, before any Python code is generated.
Work orders
The spec becomes Build, Migrate, and Decommission work orders, scoped and sequenced so array-layout and indexing changes are handled deliberately, not line by line.
Verified & shipped
Each Migrate work order is checked against the original Fortran behavior, within defined numerical tolerance, before it ships.
Works in your editor
Work orders connect into Claude Code, Cursor, Windsurf, and other AI code editors over MCP, so the governed spec travels with you instead of staying in a separate dashboard.
From finding to work order
Every Fortran import is scored across 8 engineering-health dimensions, then broken into Build, Migrate, and Decommission work orders. Here is what that looks like for an array-indexing finding.
ForgeScore findingMedium severity finding
Array layout54
How arrays are indexed and stored in memory. Moderate score: Fortran is 1-based and column-major, NumPy is 0-based and row-major, so every loop bound and slice needs re-deriving.
Migration work orderMigrate
Migrate: SCALE_ARRAY
Re-express the array routine as vectorized NumPy with 0-based indexing and explicit memory order. Includes verification against the original Fortran output, within defined numerical tolerance, before this work order is marked complete.
Common challenges
Fortran-to-Python migrations fail less on syntax and more on numerical behavior that shifts silently.
Off-by-one errors from indexing conventions
The 1-based to 0-based switch is the most common source of subtle bugs. Loop bounds, boundary conditions, and slices all need re-deriving and testing.
Row-major vs column-major layout
Unhandled memory order produces wrong results when interfacing with binary files or external libraries, and degrades cache performance even when the math is right.
Performance loss without vectorization
A loop-for-loop translation runs far slower than compiled Fortran. Matching performance means vectorizing hot loops with NumPy or compiling them with Numba or Cython.
Floating-point behavior differences
Compiler optimizations and evaluation order in the original build can produce results differing in the last few bits, even when both are correct IEEE 754 arithmetic.
Frequently asked questions
How long does a typical Fortran to Python migration take?
It depends on codebase size, how array-heavy the logic is, and whether performance parity is required. Verification work usually dominates the timeline, not translation.
Will the Python version produce bit-identical results to the original Fortran?
Usually not bit-for-bit, but numerically equivalent within a defined tolerance. Compiler and BLAS/LAPACK differences make exact bit-identical output unrealistic.
How do you verify the migrated code preserves the original behavior?
By running both versions on the same inputs and comparing within an agreed tolerance. If tests are missing, known-good outputs are captured first as a baseline.
Does migrating from Fortran to Python require downtime?
Not typically. Migrations run in parallel with the existing system. Fortran routines can also be wrapped and called from Python via f2py as a transitional step.
Will the Python version be as fast as the original Fortran?
It depends how it is done. Unvectorized translation is slower, but NumPy vectorization plus Numba or Cython on hot paths gets close to compiled Fortran.
See your ForgeScore before you commit
Every Fortran-to-Python project on Forge starts the same way: your codebase is imported, scored with ForgeScore, and reconstructed into an approved specification before a single line of Python is generated.
Ship enterprise software at AI speed.
Every modernization path is spec-first and governed from Day 0.
