swIMP

SWIG-based Interfaces for Mathematical Programming

hosted at
Get swIMP at SourceForge.net. Fast, secure and Free Open Source software downloads


Content


About swIMP  License  Download  Quick-Installation (binary distribution)  Features  Environment  Installation  Documentation  Performance  Support    Developer's page


About swIMP

swIMP (SWIG-based Interfaces for Mathematical Programming) aims at making solvers written in C or C++ available for other languages. The current focus is on Java as target language and on LP/IP-solvers which are compatible to the Open Solver Interface (OSI) from the Coin-OR-project. This includes both Open Source solvers as well as reknown commercial solvers like CPLEX and Xpress (see Features).

swIMP comes with a binary distribution of several Coin-OR-solvers for Linux/x86-machines that takes just a few minutes to install.

The wrappers are implemented using the generator tool SWIG. SWIG generates both C++ code which is then compiled into a shared library and Java-code which accesses the shared library through the Java Native Interface (JNI). In principle, SWIG also supports other target languages like Python or Perl but this would require non-trivial modifications of the SWIG interface definitions currently provided by swIMP.

The swIMP project was started as a subproject of Combean. Combean is a Java framework for mathematical structures and optimization algorithms. Among other features it contains a convenient framework for constructing complex linear programming models. If you are going to use swIMP, you might thus also want to consider combining it with Combean.

Keywords: Java, Linear Programming, LP, Integer Programming, IP, Operations Research, OR, OSI, Coin, Clp, Symphony, CPLEX, Xpress, GLPK, MOSEK, SoPlex, SWIG, JNI, Open Source.

back to top



License

swIMP is distributed under the GNU Lesser General Public License.

swIMP comes with a binaries of Jakarta Commons, JUnit and Log4J. Please consider the LICENSE-files in the dist-directory for a detailed description of these 3rd party libraries. Source-code distributions of these libraries can be obtained at the given URLs.

There is also a binary distribution of swIMP for Linux on x86-machines. This distribution contains shared libraries in binary form for the Clp, Cbc, SYMPHONY and Vol solvers , as well as the OSI C++-frontend for these solvers (all from COIN-OR project). Please refer to the coin-directory in the binary distribution for a detailed description of the Coin-license. A source code distribution of COIN-OR-solvers can be obtained at the given COIN-OR project home page.

Furthermore, the binary distribution contains a the Osi-frontend for the GLPK-solver. Since GLPK is distributed under the GPL, it may not be distributed only in binary form. If you want to use the GLPK-solver, please obtain and install it yourself. The library that comes with the binary distribution will require the GLPK shared library in your system's library path (LD_LIBRARY_PATH on Linux machines).

back to top



Download

swIMP is available for download at the Sourceforge project page.

swIMP is in beta-state and has been tested with a quite comprehensive test suite. We would be very much interested if you encounter any bugs or difficulties with the API as we would like to ensure that the quality is optimum before declaring the code ready for production.

In general, any feedback is highly welcome. You may consider using the Sourceforge tracking utility or the forums

back to top



Quick installation of the binary distribution of swIMP (Linux-x86 only)

If you have downloaded the binary distribution of swIMP for Linux on x86 machines, the following steps suffice to get you started.
back to top



Features

Java-wrappers for OSI-compatible solvers

The following solvers are currently supported:

Support for the following solvers should be easy to add (at most one day of work or so) but has not yet been added because I have no licenses for these solvers and can thus not test their integration (even though it should work out of the box with their OSI-frontend). A patch for including one of these solvers would of course be highly welcome:

back to top



Environment

back to top



Installation

Building and installing swIMP

The usual

./configure
make forcegen # can be skipped, if all supported solvers are available. see below.
make
make check    # (optional)
make install
shall suffice to build the shared library. You may want to give some arguments to configure, e.g.
./configure --prefix=/install/path \
  CPPFLAGS="-I/path/to/coin/include" LDFLAGS="-L/path/to/coin/lib"

If you don't give any arguments to configure, swIMP will be compiled against the solvers in the binary distribution. This will not work if you are not on a Linux/x86-machine. Please use the switch --disable-binbundle in order to disable this behavior.

Make sure that the path where the shared library is installed is accessible by the dynamic linker. Under Linux this means that the path either has to be contained in /etc/ld.so.conf (remember to run ldconfig after changing the setting) or in the environment variable LD_LIBRARY_PATH. If you use the binaries that come with swIMP, it suffices to source the script swimpEnv.sh.

After the build, several jar-files (one per solver) are located in the dist-directory. You may want to put them to a more convenient place where you store other jars (like /usr/local/share/java) and include it in your CLASSPATH.

jars that swIMP depends on and which do not come with swIMP can be made available in two ways:

Installation of LP solvers

