PySparQ.pysparq.dynamic_operator

PySparQ 动态算子扩展模块 - 提供运行时编译和加载自定义 C++ 算子的功能。

Submodules

Exceptions

CompilationError

编译错误异常

DynamicOperatorError

动态算子错误

DynamicOperatorFactoryError

工厂函数调用错误

DynamicOperatorLoadError

动态库加载错误

Classes

CompilerConfig

编译器配置

CppOperatorWrapper

C++ 算子包装器

Functions

cleanup_all_instances()

清理所有活跃的动态算子实例

clear_cache(→ int)

清除编译缓存

compile_cpp_code(→ str)

编译 C++ 代码为共享库

compile_operator(→ Type)

编译 C++ 代码为动态算子类。

compute_code_hash(→ str)

计算代码哈希值,用于缓存

create_operator_class(→ Type)

创建动态算子 Python 类

find_project_root(→ Optional[pathlib.Path])

查找项目根目录或已安装的包目录

format_compile_error(→ str)

格式化编译错误输出

generate_cpp_source(→ str)

生成完整的 C++ 源文件

get_cache_info(→ dict)

获取缓存信息

quick_compile(→ str)

快速编译 C++ 算子代码

Package Contents

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

Bases: Exception

编译错误异常

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

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

Bases: Exception

动态算子错误

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

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

Bases: DynamicOperatorError

工厂函数调用错误

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

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

Bases: DynamicOperatorError

动态库加载错误

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)[源代码]

编译器配置

初始化编译器配置

参数:
  • cxx -- C++ 编译器命令(默认 g++)

  • std -- C++ 标准版本(默认 c++17)

  • opt_level -- 优化级别(默认 O2)

  • include_paths -- 额外的头文件搜索路径

  • lib_paths -- 额外的库文件搜索路径

  • libraries -- 需要链接的库

  • extra_flags -- 额外的编译器标志

  • template -- 自定义代码模板

get_compile_flags() list[源代码]

生成编译器标志列表

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 调用辅助函数 - 应用算子到 SparseState
// Python 侧通过 state._cpp_ptr() 获取 C++ SparseState* 指针,
// ctypes 将其作为 ctypes.c_void_p 传递。
extern "C" void apply_operator(BaseOperator* op, SparseState* state) {{
    if (op && state) {{
        (*op)(*state);
    }}
}}

// Python 调用辅助函数 - 应用 dagger
extern "C" void apply_operator_dag(BaseOperator* op, SparseState* state) {{
    if (op && state) {{
        op->dag(*state);
    }}
}}

// 获取基类类型
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++ 算子包装器

负责加载动态库、调用工厂函数创建/销毁 C++ 算子对象

初始化包装器

参数:

lib_path -- 动态库路径

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

应用算子到 SparseState

参数:
  • ptr -- 算子对象地址

  • state_cpp_ptr -- C++ SparseState* 指针(通过 state._cpp_ptr() 获取)

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

应用 dagger 到 SparseState

参数:
  • ptr -- 算子对象地址

  • state_cpp_ptr -- C++ SparseState* 指针(通过 state._cpp_ptr() 获取)

close()[源代码]

关闭动态库并释放资源

注意:在 Windows 上,必须确保所有 C++ 对象都已销毁 才能成功删除动态库文件

create(*args) int[源代码]

创建 C++ 算子实例

参数:

*args -- 构造函数参数

返回:

C++ 对象地址(作为 Python int)

destroy(ptr: int)[源代码]

销毁 C++ 算子实例

参数:

ptr -- C++ 对象地址

get_base_class() str[源代码]

获取基类名称

get_name() str[源代码]

获取算子名称

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

加载动态库

参数:

arg_types -- 构造函数参数类型列表

抛出:

DynamicOperatorLoadError -- 加载失败

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

清理所有活跃的动态算子实例

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

清除编译缓存

参数:

cache_dir -- 缓存目录(默认使用系统临时目录)

返回:

删除的文件数量

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[源代码]

编译 C++ 代码为共享库

参数:
  • cpp_code -- 用户提供的 C++ 代码(包含类定义)

  • class_name -- 算子类名

  • cache_dir -- 缓存目录(默认使用系统临时目录)

  • ctor_params -- 构造函数参数声明

  • ctor_args -- 构造函数参数调用

  • config -- 编译器配置

  • project_root -- 项目根目录(自动检测)

  • verbose -- 是否输出详细日志

