ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Tullio.jl与Einsum.jl对比:为什么它是更强大的索引符号工具?

Tullio.jl与Einsum.jl对比:为什么它是更强大的索引符号工具? Tullio.jl与Einsum.jl对比为什么它是更强大的索引符号工具【免费下载链接】Tullio.jl⅀项目地址: https://gitcode.com/gh_mirrors/tu/Tullio.jl在 Julia 科学计算生态中索引符号index notation是描述张量运算最优雅的方式而Tullio.jl正是这一领域最灵活的 einsum 宏。它不仅能完成与 Einsum.jl 相同的矩阵乘法、转置与维度置换还能处理卷积、模板计算、散点聚合与广播等更复杂的运算。本文将从语法能力、自动求导与性能基准三个维度全面对比 Tullio.jl 与 Einsum.jl帮助你判断谁才是更适合日常使用的索引符号工具。同源而生两者都把公式写成索引符号Einsum.jl 的核心思想是把爱因斯坦求和约定直接翻译成嵌套的 for 循环Tullio.jl 的思路与其一脉相承——它本身就是一个超级 einsum 宏。作者在 README.md 中直言Tullio.jl 几乎是 Einsum.jl 的超集两者最典型的用法几乎一模一样# Einsum.jl 的写法 einsum C[i,j] : A[i,k] * B[k,j] # Tullio.jl 的写法 tullio C[i,j] : A[i,k] * B[k,j]差异从宏展开那一刻开始显现Einsum.jl 生成朴素的 for 循环性能完全依赖编译器而 Tullio.jl 生成的代码会借助多线程Threads.spawn与递归分块recursive tiling来调度在加载 LoopVectorization 相关加速包后还会自动向量化。同样是索引符号底层执行效率天差地别。解析能力对比Tullio 能读懂更复杂的表达式Einsum.jl 擅长标准的指标求和表达式而 Tullio.jl 的表达式解析器核心逻辑见 src/macro.jl支持的类型要多得多运算类型Einsum.jlTullio.jl矩阵乘法、点积✅✅维度置换、广播✅✅移位索引A[ij-1]、A[i_]❌✅卷积、模板计算❌✅mod/clamp/pad边界处理❌✅自定义归约(max)、(*)、min1❌✅管道运算符log | exp(...)❌✅举两个 Einsum.jl 写不出来的例子——卷积和下采样# 卷积自动推断移位后的索引范围 tullio C[i] : A[ij] * K[j] # K 是 OffsetArray 滤波器 # 下采样索引范围取两个表达式的交集 tullio B[i] : (A[2i] A[2i1]) / 2自动索引范围推断是 Tullio.jl 的另一大亮点当索引带有移位时它会自动从参与运算的数组axes中推断出结果数组的形状与范围甚至能算出i ∈ 3:19这样的精确区间你完全不需要手动指定边界。性能基准矩阵乘法的真实差距矩阵乘法是衡量 einsum 类工具性能的试金石。项目在 benchmarks/02/ 中提供了与 OpenBLAS、MKL、PaddedMatrices 的基准对比图以下是 Float64 精度下的结果从图中可以看到在大矩阵10³量级下Tullio.jl 与 Intel MKL 的差距缩小到约 1.5 倍优于 PaddedMatrices与 OpenBLAS 基本持平。对于用索引符号写出的张量运算这已经是非常亮眼的成绩——毕竟你换来的是极高的表达自由度。Float32 精度下的表现类似见 matmul-0.2.11-Float32-1.6.0-dev.png。转置与置换Tullio 的隐藏强项常规的矩阵乘法有 BLAS 库加持Tullio.jl 的优势反而体现在不规则张量操作上——比如转置、多维置换这类需要大量内存搬运的运算。基准图清晰地展示了这一点在转置任务中Tullio.jl红色点线在绝大多数矩阵尺寸下耗时最低显著优于 base 函数与 einsum。四维置换4321 排列的结果同样如此为什么因为 Tullio.jl 采用递归分块 多线程的访问策略能更好地利用 CPU 缓存局部性而普通的permutedims往往是一次性的大块搬运。这意味着当你需要写permutedims(B, (3,2,1))再做批处理矩阵乘法时Tullio.jl 可以直接用索引符号一步完成既省去显式置换速度还更快。不止矩阵乘法卷积、模板与散点Tullio.jl 真正的定位不是替代 BLAS而是让任意索引符号表达式都能快速运行。它在广播归约、卷积等场景同样表现抢眼例如tullio s : X[i,j] * log(Y[j,i])这类先广播再归约的运算Tullio.jl 通过分块内存访问避免了中间大数组的分配比sum(X .* log.(transpose(X)))快一个数量级详细数据见 README.md 的 Fast Slow 一节。自动求导与 GPUeinsum 没有的杀手锏这是 Tullio.jl 与 Einsum.jl 拉开代差的地方自动求导默认对右端表达式做符号求导基于 DiffRules也可用gradDual切换到 ForwardDiff为 Tracker、Zygote、ChainRules 等自动微分框架提供梯度GPU 加速配合 KernelAbstractions 与 CUDA同一段索引符号代码可以自动生成 GPU 内核实现 CPU/GPU 无缝切换见 ext/TullioCUDAExt.jl细粒度开关threads、avx、grad、nograd、cuda等关键字可灵活控制每一项能力。换句话说用索引符号写一次公式就能同时拿到CPU 多线程版、SIMD 向量化版、GPU 版和自动求导版四种实现。无缝迁移Tullio.einsum 直接替换对现有使用 Einsum.jl 的代码Tullio.jl 提供了近乎零成本的迁移路径——using Tullio: einsum即可在旧名称下使用新宏且自动关闭了线程、向量化与求导以保持行为一致。Tullio.jl 的测试套件中甚至直接跑通了 Einsum.jl 的全部测试用例见 test/einsum.jl保证兼容性。总结新手与进阶用户该如何选择只需简单点积/矩阵乘法且追求与 BLAS 完全一致的行为Einsum.jl 足够轻量需要卷积、移位、自定义归约、自动求导或 GPU直接选 Tullio.jl正在用 Einsum.jl 但遇到性能瓶颈试试using Tullio: einsum一行代码切换。Tullio.jl 用事实证明索引符号不仅是一种优雅的数学表达更可以成为高性能计算的原生语言。如果你也想让张量公式怎么写就怎么快Tullio.jl 值得一试。【免费下载链接】Tullio.jl⅀项目地址: https://gitcode.com/gh_mirrors/tu/Tullio.jl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表