Gismo库中求值函数异常——内存多重释放

问题描述

今天在使用Gismo库时遇到这样一个情况
以下这段代码是参照gismo库的example写的几个求值函数eval,eval_into,evalSingle_into,active_into的测试

#include <gismo.h>
using namespace gismo;

int main()
{
    gsKnotVector<> uKnotVector(0.0, 1.0, 0, 4);
    gsKnotVector<> vKnotVector(0.0, 1.0, 0, 4);
    
    gsTensorBSplineBasis<2, real_t> bsplineBasis(uKnotVector, uKnotVector);
    gsMatrix<real_t> pointMatrix(2, 1);
    pointMatrix(0, 0) = 0.1;
    pointMatrix(1, 0) = 0.2;
    
    gsMatrix<index_t> activeMatrix;
    gsMatrix<real_t> valueMatrix;
    gsMatrix<real_t> valueResult;

    valueMatrix = bsplineBasis.eval(pointMatrix);
    bsplineBasis.evalSingle_into(0, pointMatrix, valueResult);
    gsInfo << "valueResult: \n" << valueResult << std::endl;
    bsplineBasis.active_into(pointMatrix, activeMatrix);
    gsInfo << "activeMatrix: \n" << activeMatrix << std::endl;
    bsplineBasis.eval_into(pointMatrix, valueMatrix);
    gsInfo << "valueMatrix: \n" << valueMatrix << std::endl;
    return 0;
}

然而这段代码虽然能正常通过编译,但在实际运行时会在输出完结果后意外终止掉。
转移到Linux系统中测试后,发现在输出完结果后抛出异常:

double free or corruption (out)
Aborted (core dumped)

猜测是由于重复释放同一块空间导致

解决方案

查阅官方issue发现可以通过添加指令集来解决
在Linux系统下,可以通过在CMakeLists.txt中添加:

set(CMAKE_CXX_FLAGS "-mavx ${CMAKE_CXX_FLAGS}")

set(CMAKE_CXX_FLAGS "-march=native ${CMAKE_CXX_FLAGS}")

亦或是直接给g++添加编译选项-mavx-march=native
在Windows系统下,由于MSVC不支持以上的编译选项,我们可以在CMakeLists.txt中添加:

set(CMAKE_CXX_FLAGS "/arch:AVX ${CMAKE_CXX_FLAGS}")

为了支持跨平台,可以统一添加如下代码:

include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-march=native" COMPILE_OPT_ARCH_NATIVE_SUPPORTED)
if(COMPILE_OPT_ARCH_NATIVE_SUPPORTED)
    set(CMAKE_CXX_FLAGS "-march=native ${CMAKE_CXX_FLAGS}")
else()
    check_cxx_compiler_flag("/arch:AVX" COMPILE_OPT_ARCH_AVX_SUPPORTED)
    if(COMPILE_OPT_ARCH_AVX_SUPPORTED)
        set(CMAKE_CXX_FLAGS "/arch:AVX ${CMAKE_CXX_FLAGS}")
    endif()
endif()

这段代码会优先检查-march=native是否可用并启用它,否则检查/arch:AVX是否可用并启用

如果是直接在VS中配置的,也可以在属性页->C/C++->代码生成->启用增强指令集中选择/arch:AVX

VS中启用指令集

参考官方issue #450, #374, #4698
跨平台参考 如何在 Windows 上使用 SSE 和 AVX 指令编译 Tensor Flow?