PySparQ.pysparq.dynamic_operator

PySparQ dynamic operator extension module - provides runtime compilation and loading of custom C++ operators.

警告

compile_operator() merely compiles the user-provided operator()/dag() into a shared library and calls it via ctypes; a successful compilation only means the code passes C++ type checking. It does not imply, and cannot statically or dynamically prove, that the operator is unitary or that operator()/dag() are inverses of each other. Any implementation that overwrites registers on its own, implements dag() by zeroing registers, or destroys information in some other way will compile without complaint.

Therefore, the QCFD paths supported by this repository (QECC.Lang-driven qfvm/qnls/qham) are forbidden from using dynamic operators compiled via compile_operator. All semantics must be expressed through named, statically checkable PySparQ built-in operators (or Python composite operators built from built-in operators), and validated with the conformance test matrix provided by pysparq.conformance (arbitrary non-zero outputs, exhaustive/sampled basis states, collision detection, linearity on superpositions, positive/negative/ multiple controls, and forward+dagger and dagger+forward identity). compile_operator remains a general-purpose (not QCFD-specific) runtime operator compilation tool that can be used for prototyping, teaching, or experiments unrelated to QCFD, but it must not be treated as having passed any unitarity proof.

Submodules

Exceptions

CompilationError

Compilation error exception.

DynamicOperatorError

Dynamic operator error.

DynamicOperatorFactoryError

Factory function invocation error.

DynamicOperatorLoadError

Dynamic library load error.

Classes

CompilerConfig

Compiler configuration.

CppOperatorWrapper

C++ operator wrapper

Functions

cleanup_all_instances()

Clean up all active dynamic operator instances

clear_cache(→ int)

Clear the compilation cache

compile_cpp_code(→ str)

Compile C++ code into a shared library

compile_operator(→ Type)

Compile C++ code into a dynamic operator class.

compute_code_hash(→ str)

Compute the code hash used for caching

create_operator_class(→ Type)

Create a dynamic operator Python class

find_project_root(→ Optional[pathlib.Path])

Locate the project root directory or the installed package directory

format_compile_error(→ str)

Format compiler error output

generate_cpp_source(→ str)

Generate the complete C++ source file

get_cache_info(→ dict)

Get cache information

quick_compile(→ str)

Quickly compile C++ operator code

Package Contents

exception PySparQ.pysparq.dynamic_operator.CompilationError(message: str, stderr: str = '', returncode: int = 0)[源代码]

Bases: Exception

Compilation error exception.

Initialize self. See help(type(self)) for accurate signature.

returncode = 0
stderr = ''
exception PySparQ.pysparq.dynamic_operator.DynamicOperatorError[源代码]

Bases: Exception

Dynamic operator error.

Initialize self. See help(type(self)) for accurate signature.

exception PySparQ.pysparq.dynamic_operator.DynamicOperatorFactoryError[源代码]

Bases: DynamicOperatorError

Factory function invocation error.

Initialize self. See help(type(self)) for accurate signature.

exception PySparQ.pysparq.dynamic_operator.DynamicOperatorLoadError[源代码]

Bases: DynamicOperatorError

Dynamic library load error.

Initialize self. See help(type(self)) for accurate signature.

class PySparQ.pysparq.dynamic_operator.CompilerConfig(cxx: str = 'g++', std: str = 'c++17', opt_level: str = 'O2', include_paths: list | None = None, lib_paths: list | None = None, libraries: list | None = None, extra_flags: list | None = None, template: str | None = None)[源代码]

Compiler configuration.

Initialize the compiler configuration

参数:
  • cxx -- C++ compiler command (default g++)

  • std -- C++ standard version (default c++17)

  • opt_level -- Optimization level (default O2)

  • include_paths -- Extra header search paths

  • lib_paths -- Extra library search paths

  • libraries -- Libraries to link against

  • extra_flags -- Extra compiler flags

  • template -- Custom code template

get_compile_flags() → list[源代码]

Generate the list of compiler flags.