返回:

编译后的共享库路径 (.so 文件)

抛出:
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[源代码]

编译 C++ 代码为动态算子类。

这是一个高级函数,将用户提供的 C++ 代码编译为共享库, 并包装为可直接在 Python 中使用的算子类。动态算子可以 像原生 PySparQ 算子一样应用于 SparseState。

参数:
  • name -- 算子类名。必须是有效的 Python 类名,且必须与 C++ 代码中的类名匹配。

  • cpp_code -- C++ 源代码,仅包含类定义部分。代码必须继承自 BaseOperator 或 SelfAdjointOperator,并实现 operator() 方法。

  • base_class -- 基类名,决定 dagger 行为。可选值: - "BaseOperator": 一般算子,需手动实现 dag() 方法 - "SelfAdjointOperator": 厄米算子,dag() 自动等于 operator() 默认为 "BaseOperator"。

  • extra_includes -- 额外头文件搜索路径列表。PySparQ 头文件会自动包含。

  • extra_libs -- 额外链接库列表。大多数算子不需要额外库。

  • constructor_args -- 构造函数参数列表,格式为 [(类型, 名称), ...]。 支持的类型: size_t, int, long, double, float, bool, uint64_t。 示例: [("size_t", "reg_id"), ("double", "phase")]

  • cache_dir -- 缓存目录路径。默认使用系统临时目录下的 pysparq_dynamic_ops/。

  • verbose -- 是否输出详细编译日志,用于调试。

返回:

OpClass(reg_id=0, phase=1.0)

返回类型:

动态生成的算子类。可通过关键字参数创建实例,如

抛出:

示例

创建一个简单的翻转算子:

>>> 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")]
... )
>>>
>>> # 创建实例
>>> op = FlipOp(reg_id=0)
>>> print(repr(op))  # FlipOp(reg_id=0)

备注

  • 编译的库会基于代码哈希缓存,避免重复编译。

  • Windows 上可能存在 ABI 兼容性问题(MSVC vs MinGW)。

  • C++ 类名必须与 Python name 参数匹配。

  • 算子中的状态访问: s.get(reg_id).value 获取值,s.amplitude 获取振幅。

参见

get_cache_info: 查询编译缓存状态。 clear_cache: 清除编译缓存。 CompilerConfig: 高级编译器配置。

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

计算代码哈希值,用于缓存

哈希包括:代码内容、类名、编译器版本和配置

参数:
  • cpp_code -- 用户 C++ 代码

  • class_name -- 算子类名

  • config -- 编译器配置

返回:

16 字符的十六进制哈希字符串

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

创建动态算子 Python 类

参数:
  • name -- 算子类名

  • lib_path -- 动态库路径

  • base_class -- 基类名 ("BaseOperator" 或 "SelfAdjointOperator")

  • constructor_args -- 构造函数参数列表 [(type, name), ...]

返回:

动态创建的算子类

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

查找项目根目录或已安装的包目录

对于已安装的包,目录结构为: - site-packages/pysparq/ (Python包) - site-packages/include/ (头文件,包含 basic_components.h)

对于源代码目录: - 项目根目录包含 SparQ/ 和 PySparQ/

返回:

项目根目录路径或已安装的包目录,未找到返回 None

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

格式化编译错误输出

  • 简化文件路径

  • 高亮错误行

  • 提取关键错误信息

参数:
  • stderr -- 编译器标准错误输出

  • source_path -- 源文件路径

返回:

格式化后的错误信息

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

生成完整的 C++ 源文件

参数:
  • cpp_code -- 用户提供的 C++ 代码(包含类定义)

  • class_name -- 算子类名

  • ctor_params -- 构造函数参数声明(如 "int n, double theta")

  • ctor_args -- 构造函数参数调用(如 "n, theta")

  • config -- 编译器配置(使用模板)

返回:

完整的 C++ 源代码字符串

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

获取缓存信息

参数:

cache_dir -- 缓存目录

返回:

包含缓存统计信息的字典

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

快速编译 C++ 算子代码

参数:
  • class_code -- 包含类定义的 C++ 代码

  • class_name -- 类名

  • verbose -- 是否输出详细日志

返回:

共享库文件路径