Trivial Eigen3 Тензорная программа не строится без -On - PullRequest
1 голос
/ 03 марта 2020

Я пытаюсь создать запись программного обеспечения с модулем Tensor, который не поддерживается eigen3. Я написал простой фрагмент кода, который будет собираться с помощью простого приложения VectorXd (просто печатая его на стандартный вывод), а также будет собираться с использованием аналогичного приложения Tensor вместо VectorXd, но НЕ БУДЕТ собираться, когда я этого не сделаю бросить флаг оптимизации (-On). Обратите внимание, что моя сборка происходит из среды conda, которая использует компиляторы conda-forge, поэтому далее g ++ - это g ++, полученный из conda forge для ubuntu. Он говорит свое имя в следующих сообщениях об ошибках, если это воспринимается как проблема.

У меня такое ощущение, что дело не в программе, которую я пытаюсь написать, а на всякий случай, я включил 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, код создает и выдает ожидаемый результат.

1 Ответ

2 голосов
/ 03 марта 2020

Технически, это ошибка компоновщика (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 вам нужно связать с -lrt, если ваша версия glib c старше 2.17 - возможно, это так для вашей настройки:

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