The use of -march=native by default is not a good idea: https://github.com/cosmo-epfl/librascal/blob/1ae879cc1b1b970fc691cdba9b80cd3fcf4fadee/CMakeLists.txt#L94-L100
It can corrupt memory when using librascal as an external project. For example, compiling and running examples/spherical_invariants_example.cc externally with
clang++ -std=c++14 -O3 spherical_invariants_example.cc -o spherical_invariants_example -I../src -I/usr/local/include/eigen3 -I../build/external/wigxjpf/inc ../build/src/librascal.a ../build/external/wigxjpf/lib/libwigxjpf.a
./spherical_invariants_example ../reference_data/inputs/molecular_crystal.json
Results in
spherical_invariants_example(79937,0x1146bc5c0) malloc: *** error for object 0x7ff1ba702200: pointer being freed was not allocated
spherical_invariants_example(79937,0x1146bc5c0) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort ./spherical_invariants_example ../reference_data/inputs/molecular_crystal.jso
Adding -march=native to the above command line fixes the issue and everything works.
The origin of the problem is that some code in librascal.a/librascal.so contains code assuming one instruction set but the main binary assumes a separate instruction set. Different instructions set can have different ABI, and this results in caller/calle code not agreeing on where arguments should be passed. This is partially exacerbated by the fact that librascal is mostly a header library, meaning the end user will compile most of the code themselves, meaning they MUST match the exact compiler flags used to build librascal.
Use of -march=native by default can also be a problem on some HPC cluster, where the head and compute nodes use different instruction sets (e.g. Broadwell vs Haswell for Intel), leading to binaries that run on the head node and crash on the compute nodes.
Overall, I think we should remove this default of -march=native, and evaluate the performance difference from doing so. If there is a large performance difference, then we can add suggestions in the documentation that people use if when building librascal & their own code.
The use of
-march=nativeby default is not a good idea: https://github.com/cosmo-epfl/librascal/blob/1ae879cc1b1b970fc691cdba9b80cd3fcf4fadee/CMakeLists.txt#L94-L100It can corrupt memory when using librascal as an external project. For example, compiling and running
examples/spherical_invariants_example.ccexternally withResults in
Adding
-march=nativeto the above command line fixes the issue and everything works.The origin of the problem is that some code in librascal.a/librascal.so contains code assuming one instruction set but the main binary assumes a separate instruction set. Different instructions set can have different ABI, and this results in caller/calle code not agreeing on where arguments should be passed. This is partially exacerbated by the fact that librascal is mostly a header library, meaning the end user will compile most of the code themselves, meaning they MUST match the exact compiler flags used to build librascal.
Use of
-march=nativeby default can also be a problem on some HPC cluster, where the head and compute nodes use different instruction sets (e.g. Broadwell vs Haswell for Intel), leading to binaries that run on the head node and crash on the compute nodes.Overall, I think we should remove this default of
-march=native, and evaluate the performance difference from doing so. If there is a large performance difference, then we can add suggestions in the documentation that people use if when building librascal & their own code.