anderkve / FYS3150

https://anderkve.github.io/FYS3150
26 stars 14 forks source link

Cannot find omp.h header #83

Closed multiib closed 1 year ago

multiib commented 1 year ago

Hello! I am running macOS (x86-64) and my program is not able to find omp.h. I am using the Apple clang compiler.

This is what i have tried to run: g++ main.cpp src/state.cpp -Xpreprocessor -fopenmp -std=c++11 -I include/ -lomp -larmadillo -o main.exe

I have also tried linking and compiling in separate stages.

In file included from main.cpp:2:
/usr/local/include/armadillo:95:15: warning: WARNING: use of OpenMP disabled; omp.h header not found [-W#pragma-messages]
      #pragma message ("WARNING: use of OpenMP disabled; omp.h header not found")
              ^
main.cpp:3:10: fatal error: 'omp.h' file not found
#include <omp.h> // OpenMP
         ^~~~~~~
1 warning and 1 error generated.
In file included from src/state.cpp:1:
In file included from include/state.hpp:4:
/usr/local/include/armadillo:95:15: warning: WARNING: use of OpenMP disabled; omp.h header not found [-W#pragma-messages]
      #pragma message ("WARNING: use of OpenMP disabled; omp.h header not found")

Any tips?

anderkve commented 1 year ago

Hi @multiib!

I think on for some versions of MacOS / XCode / brew there's a mixup with which path brew is installing libomp to and which paths clang is searching by default to find header files. So you probably just need to figure out where brew installed libomp and add the correct include path in your compilation command, see e.g. here: https://stackoverflow.com/questions/25990296/how-to-include-omp-h-in-os-x

I'm not using a Mac, but I think @davidshope came across this problem for some others students during a lab session. So he might be able to help if the link above doesn't help.

dshope11 commented 1 year ago

Hi @multiib,

If there's a mismatch between where brew is installing libomp and where clang is searching for it, then there are a couple of ways to fix this.

The first is along the lines of what @anderkve mentions above - that it's possible to point clang to the location where libomp was installed by brew. Keep in mind that the installation of libomp consists of both header files (under include/) and library files (under lib/). If you successfully point clang to the headers and not also the libraries for example, then I believe that the compilation will still fail during the linking step (although it won't complain anymore about not finding omp.h). To see where brew is installing libomp, you can run the command brew list libomp. On my M1 Mac, for example, this shows:

/opt/homebrew/Cellar/libomp/15.0.3/include/ (3 files)
/opt/homebrew/Cellar/libomp/15.0.3/lib/libomp.dylib
/opt/homebrew/Cellar/libomp/15.0.3/lib/libomp.a

A second way of fixing this issue would be to just copy these libomp files into whichever directory is being searched for by clang when compiling. If armadillo is working, then one location to copy to would be wherever the files for armadillo are located.

I'd consider the first solution to be slightly better, only because this would also still work by default if you ever had to install a newer version of libomp - otherwise, you'd have to remember to again copy the updates over to the "clang-discoverable" directory. Nevertheless, if you're only able to get things working with the second method, then that's of course better than nothing - and should get you through the remainder of this course ;)

In general, it's also good practice to read through the log messages by homebrew as it's installing a package (particularly at the end) - since it will often give helpful hints as to any additional steps that may be necessary in order to e.g. use the package for compilation. The brew reinstall command can also be helpful here as well.

multiib commented 1 year ago

Both armadillo and libomp is in the same directory. I have tried all the suggested steps, but nothing seems to solve it. I am runnng macOS Ventura 13.0.

Paths:

/usr/local/Cellar/libomp/15.0.4/include/omp.h
/usr/local/Cellar/armadillo/11.4.0/include/armadillo
anderkve commented 1 year ago

Hmm, so you still get 'omp.h' not found even if you specifically point clang to a folder where it is? That's very strange. Can you add the option --verbose to your compilation command and paste the full terminal output you get (or attach it as a text file)? Please also include the full compilation command. I'll take a quick look to see if I can spot something fishy.

multiib commented 1 year ago

Alright:) Here is two commands I have tried. I have also used -I and -L to directly add g++ -c *.cpp -Xpreprocessor -fopenmp --verbose mac1.txt

g++ main.cpp src/state.cpp -std=c++11 -Xpreprocessor -fopenmp -I include/ -larmadillo -o main.exe -lomp -verbose mac2.txt

This seem to sort of work, but then my "state.hpp" won't be included. g++ -c *.cpp -Xpreprocessor -fopenmp -std=c++11 -I /usr/local/Cellar/libomp/15.0.4/include -L /usr/local/Cellar/libomp/15.0.4/lib --verbose mac3.txt

anderkve commented 1 year ago

You can add as many include paths (the -I option) as needed, so you can do both -I include to find state.hpp and -I /usr/local/Cellar/libomp/15.0.4/include to find omp.h. So try this:

g++ main.cpp src/state.cpp -Xpreprocessor -fopenmp -std=c++11 -I include -I /usr/local/Cellar/libomp/15.0.4/include -L /usr/local/Cellar/libomp/15.0.4/lib
multiib commented 1 year ago

@anderkve @dshope11

Thank you both for excellent help! Everything is working as it should now.

The command that finally compiled: g++ main.cpp src/state.cpp -Xpreprocessor -fopenmp -std=c++11 -I include -I /usr/local/Cellar/libomp/15.0.4/include -L /usr/local/Cellar/libomp/15.0.4/lib -larmadillo -lomp -o main.exe