Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atomics detection is broken #141

Closed
barracuda156 opened this issue Dec 30, 2023 · 10 comments
Closed

atomics detection is broken #141

barracuda156 opened this issue Dec 30, 2023 · 10 comments

Comments

@barracuda156
Copy link

--->  Configuring primesieve
Executing:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_primesieve/primesieve/work/build" && /opt/local/bin/cmake -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=MacPorts -DCMAKE_INSTALL_PREFIX="/opt/local" -DCMAKE_INSTALL_NAME_DIR="/opt/local/lib" -DCMAKE_SYSTEM_PREFIX_PATH="/opt/local;/usr" -DCMAKE_C_COMPILER="$CC" -DCMAKE_CXX_COMPILER="$CXX" -DCMAKE_OBJC_COMPILER="$CC" -DCMAKE_OBJCXX_COMPILER="$CXX" -DCMAKE_POLICY_DEFAULT_CMP0025=NEW -DCMAKE_POLICY_DEFAULT_CMP0060=NEW -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_COLOR_MAKEFILE=ON -DCMAKE_FIND_FRAMEWORK=LAST -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_MAKE_PROGRAM=/usr/bin/make -DCMAKE_MODULE_PATH="/opt/local/share/cmake/Modules" -DCMAKE_PREFIX_PATH="/opt/local/share/cmake/Modules" -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=OFF -DCMAKE_INSTALL_RPATH="/opt/local/lib" -Wno-dev -DBUILD_TESTS=ON -DCMAKE_OSX_ARCHITECTURES="ppc" -DCMAKE_OSX_DEPLOYMENT_TARGET="10.6" -DCMAKE_OSX_SYSROOT="/" /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_primesieve/primesieve/work/primesieve-11.1 
-- The CXX compiler identification is GNU 13.2.0
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/local/bin/g++-mp-13 - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test atomic64
-- Performing Test atomic64 - Failed
-- Performing Test atomic32
-- Performing Test atomic32 - Success
CMake Error at cmake/libatomic.cmake:40 (message):
  Failed to find libatomic!
Call Stack (most recent call first):
  CMakeLists.txt:96 (include)


-- Configuring incomplete, errors occurred!

This is GCC, so obviously libatomic is there. The check is not looking for it at all however:

Performing C++ SOURCE FILE Test atomic64 failed with the following output:
Change Dir: /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_primesieve/primesieve/work/build/CMakeFiles/CMakeTmp

Run Build Command(s):/usr/bin/make -f Makefile cmTC_041cb/fast && /usr/bin/make  -f CMakeFiles/cmTC_041cb.dir/build.make CMakeFiles/cmTC_041cb.dir/build
Building CXX object CMakeFiles/cmTC_041cb.dir/src.cxx.o
/opt/local/bin/g++-mp-13 -Datomic64  -pipe -Os -DNDEBUG -I/opt/local/include -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++11 -arch ppc -mmacosx-version-min=10.6 -o CMakeFiles/cmTC_041cb.dir/src.cxx.o -c /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_primesieve/primesieve/work/build/CMakeFiles/CMakeTmp/src.cxx
Linking CXX executable cmTC_041cb
/opt/local/bin/cmake -E cmake_link_script CMakeFiles/cmTC_041cb.dir/link.txt --verbose=1
/opt/local/bin/g++-mp-13 -pipe -Os -DNDEBUG -I/opt/local/include -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++11 -arch ppc -mmacosx-version-min=10.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/opt/local/lib -Wl,-headerpad_max_install_names  CMakeFiles/cmTC_041cb.dir/src.cxx.o -o cmTC_041cb 
Undefined symbols:
  "___atomic_store_8", referenced from:
      _main in src.cxx.o
  "___atomic_fetch_sub_8", referenced from:
      _main in src.cxx.o
  "___atomic_load_8", referenced from:
      _main in src.cxx.o
ld: symbol(s) not found
collect2: error: ld returned 1 exit status
make[1]: *** [cmTC_041cb] Error 1
make: *** [cmTC_041cb/fast] Error 2


