Metadata-Version: 2.4
Name: aadc
Version: 2.8.0
Summary: AADC-NG: adjoint algorithmic differentiation for Python
Author-email: Matlogica <info@matlogica.com>
License-Expression: LicenseRef-Matlogica-EULA
Project-URL: Homepage, https://matlogica.com
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: C++
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Intended Audience :: Financial and Insurance Industry
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE.txt
License-File: THIRD-PARTY-NOTICES.txt
Requires-Dist: numpy>=1.21.0
Requires-Dist: scipy>=1.11.0
Dynamic: license-file

# aadc

**Proprietary software. The free licence is the AADC Community Edition
Licence, and it covers NON-COMMERCIAL and ACADEMIC use only** — personal
study, personal research, hobby projects, publicly available open-source
development, and research or teaching at a university or recognised research
institute. Everything else is Production Use and requires a commercial licence,
including evaluation by a company and any calculation whose output reaches a
book, a client report or a regulator.

**What the Community Edition runs at full speed:** the interpreter and the
**JIT** backends. `compile()`, `compile('auto')`, `compile('jit')`,
`compile('avx2')` and `compile('scalar')` all select a JIT backend, so the
default path — and every path named after an instruction set — is the fast one,
with no C compiler needed on the box.

Two host-dependent exceptions, stated rather than discovered: on **non-Apple
64-bit ARM** the vector backends (what `compile()` picks there) need a licence
with the `arm64` feature, and on a **pre-AVX2 x86-64** there is no scalar JIT
at all, so `compile('scalar')` falls back to the C emitter and needs
`codegen_c`. Both report the feature they want; neither changes your numbers.

What is licensed is the **ahead-of-time code generators**, which write a
translation unit to disk that you keep, inspect, compile and ship:
`compile('avx2-c')`, `compile('scalar-c')`, `compile('avx512-c')`, the
assembly and PTX backends. On top of that, AVX-512 in any form and
double-precision GPU need their own features.

Ask for one of those without the matching licence and **no kernels install for
it**: the affected segments replay on the interpreter, which produces
**identical results, more slowly**. You are told once — `compile()` returns the
reason in its result (`unavailable`) and raises a `BackendUnavailableWarning`
naming the feature.

Nothing expires and nothing contacts a server. Every numerical answer is the
same in every tier — the licence buys speed, never correctness.

The full terms ship inside the wheel — read
`<site-packages>/aadc-<version>.dist-info/licenses/LICENSE.txt`, and
`THIRD-PARTY-NOTICES.txt` beside it for the bundled third-party components.
Commercial and free full-performance academic licences: info@matlogica.com.

Adjoint algorithmic differentiation for Python: record a calculation once,
then replay it and get exact derivatives of every output with respect to every
input.

## Install

```sh
pip install aadc
```

Supports CPython 3.10 and later. One abi3 wheel serves every CPython >= 3.11
on a given platform (the extension is built against the CPython Limited API);
3.10 is served by its own version-specific wheel.

Version 2.2.0 renames the distribution from `aadc-ng` to `aadc`, continuing
the PyPI `aadc` 1.x line. The import (`import aadc`) and every binary name
(`_aadc_ng`, the `aadc_ng` runtime package, `libaadc-ng`) are unchanged.

**Upgrading from an environment that has `aadc-ng` installed:** uninstall it
FIRST (`pip uninstall -y aadc-ng`), then `pip install aadc`. pip treats the
two as unrelated distributions that own the same files, so installing `aadc`
over `aadc-ng` works — but a later `pip uninstall aadc-ng` would then delete
the files out from under `aadc`, leaving an install whose metadata says it is
fine and whose `import aadc` fails.

## Check your entitlement in your own CI

```python
import aadc

s = aadc.license_status()
assert s["state"] == "licensed", s["detail"]
```

`state` is `unlicensed`, `licensed` or `expired`. **`expired` means the token
is genuine but this build is newer than its version ceiling** — the
entitlement is to older builds, which keep running at full speed. Compare
`version_max` against `build_version` to see the gap.

Token location, in order: `$AADC_NG_LICENSE`, `./aadc-ng.lic`,
`~/.aadc-ng/license`.

## One shared library per process

`libaadc-ng` carries thread-local recording state, so a second copy in one
process gives correct values and **silently zero gradients**. This wheel is the
only one that ships it; anything else linking it must resolve it by RPATH.
Assert it:

```python
import aadc_ng
aadc_ng.check_single_image()   # raises if more than one is mapped
```
