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

MOI.get on attribute where is_set_by_optimizer = true and TerminationStatus = OPTIMIZE_NOT_CALLED #2352

Closed
pedromxavier opened this issue Nov 20, 2023 · 7 comments

Comments

@pedromxavier
Copy link
Contributor

On the series of querying attributes with our meta-solver/reformulator I encountered a corner case when retrieving attributes after reformulation without an inner optimizer.

Basically, we have an operation mode in psrenergy/ToQUBO.jl where a call to optimize! without an optimizer will just reformulate the problem to the QUBO form, e.g.,

model = Model(ToQUBO.Optimizer)
...
optimize!(model)

instead of the usual

model = Model(
    () -> ToQUBO.Optimizer(QuantumSolver.Optimizer)
)
...
optimize!(model) # Returns termination status from `QuantumSolver`

The problem is that the OPTIMIZE_NOT_CALLED status prevents attribute retrieval for cases where is_set_by_optimizer = true.

I couldn't find any other suitable status for this case besides OTHER_ERROR which is kind of misleading since there was no error to begin with.

Note: Using optimize! is not necessary, we could be using something like reformulate! or compile! but this makes no big difference in the issue.

@odow
Copy link
Member

odow commented Nov 20, 2023

I don't know if I fully understand the issue. Do you have a reproducible example? What attribute do you want to query if the problem hasn't been set?

If you don't call optimize!, then by definition you can't query attributes that is_set_by_optimizer = true.

If you want ToQUBO.Optimizer to reformulate the problem on optimize! and make some attributes available, then it should implement MOI.optimize! and return an appropriate termination status. I guess you could use LOCALLY_SOLVED?

@pedromxavier
Copy link
Contributor Author

pedromxavier commented Nov 21, 2023

I think the question boils down to choosing the appropriate status. The problem I see with LOCALLY_SOLVED is that there will be no solutions available. Is it enough to set ResultCount = 0 and NO_SOLUTION for PrimalStatus and DualStatus?

OTHER_LIMIT seems be a good wildcard for this.

PS: An example would look like:

# Create the model
model = Model(
    # Use ToQUBO in compilation mode
    () -> ToQUBO.Optimizer(nothing)
)

# Add the variables
@variable(model, 0 <= x[1:2] <= 1)
# Add the objective
@objective(model, Min, sum(x .^ 2))

# Add the global constraint
@constraint(model, alpha, sum(x) >= 0.5)

# Compile the QUBO model
optimize!(model)

get_attribute(alpha, ToQUBO.Attributes.ConstraintEncodingPenalty()) # Error!

@odow
Copy link
Member

odow commented Nov 21, 2023

Is it enough to set ResultCount = 0 and NO_SOLUTION for PrimalStatus and DualStatus?

Yes, this should work.

@blegat
Copy link
Member

blegat commented Nov 21, 2023

I couldn't find any other suitable status for this case besides OTHER_ERROR which is kind of misleading since there was no error to begin with.

You could also consider that the error is that there was no solver attached. I think it's more important to have the RawStatusString detail clearly what happens so that solution_summary is clear and the user that forgot to give an optimizer is not confused.

@odow
Copy link
Member

odow commented Nov 21, 2023

Is there anything actionable left to do here? This seems like it can be fixed in ToQUBO, not in MOI.

@pedromxavier
Copy link
Contributor Author

@odow I think this is indeed very specific to our use case, so I don't think it's even something that is missing from the docs. Maybe, for ToQUBO and other reformulators/meta-solvers a REFORMULATION_COMPLETE or REFORMULATION_ONLY status would be the best fit, ideally speaking.

And yes, the question was answered and this issue looks ready to be closed, thanks!

@odow
Copy link
Member

odow commented Nov 21, 2023

I think LOCALLY_SOLVED + NO_RESULT + an informative description in RawStatusString is enough. The solver terminated normally, and it did not find a primal solution.

@odow odow closed this as completed Nov 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants