evaleev / libint

Libint: high-performance library for computing Gaussian integrals in quantum mechanics
Other
226 stars 95 forks source link

HF++ wrong integrals when using Intel19 compilers #118

Closed ajaypanyala closed 5 years ago

ajaypanyala commented 5 years ago

The libint version I am using is 2.5.0-beta.2 (pre-gen lib) built with "-xHost -O3" flags

icpc version 19.0.1.144 (gcc version 8.2.0 compatibility)

Compile as follows: icpc -std=c++17 -o hf_icc hartree-fock++.cc -I/opt/libint/include -L/opt/libint/lib -lint2 -I/opt/libint/include/eigen3 -lpthread

Run: ./hf_icc h2o.xyz sto-3g

The run finishes in 3 iterations and the energies are wrong. Debugging it a little and comparing with gcc build, I noticed the problem was in this line:

auto V = compute_1body_ints<libint2::Operator::nuclear>(shells, libint2::make_point_charges(atoms))[0];

The V produced has completely different values. However if I compile without -std=c++17, it runs fine and produces the right numbers.

evaleev commented 5 years ago

Intel C++ 2019 compiler seems to not load the definition of FmEval_Chebyshev7<double>::cheb_table correctly when -std=c++17 flag is used .. the table is there but it's filled with zeroes. The only fix (other than fixing the compiler ... howdy @jeffhammond ) is to disable constexpr statics via -DLIBINT2_CONSTEXPR_STATICS=0 compiler flag (or, better, specifying it via CPPFLAGS when configuring). Note that in the global scope of one of your .cpp files (e.g. the one containing main()) you need to include the following code

#if !LIBINT2_CONSTEXPR_STATICS
#  include <libint2/statics_definition.h>
#endif

I'll drop 2.5.0 soon

jeffhammond commented 5 years ago

What’s the most terse shell commands to reproduce this?

I’ll file a bug ASAP.

evaleev commented 5 years ago

I filed a ticket with Intel support. Here's the minimal example:

#include <cassert>

template <typename T> class A {
  public:
    static constexpr T data[2][2] = {{1, 2}, {3, 4}};
};

int main() {
  assert(A<double>::data[0][0] == 1);
}

The assert fails with icpc (the data is full of zeroes), passes with gcc and clang. My interpretation of https://en.cppreference.com/w/cpp/language/static#Constant_static_members is that this code is valid, at least in c++17 (but it compiles and runs correctly with gcc and clang using c++11 and up).