Trivial Eigen3 Tensor程序在没有-On的情况下无法构建

问题描述 投票:1回答:1

我正在尝试使用eigen3不提供的Tensor模块来编写软件。我编写了一段简单的代码,将使用VectorXd的简单应用程序构建(只需将其打印到stdout),并且还将使用类似于Tensor的应用程序构建以替代VectorXd,但是当我不这样做时,将不会构建抛出一个优化标志(-On)。请注意,我的构建来自使用conda-forge编译器的conda环境中,因此下面的g ++是从conda forge for ubuntu获得的g ++。如果认为这是问题所在,它将在随后的错误消息中说出其名称。

我感觉这与我要编写的程序无关,但以防万一我包含了一个似乎会产生错误的mwe.cpp。代码如下:

#include <eigen3/Eigen/Dense>
#include <eigen3/unsupported/Eigen/CXX11/Tensor>
#include <iostream>

using namespace Eigen;
using namespace std;

int main(int argc, char const *argv[])
{
    VectorXd v(6);
    v << 1, 2, 3, 4, 5, 6;
    cout << v.cwiseSqrt() << "\n";
    Tensor<double, 1> t(6);
    for (auto i=0; i<v.size(); i++){
        t(i) = v(i);
    }
    cout << "\n";
    for (auto i=0; i<t.size(); i++){
        cout << t(i) << " ";
    }
    cout << "\n";
    return 0;
}

如果上面的代码未经任何优化就编译,例如:

g++ -I ~/miniconda3/envs/myenv/include/ mwe.cpp -o mwe

我收到以下编译器错误:

/home/myname/miniconda3/envs/myenv/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: /tmp/cc2q8gj4.o: in function `Eigen::internal::(anonymous namespace)::get_random_seed()':
mwe.cpp:(.text+0x15): undefined reference to `clock_gettime'
collect2: error: ld returned 1 exit status

如果相反,我要求'n'优化级别,如下所示:

g++ -I ~/miniconda3/envs/loos/include/ -On mwe.cpp -o mwe

该程序的构建没有任何抱怨,我得到了预期的输出:

$ ./mwe 
      1
1.41421
1.73205
      2
2.23607
2.44949

1 2 3 4 5 6 

我不知道为什么这个小程序或我尝试编写的真实程序会试图为任何东西获取随机种子。任何意见,将不胜感激。我想在不进行优化的情况下进行构建的原因是为了简化调试。我实际上以为所有这些都是由调试标志引起的,但是我意识到我的构建工具的调试设置并没有要求进行优化,而是将其缩小到明显的原因。如果抛出-g -O1,则看不到错误。

[显然,如果要注释掉所有与Tensor模块有关的代码,那么这一切都将在'return'上方和cwiseSqrt()行以及include语句的主代码中进行,并生成并生成预期的输出。

c++ compiler-optimization tensor eigen3
1个回答
0
投票

从技术上讲,这是一个链接器错误(g ++会同时调用编译器和链接器,具体取决于命令行参数)。如果从某个地方调用了外部定义的函数,即使从未到达代码,也会出现链接器错误。

当启用优化功能进行编译时,g ++将优化未调用的函数(在全局名称空间之外),因此不会出现链接器错误。您可能需要尝试使用-Og而不是-O1以获得更好的调试体验。

以下代码应产生类似的行为:

int foo(); // externally defined

namespace { // anonymous namespace
// defined inside this module, but never called
int bar() {
    return foo();
}
}

int main() {
    // if you un-comment this line, the
    // optimized version will fail as well:
    // ::bar();
}

根据man clock_gettime,如果您的glibc版本早于2.17,则需要与-lrt链接-也许是这种情况:

g++ -I ~/miniconda3/envs/myenv/include/ mwe.cpp -o mwe -lrt
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.