Analysis
API reference for chia.analysis.sustainability. These pages are generated from the docstrings in the source, so they stay in sync with the code.
Note that these sustainability analyses were chosen because, as far as we could tell, they did not have public codebases for performing these analyses. We exclude frameworks, which provide their own codebases publically, like ACT and GreenSku framework, and instead direct people to those frameworks directly and encourage them to integrate CHIA with the already public codebases of those frameworks.
Focal
FOCAL: a first-order carbon model for comparing processor architectures.
Implements the Normalized Carbon Footprint (NCF) metric from Lieven Eeckhout, “FOCAL: A First-Order Carbon Model to Assess Processor Sustainability” (ASPLOS ‘24, https://doi.org/10.1145/3620665.3640415).
FOCAL weighs a design’s embodied footprint (proxied by chip area) against its
operational footprint (proxied by power under a fixed-time use case, or by
energy under a fixed-work use case) using a single embodied-to-operational
weight alpha in [0, 1]. Comparing a test design against a ref
baseline, the fixed-time NCF is:
NCF(test, ref) = alpha * (A_test / A_ref) + (1 - alpha) * (P_test / P_ref)
where A is chip area and P is power consumption. NCF < 1 means the
test design has a lower total carbon footprint than the reference (i.e. it is
more sustainable); NCF > 1 means it is worse; NCF == 1 means the two are
carbon-equal. The same expression holds for the fixed-work scenario with energy
substituted for power.
alpha is the embodied-to-operational weight in [0, 1]. Paper scenarios:
alpha = 0.8 (embodied-dominated, e.g. mobile and datacenter hardware) and
alpha = 0.2 (operational-dominated, e.g. always-connected devices).
- class chia.analysis.sustainability.focal.FocalComparison(ncf: float, embodied_ratio: float, operational_ratio: float, alpha_ref: float, test_pwr: float, ref_pwr: float, test_area: float, ref_area: float)[source]
Bases:
objectFOCAL comparison of a
testarchitecture against arefbaseline.Computed under the fixed-time scenario, i.e. power is the operational proxy. (Pass energy in place of power to evaluate the fixed-work scenario; the NCF expression is identical.)
- property more_sustainable: bool
True if the test design has a strictly lower carbon footprint.
- property verdict: str
Human-readable verdict for the test design relative to ref.
- property pct_change: float
Percent change in carbon footprint of test vs ref.
Negative means a reduction (more sustainable); e.g. -30.0 means the test design emits 30% less carbon than the reference.
- property breakeven_alpha: float | None
Embodied weight
alphaat which test and ref are carbon-equal.Solves
NCF(alpha) = 1for alpha at the current area and power ratios:alpha* = (1 - P_test/P_ref) / (A_test/A_ref - P_test/P_ref)
Returns None when the embodied and operational ratios are equal (NCF does not depend on alpha, so there is no crossing). A value outside [0, 1] means the verdict never flips within the valid weight range, i.e. the test design is uniformly more or less sustainable.
- chia.analysis.sustainability.focal.focal_compare(test_pwr: float, ref_pwr: float, test_area: float, ref_area: float, alpha_ref: float) FocalComparison[source]
Compare a
testarchitecture against arefbaseline with FOCAL.Computes the Normalized Carbon Footprint (NCF) of the test design relative to the reference under the fixed-time scenario:
NCF = alpha_ref * (test_area / ref_area) + (1 - alpha_ref) * (test_pwr / ref_pwr)
NCF < 1means the test design has a lower total carbon footprint than the reference (more sustainable);NCF > 1means it is worse.- Parameters:
test_pwr – Power of the test design (operational proxy, numerator). Substitute energy to evaluate the fixed-work scenario instead.
ref_pwr – Power of the reference design (operational proxy, denominator).
test_area – Chip area of the test design (embodied proxy, numerator).
ref_area – Chip area of the reference design (embodied proxy, denominator).
alpha_ref – Embodied-to-operational weight in [0, 1] (the FOCAL
alpha_E2O). 0.8 = embodied-dominated, 0.2 = operational-dominated.
- Returns:
A FocalComparison with the NCF, its embodied/operational components, and convenience verdicts.
- Raises:
ValueError – if a denominator is non-positive, an input is negative, or
alpha_refis outside [0, 1].
- class chia.analysis.sustainability.focal.FocalSweep(parameter: str, values: list[float], ncf: list[float], comparisons: list[FocalComparison], breakevens: list[float], test_pwr: float, ref_pwr: float, test_area: float, ref_area: float, alpha_ref: float)[source]
Bases:
objectNCF of a test/ref pair as one FOCAL parameter is swept over a range.
- property crosses_unity: bool
True if the verdict flips (NCF crosses 1) within the swept range.
- class chia.analysis.sustainability.focal.FocalBothRefs(arch_a_ref: FocalSweep, arch_b_ref: FocalSweep)[source]
Bases:
objectTwo alpha sweeps comparing arch A and arch B, each taken as the reference.
Holds the
arch_a_refsweep (A is the reference, so the test design is B) and thearch_b_refsweep (B is the reference, so the test design is A). Seesweep_both_arches_as_reffor why both directions matter.
- chia.analysis.sustainability.focal.focal_sweep(test_pwr: float, ref_pwr: float, test_area: float, ref_area: float, alpha_ref: float, *, sweep: str = 'alpha_ref', values: Sequence[float] | None = None, num: int = 51, span: float = 2.0, plot_path: str | Path | None = None) FocalSweep[source]
Sweep one FOCAL parameter and report NCF across the range.
Holds four of the five FOCAL parameters fixed at the values passed in and varies the fifth (
sweep), recomputing the test-vs-ref NCF at each point. This mirrors the paper’s sensitivity analyses: sweepingalpha_refshows how the verdict shifts between operational- and embodied-dominated regimes, while sweeping an area or power term traces NCF against that dimension.- Parameters:
test_pwr – Nominal test power.
ref_pwr – Nominal reference power.
test_area – Nominal test area.
ref_area – Nominal reference area.
alpha_ref – Nominal embodied-to-operational weight in [0, 1].
sweep – Name of the parameter to vary; one of
SWEEPABLE_PARAMETERS.values – Explicit values to sweep. If None, a default range is built:
alpha_refsweeps [0, 1]; any other parameter sweeps fromnominal / spantonominal * span.num – Number of points in the default range (ignored if
valuesgiven).span – Multiplicative half-range for non-alpha default sweeps.
plot_path – If given, save a PNG of NCF vs the swept parameter there (requires matplotlib, imported lazily).
- Returns:
A FocalSweep with the swept values, the NCF at each, the per-point FocalComparison objects, and any NCF==1 break-even crossings.
- Raises:
ValueError – if
sweepis not a FOCAL parameter, or a default range cannot be built because the nominal swept value is non-positive.
- chia.analysis.sustainability.focal.sweep_both_arches_as_ref(arch_a_pwr: float, arch_a_area: float, arch_b_pwr: float, arch_b_area: float, *, values: Sequence[float] | None = None, num: int = 51, plot_path: str | Path | None = None) FocalBothRefs[source]
Sweep alpha comparing two architectures with each used as the reference.
The NCF metric is not symmetric:
NCF(X, Y) != 1 / NCF(Y, X)in general, because NCF is a weighted sum of the area and power ratios rather than a single ratio (in factNCF(X, Y) * NCF(Y, X) >= 1). The reference design is the denominator, so for the same alpha you can get a different NCF — and even a different verdict — depending on which architecture you pick as the reference. There is no privileged “baseline” here, so it is worth looking at both directions before concluding that one design is more sustainable.This runs two alpha sweeps over the same grid: one with arch A as the reference (test design is B) and one with arch B as the reference (test design is A). Compare the two curves at a given alpha to see the asymmetry.
- Parameters:
arch_a_pwr – Power of architecture A.
arch_a_area – Chip area of architecture A.
arch_b_pwr – Power of architecture B.
arch_b_area – Chip area of architecture B.
values – Explicit alpha values to sweep. If None, sweeps [0, 1].
num – Number of alpha points in the default range (ignored if
values).plot_path – If given, save a PNG overlaying both NCF curves vs alpha (requires matplotlib, imported lazily).
- Returns:
A FocalBothRefs holding the
arch_a_refandarch_b_refsweeps.
PFAS
PFAS-in-semiconductor-manufacturing mask data for chip PFAS/carbon modeling.
All data in this module is derived from the following work, and full credit for the underlying analysis belongs to its authors:
Mariam Elgamal, Abdulrahman Mahmoud, Gu-Yeon Wei, David Brooks, and Gage Hills. “Modeling PFAS in Semiconductor Manufacturing to Quantify Trade-offs in Energy Efficiency and Environmental Impact of Computing Systems.” arXiv preprint arXiv:2505.06727 (2025).
Abstract: https://arxiv.org/abs/2505.06727 PDF: https://arxiv.org/pdf/2505.06727
Any use of this node should cite this work.
The paper uses the number of lithography masks as a first-order proxy for the amount of PFAS (“forever chemicals”) used in chip manufacturing, because the PFAS-containing layers (photoresist, anti-reflective coatings, topcoats) scale with mask count – eq. (1): #PFAS_litho ~ number of lithography masks.
- Data provenance within the paper:
BEOL_METAL_STACK_TYPES – lithography masks per BEOL metal-stack recipe. Mask counts follow Table II (“Number of lithography process steps and masks per metal line process”); the recipe names are the BEOL stack types in the Figure 5 legend, read top-to-bottom.
BEOL_PROCESSES_PER_NODE – per-node BEOL metal-stack composition, decoded from the stacked bars of Figure 5.
PROCESSES_PER_NODE – the full per-node stack: FEOL and MOL layers (counts from Figure 5) prepended to the BEOL layers above.
Any transcription errors here are ours, not the authors’.
The PFAS proxy (lithography masks * area/yield) is only meaningful when considered relative to other instances.
- chia.analysis.sustainability.pfas.num_lith_masks(node: str) int[source]
Number of PFAS-containing lithography masks for
node.Sums the full per-node stack in PROCESSES_PER_NODE: each FEOL and MOL layer counts as one mask, and each BEOL metal-stack recipe is priced by BEOL_METAL_STACK_TYPES (paper eq. 1: #PFAS_litho ~ number of masks).
- chia.analysis.sustainability.pfas.get_PFAS_proxy(node: str, area: float, yield_: float) float[source]
PFAS manufacturing proxy for
node(paper eq. 2):PFAS_chip_manufacturing = #PFAS_litho * Area / Yield
where #PFAS_litho is
num_lith_masks(node).areais die area (in whatever unit you use consistently) andyield_is the manufacturing yield in (0, 1]. (yieldis a Python keyword, hence the trailing underscore.)Like the mask proxy itself, the result is only meaningful relative to other instances computed the same way. This is not an absolute quantity of PFAS.