Gismo库中构造gsTHBSpline异常(Linux环境下)

问题描述

其实这个问题算是上一篇文章中所述问题的后续,在上一篇文章中,我们通过添加指令集解决了其中的问题,然而在Linux环境下进行后续测试过程中,在构造gsTHBSpline时再次出现了类似的问题(Windows下在参照上一篇文章处理后不会出现问题)。
测试代码如下:

#include <gismo.h>
using namespace gismo;

int main()
{
    gsKnotVector<> uKnotVector(0.0, 1.0, 0, 2);
    gsKnotVector<> vKnotVector(0.0, 1.0, 0, 2);
    
    gsTensorBSplineBasis<2, real_t> bsplineBasis(uKnotVector, uKnotVector);
    gsMatrix<real_t> pointMatrix(2, 1);
    pointMatrix(0, 0) = 0.1;
    pointMatrix(1, 0) = 0.2;
    
    gsMatrix<real_t> controlPoint(4, 2);
    for(int i = 0; i < 4; i++)
    {
        controlPoint(i, 0) = 1 + 0.1 * i;
        controlPoint(i, 1) = 1 - 0.1 * i;
    }
    gsTensorBSpline<2, real_t> bspline(bsplineBasis, controlPoint);
    gsTHBSpline<2, real_t> thbspline(bspline);
    
    gsInfo << "value: \n" << thbspline.eval(pointMatrix) << '\n';
    
    return 0;
}

编译运行后出现和之前类似的异常

double free or corruption (out)
Aborted

经过排查发现是构造gsTHBSpline那行代码导致。

解决方案

参考官方issue#374中的回复内容,我们找到可以在gismo库的构建路径中任意示例的flags.make文件,如/path/to/build/examples/CMakeFiles/parametrization_example.dir/flags.make,在我的例子中,有这样一行(不同环境下构建的可能有不同)

CXX_FLAGS =  -Wall -Wno-long-long -Wunused-variable -Wno-unknown-pragmas -march=skylake -mmmx -mavx -mavx2 -mfma -msse2 -msse3 -msse4.1 -msse4.2 -msse -mssse3 -madx -maes -mbmi2 -mf16c -mfsgsbase -mpclmul -mpopcnt -mprfchw -mrdrnd -mrdseed -mxsavec -mxsaves -mabm -mbmi -mclflushopt -mno-sse4a -mno-avxvnni -mno-avx5124fmaps -mno-avx5124vnniw -mno-avx512bf16 -mno-avx512bitalg -mno-avx512bw -mno-avx512cd -mno-avx512dq -mno-avx512er -mno-avx512f -mno-avx512ifma -mno-avx512pf -mno-avx512vbmi2 -mno-avx512vbmi -mno-avx512vl -mno-avx512vnni -mno-avx512vp2intersect -mno-avx512vpopcntdq -mno-amx-bf16 -mno-amx-int8 -mno-amx-tile -mno-enqcmd -mno-fxsr -mno-gfni -mno-hreset -mno-lzcnt -mno-movbe -mno-movdir64b -mno-movdiri -mno-mpx -mno-pconfig -mno-pku -mno-prefetchwt1 -mno-ptwrite -mno-rdpid -mno-rtm -mno-serialize -mno-sha -mno-tsxldtrk -mno-uintr -mno-vaes -mno-vpclmulqdq -mno-waitpkg -mno-wbnoinvd -mno-xsaveopt -mno-cldemote -mno-clwb -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -std=c++14

其实会发现构建路径中的所有flags.make文件中都会有这样相同的一行配置,这也解释了为什么把我们带异常的代码放到示例文件中去编译运行不会出问题。
于是我们将这些编译标志应用到我们的cmake项目中

set(CMAKE_CXX_FLAGS "-Wall -Wno-long-long -Wunused-variable -Wno-unknown-pragmas -march=skylake -mmmx -mavx -mavx2 -mfma -msse2 -msse3 -msse4.1 -msse4.2 -msse -mssse3 -madx -maes -mbmi2 -mf16c -mfsgsbase -mpclmul -mpopcnt -mprfchw -mrdrnd -mrdseed -mxsavec -mxsaves -mabm -mbmi -mclflushopt -mno-sse4a -mno-avxvnni -mno-avx5124fmaps -mno-avx5124vnniw -mno-avx512bf16 -mno-avx512bitalg -mno-avx512bw -mno-avx512cd -mno-avx512dq -mno-avx512er -mno-avx512f -mno-avx512ifma -mno-avx512pf -mno-avx512vbmi2 -mno-avx512vbmi -mno-avx512vl -mno-avx512vnni -mno-avx512vp2intersect -mno-avx512vpopcntdq -mno-amx-bf16 -mno-amx-int8 -mno-amx-tile -mno-enqcmd -mno-fxsr -mno-gfni -mno-hreset -mno-lzcnt -mno-movbe -mno-movdir64b -mno-movdiri -mno-mpx -mno-pconfig -mno-pku -mno-prefetchwt1 -mno-ptwrite -mno-rdpid -mno-rtm -mno-serialize -mno-sha -mno-tsxldtrk -mno-uintr -mno-vaes -mno-vpclmulqdq -mno-waitpkg -mno-wbnoinvd -mno-xsaveopt -mno-cldemote -mno-clwb -O3 -DNDEBUG -fvisibility=hidden -fvisibility-inlines-hidden -std=c++14 ${CMAKE_CXX_FLAGS}")

重新构建项目发现不再出现问题。
至此问题得到解决,当然为了避免冗余,肯定可以删除其中某些不必要的标志,这里未作深究,可以进行尝试。

参考官方issue #374