NumPy and SciPy. Static vs Dynamic loading - numpy

TLDR: Can I use static ATLAS/LAPACK libraries with NumPy & SciPy?
Background:
After building ATLAS with LAPACK with the following:
wget http://sourceforge.net/projects/math-atlas/files/Stable/3.10.1/atlas3.10.1.tar.bz2/download
wget http://www.netlib.org/lapack/lapack-3.4.2.tgz
tar -jxvf atlas3.10.1.tar.bz2
mkdir BUILD
cd BUILD
../ATLAS/configure -b 64 -Fa alg -fPIC \
--with-netlib-lapack-tarfile=../lapack-3.4.2.tgz \
--prefix=<ATLAS_INSTALL_PATH>
make
cd lib
make shared
make ptshared
cd ..
make install
I got the following files under BUILD/lib:
Make.inc#
Makefile
.a files:
libatlas.a
libcblas.a
libf77blas.a
libptf77blas.a
libtstatlas.a
liblapack.a
libf77refblas.a
libptlapack.a
libptcblas.a
.so files:
libsatlas.so*
libtatlas.so*
My first question is, why don't I have .so (shared dynamic library) files for lapack and cblas?
My second question is, which of the following two files does NumPy use?
libsatlas.so*
libtatlas.so*
Finally, if I define:
BLAS=/path_to_BUILD/lib/libcblas.a
LAPACK=/path_to_BUILD/lib/liblapack.a
ATLAS=/path_to_BUILD/lib/libatlas.a
and add /path_to_BUILD/lib to LD_LIBRARY_PATH and to the library_dirs variable within the site.cfg file in NumPy. Would NumPy and SciPy use my libraries? (even though they are static?).

You should be able to. Add
[DEFAULT]
search_static_first = true
to your site.cfg file and you should be good to go.

Related

Could not load dynamic library 'libnvinfer.so.7'

I know that this question has been asked a lot, but none of the suggestions seem to work, probably since my setup is somewhat different:
Ubuntu 22.04
python 3.10.8
tensorflow 2.11.0
cudatoolkit 11.2.2
cudnn 8.1.0.77
nvidia-tensorrt 8.4.3.1
nvidia-pyindex 1.0.9
Having created a conda environment 'tf', in the directory home/dan/anaconda3/envs/tf/lib/python3.10/site-packages/tensorrt I have
libnvinfer_builder_resource.so.8.4.3
libnvinfer_plugin.so.8
libnvinfer.so.8
libnvonnxparser.so.8
libnvparsers.so.8
tensorrt.so
When running python3 -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))" I get
tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7';
dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory;
LD_LIBRARY_PATH: :/home/dan/anaconda3/envs/tf/lib
tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7';
dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory;
LD_LIBRARY_PATH: :/home/dan/anaconda3/envs/tf/lib
tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
I'm guessing I should downgrade nvidia-tensorrt, but nothing I've tried seems to work, any advice would be much appreciated.
Solution: follow the steps listed here https://github.com/tensorflow/tensorflow/issues/57679#issuecomment-1249197802.
Add the following to ~/.bashrc (for the conda envs as described in my scenario):
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dan/anaconda3/lib/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dan/anaconda3/lib/python3.8/site-packages/tensorrt/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dan/anaconda3/envs/tf/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/dan/anaconda3/envs/tf/lib/python3.8/site-packages/tensorrt/
For me the setting a symbolic link from libnvinfer version 7 to 8 worked:
# the follwoing path will be different for you - depending on your install method
$ cd env/lib/python3.10/site-packages/tensorrt
# create symbolic links
$ ln -s libnvinfer_plugin.so.8 libnvinfer_plugin.so.7
$ ln -s linvinfer.so.8 libnvinfer.so.7
# add tensorrt to library path
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/env/lib/python3.10/site-packages/tensorrt/

Setting up on Macbook Pro M1 Tenserflow with OpenCV, Scipy, Scikit-learn

