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/macos-deps.sh. 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:
  latest_subdir
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) 
-- Could NOT find LibUUID (missing: LIBUUID_INCLUDE_DIR UUID_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 LibYAML (missing: LIBYAML_INCLUDE_DIR YAML_LIBRARY) 
-- Could NOT find JNI (missing: JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH) 
-- 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
ninja: error: loading 'build.ninja': No such file or directory
ninja install
ninja: error: loading 'build.ninja': 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.

I just migrated to an M1 Mac and my ODBC connections stopped working. I tried both the old libraries copied over from an Intel Mac, hoping they would be universal, and installed new ones from several different sources. The symptoms are the same in all cases: I can make ODBC queries with isql but not from within SWI-Prolog.

?- odbc_connect('bioinformatics', Connection, []),  odbc_query(Connection, 'select workflow, run_id from __id_run where order_id = ''19qury''', Row).
ERROR: ODBC: State 01000: [unixODBC][Driver Manager]Can't open lib '/opt/homebrew/lib/mariadb/libmaodbc.dylib' : file not found
ERROR: In:
ERROR:   [11] odbc:odbc_connect(bioinformatics,_9372,[])
ERROR:   [10] '<meta-call>'('<garbage_collected>') <foreign>
ERROR:    [9] toplevel_call('<garbage_collected>') at /Applications/SWI-Prolog.app/Contents/swipl/boot/toplevel.pl:1117

I am not sure about the origin of the “file not found” message. If it is about the shared library, it is certainly found at that location and works without problems when called by sql.

It seems it can find and load odbc4pl.so as well as its dependency odbc.dylib. You can use otool -L odbc4pl.so to figure out which odbc.dylib it finds. The lipo tool is also useful for finding the archictectures for the various shared objects. This can be a nasty search :frowning: Looks like some issue with the architecture or incompatible ODBC components.

It was very easy in this case: odbc4pl is nowhere to be found. I did find packages-odbc in my archive without any trace of it having been built. It does not build now, missing PrologPackage.cmake. I tried building the whole thing but ran into access problems trying to clone it recursively:

fatal: clone of 'https://github.com/SWI-Prolog/packages-yaml.git' into submodule path '/Users/gene.selkov/src/swipl-devel/packages/yaml' failed
Failed to clone 'packages/yaml'. Retry scheduled
Cloning into '/Users/gene.selkov/src/swipl-devel/packages/zlib'...
kex_exchange_identification: Connection closed by remote host
Connection closed by 140.82.114.3 port 22

The same condition occurred while trying to clone all submodules.

At least that gets us somewhere. The packages can only be build as part of a complete system build, so that is ok. The fact that you cannot clone the repo is something else. Network issues? Broken git installation? You first need to get that right.

It still does not answer from where you got the initial SWI-Prolog installation. The binary bundle contains the ODBC interface and so thus the Macports version AFAIK. The Homebrew version is quite limited. I tried to remedy this once, but got stuck between their and SWI-Prolog’s policies.

Sorry, I made a false statement based on file index. My new Mac with the newest version of OS did not run the indexing job for many days; now that I forced it, it refuses to index application contents, so it is not good for making negative assertions. I was able to locate odbc4pl.so in my old mac’s file index and trusted the negative result I got from the new system.

So I installed the stable binary from SWI-Prolog downloads and it does contain all ODBC libraries. The question of which file is not found still stands.

otool -L /Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/odbc4pl.so
/Applications/SWI-Prolog.app/Contents/swipl/lib/x86_64-darwin/odbc4pl.so:
	@rpath/libodbc.2.dylib (compatibility version 3.0.0, current version 3.0.0)
	@rpath/libswipl.8.dylib (compatibility version 8.0.0, current version 8.4.1)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
	@rpath/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

lipo -info /Applications/SWI-Prolog.app/Contents/Frameworks/libodbc.2.dylib
Non-fat file: /Applications/SWI-Prolog.app/Contents/Frameworks/libodbc.2.dylib is architecture: x86_64

otool -L /opt/homebrew/lib/mariadb/libmaodbc.dylib
/opt/homebrew/lib/mariadb/libmaodbc.dylib:
	/opt/homebrew/opt/mariadb-connector-odbc/lib/mariadb/libmaodbc.dylib (compatibility version 0.0.0, current version 0.0.0)
	/opt/homebrew/opt/mariadb-connector-c/lib/mariadb/libmariadb.3.dylib (compatibility version 3.0.0, current version 3.0.0)
	/opt/homebrew/opt/unixodbc/lib/libodbcinst.2.dylib (compatibility version 3.0.0, current version 3.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)
	/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)

