libxsmm

GitHub
948 202 较难 1 次阅读 3天前BSD-3-Clause数据工具开发框架
AI 解读 由 AI 自动生成,仅供参考

libxsmm 是一款专为高性能计算设计的开源库,专注于加速密集与稀疏矩阵运算,以及深度学习中的基础操作(如小型卷积)。它主要解决了在 Intel 架构处理器上,如何无需重新编译即可自动适配不同指令集(如 SSE、AVX-512 及未来的 AMX)以榨取极致性能的问题。

传统数学库往往需要针对特定硬件设置复杂的编译标志,而 libxsmm 通过独特的即时(JIT)代码生成技术,能够在运行时动态生成最优化的机器码。这意味着开发者只需构建一次程序,即可在各种支持的 Intel CPU 上自动获得最佳执行效率,真正实现了“一次构建,处处高效”。此外,它还广泛支持 FP64、FP32、bfloat16 以及 int8/int16 等多种数据类型,灵活满足从科学计算到量化神经网络的不同需求。

这款工具非常适合需要底层性能优化的 C/C++ 或 Fortran 开发者、高性能计算研究人员以及从事深度学习框架开发的工程师使用。如果你正在开发对矩阵乘法速度极其敏感的应用,或者希望在异构计算环境中简化部署流程,libxsmm 提供了一个强大且编译器无关的解决方案,帮助你将硬件潜力发挥到极致。

使用场景

某高性能计算团队正在开发一套基于 CPU 的实时金融风险预测系统,核心算法依赖海量的小矩阵乘法运算。

没有 libxsmm 时

  • 性能瓶颈严重:通用数学库(如标准 BLAS)针对大矩阵优化,处理系统中大量 $13 \times 5$ 这类微小矩阵时,函数调用开销远超计算本身,导致 CPU 利用率极低。
  • 硬件潜力浪费:代码无法自动适配不同代际的 Intel 处理器,难以利用 AVX-512、VNNI 或 AMX 等新指令集加速,升级硬件后性能无明显提升。
  • 维护成本高昂:为了榨取性能,开发人员被迫手动编写复杂的内联汇编或针对特定编译器调整标志,导致代码移植性差,“一次构建”无法“到处部署”。

使用 libxsmm 后

  • 运算速度飞跃:libxsmm 通过即时编译(JIT)技术生成专用内核,消除了小矩阵计算的调用开销,使风险预测模型的推理延迟降低了 80% 以上。
  • 自动硬件适配:程序运行时自动检测当前 CPU 架构并生成最优指令代码,无需修改源码即可在旧款服务器或最新 Sapphire Rapids 芯片上满血运行。
  • 开发效率提升:团队只需调用简洁的 C++ 接口即可实现高精度矩阵运算,不再受困于底层指令集差异,显著缩短了从算法验证到生产部署的周期。

libxsmm 通过动态生成专属机器码,将原本被通用库拖累的小矩阵计算转化为极致性能,让算法真正跑满硬件极限。

运行环境要求

操作系统
  • Linux
  • macOS
  • FreeBSD
GPU
  • 不需要 GPU
  • 该库专为 Intel CPU 架构优化,支持 SSE, AVX, AVX2, AVX-512 (含 VNNI/Bfloat16) 及 AMX 指令集
内存

未说明(取决于具体矩阵运算规模,库本身针对小矩阵乘法优化)

依赖
notes1. 该库主要针对 Intel 架构处理器进行优化,不支持非 Intel 平台的 SIMD 加速。 2. 核心功能是即时编译 (JIT) 生成代码以执行小型密集/稀疏矩阵乘法及深度学习原语。 3. 适用于‘一次构建,到处部署’,无需针对特定目标架构设置特殊编译标志即可利用可用性能。 4. 可通过 Fedora/RedHat/CentOS, Debian/Ubuntu, FreeBSD 的包管理器安装,或使用 Spack/EasyBuild 安装。 5. 默认需要 C/C++ 和 Fortran 编译器,若不需要 Fortran 接口可通过配置禁用。
python不需要 Python(主要提供 C, C++, Fortran 接口)
GNU Make
C/C++ 编译器 (如 GCC, Clang, Intel Compiler)
Fortran 编译器 (可选,如 gfortran)
BLAS 库 (用于示例链接,如 -lblas)
libxsmm hero image

快速开始

LIBXSMM

BSD 3-Clause 许可证 GCC 构建状态 Clang 构建状态 Intel 构建状态 混合构建状态 静态分析状态 Read the Docs

LIBXSMM 是一个用于专用密集和稀疏矩阵运算以及深度学习原语(如小型卷积)的库。该库主要面向英特尔架构,支持 Intel SSEIntel AVXIntel AVX2Intel AVX‑512(含 VNNI 和 Bfloat16)以及未来代号为 Sapphire Rapids 的英特尔处理器所支持的 Intel AMX(高级矩阵扩展)。代码生成主要基于 即时编译 (JIT) 技术,以实现与编译器无关的高性能(包括矩阵乘法、矩阵转置/复制、稀疏功能和深度学习)。LIBXSMM 适合“一次构建,随处部署”,即无需使用特定的目标标志即可充分利用现有性能。支持的 GEMM 数据类型有:FP64FP32bfloat16int16int8