I think I read pretty much most of the guides on setting up tensorflow, tensorflow-hub, object detection on Mac M1 on BigSur v11.6. I managed to figure out most of the errors after more than 2 weeks. But I am stuck at OpenCV setup. I tried to compile it from source but seems like it can't find the modules from its core package so constantly can't make the file after the successful cmake build. It fails at different stages, crying for different libraries, despite they are there but max reached 31% after multiple cmake and deletion of the build folder or the cmake cash file. So I am not sure what to do in order to make successfully the file.
I git cloned and unzipped the opencv-4.5.0 and opencv_contrib-4.5.0 in my miniforge3 directory. Then I created a folder "build" in my opencv-4.5.0 folder and the cmake command I use in it is (my miniforge conda environment is called silicon and made sure I am using arch arm64 in bash environment):
cmake -DCMAKE_SYSTEM_PROCESSOR=arm64 -DCMAKE_OSX_ARCHITECTURES=arm64 -DWITH_OPENJPEG=OFF -DWITH_IPP=OFF -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=/Users/adi/miniforge3/opencv_contrib-4.5.0/modules -D PYTHON3_EXECUTABLE=/Users/adi/miniforge3/envs/silicon/bin/python3.8 -D BUILD_opencv_python2=OFF -D BUILD_opencv_python3=ON -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=OFF -D OPENCV_ENABLE_NONFREE=ON -D BUILD_EXAMPLES=ON /Users/adi/miniforge3/opencv-4.5.0
So it cries like:
[ 20%] Linking CXX shared library ../../lib/libopencv_core.dylib
[ 20%] Built target opencv_core
make: *** [all] Error 2
or also like in another tries was initially asking for calib3d or dnn but those libraries are there in the main folder opencv-4.5.0.
The other way I try to install openCV is with conda:
conda install opencv
But then when I test with
python -c "import cv2; cv2.__version__"
it seems like it searches for the ffmepg via homebrew (I didn't install any of these via homebrew but with conda). So it complained:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/adi/miniforge3/envs/silicon/lib/python3.8/site-packages/cv2/__init__.py", line 5, in <module>
from .cv2 import *
ImportError: dlopen(/Users/adi/miniforge3/envs/silicon/lib/python3.8/site-packages/cv2/cv2.cpython-38-darwin.so, 2): Library not loaded: /opt/homebrew/opt/ffmpeg/lib/libavcodec.58.dylib
Referenced from: /Users/adi/miniforge3/envs/silicon/lib/python3.8/site-packages/cv2/cv2.cpython-38-darwin.so
Reason: image not found
Though I have these libs, so when I searched with: find /usr/ -name 'libavcodec.58.dylib' I could find many locations:
find: /usr//sbin/authserver: Permission denied
find: /usr//local/mysql-8.0.22-macos10.15-x86_64/keyring: Permission denied
find: /usr//local/mysql-8.0.22-macos10.15-x86_64/data: Permission denied
find: /usr//local/hw_mp_userdata/Internet_Manager/OnlineUpdate: Permission denied
/usr//local/lib/libavcodec.58.dylib
/usr//local/Cellar/ffmpeg/4.4_2/lib/libavcodec.58.dylib
(silicon) MacBook-Pro:opencv-4.5.0 adi$ ln -s /usr/local/Cellar/ffmpeg/4.4_2/lib/libavcodec.58.dylib /opt/homebrew/opt/ffmpeg/lib/libavcodec.58.dylib
ln: /opt/homebrew/opt/ffmpeg/lib/libavcodec.58.dylib: No such file or directory
One of the guides said to install homebrew also in arm64 env, so I did it with:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
alias ibrew='arch -x86_64 /usr/local/bin/brew' # create brew for intel (ibrew) and arm/ silicon
Not sure if that is affecting it but seems like it didn't do anything because still uses /opt/homebrew/ instead of /usr/local/.
So any help would be highly appreciated if I can make any of the ways work. Ultimately I want to use Tenserflow Model Zoo Object Detection models. So all the other dependencies seems fine (for now) besides either OpenCV not working or if it is working with conda install then it seems that scipy and scikit-learn don't work.
In my case I also had lot of trouble trying to install both modules. I finally managed to do so but to be honest not really sure how and why. I leave below the requirements in case you might want to recreate the environment that worked in my case. You should have the conda Miniforge 3 installed :
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: osx-arm64
absl-py=1.0.0=pypi_0
astunparse=1.6.3=pypi_0
autocfg=0.0.8=pypi_0
blas=2.113=openblas
blas-devel=3.9.0=13_osxarm64_openblas
boto3=1.22.10=pypi_0
botocore=1.25.10=pypi_0
c-ares=1.18.1=h1a28f6b_0
ca-certificates=2022.2.1=hca03da5_0
cachetools=5.0.0=pypi_0
certifi=2021.10.8=py39hca03da5_2
charset-normalizer=2.0.12=pypi_0
cycler=0.11.0=pypi_0
expat=2.4.4=hc377ac9_0
flatbuffers=2.0=pypi_0
fonttools=4.31.1=pypi_0
gast=0.5.3=pypi_0
gluoncv=0.10.5=pypi_0
google-auth=2.6.0=pypi_0
google-auth-oauthlib=0.4.6=pypi_0
google-pasta=0.2.0=pypi_0
grpcio=1.42.0=py39h95c9599_0
h5py=3.6.0=py39h7fe8675_0
hdf5=1.12.1=h5aa262f_1
idna=3.3=pypi_0
importlib-metadata=4.11.3=pypi_0
jmespath=1.0.0=pypi_0
keras=2.8.0=pypi_0
keras-preprocessing=1.1.2=pypi_0
kiwisolver=1.4.0=pypi_0
krb5=1.19.2=h3b8d789_0
libblas=3.9.0=13_osxarm64_openblas
libcblas=3.9.0=13_osxarm64_openblas
libclang=13.0.0=pypi_0
libcurl=7.80.0=hc6d1d07_0
libcxx=12.0.0=hf6beb65_1
libedit=3.1.20210910=h1a28f6b_0
libev=4.33=h1a28f6b_1
libffi=3.4.2=hc377ac9_2
libgfortran=5.0.0=11_1_0_h6a59814_26
libgfortran5=11.1.0=h6a59814_26
libiconv=1.16=h1a28f6b_1
liblapack=3.9.0=13_osxarm64_openblas
liblapacke=3.9.0=13_osxarm64_openblas
libnghttp2=1.46.0=h95c9599_0
libopenblas=0.3.18=openmp_h5dd58f0_0
libssh2=1.9.0=hf27765b_1
llvm-openmp=12.0.0=haf9daa7_1
markdown=3.3.6=pypi_0
matplotlib=3.5.1=pypi_0
mxnet=1.6.0=pypi_0
ncurses=6.3=h1a28f6b_2
numpy=1.21.2=py39hb38b75b_0
numpy-base=1.21.2=py39h6269429_0
oauthlib=3.2.0=pypi_0
openblas=0.3.18=openmp_h3b88efd_0
opencv-python=4.5.5.64=pypi_0
openssl=1.1.1m=h1a28f6b_0
opt-einsum=3.3.0=pypi_0
packaging=21.3=pypi_0
pandas=1.4.1=pypi_0
pillow=9.0.1=pypi_0
pip=22.0.4=pypi_0
portalocker=2.4.0=pypi_0
protobuf=3.19.4=pypi_0
pyasn1=0.4.8=pypi_0
pyasn1-modules=0.2.8=pypi_0
pydot=1.4.2=pypi_0
pyparsing=3.0.7=pypi_0
python=3.9.7=hc70090a_1
python-dateutil=2.8.2=pypi_0
python-graphviz=0.8.4=pypi_0
pytz=2022.1=pypi_0
pyyaml=6.0=pypi_0
readline=8.1.2=h1a28f6b_1
requests=2.27.1=pypi_0
requests-oauthlib=1.3.1=pypi_0
rsa=4.8=pypi_0
s3transfer=0.5.2=pypi_0
scipy=1.8.0=pypi_0
setuptools=58.0.4=py39hca03da5_1
six=1.16.0=pyhd3eb1b0_1
sqlite=3.38.0=h1058600_0
tensorboard=2.8.0=pypi_0
tensorboard-data-server=0.6.1=pypi_0
tensorboard-plugin-wit=1.8.1=pypi_0
tensorflow-deps=2.8.0=0
tensorflow-macos=2.8.0=pypi_0
termcolor=1.1.0=pypi_0
tf-estimator-nightly=2.8.0.dev2021122109=pypi_0
tk=8.6.11=hb8d0fd4_0
tqdm=4.63.1=pypi_0
typing-extensions=4.1.1=pypi_0
tzdata=2021e=hda174b7_0
urllib3=1.26.9=pypi_0
werkzeug=2.0.3=pypi_0
wheel=0.37.1=pyhd3eb1b0_0
wrapt=1.14.0=pypi_0
xz=5.2.5=h1a28f6b_0
yacs=0.1.8=pypi_0
zipp=3.7.0=pypi_0
zlib=1.2.11=h5a0b063_4

Configure cmake to work with homebrew libraries instead system-provided libraries

I find myself going against the grain configuring cmake paths with ccmake over and over again as with every change of for ex. compiler some of my library paths get lost.
In particular paths to (unlinked) lapack, lapacke, gsl get either lost or set to system defaults instead the ones I've installed with brew.
There has to be a way to tell cmake to "ignore" system libraries and instead look in homebrew paths (say. /opt/homebrew/lib, /opt/homebrew/include etc.).
I'd prefer not to link those libraries as this is not recommend and I'm not experienced in switching environments.
[EDIT] MRE:
git clone https://gitlab.physik.uni-muenchen.de/AG-Scrinzi/tRecX.git
cd tRecX
cmake . -DCMAKE_BUILD_TYPE=Parallel
make -j 8
I add the following to .bash_profile/.zshrc:
export LDFLAGS="-L/opt/homebrew/opt/lapack/lib -L/opt/homebrew/opt/lapack/lib"
export CPPFLAGS="-I/opt/homebrew/opt/lapack/include -I/opt/homebrew/opt/openblas/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/lapack/lib/pkgconfig /opt/homebrew/opt/openblas/lib/pkgconfig"
then I try:
cmake . -DCMAKE_PREFIX_PATH=/opt/homebrew -DCMAKE_FIND_FRAMEWORK=NEVER -DCMAKE_FIND_APPBUNDLE=NEVER -DCMAKE_FIND_USE_CMAKE_SYSTEM_PATH=FALSE -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=FALSE -DMPI_CXX_COMPILER=/opt/homebrew/bin/mpicxx -DMPI_C_COMPILER=/opt/homebrew/bin/mpicc -DCMAKE_CXX_COMPILER=/opt/homebrew/bin/g++-11 -DCMAKE_C_COMPILER=/opt/homebrew/bin/gcc-11
The most common solution is to just set CMAKE_PREFIX_PATH to /opt/homebrew. CMake will then look preferentially in /opt/homebrew for everything. Since you're on Apple, you might need to set CMAKE_FIND_FRAMEWORK and CMAKE_FIND_APPBUNDLE to LAST or NEVER, too.
You can skip the standard platform search paths by setting CMAKE_FIND_USE_CMAKE_SYSTEM_PATH to FALSE at the command line, in a preset, or in a toolchain file. You might also wish to disable looking at the PATH environment variable by setting CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH to FALSE.
Finally, if you're in a cross-compiling scenario or toolchain file, you can change the definition of the system directories by setting CMAKE_SYSROOT. Note that the sysroot will have to contain the language runtime libraries (e.g. glibc) and will be passed to the --sysroot flag (or equivalent). Just be aware of those effects, too.
All of this is documented here:
https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_FRAMEWORK.html#variable:CMAKE_FIND_FRAMEWORK
https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_APPBUNDLE.html#variable:CMAKE_FIND_APPBUNDLE
The following homebrew.cmake toolchain file worked for me:
set(HOMEBREW_PREFIX "/usr/local"
CACHE PATH "Path to Homebrew installation")
set(CMAKE_C_COMPILER "${HOMEBREW_PREFIX}/bin/gcc-11")
set(CMAKE_CXX_COMPILER "${HOMEBREW_PREFIX}/bin/g++-11")
set(CMAKE_PREFIX_PATH
"${HOMEBREW_PREFIX}"
# These libraries are keg-only and not loaded into
# the root prefix by default (to avoid clashes).
"${HOMEBREW_PREFIX}/opt/lapack"
"${HOMEBREW_PREFIX}/opt/openblas"
"${HOMEBREW_PREFIX}/opt/gcc/lib/gcc/11"
)
list(TRANSFORM CMAKE_PREFIX_PATH APPEND "/include"
OUTPUT_VARIABLE CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES}")
set(CMAKE_FIND_FRAMEWORK NEVER)
set(CMAKE_FIND_APPBUNDLE NEVER)
set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH FALSE)
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH FALSE)
I built with the following commands:
$ ls
tRecX homebrew.cmake
$ cmake -G Ninja -S tRecX -B tRecX-build \
-DCMAKE_TOOLCHAIN_FILE=$PWD/homebrew.cmake \
-DCBLAS=/usr/local/opt/openblas/lib/libblas.dylib \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
-DCMAKE_BUILD_TYPE=Parallel
[ ... output clipped ... ]
Boost found -- full functionality
Build "Parallel" with C++ flags -D_USE_BOOST_ -O3 -pthread -D_USE_FFTW_, return to default by -UCMAKE_BUILD_TYPE
Compiler: /usr/local/bin/g++-11, change by -DCMAKE_CXX_COMPILER=[path_to_complier]
-- Linking to libraries Boost::system;Boost::filesystem;/usr/local/lib/libfftw3.dylib;/usr/local/opt/gcc/lib/gcc/11/libgfortran.dylib;alglib;/usr/local/lib/libarpack.dylib;Boost::system;Boost::filesystem;/usr/local/opt/lapack/lib/liblapacke.dylib;/usr/local/opt/openblas/lib/libblas.dylib;/usr/local/opt/lapack/lib/liblapack.dylib;/usr/local/opt/lapack/lib/libblas.dylib;m
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/alexreinking/Development/tRecX-build
$ cmake --build tRecX-build
I had to set CBLAS manually because libblas.dylib provides the OpenBLAS CBLAS interface, but the build system specifically looks for a library named libcblas. There's no other option in this case.
The code and build have issues with its linking model and dependencies. I was able to paper over these by setting -Wl,-undefined,dynamic_lookup. However, note that this will just defer linker errors to runtime and might impose a large startup cost.
If you can make commits to the project, I would store these settings in a preset, maybe name it homebrew-parallel or something:
-DCMAKE_TOOLCHAIN_FILE=$PWD/homebrew.cmake \
-DCBLAS=/usr/local/opt/openblas/lib/libblas.dylib \
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
-DCMAKE_BUILD_TYPE=Parallel
Then you could just run cmake --preset=homebrew-parallel

