Skip to main content

Minimal scalar-based automatic differentiation engine

Project description

coregrad

A minimal, mathematically explicit reverse-mode automatic differentiation engine operating on scalar-valued computational graphs. The system constructs a dynamic directed acyclic graph (DAG) during the forward evaluation pass and evaluates exact analytical gradients through localized topological backpropagation.

coregrad is engineered strictly for foundational deep learning systems research, architectural prototyping, and algorithmic verification of gradient propagation dynamics at the atomic (scalar) level.


Theoretical Foundations

Reverse-Mode Automatic Differentiation

For a scalar-valued objective function (or loss) $L: \mathbb{R}^n \to \mathbb{R}$ evaluated over a sequence of intermediate computational nodes, automatic differentiation systematically evaluates the partial derivatives $\frac{\partial L}{\partial x_i}$ for all inputs $x_i$.

Reverse-mode automatic differentiation executes this in two phases:

  1. Forward Pass: Computes the numerical value of each node along the execution trace.
  2. Backward Pass: Traverses the computational graph in reverse topological order, applying the chain rule of calculus.

The Chain Rule and Local Gradient Accumulation

Given an intermediate node $z$ that serves as an input to a subsequent node $u$, the total derivative of the objective function $L$ with respect to $z$ is accumulated across all its outgoing paths:

$$\frac{\partial L}{\partial z} = \sum_{u \in \text{Children}(z)} \frac{\partial L}{\partial u} \cdot \frac{\partial u}{\partial z}$$

Where $\frac{\partial u}{\partial z}$ represents the local gradient defined entirely by the mathematical operation generating $u$. In coregrad, nodes accumulate gradients in-place ($\mathit{grad} \leftarrow \mathit{grad} + \delta$), resolving multi-path dependencies and correctly evaluating multivariate expressions without redundant computation.


Analytical Verification: Manual vs. Computational Trace

To verify the mathematical validity of the engine, we evaluate a complex composite expression $L = f(x_1, x_2, \dots, x_8)$ using an intermediate structural sequence $Z$.

1. Primal Evaluation (Forward Pass)

Given the boundary conditions:

$$x_1 = -2, \quad x_2 = 1, \quad x_3 = -1, \quad x_4 = -4, \quad x_5 = -2, \quad x_6 = 2, \quad x_7 = -1, \quad x_8 = -1.2$$

The computational execution trace progresses sequentially:

$$\begin{aligned} z_1 &= x_1 \cdot x_2 = (-2) \cdot 1 = -2
z_2 &= z_1 + x_3 = (-2) + (-1) = -3
z_3 &= z_2 - x_4 = (-3) - (-4) = 1
z_4 &= z_3^{x_5} = 1^{-2} = 1
z_5 &= \frac{z_4}{x_6} = \frac{1}{2} = 0.5
z_6 &= \frac{x_7}{z_5} = \frac{-1}{0.5} = -2
L &= z_6 + x_8 = (-2) + (-1.2) = -3.2 \end{aligned}$$


2. Adjoint Propagation (Backward Pass)

Applying reverse-mode automatic differentiation starting from the objective boundary condition $\frac{\partial L}{\partial L} = 1$, the analytical gradients are propagated downstream through strict, isolated vertical resolutions:

$$\frac{\partial L}{\partial z_6} = 1.0$$

$$\frac{\partial L}{\partial x_8} = 1.0$$

$$\frac{\partial L}{\partial x_7} = \frac{\partial L}{\partial z_6} \cdot \frac{\partial z_6}{\partial x_7} = 1 \cdot \frac{1}{z_5} = \frac{1}{0.5} = 2.0$$

$$\frac{\partial L}{\partial z_5} = \frac{\partial L}{\partial z_6} \cdot \frac{\partial z_6}{\partial z_5} = 1 \cdot \left(-\frac{x_7}{z_5^2}\right) = -\frac{-1}{0.5^2} = 4.0$$

$$\frac{\partial L}{\partial z_4} = \frac{\partial L}{\partial z_5} \cdot \frac{\partial z_5}{\partial z_4} = 4 \cdot \frac{1}{x_6} = \frac{4}{2} = 2.0$$

$$\frac{\partial L}{\partial x_6} = \frac{\partial L}{\partial z_5} \cdot \frac{\partial z_5}{\partial x_6} = 4 \cdot \left(-\frac{z_4}{x_6^2}\right) = 4 \cdot \left(-\frac{1}{2^2}\right) = -1.0$$

$$\frac{\partial L}{\partial z_3} = \frac{\partial L}{\partial z_4} \cdot \frac{\partial z_4}{\partial z_3} = 2 \cdot \left(x_5 \cdot z_3^{x_5 - 1}\right) = 2 \cdot \left(-2 \cdot 1^{-3}\right) = -4.0$$

$$\frac{\partial L}{\partial x_5} = \frac{\partial L}{\partial z_4} \cdot \frac{\partial z_4}{\partial x_5} = 2 \cdot \left(z_4 \cdot \ln(z_3)\right) = 2 \cdot (1 \cdot \ln(1)) = 0.0$$

$$\frac{\partial L}{\partial z_2} = \frac{\partial L}{\partial z_3} \cdot \frac{\partial z_3}{\partial z_2} = -4 \cdot 1 = -4.0$$

$$\frac{\partial L}{\partial x_4} = \frac{\partial L}{\partial z_3} \cdot \frac{\partial z_3}{\partial x_4} = -4 \cdot (-1) = 4.0$$

$$\frac{\partial L}{\partial z_1} = \frac{\partial L}{\partial z_2} \cdot \frac{\partial z_2}{\partial z_1} = -4 \cdot 1 = -4.0$$