有关常见问题解答,请参阅 https://github.com/libxsmm/libxsmm/wiki/Q&A

文档在哪里可以找到?

入门:以下 C++ 代码专注于特定功能,但也可被视为 Hello LIBXSMM。使用 cd /path/to/libxsmm; make STATIC=0(共享库)编译示例,将代码保存为 hello.cpp(如下所示),并使用 g++ -I/path/to/libxsmm/include hello.cpp -L/path/to/libxsmm/lib -lxsmm -lblas -o hello(GNU CCC)进行编译,最后通过 LD_LIBRARY_PATH=/path/to/libxsmm/lib LIBXSMM_VERBOSE=2 ./hello 运行。

#include <libxsmm.h>
#include <vector>
int main(int argc, char* argv[]) {
  typedef double T;
  int batchsize = 1000, m = 13, n = 5, k = 7;
  std::vector<T> a(batchsize * m * k), b(batchsize * k * n), c(m * n, 0);
  /* C/C++ 和 Fortran 接口均可使用 */
  typedef libxsmm_mmfunction<T> kernel_type;
  /* 生成并调度一个矩阵乘法内核(C++ 函数对象) */
  kernel_type kernel(LIBXSMM_GEMM_FLAG_NONE, m, n, k, 1.0 /*alpha*/, 1.0 /*beta*/);
  assert(kernel);
  for (int i = 0; i < batchsize; ++i) { /* 初始化输入 */
    for (int ki = 0; ki < k; ++ki) {
      for (int j = 0; j < m; ++j) a[i * j * ki] = static_cast<T>(1) / ((i + j + ki) % 25);
      for (int j = 0; j < n; ++j) b[i * j * ki] = static_cast<T>(7) / ((i + j + ki) % 75);
    }
  }
  /* 内核执行矩阵乘法并累加结果:C += Ai * Bi */
  for (int i = 0; i < batchsize; ++i) kernel(&a[i * m * k], &b[i * k * n], &c[0]);
}

C 代码 以及 Fortran 代码 与上述 示例 类似。

什么是小型矩阵乘法? 当使用 M、N 和 K 参数来表征问题规模时,适合 LIBXSMM 的问题规模大致位于 (M N K)1/3 <= 64 范围内(这表明非方阵甚至“高而瘦”的形状也包含在内)。该库不采用多级 K、M、N 分块策略。如果将 LIBXSMM 用于更大的规模,可能会生成过多的代码(由于在 M 或 K 维度上的展开),同时也无法实现有效的分块方案来充分利用缓存层次结构。就 GEMM 而言,支持的内核仅限于 Alpha := 1Beta := { 1, 0 } 以及 TransA := 'N'

接口与领域

概述

请参阅 https://github.com/libxsmm/libxsmm/tree/main/include,了解所有已发布的函数。以下列出可用的领域及已记录的功能:

为了初始化库内部资源,显式初始化例程有助于避免首次调用 LIBXSMM 时的延迟初始化开销。库会在程序退出时释放内部资源,但也提供了与上述初始化配套的终止例程。

/** 初始化库;在特定时刻承担设置成本。 */
void libxsmm_init(void);
/** 反初始化库并释放内部内存(可选)。 */
void libxsmm_finalize(void);

矩阵乘法

该领域(MM)支持小型矩阵乘法(SMM)、多组矩阵乘法批处理,以及业界标准的通用矩阵-矩阵乘法(GEMM)接口。

矩阵乘法领域(MM) 包含以下例程:

深度学习

在此我们展示如何利用 LIBXSMM 提供的张量处理原语来实现深度学习应用中的常见算子,例如带有激活函数融合的 GEMM、带有激活函数融合的卷积、各类归一化算子以及池化算子等。用于性能评估的示例驱动程序作为 LIBXSMM_DNN 的一部分提供。

服务函数

为了方便库的使用和集成,提供了一些服务例程。这些例程可能不属于 LIBXSMM 的核心功能(SMM 或 DNN 领域),但建议用户使用此领域(AUX)。它们分为两类:(1) 同时适用于 C 和 FORTRAN 的例程,以及 (2) 仅通过 C 接口可用的例程。

服务函数领域(AUX) 包含以下例程:

后端

有关 JIT 后端和代码生成器的更多信息,请参阅单独的 文档编码器示例集 可帮助您开始使用 LIBXSMM 编写内核。请注意,LIBXSMM 的独立 生成器驱动程序 已被视为遗留(已弃用)。

构建说明

概述

主接口文件是 生成的,因此 存储在代码仓库中。要查看 C/C++FORTRAN 的接口,可以参考用于生成实际接口的模板文件。构建和使用 LIBXSMM 的一般方法有两种:

:LIBXSMM 以预编译包的形式提供给 Fedora/RedHat/CentOS、Debian/Ubuntu、FreeBSD 等系统。此外,LIBXSMM 还可以通过 Spack 包管理器EasyBuild+EasyConfig 进行安装。

经典库(ABI)

