Skip to main content

giul

giúl — Irish for joule. One ruler for "what did this answer cost in energy" across the FoxxeLabs fleet: Aigne, Tuiscint, Gléas.

Two rulers make a comparison an argument instead of evidence. This is one, and all three pin it.

pip install giul              # no dependencies; imports fine with no GPU
pip install giul[nvml]        # + nvidia-ml-py, for the energy counter
pip install giul[remote]      # + httpx, for metering a remote node

What a joule means here

The number a request is charged is energy above idle:

joules = measured − idle_w × seconds

A request pays for the power it caused, not for the power the box burns existing. idle_w is supplied by the caller, per node — giul never guesses it, because a wrong idle floor silently rewrites every figure that node reports.

Three rules

  1. Charged above idle. As above.
  2. No fabricated zeros. A window that measured ≤ 0 J above idle did not measure a free request, it failed to measure one. It degrades to estimated (with a hint) or unknown — never a sampled zero.
  3. Estimates are labelled as estimates. An estimate that reads as a measurement is exactly how an efficiency claim stops being evidence. A sampler that cannot be reached costs a measurement, never the request.

Use

from giul import Meter, Node

node = Node(name="iris", gpu_index=0, idle_w=38.0,
            is_local=True, power_endpoint=None)

# async
async with Meter.for_node(node, joules_per_1k_hint=4100.0) as m:
    await retrieve(); m.mark("retrieve")
    await generate(); m.mark("generate")
e = m.result(tokens=412)
# e.joules, e.method, e.backend, e.stages == {"retrieve": Energy, "generate": Energy}

# sync
with Meter.for_node(node, sync=torch.cuda.synchronize).sync() as m:
    ...; m.mark("verify")
e = m.result(tokens=n)

mark(name) closes the current stage and opens the next. The total is always computed over the whole window, never by summing stages, so a stage the sampler was too slow to see cannot corrupt it.

The caller synchronises the GPU before the closing read. On the counter backend the register only counts work the card has finished; pass sync=torch.cuda.synchronize when the work is local. An HTTP upstream needs nothing — the completion returning is the sync point.

Backends

Chosen at runtime in one place (Meter.for_node), needing no per-node configuration. Support is probed once per card and cached.

backend when how
nvml_counter local card, pynvml present, counter answers nvmlDeviceGetTotalEnergyConsumption delta — a true measurement of a sub-second window
smi_sampler local card, nvidia-smi on PATH integral of power.draw samples
remote_agent node.power_endpoint set the same integral, sampled by giul-agent on that node
none otherwise estimated with a hint, else unknown

method stays sampled / estimated / unknown. The counter is a measurement, so it reports method="sampled"; the distinction lives in backend.

Tools

giul-probe                    # what this host's cards support; counter vs sampler
giul-agent --port 9402        # expose a node's power draw; stdlib only, read-only

Bind giul-agent to the mesh address, not 0.0.0.0, unless the node is otherwise firewalled.

Not in 0.1

CPU/RAPL, carbon, € cost, storing series, any UI.

Download files

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

Source Distribution

giul-0.1.0.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

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

giul-0.1.0-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: giul-0.1.0.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for giul-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3f31b454db0f895324b852220db52178d9ca544da67c1df3e1b1693677ed74f7
MD5 16596fc81d7973ed893e17f3a66aad7e
BLAKE2b-256 495b212a06273c46ea21e5f12834f1d1d29d088398f6c50fd0ef8af7525b91aa

See more details on using hashes here.

File details

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

File metadata

  • Download URL: giul-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for giul-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cda79b890b3a160d22104e6e1cd77070beaa1e1d01429eff66509b1c84efd2b9
MD5 accb5753784bbb7c06aa4c56454bbe6a
BLAKE2b-256 8135c6bc66d347d4dd4b26a693f0ba98580868f6db77bae884c080818f28cb44

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page