Building SDPA for Python on macOS
SDPA for Python (sdpa-python
) is a wrapper on top of the SDPA package. We will go over building SDPA first, followed by SDPA for Python.
Obtaining and building the backend
As a backend, we can use either the regular SDPA package, or the SDPA Multiprecision variant. SDPA Multiprecision is a fork of SDPA-GMP.
If you choose to use SDPA Multiprecision, please follow the instructions in the README of its GitHub repository, and then skip directly to the next section on building the Python wrapper.
If you choose to use the regular SDPA package, we will download it from the official website. Currently, the latest version is 7.3.18.
Sourceforge download links involve redirects. If you are using wget
, it automatically redirects, however, if you are using curl
, you have to add -L
flag to enable redirects:
curl -L -O https://downloads.sourceforge.net/project/sdpa/sdpa/sdpa_7.3.18.tar.gz
Once downloaded, unzip it using:
tar -zxf sdpa_7.3.18.tar.gz
To build SDPA (with or without the Python wrapper), you need to have the basic build tools, i.e. make
and gcc
/g++
on your computer. On macOS, these tools come bundled with Xcode Command Line Tools which can be installed by:
xcode-select --install
Additional Requirements
Building SDPA also requires you to have
-
A BLAS/LAPACK library. On macOS, they are installed as part of the Apple Accelerate framework. I recommend you stick with Apple’s BLAS/LAPACK implementation because it would work regardless of whether you have an Intel based Mac or M1 based Mac.
The best way to check if they are present is to compile a very basic Hello World program with
g++ hello.c -lblas -llapack
. On macOS,-lblas
and-llapack
will use the BLAS/LAPACK provided by Accelerate framework. -
A FORTRAN compiler. It will be required to build MUMPS which is written in Fortran.
On macOS, the most convenient to install and recent
gfortran
binary that I found at time of writing is provided by this GitHub repository.
Minor fixes
The sdpa
buildsystem will download MUMPS and build it. A Makefile
has been provided inside the mumps
subfolder of sdpa
source. Depending on the version of gfortran
that you use, you may or may not need the -fallow-argument-mismatch
flag provided in this file.
-
Older versions of
gfortran
will not need this flag and do not recognize it. If while runningmake
, you run into a compiler error forgfortran
, remove this flag. -
Secondly, on macOS you may not have
wget
on your system. TheMakefile
will usewget
to download the MUMPS source. You can modify the following line in theMakefile
in themumps
subfolder to usecurl
instead ofwget
:wget http://ftp.de.debian.org/debian/pool/main/m/mumps/${MUMPS_TAR_FILE}
so it should look like
curl -O http://ftp.de.debian.org/debian/pool/main/m/mumps/${MUMPS_TAR_FILE}
Build
The next step should be to run the configure script in the sdpa
root directory. Assuming you have sdpa
unzipped on your Desktop:
./configure --prefix=$HOME/Desktop/sdpa-7.3.18
This should check whether all requirements are met for the build. Once done, issue the make command:
make
This will generate the sdpa
binary as well as libsdpa.a
static library. The libsdpa.a
library is what the Python wrapper will link against.
This will also generate the make.inc
file which sdpa-python
would require you to link to.
Test run the SDPA binary
Let’s do a test run on the sdpa
binary to make sure all is well until this point. While still within the sdpa-7.3.18
folder, do
./sdpa example1.dat example1.out
This should complete a test run the sdpa
binary using one of the provided example files. If you can see the solver output, and pdOPT
as the status, the build was successful. We can now move onto building the Python wrapper.
Obtaining and installing SDPA Python wrapper
Once you have built and done a test run on sdpa
(or sdpa_gmp
if using the Multiprecision backend), you have a working SDPA binary, it’s finally time to build and install sdpa-python
.
We need SPOOLES for building sdpa-python
.
Obtaining and building the SPOOLES library and headers
If you are using the SDPA Multiprecision backend, it contains SPOOLES and will build it as part of the buildsystem. In that case, you can skip directly to the next subsection.
If you are using the regular SDPA backend, you will have to download as well as build the SPOOLES library.
SPOOLES can be obtained from the official SPOOLES webpage or the Debian package sources.
curl -O http://ftp.de.debian.org/debian/pool/main/s/spooles/spooles_2.2.orig.tar.gz
mkdir spooles
tar -zxf spooles_2.2.orig.tar.gz -C spooles
cd spooles
The Make.inc
file (located in the root of the extracted spooles
folder) needs to be patched before SPOOLES can be successfully built. Patch and build the library as below.
curl -O https://raw.githubusercontent.com/sdpa-python/sdpa-multiprecision/main/spooles/patches/patch-Make.inc
patch -p0 < patch-Make.inc
make lib
By default, the Makefile
will load the code into spooles.a
and this may cause the library to be not locatable (despite providing the search path in setupcfg.py
). To avoid this issue, please rename this file to libspooles.a
.
mv spooles.a libspooles.a
Obtain and prepare sdpa-python
for build
You can obtain it by
git clone https://github.com/sdpa-python/sdpa-python.git
Then do
cd sdpa-python
There is a file setupcfg.py
in the root of sdpa-python
. We need to edit it and provide
-
The location of SDPA headers and static library (i.e.
libsdpa.a
orlibsdpa_gmp.a
):SDPA_DIR = '/path/to/sdpa_package_name'
-
Only if using the regular SDPA backend, the location of SPOOLES library and headers (for Multiprecision backend these variables need not be changed):
SPOOLES_DIR = '/path/to/spooles/' SPOOLES_INCLUDE = SPOOLES_DIR
-
The location of
libgfortran.a
andlibquadmath.a
. Assuming you installed it from this GitHub repository with the default options:GFORTRAN_LIBS ='/usr/local/gfortran/lib'
-
Only if using the SDPA Multiprecision backend, the location of GMP library and headers:
GMP_DIR = '/path/to/gmp-version'
-
Lastly, if you are using the SDPA Multiprecision backend, please set
USEGMP = True
in this file.
Install sdpa-python
Package
Finally, build and install sdpa-python
package. While still in the sdpa-python
directory, do:
python setup.py install
Assuming all goes well, you should be able to do import sdpap
in Python. If you run into problems, cd
out of the sdpa-python
directory. Having folders with the name sdpap
in your current directory, you will run into problems while doing import sdpap
in Python (it will complain about a circular dependency problem).
Cleanup
Once installed, you can delete both the sdpa
and sdpa-python
folders.