How to include the .so of custom ops in the pip wheel and organize the sources of custom ops?

Following the documentation, I put my_op.cc and my_op.cu.cc under tensorflow/core/user_ops, and created tensorflow/core/user_ops/BUILD which contains
load("//tensorflow:tensorflow.bzl", "tf_custom_op_library")
tf_custom_op_library(
name = "my_op.so",
srcs = ["my_op.cc"],
gpu_srcs = ["my_op.cu.cc"],
)
Then I run the following commands under the root of tensorflow:
bazel build -c opt //tensorflow/core/user_ops:all
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
After building and installing the pip wheel, I want to use my_op in the project my_project.
I think I should create something like my_project/tf_op/__init__.py and my_project/tf_op/my_op.py, which calls tf.load_op_library like the example cuda_op.py. However, the my_op.so is not included in the installed pip wheel. How can I generate the input (the path of my_op.so) for tf.load_op_library?
Is there any better way to organized my_op.cc, my_op.cu.cc, my_op.py with my_project?
You can preserve directory structure of your project and create setup.py such that it also include .so files. You can also add other non-python files of your project same way.
Example Directory Structure:
my_package
my_project
__init__.py
setup.py
You can install 'my_project' package while in my_package directory using command:
pip install . --user (Avoid --user argument if you install packages with root access)
from setuptools import setup, find_packages
setup(name='my_project',
version='1.0',
description='Project Details',
packages=find_packages(),
include_package_data=True,
package_data = {
'': ['*.so', '*.txt', '*.csv'],
},
zip_safe=False)
Don't forget to add __init__.py in all folders containing python modules you want to import.
Reference: https://docs.python.org/2/distutils/setupscript.html#installing-package-data