$$\frac{\partial L}{\partial x_3} = \frac{\partial L}{\partial z_2} \cdot \frac{\partial z_2}{\partial x_3} = -4 \cdot 1 = -4.0$$

$$\frac{\partial L}{\partial x_1} = \frac{\partial L}{\partial z_1} \cdot \frac{\partial z_1}{\partial x_1} = -4 \cdot x_2 = -4 \cdot 1 = -4.0$$

$$\frac{\partial L}{\partial x_2} = \frac{\partial L}{\partial z_1} \cdot \frac{\partial z_1}{\partial x_2} = -4 \cdot x_1 = -4 \cdot (-2) = 8.0$$


3. Verification Matrix

The analytical derivations match the absolute numerical outputs evaluated by the coregrad execution engine:

Graph Node ($v$) Primal Value ($v.\mathit{data}$) Adjoint Gradient ($v.\mathit{grad}$)
$x_1$ -2.0000 -4.0000
$x_2$ 1.0000 8.0000
$x_3$ -1.0000 -4.0000
$x_4$ -4.0000 4.0000
$x_5$ -2.0000 0.0000
$x_6$ 2.0000 -1.0000
$x_7$ -1.0000 2.0000
$x_8$ -1.2000 1.0000
$z_1$ -2.0000 -4.0000
$z_2$ -3.0000 -4.0000
$z_3$ 1.0000 -4.0000
$z_4$ 1.0000 2.0000
$z_5$ 0.5000 4.0000
$z_6$ -2.0000 1.0000
$L$ -3.2000 1.0000

Derived Computational Graph Structure

The verified execution trace matches the exact topological resolution mapped below: Computational Graph Structure


Core Operations

The Scalar abstraction overloads standard Python magic methods to construct dynamic dependencies using internal pointer metadata (_prev and _op).

Mathematical Operation Operator Overload Local Gradient Activation Primitive ($\Delta = \text{out}.\mathit{grad}$)
Addition a + b $\frac{\partial L}{\partial a} \mathrel{+}= \Delta, \quad \frac{\partial L}{\partial b} \mathrel{+}= \Delta$
Subtraction a - b $\frac{\partial L}{\partial a} \mathrel{+}= \Delta, \quad \frac{\partial L}{\partial b} \mathrel{-}= \Delta$
Multiplication a * b $\frac{\partial L}{\partial a} \mathrel{+}= b \cdot \Delta, \quad \frac{\partial L}{\partial b} \mathrel{+}= a \cdot \Delta$
Division a / b $\frac{\partial L}{\partial a} \mathrel{+}= \frac{1}{b} \cdot \Delta, \quad \frac{\partial L}{\partial b} \mathrel{+}= \left(-\frac{a}{b^2}\right) \cdot \Delta$
Power Scaling a ** b $\frac{\partial L}{\partial a} \mathrel{+}= \left(b \cdot a^{b-1}\right) \cdot \Delta$
Hyperbolic Tangent a.tanh() $\frac{\partial L}{\partial a} \mathrel{+}= \left(1 - \tanh^2(a)\right) \cdot \Delta$

Implementation & Usage

The following verification script demonstrates primal structural mapping, reverse execution initialization via .backward(), and topological adjoint propagation across a single neuron optimization checkpoint.

from coregrad.engine import Scalar

# Weights initialization
w1 = Scalar(-0.34, var_name="w1")
w2 = Scalar(0.67, var_name="w2")

# Bias initialization
b = Scalar(-1, var_name="b")

# Input boundary conditions
x1 = Scalar(-2, var_name="x1")
x2 = Scalar(-0.3, var_name="x2")

# Forward Pass Execution Trace
z1 = w1 * x1; z1.var_name = "z1"
z2 = w2 * x2; z2.var_name = "z2"
z3 = z1 + z2; z3.var_name = "z3"
z4 = z3 + b; z4.var_name = "z4"
y = z4.tanh(); y.var_name = "y"

# Adjoint Propagation initialization
y.backward()

# Inspection of evaluated analytical gradients
print(f"Logit Gradient (dy/dy): {y.grad}")
print(f"Weight 1 Gradient (dy/dw1): {w1.grad}")
print(f"Weight 2 Gradient (dy/dw2): {w2.grad}")
print(f"Bias Gradient (dy/db): {b.grad}")

Downstream Application Extensions

To verify the optimization capability of this scalar engine within high-dimensional non-linear spaces, an empirical implementation of a deep feedforward network classifier was constructed.

The accompanying repository evaluates coregrad on the standard MNIST digit classification task, verifying optimization stability under standard batch stochastic gradient descent (SGD).


Author

Himanshu Singh Research Engineer

Year: 2026

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

coregrad-0.1.0.tar.gz (11.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

coregrad-0.1.0-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file coregrad-0.1.0.tar.gz.

File metadata

  • Download URL: coregrad-0.1.0.tar.gz
  • Upload date:
  • Size: 11.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for coregrad-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3bd29412feae24f7fe49166d500909c5f71085d000e763b759aa0f89eb068f4b
MD5 ac808ef2a49aaaf56edba727f511b1b6
BLAKE2b-256 f7f2646961c634ea99be99a81c5ed77ec561eec357cb0bba7e93c16838995f14

See more details on using hashes here.

File details

Details for the file coregrad-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: coregrad-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for coregrad-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 64f7da7dd5bb9ee40a5efdc107ecab45c043bcce4cb6c9eae7b6c0b0ca53fe64
MD5 a3f160426bd3191d121da305204fd075
BLAKE2b-256 44da7bee821558f31eb4bb98c27f0e6679077c019a0d5885cec4ec72435dcd45

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page