
高性能计算科学计算【免费下载链接】OpenBLASOpenBLAS is an optimized BLAS library based on GotoBLAS2 1.13 BSD version.项目地址https://gitcode.com/gh_mirrors/op/OpenBLAS点击查看免费下载OpenBLAS 在实现标准 Netlib BLAS、CBLAS、LAPACK 与 LAPACKE 接口之外还提供了一批 OpenBLAS 特有的扩展函数它们大多可视为BLAS 扩展BLAS-like extensions。本文以 docs/extensions.md 为骨架结合 cblas.h、common_interface.h 及driver/others/、interface/、utest/test_extensions/下的源码与测试系统梳理这些非标准 API 的语义、适用场景与底层实现帮助读者在需要使用矩阵转置、批量 GEMM、低精度计算或精细控制线程行为时直接落地使用。一、BLAS 风格扩展例程BLAS-like Extensions这些例程以 Netlib 参考实现中的标准例程为模板但增加了额外的功能如对y的缩放、原位转置、批量调用等因此属于非标准扩展。下表摘自 docs/extensions.md其中?为类型前缀通配符s/d/c/z 分别对应单精度实数、双精度实数、单精度复数、双精度复数。例程数据类型功能说明?axpbys,d,c,z类似axpy但额外支持对y向量乘以一个系数?gemm3mc,z基于 3M 算法的复数矩阵乘法?imatcopys,d,c,z原位in-place转置/复制?omatcopys,d,c,z非原位out-of-place转置/复制?geadds,d,c,z类似 ATLAS 的矩阵加法B α·A β·B?gemmts,d,c,z仅更新三角部分的gemmcblas_?gemm_batchs,d,c,z,b对若干组输入数据执行批量gemmcblas_?gemm_batch_strideds,d,c,z,b对存放在固定偏移处的多组数据执行批量gemm1.1 变体 axpby带 y 缩放的向量更新标准axpy计算y : α·x y而?axpby扩展为y : α·x β·y即y向量自身也带一个缩放系数 β。这在需要同时覆盖向量累加与缩放的场景例如迭代求解器中的组合更新非常实用可减少一次独立的scal调用。接口层实现位于 interface/axpby.c复数版本为 interface/zaxpby.c其命名沿用了 Fortran BLAS 的NAME/ CBLAS 的CNAME双入口生成机制单元测试可参考 utest/test_extensions/test_saxpby.c、test_daxpby.c 与复数版本的test_caxpby.c、test_zaxpby.c。1.2 gemm3m3M 算法的复数矩阵乘法标准复数gemm需要 4 次实数矩阵乘法而?gemm3m借助 3M 算法把复数乘法拆分为 3 次实数乘法在矩阵规模较大时可以减少一半的浮点开销。它只提供复数类型 c/z。实现入口为 interface/gemm3m.c对应 CBLAS 包装cblas_cgemm3m/cblas_zgemm3m底层复用了 kernel 层的GEMM3M内核测试见 utest/test_extensions/test_cgemm.c 与test_zgemm.c中的 3M 用例。1.3 imatcopy / omatcopy矩阵原位与非原位转置复制?imatcopyin-place matrix copy在同一个矩阵缓冲区内完成转置典型签名形如imatcopy(order, trans, rows, cols, alpha, A, lda, ldb)要求矩阵满足转置后的行数/列数与lda/ldb匹配的约束?omatcopyout-of-place matrix copy把源矩阵转置或按trans指定的方式变换后写入另一个目标缓冲区签名形如omatcopy(order, trans, rows, cols, alpha, A, lda, B, ldb)。两者都支持缩放系数 α即B α·Aᵀ之类的语义。实现位于 interface/imatcopy.c 与 interface/omatcopy.c复数版本 zimatcopy.c、zomatcopy.c测试见 utest/test_extensions/test_simatcopy.c、test_dimatcopy.c 及复数对应文件。1.4 geaddATLAS 风格矩阵加法?geadd计算B : α·A β·B与 ATLAS 提供的同名例程语义一致。注意与标准 BLAS 中输出矩阵 C 独立于输入的惯例不同这里的B既是输入也是输出因此在调用时需要格外注意别名问题。实现位于 interface/geadd.c复数版本 zgeadd.c测试见 utest/test_extensions/test_sgeadd.c、test_dgeadd.c 与复数对应文件。1.5 gemmt仅更新三角部分的矩阵乘法?gemmt与gemm的计算完全相同区别在于只更新结果矩阵的上三角或下三角部分另一三角保持不变。对于对称/三角存储的调用方而言这避免了无谓写入也减少了对缓存行的不必要污染。实现位于 interface/gemmt.c复数/单复数测试分别见 utest/test_extensions/test_sgemmt.c、test_dgemmt.c 与test_cgemmt.c、test_zgemmt.c。1.6 gemm_batch 与 gemm_batch_strided批量矩阵乘法这两组函数用于一次性提交多组独立的 GEMM 计算避免反复调用gemm带来的函数调用与调度开销cblas_?gemm_batch每一组的TransA/TransB/M/N/K/alpha/beta/lda/ldb/ldc均以数组形式传入且A/B/C为指针数组每组独立的内存指针还支持group_count与group_size两级分组结构cblas_?gemm_batch_strided所有组共用同一组Trans/M/N/K/alpha/beta与lda/ldb/ldc每组数据以固定的stridea/strideb/stridec步长存放在同一大数组中最后以group_size指定参与计算的组数。类型前缀?覆盖 s/d/c/z 以及 bbfloat16见后文。实现位于 interface/gemm_batch.c 与 interface/gemm_batch_strided.c其中 strided 版本通过 kernel/level3 的分组调度 将多组任务合并处理对应的 bfloat16 批量入口为cblas_sbgemm_batch/cblas_sbgemm_batch_strided声明见 cblas.h。调用cblas_sgemm_batch的签名形如cblas_sgemm_batch(CblasRowMajor, transa_array, transb_array, m_array, n_array, k_array, alpha_array, a_array, lda_array, b_array, ldb_array, beta_array, c_array, ldc_array, group_count, group_size);二、bfloat16 低精度功能需要BUILD_BFLOAT161bfloat16BF16以 16 位存储、保留 8 位指数与 7 位尾数精度接近 float16 但动态范围与 float32 相当是深度学习中常见的低精度格式。OpenBLAS 在编译时启用BUILD_BFLOAT161后即提供下述函数完整声明见 cblas.h 的/* BFLOAT16 and INT8 extensions */段。2.1 构建开关Makefile 构建在 Makefile.rule 中取消注释BUILD_BFLOAT16 1CMake 构建设置-DBUILD_BFLOAT161相关逻辑见 CMakeLists.txt 与 cmake/kernel.cmake。编译系统通过宏在 Makefile.system 中向 C 编译器追加-DBUILD_BFLOAT16从而启用相关内核与接口。2.2 类型转换函数函数行为void cblas_sbstobf16(n, in, incin, out, incout)把 float 数组按舍入转换为 bfloat16 数组void cblas_sbdtobf16(n, in, incin, out, incout)把 double 数组按舍入转换为 bfloat16 数组void cblas_sbf16tos(n, in, incin, out, incout)把 bfloat16 数组转换为 float 数组void cblas_dbf16tod(n, in, incin, out, incout)把 bfloat16 数组转换为 double 数组转换支持负的 strideincin/incout为负时从尾部反向遍历其 Fortran 风格入口由 interface/bf16to.c 与 interface/tobf16.c 提供底层分别调用 kernel 层转换内核S_BF16_TO_K/D_BF16_TO_K与S_TO_BF16_K等。2.3 计算函数函数语义float cblas_sbdot(n, x, incx, y, incy)两个 bfloat16 数组的点积结果以 float 返回void cblas_sbgemv(...)GEMV输入矩阵 A 与向量 X 为 bfloat16alpha/beta与结果 Y 为 floatvoid cblas_sbgemm(...)GEMM两个输入数组均为 bfloat16alpha/beta与 C 为 floatvoid cblas_bgemv(...)GEMVA、X、alpha/beta与结果 Y全部为 bfloat16void cblas_bgemm(...)GEMMA、B、alpha/beta与 C全部为 bfloat16关键区别在于半精度输入、单精度累加输出sbgemm/sbgemv/sbdot与全 bfloat16 链路bgemm/bgemv两种模式前者用 float 做中间累加以降低精度损失更适合作为低精度权重、高精度累加的训练/推理场景后者则完全在 bfloat16 域内计算适合对存储带宽更敏感的场景。cblas_sbdot的接口实现位于 interface/bf16dot.c核心调用 kernel 层BF16_DOT_Ksbgemv的驱动在 driver/level2/sbgemv_thread.csbgemm的驱动在 driver/level3 下对应内核。测试集中在 utest/test_extensions/test_bgemm.c含sbgemm与bgemm的数值验证。bfloat16 的批量扩展同样存在cblas_sbgemm_batch与cblas_sbgemm_batch_strided。三、半精度 fp16 功能需要BUILD_HFLOAT161当以BUILD_HFLOAT161编译Makefile.rule 中对应宏CMake 同理时OpenBLAS 提供 fp16 扩展。目前文档列出的核心例程为void cblas_shgemm(...)两个输入矩阵均为hfloat16alpha/beta与输出 C 为 float 的 GEMM。其签名见 cblas.h 的/* FLOAT16 extensions */段与cblas_sbgemm完全平行只是数据类型换成hfloat16。fp16 的 GEMM 内核在 kernel 目录下随架构提供例如 x86 的 fp16 指令路径测试见 utest/test_extensions/test_bgemm.c 中的 fp16 用例。四、运行时工具函数Utility FunctionsOpenBLAS 还导出一组查询/控制运行时行为的工具函数实现集中在 driver/others 目录。4.1 线程数量控制openblas_get_num_threads()返回当前线程数openblas_set_num_threads(int num_threads)设置线程数。底层实现在 driver/others/openblas_get_num_threads.c 与 driver/others/openblas_set_num_threads.c。注意在未启用多线程非SMP_SERVER的构建中openblas_set_num_threads是空操作openblas_set_num_threads_local固定返回 1见 openblas_set_num_threads.c 的#else分支。这两个函数还提供带尾下划线的 Fortran 风格入口openblas_get_num_threads_/openblas_set_num_threads_。更精细的运行时线程控制还有int openblas_get_num_procs(void)返回系统可用处理器数量可能包含超线程核int openblas_get_parallel(void)返回当前并行后端类型——0表示顺序单线程执行1表示基于平台线程SMP的实现2表示基于 OpenMP 的实现。该返回值由 driver/others/openblas_get_parallel.c 根据编译宏USE_OPENMP/SMP_SERVER静态决定。4.2 构建配置查询char * openblas_get_config()返回编译时选项字符串例如NO_LAPACKE DYNAMIC_ARCH NO_AFFINITY Haswellchar * openblas_get_corename()返回当前动态架构下运行时选中的CPU 核心代号。实现见 driver/others/openblas_get_config.c。openblas_get_config返回的字符串由一组#ifdef拼接而成包含VERSION、USE64BITINT、NO_CBLAS、NO_LAPACK、NO_LAPACKE、DYNAMIC_ARCH、NO_AFFINITY、USE_OPENMP、USE_TLS、USE_LOCKING等标志在DYNAMIC_ARCH下还会附加gotoblas_corename()得到的当前内核名称最后追加SINGLE_THREADED或MAX_THREADSNN 为编译期MAX_CPU_NUMBER。这也是快速诊断装好的 OpenBLAS 到底开了哪些特性的最直接手段。4.3 线程亲和性设置int openblas_set_affinity(int thread_index, size_t cpusetsize, cpu_set_t *cpuset)把指定线程的 CPU 亲和掩码设为给定 cpuset。仅 Linux 可用语义与pthread_setaffinity_np完全一致。在平台线程后端driver/others/blas_server.c中其内部函数openblas_setaffinity/openblas_getaffinity会先检查thread_idx是否落在[0, active_threads)随后把最后一个线程视作调用线程自身、其余线程映射到内部线程句柄再转发给pthread_setaffinity_np/pthread_getaffinity_np。OpenMP 后端blas_server_omp.c则提示改用 OpenMP 环境变量设置亲和性。4.4 自定义线程后端openblas_set_threads_callback_function(openblas_threads_callback callback)用调用方提供的回调覆盖默认多线程后端。回调类型定义在 common_interface.htypedef void (*openblas_dojob_callback)(int thread_num, void *jobdata, int dojob_data); typedef void (*openblas_threads_callback)(int sync, openblas_dojob_callback dojob, int numjobs, size_t jobdata_elsize, void *jobdata, int dojob_data);全局回调变量openblas_threads_callback_与设置函数位于 driver/others/blas_server_callback.c注释明确提醒该函数不是线程安全的必须在调用任何其他 OpenBLAS 函数之前调用以便把线程管理权移交给调用方例如自定义任务调度器或运行时。4.5 自定义 XERBLA 错误处理openblas_set_xerbla(openblas_xerbla_handler handler)替换当前 OpenBLAS 实例的 XERBLA 处理函数返回上一个handler传入NULL恢复默认实现。handler 原型见 common.htypedef void (*openblas_xerbla_handler)(const char *name, const blasint *info, size_t name_length);实现位于 driver/others/xerbla.c默认 handler 以** On entry to %6.*s parameter number %2lld had an illegal value格式打印违规参数号xerbla.c 中MSGFMT宏内部openblas_xerbla_dispatch通过原子锁分发到当前注册的 handler。文档特别强调三点回调可能被并发调用因此 handler 必须是线程安全的name只在回调期间有效name_length字节不保证以 NUL 结尾回调内应使用name_length而非strlen默认实现即用memchr在限定长度内查找终止符见openblas_xerbla_name_lengthELF 平台上如果应用自己提供强符号xerblaFortran 入口BLASFUNC(xerbla)被声明为weak, alias(__xerbla)该强符号会绕过注册的 handlerxerbla.c 的__ELF__分支。单元测试 utest/test_extensions/xerbla.c 演示了如何注册自定义 handler、校验srname与info的一致性并恢复默认行为。五、相关环境变量与文档入口线程相关扩展通常与环境变量配合使用。例如 docs/runtime_variables.md 记录了OPENBLAS_NUM_THREADS非 OpenMP 构建下使用的线程数与GOTO_NUM_THREADS其等价别名driver/others/openblas_env.c 中openblas_read_env还会读取OPENBLAS_VERBOSE、OPENBLAS_THREAD_TIMEOUT、OPENBLAS_BLOCK_FACTOR、OPENBLAS_DEFAULT_NUM_THREADS与OMP_NUM_THREADS等供诊断与调优使用。扩展 API 的系统性测试位于 utest/test_extensions其中utest_main2.c汇总了各扩展例程的测试入口是阅读各 API 参数语义与预期行为的良好起点。六、小结OpenBLAS 的扩展 API 覆盖三个层面矩阵运算扩展axpby、imatcopy/omatcopy、geadd、gemmt、gemm3m、gemm_batch 系列、低精度计算bfloat16 与 fp16 的转换/点积/GEMV/GEMM编译期由BUILD_BFLOAT16/BUILD_HFLOAT16控制以及运行时控制线程数、处理器数、并行后端类型、构建配置、亲和性、自定义线程后端与 XERBLA handler。这些 API 并非 Netlib 标准属于 OpenBLAS 私有扩展迁移到其他 BLAS 实现时需要做兼容处理但正因如此它们能更精细地满足高性能计算与 AI 推理场景下的特殊需求。本文所引用的接口声明、实现文件与测试用例均可在当前仓库中直接查阅验证。赞分享高性能计算科学计算【免费下载链接】OpenBLASOpenBLAS is an optimized BLAS library based on GotoBLAS2 1.13 BSD version.项目地址https://gitcode.com/gh_mirrors/op/OpenBLAS点击查看免费下载相关推荐OpenBLAS CSROT/ZSROT旋转运算高性能复数平面旋转的终极指南OpenBLAS CSROT/ZSROT旋转运算高性能复数平面旋转的终极指南 OpenBLAS作为优化的BLAS基础线性代数子程序库提供了高性能的数学计高性能计算科学计算SVGKit自定义扩展终极指南如何支持非标准SVG标签SVGKit自定义扩展终极指南如何支持非标准SVG标签 在iOS和macOS应用开发中SVGKit是一个强大的开源库能够原生渲染SVG矢量图形。但在实际项UI组件图形学Pino API 完全指南从 pino() 工厂函数到日志实例、静态工具与 TypeScript 类型扩展Pino API 完全指南从 pino 工厂函数到日志实例、静态工具与 TypeScript 类型扩展 Pino 是一个以性能为设计核心的 Node.js 结上一篇如何快速实现跨平台移动自动化Mobile MCP终极指南下一篇snips.shSSH驱动的代码片段管理工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考