Set multiple paths to CMAKE_Fortran_MODULE_DIRECTORY

So I am trying to include an installed Fortran library to a CMake project. I know the directory where the module (.mod) file is located, but my project can't seem to find it unless I set CMAKE_Fortran_MODULE_DIRECTORY.
SET(LIB_INCLUDE_DIR /usr/local/include)
SET(EX_FILES main.f90 file1.f90 file2.f90)
INCLUDE_DIRECTORIES(${LIB_INCLUDE_DIR})
ADD_EXECUTABLE(test ${EX_FILES})
TARGET_LINK_LIBRARIES(test lib1)
Where the error is
use lib1
1
Fatal Error: Can't open module file 'lib1.mod' for reading at (1): No such file or directory
unless I include the line
SET(CMAKE_Fortran_MODULE_DIRECTORY ${LIB_INCLUDE_DIR})
And then it can find the file just fine. But I'm running into a little problem. By setting CMAKE_Fortran_MODULE_DIRECTORY, CMake tries to write all generated modules to this directory rather than the CMAKE_BINARY_DIR (where I would like it).
From the documentation, I know that CMAKE_Fortan_MODULE_DIRECTORY is meant to be set to specify where to write generated module files, but some compilers look to that directory to find modules. Is there any way to set multiple directories so that if it can't find in/write to one directory, it searches the second? When I try to set CMAKE_Fortran_MODULE_DIRECTORY to be multiple directories, it only looks at the first directory.
If it helps I am on a Ubuntu 14.04 LTS system using gfortran 4.8.4
EDIT:
So by Alexander Vogt's suggestion I ran with VERBOSE=1 and got
cd /home/user/Repos/build/src && gfortran -I/home/user/Repos/build/src -isystem /usr/local/include -c /home/user/Repos/test_project/src/main.f90 -o CMakeFiles/test.dir/main.f90.o
when I did NOT set CMAKE_Fortran_MODULE_DIRECTORY and
cd /home/user/Repos/build/src && gfortran -J/usr/local/include -I/home/user/Repos/build/src -isystem /usr/local/include -c /home/user/Repos/test_project/src/main.f90 -o CMakeFiles/test.dir/main.f90.o
when I did.
It seems the only difference is the -J flag, which sets exactly what CMAKE_Fortran_MODULE_DIRECTORY sets. Is there some flag that sets just where to look for compiled modules, and not where to put them?