• OctoMY API
  • OctoMY API Reference
  • C++ Classes
  • OctoMY
  • Program
  • eval::Program Class

    class eval::Program

    An immutable compiled expression program, produced by an eval::Graph. More...

    Header: #include <Program>

    Public Functions

    eval::Result<void> evaluateBatch(std::span<const float> inputs, std::span<float> outputs, int count)
    eval::Program::Lowering lowering() const
    QString loweringDeclinedReason() const
    void setFloat(eval::Handle h, float v)
    void setMat4(eval::Handle h, const QMatrix4x4 &m)
    QString spirvDisassembly() const

    Detailed Description

    A Program holds the compiled state of one eval::Graph: the slot bindings, and the lane that runs them. After compile() it does not change. Callers look up slot handles once with input() and output(), set inputs, call evaluate() and read the outputs.

    Several threads can share one Program. Each worker holds its own ThreadCopy for input and output scratch, so no synchronization is needed. lowering() reports which lane actually ran, which can differ from the backend() that was asked for.

    See also eval::Graph and eval::evaluate().

    Member Function Documentation

    eval::Result<void> Program::evaluateBatch(std::span<const float> inputs, std::span<float> outputs, int count)

    A program with no outputs has nothing to lower, so it has not failed.

    `Program p;` — the default-constructed skeleton — reaches here, and `smokeLinking` evaluates one deliberately while walking every public entry point. Reporting an internal error for it would make "no lane" and "nothing to run" the same answer, and only one of them is a defect.

    eval::Program::Lowering Program::lowering() const

    Returns the lowering that actually runs this program, as opposed to the backend that was asked for.

    Every lowering goes through glslang to SPIR-V. The value says what runs the SPIR-V: the interpreter, the in-memory LLVM JIT, or a GPU dispatch. A default-constructed Program has no lane and returns Lowering::None.

    See also spirvDisassembly().

    QString Program::loweringDeclinedReason() const

    `SUP-9` — the fallback names NOTHING, and it used to name a lane.

    This returned `Lowering::AstWalker`, which was true while the walker was the catch-all. After the deletion it was a program with no lane reporting the one lowering that no longer exists — the most plausible possible wrong answer, and `testOpalExpressionTasks` watches this value precisely to notice when a lane stops running.

    Only a default-constructed `Program` reaches here: `Graph::compile` refuses rather than returning a laneless one.

    void Program::setFloat(eval::Handle h, float v)

    `SUP-88` — a wide slot has no single value, and says so.

    Without this it returns a default-constructed `Value` converted to a QVariant, which is a VALID QVariant holding zero — a plausible number for a slot the caller has not read. An invalid QVariant is the only answer here that a caller can tell apart from a result.

    void Program::setMat4(eval::Handle h, const QMatrix4x4 &m)

    `setMat4`/`getMat4` were STUBS, and a stub setter is worse than a missing one: `setMat4` accepted a matrix and dropped it, so a caller binding a `mat4` input got the zero matrix and no diagnostic, and `getMat4` answered the default-constructed identity for every output.

    Matrices have read and written correctly through `Program::get()`/`set()` as a column-major `QVariantList` since Phase 5d — these two typed convenience overloads were left behind and nothing noticed, because the only caller in the tree is `testEvalUnit`'s link-only smoke row, which calls each of them and discards the result.

    **The order is the whole content of the fix.** `Value::mat` is column-major, and so is `QMatrix4x4`'s raw storage: `constData()` and `data()` both hand out columns. What is NOT column-major is `QMatrix4x4(const float*)`, whose documentation says the array "is assumed to be in row-major order" — so constructing from `v.mat` would transpose every matrix and still compile, which is exactly the failure §SUR-66c names for the GLSL side.

    QString Program::spirvDisassembly() const

    Returns the SPIR-V this program lowered through, as disassembled text.

    The value is empty when the program kept no SPIR-V, and that is a normal answer. Only the interpreter lane keeps the binary. The native and GPU lanes consume the module into LLVM IR or a QShader, and a program with no lane never produced one. Read lowering() beside this value to tell the cases apart.