OpenCUDA-Lab: library features and public functions
====================================================

The product is libopencuda (include/opencuda/opencuda.h).
Python's opencudalab package mostly loads that library.
The lists below are what the C library actually provides.

Version: 0.1.0 (preview ABI; SOVERSION is still 0)


FEATURES
--------

1. GPU (or mock) memory pool
   Replaces cudaMalloc / cudaFree with a pooled allocator. Backends:

   - VMM       CUDA virtual memory (cuMemCreate / cuMemMap): grow/move
               buffers in place
   - Runtime   cudaMalloc / cudaMallocAsync slab
   - Mock      host RAM, no GPU (macOS / CI)
   - Mock-flat one contiguous slab, for ablation

   Optional: grow the pool, per-thread small-block cache, refuse allocs
   that would exceed a predicted envelope.

2. Peak-memory prediction (not by reading source)
   You declare stages + buffers + lifetimes. The library estimates peak
   live bytes, then inflates that into a calibrated upper bound (risk
   level alpha). It does not open Python or notebook source and infer
   tensors from the code.

3. Admission control
   Before a job: proceed, grow the pool, recommend a smaller batch, or
   reject. Target: P(actual peak > bound) <= alpha.

4. Lifetime-aware placement
   Uses the same buffer declarations to pack allocations so overlapping-
   lifetime buffers do not fight for the same space. ocl_realloc can
   grow by mapping adjacent pages instead of copy-and-free.

5. Calibration
   You feed (predicted, actual) pairs. It learns a safety multiplier.
   Save/load that state.

6. Telemetry and replay
   Counts, peaks, fragmentation, malloc latency percentiles. Export
   JSON/CSV. Record an allocation trace for later replay.

7. Drop-in hooks
   - PyTorch: ocl_pytorch_alloc / ocl_pytorch_free via CUDAPluggableAllocator
   - Existing C/CUDA: #define OCL_INTERCEPT_CUDA_MALLOC remaps
     cudaMalloc / cudaFree

Init flags (ocl_init / ocl_init_ex config):
   planner, relocation, admission, tracing, growable pool, thread cache

What the cats-vs-dogs uncommented notebook cell uses:
   only ocl_pytorch_alloc / ocl_pytorch_free.
   Prediction, admit, and plan are the C API
   (ocl_predict_pipeline, ocl_admit, ocl_plan_pipeline) and are not
   called from that notebook.


PUBLIC FUNCTIONS
----------------

Lifecycle
  ocl_config_default          Fill a config with defaults
  ocl_init / ocl_init_ex      Start the runtime (pool size, flags,
                              backend, alpha)
  ocl_shutdown                Tear down
  ocl_is_initialized          Already started?
  ocl_backend_name            Which backend is live
  ocl_backend_caps            Backend capability bits
  ocl_mem_info                Free / total bytes
  ocl_version_string          Version
  ocl_error_string            Error code to text

Allocation
  ocl_malloc                  Allocate device (or mock) memory
  ocl_realloc                 Resize; in-place when VMM allows
  ocl_free                    Free
  ocl_malloc_planned          Allocate at a precomputed plan offset
  ocl_allocation_size         Size of a live block (including rounding)
  ocl_defragment              Relocate to reduce fragmentation

PyTorch hook
  ocl_pytorch_alloc           Allocator entry for CUDAPluggableAllocator
  ocl_pytorch_free            Matching free

Prediction and batch advice
  ocl_tensor_bytes            Bytes for a tensor descriptor
  ocl_predict_peak_memory     Point estimate for one kernel
  ocl_predict_pipeline        Point estimate + calibrated envelope for
                              a pipeline
  ocl_recommend_batch_size    Largest batch that fits a VRAM cap
                              (one kernel)
  ocl_recommend_batch_size_pipeline
                              Same, full pipeline + alpha

Calibration
  ocl_calibration_observe     Record predicted vs actual peak
  ocl_calibration_set_alpha   Set risk level
  ocl_calibration_stats       Coverage, slack, multiplier
  ocl_calibration_save        Persist calibrator state
  ocl_calibration_load        Load calibrator state
  ocl_calibration_reset       Clear observations

Admission and planner
  ocl_admit                   Proceed / grow pool / reduce batch / reject
  ocl_plan_pipeline           Compute placement and install the plan
  ocl_plan_clear              Drop the plan
  ocl_plan_pointer            Current pointer for a planned buffer
                              (re-read after relocate)

Telemetry
  ocl_get_stats               Counters, peaks, fragmentation, latencies
  ocl_reset_stats             Clear stats
  ocl_report_actual_batch     What batch you actually ran
  ocl_export_telemetry_json   Write stats as JSON
  ocl_export_telemetry_csv    Write stats as CSV
  ocl_telemetry_annotate      Stamp extra key/value on exports
  ocl_trace_begin             Start allocation event trace
  ocl_trace_end               Stop allocation event trace

CUDA helper header (include/opencuda/opencuda_cuda.h)
  ocl_init_cuda               Init for a CUDA device (mock if no CUDA build)
  ocl_cudaMalloc / ocl_cudaFree
  ocl_cudaMallocAsync / ocl_cudaFreeAsync
                              Wrappers used when intercept is on
  #define OCL_INTERCEPT_CUDA_MALLOC
                              Rename cudaMalloc/cudaFree to those wrappers

Python package (opencudalab)
  library_path()              Path to the .so / .dylib / .dll
  load()                      ctypes load of that library
  python -m opencudalab       Runs the ResNet with/without compare helper


SOURCE OF TRUTH
---------------

include/opencuda/opencuda.h
include/opencuda/opencuda_cuda.h
python/opencudalab/__init__.py