对于给定的项目,有两种方式可以依赖预构建的代码:(1) 使用 LIBXSMM 的基于 Makefile 的构建系统,(2) 或者 使用其他构建系统并编写自己的 LIBXSMM 构建规则。基于 Makefile 的构建系统依赖于 GNU Make(通常与 make 命令相关联,但例如 FreeBSD 将其称为 gmake)。可以通过使用 键‑值 对来定制构建。键‑值 对可以通过两种方式提供:(1) 在 “make” 命令之后,或(2) 在 “make” 命令之前(env),这实际上等同于将 键‑值 对作为环境变量导出(exportsetenv)。这两种方法可以混合使用(第二种方法可能需要 make 的 -e 标志)。

与默认情况下无需配置的 仅头文件 不同,第三方构建系统可以编译和链接 LIBXSMM 的源代码,但仍可避免对库进行配置(通过 libxsmm_config.py)。省略配置的前提是通过定义 LIBXSMM_DEFAULT_CONFIG (-D) 来选择启用该功能。零配置功能不适用于 LIBXSMM 的 Fortran 接口。

注意:默认情况下需要 C/C++ 和 FORTRAN 编译器(部分示例代码是用 C++ 编写的)。除了指定编译器(make CXX=g++ CC=gcc FC=gfortran,也许还需要 AR=ar)之外,还可以放宽对 FORTRAN 编译器的要求(make FC=make FORTRAN=0)。后者会影响 MODule 文件以及相应的 libxsmm.f 库的可用性(接口 libxsmm.f 仍然会被生成)。

构建系统会将一组给定的键值对视为一个唯一的构建,并为不同的标志组合触发重新构建。如需更高级的构建或更多背景信息,请参阅关于 自定义 的章节。要在 include 目录内生成库的接口并构建静态库(默认情况下,STATIC=1 已启用),请运行以下任一命令(或两者):

make STATIC=0
make

在 CRAY 系统上,无论使用 CRAY 编译器、Intel 编译器还是 GNU 编译器集合(GCC),都应使用 CRAY 编译环境(CCE)。CCE 最终会禁止构建共享库(STATIC=0)。无论如何,(1) 切换到所需的编译器(加载/切换模块),然后(2) 依赖以下命令:

make CXX=CC CC=cc FC=ftn

多种构建环境开箱即用即可兼容,详情请参阅 https://github.com/libxsmm/libxsmm/wiki/Compatibility。如果构建过程失败,尝试避免使用高级 GCC 标志可能会有所帮助。这对于那些假装与 GCC 兼容(并被当作 GCC 兼容处理)但实际上无法识别上述标志的工具链尤其有用:

make COMPATIBLE=1

如果 Binutils 版本过旧,在构建库时可能会导致汇编失败(这与 JIT 生成的代码无关,也不会影响 JIT 代码对系统的优化)。LIBXSMM 实现了一些功能,使用了编译器内置函数和多个根据 CPUID 调度的代码路径。与 INTRINSICS=2(默认值)不同,INTRINSICS=1 会启用完全静态的代码路径,以适应目标架构。如果没有指定目标(例如 AVX=3AVX=2),则无法针对这些代码路径利用指令集扩展。尝试通过安装最新版本的 GNU Binutils 来修复编译失败(并执行 export PATH=/path/to/binutils/bin:${PATH})。Binutils 的版本独立于 GNU GCC 和其他编译器。如果无法更新 Binutils,则可以使用 libxsmm_cpuid.h 中列出的 CPUID 值作为替代方案:从较高的值开始(小于 1999),逐步递减,直到编译成功为止(例如,make INTRINSICS=1021)。作为最后的手段,可以采用完全静态的代码路径:

make INTRINSICS=1

要测试和验证构建结果,请参阅 https://github.com/libxsmm/libxsmm/wiki/Validation。为了运行一些基本的健全性检查,需要注意的是,每组给定的键值对代表不同的构建(及测试):

make STATIC=0 tests

要删除中间文件,或删除所有生成的文件和文件夹(包括接口和库归档文件),请运行以下其中一个 make 目标。额外的 distclean 目标会递归地清理整个目录树(自 版本 1.9 之后)。

make clean
make realclean

FORTAN 代码可以使用 LIBXSMM:

  • 通过使用模块并与 libxsmmflibxsmmlibxsmmext 链接,
  • 通过包含 libxsmm.f 并与 libxsmmlibxsmmext 链接,或
  • 通过(隐式)调用子程序并与 libxsmmlibxsmmext 链接。

注意libxsmmf 需要 libxsmmext(自 LIBXSMM 2.0 开始),因此也需要链接 OpenMP 运行时库。

使用 Fortran 模块(或包含接口)至少需要 Fortran 2003 编译器(F2K3)。FORTAN 77 兼容性仅以隐式方式提供(无接口),且可用的例程子集记录在 libxsmm.f 中,并用 注释 标记(属于实现的一部分)。

仅头文件

