# 基本原理


本文介绍基本原理。

# 科学计算算法替换原理

科学计算函数库分为两个层次,底层算法和上层应用。通过上层应用来调用底层算法,如图所示:

上层应用包含直接对外暴露、用户可直接调用使用的函数集,其大致分类为初等数学、线性代数、插值、微积分、傅里叶变换、稀疏矩阵等板块函数。

底层算法包含 BLAS/LAPACK 等有关矢量、矩阵乘法、矩阵分解、线性方程组求解等底层核心算法工具集,作为基础数学工具箱内核,支撑整个基础数学算法。

当前科学计算函数库中各子库间的依赖关系如下图所示:

本部分以如何替换平台底层算法中 BLAS 算法库为例,介绍科学计算函数库中底层算法的替换原理和过程。

平台提供了 BinaryBuilder 和 libblastrampoline 两个工具。 libblastrampoline 是 BLAS/LAPACK 代理模块,使用 PLT trampolines 提供 BLAS/LAPACK 解复用库,加载时 libblastrampoline 将检查 LBT_DEFAULT_LIBS 环境变量并尝试将对其进行的 BLAS 调用转发到该库,允许用户在运行时动态地选择调用的后端 BLAS/LAPACK 库。BinaryBuilder 是用于构建二进制包的工具库,提供将 C 库编译成动态链接库形式,并封装成_JLL文件,提供自适应操作系统的调用动态链接库接口。

  1. 首先利用 BinaryBuilder 将符合 BLAS 标准的BLASTest库编译成BLASTest_jll文件;

  2. 撰写第三方库BLASTest.jl库并依赖BLASTest_jll库;

  3. 方法核心:在BLASTest__init__()函数中,利用BLAS.lbt_forward(libname, clear, verbose)函数,进行转发重定向到BLASTest,如果将clear设置为 1,它将在设置新映射之前清除所有以前的映射,而如果将其设置为 0,它将仅保留给定libname中不存在的符号;

  4. 其余接口:lbt_get_config()lbt_{set,get}_num_threads()用于设置、获取线程等内容;

  5. 所有lbt_*函数都应该被认为是线程不安全的。不要尝试同时在两个不同的线程上加载两个BLAS库。

    构建完成后,使用以下流程进行基本底层BLAS切换:

    (1) 复制BLISBLAS.jl文件路径pkgdir

    (2) 通过using Pkg;Pkg.dev(“pkgdir”)安装库;

    (3) using BLISBLAS后利用BLAS.get_config函数进行查看底层库依赖。

# 算法注册/设置接口

# BLAS 接口

  1. 加载指定BLAS算法库

LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear,int32_t verbose, const char * suffix_hint);

功能 加载给定的libname,在导出列表中查找所有已注册的算法库
参数 [in] libname BLAS 库名
[in] clear 是否清除所有已有映射,非 0 为清除,0 保留
[in] verbose 是否打印调试信息,非 0 打印
[in] suffix_hint 是否用于搜索第一个后缀库中的 BLAS,非 NULL 是
返回 算法库地址
  1. 设置底层BLAS库中的线程数

LBT_DLLEXPORT void lbt_set_num_threads(int32_t num_threads);

功能 设置底层 BLAS 库中的线程数。如果出现多个库被加载,将它们全部设置为相同的值。
参数 [in] num_threads 线程数
  1. 获取底层BLAS库中的线程数

LBT_DLLEXPORT int32_t lbt_get_num_threads();

功能 返回底层 BLAS 库配置的线程数。在这种情况下加载多个库,返回所有返回值的最大值。
参数 线程数

# LAPACK接口

加载指定LAPACK算法库

LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t verbose, const char * suffix_hint);

功能 加载给定的libname,在导出列表中查找所有已注册的算法库
参数 [in] libname LAPACK 库名
[in] clear 是否清除所有已有映射,非 0 为清除,0 保留
[in] verbose 是否打印调试信息,非 0 打印
[in] suffix_hint 是否用于搜索第一个后缀库中的 BLAS/LAPACK,非 NULL 是
返回 算法库地址

# FFT 接口

FFTW.set_provider!(provider;export_prefs::Bool = false)

功能 用于设置FFT底层算法库来源的外部函数接口。首选项从加载路径上的Project.tomlLocalPreferences.toml文件加载。
参数 [in] provider String 算法库名称
[in] export_prefs Bool export_prefs 选项确定设置的首选项应存储在LocalPreferences.toml还是Project.toml中。

FFTW.get_provider()

功能 获取LocalPreferences.tomlProject.toml中存储的算法库名称
参数 [out] provider String 算法库名称