Skip to content

Commit

Permalink
Merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
pedromxavier committed Apr 12, 2023
2 parents b87592b + 4d70faf commit 9342a69
Show file tree
Hide file tree
Showing 13 changed files with 2,563 additions and 768 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ jobs:
${{ runner.os }}-
- uses: julia-actions/julia-buildpkg@v1
env:
SECRET_XPRS_WIN_8110: ${{ secrets.XPRS_WIN_8110 }}
SECRET_XPRL_WIN_8110: ${{ secrets.XPRL_WIN_8110 }}
SECRET_XPRA_WIN_8130: ${{ secrets.XPAUTH_XPR }}
SECRET_XPRS_WIN: ${{ secrets.XPRS_WIN_900 }}
SECRET_XPRL_WIN: ${{ secrets.XPRL_WIN_900 }}
SECRET_XPRA_WIN: ${{ secrets.XPAUTH_XPR }}
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v1
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name = "Xpress"
uuid = "9e70acf3-d6c9-5be6-b5bd-4e2c73e3e054"
authors = ["Joaquim Dias Garcia <[email protected]>, Dheepak Krishnamurthy <[email protected]>, Jose Daniel Lara <[email protected]>"]
url = "https://github.com/jump-dev/Xpress.jl"
version = "0.15.6"
version = "0.16.1"

[deps]
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
Expand Down
153 changes: 61 additions & 92 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,113 +1,77 @@
# Xpress.jl