版本 1.4.4 引入了对 C 和 C++ 中“仅头文件”用法的支持。只需包含 libxsmm_source.h 即可避免构建整个库。然而,这种方式放弃了明确定义的应用二进制接口(ABI)。使用共享库形式时,ABI 允许在应用部署后进行热修复,并确保仅依赖 LIBXSMM 的公共接口。相比之下,仅头文件形式不仅暴露了 LIBXSMM 的内部实现,还可能因编译时间延长而增加应用开发的周转时间。该头文件被有意命名为 “libxsmm_source.h”,因为它依赖于 src 目录(如前所述)。

仅头文件形式依赖于根据源代码目录(src)内容生成libxsmm_source.hLIBXSMM 1.16(及更高版本)提供了无需调用 make 目标即可实现的仅头文件支持(零配置),适用于任何 LIBXSMM 检出版本。若要使用非默认的已配置仅头文件模式,必须定义 LIBXSMM_CONFIGURED-D)。此前,需要调用 make header-only(v1.6.2 或更高版本)、make cheader(v1.6.2 之前)或任何用于构建库的目标(make)。零配置特性使第三方构建系统能够更轻松地集成 LIBXSMM,即使系统从源码构建 LIBXSMM 也是如此(参见 经典 ABI)。Fortran 代码可以包含 libxsmm.f,但仍需生成相应接口。

注意:构建应用程序时,会将相同的构建设置应用于 LIBXSMM!例如,若要省略 LIBXSMM 内部的调试代码,必须定义 NDEBUG-DNDEBUG)。

构建 LIBXSMM 的规则

