How Aner works
Follow an Aner program from source and static checks to the native runtime, CPU and GPU kernels, parallel workers and the proposed native compiler.
Implemented in developmentAner gives researchers a checked scientific language over a native execution engine. You write an experiment in .aner source; Aner checks the program, interprets its control flow, and calls native operations for data, numerical work and supported models. Those operations can run on a CPU or, where supported and explicitly selected, a local accelerator.
This page explains the current development architecture and the proposed path toward compiling Aner programs for a target machine. Available APIs can differ between an installed release and the development engine; use release and development status to check availability.
Two different things are built
The Aner engine is implemented in C++, with a C++20 build baseline. Maintainers compile that engine and its native modules into the platform’s aner executable. A researcher installs the appropriate binary and can run Aner programs without installing a C++ compiler.
Your Aner program follows a separate path. Today, opening or running an .aner file does not translate that program into C++ or produce a new native executable. The already compiled Aner engine reads and executes it. Numerical operations still reach native kernels through that engine.
Solid arrows show the current execution path. The dashed branch is a proposed compiler direction, with no committed release date.
From source to a result
The frontend first turns source text into tokens, parses a syntax tree, resolves names and checks types. This produces a checked representation of the program, preserving source locations for diagnostics. Checking can catch problems such as an unknown name, an invalid call or an incompatible type before execution.
The interpreter then evaluates that checked program: variables, conditions, function calls and loops determine which work runs. A call to a supported native operation crosses into the C++ runtime. For example, matrix multiplication reaches a numerical kernel rather than asking the interpreter to multiply every matrix cell through an Aner callback.
Static checking and runtime validation work together. Some properties depend on actual data: a tensor’s dimensions, an allocation request, a file’s contents or whether a GPU can initialize. The relevant native operation checks those properties when needed and reports failures through Aner’s diagnostics.
Built in modules connect to this native implementation. Their public contracts define accepted values, resource limits and errors; using a module does not make every operation a GPU operation. Ordinary scalar control flow remains interpreted, and typed arrays currently perform their numerical work on CPU. See the language reference, Tensor reference and module catalogue for the exact supported surfaces.
How CPU, CUDA and Metal fit together
The runtime owns numerical buffers, device placement, transfers and completion. Supported Tensor operations dispatch according to the operands’ actual placement and precision. An execution profile can prepare that placement before work begins; changing the profile leaves existing values unchanged. The backend calls the platform’s native libraries and runtime, which in turn use the operating system and hardware driver to execute work on the device.
| Execution target | Native route | Supported Tensor precision |
|---|---|---|
| CPU | Portable C++ kernels; eligible builds can use Apple Accelerate or an installed CBLAS provider | Float64 and Float32 |
| NVIDIA GPU | CUDA kernels and cuBLAS through the CUDA runtime and a compatible NVIDIA driver | Float64 and Float32 |
| Apple GPU | Metal kernels and Metal Performance Shaders through Apple’s native frameworks and driver | Float32 |
A GPU path requires both an Aner binary containing that backend and compatible hardware/runtime support. Installing a driver alone does not add a missing backend. The native runtime handles queues or streams, device buffers and synchronization; an Aner program does not configure those low level objects itself. A backend may prepare device kernels, including compiling Metal shader source, while the Aner program still follows the interpreter path above.
Precision is an explicit scientific choice. The default execution profile is CPU, Float64, with the preserve policy. Automatic device selection considers available CUDA, then Metal/MPS, then CPU, and applies the chosen precision policy. On available Metal/MPS, preserving Float64 resolves to CPU Float64 with a reported fallback; adapt permits Float32 when the selected backend lacks Float64, and fast intentionally selects Float32. Explicitly requesting an unavailable accelerator fails. Tensor operations do not implicitly move or cast their operands.
These choices concern supported operations, not arbitrary GPU execution of a source program. Actual speed depends on workload size, transfers, synchronization, precision and hardware. Inspect the resolved profile and compare numerical results before interpreting timing. The device and performance guide contains runnable examples and the complete policy.
From one computer to several
Aner separates the scientific workload from an explicit execution context. Local repetitions, remote native tasks and replicated model training have different contracts; they are separate ways to organize work.
Local independent repetitions. parallel.repeat admits a checked, isolated task function, copies its initial parameters and schedules iterations across a bounded set of local CPU workers. Each iteration has private interpreter state and a deterministic seed. Successful numeric outputs are published in iteration order. This supports repeated simulations and independent CPU work without changing the task into a GPU kernel.
Configured worker processes. Supported native CPU tasks can run through explicitly configured local processes or SSH workers. Workers must be enrolled and compatible. The runtime coordinates the admitted task and validates its results; it does not discover a cluster or send any arbitrary source function to another computer. Remote execution of general repetition callbacks remains future work.
Supported Dense model replicas. parallel.fit gives each worker a full model replica and a disjoint share of the training rows. Workers compute forward/backward work on their declared CPU, CUDA or Metal/MPS backend. Gradient sums and sample counts return through host communication; the coordinator combines them with sample weighting, performs one canonical CPU optimizer update and distributes the next parameters. This is replicated training, with separate worker memory, rather than a model split across pooled GPU memory. Direct GPU collectives, general model sharding and durable distributed recovery remain future work.
Begin with CPU parallelism in practice, then use the repetition guide, worker execution reference or distributed Dense training guide for the workload you need.
The proposed native compiler
The next execution path would reuse the frontend and introduce a typed intermediate representation, or IR: a lower level description that retains Aner’s types and operations. Native lowering and compiler infrastructure such as LLVM could then generate an executable for a chosen machine. That executable would call the shared runtime for numerical kernels, allocation, shape checks and backend access.
This is an ahead of time compilation direction: produce the target executable before launching it. A just in time compiler would instead generate native code during a run; it is a separate possibility and is not currently implemented.
The aim is to reduce interpretation overhead where a workload benefits, while preserving language semantics and numerical contracts. Compiling scalar control flow would not automatically remove data movement, provide an unsupported GPU operation or distribute work across a cluster. Target compatibility, correctness tests and measured workloads would determine where native compilation is useful.
This path is planned. Native compilation through aner build is not implemented, and no particular speedup or release date is promised. Researchers can already exercise native numerical operations and supported accelerators through the interpreter. The language architecture proposal describes the intended compiler boundary; the roadmap separates current work from future milestones.
Read further
For the underlying infrastructure, see the LLVM frontend tutorial, NVIDIA cuBLAS documentation and Apple Metal Performance Shaders documentation. These explain technologies used or considered beneath Aner; Aner’s own references define the supported language and runtime behavior.