From 5367bebc01d0e403889b2e63001c2e15c70bbb80 Mon Sep 17 00:00:00 2001 From: "Santos Xavier, Alinson" Date: Wed, 7 Aug 2019 12:57:53 -0500 Subject: [PATCH] Add README and code generation scripts --- .gitignore | 2 +- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ gen/generate.jl | 20 +++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100755 README.md create mode 100755 gen/generate.jl diff --git a/.gitignore b/.gitignore index 6121d2a..b20a270 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ deps/build.log deps/deps.jl -gen +gen/output Manifest.toml diff --git a/README.md b/README.md new file mode 100755 index 0000000..dad4ac8 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +CPLEXW.jl +========= +This package contains an unofficial low-level Julia wrapper for IBM® ILOG® CPLEX® Optimization Studio, automatically generated from the official C headers using [Clang.jl][1]. Unlike [CPLEX.jl][2], this wrapper allows access to all advanced CPLEX routines. However, it does not currently implement [MathOptInterface][3] or [MathProgBase][4] and therefore does not completely replace CPLEX.jl. + +**Disclaimer:** You cannot use CPLEXW.jl without having purchased and installed a copy of CPLEX Optimization Studio from IBM. This wrapper is maintained by the JuliaOpt community, and is **not** officially developed or supported by IBM. + + +Installation +------------ +Please follow the same install instructions from [CPLEX.jl][2], but instead of running `Pkg.add("CPLEX")`, run the following command instead: + + Pkg.add("https://github.com/iSoron/CPLEXW.git") + +Usage +----- + +The following example shows how can the package be used in standalone mode. After including `CPLEXW`, all standard CPLEX constants and functions (C API) become available to Julia. For a complete description of the available functions, please refer to the official CPLEX documentation. Julia's manual page on [how to call C functions][5] may also be helpful. + + using CPLEXW + + # Create CPLEX environment + rval = [Cint(0)] + env = CPXopenCPLEX(rval) + + # Change some parameters + CPXsetintparam(env, CPX_PARAM_SCRIND, CPX_ON) # Print to the screen + CPXsetdblparam(env, CPX_PARAM_TILIM, 30) # Time limit in seconds + + # Create, populate and solve a problem + lp = CPXcreateprob(env, rval, "problem") + CPXreadcopyprob(env, lp, "myinstance.mps.gz", "mps") + CPXmipopt(env, lp) + +Usage with JuMP and CPLEX.jl +---------------------------- +This package can also be used when you already have a JuMP optimization model (solved with CPLEX), but you need access to some advanced routines which are not available through CPLEX.jl. The next example illustrates this scenario: + + using JuMP, CPLEX, CPLEXW + + # Create JuMP + CPLEX.jl model + model = direct_model(CPLEX.Optimizer()) + @variable(model, x >= 0) + @objective(model, Min, x) + optimize!(model) + + # Call low-level CPLEX function + cpx = backend(model).inner + CPXgetnumnz(cpx.env, cpx.lp) + +Regenerating wrappers +--------------------- +To regenerate the wrappers, run the script `gen/generate.jl`. The environment variable `CPLEX_INCLUDE_DIR` must be defined, and must point to the directory containing the header files. For example, if CPLEX is installed at `/opt/cplex-12.8`, the variable should be set to `/opt/cplex-12.8/cplex/include/ilcplex/`. If successful, the script will generate several files in the directory `gen/output`. Only the files `commons.jl` and `cplex.jl` are currently used. + +[1]: https://github.com/JuliaInterop/Clang.jl +[2]: https://github.com/JuliaOpt/CPLEX.jl +[3]: https://github.com/JuliaOpt/MathOptInterface.jl +[4]: https://github.com/JuliaOpt/MathProgBase.jl +[5]: https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/ \ No newline at end of file diff --git a/gen/generate.jl b/gen/generate.jl new file mode 100755 index 0000000..812f2be --- /dev/null +++ b/gen/generate.jl @@ -0,0 +1,20 @@ +using Clang + +if "CPLEX_INCLUDE_DIR" ∉ keys(ENV) + error("CPLEX_INCLUDE_DIR must be defined") +end + +CPLEX_INCLUDE_DIR = ENV["CPLEX_INCLUDE_DIR"] + +mkpath("output") +context = Clang.init( + headers=["$CPLEX_INCLUDE_DIR/cpxconst.h", "$CPLEX_INCLUDE_DIR/cplex.h"], + common_file="commons.jl", + output_dir="output", + clang_includes=vcat(CPLEX_INCLUDE_DIR, LLVM_INCLUDE), + clang_args = ["-I", CPLEX_INCLUDE_DIR], + clang_diagnostics=true, + header_wrapped=(header, cursorname) -> header == cursorname, + header_library=header_name -> "libcplex" +) +Clang.run(context)