Source file was:

    #include <atomic>
    #include <stdint.h>
    int main() {
        std::atomic<int64_t> x;
        x = 1;
        x--;
        return (int) x;
    }

Of course it will not work without passing -latomic flag.

@barracuda156
Copy link
Author

Once -latomic flag is added, everything works and all tests pass:

--->  Testing primesieve
Executing:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_primesieve/primesieve/work/build" && ctest 
Test project /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_math_primesieve/primesieve/work/build
      Start  1: calculator
 1/32 Test  #1: calculator .......................   Passed    0.01 sec
      Start  2: clear_primesieve_iterator1
 2/32 Test  #2: clear_primesieve_iterator1 .......   Passed    0.02 sec
      Start  3: clear_primesieve_iterator2
 3/32 Test  #3: clear_primesieve_iterator2 .......   Passed    0.01 sec
      Start  4: count_primes1
 4/32 Test  #4: count_primes1 ....................   Passed    0.81 sec
      Start  5: count_primes2
 5/32 Test  #5: count_primes2 ....................   Passed    7.45 sec
      Start  6: count_primes3
 6/32 Test  #6: count_primes3 ....................   Passed    6.34 sec
      Start  7: count_quadruplets
 7/32 Test  #7: count_quadruplets ................   Passed    0.41 sec
      Start  8: count_quintuplets
 8/32 Test  #8: count_quintuplets ................   Passed    0.41 sec
      Start  9: count_sextuplets
 9/32 Test  #9: count_sextuplets .................   Passed    0.43 sec
      Start 10: count_triplets
10/32 Test #10: count_triplets ...................   Passed    0.41 sec
      Start 11: count_twins
11/32 Test #11: count_twins ......................   Passed    0.39 sec
      Start 12: cpu_info
12/32 Test #12: cpu_info .........................   Passed    0.01 sec
      Start 13: floorPow2
13/32 Test #13: floorPow2 ........................   Passed    0.40 sec
      Start 14: generate_n_primes1
14/32 Test #14: generate_n_primes1 ...............   Passed   25.03 sec
      Start 15: generate_n_primes2
15/32 Test #15: generate_n_primes2 ...............   Passed    0.63 sec
      Start 16: generate_primes1
16/32 Test #16: generate_primes1 .................   Passed    0.21 sec
      Start 17: generate_primes2
17/32 Test #17: generate_primes2 .................   Passed   25.05 sec
      Start 18: ilog2
18/32 Test #18: ilog2 ............................   Passed    0.39 sec
      Start 19: isqrt
19/32 Test #19: isqrt ............................   Passed    0.39 sec
      Start 20: isqrt_constexpr
20/32 Test #20: isqrt_constexpr ..................   Passed    0.01 sec
      Start 21: move_primesieve_iterator
21/32 Test #21: move_primesieve_iterator .........   Passed    3.53 sec
      Start 22: next_prime1
22/32 Test #22: next_prime1 ......................   Passed    2.12 sec
      Start 23: next_prime2
23/32 Test #23: next_prime2 ......................   Passed   27.30 sec
      Start 24: nth_prime1
24/32 Test #24: nth_prime1 .......................   Passed    2.29 sec
      Start 25: nth_prime2
25/32 Test #25: nth_prime2 .......................   Passed    0.04 sec
      Start 26: nth_prime3
26/32 Test #26: nth_prime3 .......................   Passed    1.33 sec
      Start 27: number_of_bits
27/32 Test #27: number_of_bits ...................   Passed    0.01 sec
      Start 28: pod_vector
28/32 Test #28: pod_vector .......................   Passed    0.01 sec
      Start 29: prev_prime1
29/32 Test #29: prev_prime1 ......................   Passed   25.98 sec
      Start 30: prev_prime2
30/32 Test #30: prev_prime2 ......................   Passed    0.78 sec
      Start 31: skipto_next_prime
31/32 Test #31: skipto_next_prime ................   Passed   27.46 sec
      Start 32: skipto_prev_prime
32/32 Test #32: skipto_prev_prime ................   Passed    0.58 sec

100% tests passed, 0 tests failed out of 32