DEFAULT_TEMPLATE = Multiline-String
Show Value
"""#include "basic_components.h"
#include <vector>
#include <complex>

using namespace qram_simulator;

{USER_CPP_CODE}

extern "C" BaseOperator* create_operator({CTOR_PARAMS}) {{
    return new {CLASS_NAME}({CTOR_ARGS});
}}

extern "C" void destroy_operator(BaseOperator* op) {{
    delete op;
}}

extern "C" const char* get_operator_name() {{
    return "{CLASS_NAME}";
}}
"""
PYTHON_TEMPLATE = Multiline-String
Show Value
"""#include "basic_components.h"
#include <vector>
#include <complex>

using namespace qram_simulator;

{USER_CPP_CODE}

extern "C" BaseOperator* create_operator({CTOR_PARAMS}) {{
    return new {CLASS_NAME}({CTOR_ARGS});
}}

extern "C" void destroy_operator(BaseOperator* op) {{
    delete op;
}}

extern "C" const char* get_operator_name() {{
    return "{CLASS_NAME}";
}}

// Python call helper - applies the operator to a SparseState
// The Python side obtains the C++ SparseState* pointer via state._cpp_ptr(),
// which ctypes passes as ctypes.c_void_p.
extern "C" void apply_operator(BaseOperator* op, SparseState* state) {{
    if (op && state) {{
        (*op)(*state);
    }}
}}

// Python call helper - applies the dagger
extern "C" void apply_operator_dag(BaseOperator* op, SparseState* state) {{
    if (op && state) {{
        op->dag(*state);
    }}
}}

// Returns the base class type
extern "C" const char* get_base_class() {{
    return "{BASE_CLASS}";
}}
"""
cxx = 'g++'
extra_flags = []
include_paths = []
lib_paths = []
libraries = []
opt_level = 'O2'
std = 'c++17'
template = Multiline-String
Show Value
"""#include "basic_components.h"
#include <vector>
#include <complex>

using namespace qram_simulator;

{USER_CPP_CODE}

extern "C" BaseOperator* create_operator({CTOR_PARAMS}) {{
    return new {CLASS_NAME}({CTOR_ARGS});
}}

extern "C" void destroy_operator(BaseOperator* op) {{
    delete op;
}}

extern "C" const char* get_operator_name() {{
    return "{CLASS_NAME}";
}}
"""
class PySparQ.pysparq.dynamic_operator.CppOperatorWrapper(lib_path: str)[源代码]

C++ operator wrapper

Loads the dynamic library and invokes the factory functions to create/destroy C++ operator objects

Initialize the wrapper

参数:

lib_path -- Dynamic library path

apply(ptr: int, state_cpp_ptr: int)[源代码]

Apply the operator to a SparseState

参数:
  • ptr -- Operator object address

  • state_cpp_ptr -- C++ SparseState* pointer (obtained via state._cpp_ptr())

apply_dag(ptr: int, state_cpp_ptr: int)[源代码]

Apply the dagger to a SparseState

参数:
  • ptr -- Operator object address

  • state_cpp_ptr -- C++ SparseState* pointer (obtained via state._cpp_ptr())

close()[源代码]

Close the dynamic library and release resources

Note: on Windows, all C++ objects must already be destroyed before the dynamic library file can be deleted successfully

create(*args) → int[源代码]

Create a C++ operator instance

参数:

*args -- Constructor arguments

返回:

C++ object address (as a Python int)

destroy(ptr: int)[源代码]

Destroy a C++ operator instance

参数:

ptr -- C++ object address

get_base_class() → str[源代码]

Get the base class name.

get_name() → str[源代码]

Get the operator name.

load(arg_types: List[str] = None)[源代码]

Load the dynamic library

参数:

arg_types -- List of constructor argument types

抛出:

DynamicOperatorLoadError -- Load failed

lib_path
PySparQ.pysparq.dynamic_operator.cleanup_all_instances()[源代码]

Clean up all active dynamic operator instances

PySparQ.pysparq.dynamic_operator.clear_cache(cache_dir: str | None = None) → int[源代码]

Clear the compilation cache

参数:

cache_dir -- Cache directory (defaults to the system temporary directory)

返回:

The number of deleted files

PySparQ.pysparq.dynamic_operator.compile_cpp_code(cpp_code: str, class_name: str, cache_dir: str | None = None, ctor_params: str = '', ctor_args: str = '', config: CompilerConfig | None = None, project_root: str | None = None, verbose: bool = False) → str[源代码]

Compile C++ code into a shared library

参数:
  • cpp_code -- User-provided C++ code (containing the class definition)

  • class_name -- Operator class name

  • cache_dir -- Cache directory (defaults to the system temporary directory)

  • ctor_params -- Constructor parameter declarations

  • ctor_args -- Constructor call arguments

  • config -- Compiler configuration

  • project_root -- Project root directory (auto-detected)

  • verbose -- Whether to print verbose logs

返回:

Path of the compiled shared library (.so file)

抛出:
PySparQ.pysparq.dynamic_operator.compile_operator(name: str, cpp_code: str, base_class: str = 'BaseOperator', extra_includes: List[str] = None, extra_libs: List[str] = None, constructor_args: List[Tuple[str, str]] = None, cache_dir: str | None = None, verbose: bool = False) → Type[源代码]

Compile C++ code into a dynamic operator class.

This is a high-level function that compiles user-provided C++ code into a shared library and wraps it into an operator class that can be used directly from Python. A dynamic operator can be applied to a SparseState just like a native PySparQ operator.

警告

A successful compilation only means operator()/dag() passed C++ type checking; it constitutes no unitarity proof whatsoever: this function neither statically nor dynamically verifies that the generated operator is unitary, or that dag() is actually the inverse of operator(). Hence the supported QCFD paths (QECC.Lang-driven qfvm/qnls/qham) forbid the use of dynamic operators compiled by this function; QCFD semantics must use named PySparQ built-in operators and be validated with the pysparq.conformance conformance test matrix.