Of course, using swIMP only makes sense if you have some LP solvers installed that you would like to access through swIMP. If you do not want to/cannot use the binaries that come with swIMP, a quick way to get you started (if you don't have the solvers installed already) is as follows:

  1. Download GLPK and install it (./configure; make; make install).
  2. Download the Coin solvers (refer to the guide how obtain and install Coin packages).
  3. Install swIMP as described above.

Detection of available LP solvers

The ./configure script of swIMP tries to find out which LP solvers are installed at your site. This is done by checking whether header files of the given solvers are available for compilation. The following header files are used for this check:

Solver Corresponding header file
Cbc CbcSolver.hpp
Clp ClpSolve.hpp
SYMPHONY symphony.h
Vol VolVolume.hpp
GLPK glpk.h
MOSEK mosek.h

If a header is found, the wrapper classes (both C++ and Java) for the corresponding solver are generated, otherwise the unavailable solver is excluded from the build. Please examine the output of ./configure to find out whether all the solver that you expect are indeed accessible during the build. For example the output

checking VolVolume.hpp usability... yes
checking VolVolume.hpp presence... yes
checking for VolVolume.hpp... yes
checking symphony.h usability... no
checking symphony.h presence... no
means that the Vol-solver has been found but the SYMPHONY solver is not available. Please note that ./configure only checks the availability of the header file and not of the library of the solver. If the library is not accessible (e.g. due to a wrong LDFLAGS-setting), you will get an error during linking.

Currently, swIMP is distributed with a version of the generated C++ and Java classes which contains wrappers for all supported solvers except MOSEK (since MOSEK is a commercial solver and not everybody may have access to it). If this works for you, you do not need to invoke 'make forcegen' and in particular you will not need to install SWIG on your machine. If not all solver are available, however, you have to regenerate the wrappers by running 'make forcegen' first. Of course, this requires SWIG.

Alternatively, you can patch the file iface/coin_wrap.cxx. This is fairly easy. The only thing that has to be done is to comment out the JNI wrapper functions for the unavailable solver. In the future this shall be achieved by including suitable #ifdef's in coin_wrap.cxx but unfortunately I do not see a way to achieve this with SWIG directly and writing some kind of awk postprocessor or so looks like a quite ugly solution.

Checking the installation of the native libraries

swIMP comes with a tool that tries to load the supported native libraries and reports which libraries are available. Simply, setup your class path to contain swimp.jar and execute probeSolvers.sh. By executing probeSolvers.sh -h you can get a description which shows further options provided by the tool.

Running the automatic test suite

When the shared library is available through the dynamic linker, you can execute the automatic test suite. This is done by executing

make test
and test results will be written in the subdirectory testrep. The difference between 'make check' and 'make test' is that make test will execute the tests using your environment, whereas 'make check' uses the local copy of the library before installation. Thus, 'make test' checks your installation and not just the correctness of the build.

If you get an error message like

Testsuite: net.sourceforge.swimp.test.coin.TestCoinShallowPackedVectorBase
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0,013 sec

Testcase: testMethodsOfDerivedClasses took 0,008 sec
        Caused an ERROR
no swIMP in java.library.path
java.lang.UnsatisfiedLinkError: no swIMP in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1517)
        at java.lang.Runtime.loadLibrary0(Runtime.java:788)
        at java.lang.System.loadLibrary(System.java:834)
        at net.sourceforge.swimp.coin.coinJNI.(coinJNI.java:44)
        at net.sourceforge.swimp.coin.IntArray.(IntArray.java:41)
        at net.sourceforge.swimp.coin.coin.jarrayToSwig(coin.java:39)
        at net.sourceforge.swimp.test.coin.TestCoinShallowPackedVectorBase.setUp
(TestCoinShallowPackedVectorBase.java:53)
you should check your dynamic linker settings (i.e. your LD_LIBRARY_PATH on a Linux system).

back to top



Documentation

For an overview of the API of the generated wrapper classes, please refer to the Javadoc. Unfortunately, I found no easy way to include the inline documentation that comes with Coin in the Javadoc. Thus, there is no description of the individual member functions. However, as the signatures of the functions are identical (or at least analogous) to the member functions of the corresponding Osi C++-class, we refer the reader to the original Coin-documentation, which is also available as online version.
back to top



Performance

Since version 0.9 swIMP uses a hand-tailored SWIG-mapping that hands Java-array of type int[] or double[] directly down to the C++ library layer. There is no copying of data involved. Measurements show that the overhead for using a Java-array in comparison to using a SWIG-generated wrapper for a C++-array (basically a representation of the pointer to the C++-array as a Java-long) is negligible.

Caveat: This mapping is based on the assumption that the data types jint and jdouble, used by JNI (Java Native Interface) and the native C++ data types int and double are identical. This is the case for the environment where we develop swIMP and we hope that this will be the case for most swIMP users. swIMP will stop the build process with an error if this assumption is not justified. In that case, please report this to the Sourceforge support tracker. If we see that there is need for that in the swIMP-user community, we will add an alternative mapping, which requires a bit more computational overhead but which will work without any assumptions on the structure of the data types jint and jdouble.

We have also compared the performance of swIMP-generated code with native C++-code. You can run our simple performance test suite by using the command make perftest. This show the times for calls to the methods setVector and setConstant of CoinPackedVector in the following three cases:

The test resuls show that the overhead due to swIMP is reasonable (approx. 30% in that case) and that there is practically no difference between using Java-arrays directly vs. SWIG-wrappers for C++-arrays. On my machine the results are for example as follows (every measurement is based on 100 independent calls to the method):
     [exec] setVector(int, int*, double*): size=1000000, numVals=30000: 1060 (ms)

     [exec] setConstant(int, int*, double): size=1000000: 1040 (ms)

     [java] CoinPackedVector.setVector(Java): size=1000000, numVals = 30000:
     [java]   count = 1  total = 1379 (ms)  average = 1379.0 (ms)

     [java] CoinPackedVector.setVector(SWIG): size=1000000, numVals = 30000:
     [java]   count = 1  total = 1333 (ms)  average = 1333.0 (ms)

     [java] CoinPackedVector.setConstant(Java): size=1000000:
     [java]   count = 1  total = 1326 (ms)  average = 1326.0 (ms)

     [java] CoinPackedVector.setConstant(SWIG): size=1000000:
     [java]   count = 1  total = 1280 (ms)  average = 1280.0 (ms)

back to top



Support

If you need support, please feel free to contact the project through the Sourceforge support tracker. We will do our best to answer in a timely manner.
back to top