From 92625d72630dd98e03832dbed5b743beabb12571 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Xavier Date: Wed, 5 Mar 2025 10:27:47 -0500 Subject: [PATCH] Add tests for fixed variables --- Project.toml | 16 +++--- ...OI_PythonCall.jl => MOI_PythonCall_Ext.jl} | 4 +- .../QUBODrivers_Test_Ext.jl | 32 +++++++----- .../QUBODrivers_Test_Ext}/examples/basic.jl | 12 ++--- .../QUBODrivers_Test_Ext}/examples/corner.jl | 12 +++-- .../examples/examples.jl | 4 +- ext/QUBODrivers_Test_Ext/examples/fixed.jl | 39 ++++++++++++++ .../interface/automatic.jl | 4 +- ext/QUBODrivers_Test_Ext/interface/moi.jl | 48 +++++++++++++++++ src/QUBODrivers.jl | 43 +++------------ src/interface/test.jl | 5 ++ src/library/sampler/wrappers/moi.jl | 52 +++++++++++++------ src/library/test/interface/moi.jl | 20 ------- src/projectversion.jl | 29 +++++++++++ test/Project.toml | 3 -- test/runtests.jl | 2 +- 16 files changed, 214 insertions(+), 111 deletions(-) rename ext/{MOI_PythonCall.jl => MOI_PythonCall_Ext.jl} (60%) rename src/library/test/test.jl => ext/QUBODrivers_Test_Ext/QUBODrivers_Test_Ext.jl (56%) rename {src/library/test => ext/QUBODrivers_Test_Ext}/examples/basic.jl (97%) rename {src/library/test => ext/QUBODrivers_Test_Ext}/examples/corner.jl (84%) rename {src/library/test => ext/QUBODrivers_Test_Ext}/examples/examples.jl (71%) create mode 100644 ext/QUBODrivers_Test_Ext/examples/fixed.jl rename {src/library/test => ext/QUBODrivers_Test_Ext}/interface/automatic.jl (77%) create mode 100644 ext/QUBODrivers_Test_Ext/interface/moi.jl create mode 100644 src/interface/test.jl delete mode 100644 src/library/test/interface/moi.jl create mode 100644 src/projectversion.jl diff --git a/Project.toml b/Project.toml index a366bb3..8fa0d34 100644 --- a/Project.toml +++ b/Project.toml @@ -1,23 +1,25 @@ name = "QUBODrivers" uuid = "a3f166f7-2cd3-47b6-9e1e-6fbfe0449eb0" authors = ["pedromxavier ", "pedroripper ", "AndradeTiago ", "joaquimg ", "bernalde "] -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" diff --git a/ext/MOI_PythonCall.jl b/ext/MOI_PythonCall_Ext.jl similarity index 60% rename from ext/MOI_PythonCall.jl rename to ext/MOI_PythonCall_Ext.jl index 23cf423..268ca54 100644 --- a/ext/MOI_PythonCall.jl +++ b/ext/MOI_PythonCall_Ext.jl @@ -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 diff --git a/src/library/test/test.jl b/ext/QUBODrivers_Test_Ext/QUBODrivers_Test_Ext.jl similarity index 56% rename from src/library/test/test.jl rename to ext/QUBODrivers_Test_Ext/QUBODrivers_Test_Ext.jl index e56c5aa..594c8f0 100644 --- a/src/library/test/test.jl +++ b/ext/QUBODrivers_Test_Ext/QUBODrivers_Test_Ext.jl @@ -1,3 +1,13 @@ +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") @@ -5,13 +15,7 @@ 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 @@ -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 @@ -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) @@ -49,4 +53,6 @@ function QUBODrivers.test( end return nothing +end + end \ No newline at end of file diff --git a/src/library/test/examples/basic.jl b/ext/QUBODrivers_Test_Ext/examples/basic.jl similarity index 97% rename from src/library/test/examples/basic.jl rename to ext/QUBODrivers_Test_Ext/examples/basic.jl index cd36007..c4e425b 100644 --- a/src/library/test/examples/basic.jl +++ b/ext/QUBODrivers_Test_Ext/examples/basic.jl @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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 diff --git a/src/library/test/examples/corner.jl b/ext/QUBODrivers_Test_Ext/examples/corner.jl similarity index 84% rename from src/library/test/examples/corner.jl rename to ext/QUBODrivers_Test_Ext/examples/corner.jl index e971040..9e52ac5 100644 --- a/src/library/test/examples/corner.jl +++ b/ext/QUBODrivers_Test_Ext/examples/corner.jl @@ -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]. @@ -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) @@ -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 diff --git a/src/library/test/examples/examples.jl b/ext/QUBODrivers_Test_Ext/examples/examples.jl similarity index 71% rename from src/library/test/examples/examples.jl rename to ext/QUBODrivers_Test_Ext/examples/examples.jl index aefd346..b586ec1 100644 --- a/src/library/test/examples/examples.jl +++ b/ext/QUBODrivers_Test_Ext/examples/examples.jl @@ -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 diff --git a/ext/QUBODrivers_Test_Ext/examples/fixed.jl b/ext/QUBODrivers_Test_Ext/examples/fixed.jl new file mode 100644 index 0000000..9b1cd78 --- /dev/null +++ b/ext/QUBODrivers_Test_Ext/examples/fixed.jl @@ -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 diff --git a/src/library/test/interface/automatic.jl b/ext/QUBODrivers_Test_Ext/interface/automatic.jl similarity index 77% rename from src/library/test/interface/automatic.jl rename to ext/QUBODrivers_Test_Ext/interface/automatic.jl index 87656e3..737ad7d 100644 --- a/src/library/test/interface/automatic.jl +++ b/ext/QUBODrivers_Test_Ext/interface/automatic.jl @@ -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 \ No newline at end of file diff --git a/ext/QUBODrivers_Test_Ext/interface/moi.jl b/ext/QUBODrivers_Test_Ext/interface/moi.jl new file mode 100644 index 0000000..d821968 --- /dev/null +++ b/ext/QUBODrivers_Test_Ext/interface/moi.jl @@ -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 diff --git a/src/QUBODrivers.jl b/src/QUBODrivers.jl index 81cfb51..12405fd 100644 --- a/src/QUBODrivers.jl +++ b/src/QUBODrivers.jl @@ -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} @@ -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") diff --git a/src/interface/test.jl b/src/interface/test.jl new file mode 100644 index 0000000..fcad94c --- /dev/null +++ b/src/interface/test.jl @@ -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 \ No newline at end of file diff --git a/src/library/sampler/wrappers/moi.jl b/src/library/sampler/wrappers/moi.jl index 233c8db..4208cbc 100644 --- a/src/library/sampler/wrappers/moi.jl +++ b/src/library/sampler/wrappers/moi.jl @@ -6,14 +6,14 @@ MOI.supports_constraint( ) = false # ~ They are also binary -MOI.supports_constraint(::AbstractSampler, ::Type{VI}, ::Type{MOI.ZeroOne}) = true +MOI.supports_constraint(::AbstractSampler{T}, ::Type{VI}, ::Type{MOI.ZeroOne}) where {T} = true -MOI.supports_constraint(::AbstractSampler, ::Type{VI}, ::Type{Spin}) = true +MOI.supports_constraint(::AbstractSampler{T}, ::Type{VI}, ::Type{Spin}) where {T} = true # ~ Objective Function Support -MOI.supports(::AbstractSampler, ::MOI.ObjectiveFunction{<:Any}) = false +MOI.supports(::AbstractSampler{T}, ::MOI.ObjectiveFunction{<:Any}) where {T} = false -MOI.supports(::AbstractSampler, ::MOI.ObjectiveSense) = true +MOI.supports(::AbstractSampler{T}, ::MOI.ObjectiveSense) where {T} = true MOI.supports( ::AbstractSampler{T}, @@ -21,10 +21,10 @@ MOI.supports( ) where {T} = true # By default, all samplers are their own raw solvers. -MOI.get(sampler::AbstractSampler, ::MOI.RawSolver) = sampler +MOI.get(sampler::AbstractSampler{T}, ::MOI.RawSolver) where {T} = sampler # Since problems are unconstrained, all available solutions are feasible. -function MOI.get(sampler::AbstractSampler, ps::MOI.PrimalStatus) +function MOI.get(sampler::AbstractSampler{T}, ps::MOI.PrimalStatus) where {T} m = MOI.get(sampler, MOI.ResultCount()) i = ps.result_index @@ -36,7 +36,7 @@ function MOI.get(sampler::AbstractSampler, ps::MOI.PrimalStatus) end # No constraints, no dual solutions -MOI.get(::AbstractSampler, ::MOI.DualStatus) = MOI.NO_SOLUTION +MOI.get(::AbstractSampler{T}, ::MOI.DualStatus) where {T} = MOI.NO_SOLUTION # ~*~ :: MathOptInterface :: ~*~ # @@ -46,11 +46,11 @@ function MOI.empty!(sampler::AbstractSampler{T}) where {T} return sampler end -function MOI.is_empty(sampler::AbstractSampler) +function MOI.is_empty(sampler::AbstractSampler{T}) where {T} return isempty(QUBOTools.backend(sampler)) end -function MOI.optimize!(sampler::AbstractSampler) +function MOI.optimize!(sampler::AbstractSampler{T}) where {T} return _sample!(sampler) end @@ -67,7 +67,7 @@ function MOI.copy_to(sampler::AbstractSampler{T}, src::MOI.ModelLike) where {T} return MOIU.identity_index_map(src) end -function MOI.get(sampler::AbstractSampler, ::MOI.RawStatusString) +function MOI.get(sampler::AbstractSampler{T}, ::MOI.RawStatusString) where {T} solution_metadata = QUBOTools.metadata(QUBOTools.solution(sampler)) if !haskey(solution_metadata, "status") @@ -77,13 +77,13 @@ function MOI.get(sampler::AbstractSampler, ::MOI.RawStatusString) end end -MOI.supports(::AbstractSampler, ::MOI.RawStatusString) = true +MOI.supports(::AbstractSampler{T}, ::MOI.RawStatusString) where {T} = true -function MOI.get(sampler::AbstractSampler, ::MOI.ResultCount) +function MOI.get(sampler::AbstractSampler{T}, ::MOI.ResultCount) where {T} return length(QUBOTools.solution(sampler)) end -function MOI.get(sampler::AbstractSampler, ::MOI.TerminationStatus) +function MOI.get(sampler::AbstractSampler{T}, ::MOI.TerminationStatus) where {T} ω = QUBOTools.solution(sampler) if isempty(ω) @@ -110,7 +110,7 @@ function MOI.get(sampler::AbstractSampler{T}, ::MOI.ObjectiveSense) where {T} end end -function MOI.get(sampler::AbstractSampler, ov::MOI.ObjectiveValue) +function MOI.get(sampler::AbstractSampler{T}, ov::MOI.ObjectiveValue) where {T} i = ov.result_index ω = QUBOTools.solution(sampler) m = length(ω) @@ -124,7 +124,7 @@ function MOI.get(sampler::AbstractSampler, ov::MOI.ObjectiveValue) return QUBOTools.value(ω, i) end -function MOI.get(sampler::AbstractSampler, ::MOI.SolveTimeSec) +function MOI.get(sampler::AbstractSampler{T}, ::MOI.SolveTimeSec) where {T} return QUBOTools.effective_time(QUBOTools.solution(sampler)) end @@ -145,6 +145,26 @@ function MOI.get(sampler::AbstractSampler{T}, vp::MOI.VariablePrimal, vi::VI) wh return convert(T, s) end -function MOI.get(sampler::AbstractSampler, ::MOI.NumberOfVariables) +function MOI.get(sampler::AbstractSampler{T}, ::MOI.NumberOfVariables) where {T} return QUBOTools.dimension(sampler) end + +function MOI.get(sampler::AbstractSampler{T}, ::MOI.ListOfConstraintTypesPresent) where {T} + if iszero(MOI.get(sampler, MOI.NumberOfVariables())) + return [] + end + + if QUBOTools.domain(sampler) === QUBOTools.BoolDomain + return [(VI, MOI.ZeroOne)] + else # QUBOTools.domain(sampler) === QUBOTools.SpinDomain + return [(VI, Spin)] + end +end + +function MOI.get(sampler::AbstractSampler{T}, ::MOI.ListOfVariableIndices) where {T} + return Vector{VI}(QUBOTools.variables(sampler)) +end + +function MOI.supports(sampler::AbstractSampler{T}, ::MOIB.ListOfNonstandardBridges{T}) where {T} + return false +end diff --git a/src/library/test/interface/moi.jl b/src/library/test/interface/moi.jl deleted file mode 100644 index 4e58ed4..0000000 --- a/src/library/test/interface/moi.jl +++ /dev/null @@ -1,20 +0,0 @@ -function _test_moi_interface(::Function, ::Type{S}) where {S<:AbstractSampler} - 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,)) - # Copy-To - Test.@test hasmethod(MOI.copy_to, (S, MOI.ModelLike)) - # Optimize! - Test.@test hasmethod(MOI.optimize!, (S,)) || hasmethod(MOI.optimize!, (S, MOI.ModelLike)) - end - - 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)) - end - end -end \ No newline at end of file diff --git a/src/projectversion.jl b/src/projectversion.jl new file mode 100644 index 0000000..ce0b26e --- /dev/null +++ b/src/projectversion.jl @@ -0,0 +1,29 @@ +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 diff --git a/test/Project.toml b/test/Project.toml index 7ca82a5..035fad3 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,6 +1,3 @@ [deps] PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -PythonCall = "0.9.23" diff --git a/test/runtests.jl b/test/runtests.jl index 19ff246..762f731 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,8 +16,8 @@ include("ext/ext.jl") function main() @testset "◈ ◈ ◈ QUBODrivers.jl Test Suite ◈ ◈ ◈" verbose = true begin test_setup_macro() - test_sampler_bundle() test_extensions() + test_sampler_bundle() end return nothing