@kimwalisch
Copy link
Owner

The code below from CMakeLists.txt seems to be broken using the latest OSes, compilers, ...

find_library(ATOMIC NAMES atomic libatomic.so.1)

Ideally we would like to replace the code above and use a proper CMake module for libatomic. This did not exist a few years ago, but according to ChatGPT we could now potentially use:

# If atomic 64-bit code fails to compile then we
# need to add libatomic to the linker flags.
if(NOT atomic64)
    find_package(LibAtomic REQUIRED)
    set(LIBATOMIC ${LibAtomic_LIBRARIES})
    message(STATUS "Found libatomic: ${LIBATOMIC}")
endif()

instead of:

if(NOT atomic64)
    find_library(ATOMIC NAMES atomic libatomic.so.1)

    if(ATOMIC)
        set(LIBATOMIC ${ATOMIC})
        message(STATUS "Found libatomic: ${LIBATOMIC}")
    else()
        check_cxx_source_compiles("
            #include <atomic>
            #include <stdint.h>
            int main() {
                std::atomic<int32_t> x;
                x = 1;
                x--;
                return (int) x;
            }"
            atomic32)

        if(atomic32)
            message(FATAL_ERROR "Failed to find libatomic!")
        endif()
    endif()
endif()

I have not tested this yet, if it works there is a high risk that it will only work on newer OSes.

@barracuda156
Copy link
Author

I am pretty sure extension should not be added to a library name in the check. Also on Mac is will be dylib.

@kimwalisch
Copy link
Owner

Another option that would likely fix the problem and work well on old OSes is:

if(NOT atomic64)
    find_library(ATOMIC NAMES atomic libatomic.so.1)

    if(ATOMIC)
        set(LIBATOMIC ${ATOMIC})
        message(STATUS "Found libatomic: ${LIBATOMIC}")
    else()
        # Try -latomic as a fallback if our code fails to detect libatomic
        set(LIBATOMIC atomic)
        message(STATUS "Found libatomic: ${LIBATOMIC}")
    endif()
endif()

@barracuda156
Copy link
Author

@kimwalisch Something like this should work: pghysels/STRUMPACK@be6d1f6

See also: https://github.com/grpc/grpc/pull/21341/files
potassco/clasp#95
Etc., this is a recurring issue.

P. S. I should open an issue with CMake upstream, this has to be really implemented with CMake to begin with.

@kimwalisch
Copy link
Owner

@barracuda156 Can you please let me know where libatomic is located on your PC and how it is named?

I have found another code snippet online that I think is superior to the solutions I have seen so far: https://github.com/agroal/pgagroal/blob/master/cmake/FindLibatomic.cmake#L6. It is similar to the code used in primesieve but it includes hints to a list of paths where libatomic cloud potentially be located if the compiler/linker cannot find it in the default path.

@kimwalisch
Copy link
Owner

@barracuda156 Could you please try if the following fix works on your PC? Add libatomic.1.dylib to this line:

find_library(ATOMIC NAMES atomic atomic.so.1 libatomic.so.1 libatomic.1.dylib)

instead of:

find_library(ATOMIC NAMES atomic libatomic.so.1)

In the cmake/libatomic.cmake file.

kimwalisch added a commit that referenced this issue Jan 2, 2024
@kimwalisch
Copy link
Owner

I was able to partially reproduce your issue on macOS 14.2 with homebrew GCC 13.2. I tried all of the potential solutions discussed in this thread, in the end the only solution that worked was adding -latomic to the linker options. So I have added this method as a fallback (https://github.com/kimwalisch/primesieve/blob/master/cmake/libatomic.cmake#L39) in case our other methods fail to find libatomic.

Could you please try if the latest code from the master branch works fine on your PC?

@barracuda156
Copy link
Author

@kimwalisch Sorry, it was a busy day, I am off the machine now. I can verify tomorrow, but passing -latomic must work, since that is exactly what we did to fix it in Macports locally: macports/macports-ports@16d0102

@kimwalisch
Copy link
Owner

Closing, I assume I have fixed this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants