LSR 0015 - LAMMP 接口规范 ================================================================================ 基本信息 -------------------------------------------------------------------------------- - LSR 编号:0015 - 标题:LAMMP 接口规范 - 作者:Jericho Knox - 状态:草案 - 类型:标准规范类 - 创建日期:06-02-2026 - 归属项目:LAMMP - 适用范围:LAMMP 库所有标准与非标准 API、数据类型、内存模型、兼容约束等 - 替代文档:无 - 相关文档:无 摘要 -------------------------------------------------------------------------------- 本规范定义 **LAMMP** 的所有公共接口,包含**数据类型、上下文系统、函数命名、内存管理、运算规则、错误处理、兼容性约束**。 接口设计目标: 1. **高效性**:最小化调用开销; 2. **简洁性**:接口语义清晰,无冗余设计; 3. **灵活性**:支持无限精度/有限精度双类型体系; 4. **可扩展性**:预留新类型、新运算、新上下文参数扩展空间; 5. **安全性**:上下文隔离、内存安全、类型安全。 本规范**不限制底层实现机制**,仅约束对外暴露的 API 行为与契约。 1. 上下文系统 -------------------------------------------------------------------------------- 1.1 核心设计目标 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 实现**类型安全的泛型设计**,隔离不同精度/位宽/舍入模式的计算环境,避免未定义行为。 1.2 上下文约束规则 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. **不透明结构体指针** 所有上下文类型对外均为不透明指针,禁止直接访问或修改内部成员。 2. **参数不可变约束** 精度、位宽、舍入模式等核心参数**仅在初始化时设置**,初始化后不可修改。 3. **传递规则** 所有运算、初始化、销毁函数必须**显式传递上下文**作为参数。 4. **多实例隔离** 同一作用域可创建多个上下文实例,**类型隔离,不可混用**。 5. **生命周期约束** - 上下文必须在所有关联对象销毁后才能销毁 - 上下文销毁后,关联对象禁止任何操作 - 未销毁关联对象直接销毁上下文 → 内存泄漏/未定义行为 1.3 上下文标准 API 模板 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: c // 上下文初始化:指定精度/位宽,返回上下文句柄 XXX_ctx_t XXX_ctx_init(xxxxxx); // 上下文销毁:必须在所有关联对象销毁后调用 void XXX_ctx_clear(XXX_ctx_t ctx); // 上下文获取配置(可选扩展) size_t XXX_ctx_get_precision(XXX_ctx_t ctx); round_mode_t XXX_ctx_get_rounding(XXX_ctx_t ctx); 1.4 合法/非法示例 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: c // 合法流程 nint_ctx_t ctx1 = nint_ctx_init(20); nint_ctx_t ctx2 = nint_ctx_init(10); nint_t val1, val2; nint_init(val1, ctx1); nint_init(val2, ctx2); // 运算必须使用同一上下文 nint_t res; nint_init(res, ctx1); nint_add(res, val1, val1, ctx1); // 合法 // 销毁顺序:对象 → 上下文 nint_clear(val1, ctx1); nint_clear(val2, ctx2); nint_clear(res, ctx1); nint_ctx_clear(ctx1); nint_ctx_clear(ctx2); .. code-block:: c // 非法示例(禁止行为) nint_add(res, val1, val2, ctx2); // 上下文混用 nint_ctx_clear(ctx1); // 先销毁上下文,后销毁对象 → UB 不建议在同一个作用域内创建多个同一类型的上下文,以避免可能的未定义行为。 2. 数据类型规范 -------------------------------------------------------------------------------- LAMMP 类型分为两大体系: - **无限精度类型**:使用指针存储,自动扩容; - **有限精度类型**:具体精度/位宽取决于设置或依赖上下文。 2.1 有符号整数类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - 类型名 - 精度属性 - 上下文 - 用途 * - ``lmpz_t`` - 无限精度 - 无 - 通用任意精度有符号整数 * - ``nint_t`` - 有限精度 - 有 - 固定位宽有符号整数(高性能批量计算场景) 2.2 有理数类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - 类型名 - 精度属性 - 上下文 - 用途 * - ``lmpq_t`` - 无限精度 - 无 - 精确分数/有理数运算 2.3 浮点数类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - 类型名 - 精度属性 - 上下文 - 用途 * - ``lmpf_t`` - 无限精度 - 无 - 通用任意精度浮点数 * - ``nfloat_t`` - 有限精度 - 有 - 固定精度高性能浮点数(高性能批量计算场景) * - ``lmag_t`` - 无限精度 - 无 - 无符号浮点数(幅值/误差运算) * - ``liar_t`` - 无限精度 - (待定) - 区间算术浮点数(绝对误差限计算) 2.4 多项式类型 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - 类型名 - 系数 - 上下文 - 用途 * - ``lmpz_poly_t`` - 整系数 - 无 - 无限精度整系数 * - ``lmpq_poly_t`` - 有理数 - 无 - 无限精度有理数多项式 * - ``lmpf_poly_t`` - 浮点系数 - 无 - 无限精度浮点系数多项式 * - ``modn_poly_t`` - n的剩余类 - 有 - 有限精度浮点系数多项式 其他数据类型待定。 3. 标准函数接口规范 -------------------------------------------------------------------------------- 3.1 命名规范 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 标准接口函数命名基本范式: .. code-block:: text [前缀]_[动作]_[对象] - 前缀:``lmpz``/``lmpq``/``lmpf``/``nint``/``nfloat``/``liar``... - 动作:``init``/``clear``/``add``/``sub``/``mul``/``div``/``set``/``to``/``cmp``... - 对象:``lmpz``/``lmpq``/``lmpf``/``nint``/``nfloat``/``liar``/``ui``/``si``/``str``... - ``ui`` :无符号整数 - ``str`` :字符串(用于赋值) - ...(其他类型) 示例: - ``lmpz_add`` :无限整数加法 - ``nfloat_mul`` :有限浮点数乘法 - ``nint_set_ui`` :有限整数赋值 - ``nint_to_lmpz`` :有限整数转换为无限整数 - ``nint_to_lmpf`` :有限整数转换为无限浮点数 对于复杂的函数,可以自行考虑合理的命名方式,但应基本遵循上述命名规范。 3.2 生命周期函数 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 四类基本生命周期函数: - 初始化:``init`` - 销毁:``clear`` - 移动:``move`` (源对象相当于被clear) - 拷贝:``copy`` 生命周期函数的实现不强制要求可重入,即实现时,无需保证可重复初始化或重复销毁。**调用方应自行保证不重复调用生命周期函数**。 .. code-block:: c // 初始化对象(绑定上下文) void lmpz_init(lmpz_t op); void nint_init(nint_t op, nint_ctx_t ctx); // 重置/清空对象 void lmpz_clear(lmpz_t op); void nint_clear(nint_t op, nint_ctx_t ctx); // 拷贝对象 void lmpz_copy(lmpz_t rop, const lmpz_t op); void nint_copy(nint_t rop, const nint_t op, nint_ctx_t ctx); // 移动对象(源对象相当于被clear) void lmpz_move(lmpz_t rop, lmpz_t op); void nint_move(nint_t rop, nint_t op, nint_ctx_t ctx); 3.3 运算函数规范 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. **输出参数在前** `` 函数(输出, 输入1, 输入2, 上下文(如需要))`` 2. **const 修饰输入参数** 3. **无返回值**,禁止直接返回指针。 4. **上下文为最后一个参数** 标准格式: .. code-block:: c // 无限精度 void lmpz_add(lmpz_t rop, const lmpz_t op1, const lmpz_t op2); // 有限精度 void nint_add(nint_t rop, const nint_t op1, const nint_t op2, nint_ctx_t ctx); 4. 内存管理规范 -------------------------------------------------------------------------------- 4.1 基本原则 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. **谁初始化,谁销毁** 2. **无限精度类型**:自动管理内存,无需手动扩容 3. **有限精度类型**:上下文统一管理内存池/缓存 4.2 生命周期顺序 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. **有上下文对象**: 1. 创建上下文 2. 初始化对象(绑定上下文) 3. 执行运算 4. 清空对象 5. 销毁上下文 2. **无上下文对象**: 1. 初始化对象 2. 执行运算 3. 清空对象 违反顺序将导致未定义行为(UB)。 5. 错误与异常处理规范 -------------------------------------------------------------------------------- ``LAMMP`` 仅保留最低限度的错误检查,绝大多数错误处理机制都应在 ``Release`` 模式下不发生,这是为了追求绝对的效率。同时,错误或异常只抛出,不处理。错误处理机制应由调用方自行实现。 6. 编码示例 -------------------------------------------------------------------------------- 仅作为参考,实际代码应根据具体实现进行调整。 .. code-block:: c #include "lammp/lmpz.h" int main() { // 初始化全局环境建议在进程或线程创建时调用 lmmp_global_init(); // 初始化全局环境 lmpz_t a, b, c; // 初始化 lmpz_init(a); lmpz_init(b); lmpz_init(c); // 赋值 lmpz_set_ui(a, 1000); lmpz_set_ui(b, 2000); // 运算 lmpz_add(c, a, b); // c = a + b // 输出/使用 // ... // 销毁 lmpz_clear(a); lmpz_clear(b); lmpz_clear(c); lmmp_global_clear(); // 清理全局环境 return 0; } .. code-block:: c #include "lammp/nint.h" int main() { // 初始化全局环境建议在进程或线程创建时调用 lmmp_global_init(); // 初始化全局环境 // 创建上下文 nint_ctx_t ctx = nint_ctx_init(32); // 32 limb 精度 nint_t a, b, c; // 初始化对象 nint_init(a, ctx); nint_init(b, ctx); nint_init(c, ctx); // 赋值与运算 nint_set_ui(a, 12345, ctx); nint_set_ui(b, 67890, ctx); nint_add(c, a, b, ctx); // 销毁 nint_clear(a, ctx); nint_clear(b, ctx); nint_clear(c, ctx); nint_ctx_clear(ctx); lmmp_global_clear(); // 清理全局环境 return 0; } 7. 接口兼容性约束 -------------------------------------------------------------------------------- LAMMP 暴露的接口有**标准接口**和**非标准接口**,标准接口应尽可能保持兼容性,但不作为强制约束。非标准接口通常以 ``XXX_`` 命名(**结尾以下划线收尾**),标准接口则需满足标准接口函数的命名规范。 其他要求如下: 1. 应尽可能避免删除标准接口; 2. 为提高可拓展性和开发自由度,应尽可能暴露非标准接口; 3. 非标准接口可以更加灵活,以运行效率作为第一优先级,而非兼容性; 4. 所有接口应至少兼容C11标准,同时可以兼容C++11标准。