diff --git a/specs/physics/physical_limits.t27 b/specs/physics/physical_limits.t27 new file mode 100644 index 0000000000..e245622882 --- /dev/null +++ b/specs/physics/physical_limits.t27 @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: Apache-2.0 +// specs/physics/physical_limits.t27 -- the published physical limits of computation, as functions, +// so that any process (a compile, a next-token step, a particle step) can be priced against them. +// +// THE MODEL: five bounds, each a closed formula in CODATA 2022 constants. +// Landauer (R. Landauer, IBM J. Res. Dev. 5, 183, 1961): erasing one bit at temperature T costs +// E >= k_B T ln 2. +// Margolus-Levitin (N. Margolus, L. Levitin, Physica D 120, 188, 1998): a system of mean energy E +// above its ground state passes through at most 2E / (pi hbar) orthogonal states per second. +// Bremermann (H. Bremermann, 1962): at most c^2 / h bits per second per kilogram of mass; with +// E = m c^2 this is a quarter of the Margolus-Levitin rate (test "ML is four Bremermann"). +// Bekenstein (J. Bekenstein, Phys. Rev. D 23, 287, 1981): a system of radius R and energy E holds +// at most I = 2 pi R E / (hbar c ln 2) bits. +// Holographic ('t Hooft, gr-qc/9310026, 1993; L. Susskind, J. Math. Phys. 36, 6377, 1995): the +// bits behind a surface of area A are at most A / (4 l_P^2 ln 2), l_P^2 = hbar G / c^3. +// The constants are CODATA 2022 (NIST SP 961; https://physics.nist.gov/cuu/Constants/): k_B, h and c +// are exact by the 2019 SI; hbar is derived as h / (2 pi), never typed in (the truncated +// 1.054571817e-34 is 6.1e-10 short and test "hbar is h over 2 pi" rejects it); G = 6.67430e-11 has +// a relative uncertainty of 2.2e-5, so everything below that uses G is good to about 1e-5 and no +// closer, whatever the digits say. +// +// A CROSS-CHECK THAT CAN FAIL: for a Schwarzschild horizon, R = 2 G m / c^2 and E = m c^2, the +// Bekenstein bound and the holographic bound are the same number (test "a horizon saturates both"). +// They come from two different arguments and share only the constants, so agreement to 1e-12 says +// the constants, the factors of 2 and 4 and the ln 2 are mutually consistent. +// +// PRICING A TOKEN: `gap` divides the energy a process really spent by the Landauer cost of the bits +// it produced. The only token figure with a source is the per-prompt one: the median Gemini Apps +// text prompt consumes 0.24 Wh (C. Elsworth et al., "Measuring the environmental impact of +// delivering AI at Google Scale", arXiv:2508.15734, 2025, abstract), which includes the whole +// serving stack, not only the GPU. Tokens per prompt, the vocabulary size and the FLOPs per token +// are NOT sourced here and are labelled UNVERIFIED; the verdict does not lean on them: test "the +// verdict survives the unverified inputs" brackets the token energy over four decades and the gap +// stays above 1e17. +// Status labels, per figure: SOURCED (cited above) or UNVERIFIED (an illustrative round number). +// +// WHAT IT DOES NOT CLAIM: no machine is near any of these limits and none of the ratios is an +// efficiency score; they are floors, and a floor 1e19 below the bill says only that the bill is +// not set by thermodynamics. Index bits (the ceiling of log2 of the vocabulary) over-count the +// information of a token, so the gap printed is a lower bound on the gap per true bit; the +// arithmetic inside the chip erases far more bits than the token carries, which is why a gate-level +// price would be higher and is not computed. Bremermann and Margolus-Levitin bound the speed of an +// idealised isolated system, Bekenstein and the holographic bound its size; none says how to build +// one. The holographic principle is a conjecture ('t Hooft, Susskind); the bound is used here as a +// formula with a known source, not as a statement that the universe is a hologram. No constant here +// comes from the V = n * 3^k * pi^m * phi^p * e^q lattice (specs/physics/sacred_lattice.t27 shows +// those fits are at the chance rate). +// Claim status: every number below is a test; the worked values (2.871e-21 J, 1.356e50 bit/s/kg, +// 5.4258e50 ops/s for 1 kg after S. Lloyd, Nature 406, 1047, 2000, 2.5769e43 bits for 1 kg in 1 m) +// agree with the published ones to the digits given. +// phi^2 + 1/phi^2 = 3 | TRINITY + +module physical_limits { + + pub const KIND : str = "physics-limits"; + pub const ID : str = "physical-limits"; + pub const VERSION : u8 = 1; + pub const K_B : f64 = 1.380649e-23; // J/K, exact (2019 SI) + pub const H_PLANCK : f64 = 6.62607015e-34; // J s, exact (2019 SI) + pub const C_LIGHT : f64 = 299792458.0; // m/s, exact + pub const G_NEWTON : f64 = 6.67430e-11; // m^3/(kg s^2), CODATA 2022, u_r = 2.2e-5 + pub const PI : f64 = 3.141592653589793; + pub const LN2 : f64 = 0.6931471805599453; + pub const ROOM_K : f64 = 300.0; // the temperature the Landauer figure is quoted at + + pub const PROMPT_J : f64 = 864.0; // 0.24 Wh * 3600 J/Wh, median Gemini Apps text prompt + pub const TOKENS_PER_PROMPT : f64 = 500.0; // UNVERIFIED: an illustrative reply length + pub const VOCAB : f64 = 128256.0; // UNVERIFIED here: Llama 3 tokenizer size, as an example + pub const FLOPS_PER_TOKEN : f64 = 140000000000.0; // UNVERIFIED: 2 * 70e9 parameters + pub const TOKEN_SECONDS : f64 = 0.001; // UNVERIFIED: one token per millisecond + + pub const STATUS_SOURCED : u8 = 0; + pub const STATUS_UNVERIFIED : u8 = 1; + pub const FIG_PROMPT_J : u8 = 0; + pub const FIG_TOKENS : u8 = 1; + pub const FIG_VOCAB : u8 = 2; + pub const FIG_FLOPS : u8 = 3; + pub const FIG_SECONDS : u8 = 4; + pub const FIG_COUNT : u8 = 5; + + // Which of the figures above has a source and which is a round number. + fn figure_status(which: u8) -> u8 { + if (which == FIG_PROMPT_J) { + return STATUS_SOURCED; + } + return STATUS_UNVERIFIED; + } + + fn sourced_count() -> u8 { + var n : u8 = 0; + var i : u8 = 0; + while (i < FIG_COUNT) { + if (figure_status(i) == STATUS_SOURCED) { + n = n + 1; + } + i = i + 1; + } + return n; + } + + // hbar = h / (2 pi), derived because h is the exact constant. + fn hbar() -> f64 { + return H_PLANCK / (2.0 * PI); + } + + // Landauer: the least energy, in joules, to erase one bit at temperature t kelvin. + fn landauer_j(t: f64) -> f64 { + return K_B * t * LN2; + } + + // Margolus-Levitin: operations per second available to a system of energy e joules. + fn ml_ops_per_s(e: f64) -> f64 { + return 2.0 * e / (PI * hbar()); + } + + // The same bound over a stretch of secs seconds. + fn ml_ops(e: f64, secs: f64) -> f64 { + return ml_ops_per_s(e) * secs; + } + + fn rest_energy(m: f64) -> f64 { + return m * C_LIGHT * C_LIGHT; + } + + // Bremermann: bits per second for a mass of m kilograms. + fn bremermann(m: f64) -> f64 { + return m * C_LIGHT * C_LIGHT / H_PLANCK; + } + + // Bekenstein: bits in a sphere of radius r metres holding e joules. + fn bekenstein_bits(r: f64, e: f64) -> f64 { + return 2.0 * PI * r * e / (hbar() * C_LIGHT * LN2); + } + + // The Planck length squared, hbar G / c^3, in square metres. + fn planck_length_sq() -> f64 { + return hbar() * G_NEWTON / (C_LIGHT * C_LIGHT * C_LIGHT); + } + + // Holographic: bits behind a surface of area a square metres. + fn holographic_bits(a: f64) -> f64 { + return a / (4.0 * planck_length_sq() * LN2); + } + + fn sphere_area(r: f64) -> f64 { + return 4.0 * PI * r * r; + } + + // The radius of the horizon of a mass of m kilograms. + fn schwarzschild_radius(m: f64) -> f64 { + return 2.0 * G_NEWTON * m / (C_LIGHT * C_LIGHT); + } + + // The bits a horizon holds by each of the two bounds, for the same mass. + fn horizon_bekenstein(m: f64) -> f64 { + return bekenstein_bits(schwarzschild_radius(m), rest_energy(m)); + } + + fn horizon_holographic(m: f64) -> f64 { + return holographic_bits(sphere_area(schwarzschild_radius(m))); + } + + // Bits needed to name one of n symbols: the smallest k with 2^k >= n. + fn index_bits(n: f64) -> f64 { + var k : f64 = 0.0; + var cap : f64 = 1.0; + while (cap < n) { + cap = cap * 2.0; + k = k + 1.0; + } + return k; + } + + // The energy of one token, from the per-prompt figure and a reply length. + fn token_energy_j(prompt_j: f64, tokens: f64) -> f64 { + return prompt_j / tokens; + } + + // How many times the energy spent exceeds the Landauer cost of erasing bits bits at t kelvin. + fn gap(e_j: f64, bits: f64, t: f64) -> f64 { + return e_j / (bits * landauer_j(t)); + } + + fn rel_close(a: f64, b: f64, tol: f64) -> bool { + return @abs(a - b) <= tol * @abs(b); + } + + test "Landauer at 300 K is 2.871e-21 J and scales with T" { + assert(rel_close(landauer_j(ROOM_K), 2.870978885078724e-21, 0.000000001)); + assert(rel_close(landauer_j(ROOM_K), 2.87e-21, 0.001)); + assert(rel_close(landauer_j(600.0), 2.0 * landauer_j(ROOM_K), 0.000000000001)); + assert(landauer_j(0.0) == 0.0); + } + + test "hbar is h over 2 pi, not the truncated 1.054571817e-34" { + assert(rel_close(hbar(), 1.0545718176461565e-34, 0.000000000001)); + assert(!rel_close(1.054571817e-34, hbar(), 0.0000000001)); + } + + test "Margolus-Levitin: 1 kg of rest energy gives 5.4258e50 ops per second" { + assert(rel_close(ml_ops_per_s(1.0), 6.036760718568607e33, 0.000000000001)); + assert(rel_close(ml_ops_per_s(rest_energy(1.0)), 5.4258e50, 0.0001)); + assert(rel_close(ml_ops(2.0, 0.5), ml_ops_per_s(1.0), 0.000000000001)); + } + + test "Bremermann: 1.356e50 bits per second per kilogram" { + assert(rel_close(bremermann(1.0), 1.3563924896521321e50, 0.000000000001)); + assert(rel_close(bremermann(2.0), 2.0 * bremermann(1.0), 0.000000000001)); + } + + test "ML is four Bremermann when the energy is the rest energy" { + assert(rel_close(ml_ops_per_s(rest_energy(1.0)), 4.0 * bremermann(1.0), 0.000000000001)); + assert(rel_close(ml_ops_per_s(rest_energy(0.5)), 4.0 * bremermann(0.5), 0.000000000001)); + } + + test "Bekenstein: 1 kg in 1 m holds 2.5769e43 bits" { + assert(rel_close(bekenstein_bits(1.0, rest_energy(1.0)), 2.576908209992606e43, 0.000000000001)); + assert(rel_close(bekenstein_bits(2.0, 1.0), 2.0 * bekenstein_bits(1.0, 1.0), 0.000000000001)); + } + + test "the Planck length is 1.616255e-35 m" { + assert(rel_close(@sqrt(planck_length_sq()), 1.616255e-35, 0.000001)); + assert(rel_close(planck_length_sq(), 2.6122803039748724e-70, 0.000000000001)); + } + + test "holographic: 1 square metre holds 1.3807e69 bits" { + assert(rel_close(holographic_bits(1.0), 1.3806855247250303e69, 0.000000000001)); + assert(rel_close(holographic_bits(sphere_area(1.0)), 1.7350206005575696e70, 0.000000000001)); + } + + test "a horizon saturates both bounds: 3.8273e16 bits for 1 kg" { + assert(rel_close(horizon_bekenstein(1.0), horizon_holographic(1.0), 0.000000000001)); + assert(rel_close(horizon_bekenstein(1.0), 3.827306673242558e16, 0.000000000001)); + assert(rel_close(horizon_bekenstein(3.0), 9.0 * horizon_bekenstein(1.0), 0.000000000001)); + assert(rel_close(horizon_bekenstein(5.0), horizon_holographic(5.0), 0.000000000001)); + } + + test "a token needs 17 index bits and costs 1.728 J on the sourced prompt figure" { + assert(index_bits(2.0) == 1.0); + assert(index_bits(3.0) == 2.0); + assert(index_bits(1024.0) == 10.0); + assert(index_bits(VOCAB) == 17.0); + assert(rel_close(token_energy_j(PROMPT_J, TOKENS_PER_PROMPT), 1.728, 0.000000000001)); + } + + test "one GPU token sits 3.5e19 above the Landauer cost of its bits" { + const e = token_energy_j(PROMPT_J, TOKENS_PER_PROMPT); + const bits = index_bits(VOCAB); + const g = gap(e, bits, ROOM_K); + assert(rel_close(g, 3.540501790236684e19, 0.000000001)); + assert(g > 1.0e19); + assert(g < 1.0e20); + } + + test "the verdict survives the unverified inputs" { + assert(gap(0.01, 17.0, ROOM_K) > 1.0e17); + assert(gap(100.0, 17.0, ROOM_K) > 1.0e17); + assert(gap(token_energy_j(PROMPT_J, 5000.0), 17.0, ROOM_K) > 1.0e17); + assert(gap(token_energy_j(PROMPT_J, 50.0), 17.0, ROOM_K) > 1.0e17); + assert(gap(1.0, 17.0, ROOM_K) > gap(1.0, 17.0, 3000.0)); + } + + test "the token's energy could pay for 1e31 operations; the model does 1.4e11" { + const e = token_energy_j(PROMPT_J, TOKENS_PER_PROMPT); + const allowed = ml_ops(e, TOKEN_SECONDS); + assert(rel_close(allowed, 1.0431522521686553e31, 0.000000001)); + assert(allowed / FLOPS_PER_TOKEN > 1.0e19); + } + + test "only the per-prompt figure has a source" { + assert(figure_status(FIG_PROMPT_J) == STATUS_SOURCED); + assert(figure_status(FIG_TOKENS) == STATUS_UNVERIFIED); + assert(figure_status(FIG_VOCAB) == STATUS_UNVERIFIED); + assert(figure_status(FIG_FLOPS) == STATUS_UNVERIFIED); + assert(figure_status(FIG_SECONDS) == STATUS_UNVERIFIED); + assert(sourced_count() == 1); + } + + test "VERSION says what the header says" { + assert(VERSION == 1); + assert(FIG_COUNT == 5); + assert(rel_close(PROMPT_J, 0.24 * 3600.0, 0.000000000001)); + } +} +// phi^2 + 1/phi^2 = 3 | TRINITY