GizStack
View .mdOpen in ChatGPTOpen in Claude

gizhw:device

the devices the machine has, as the program opens and drives them. Discovery reads sysfs (each class folder of /sys/class: its devices, their node, bus, ids and model); sensors and RAPL energy are readings; the NVIDIA GPU boards are read and controlled through NVML (the driver's management library). A Handle is one open device node: ioctl, mmap, read, write, poll and close through libc, with arguments in native memory. Every class module (npu, v4l2, evdev, bus, tpm, block, rdma, codec) drives its device through a Handle and calls libc through libcCall only here. The CPU's facts (features, caches, NUMA nodes) are gizlang:machine's.

gizlang
import * as Device from "gizhw:device";

Types

Device

gizlang
type Device = { name: string; kind: string; path: string; node: string; bus: string; vendor: i64; product: i64; model: string; driver: string; }

A device of one class: name is its entry in the class folder (renderD128, accel0, tpm0), kind the class (drm, accel, tpm), path its sysfs directory, resolved. node is its /dev file ("" when it has none), bus the bus it sits on (pci, usb, platform, "" when unknown), vendor and product its ids (0 when none), model its model text, and driver the driver bound to it ("" when none).

  • name: string
  • kind: string
  • path: string
  • node: string
  • bus: string
  • vendor: i64
  • product: i64
  • model: string
  • driver: string

Sensor

gizlang
type Sensor = { device: string; channel: string; value: i64; }

A reading of one hwmon channel: device is the hwmon's name (k10temp, nvme) and channel its file (temp1_input). value is in the channel's unit: milli-degrees C (temp), rpm (fan), microwatts (power), millivolts (in) or milliamps (curr).

  • device: string
  • channel: string
  • value: i64

Energy

gizlang
type Energy = { domain: string; microjoules: i64; }

An energy counter of a powercap domain: domain is its name (package-0) and microjoules its count. The count wraps at the domain's max_energy_range_uj, so a power is the difference of two reads over their time.

  • domain: string
  • microjoules: i64

Telemetry

gizlang
type Telemetry = { sensors: Vec<Sensor>; energy: Vec<Energy>; gpus: Vec<GpuReading>; }

The readings of one moment: the hwmon sensors, the RAPL energy counters and each NVIDIA board's state (none when the driver's management library is not there).

  • sensors: Vec<M7.Sensor>
  • energy: Vec<M7.Energy>
  • gpus: Vec<M7.GpuReading>

Handle

gizlang
type Handle

An open device node or socket: fd is its descriptor, and the addresses of the libc functions it calls.

  • fd: i64

GpuBoards

gizlang
type GpuBoards

The NVIDIA GPUs of the machine (gpuBoards()).

  • count: i64

GpuReading

gizlang
type GpuReading = { index: i64; name: string; temperature: i64; utilization: i64; memoryUtilization: i64; memoryUsed: i64; memoryTotal: i64; power: f64; powerLimit: f64; powerMin: f64; powerMax: f64; fans: Vec<i64>; smClock: i64; memoryClock: i64; reasons: u64; replays: i64; }

One GPU's state: temperature in degrees C, utilization in percent, memory in bytes, power in watts, clocks in MHz. fans: each fan's speed in percent. reasons: NVML's clocks event reasons (bits: 4 software power cap, 32 software thermal, 64 hardware thermal, 128 hardware power brake). replays: PCIe replays since the driver loaded.

  • index: i64
  • name: string
  • temperature: i64
  • utilization: i64
  • memoryUtilization: i64
  • memoryUsed: i64
  • memoryTotal: i64
  • power: f64
  • powerLimit: f64
  • powerMin: f64
  • powerMax: f64
  • fans: Vec<i64>
  • smClock: i64
  • memoryClock: i64
  • reasons: u64
  • replays: i64

Xid

gizlang
type Xid = { index: i64; xid: i64; }

An Xid error a GPU reported (a driver or hardware fault; 79: the GPU fell off the bus).

  • index: i64
  • xid: i64

Functions

platform

gizlang
function platform(sys: System): string

The kernel this program runs on, in lower case ("linux", "darwin"; "unknown" when it does not say): a class module (camera, audio, input) picks its backend by it.

Effects: fail, io.

noBackend

gizlang
function noBackend(sys: System, kind: string): string

The error of a class module on a platform that has no backend for it: the class and the platform, named.

Effects: fail, io.

devices

gizlang
function devices(sys: System, kind: string): Vec<Device> throws IoError

The devices of class kind, a folder of /sys/class (such as "accel", "drm", "tpm", "nvme", "video4linux" or "sound"), in the order the kernel lists them. A class that the kernel does not have gives none.

Effects: fail, io.

sensors

gizlang
function sensors(sys: System): Vec<Sensor> throws IoError

Every reading of a temperature, fan, power, voltage or current channel that hwmon reports, by hwmon device in the order the kernel lists them. A channel that cannot be read is skipped.

Effects: fail, io.

energy

gizlang
function energy(sys: System): Vec<Energy> throws IoError

The energy counter of every powercap domain that has one (RAPL, through the powercap interface), in the order the kernel lists them.

Effects: fail, io.

telemetry

gizlang
function telemetry(sys: System): Telemetry throws IoError

Every reading now. A board that NVML cannot read is left out.

Effects: fail, io.

open

gizlang
function open(sys: System, path: string, writable: bool): Handle throws IoError

Opens device node path (a /dev file) read-write when writable, read-only otherwise.

Effects: fail, io.

openNode

gizlang
function openNode(sys: System, path: string, writable: bool): Handle throws string

Opens path like open, with the failure as text, for a class module that returns string errors.

Effects: fail, io.

wrap

gizlang
function wrap(sys: System, fd: i64): Handle

