Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Variables and other fixes #13

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
16 changes: 9 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
name = "QUBODrivers"
uuid = "a3f166f7-2cd3-47b6-9e1e-6fbfe0449eb0"
authors = ["pedromxavier <mail@pedro.ϵλ>", "pedroripper <[email protected]>", "AndradeTiago <[email protected]>", "joaquimg <[email protected]>", "bernalde <[email protected]>"]
version = "0.3.3"
version = "0.3.4-dev"

[deps]
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
QUBOTools = "60eb5b62-0a39-4ddc-84c5-97d2adff9319"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
QUBOTools = "60eb5b62-0a39-4ddc-84c5-97d2adff9319"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[weakdeps]
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"

Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[extensions]
MOI_PythonCall = ["PythonCall"]
QUBODrivers_Test_Ext = ["Test"]
MOI_PythonCall_Ext = ["PythonCall"]

[compat]
MathOptInterface = "1"
PythonCall = "0.9"
QUBOTools = "0.10"
Test = "1"
julia = "1.9"
4 changes: 2 additions & 2 deletions ext/MOI_PythonCall.jl → ext/MOI_PythonCall_Ext.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module MOI_PythonCall
module MOI_PythonCall_Ext

import MathOptInterface as MOI
import PythonCall

if !hasmethod(MOI.Utilities.map_indices, Tuple{PythonCall.Py})
if !hasmethod(MOI.Utilities.map_indices, Tuple{<:Function,PythonCall.Py})
MOI.Utilities.map_indices(::Function, obj::PythonCall.Py) = obj
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
module QUBODrivers_Test_Ext

import Test
import QUBODrivers
import MathOptInterface as MOI

const VI = MOI.VariableIndex
const SAF{T} = MOI.ScalarAffineFunction{T}
const SQF{T} = MOI.ScalarQuadraticFunction{T}

# Interface Tests
include("interface/moi.jl")
include("interface/automatic.jl")

# Example Tests
include("examples/examples.jl")

@doc raw"""
test(optimizer::Type{S}; examples::Bool=false) where {S<:AbstractSampler}
test(config!::Function, optimizer::Type{S}; examples::Bool=false) where {S<:AbstractSampler}
"""
function test end

function QUBODrivers.test(::Type{S}; examples::Bool = true) where {S<:AbstractSampler}
function QUBODrivers.test(::Type{S}; examples::Bool = true) where {S<:QUBODrivers.AbstractSampler}
QUBODrivers.test(identity, S; examples)

return nothing
Expand All @@ -21,7 +25,7 @@ function QUBODrivers.test(
config!::Function,
::Type{S};
examples::Bool = true,
) where {S<:AbstractSampler}
) where {S<:QUBODrivers.AbstractSampler}
QUBODrivers.test(config!, S{Float64}; examples)

return nothing
Expand All @@ -31,13 +35,13 @@ function QUBODrivers.test(
config!::Function,
::Type{S};
examples::Bool = true,
) where {T,S<:AbstractSampler{T}}
solver = S()
) where {T,S<:QUBODrivers.AbstractSampler{T}}
sampler = S()

solver_name = MOI.get(solver, MOI.SolverName())
solver_version = MOI.get(solver, MOI.SolverVersion())
sampler_name = MOI.get(sampler, MOI.SolverName())
sampler_version = MOI.get(sampler, MOI.SolverVersion())

