Mac M1

I’ve had a brief look where we must go with the Mac M1. Its a great piece of hardware. SWI-Prolog runs fine on it and is remarkable fast. You have to build from source though, including builds using Macports or Homebrew. What I figured out is this:

  • There exist universal binaries. Those are just binaries that contain both versions and the OS will pick the right one.
  • There is a tool (lipo) that allows creating, examining and extracting specific architectures from a universal binary.
  • CMake seems to have a flag that does all the logic to create MacOS universal binaries. See c++ - macOS build universal binary 2 with CMake - Stack Overflow
  • We still need the dependencies. See scripts/ Most are configured using GNU autoconf.
  • GCC produces almost twice as fast executables than Clang (the gap is rather extreme in SWI-Prolog’s case, but that is what we want to compile).
  • GCC cannot produce M1 binaries yet (announced for GCC-12?)

Anyone with experience and suggestions how to start properly supporting the M1 (while keep supporting Intel Macs)?

My M1 macbook pro Monterey now won’t build SWI-Prolog-8.5.3 from source.
I am little knowledge to fix this kind of problem, especially about cmake and ninja, it seems difficult for me to fix this. I have just started to learn about them to ask experts like you for help in the near future.

M1 mac seems faster than intel mac, which is my first impression, though from a tiny experience. For example, the M1 MacBook Pro solves a problem related on ZDD in just 20 seconds, while an intel imac 3.8 GHz 8-Core Intel Core i7 of mine takes more than 30 seconds.

This is the error log of the build for just in case of easy fixing:

-- Configuring SWI-Prolog-8.5.3
-- Using Homebrew packages from /opt/homebrew
CMake Error at cmake/port/Darwin.cmake:75 (latest_subdir):
  latest_subdir Function invoked with incorrect arguments for function named:
Call Stack (most recent call first):
  cmake/Ports.cmake:2 (include)
  CMakeLists.txt:78 (include)

-- Could NOT find LibTCMalloc (missing: LIBTCMALLOC_LIBRARY) 
-- Could NOT find LibTCMalloc (missing: LIBTCMALLOC_LIBRARY) 
To activate the Python tests: python3 -mpip install protobuf
-- Could NOT find ODBC (missing: ODBC_INCLUDE_DIR) 
-- Optional package Berkeley DB was not found
-- Could NOT find Qt5Widgets (missing: Qt5Widgets_DIR)
-- Configuring incomplete, errors occurred!
See also "/Users/cantor/src/swipl-devel/build/CMakeFiles/CMakeOutput.log".
See also "/Users/cantor/src/swipl-devel/build/CMakeFiles/CMakeError.log".
ninja: error: loading '': No such file or directory
ninja install
ninja: error: loading '': No such file or directory

Thanks. Pushed a fix.

Thanks the quick fix.

M1 mac

% ?- time(test(rect(7,7), C)).
%@ % 412,054,447 inferences, 23.996 CPU in 24.076 seconds (100% CPU, 17171863 Lips)
%@ C = 789360053252.

intel Mac.

% ?- time(test(rect(7,7), C)).
%@ % 412,054,447 inferences, 32.459 CPU in 32.623 seconds (99% CPU, 12694420 Lips)
%@ C = 789360053252.

I am curious about customized build SWI for my M1 mac. I am using Xcode, but
I would like to find other way to use an appropriate version of gcc for example, though it may be more difficult for me than writing codes on ZDD.

Thanks again.

It seems we need to wait for GCC-12. Using it is fairly easy: just install using Homebrew or Macports and run (assuming gcc-12 is called gcc-12):

CC=gcc-12 cmake [options] ..

If gcc-12 keeps the speed advantage over Clang for SWI-Prolog on the M1 this would produce a pretty fast version of Prolog :slight_smile: I have the impression that GCC’s advantage is mostly related to dealing with large functions with a difficult control flow. That level of analysis is pretty unrelated to the target CPU. Of course, the quality of the final code generation also counts.

I see. Anyway I would like to try gcc-12 following your guide.

% brew info gcc
gcc: stable 11.2.0 (bottled), HEAD

BTW, as my zdd library has reached to a stage of functionality for my initial goal, now I would like to find a way to improve codes on handling the hash table. My ZDD library is just a simple library for handling simple hash tables as you know well using just functor/setarg/arg/term_hash for manipulating families of sets, I really think so.