LIBXSMM 可以作为仅头文件库使用,即无需预先构建任何源代码。然而,有时也可能希望使用自定义设置或构建系统将 LIBXSMM 构建成中间库。在这种情况下,仍可实施自定义构建规则,在编译代码之前配置 LIBXSMM 的接口。更常见的是,以自定义方式从源码构建 LIBXSMM 时,可能会选择不配置接口,而直接采用“(零配置)[#zero-config-abi]”,即定义 LIBXSMM_DEFAULT_CONFIG-DLIBXSMM_DEFAULT_CONFIG)。例如,LIBXSMM 的 CMake 模块可能如下所示:

include(FetchContent)
FetchContent_Declare(
  xsmm
  URL https://github.com/chelini/libxsmm/archive/<your-preferred-revision>.tar.gz
  URL_HASH SHA256=<sha256sum-corresponding-to-above-revision>
)
FetchContent_GetProperties(xsmm)
if(NOT xsmm_POPULATED)
  FetchContent_Populate(xsmm)
endif()

set(LIBXSMMROOT ${xsmm_SOURCE_DIR})
file(GLOB _GLOB_XSMM_SRCS LIST_DIRECTORIES false CONFIGURE_DEPENDS ${LIBXSMMROOT}/src/*.c)
list(REMOVE_ITEM _GLOB_XSMM_SRCS ${LIBXSMMROOT}/src/libxsmm_generator_gemm_driver.c)
set(XSMM_INCLUDE_DIRS ${LIBXSMMROOT}/include)

add_library(xsmm STATIC ${_GLOB_XSMM_SRCS})
target_include_directories(xsmm PUBLIC ${XSMM_INCLUDE_DIRS})
target_compile_definitions(xsmm PUBLIC
  LIBXSMM_DEFAULT_CONFIG
)

链接说明

使用经典 ABI(包括Fortran代码)时,需要将 LIBXSMM 链接到应用程序中。该库与线程运行时无关,因此应用程序可以自由使用任何线程运行时(例如 OpenMP)。该库也是线程安全的,多个应用线程可以同时调用 LIBXSMM 的例程。为 LIBXSMM 主库启用 OpenMP 也受支持(OMP=1),这主要影响库内使用的同步原语。所有“omp”功能(函数后缀)均由 libxsmmext 库提供,该库会自动以启用 OpenMP 的方式构建。使用这些“omp”功能时,链接行中必须包含 libxsmmext

用途
libxsmm 线程安全的核心函数(同一例程可被并发调用)。包含可接收线程 ID 和库外线程数量的例程。
libxsmmf 使用 Fortran MODule 时必需,但包含 libxsmm.f 或依赖隐式接口(Fortran 77)时则不需要。

为简化与 LIBXSMM 的链接,可以使用 pkg-config。例如:

export PKG_CONFIG_PATH=/path/to/libxsmm/lib
pkg-config libxsmm --libs

同样,应用程序可以自由选择任何 BLAS 或 LAPACK 库(前提是操作系统上的链接模型支持),因此在链接 LIBXSMM 本身时链接 GEMM 例程(通过指定 BLAS=1|2)可能会妨碍用户在最终链接应用程序时做出这一决定。若要使用不包含 GEMM 相关功能的 LIBXSMM,可以通过两种方式移除对 BLAS 的依赖:(1) 构建一个特殊库,使用 make BLAS=0;或 (2) 链接应用程序至 libxsmmnoblas 库。然而,如果应用程序已经使用 BLAS,则可以使用调用包装器来拦截现有的 BLAS 调用,并改用 LIBXSMM。

注意:当 BLAS 以静态方式链接(“.a”)时,LIBXSMM 不支持动态链接 libxsmmlibxsmmext(“.so”)。如果 BLAS 是静态链接的,则必须使用 LIBXSMM 的静态版本!

安装

安装 LIBXSMM 有两种主要方式(这两种方式可以结合使用):(1) 以树外的方式构建库,以及 (2) 将其安装到指定位置。 树外构建的方式如下:

cd libxsmm-install
make -f /path/to/libxsmm/Makefile

安装到特定位置的方式如下(使用 PREFIXDESTDIR):

make MNK="1 2 3 4 5" PREFIX=/path/to/libxsmm-install install

PREFIXDESTDIR 是等效的,可以是相对路径或绝对路径。可以在不同的位置重复进行安装操作,而无需重新构建。除非指定了 PREFIXDESTDIR,否则每个 包配置文件 中的前缀目录都会被设置为 LIBXSMM 的构建目录(暂存文件夹)。PREFIX(或 DESTDIR)对 pkg-config 文件的影响与是否调用了安装目标无关(即通过 make 命令执行时)。

此外,执行 make install-minimal 会跳过文档的安装(默认情况下,文档会被安装到 PREFIX/share/libxsmm)。另外,PINCDIRPOUTDIRPBINDIRPDOCDIR 允许自定义在 PREFIX 目录下的子目录位置。为了构建一个面向不确定用户的通用软件包(例如 Linux 发行版或其他类似环境),建议不要过度指定或自定义构建步骤,即不应启用 JIT、SSE、AVX、OMP、BLAS 等选项。以下示例展示了如何构建并安装一套完整的库,使生成的接口同时匹配静态库和共享库:

make PREFIX=/path/to/libxsmm-install STATIC=0 install
make PREFIX=/path/to/libxsmm-install install

运行时控制

错误处理

该库使用 C 语言提供的机制来处理错误(不使用异常)。后端通过参数传递结果代码,而不是直接返回值。这个参数通常是一个描述符结构体,用于指示和记录代码生成的状态。然而,前端可能不会报告任何错误状态,这在调用端可能会带来很大的便利。相反,前端实现了详细模式,用于提示意外输入或从后端捕获的错误。LIBXSMM 的设计原则是默认静默运行(非详细模式),并且不会导致程序意外退出。

详细模式

详细模式(详细程度)允许用户在库结束运行时,通过接收一份简短的表格式统计信息,深入了解代码调度机制。此功能的设计目标是不影响任何关键代码路径的性能,因此详细模式始终启用,且不需要符号表(SYM=1)或调试代码(DBG=1)。当环境变量 LIBXSMM_VERBOSE 被设置为非零值时,统计信息会输出到标准错误流 (stderr)。例如:

LIBXSMM_VERBOSE=1 ./myapplication
[... 应用程序输出]

HSW/SP      TRY    JIT    STA    COL
   0..13      0      0      0      0
  14..23      0      0      0      0
 24..128      3      3      0      0

这些表格会根据单精度和双精度分别显示,但如果所有计数器都为零,则表格会被省略。如果两个表格都被省略,库会显示原本计划用于 JIT 编译的代码路径:LIBXSMM_TARGET=hsw(否则代码路径会显示在表格标题中)。实际的计数器分为三个类别:小型核(MNK1/3 <= 13)、中型核(13 < MNK1/3 <= 23)以及大型核(23 < MNK1/3 <=& 64;实际上限取决于编译时选择的 LIBXSMM_MAX_MNK)。需要注意的是,“大型”核在算术强度方面仍然属于较小规模,而算术强度会随着核大小线性增长。遗憾的是,算术强度取决于核的具体使用方式(哪些操作数被加载或存储到主内存中),收集这些信息会对性能产生一定影响。

TRY 计数器表示所有尝试注册静态生成的核,以及所有尝试动态生成并注册核的行为。它还包括因 GEMM 参数不支持而被拒绝的 JIT 请求。JITSTA 计数器则将上述事件(TRY)的成功案例进一步区分为动态生成的代码(JIT)和静态生成的代码(STA)。如果代码注册表的容量(O(n) = 105)已满,即使继续尝试也无法再注册新的核。不过,多次注册核(O(n) = 103)可能会增加哈希冲突次数(COL),从而降低性能。如果有效利用小型线程局部缓存,则可以避免这种情况。

注册表:20 MB(gemm=0 mcopy=14 tcopy=0)

如果使用调用包装器,还可以获得额外的运行时统计信息(参见 调用包装器)。

注意:将 LIBXSMM_VERBOSE 设置为负值会使每个生成的 JIT 核被转储到一个二进制文件中,文件名与 Intel VTune 中显示的函数名相同。可以通过以下命令反汇编这些原始二进制文件:

objdump -D -b binary -m i386 -M x86-64 [JIT-dump-file]

调用跟踪

在初次使用 LIBXSMM API 时,可以依赖库的调试版本(make DBG=1)。该版本在库内部出现错误或警告时还会输出到控制台(stderr)。此外,还可以打印 LIBXSMM 内部的执行流程(调用跟踪),这可以与 DBG=1 或 OPT=0 结合使用:

make TRACE=1

构建一个能够跟踪库内调用的应用程序需要 LIBXSMM 的共享库;或者,应用程序也可以以动态方式链接 LIBXSMM 的静态库(GNU 工具链:-rdynamic)。无需调试器即可实现调用跟踪的方法是通过名为 LIBXSMM_TRACE 的环境变量。

LIBXSMM_TRACE=1 ./myapplication

语法上最多可接受三个由逗号分隔的参数(允许省略参数):tid 表示要跟踪的线程 ID,取值范围为 1 到 NTHREADS;当 LIBXSMM_TRACE=1 时,默认会筛选“主线程”(即首次进入跟踪设施的线程)。若要捕获所有线程(不加筛选),可以提供一个负数 ID(这也是省略参数时的默认值)。第二个参数用于修剪调用树的更高层级,默认值为 i=1(其中零级是最顶层,与主函数处于同一级别)。最后一个参数指定包含的调用层级数,默认值为 n=-1(表示无筛选)。

尽管 ltrace(Linux 工具)也能提供类似的洞察,但上述提到的筛选表达式使得 LIBXSMM 的跟踪功能更具实用性。请注意,即使在 LIBXSMM_TRACE=0 的情况下,跟踪功能也会严重降低性能,这不仅是因为控制台输出,还因为可能会阻止(内部)函数的内联,并且每次函数进入和退出时都会增加额外的调用开销。因此,也可以单独启用调试符号(make SYM=1;TRACE=1 或 DBG=1 会自动启用),这在对应用程序进行性能分析时可能会很有用。

验证

本节介绍如何使用 LIBXSMM 工具测试应用程序的正确性,特别是使用 libxsmm_matdifflibxsmm_matdiff_epsilon 函数。前者(libxsmm_matdiff)比较两个矩阵(也可以退化为向量形式),并返回一个结构体,其中包含关于两矩阵差异的信息(黄金结果与测试结果)。后者(libxsmm_matdiff_epsilon)结合了绝对范数和相对范数(由上述结构体给出),计算出一个标量“epsilon”,可用于与容差进行比较。

在应用程序中使用 libxsmm_matdiff_epsilon 时,会暴露一个名为 LIBXSMM_MATDIFF 的环境变量,该变量可以指定文件或目录路径(如果仅设置为 LIBXSMM_MATDIFF=1,则会使用默认文件名)。无论哪种情况,应用程序每次调用 libxsmm_matdiff_epsilon 时,都会向相应文件追加一行记录,内容包括 epsilon 值以及启动应用程序时使用的命令行。生成的文件可以进一步分析,例如运行 sort -gk1 libxsmm_matdiff.log | tail -n 10,即可得到发现的前十个最大 epsilon 值及其对应的命令行。

环境变量 LIBXSMM_MATDIFF 还可以携带可选的空格分隔参数,用于补充每个文件条目的信息,例如 export LIBXSMM_MATDIFF="libxsmm_matdiff.log hello world"。在复杂情况下,这可用于补充仅在运行时才知道的值,比如用于判断 epsilon 的实际容差(通过 putenv 设置)。

性能

对于使用 LIBXSMM JIT 代码的应用程序,性能剖析得到了很好的支持。该库支持 Intel VTune AmplifierLinux perf。文中详细介绍了如何集成性能剖析工具以及如何运行应用程序。

在编译时,有多种选项可以对 LIBXSMM 进行定制。该库针对广泛的使用场景进行了配置,其中包括针对典型用途的高级默认设置。

为了查找应用程序或性能复现工具的性能结果,仓库提供了一个名为 “results”的孤立分支,用于收集相关材料,如实测的性能结果及说明性图表。这些结果可以在 https://github.com/libxsmm/libxsmm/tree/results#libxsmm-results 找到,也可以按如下方式克隆:

git clone --branch results \
  https://github.com/libxsmm/libxsmm.git \
  libxsmm-results

请注意,比较性能结果时,需要考虑矩阵乘法的运算对象是否被流式加载。例如,在所有矩阵都位于 L1 缓存的情况下进行乘法运算,可能会更倾向于某种实现方式,而这种实现方式在实际工作负载中表现可能较差(如果实际工作负载需要从主内存中流式加载部分或全部矩阵)。大多数 代码示例 都旨在重现性能结果,建议尽可能模拟实际情况,或参考真实的 应用程序

高性能计算(HPC)

[1] https://cp2k.org/:开源分子动力学软件CP2K及其配套的DBCSR库,该库用于处理大量小矩阵乘法的批处理运算。这些批处理数据来源于一个分布式块稀疏矩阵,其中包含针对特定问题的小型矩阵。自CP2K 3.0版本起,LIBXSMM可替代CP2K中的libsmm库。

[2] https://github.com/SeisSol/SeisSol/:SeisSol是用于地震场景模拟、特别是动态破裂过程模拟的领先代码之一。LIBXSMM提供了高度优化的汇编内核,构成了SeisSol的核心计算基础(详见https://github.com/TUM-I5/seissol_kernels/)。

[3] https://github.com/NekBox/NekBox:NekBox是一款高度可扩展且跨平台的谱元法代码,其灵感源自Nek5000。NekBox专为盒状几何问题设计,旨在快速原型化新方法,并充分利用超越FORTRAN 77标准的FORTRAN特性。LIBXSMM可用于替代Nek5000 NekBox中的MXM_STD代码。此外,请参阅LIBXSMM提供的NekBox重现示例

[4] https://github.com/Nek5000/Nek5000:Nek5000是由https://nek5000.mcs.anl.gov/开发的开源、高度可扩展且始终可移植的谱元法代码。Nek5000的开发分支已集成LIBXSMM。

[5] https://www.pyfr.org/:PyFR是一个基于Python的开源框架,采用通量重构方法在流式架构上求解对流-扩散类问题。PyFR将LIBXSMM作为OpenMP后端的矩阵乘法提供者。

[6] http://dial3343.org/about/:极端规模间断伽辽金环境(EDGE)是一种用于求解双曲型偏微分方程的求解器,尤其适用于地震模拟。EDGE的源代码可以选择性地依赖LIBXSMM,但为了获得高性能,强烈建议使用LIBXSMM的内核。

[7] https://sxs-collaboration.github.io/spectre/:SpECTRE是一款开源代码,用于天体物理和引力物理中的多尺度、多物理场问题,可在Petascale级别运行,并专为Exascale计算机设计。未来,SpECTRE可能被应用于流体力学、地球科学、等离子体物理、核物理以及工程学等跨学科领域的问题。

[8] https://ceed.exascaleproject.org/ceed-code/:高效Exascale离散化中心(CEED)依托Nek5000、MFEM、MAGMA、OCCA和PETSc等项目的成果,开发应用程序接口(API),涵盖高层和底层两个层面,以使应用能够充分利用高阶方法。CEED的底层API——libCEED——将LIBXSMM用作后端,从而在CPU上实现高性能。

[9] https://github.com/romeric/Fastor:Fastor是一个轻量级的高性能张量代数框架,适用于现代C++,并可选择将LIBXSMM作为JIT后端

机器学习与深度学习(AI)

[10] https://github.com/plaidml/plaidml:PlaidML是一个开源张量编译器,旨在实现跨多种CPU、GPU及其他加速器的高性能可移植性。结合Intel的nGraph编译器,PlaidML主要面向PyTorch、Keras(TensorFlow)和OpenVino等流行的深度学习框架。PlaidML/v1(开发分支)采用了正在行业范围内广泛普及的可扩展编译基础设施——MLIR。PlaidML/v1开始使用LIBXSMM作为面向CPU的后端。

[11] https://github.com/intel/intel-extension-for-pytorch:英特尔PyTorch扩展旨在通过优异的性能,为用户在CPU上使用PyTorch提供流畅的体验。该扩展包开始依赖LIBXSMM以实现CPU上的高性能

[12] https://github.com/libxsmm/tpp-pytorch-extension:英特尔(R) PyTorch张量处理原语扩展是一个开源软件库,将张量处理原语(TPP)集成到PyTorch中。它旨在通过优异的性能,为用户在CPU上使用PyTorch提供流畅的体验。英特尔提交的MLPerf训练基准代码正是利用了该项目(详见https://github.com/mlcommons/training_results.1/tree/main/Intel/benchmarks/bert/implementations/pytorch-cpu)。

[13] https://github.com/libxsmm/libxsmm-dnn:LIBXSMM-DNN是一个开源软件库,展示了如何利用张量处理原语(TPP)来实现各种深度学习原语,如卷积、线性层,甚至池化和归一化操作。由于采用了TPP技术,无需编写任何平台相关的代码。

自动驾驶(AD)

[15] https://software.seek.intel.com/accelerating-eigen-math-library:加速Eigen数学库以应对自动驾驶工作负载:卡尔曼滤波对速度的需求。发表于《Parallel Universe》杂志第31期(pdf)的文章。

参考文献

[1] https://sc19.supercomputing.org/proceedings/tech_poster/tech_poster_pages/rpost244.html:通过单一构建模块实现高性能深度学习(海报摘要),SC’19:国际高性能计算、网络、存储与分析大会,丹佛(科罗拉多州)。

[2] https://dl.acm.org/doi/10.1109/SC.2018.00069:SIMD架构上高性能深度学习卷积的剖析(论文)。SC'18:国际高性能计算、网络、存储与分析大会,达拉斯(德克萨斯州)。

[3] https://pasc17.pasc-conference.org/fileadmin/user_upload/pasc17/program/post116s2.pdf:DBCSR:用于电子结构代码的稀疏矩阵乘法库(海报),PASC’17:PASC17大会,卢加诺(瑞士)。

[4] https://sc17.supercomputing.org/SC17%20Archive/tech_poster/tech_poster_pages/post190.html:理解英特尔架构上CNN小型卷积运算的性能(海报摘要),SC’17:国际高性能计算、网络、存储与分析大会,丹佛(科罗拉多州)。

[5] https://www.computer.org/csdl/proceedings-article/sc/2016/8815a981/12OmNCeaQ1D:LIBXSMM:通过运行时代码生成加速小型矩阵乘法。SC'16:国际高性能计算、网络、存储与分析大会,盐湖城(犹他州)。

[6] http://sc15.supercomputing.org/sites/all/themes/SC15images/tech_poster/tech_poster_pages/post137.html:LIBXSMM:一个用于小型矩阵乘法的高性能库(海报摘要)。SC'15:国际高性能计算、网络、存储与分析大会,奥斯汀(德克萨斯州)。

[7] 《张量处理原语:面向深度学习与HPC工作loads的高效性和可移植性编程抽象》(arXiv预印本)。SC'21:国际高性能计算、网络、存储与分析大会,圣路易斯。

文章

[1] https://www.nextplatform.com/2019/10/09/cloudy-supercomputers-join-the-hpc-petascale-club/:云端超级计算机加入HPC拍字节级俱乐部。罗布·法伯撰写的文章,2019年。文章在单独一节中介绍了LIBXSMM。

[2] https://www.nextplatform.com/2019/06/26/counting-the-cost-of-scaling-hpc-applications/:计算HPC应用扩展的成本。蒂莫西·普里克特·摩根撰写的文章,2019年。本文主要讨论CP2K开源分子动力学软件,而非LIBXSMM。然而,LIBXSMM对应用性能起到了关键作用。

[3] https://www.nextplatform.com/2019/06/26/counting-the-cost-of-scaling-hpc-applications/:Azure HC系列在两万个核心上进行HPC基准测试。约翰·拉塞尔撰写的文章,2019年。本文同样聚焦于CP2K开源分子动力学软件,而非LIBXSMM。不过,LIBXSMM对应用性能至关重要。

[4] https://software.intel.com/sites/default/files/parallel-universe-issue-34.pdf:LIBXSMM:英特尔硬件与软件开发的开源灵感来源(PDF文件)。汉斯·帕布斯特、格雷格·亨利和亚历山大·海内克合著的文章,2018年。

[5] https://medium.com/@rmfarber/libxsmm-brings-deep-learning-lessons-learned-to-many-hpc-applications-9143c6c93125:LIBXSMM将深度学习的经验教训应用于众多HPC应用。罗布·法伯撰写的文章,2018年。

[6] https://www.rdworldonline.com/largest-supercomputer-simulation-of-sumatra-andaman-earthquake/:苏门答腊—安达曼地震的最大规模超级计算机模拟。琳达·巴尼撰写的文章,2018年。

版本历史

1.172021/12/03
1.16.32021/10/14
1.16.22021/08/31
1.16.12020/06/26
1.162020/06/20
1.152020/03/13
1.142019/10/25
1.132019/07/15
1.12.12019/05/23
1.122019/05/10
1.112019/04/29
1.102018/11/12
1.92018/03/15
1.8.32018/02/02
1.8.22017/12/24
1.8.12017/05/12
1.82017/03/30
1.7.12017/01/27
1.72017/01/26
1.6.62017/01/19

常见问题

相似工具推荐

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|今天
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

140.4k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

107.7k|★★☆☆☆|2天前
开发框架图像Agent

NextChat

NextChat 是一款轻量且极速的 AI 助手,旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性,以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发,NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。 这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言,它也提供了便捷的自托管方案,支持一键部署到 Vercel 或 Zeabur 等平台。 NextChat 的核心亮点在于其广泛的模型兼容性,原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型,让用户在一个界面即可自由切换不同 AI 能力。此外,它还率先支持 MCP(Model Context Protocol)协议,增强了上下文处理能力。针对企业用户,NextChat 提供专业版解决方案,具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能,满足公司对数据隐私和个性化管理的高标准要求。

87.6k|★★☆☆☆|昨天
开发框架语言模型

ML-For-Beginners

ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程,旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周,包含 26 节精炼课程和 52 道配套测验,内容涵盖从基础概念到实际应用的完整流程,有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。 无论是希望转型的开发者、需要补充算法背景的研究人员,还是对人工智能充满好奇的普通爱好者,都能从中受益。课程不仅提供了清晰的理论讲解,还强调动手实践,让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持,通过自动化机制提供了包括简体中文在内的 50 多种语言版本,极大地降低了全球不同背景用户的学习门槛。此外,项目采用开源协作模式,社区活跃且内容持续更新,确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路,ML-For-Beginners 将是理想的起点。

85k|★★☆☆☆|今天
图像数据工具视频

ragflow

RAGFlow 是一款领先的开源检索增强生成(RAG)引擎,旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体(Agent)能力相结合,不仅支持从各类文档中高效提取知识,还能让模型基于这些知识进行逻辑推理和任务执行。 在大模型应用中,幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构(如表格、图表及混合排版),显著提升了信息检索的准确度,从而有效减少模型“胡编乱造”的现象,确保回答既有据可依又具备时效性。其内置的智能体机制更进一步,使系统不仅能回答问题,还能自主规划步骤解决复杂问题。 这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统,还是致力于探索大模型在垂直领域落地的创新者,都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口,既降低了非算法背景用户的上手门槛,也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目,它正成为连接通用大模型与行业专有知识之间的重要桥梁。

77.1k|★★★☆☆|2天前
Agent图像开发框架