Skip to content

Expose function names to HUGR - but not IDs. #1

@jake-arkinstall

Description

@jake-arkinstall

Tl;dr:

Function name -> ID mapping is target-specific implementation detail that is designed to be handled in lowering. Doing so allows different lowering implementations to establish different schemes, which provides significant opportunity for user-friendly error flows in simulation environments, and narrow contracts to be used in constrained targets.

I request that @gpu(mkhash("internal_func_name")) becomes @gpu("internal_func_name"), and for ID mapping to be avoided entirely before lowering.

Background

The tket2 GPU module denotes functions with a name (as a string) and an ID (as an integer). This allows the user-facing interface to use friendly function names, while calls to the corresponding GPU library use integers for quick lookup.

The integer mapping for functions is a narrow contract between the compiled user program and the target library implementation. Because of this, the GPU module provides a generic mechanism mapping names to IDs which is to be implemented during lowering. This reframes the narrow contract as one between the lowering implementation and the target library implementation.

For example, the CudaQ QEC Realtime Decoding library - which this repository provides an interface for. The underlying library doesn't use IDs, but exposes functions that can be loaded by a chosen wrapper implementation. It is up to the wrapper implementation to establish the ID mapping.

Example: Simulations

In simulations, we can afford a full handshake process, which allows for a clean validation and error handling flow. This allows simulation to be a forgiving and informative environment.

In selene-hugr-qis-compiler, the mapping of function names to IDs is already part of the API between the generated code and the GPU library itself. There is no assumption made about the mapping at compilation time.

This approach provides the name itself, as a string, to the destination GPU library plugin, which returns the index that it decides the name should map to. If a function is not known, it can provide an error like "Unknown function name {funcname}", which is in turn delivered through the result stream and presented to the user.

A plugin may pre-register a list of known function names and already have an internal mapping of names to IDs, or it may dynamically load symbols from a decoder on-demand and return an index into a vector of loaded symbols. As calls carry signature strings, libffi could be used call it with the right parameters and conventions on-demand. This would allow a user to map guppy code to any library they wish, without the need for a bespoke plugin to be built for said library.

Example: Constrained environments

In constrained environments, a handshake process may add too much overhead. Additionally, the available libraries are restricted and known during compilation, so the lowering implementation has sufficient information to perform hashing and validation itself.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions