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

Add extension support for PythonCall #2301

Closed
pedromxavier opened this issue Sep 29, 2023 · 10 comments
Closed

Add extension support for PythonCall #2301

pedromxavier opened this issue Sep 29, 2023 · 10 comments

Comments

@pedromxavier
Copy link
Contributor

pedromxavier commented Sep 29, 2023

When building MOI wrappers for Python solvers using PythonCall, it is necessary to implement

MOIU.map_indices(::Function, x::PythonCall.Py) = x

for Python objects to be accepted in the MOI attribute system.

A possible solution, to avoid type piracy, is for MOI to have a PythonCall extension.

@odow
Copy link
Member

odow commented Sep 29, 2023

Do you have an example of this? It's a trivial method so I don't think piracy is the end of the world.

But you could probably refactor the solver one your end.

@pedromxavier
Copy link
Contributor Author

https://github.com/psrenergy/QiskitOpt.jl/blob/c71c79f4380ebdd19cade93c9555c93541c70cf0/src/QAOA.jl#L30-L32

The lines above are passed into the QUBODrivers.jl.@setup macro that basically generates MOI.get|set|support boilerplate.

Packages as QiskitOpt.jl and DWave.jl rely on Python APIs for connecting to solvers in the cloud.
Part of their configuration is given by attributes whose values are Python objects.

This method has to be implemented for both QiskitOpt.jl and DWave.jl, which leads the compiler to complain about it.

A solution would be for QUBODrivers to have an extension to implement this method when PythonCall is loaded (since it already depends on MOI).

@odow
Copy link
Member

odow commented Sep 29, 2023

Instead of

ClassicalOptimizer["optimizer"]            = qiskit_algorithms.optimizers.COBYLA

do something like

struct MyPythonCallWrapper{T}
    data::T
end
MOIU.map_indices(::Function, x:: MyPythonCallWrapper) = x

ClassicalOptimizer["optimizer"]            = MyPythonCallWrapper(qiskit_algorithms.optimizers.COBYLA)

This is something that can/should be worked around in QiskitOpt.jl, not in MOI.

I don't really want to create an extension just to add this single method for PythonCall.

@pedromxavier
Copy link
Contributor Author

I agree with you that a wrapper is the best way to go. This will have to be fixed at QUBODrivers level, since some other projects use it to reach out to Python too.

I think your suggestion is sufficient to close the issue.

@odow
Copy link
Member

odow commented Sep 29, 2023

I think you're also okay to add MOIU.map_indices(::Function, x::PythonCall.Py) = x, if you accept a very minor risk that QiskitOpt might conflict with some other hypothetical package (although they'll likely just implement the exact same method...)

@pedromxavier
Copy link
Contributor Author

As far as I understood, MOIU.map_indices gets called after returning from MOI.get. This means that even if I'm able to create a wrapper for one of those values for it to pass through map_indices, I will not be able to unwrap the value before it reaches the user, right?

@odow
Copy link
Member

odow commented Sep 30, 2023

I don't really understand the macro, but yes, you'd need the user to pass something like QiskitOpt.Algorithm(qiskit_algorithms.optimizers.COBYLA) and then on the return, they'd need to interact with QiskitOpt.Algorithm, not qiskit_algorithms.optimizers.COBYLA.

I wouldn't have a generic wrapper, I'd perhaps make one for each attribute.

@odow
Copy link
Member

odow commented Sep 30, 2023

But in the near term, just be a 🏴‍☠️

@pedromxavier
Copy link
Contributor Author

Ahoy! 🏴‍☠️

@odow
Copy link
Member

odow commented Oct 3, 2023

Closing this as won't-fix.

@odow odow closed this as completed Oct 3, 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

2 participants