ePSOPT Setup

Similar to ETOL, PSOPT is an open source software package that relies on open source packages. The library can be obtained at https://github.com/PSOPT/psopt. It comes with an Ubuntu 18.04 install script, which also installs the prerequisite software packages. The library does not provide an install script for other operating systems, such as Windows. However, PSOPT has been successfully used on Windows with ePSOPT.

Windows Setup

Many packages need to be built from source. The primary packages are IPOPT and ADOL-C. These two packages require additional open source packages too. The following steps provide instructions for building PSOPT and its dependencies on a Windows 10 machine.

  1. If MSYS2 is not installed, complete the instructions in the Windows Setup section.

  2. Install additional prerequisite software

    pacman -S unzip mingw-w64-x86_64-openblas mingw-w64-x86_64-lapack \
    mingw-w64-x86_64-suitesparse mingw-w64-x86_64-metis mingw-w64-x86_64-swig \
    mingw-w64-x86_64-readline mingw-w64-x86_64-libgd
    
  3. Install ColPack with CMake.

    1. Open a MSYS2 shell

    2. Download Colpack

      git clone https://github.com/CSCsw/ColPack.git
      
    3. Edit the CMakeLists.txt file in ./ColPack/build/cmake. Replace “ColPack_headers” with “ColPack”. Replace “ColPack_libs” with “cmake/ColPack”. Delete “/shared_archive”, “/shared_library”, “/shared_runtime”, “/archive”, “/library”, and “/runtime”. Change “WIN32” to “MSVC”. Change the following lines

      101    ${COLPACK_ROOT_DIR}/src/Recovery/*.cpp
      
      170    $target_link_libraries(ColPack_shared PRIVATE ${OpenMP_C_LIBRARIES})
      
    4. Change directory to ColPack’s build directory

      cd ColPack/build
      
    5. Create a “mywork” directory

      mkdir mywork && cd mywork
      
    6. Generate the build files

      cmake ../cmake -DCMAKE_INSTALL_PREFIX:PATH=/mingw64 -DENABLE_OPENMP=ON -DENABLE_EXAMPLES=OFF -G "Unix Makefiles"
      
    7. Build the files

      make && make install
      
  4. Install ADOL-C

    1. Open a MSYS Shell

    2. Download ADOL-C

      git clone https://github.com/coin-or/ADOL-C.git
      
    3. Change directory to ADOL-C

      cd ADOL-C
      
    4. Edit ./ADOL-C/swig/adolc-numpy-for.i. Change all “unsigned long” to “unsigned long long”

    5. Edit ./configure.ac. On line 95, change “_lib=lib64” to “_lib=lib”.

    6. Edit ./ADOL-C/swig/setup.py. Replace “lib64” to “lib”. Change line 193 to

      libraries=['adolc','ColPack','gomp'],
      
    7. Run the following

      autoreconf -vfi
      
    8. Configure the build

      ./configure --prefix=/mingw64 --with-colpack=/mingw64 \
      --with-cflags="-O3 -fPIC -std=c99 -Wall" \
      --with-cxxflags="-O3 -std=c++11 -Wall -fPIC" --enable-sparse \
      --with-boost-libdir=/mingw64/lib --enable-ulong --enable-static=yes --enable-shared=no --with-openmp-flag="-fopenmp"
      
    9. Build and install

      make && make install
      
  5. Install a IPOPT Linear Solver. For example the Harwell Subroutines Library (HSL) was successfully used on Windows.

  6. Install IPOPT such that it dynamically loads a linear solver

    1. Open a MSYS2 Shell

    2. Download Ipopt

      git clone https://github.com/coin-or/Ipopt.git
      
    3. Change directory to Ipopt

      cd Ipopt
      
    4. Modify it load such that it loads the installed linear solver’s dll. For example, if HSL is used, modify ./src/contrib/LinearSolverLoader/HSLLoader.c, by changing ‘#define HSLLIBNAME SHAREDEXT’ to ‘#define HSLLIBNAME “libhsl.dll”’

    5. Make a build folder

      mkdir build && cd build
      
    6. Configure the build

      ../configure --enable-static=yes --enable-shared=no coin_skip_warn_cxxflags=yes \
      --with-mumps=no --with-asl=no --with-hsl=no --prefix=/mingw64 \
      LDFLAGS="-Wl,--no-as-needed -ldl"
      
    7. Build Ipopt

      make -j $(($(nproc) - 1))
      
    8. Install Ipopt

      make install
      
  7. Install a PDFLib-Lite shared library based on MinGW32 Linux Distro Notes

    1. Open a MSYS2 shell

    2. Download PDFLib-Lite

      git clone https://github.com/Distrotech/PDFlib-Lite.git
      
    3. Change directory to PDFlib-Lite

      cd PDFlib-Lite
      
    4. Edit ./libs/pdcore/pc_util.h by adding the following to line 25

      #undef isfinite
      
    5. Change line 23 in ./config/mkcommon.inc to

      EXE             =
      
    6. Configure the build

      ./configure --prefix=/mingw64 CFLAGS="-DPDFLIB_EXPORTS" --enable-64-bit
      
    7. Build and install

      make && make install
      
    8. Change directory to /mingw64/lib

      cd /mingw64/lib
      
    9. Create a shared Library

      gcc -shared -o libpdf.dll libpdf.a
      
    10. Create a gendef file

      gendef - libpdf.dll > libpdf.def
      
    11. Create a dll.a file

      dlltool -d libpdf.def -l libpdf.dll.a
      
    12. Move the dll file to the mingw64/bin directory

      mv ./libpdf.dll ../bin
      
  8. Install PSOPT

    1. Open a MSYS2 shell

    2. Download PSOPT

      git clone https://github.com/PSOPT/psopt.git
      
    3. Change directory to PSOPT

      cd psopt
      
    4. Download lusol into the PSOPT directory

      wget --continue http://www.stanford.edu/group/SOL/software/lusol/lusol.zip
      
    5. Extract the lusol files

      unzip ./lusol.zip
      
    6. Edit ./Makefile.

      1. Delete lines 194 and 186, which are for $(CXSPARSE).

      2. Change the following lines

        9     prefix = /mingw64
        179   all: $(DMATRIX_LIBS) $(LUSOL_LIBS) $(PSOPT_LIBS)
        
    7. Edit ./dmatrix/lib/Makefile. Change the following lines

      18    IPOPTINCDIR = ${prefix}/include/coin-or
      27    CXX           = g++
      28    CC            = gcc
      29    CXXFLAGS      = -O0 -g -I$(SNOPTDIR)/cppsrc -I$(DMATRIXDIR)/include -I$(SNOPTDIR)/cppexamples -I$(PSOPTSRCDIR) -DLAPACK -DUNIX -DSPARSE_MATRIX -DUSE_SNOPT -DUSE_IPOPT -I$(CXSPARSE)/Include -I$(LUSOL) -I$(CXSPARSE)/../SuiteSparse_config -I$(IPOPTINCDIR) -fomit-frame-pointer -pipe -DNDEBUG -fPIC -DHAVE_MALLOC
      
    8. Edit ./PSOPT/lib/Makefile. Change the following lines

      16    prefix = /mingw64
      18    IPOPTINCDIR = -I${prefix}/include/coin-or
      27    CXX           = g++
      28    CC            = gcc
      29    CXXFLAGS      = -O0 -g -I${prefix}/include -I${prefix}/include/adolc -I$(DMATRIXDIR)/include -I$(SNOPTDIR)/cppexamples -I$(PSOPTSRCDIR) -DLAPACK -DWIN32 -DSPARSE_MATRIX -DUSE_IPOPT -I$(LUSOL) $(IPOPTINCDIR) -fomit-frame-pointer -pipe -DNDEBUG -fPIC -DHAVE_MALLOC -std=c++11  -DPSOPT_EXPORT
      
    9. Edit plot.cxx and psopt.h in ./PSOPT/src, by replacing all instances of “const string& title” to “const string title”.

    10. Edit ./PSOPT/src/psopt.h.

      1. Add to beginning of lines 1111 and 1113

        __declspec(dllexport)
        
      2. Replace lines 39 to 43 with

        #ifndef PSOPT_API
        #ifdef WIN32
        #ifdef PSOPT_EXPORT
        #define PSOPT_API __declspec(dllexport)
        #else
        #define PSOPT_API __declspec(dllimport)
        #endif
        #endif
        #endif
        
    11. Edit ./PSOPT/src/plot.h. Delete or comment out lines 61 to 65

    12. Edit ./PSOPT/src/IPOPT_interface.cxx. Replace “WIN32” with “MSVC”.

    13. Edit ./PSOPT/src/NLP_interface.cxx to use the installed IPOPT linear solver. A list of supported linear solver values are provided at https://coin-or.github.io/Ipopt/OPTIONS.html#OPT_Linear_Solver. For example for HSL ma57, add the following to line 559

      app->Options()->SetStringValue("linear_solver","ma57");
      
    14. Edit ./dmatrix/include/dmatrixv.h.

      1. Change line 116 to

        #define DEC_THREAD __thread
        
      2. First delete any instance of “=NULL” and “= Null”.

      3. Replace any instance of “ntype=0” with “ntype”.

      4. Between lines 1725 to 1832 replace:

        1. “[]” with “[] = NULL”

        2. “* U” with “* U = NULL”

        3. “* V” with “* V = NULL”

        4. “* rindx” with “* rindx = NULL”

        5. “* cindx” with “* cindx = NULL”

        6. “int ntype” with “int ntype = 0”

      5. Between lines 2443 to 2484, replace:

        1. “[]” with “[] = NULL”

        2. “* U” with “* U = NULL”

        3. “* V” with “* V = NULL”

    15. Build PSOPT

      make all
      
    16. Create a PSOPT_HOME environment variable that point points the PSOPT root directory. For example, in bashrc, add the following line at the end of the file

      export PSOPT_HOME=/home/${USER}/psopt