期望 LAPACK 例程在两种不同的处理器架构上获得相同的结果是不是合理?

Posted

技术标签:

【中文标题】期望 LAPACK 例程在两种不同的处理器架构上获得相同的结果是不是合理?【英文标题】:Is it reasonable to expect identical results for LAPACK routines on two different processor architectures?期望 LAPACK 例程在两种不同的处理器架构上获得相同的结果是否合理? 【发布时间】:2021-09-09 15:05:59 【问题描述】:

我正在尝试使用 Apple Accelerate 库通过 LAPACK 反转 400x400 矩阵。我使用?getrf_?getri 创建了一个矩阵求逆方法。

void invert() 
    aligned_buffer<int> pivot(get_num_rows()*get_num_columns());
    int info = 0;
    int num_rows = get_num_rows();
    int num_columns = get_num_columns();

    if constexpr (std::is_same<T, float>::value) 
        sgetrf_(&num_rows, &num_columns, const_cast<T *> (get()),
                &num_rows, pivot.data(), &info);
     else 
        dgetrf_(&num_rows, &num_columns, const_cast<T *> (get()),
                &num_rows, pivot.data(), &info);
    
    assert((info == 0) && "Error factorizing matrix.");

    aligned_buffer<T> work(work_size);

    if constexpr (std::is_same<T, float>::value) 
        sgetri_(&num_rows, const_cast<T *> (get()), &num_rows,
                pivot.data(), work.data(), &work_size, &info);
     else 
        dgetri_(&num_rows, const_cast<T *> (get()), &num_rows,
                pivot.data(), work.data(), &work_size, &info);
    

    assert((info == 0) && "Error inverting matrix.");

但是,在两台不同的机器上运行代码时,我似乎得到了不同的结果。一台机器配备四核 Intel Core i7,另一台机器配备四核 Intel Core i5。当我比较倒置矩阵的结果时,除了第 49,50 97,98、148,149 197,198 行等之外,结果是相同的。差异很小但仍然存在。

对于使用相同的 LAPACK 库或不同的 lapack 库的两个不同的处理器架构,期望这些精度与此级别的精度相同是合理的吗?

【问题讨论】:

【参考方案1】:

一般来说,在不同的硬件上期望相同的位精确结果是不合理的。您正在执行数值不稳定的过程这一事实也可能导致任何差异的放大(如果可能,通常更喜欢使用因子求解而不是求逆)。

由于浮点运算的性质,运算顺序或精度的任何差异都可能导致不同的结果。 BLAS(它是大多数 LAPACK 的基础)通常主要是为了性能而编写的。这意味着对于不同的微架构,更不用说不同的架构,操作顺序可能不同(例如,在内核中容纳不同数量的 FMA 单元)。由于某些操作的循环剥离,数据对齐也会产生影响。 FMA 的可用性、向量长度和/或不同的内部精度也会产生影响。

即使在相同的硬件、相同的库、相同对齐的相同数据上,如果涉及线程,您可能仍然无法获得可再现性,除非库作者已竭尽全力保证这一点。

【讨论】:

以上是关于期望 LAPACK 例程在两种不同的处理器架构上获得相同的结果是不是合理?的主要内容,如果未能解决你的问题,请参考以下文章

将 C++ 与 BLAS 和 LAPACK 连接起来

在具有自动内存管理的编程环境中,OS内存分配例程在运行时调用的频率是多少?

使用 LAPACK 的 Fortran2003 中的动态内存分配错误

在Developerkit开发板上运行blink例程

大众运输+ RabbitMQ。在两种不同的消息类型之间共享一个队列

Pandas Dataframe:在两种完全不同的格式之间转换日期格式[重复]