lipo -info /opt/homebrew/lib/mariadb/libmaodbc.dylib
Non-fat file: /opt/homebrew/lib/mariadb/libmaodbc.dylib is architecture: arm64

Is this the case of architecture mismatch?

I’m out of ideas for what’s wrong with GitHub. Do I need to join all of submodule repos as a member? I don’t have this problem with other random repos I have cloned.

It seems the devel binary does contain a fat libodbc.2.dylib. That might get you a step further.

Either

git clone https://github.com/SWI-Prolog/swipl-devel.git
cd swipl-devel
git submodule update --init

or

git clone --recursive https://github.com/SWI-Prolog/swipl-devel.git

should work just fine. If not, there are issues with your network, git installation, permissions, etc. It is really hard to give advice on those :frowning:

I’m making some progress. I was unable to locate the devel binary and tried building from sources again. I do not understand the problem of GitHub dropping connections while cloning submodules (only some of them); it may have something to do with port mappings on my computer conflicting with ssh over https or something; I avoided the issue by cloning the source on another computer and moving the whole tree.

The next problem was libarchive not listed as a dependency.

ninja: error: 'man/archive', needed by 'man/lib/prologpack.tex', missing and no known rule to make it

I already had libarchive installed by brew; installing it with macports fixed the issue.

The next problem (without a solution):

[1957/2464] Building C object src/CMakeFiles/swiplobjs.dir/pl-coverage.c.o
FAILED: src/CMakeFiles/swiplobjs.dir/pl-coverage.c.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc  -I/Users/gene.selkov/src/swipl-devel/build/src -I/Users/gene.selkov/src/swipl-devel/src -I/opt/local/include -O2 -g -DNDEBUG -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -mmacosx-version-min=12.0 -fPIC -fvisibility=hidden -Wall -std=gnu11 -MD -MT src/CMakeFiles/swiplobjs.dir/pl-coverage.c.o -MF src/CMakeFiles/swiplobjs.dir/pl-coverage.c.o.d -o src/CMakeFiles/swiplobjs.dir/pl-coverage.c.o -c /Users/gene.selkov/src/swipl-devel/src/pl-coverage.c
/Users/gene.selkov/src/swipl-devel/src/pl-coverage.c:176:7: error: expected expression
      ClauseRef cref = clause_clref(cov->cref);
      ^
/Users/gene.selkov/src/swipl-devel/src/pl-coverage.c:177:24: error: use of undeclared identifier 'cref'
      Clause    cl   = cref->value.clause;
                       ^
/Users/gene.selkov/src/swipl-devel/src/pl-coverage.c:179:12: error: use of undeclared identifier 'cref'; did you mean 'free'?
      if ( cref )
           ^~~~
           free
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/include/malloc/_malloc.h:42:7: note: 'free' declared here
void     free(void *);
         ^
3 errors generated.

I can’t find the definition of ClauseRef anywhere in the source tree

commit 160b25158edac3d97d593891876dda692c3dd201 (HEAD -> master, origin/master, origin/HEAD)
Author: Jan Wielemaker <J.Wielemaker@vu.nl>
Date:   Thu May 5 13:53:47 2022 +0200

    Updated plunit

Hey,
Your last issue seems to be the same as the one reported here Compile fails in pl-coverage.c with some compilers · Issue #988 · SWI-Prolog/swipl-devel · GitHub.
This is probably unrelated to your previous issues at it was only introduced very recently.

The attached patch should circumvent this problem
0001-FIX-Declaration-following-a-label-in-the-new-coverag.patch.pl (I added an extra .pl extension simply to please Discourse).
You can confirm that it works by downloading the patch and running:

$ cd /your/copy/of/swipl-devel
$ git apply ~/Downloads/0001-FIX-Declaration-following-a-label-in-the-new-coverag.patch.pl

And then run ninja again.

Cheers

The git repo compiles cleanly again on the M1 (at least, for me :slight_smile: )