Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "MQLib"
uuid = "16f11440-1623-44c9-850c-358a6c72f3c9"
authors = ["pedromxavier <mail@pedro.ϵλ>", "pedroripper <pedroripper@psr-inc.com>"]
authors = ["pedromxavier <mail@pedro.ϵλ>", "pedroripper <pedroripper@psr-inc.com>", "David E. Bernal Neira <dbernaln@purdue.edu>"]
version = "0.4.1"

[deps]
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,9 @@ To list available heuristics and their descriptions, run:
```julia
MQLib.show_heuristics()
```

## Authors

- pedromxavier <mail@pedro.ϵλ>
- pedroripper <pedroripper@psr-inc.com>
- David E. Bernal Neira <dbernaln@purdue.edu>
46 changes: 40 additions & 6 deletions src/MQLib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ import MathOptInterface as MOI

const __VERSION__ = v"0.1.0"
const _HEURISTICS = Dict{String,String}()
const _MQLIB_STDIN = "/dev/stdin"

abstract type _MQLibInput end

struct _MQLibFileInput <: _MQLibInput
file_path::String
end

struct _MQLibStdinInput <: _MQLibInput
data::Vector{UInt8}
file_path::String
end

function __init__()
let exe = MQLib_jll.MQLib()
Expand Down Expand Up @@ -80,17 +92,15 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
)

mktempdir() do temp_path
file_path = joinpath(temp_path, "model.qubo")
input = _mqlib_input(model, joinpath(temp_path, "model.qubo"))

args = _mqlib_args(;
file_path,
file_path = _mqlib_file_path(input),
heuristic,
random_seed,
run_time_limit,
)

QUBOTools.write_model(file_path, model, QUBOTools.Format{:qubo}(; style = :mqlib))

let exe = MQLib_jll.MQLib()
cmd = `$exe $args`

Expand All @@ -99,7 +109,7 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
t = 0.0

for i = 1:num_reads
lines = readlines(cmd)
lines = _mqlib_readlines(cmd, input)
info = split(lines[begin], ',')

λ = parse(T, info[4])
Expand All @@ -125,6 +135,30 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
return QUBOTools.SampleSet{T}(samples, metadata; sense = :max, domain = :bool)
end

function _mqlib_input(model::QUBOTools.AbstractModel, file_path::String)
if _supports_mqlib_stdin()
io = IOBuffer()

QUBOTools.write_model(io, model, QUBOTools.Format{:qubo}(; style = :mqlib))

return _MQLibStdinInput(take!(io), _MQLIB_STDIN)
else
QUBOTools.write_model(file_path, model, QUBOTools.Format{:qubo}(; style = :mqlib))

return _MQLibFileInput(file_path)
end
end

_mqlib_file_path(input::_MQLibInput) = input.file_path

_supports_mqlib_stdin() = Sys.isunix() && ispath(_MQLIB_STDIN)

_mqlib_readlines(cmd::Cmd, input::_MQLibFileInput) = readlines(cmd)

function _mqlib_readlines(cmd::Cmd, input::_MQLibStdinInput)
return readlines(pipeline(cmd; stdin = IOBuffer(input.data)))
end

function _print_header(silent::Bool, heuristic::Union{String,Nothing})
if !silent
heuristic = something(heuristic, "Hyper-Heuristic")
Expand Down Expand Up @@ -220,4 +254,4 @@ function show_heuristics()
return nothing
end

end # module
end # module
40 changes: 40 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
import MQLib
import MQLib: MOI, QUBODrivers
import Test

const QUBOTools = MQLib.QUBOTools

function test_model()
return QUBOTools.Model{Int,Float64,Int}(
Set(1:2),
Dict(1 => 1.0, 2 => -1.0),
Dict((1, 2) => 2.0);
scale = 1.0,
offset = 0.0,
sense = :max,
domain = :bool,
)
end

Test.@testset "MQLib input" begin
model = test_model()
io = IOBuffer()

QUBOTools.write_model(io, model, QUBOTools.Format{:qubo}(; style = :mqlib))

expected = String(take!(io))

mktempdir() do dir
file_path = joinpath(dir, "model.qubo")
input = MQLib._mqlib_input(model, file_path)

if MQLib._supports_mqlib_stdin()
Test.@test input isa MQLib._MQLibStdinInput
Test.@test MQLib._mqlib_file_path(input) == MQLib._MQLIB_STDIN
Test.@test String(copy(input.data)) == expected
Test.@test !isfile(file_path)
else
Test.@test input isa MQLib._MQLibFileInput
Test.@test MQLib._mqlib_file_path(input) == file_path
Test.@test read(file_path, String) == expected
end
end
end

QUBODrivers.test(MQLib.Optimizer) do model
MOI.set(model, MOI.Silent(), true)
Expand Down
Loading