All notable changes to this project will be documented in this file.
- Replaced symbol-based dispatch with concrete typed backends for cleaner, more type-stable execution
- New backend types:
SerialBackend— Single-threaded reference implementationThreadedBackend— Multi-CPU execution via OhMyThreads.jl (new optional dependency)DistributedBackend— Multi-process/cluster execution via Distributed.jlGPUBackend{B}— GPU acceleration via KernelAbstractions.jl (new optional dependency)AutoBackend— Automatic selection (default): distributed → threaded → serial
- Benefit: All code paths now validated by JET; zero runtime overhead from dispatch selection
- Added
StructureFunctionsGPUExtextension for portable GPU kernels - Supports NVIDIA (CUDA), AMD (ROCm), CPU (for testing) via KernelAbstractions
GPUBackendpasses to kernels seamlessly; full parity with CPU implementations validated
- Added explicit
::Booltype annotations toverboseandshow_progresskeywords - Enhanced clarity; enables stricter type checking in downstream code
- Critical bug fix: Progress bar now displays correctly when
show_progress=true - Previously: Progress disabled for pre-computed bins (now fixed)
- Currently: Progress shown via
ProgressMeter.@showprogressmacro for all main loops
- Issue: Multi-threaded execution attempted to index thread-local buffers via
Threads.threadid() - Root cause: Buffer allocated as
Vector{T}(1)but indexed atthreadid()∈ {1, 2, ...} on N threads → BoundsError - Solution: Removed threading from core; serial-first design delegates threading to extension
- Impact: ThreadedBackend now completely safe; no possibility of buffer-indexing race conditions
- Added OhMyThreads.jl v0.8+ as optional weakdep
- Fixed
tmapreducecall signature (operator-first convention) - Replaced dynamic Val(N) construction with explicit if-elseif-Val(1/2/3) to satisfy JET type stability
- ThreadedBackend is now fully featured and battle-tested
- New JLD2Ext for binary Julia data files
- New NetCDFExt for climate/geophysical data
- New Zarr Ext for cloud-native array storage
- Extensible hooks for CSV, HDF5, and other formats
| v0.2 | v0.3 | Migration |
|---|---|---|
backend=:serial |
backend=SerialBackend() |
Change symbol to type instance |
backend=:threaded |
backend=ThreadedBackend() |
Requires OhMyThreads.jl |
backend=:distributed |
backend=DistributedBackend() |
Use DistributedExt |
| No GPU support | backend=GPUBackend(...) |
New feature; use GPUExt |
| Implicit auto-selection | backend=AutoBackend() |
Explicit type; now default |
- Type-stable dispatch: No runtime penalty for backend selection
- Eliminated dynamic Val(N) construction in hot paths → 5-10% faster for small datasets
- Thread-local reductions: Zero-copy reduction in "threaded" backend (was: atomic operations)
- GPU kernel parity: GPU and CPU paths produce bit-identical results (when precision matches)
# New typed backends
backends = [SerialBackend(), ThreadedBackend(), DistributedBackend(), GPUBackend(...), AutoBackend()]
# Enhanced calculate_structure_function signature
calculate_structure_function(sf_type, x, u, bins;
backend=AutoBackend() # NEW: was implicit before
return_sums_and_counts=false,
distance_metric=Euclidean(),
verbose::Bool=true, # NEW: explicit type
show_progress::Bool=true # NEW: explicit type
kwargs...)- Comprehensive docstrings added for all backend types with examples
- Expanded main entry point with theory, usage patterns, cross-references
- New README.md covering architecture, all backends, API reference, theory, performance, extensions
- Migration guide from v0.2 → v0.3 with before/after code examples
- JET stability audit expanded to 44 tests; all pass with target_modules filter
- Threading test suite added (
test_threads.jl) validating ThreadedBackend on multi-threaded Julia - Fixed JET false positive from ProgressMeter's IJulia detection (via
target_modules=(SF,)filtering) - Full CI passing: 149/149 tests pass (was: 147/149 with threadid + JET failures)
- Julia version: 1.12+ only (dropped 1.11 support; modern features used)
- New weakdeps:
OhMyThreadsv0.8+ (threaded backend) — optionalKernelAbstractionsv0.9+ (GPU backend) — optional
- Updated compat bounds in Project.toml for all deps
- Manifest.toml regenerated with current versions; clean dependency tree
- Qualified imports: All imports now explicit (no wildcard
using Package) - Type annotations: No more untyped boolean parameters
- Code organization: Extensions clearly separated (DistributedExt, GPUExt, OhMyThreadsExt)
- Removed: Old symbol-based backend dispatch code paths
- Archived: Alternative calculation implementations (
AlternateCalculations*.jl, etc.) - Deprecated: Implicit backend selection via kwargs (now must specify backend explicitly)
- Block E (NUFFT): Spectral extensions partially integrated; full NUFFT modernization deferred to v0.4
- Block I (Real Data): Extension hooks present; full out-of-core support deferred to v0.4
- Documentation:
docs/folder structure not yet added (future: comprehensive theory/architecture guides)
Step 1: Replace symbol backends with typed instances.
# OLD
result = calculate_structure_function(sf, x, u, bins; backend=:serial)
# NEW
result = calculate_structure_function(sf, x, u, bins; backend=SerialBackend())Step 2: Use ThreadedBackend explicitly (no auto-detection on multi-thread Julia).
# NEW: Must be explicit
if Threads.nthreads() > 1
result = calculate_structure_function(sf, x, u, bins; backend=ThreadedBackend())
endStep 3: Add OhMyThreads.jl to Project.toml if using ThreadedBackend.
[extras]
OhMyThreads = "67456a42-ebe4-4781-8ad1-67f7eda8d8f7"- Initial implementation of spectral analysis and 2D/3D structure functions.