Test.@testset "☢ QUBODrivers' Test Suite for «$(solver_name) v$(solver_version)» ☢" verbose = true begin
Test.@testset "☢ QUBODrivers' Test Suite for «$(sampler_name) v$(sampler_version)» ☢" verbose = true begin
Test.@testset "→ Interface" begin
_test_moi_interface(config!, S)
_test_automatic_interface(config!, S)
Expand All @@ -49,4 +53,6 @@ function QUBODrivers.test(
end

return nothing
end

end
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ function _test_basic_bool_min(
sampler::Type{S},
n::Integer,
Q::Matrix{T},
) where {T,S<:AbstractSampler{T}}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "▷ Bool ⋄ Min" begin
model = MOI.instantiate(sampler; with_bridge_type = T)

Expand Down Expand Up @@ -52,7 +52,7 @@ function _test_basic_bool_max(
sampler::Type{S},
n::Integer,
Q::Matrix{T},
) where {T,S<:AbstractSampler{T}}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "▷ Bool ⋄ Max" begin
model = MOI.instantiate(sampler; with_bridge_type = T)

Expand Down Expand Up @@ -102,7 +102,7 @@ function _test_basic_spin_min(
n::Integer,
h::Vector{T},
J::Matrix{T},
) where {T,S<:AbstractSampler{T}}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "▷ Spin ⋄ Min" begin
# Build Model
model = MOI.instantiate(sampler; with_bridge_type = T)
Expand Down Expand Up @@ -153,7 +153,7 @@ function _test_basic_spin_max(
n::Integer,
h::Vector{T},
J::Matrix{T},
) where {T,S<:AbstractSampler{T}}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "▷ Spin ⋄ Max" begin
# Build Model
model = MOI.instantiate(sampler; with_bridge_type = T)
Expand Down Expand Up @@ -205,7 +205,7 @@ function _test_basic_spin_min_and_max(
n::Integer,
h::Vector{T},
J::Matrix{T},
) where {T,S<:AbstractSampler{T}}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "▷ Spin ⋄ Min and Max" begin
# Build Model
model = MOI.instantiate(sampler; with_bridge_type = T)
Expand Down Expand Up @@ -287,7 +287,7 @@ end
function _test_basic_examples(
config!::Function,
sampler::Type{S},
) where {T,S<:AbstractSampler{T}}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "⊚ Basic ⊚" verbose = true begin
# Problem size
n = 3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
raw"""
_test_corner_blanks(config!::Function, sampler::Type{S}) where {S<:AbstractSampler}
_test_corner_blanks(config!::Function, sampler::Type{S}) where {S<:QUBODrivers.AbstractSampler}

This test case probes problems with blanks in the objective function.
Some solvers will only return answers for variables present in the expression[^QUBODrivers#6].
Expand All @@ -20,18 +20,20 @@ Some solvers will only return answers for variables present in the expression[^Q
function _test_corner_blanks(
config!::Function,
sampler::Type{S},
) where {T,S<:AbstractSampler{T}}
@testset "Blanks" begin
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "Blanks" begin
# Build Model
model = MOI.instantiate(sampler; with_bridge_type = T)

c = [1, 1]
i = [1, 3]
x, _ = MOI.add_constrained_variables(model, fill(MOI.ZeroOne(), 3))

MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)
MOI.set(
model,
MOI.ObjectiveFunction{SAF{T}}(),
SAF{T}(SAT{T}[SAT{T}(one(T), x[1]), SAT{T}(one(T), x[3])], zero(T)),
x[i]' * c,
)

config!(model)
Expand All @@ -45,7 +47,7 @@ end
function _test_corner_examples(
config!::Function,
sampler::Type{S},
) where {S<:AbstractSampler}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "⊚ Corner cases ⊚" begin
_test_corner_blanks(config!, sampler)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
include("basic.jl")
include("corner.jl")
include("fixed.jl")

function _test_examples(
config!::Function,
sampler::Type{S},
) where {S<:AbstractSampler}
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "→ Examples" begin
_test_basic_examples(config!, sampler)
_test_corner_examples(config!, sampler)
_test_fixed_variables(config!, sampler)
end

return nothing
Expand Down
39 changes: 39 additions & 0 deletions ext/QUBODrivers_Test_Ext/examples/fixed.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
raw"""
"""
function _test_fixed_variables(
config!::Function,
sampler::Type{S},
) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "Fixed Variables" begin
model = MOI.instantiate(sampler; with_bridge_type = T)

Q = T[1 2 3; 0 4 5; 0 0 6]
x, _ = MOI.add_constrained_variables(model, fill(MOI.ZeroOne, 3))

MOI.set(
model,
MOI.ObjectiveSense(),
MOI.MIN_SENSE,
)

MOI.set(
model,
MOI.ObjectiveFunction{SQF{T}}(),
x' * Q * x,
)

MOI.add_constraint(model, x[2], MOI.EqualTo(one(T)))

config!(model)

MOI.optimize!(model)

Test.@test MOI.get(model, MOI.ResultCount()) > 0

for ri = 1:MOI.get(model, MOI.ResultCount())
Test.@test MOI.get(model, MOI.VariablePrimal(ri)) |> isone
end
end

return nothing
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
function _test_automatic_interface(::Function, ::Type{S}) where {S<:AbstractSampler}
function _test_automatic_interface(::Function, ::Type{S}) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "QUBODrivers (Automatic)" verbose = true begin
Test.@test hasmethod(QUBODrivers.sample, (S,))
end

return nothing
end
48 changes: 48 additions & 0 deletions ext/QUBODrivers_Test_Ext/interface/moi.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function _test_moi_interface(config!::Function, ::Type{S}) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "MOI" verbose = true begin
Test.@testset "`optimize!` Interface" begin
# Emptiness
Test.@test hasmethod(MOI.empty!, (S,))
Test.@test hasmethod(MOI.is_empty, (S,))
# Optimize! / Copy-To
Test.@test hasmethod(MOI.optimize!, (S,)) && hasmethod(MOI.copy_to, (S, MOI.ModelLike)) ||
hasmethod(MOI.optimize!, (S, MOI.ModelLike))
end

_test_moi_interface_instantiate(config!, S)

_test_moi_interface_attributes(config!, S)
end

return nothing
end

function _test_moi_interface_instantiate(config!::Function, ::Type{S}) where {T,S<:QUBODrivers.AbstractSampler{T}}
let sampler = S()
config!(sampler)

Test.@test true
end

return nothing
end

function _test_moi_interface_attributes(config!::Function, ::Type{S}) where {T,S<:QUBODrivers.AbstractSampler{T}}
Test.@testset "Attributes" begin
# Basic Attributes
Test.@test hasmethod(MOI.get, (S, MOI.SolverName))
Test.@test hasmethod(MOI.get, (S, MOI.SolverVersion))
Test.@test hasmethod(MOI.get, (S, MOI.RawSolver))

Test.@testset "Attribute Access" begin
let sampler = S()
config!(sampler)

Test.@test MOI.get(sampler, MOI.SolverName()) isa AbstractString
Test.@test MOI.get(sampler, MOI.SolverVersion()) isa VersionNumber
end
end
end

return nothing
end
43 changes: 7 additions & 36 deletions src/QUBODrivers.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module QUBODrivers

using Test
using MathOptInterface
const MOI = MathOptInterface
import TOML
import MathOptInterface as MOI

const MOIU = MOI.Utilities
const MOIB = MOI.Bridges
const VI = MOI.VariableIndex
const SAF{T} = MOI.ScalarAffineFunction{T}
const SAT{T} = MOI.ScalarAffineTerm{T}
Expand All @@ -14,54 +15,24 @@ using QUBOTools
const QUBOTools_MOI = Base.get_extension(QUBOTools, :QUBOTools_MOI)
const Spin = QUBOTools_MOI.Spin

import TOML

const __PROJECT__ = Ref{Union{String,Nothing}}(nothing)

function __project__()
if isnothing(__PROJECT__[])
proj_path = abspath(dirname(@__DIR__))

@assert isdir(proj_path)

__PROJECT__[] = proj_path
end

return __PROJECT__[]::String
end

const __VERSION__ = Ref{Union{VersionNumber,Nothing}}(nothing)

function __version__()::VersionNumber
if isnothing(__VERSION__[])
proj_file_path = abspath(__project__(), "Project.toml")

@assert isfile(proj_file_path)

proj_file_data = TOML.parsefile(proj_file_path)

__VERSION__[] = VersionNumber(proj_file_data["version"])
end

return __VERSION__[]::VersionNumber
end
include("projectversion.jl")

export MOI, Sample, SampleSet, Spin, ↓, ↑

include("interface/sampler.jl")
include("interface/attributes.jl")
include("interface/test.jl")

include("library/sampler/wrappers/moi.jl")
include("library/sampler/wrappers/qubotools.jl")

include("library/test/test.jl")

include("library/setup/error.jl")
include("library/setup/specs.jl")
include("library/setup/parse.jl")
include("library/setup/quote.jl")
include("library/setup/macro.jl")

export AbstractSampler
export ExactSampler, IdentitySampler, RandomSampler

include("library/drivers/ExactSampler.jl")
Expand Down
5 changes: 5 additions & 0 deletions src/interface/test.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@doc raw"""
test(optimizer::Type{S}; examples::Bool=false) where {S<:AbstractSampler}
test(config!::Function, optimizer::Type{S}; examples::Bool=false) where {S<:AbstractSampler}
"""
function test end
Loading
Loading