solprop.calibration.grain#

Operation-grain candidates from the work sizes the calibration problems run (SEP 46).

Each CPU operation class threads by its work: serially below its threshold, on the medium width below its full size, on its pool’s capacity from there (_execution.ExecutionRecord). A workspace’s execution_sizing records every operation it runs, with its class, work and width. A threshold or full size matters only where it falls between two work sizes the problems actually run, so the candidates of a class are its one-step moves past the nearest of them: thread one more size, serialise one more, widen one more to the full pool, narrow one more to the medium width. At most four a class (section 6.5); a candidate that changes no operation’s width is left out. The medium width and the compact team take a short ladder of their own. Each candidate is then timed on the problems it changes, and §6.5’s rule decides (solprop.calibration.selection).

Every function here is pure.

Module Attributes

Record

A native execution record (ExecutionRecord.native()).

TIMED

The classes whose thresholds the grain moves, in the order their candidates go.

SHAPE_MOVES

The transforms' shape settings the grain halves and doubles.

Functions

affected(record, base, found, capacity)

Return whether record gives any of found another width than base does.

best(candidates, verdicts)

Return each setting's admitted candidate with the lowest score.

operations(sizing)

Return the operations a workspace's execution_sizing records.

proposals(record, problems, capacity[, ...])

Return the grain candidates for problems running problems' operations.

width(record, operation, capacity)

Return the width record gives operation on a pool of capacity threads.

Classes

Candidate(setting, name, changes)

One grain candidate: a setting's group and the record's changed fields.

Operation(pool, kind, elements[, samples])

One operation a problem runs, as its workspace's sizing records it.

class solprop.calibration.grain.Candidate(setting, name, changes)[source]#

Bases: object

One grain candidate: a setting’s group and the record’s changed fields.

Attributes:
settingstr

What it moves: an operation class, "medium" or "compact".

namestr

A short description, such as "stage threshold 2048".

changesMapping[str, int]

The fields it sets over the base record.

changes: Mapping[str, int]#
name: str#
record(base)[source]#

Return base with this candidate’s changes.

Parameters:
baseMapping[str, int or bool]

A native execution record.

Returns:
dict

The candidate’s record.

setting: str#
class solprop.calibration.grain.Operation(pool, kind, elements, samples=0)[source]#

Bases: object

One operation a problem runs, as its workspace’s sizing records it.

Attributes:
poolstr

"kernels", "fft", "raman_fft" or "raman_tail_fft".

kindstr

Its class: "stage", "response", "dense", "fft", "raman", "copy", "flow", "modal" or "adams".

elementsint

Its work.

samplesint

A response’s fine samples per column, a transform batch’s row length; zero otherwise.

elements: int#
kind: str#
pool: str#
samples: int = 0#
type solprop.calibration.grain.Record = Mapping[str, int | bool]#

A native execution record (ExecutionRecord.native()).

solprop.calibration.grain.SHAPE_MOVES = ('fft_thread_elements',)#

The transforms’ shape settings the grain halves and doubles.

Not the long row: with its moves too, a thorough calibration of 16 cores of an AMD EPYC 7763 timed 21 grain candidates and ran out of rounds before any verdict, where 17 had concluded.

solprop.calibration.grain.TIMED = ('stage', 'response', 'raman', 'copy', 'dense', 'modal', 'fft')#

The classes whose thresholds the grain moves, in the order their candidates go.

The exponential Adams trial’s passes and a coupled flow’s matrix functions run in no calibration window: their thresholds keep the built-in table’s. The transforms thread by shape (rows and row length, solprop issue #587), so beside their threshold the grain moves their thread grain (SHAPE_MOVES) rather than their full size: by element count alone, a full width from 98304 elements won 0.56 on a line’s many short rows and ran grin_nonlinear’s few long rows 8-10 % slower on AMD EPYC cores (SEP 46 Part II). They go last: a move of theirs changes nearly every problem’s width, so each costs a round’s worth of windows, and a level’s limit drops them first.

solprop.calibration.grain.affected(record, base, found, capacity)[source]#

Return whether record gives any of found another width than base does.

Parameters:
record, baseMapping[str, int or bool]

Two native execution records.

founditerable of Operation

A problem’s operations.

capacityint

The pool’s width.

Returns:
bool

Whether timing the problem can tell the two apart.

solprop.calibration.grain.best(candidates, verdicts)[source]#

Return each setting’s admitted candidate with the lowest score.

Parameters:
candidatesiterable of Candidate

The candidates timed.

verdictsMapping[str, Verdict]

Each one’s verdict, by name.

Returns:
list of Candidate

At most one a setting, in the order the settings first appear.

solprop.calibration.grain.operations(sizing)[source]#

Return the operations a workspace’s execution_sizing records.

Parameters:
sizingMapping[str, object]

The sizing, keyed pool.operation.elements[.samples.N].

Returns:
list of Operation

One per key, in key order; keys of another form are left out.

Examples

>>> found = operations({"kernels.stage.4096": {}, "fft.fft.66.samples.33": {}})
>>> [(operation.kind, operation.elements, operation.samples) for operation in found]
[('fft', 66, 33), ('stage', 4096, 0)]
solprop.calibration.grain.proposals(record, problems, capacity, compact=(), *, limit=None, fulls=True)[source]#

Return the grain candidates for problems running problems’ operations.

Parameters:
recordMapping[str, int or bool]

The base record: the process’s, under which the problems were sized.

problemsMapping[str, list of Operation]

Each problem’s operations.

capacityint

The pool’s width.

compactiterable of str

The problems that run on a compact team.

limitint or None, optional

The most candidates; the medium widths and compact teams come first, then the classes in TIMED order.

fullsbool, optional

Whether to move the classes’ full sizes as well as their thresholds.

Returns:
list of Candidate

The medium widths, the compact teams, then each timed class’s moves; each changes some operation’s width (or a compact problem’s team).

Examples

>>> base = {"stage_threshold": 100, "stage_full": 1000, "medium_threads": 4}
>>> found = proposals(base, {"p": [Operation("kernels", "stage", 500)]}, 18)
>>> [candidate.name for candidate in found]
['medium 2', 'medium 8', 'stage threshold 501', 'stage full 500']
solprop.calibration.grain.width(record, operation, capacity)[source]#

Return the width record gives operation on a pool of capacity threads.

The native rule (operation_threads), without the compact cap, the stable team or an explicit pool: one below the threshold, the full pool for a long or wide response, a thread per fft_thread_elements samples (at most one a row, or the medium width for rows fft_long_row long) for a transform batch of known row length, the medium width below the full size, the full pool from it.

Parameters:
recordMapping[str, int or bool]

A native execution record.

operationOperation

The operation.

capacityint

The pool’s width.

Returns:
int

Threads.

Examples

>>> table = {"stage_threshold": 100, "stage_full": 1000, "medium_threads": 4}
>>> [width(table, Operation("kernels", "stage", n), 18) for n in (50, 500, 5000)]
[1, 4, 18]