SparseIR C-API
This crate provides a C API for the SparseIR library.
Language Support
- Fortran (via ISO_C_BINDING)
- Julia (via ccall)
- Python (via ctypes)
- C/C++
- Other languages that can call C ABIs
Features
Currently Implemented
See the header file for the complete API: include/sparseir/sparseir.h
Sampling: Supported Type Patterns
The C-API provides eval (coefficients → values) and fit (values → coefficients) functions with different type combinations. The suffix indicates input/output types:
d= double (f64, real)z= double complex (Complex64)
Evaluate Functions (Coefficients → Values)
| Function | Tau | Matsubara (full) | Matsubara (positive_only) |
|---|---|---|---|
spir_sampling_eval_dd |
✅ | ❌ | ❌ |
spir_sampling_eval_dz |
❌ | ✅ | ✅ |
spir_sampling_eval_zz |
✅ | ✅ | ✅* |
Fit Functions (Values → Coefficients)
| Function | Tau | Matsubara (full) | Matsubara (positive_only) |
|---|---|---|---|
spir_sampling_fit_dd |
✅ | ❌ | ❌ |
spir_sampling_fit_zd |
❌ | ✅* | ✅ |
spir_sampling_fit_zz |
✅ | ✅ | ✅** |
* For Matsubara (full), fit_zd internally fits complex coefficients and returns their real parts. This is physically correct for Green's functions where IR coefficients are guaranteed to be real by symmetry.
** For Matsubara (positive_only), fit_zz internally fits to real coefficients and converts to complex with zero imaginary parts. This is valid because IR coefficients are guaranteed to be real for physical Green's functions.
* For Matsubara (positive_only), eval_zz extracts real parts from input coefficients and evaluates. This is valid because IR coefficients are guaranteed to be real for physical Green's functions.
Notes
- Tau sampling: Uses real transformation matrix. Supports
ddfor real data,zzfor complex data (real/imag parts transformed independently). - Matsubara (full): Uses complex transformation matrix with both positive and negative frequencies. Natural type is
zz. Thedzevaluate is supported for real coefficients (physically guaranteed for Green's functions). - Matsubara (positive_only): Uses only positive frequencies with complex matrix but real coefficients. Natural types are
dz(evaluate) andzd(fit). Also supportszzvariants by extracting/adding zero imaginary parts.
Error Handling
All C-API functions use catch_unwind() to prevent panics from crossing the FFI boundary:
- Returns error codes instead of panicking
- Process remains stable even on internal errors
- Safe for production use
Building
# Build shared library (.dylib on macOS, .so on Linux, .dll on Windows)
# The C header is automatically generated by cbindgen during build
# Run tests
Installation
Install the header and shared library to your system:
# Install cargo-c (first time only)
# Install header and shared library to system directories
# Or install to a custom prefix
By default, cargo cinstall installs to:
- Header:
/usr/local/include/sparse_ir_capi/sparse_ir_capi.h(Linux/macOS) - Library:
/usr/local/lib/libsparse_ir_capi.so(Linux) or.dylib(macOS) - Static library:
/usr/local/lib/libsparse_ir_capi.a - pkg-config:
/usr/local/lib/pkgconfig/sparse_ir_capi.pc
After installation, you can use pkg-config to find the library:
Note on Header Files:
The header file include/sparseir/sparseir.h is automatically generated by cbindgen during cargo build with C++ compatibility enabled (--cpp-compat flag). The header is used directly without post-processing.
The Cargo.toml is configured with generation = false so that cargo cinstall uses the header from assets/sparse_ir_capi.h. This file is a copy of include/sparseir/sparseir.h and is maintained in the repository (not generated by build.rs to avoid cargo publish issues).
Do not manually edit include/sparseir/sparseir.h - it is automatically generated and will be overwritten on the next build. When the header changes, update assets/sparse_ir_capi.h manually or via CI/CD.
Header Generation
The C header (include/sparseir/sparseir.h) is automatically generated from Rust source code using cbindgen:
- Build time: Header is regenerated automatically when Rust sources change
- Manual regeneration:
cargo build(header is created bybuild.rs) - Configuration: See
cbindgen.tomlfor generation settings
Do not edit the generated header manually - edit the Rust source code instead!
Usage Examples
Julia
# Load library
const lib = "../target/release/libsparse_ir_capi.dylib"
# Create kernel
kernel_ptr = Ref{Ptr{Cvoid}}()
status = ccall((:spir_logistic_kernel_new, lib),
Int32, (Float64, Ref{Ptr{Cvoid}}),
10.0, kernel_ptr)
# Compute kernel value
result = Ref{Float64}()
status = ccall((:spir_kernel_compute, lib),
Int32, (Ptr{Cvoid}, Float64, Float64, Ref{Float64}),
kernel_ptr[], 0.5, 0.5, result)
println("K(0.5, 0.5) = ", result[])
# Release
ccall((:spir_kernel_release, lib), Cvoid, (Ptr{Cvoid},), kernel_ptr[])
See examples/test_julia.jl for a complete example.
C
int
Testing
Run the Julia example:
Memory Management
All objects returned by *_new() functions must be released with their corresponding *_release() function:
spir_kernel_release()- (more to come:
spir_basis_release(), etc.)
All objects are immutable and thread-safe.
License
This crate is dual-licensed under the terms of the MIT license and the Apache License (Version 2.0).
- You may use this crate under the terms of either license, at your option: