While using the the blas no matter the framework accelerate or the openblas in the MacOS, it tells the Segmentation fault. How to fix this problem. The code is
MODULE BLAS_INTERFACE
IMPLICIT NONE
INTERFACE
FUNCTION ZDOTC(N, X, INCX, Y, INCY) RESULT(DOTC)
INTEGER, INTENT(IN) :: N
COMPLEX(8), INTENT(IN) :: X(*), Y(*)
INTEGER, INTENT(IN) :: INCX, INCY
COMPLEX(8) :: DOTC
END FUNCTION ZDOTC
END INTERFACE
END MODULE BLAS_INTERFACE
PROGRAM TEST_ZDOTC
USE BLAS_INTERFACE, ONLY: ZDOTC
IMPLICIT NONE
INTEGER, PARAMETER :: N = 3
COMPLEX(8) :: X(N), Y(N)
COMPLEX(8) :: dot_result
X = [ (1.0D0, 2.0D0), (3.0D0, 4.0D0), (5.0D0, 6.0D0) ]
Y = [ (2.0D0, 1.0D0), (4.0D0, 3.0D0), (6.0D0, 5.0D0) ]
dot_result = ZDOTC(N, X, 1, Y, 1)
PRINT *, dot_result
END PROGRAM TEST_ZDOTC
I think it is, but I was unaware of the problems with zdotc() and zdotu() when I posted the previous test/demo code. I was only aware of the problems with the single-to-double declaration errors. These double-to-double errors are new to me, and they are surprising because I would have thought they they would have been used much more frequently than the single precision routines.
It is correct that -ff2c does fix the problem using gfortran. This apparently corrupts the calling code to match the traditionally corrupt library code. This old f2c conversion error strikes again.
I’m not sure that ld looks at LDPATH. Look at the output from man ld, and that environment variable is not mentioned. Maybe there is some other symbol that is used?
I use several combinations of libraries and compilers, so I usually set search paths in makefiles rather than environment variables. That helps ensure that I keep things straight when I switch projects.
You need to tell the linker where it can find the OpenBLAS library.
Btw a good way to check which (dynamic) libraries have been linked on a Mac is with otool -L,
$ gfortran test_blas.f90 -framework Accelerate
$ otool -L a.out
a.out:
/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib (compatibility version 6.0.0, current version 6.0.0)
/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate (compatibility version 1.0.0, current version 4.0.0)
/opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)
Not that MacOS also has named BLAS and LAPACK librares (sub-components of Accelerate):
$ gfortran test_blas.f90 -lblas
$ otool -L a.out
a.out:
/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib (compatibility version 1.0.0, current version 1.0.0)
/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib (compatibility version 6.0.0, current version 6.0.0)
/opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)
This does work. However, LIBRARY_PATH is not mentioned anywhere in man ld either, so one would need to know to look elsewhere: Environment Variables (Using the GNU Compiler Collection (GCC))
Anyone know if there is local documentation (e.g. a man page) where this is discussed?
In my case, I just searched the net with related keywords and found those pages (GCC manual and Stackoverflow). But I usually do not use LIBRARY_PATH for my programs (indeed, I guess my compilation method is probably similar to yours mentioned above…). RE local documents, man gfortran and searching for the ENVIRONMENT section gives:
ENVIRONMENT
The gfortran compiler currently does not make use of
any environment variables to control its operation above and
beyond those that affect the operation of gcc.
and doing the same for gcc (with man gcc) gives:
ENVIRONMENT
...
LIBRARY_PATH
The value of LIBRARY_PATH is a colon-separated list
of directories, much like PATH. When configured as a native
compiler, GCC tries the directories thus specified when
searching for special linker files, if it cannot find them
using GCC_EXEC_PREFIX. Linking using GCC also
uses these directories when searching for ordinary libraries
for the -l option (but directories specified with -L come first).
(Probably the same sentences shown in the above online manual.)
I don’t think this comment applies to any of the questions in this thread, but I thought it might be mentioned that the MacOS ld behaves differently than the typical linux ld in several ways. I don’t know if this is because they are entirely different tools or if they are the same basic tool but with different build configurations. One difference I’ve noticed is that you never need to specify a library with the MacOS ld command more than once. It automatically searches the specified libraries repeatedly to satisfy any unresolved symbols. The linux ld command by contrast sometimes requires either that a library to be specified more than once or that it be listed within -( and -) symbols, which apparently duplicates the MacOS ld behavior.
Most of the utilities in macOS were inherited from BSD, whereas the ones used in linux come from GNU (that is, unless you’re Ubuntu and want to use the Rust-based equivalents instead, hehehe). So they tend to behave very differently.
I kind of prefer the GNU behavior (e.g., date), and homebrew lets you replace some of those (BSD) utilities with the GNU ones.
I think it’s because GNU’s ld only visits symbols tables once and in the listed order, which is fine only for shared libraries (but for static ones, you might need -Wl,--start-group/-Wl,--end-group).
(Since glibc is not intended for static linking, I think the GNU guys don’t really care that people prefer static libraries for performance and/or portability reasons)