# 基本原理
本文介绍基本原理。
# 科学计算算法替换原理
科学计算函数库分为两个层次,底层算法和上层应用。通过上层应用来调用底层算法,如图所示:
上层应用包含直接对外暴露、用户可直接调用使用的函数集,其大致分类为初等数学、线性代数、插值、微积分、傅里叶变换、稀疏矩阵等板块函数。
底层算法包含 BLAS/LAPACK 等有关矢量、矩阵乘法、矩阵分解、线性方程组求解等底层核心算法工具集,作为基础数学工具箱内核,支撑整个基础数学算法。
当前科学计算函数库中各子库间的依赖关系如下图所示:
本部分以如何替换平台底层算法中 BLAS 算法库为例,介绍科学计算函数库中底层算法的替换原理和过程。
平台提供了 BinaryBuilder 和 libblastrampoline 两个工具。
libblastrampoline 是 BLAS/LAPACK 代理模块,使用 PLT trampolines 提供 BLAS/LAPACK 解复用库,加载时 libblastrampoline 将检查 LBT_DEFAULT_LIBS 环境变量并尝试将对其进行的
BLAS 调用转发到该库,允许用户在运行时动态地选择调用的后端 BLAS/LAPACK 库。BinaryBuilder 是用于构建二进制包的工具库,提供将 C 库编译成动态链接库形式,并封装成_JLL文件,提供自适应操作系统的调用动态链接库接口。
首先利用 BinaryBuilder 将符合 BLAS 标准的
BLASTest库编译成BLASTest_jll文件;撰写第三方库
BLASTest.jl库并依赖BLASTest_jll库;方法核心:在
BLASTest库__init__()函数中,利用BLAS.lbt_forward(libname, clear, verbose)函数,进行转发重定向到BLASTest,如果将clear设置为 1,它将在设置新映射之前清除所有以前的映射,而如果将其设置为 0,它将仅保留给定libname中不存在的符号;其余接口:
lbt_get_config()、lbt_{set,get}_num_threads()用于设置、获取线程等内容;所有
lbt_*函数都应该被认为是线程不安全的。不要尝试同时在两个不同的线程上加载两个BLAS库。构建完成后,使用以下流程进行基本底层
BLAS切换:(1) 复制
BLISBLAS.jl文件路径pkgdir;(2) 通过
using Pkg;Pkg.dev(“pkgdir”)安装库;(3)
using BLISBLAS后利用BLAS.get_config函数进行查看底层库依赖。
# 算法注册/设置接口
# BLAS 接口
- 加载指定
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 是 |
| 返回 | 算法库地址 |
- 设置底层
BLAS库中的线程数
LBT_DLLEXPORT void lbt_set_num_threads(int32_t num_threads);
| 功能 | 设置底层 BLAS 库中的线程数。如果出现多个库被加载,将它们全部设置为相同的值。 |
|---|---|
| 参数 | [in] num_threads 线程数 |
- 获取底层
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.toml和LocalPreferences.toml文件加载。 |
|---|---|
| 参数 | [in] provider String 算法库名称 [in] export_prefs Bool export_prefs 选项确定设置的首选项应存储在 LocalPreferences.toml还是Project.toml中。 |
FFTW.get_provider()
| 功能 | 获取LocalPreferences.toml或Project.toml中存储的算法库名称 |
|---|---|
| 参数 | [out] provider String 算法库名称 |