# ethanswang/mlxpdlp architecture

> Architecture diagram of the GitHub repository ethanswang/mlxpdlp, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ethanswang/mlxpdlp
- Repository: https://github.com/ethanswang/mlxpdlp

## Overview

mlxPDLP is a C++ linear-programming solver implementing PDHG on MLX CPU or Metal, with C++ and Python interfaces, MPS ingestion, optional presolve, and shared-matrix batch solving. The principal workflow supplies a CSR LP (or loads an MPS model), prepares and solves it, then returns solution and termination diagnostics. The README documents capabilities beyond the sampled excerpts; links for those subsystems are included only where their paths and roles are supported.

Main entry points: [`src/solver.cpp`](https://github.com/ethanswang/mlxpdlp/blob/main/src/solver.cpp) (PDHG solver), [`python/mlxpdlp/__init__.py`](https://github.com/ethanswang/mlxpdlp/blob/main/python/mlxpdlp/__init__.py) (Python API), [`src/batch_solver.cpp`](https://github.com/ethanswang/mlxpdlp/blob/main/src/batch_solver.cpp) (Shared matrix plan), [`python/src/batch_bindings.h`](https://github.com/ethanswang/mlxpdlp/blob/main/python/src/batch_bindings.h) (Batch bindings)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interfaces["User interfaces"]
  node_python_api["Python API<br/>[__init__.py]"]
  node_bindings["Native bindings<br/>[module.cpp]"]
  node_solver_api["Solver API<br/>[solver.h]"]
  node_batch_api["Batch API<br/>[batch_solver.h]"]
end

subgraph group_ingestion["LP ingestion"]
  node_mps_api["MPS loader API<br/>[mps_loader.h]"]
  node_mps_loader["MPS loading<br/>[mps_loader.c]"]
  node_mps_parser["MPS parsing<br/>[mps_parser.c]"]
end

subgraph group_engine["Solve engine"]
  node_presolve["Presolve adapter"]
  node_matrix["Matrix preparation<br/>[shared_matrix.cpp]"]
  node_solver["PDHG solver<br/>[solver.cpp]"]
  node_sparse_cpu["CPU sparse ops"]
  node_sparse_metal["Metal sparse ops<br/>[metal_spmv.h]"]
  node_host_polish["FP64 correction"]
end

subgraph group_batch["Batch solving"]
  node_batch_plan["Shared matrix plan<br/>[batch_solver.cpp]"]
  node_batch_bindings["Batch bindings<br/>[batch_bindings.h]"]
  node_batch_result["Batch results<br/>[batch_solver.h]"]
end

node_cpp_user(("C++ caller"))
node_python_user(("Python caller"))
node_mps_file["MPS model"]
node_result["Solve result<br/>[solver.h]"]

node_cpp_user -->|"supplies CSR"| node_solver_api
node_python_user -->|"calls"| node_python_api
node_python_api -->|"delegates"| node_bindings
node_bindings -->|"constructs solver"| node_solver_api
node_python_api -->|"loads MPS"| node_mps_api
node_mps_file -->|"input model"| node_mps_api
node_mps_api -->|"loads"| node_mps_loader
node_mps_loader -->|"parses"| node_mps_parser
node_solver_api -->|"invokes"| node_solver
node_solver -.->|"optionally presolves"| node_presolve
node_solver -->|"prepares operator"| node_matrix
node_solver -->|"uses on CPU"| node_sparse_cpu
node_solver -->|"uses on Metal"| node_sparse_metal
node_solver -.->|"optionally corrects"| node_host_polish
node_solver -->|"returns"| node_result
node_cpp_user -->|"submits batch"| node_batch_api
node_python_api -->|"exposes batch"| node_batch_bindings
node_batch_bindings -->|"submits"| node_batch_plan
node_batch_api -->|"executes batch"| node_batch_plan
node_batch_plan -->|"runs members"| node_solver
node_batch_plan -->|"assembles"| node_batch_result
node_batch_bindings -->|"converts results"| node_batch_result

click node_python_api "https://github.com/ethanswang/mlxpdlp/blob/main/python/mlxpdlp/__init__.py"
click node_bindings "https://github.com/ethanswang/mlxpdlp/blob/main/python/src/module.cpp"
click node_solver_api "https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/solver.h"
click node_batch_api "https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/batch_solver.h"
click node_mps_api "https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/mps_loader.h"
click node_mps_loader "https://github.com/ethanswang/mlxpdlp/blob/main/src/mps_loader.c"
click node_mps_parser "https://github.com/ethanswang/mlxpdlp/blob/main/src/mps_parser.c"
click node_presolve "https://github.com/ethanswang/mlxpdlp/blob/main/src/presolve_adapter.cpp"
click node_matrix "https://github.com/ethanswang/mlxpdlp/blob/main/src/shared_matrix.cpp"
click node_solver "https://github.com/ethanswang/mlxpdlp/blob/main/src/solver.cpp"
click node_sparse_cpu "https://github.com/ethanswang/mlxpdlp/blob/main/src/cpu_sparse_matrix.h"
click node_sparse_metal "https://github.com/ethanswang/mlxpdlp/blob/main/src/metal_spmv.h"
click node_host_polish "https://github.com/ethanswang/mlxpdlp/blob/main/src/host_double_polish.cpp"
click node_result "https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/solver.h"
click node_batch_plan "https://github.com/ethanswang/mlxpdlp/blob/main/src/batch_solver.cpp"
click node_batch_bindings "https://github.com/ethanswang/mlxpdlp/blob/main/python/src/batch_bindings.h"
click node_batch_result "https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/batch_solver.h"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_python_api,node_bindings,node_solver_api,node_batch_api toneBlue
class node_mps_api,node_mps_loader,node_mps_parser toneAmber
class node_presolve,node_matrix,node_solver,node_sparse_cpu,node_sparse_metal,node_host_polish toneMint
class node_batch_plan,node_batch_bindings,node_batch_result toneRose
class node_cpp_user,node_python_user,node_mps_file toneIndigo
class node_result toneTeal
```

## Components

### User interfaces

- [Python API](https://github.com/ethanswang/mlxpdlp/blob/main/python/mlxpdlp/__init__.py): `python/mlxpdlp/__init__.py`
- [Native bindings](https://github.com/ethanswang/mlxpdlp/blob/main/python/src/module.cpp): `python/src/module.cpp`
- [Solver API](https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/solver.h): `include/mlxPDLP/solver.h`
- [Batch API](https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/batch_solver.h): `include/mlxPDLP/batch_solver.h`

### LP ingestion

- [MPS loader API](https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/mps_loader.h): `include/mlxPDLP/mps_loader.h`
- [MPS loading](https://github.com/ethanswang/mlxpdlp/blob/main/src/mps_loader.c): `src/mps_loader.c`
- [MPS parsing](https://github.com/ethanswang/mlxpdlp/blob/main/src/mps_parser.c): `src/mps_parser.c`

### Solve engine

- [Presolve adapter](https://github.com/ethanswang/mlxpdlp/blob/main/src/presolve_adapter.cpp): `src/presolve_adapter.cpp`
- [Matrix preparation](https://github.com/ethanswang/mlxpdlp/blob/main/src/shared_matrix.cpp): `src/shared_matrix.cpp`
- [PDHG solver](https://github.com/ethanswang/mlxpdlp/blob/main/src/solver.cpp): `src/solver.cpp`
- [CPU sparse ops](https://github.com/ethanswang/mlxpdlp/blob/main/src/cpu_sparse_matrix.h): `src/cpu_sparse_matrix.h`
- [Metal sparse ops](https://github.com/ethanswang/mlxpdlp/blob/main/src/metal_spmv.h): `src/metal_spmv.h`
- [FP64 correction](https://github.com/ethanswang/mlxpdlp/blob/main/src/host_double_polish.cpp): `src/host_double_polish.cpp`

### Batch solving

- [Shared matrix plan](https://github.com/ethanswang/mlxpdlp/blob/main/src/batch_solver.cpp): `src/batch_solver.cpp`
- [Batch bindings](https://github.com/ethanswang/mlxpdlp/blob/main/python/src/batch_bindings.h): `python/src/batch_bindings.h`
- [Batch results](https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/batch_solver.h): `include/mlxPDLP/batch_solver.h`

### Other components

- **C++ caller**
- **Python caller**
- **MPS model**
- [Solve result](https://github.com/ethanswang/mlxpdlp/blob/main/include/mlxPDLP/solver.h): `include/mlxPDLP/solver.h`

## Connections

- C++ caller → Solver API: supplies CSR
- Python caller → Python API: calls
- Python API → Native bindings: delegates
- Native bindings → Solver API: constructs solver
- Python API → MPS loader API: loads MPS
- MPS model → MPS loader API: input model
- MPS loader API → MPS loading: loads
- MPS loading → MPS parsing: parses
- Solver API → PDHG solver: invokes
- PDHG solver → Presolve adapter: optionally presolves
- PDHG solver → Matrix preparation: prepares operator
- PDHG solver → CPU sparse ops: uses on CPU
- PDHG solver → Metal sparse ops: uses on Metal
- PDHG solver → FP64 correction: optionally corrects
- PDHG solver → Solve result: returns
- C++ caller → Batch API: submits batch
- Python API → Batch bindings: exposes batch
- Batch bindings → Shared matrix plan: submits
- Batch API → Shared matrix plan: executes batch
- Shared matrix plan → PDHG solver: runs members
- Shared matrix plan → Batch results: assembles
- Batch bindings → Batch results: converts results
