Python: SPG Generating Node#

An SPG node with no input AOV at all. Every value it needs is a typed USD attribute, and it draws a checkerboard into its own output, which the scene publishes as Checker.

The run checks itself: it rebuilds the same checkerboard on the host from the attributes the scene authored and compares the two pixel for pixel.

Running#

uv run main.py

The first step compiles the kernel with NVRTC and can take up to a minute on a cold shader cache. A successful run writes _output/checker.png and prints pixels differing from the host-computed pattern: 0. A difference above zero exits non-zero.

The Node#

-- Launch script for a node with no resource-input.
--
-- Nothing hands this node a resource, so there is no descriptor to take a shape
-- from. The size comes from typed USD attributes instead, like every other
-- value the node uses.
function checker(inputs, outputs)
    local width  = inputs["width"].value
    local height = inputs["height"].value
    assert(width > 0 and height > 0, "width and height must be positive")
    assert(inputs["squareSize"].value > 0, "squareSize must be positive")

    outputs["Checker"] = cuda.image(width, height, cuda.uchar4)

    return cuda.kernel({
        args = {
            cuda.int(width),                        -- -> int width
            cuda.int(height),                       -- -> int height
            cuda.int(inputs["squareSize"]),         -- -> int squareSize
            cuda.array(inputs["colorA"]),           -- -> const float* colorA
            cuda.array(inputs["colorB"]),           -- -> const float* colorB
            cuda.SurfaceObject(outputs["Checker"]), -- -> cudaSurfaceObject_t output
        },
        block = { 16, 16 },
        grid  = { math.ceil(width / 16), math.ceil(height / 16) },
    })
end

Refer to Write a Node With No Input for what a node without an input can and cannot assume.