参数:
  • name -- Operator class name. Must be a valid Python class name and must match the class name in the C++ code.

  • cpp_code -- C++ source code, containing only the class definition part. The code must inherit from BaseOperator or SelfAdjointOperator and implement the operator() method.

  • base_class -- Base class name, determines dagger behavior. Allowed values: - "BaseOperator": general operator, requires a manually implemented dag() method - "SelfAdjointOperator": Hermitian operator, dag() automatically equals operator() Defaults to "BaseOperator".

  • extra_includes -- List of extra header search paths. PySparQ headers are included automatically.

  • extra_libs -- List of extra libraries to link. Most operators need no extra libraries.

  • constructor_args -- List of constructor arguments in the form [(type, name), ...]. Supported types: size_t, int, long, double, float, bool, uint64_t. Example: [("size_t", "reg_id"), ("double", "phase")]

  • cache_dir -- Cache directory path. Defaults to pysparq_dynamic_ops/ under the system temporary directory.

  • verbose -- Whether to print verbose compilation logs, useful for debugging.

返回:

The dynamically generated operator class. Instances are created with keyword arguments, e.g.: OpClass(reg_id=0, phase=1.0)

抛出:

示例

Create a simple flip operator:

>>> from pysparq.dynamic_operator import compile_operator
>>>
>>> cpp_code = '''
... class FlipOp : public SelfAdjointOperator {
...     size_t reg_id;
... public:
...     FlipOp(size_t r) : reg_id(r) {}
...     void operator()(std::vector<System>& state) const override {
...         for (auto& s : state) {
...             s.get(reg_id).value ^= 1;
...         }
...     }
... };
... '''
>>>
>>> FlipOp = compile_operator(
...     name="FlipOp",
...     cpp_code=cpp_code,
...     base_class="SelfAdjointOperator",
...     constructor_args=[("size_t", "reg_id")]
... )
>>>
>>> # Create an instance
>>> op = FlipOp(reg_id=0)
>>> print(repr(op))  # FlipOp(reg_id=0)

备注

  • Compiled libraries are cached by code hash to avoid redundant compilation.

  • ABI compatibility issues may exist on Windows (MSVC vs MinGW).

  • The C++ class name must match the Python name parameter.

  • State access inside operators: s.get(reg_id).value gets the value, s.amplitude gets the amplitude.

参见

get_cache_info: Query the compilation cache status. clear_cache: Clear the compilation cache. CompilerConfig: Advanced compiler configuration.

PySparQ.pysparq.dynamic_operator.compute_code_hash(cpp_code: str, class_name: str, config: CompilerConfig) → str[源代码]

Compute the code hash used for caching

The hash covers: code content, class name, compiler version, and configuration

参数:
  • cpp_code -- User C++ code

  • class_name -- Operator class name

  • config -- Compiler configuration

返回:

A 16-character hexadecimal hash string

PySparQ.pysparq.dynamic_operator.create_operator_class(name: str, lib_path: str, base_class: str = 'BaseOperator', constructor_args: List[Tuple[str, str]] = None) → Type[源代码]

Create a dynamic operator Python class

参数:
  • name -- Operator class name

  • lib_path -- Dynamic library path

  • base_class -- Base class name ("BaseOperator" or "SelfAdjointOperator")

  • constructor_args -- List of constructor arguments [(type, name), ...]

返回:

The dynamically created operator class

PySparQ.pysparq.dynamic_operator.find_project_root() → pathlib.Path | None[源代码]

Locate the project root directory or the installed package directory

For an installed package, the directory layout is: - site-packages/pysparq/ (Python package) - site-packages/include/ (headers, including basic_components.h)

For a source checkout (the SparQSim repository): - The project root contains extern/qram-simulator/ (C++ core submodule) and PySparQ/

返回:

The project root path or the installed package directory; None if not found

PySparQ.pysparq.dynamic_operator.format_compile_error(stderr: str, source_path: str) → str[源代码]

Format compiler error output

  • Simplifies file paths

  • Highlights error lines

  • Extracts the key error information

参数:
  • stderr -- Compiler standard error output

  • source_path -- Source file path

返回:

The formatted error message

PySparQ.pysparq.dynamic_operator.generate_cpp_source(cpp_code: str, class_name: str, ctor_params: str = '', ctor_args: str = '', config: CompilerConfig | None = None) → str[源代码]

Generate the complete C++ source file

参数:
  • cpp_code -- User-provided C++ code (containing the class definition)

  • class_name -- Operator class name

  • ctor_params -- Constructor parameter declarations (e.g. "int n, double theta")

  • ctor_args -- Constructor call arguments (e.g. "n, theta")

  • config -- Compiler configuration (provides the template)

返回:

The complete C++ source code string

PySparQ.pysparq.dynamic_operator.get_cache_info(cache_dir: str | None = None) → dict[源代码]

Get cache information

参数:

cache_dir -- Cache directory

返回:

A dictionary with cache statistics

PySparQ.pysparq.dynamic_operator.quick_compile(class_code: str, class_name: str, verbose: bool = False) → str[源代码]

Quickly compile C++ operator code

参数:
  • class_code -- C++ code containing the class definition

  • class_name -- Class name

  • verbose -- Whether to print verbose logs

返回:

The shared library file path