A handle on the descriptor fd that is already open (a socket, or one a library gave).

Effects: fail, io.

libcCall

gizlang
function libcCall(sys: System, name: string, args: Vec<u64>): u64

Calls the C library's function name with integer arguments (a socket, a name lookup) and gives its raw result. Only this module calls libc by name; a class module uses a Handle or this call.

Effects: fail, io.

textAt

gizlang
function textAt(data: bytes, at: i64, length: i64): string

The text of a fixed-size C string field data[at, at + length) of a struct, up to its NUL, trimmed.

Effects: fail.

cstring

gizlang
function cstring(os: Native, text: string): u64

A NUL-terminated copy of text in native memory, for a C string argument (free it with the native interface).

Effects: fail, io.

cstringAt

gizlang
function cstringAt(os: Native, address: u64): string

The text of the NUL-terminated string at address (at most 256 bytes): a C string the library gave.

Effects: fail, io.

gpuBoards

gizlang
function gpuBoards(sys: System): GpuBoards throws string

NVML, set up. An error says when the driver has no NVML or it does not start. Xid errors are watched on each GPU that allows it (GpuBoards.xids).

Effects: fail, io.

Methods

Device.attribute

gizlang
function Device.attribute(self: Device, sys: System, name: string): string throws IoError

The text of attribute name of this device (a file of its sysfs folder, such as brightness, online or cur_brightness), trimmed.

Effects: fail, io.

Device.setAttribute

gizlang
function Device.setAttribute(self: Device, sys: System, name: string, value: string): i64 throws IoError

Writes value to attribute name of this device: the process needs write authority for that folder. Gives the number of bytes written.

Effects: fail, io.

Handle.text

gizlang
function Handle.text(self: Handle, at: u64): string

The text at address, a NUL-terminated C string the library gave.

Effects: fail, io.

Handle.alloc

gizlang
function Handle.alloc(self: Handle, size: i64): u64

Allocates size bytes of native memory (free it with free).

Effects: fail, io.

Handle.free

gizlang
function Handle.free(self: Handle, at: u64): void

Frees native memory from alloc.

Effects: fail, io.

Handle.poke

gizlang
function Handle.poke(self: Handle, at: u64, data: bytes): void

Copies data into native memory at at.

Effects: fail, io.

Handle.peek

gizlang
function Handle.peek(self: Handle, at: u64, length: i64): bytes

The length bytes of native memory at at.

Effects: fail, io.

Handle.peekInto

gizlang
function Handle.peekInto(self: Handle, at: u64, into: mut bytes): void

The into.length bytes of native memory at at, copied into into with no allocation.

Effects: fail.

Handle.flush

gizlang
function Handle.flush(self: Handle, at: u64, length: i64): void

Writes the CPU cache lines of length bytes of a mapping at at back to memory and drops them (Native.flush).

Effects: fail, io.

Handle.ioctl

gizlang
function Handle.ioctl(self: Handle, request: u64, argument: u64): i64 throws string

ioctl request with argument, a native address (or 0): a negative result is a failure. Gives the result.

Effects: fail, io.

Handle.exchange

gizlang
function Handle.exchange(self: Handle, request: u64, data: bytes): bytes throws string

ioctl request with data as the argument struct: the struct is copied to native memory, the kernel fills it, and the struct after the call is given.

Effects: fail, io.

Handle.readBytes

gizlang
function Handle.readBytes(self: Handle, length: i64): bytes throws string

Reads up to length bytes from the descriptor, waiting for them; gives what was read.

Effects: fail, io.

Handle.writeBytes

gizlang
function Handle.writeBytes(self: Handle, data: bytes): i64 throws string

Writes data to the descriptor. Gives the number of bytes written.

Effects: fail, io.

Handle.poll

gizlang
function Handle.poll(self: Handle, events: i64, timeout: i64): i64 throws string

Waits up to timeout ms for the descriptor to be ready for events (POLLIN 1, POLLOUT 4). Gives the events that are ready: 0 at a timeout.

Effects: fail, io.

Handle.map

gizlang
function Handle.map(self: Handle, length: i64, offset: i64, alignment: i64 = 1): u64 throws string

Maps length bytes of the device at offset, shared, readable and writable, at an address that is a multiple of alignment (a power of two; 1 for any). Gives the address.

Effects: fail, io.

Handle.unmap

gizlang
function Handle.unmap(self: Handle, at: u64, length: i64): void

Unmaps length bytes from at (from map).

Effects: fail, io.

Handle.close

gizlang
function Handle.close(self: Handle): void

Closes the descriptor.

Effects: fail, io.

GpuBoards.state

gizlang
function GpuBoards.state(self: GpuBoards, i: i64): GpuReading throws string

GPU i's state now.

Effects: fail, io.

GpuBoards.setPowerLimit

gizlang
function GpuBoards.setPowerLimit(self: GpuBoards, i: i64, watts: f64): void throws string

Sets GPU i's power limit to watts (within GpuReading.powerMin to powerMax; root).

Effects: fail, io.

GpuBoards.setFans

gizlang
function GpuBoards.setFans(self: GpuBoards, i: i64, percent: i64): void throws string

Sets every fan of GPU i to percent (root).

Effects: fail, io.

GpuBoards.defaultFans

gizlang
function GpuBoards.defaultFans(self: GpuBoards, i: i64): void throws string

Gives every fan of GPU i back to the GPU's own (VBIOS) control (root).

Effects: fail, io.

GpuBoards.xids

gizlang
function GpuBoards.xids(self: GpuBoards): Vec<Xid>

The Xid errors reported since the last call, without waiting.

Effects: fail, io.

GpuBoards.close

gizlang
function GpuBoards.close(self: mut GpuBoards): void

Stops NVML.

Effects: fail, io.