Skip to content

Latest commit

 

History

History
120 lines (86 loc) · 4.52 KB

README.md

File metadata and controls

120 lines (86 loc) · 4.52 KB

GMSK

gmsk is an unofficial wrapper for MOSEK, the conic optimizer from MOSEK ApS.

For Detailed Documentation, See Go Reference

Examples

See Examples section on Go Reference for many examples reproduced from C api code.

Hello World example from C api is provided below.

package main

import (
	"fmt"
	"log"

	"github.com/fardream/gmsk"
)

// This is reproduced from MOSEK C example hellowworld.c
// However, the response code is checked here.
func main() {
	checkOk := func(err error) {
		if err != nil {
			log.Fatalf("failed: %s", err.Error())
		}
	}

	task, err := gmsk.MakeTask(nil, 0, 0)
	if err != nil {
		log.Fatal(err)
	}
	defer gmsk.DeleteTask(task)

	checkOk(task.AppendVars(1))
	checkOk(task.PutCJ(0, 1.0))
	checkOk(task.PutVarBound(0, gmsk.BK_RA, 2.0, 3.0))
	checkOk(task.PutObjSense(gmsk.OBJECTIVE_SENSE_MINIMIZE))
	_, res := task.OptimizeTrm()
	checkOk(res)
	result := make([]float64, 1)
	result, res = task.GetXx(gmsk.SOL_ITR, result)

	fmt.Printf("Solution x = %.6f\n", result[0])
}

Setup MOSEK c api for gmsk

GMSK requires the C api for MOSEK, which can be obtained from MOSEK's website. To actually build the package, a recent enough C toolchain, and the environment should be properly set up.

Set up on Linux

On linux, this can be achieved by setting CPATH environment variable and LIBRARY_PATH

# prepend mosek header folder to CPATH, replace {version} and {arch} with the one you have installed
export CPATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/h${CPATH:+":${CPATH}"}
# prepend mosek lib folder to LIBRARY_PATH
export LIBRARY_PATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin${LIBRARY_PATH:+":${LIBRARY_PATH}"}
export LD_LIBRARY_PATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin${LD_LIBRARY_PATH:+":${LD_LIBRARY_PATH}"}

Alternatively, this can set up for cgo specifically

export CGO_CFLAGS="-I${MSKHOME}/mosek/{version}/tools/platform/{arch}/h"
export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin"

IF LD_LIBRARY_PATH doesn't include MOSEK's binary folder when running the code, the binary can be set up by adding MOSEK's binary folder to rpath, for example, the CGO_LDFLAGS can be updated to add rpath

export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin -Wl,-rpath=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin"

Setup on macOS

Follow the installation instructions on MOSEK's website - remember to run install.py. Note unless System Integrity Protect (SIP) is turned off on macOS, the environment variable LD_LIBRARY_PATH (and macOS specific DYLD_LIBRARY_PATH) will NOT work.

When building, the setup is similar to linux

# prepend mosek header folder to CPATH, replace {version} and {arch} with the one you have installed
export CPATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/h${CPATH:+":${CPATH}"}
# prepend mosek lib folder to LIBRARY_PATH
export LIBRARY_PATH=${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin${LIBRARY_PATH:+":${LIBRARY_PATH}"}

or

export CGO_CFLAGS="-I${MSKHOME}/mosek/{version}/tools/platform/{arch}/h"
export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin"

However, the binary may not be able to find libmosek at runtime. Besides default search path, macOS will also look for dynlib in the rpaths of the binary - however, it only does so if the load path of the dynlib starts with @rpath - which is controlled by the LC_ID_DYLIB of the dynlib (in this case, libmosek64).

So there are two options

  1. Use rpath. First add rpath to the linker line

    export CGO_LDFLAGS="-L${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin -Wl,-headerpad,128 -Wl,-rpath,${MSKHOME}/mosek/{version}/tools/platform/{arch}/bin" #

    Then check LC_ID_DYNLIB on the libmosek64.dynlib, and update it with install_name_tool (which is part of Apple's development suite). For example, for 10.0 version of the library

    install_name_tool -id @rpath/libmosek64.10.0.dynlib path/to/libmosek64.10.0.dynlib
  2. Change LC_ID_DYNLIB to the full absolute path of libmosek64.

    install_name_tool -id /abspath/to/libmosek64.10.0.dynlib path/to/libmosek64.10.0.dynlib