| **Build Status** | **Social** |
|:----------------:|:----------:|
| [![Build Status][build-img]][build-url] [![Codecov branch][codecov-img]][codecov-url] | [![Gitter][gitter-img]][gitter-url] [<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Discourse_logo.png/799px-Discourse_logo.png" width="64">][discourse-url] |
[![Build Status](https://github.com/jump-dev/Xpress.jl/workflows/CI/badge.svg?branch=master)](https://github.com/jump-dev/Xpress.jl/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/jump-dev/Xpress.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/jump-dev/Xpress.jl)


[build-img]: https://github.com/jump-dev/Xpress.jl/workflows/CI/badge.svg?branch=master
[build-url]: https://github.com/jump-dev/Xpress.jl/actions?query=workflow%3ACI
[codecov-img]: http://codecov.io/github/jump-dev/Xpress.jl/coverage.svg?branch=master
[codecov-url]: http://codecov.io/github/jump-dev/Xpress.jl?branch=master

[gitter-url]: https://gitter.im/JuliaOpt/JuMP-dev?utm_source=share-link&utm_medium=link&utm_campaign=share-link
[gitter-img]: https://badges.gitter.im/JuliaOpt/JuMP-dev.svg
[discourse-url]: https://discourse.julialang.org/c/domain/opt


Xpress.jl is a wrapper for the [FICO Xpress Solver](https://www.fico.com/products/fico-xpress-solver).
[Xpress.jl](https://github.com/jump-dev/Xpress.jl) is a wrapper for the [FICO Xpress Solver](https://www.fico.com/products/fico-xpress-solver).

It has two components:

- a thin wrapper around the complete C API
- an interface to [MathOptInterface](https://github.com/jump-dev/MathOptInterface.jl)

The C API can be accessed via `Xpress.Lib.XPRSxx` functions, where the names and
arguments are identical to the C API. See the [Xpress documentation](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML)
for details.
## Affiliation

*The Xpress wrapper for Julia is community driven and not officially supported
by FICO Xpress. If you are a commercial customer interested in official support for
Julia from FICO Xpress, let them know!*
The Xpress wrapper for Julia is community driven and not officially supported
by FICO Xpress. If you are a commercial customer interested in official support
for Julia from FICO Xpress, let them know.

## Install:
## License

Here is the procedure to setup this package:
`Xpress.jl` is licensed under the [MIT License](https://github.com/jump-dev/Xpress.jl/blob/master/LICENSE.md).

1. Obtain a license of Xpress and install Xpress solver, following the instructions on FICO's website.
The underlying solver is a closed-source commercial product for which you must
[purchase a license](https://www.fico.com/products/fico-xpress-solver).

2. Install this package using `Pkg.add("Xpress")`.
## Installation

3. Make sure the XPRESSDIR environmental variable is set to the path of the Xpress directory. This is part of a standard installation. The Xpress library will be searched for in XPRESSDIR/lib on unix platforms and XPRESSDIR/bin on Windows.
First, obtain a license of Xpress and install Xpress solver, following the
[instructions on the FICO website](https://www.fico.com/products/fico-xpress-solver).

Then, install this package using:
```julia
import Pkg
Pkg.add("Xpress")
```

4. Now, you can start using it.
If you encounter an error, make sure that the `XPRESSDIR` environmental variable
is set to the path of the Xpress directory. This should be part of a standard
installation. The Xpress library will be searched for in `XPRESSDIR/lib` on Unix
platforms and `XPRESSDIR/bin` on Windows.

You should use the xpress version matching to your julia installation and vice-versa.
For example, on macOS, you may need:
```julia
ENV["XPRESSDIR"] = "/Applications/FICO Xpress/xpressmp/"
import Pkg
Pkg.add("Xpress")
```

By default, `build`ing *Xpress.jl* will fail if the Xpress library is not found.
By default, building Xpress.jl will fail if the Xpress library is not found.
This may not be desirable in certain cases, for example when part of a package's
test suite uses Xpress as an optional test dependency, but Xpress cannot be
installed on a CI server running the test suite. To support this use case, the
`XPRESS_JL_SKIP_LIB_CHECK` environment variable may be set (to any value) to
make *Xpress.jl* installable (but not usable).
make Xpress.jl installable (but not usable).

## Use Other Packages
## Use with JuMP

We highly recommend that you use the *Xpress.jl* package with higher level
packages such as [JuMP.jl](https://github.com/jump-dev/JuMP.jl) or
[MathOptInterface.jl](https://github.com/jump-dev/MathOptInterface.jl).
To use Xpress with JuMP, use:

This can be done using the ``Xpress.Optimizer`` object. Here is how to create a
*JuMP* model that uses Xpress as the solver. Parameters are passed as keyword
arguments:
```julia
using JuMP, Xpress

model = Model(()->Xpress.Optimizer(DEFAULTALG=2, PRESOLVE=0, logfile = "output.log"))
model = Model(Xpress.Optimizer)
set_optimizer(model, "PRESOLVE", 0)
```

In order to initialize an optimizer without console printing run
`Xpress.Optimizer(OUTPUTLOG = 0)`. Setting `OUTPUTLOG` to zero will also disable
printing to the log file in all systems.
## Options

For other parameters use [Xpress Optimizer manual](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/)
or type `julia -e "using Xpress; println(keys(Xpress.XPRS_ATTRIBUTES))"`.

If logfile is set to `""`, log file is disabled and output is printed to the
console ([there might be issues with console output on windows (it is manually implemented with callbacks)](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/OUTPUTLOG.html)).
If logfile is set to a filepath, output is printed to the file.
By default, logfile is set to `""` (console).

Parameters in a JuMP model can be directly modified:

```julia
julia> using Xpress, JuMP;

julia> model = Model(()->Xpress.Optimizer());

julia> get_optimizer_attribute(model, "logfile")

julia> set_optimizer_attribute(model, "logfile", "output.log")

julia> get_optimizer_attribute(model, "logfile")
"output.log"
```

If you've already created an instance of an MOI `Optimizer`, you can use
`MOI.RawParameter` to get and set the location of the current logfile.

```julia
julia> using Xpress, MathOptInterface; const MOI = MathOptInterface;

julia> OPTIMIZER = Xpress.Optimizer();

julia> MOI.get(OPTIMIZER, MOI.RawParameter("logfile"))
""

julia> MOI.set(OPTIMIZER, MOI.RawParameter("logfile"), "output.log")

julia> MOI.get(OPTIMIZER, MOI.RawParameter("logfile"))
"output.log"
```
If `logfile` is set to `""`, the log file is disabled and output is printed
to the console ([there might be issues with console output on windows (it is manually implemented with callbacks)](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/OUTPUTLOG.html)).
If `logfile` is set to a file's path, output is printed to that file.
By default, `logfile = ""` (console).

## Callbacks

Expand All @@ -116,26 +80,31 @@ Solver specific and solver independent callbacks are working in
consequently, in [JuMP](https://github.com/jump-dev/JuMP.jl). However, the
current implementation should be considered experimental.

## Environement variables
## Environment variables

- `XPRESS_JL_SKIP_LIB_CHECK` - Used to skip build lib check as previsouly described.
- `XPRESS_JL_SKIP_LIB_CHECK`: Used to skip build lib check as previously described.
- `XPRESS_JL_NO_INFO`: Disable license info log.
- `XPRESS_JL_NO_DEPS_ERROR`: Disable error when do deps.jl file is found.
- `XPRESS_JL_NO_AUTO_INIT`: Disable automatic run of `Xpress.initialize()`.
Specially useful for explicitly loading the dynamic library.

- `XPRESS_JL_NO_INFO` - Disable license info log.
## Skipping Xpress.postsolve

- `XPRESS_JL_NO_DEPS_ERROR` - Disable error when do deps.jl file is found.
In older versions of Xpress, the command `XPRSpostsolve` throws an error in
infeasible models. In these older versions the post solve should not be
executed. To do this, one can use the `MOI.RawOptimizerAttribute("MOI_POST_SOLVE")`
to skip this routine.

- `XPRESS_JL_NO_AUTO_INIT` - Disable automatic run of `Xpress.initialize()`.
Specially useful for explicitly loading the dynamic library.
## C API

## Julia version warning

The Julia versions 1.1.x do not work properly with MOI dues to Julia bugs. Hence, these versions are not supported.
The C API can be accessed via `Xpress.Lib.XPRSxx` functions, where the names and
arguments are identical to the C API.

## Skipping Xpress.postsolve
See the [Xpress documentation](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML)
for details.

In older versions of Xpress the command `XPRSpostsolve` throws an error in Infeasible models. In these older versions the post solve
should not be executed. To do this one can use the `RawOptimizerAttribute("MOI_POST_SOLVE")` to skip this routine.
## Documentation

## Reference:
For more information, consult the
[FICO optimizer manual](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML).

[FICO optimizer manual](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML)
9 changes: 4 additions & 5 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ end
function ci_installation()
files = if Sys.iswindows()
[
(ENV["SECRET_XPRS_WIN_8110"], "xprs.dll")
(ENV["SECRET_XPRL_WIN_8110"], "xprl.dll")
(ENV["SECRET_XPRA_WIN_8130"], "xpauth.xpr")
(ENV["SECRET_XPRS_WIN"], "xprs.dll")
(ENV["SECRET_XPRL_WIN"], "xprl.dll")
(ENV["SECRET_XPRA_WIN"], "xpauth.xpr")
]
end
for (url, file) in files
Expand All @@ -84,12 +84,11 @@ function ci_installation()
end
end


if haskey(ENV, "XPRESS_JL_SKIP_LIB_CHECK")
# Skip!
elseif get(ENV, "JULIA_REGISTRYCI_AUTOMERGE", "false") == "true"
write_depsfile("julia_registryci_automerge")
elseif get(ENV, "SECRET_XPRS_WIN_8110", "") != ""
elseif get(ENV, "SECRET_XPRS_WIN", "") != ""
ci_installation()
else
local_installation()
Expand Down
10 changes: 5 additions & 5 deletions scripts/build_param_control_dicts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Xpress.jl/scripts/build_param_control_dicts.jl
Last build: $(now())
$("Optimizer version: $(get_version())")
$("Optimizer version: $(Xpress.get_version())")
Banner from lib:
$(get_banner())
$(Xpress.get_banner())
Banner from header (xprs.h):
$(lines[7])
Expand Down Expand Up @@ -133,11 +133,11 @@ const DOUBLE_CONTROLS_VALUES = values(DOUBLE_CONTROLS)
const INTEGER_CONTROLS_VALUES = values(INTEGER_CONTROLS)
const STRING_ATTRBUTES_VALUES = values(STRING_ATTRIBUTES)
const STRING_ATTRIBUTES_VALUES = values(STRING_ATTRIBUTES)
const DOUBLE_ATTRBUTES_VALUES = values(DOUBLE_ATTRIBUTES)
const DOUBLE_ATTRIBUTES_VALUES = values(DOUBLE_ATTRIBUTES)
const INTEGER_ATTRBUTES_VALUES = values(INTEGER_ATTRIBUTES)
const INTEGER_ATTRIBUTES_VALUES = values(INTEGER_ATTRIBUTES)
"""

open(joinpath(@__DIR__, "..", "src", "attributes_controls.jl"), "w") do f
Expand Down
75 changes: 42 additions & 33 deletions scripts/generate.jl
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
# requires julia 1.6

using Clang

# LIBXPRESS_HEADERS are those headers to be wrapped.
const LIBXPRESS_INCLUDE = joinpath(ENV["XPRESSDIR"], "include") |> expanduser |> normpath
const LIBXPRESS_HEADERS = [
joinpath(LIBXPRESS_INCLUDE, header) for header in [
# "bindrv.h",
# "mmhttp.h",
# "mmquad.h",
# "mmsystem.h",
# "mmxprs.h",
# "mosel_dso.h",
# "mosel_mc.h",
# "mosel_ni.h",
# "mosel_nifct.h",
# "mosel_rt.h",
# "xprb.h",
# "xprb_cpp.h",
# "xprd.h",
# "xprm_mc.h",
# "xprm_ni.h",
# "xprm_rt.h",
# "xprnls.h",
"xprs.h",
# "xprs_mse_defaulthandler.h",
# "XPRSdefaultMipSolEnumHandler.java",
# "xslp.h",
]
]
joinpath(LIBXPRESS_INCLUDE, header) for header in [
# "bindrv.h",
# "mmhttp.h",
# "mmquad.h",
# "mmsystem.h",
# "mmxprs.h",
# "mosel_dso.h",
# "mosel_mc.h",
# "mosel_ni.h",
# "mosel_nifct.h",
# "mosel_rt.h",
# "xprb.h",
# "xprb_cpp.h",
# "xprd.h",
# "xprm_mc.h",
# "xprm_ni.h",
# "xprm_rt.h",
# "xprnls.h",
"xprs.h",
# "xprs_mse_defaulthandler.h",
# "XPRSdefaultMipSolEnumHandler.java",
# "xslp.h",
]
]

wc = init(; headers = LIBXPRESS_HEADERS,
output_file = joinpath(@__DIR__, "../src/lib.jl"),
common_file = joinpath(@__DIR__, "../src/common.jl"),
clang_includes = vcat(LIBXPRESS_INCLUDE, CLANG_INCLUDE),
clang_args = ["-I", joinpath(LIBXPRESS_INCLUDE, "..")],
header_wrapped = (root, current)->root == current,
header_library = x->"libxprs",
clang_diagnostics = true,
)
wc = init(;
headers = LIBXPRESS_HEADERS,
output_file = joinpath(@__DIR__, "../src/lib.jl"),
common_file = joinpath(@__DIR__, "../src/common.jl"),
clang_includes = vcat(LIBXPRESS_INCLUDE, CLANG_INCLUDE),
clang_args = ["-I", joinpath(LIBXPRESS_INCLUDE, "..")],
header_wrapped = (root, current)->root == current,
header_library = x->"libxprs",
clang_diagnostics = true,
)

run(wc)

# # create context
# ctx = create_context(headers, args, options)

# # run generator
# build!(ctx)
Loading

0 comments on commit 9342a69

Please sign in to comment.