Skip to content

Xopt integration#318

Open
roussel-ryan wants to merge 14 commits into
bluesky:mainfrom
roussel-ryan:xopt
Open

Xopt integration#318
roussel-ryan wants to merge 14 commits into
bluesky:mainfrom
roussel-ryan:xopt

Conversation

@roussel-ryan

Copy link
Copy Markdown

This pull request adds support for integrating the Xopt optimization library into blop, introducing a new agent, optimizer, and mapping utilities, along with comprehensive tests for these components. The changes enable users to use Xopt Generator objects within the existing framework, and ensure robust mapping and interaction between the framework's abstractions and Xopt's API.

This PR should serve as a starting point for discussing Xopt integration into blop or bluesky-adaptive (bluesky/bluesky-adaptive#61).

The most important changes are:

Xopt Integration:

  • Added XoptAgent, XoptOptimizer, and build_vocs to the codebase, providing a new agent and optimizer that wrap Xopt generators and a utility for mapping framework abstractions to Xopt's VOCS format (src/blop/xopt/agent.py, src/blop/xopt/optimizer.py, src/blop/xopt/mapping.py, src/blop/xopt/__init__.py). [1] [2]

  • Made the new Xopt components available at the top-level API by importing them in src/blop/__init__.py and adding them to __all__. [1] [2]

Dependency Management:

  • Added xopt as an optional dependency in pyproject.toml to enable Xopt-based optimization.

Testing and Validation:

  • Added comprehensive tests for the Xopt agent (test_agent.py), optimizer (test_optimizer.py), and VOCS mapping (test_mapping.py), covering initialization, suggestion, ingestion, checkpointing, constraint handling, and error cases. [1] [2] [3]

@checkmarx-gh-ast-us-povs

checkmarx-gh-ast-us-povs Bot commented Jun 4, 2026

Copy link
Copy Markdown

Logo
Checkmarx One – Scan Summary & Details865454f0-2a60-49a8-82d0-634324cdb856


New Issues (1) Checkmarx found the following issues in this Pull Request
# Severity Issue Source File / Package Checkmarx Insight
1 HIGH Deserialization_of_Untrusted_Data src/blop/xopt/optimizer.py: 49
detailsThe serialized object stream processed in  in the file /src/blop/xopt/optimizer.py at line 49 is deserialized by load in the file /src/blop/xopt/o...
ID: rrz2NO86clojLL1mHn8JwmtiXOE%3D
Attack Vector

Communicate with Checkmarx by submitting a PR comment with @Checkmarx followed by one of the supported commands. Learn about the supported commands here.

Comment thread src/blop/xopt/mapping.py Outdated
if isinstance(dof, RangeDOF):
variables[dof.parameter_name] = [float(dof.bounds[0]), float(dof.bounds[1])]
elif isinstance(dof, ChoiceDOF):
# Keep scope explicit: only numeric choices map cleanly to current VOCS variable model.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that future development on the Xopt side will include discrete variables, see xopt-org/Xopt#421

@roussel-ryan

Copy link
Copy Markdown
Author

Note: after discussion, I will refactor this PR to not do automatic conversion to VOCS parlance and just pass the generator object to an optimizer

@roussel-ryan

roussel-ryan commented Jun 5, 2026

Copy link
Copy Markdown
Author

@thopkins32 so it looks like we need to make a decision since the more recent versions of botorch (.v0.17.0) require python >=3.11 meaning that Xopt does the same, how do you think we should resolve this? I could potentially re-enable support 3.10, but only if this is something you all think is necessary

@thopkins32

Copy link
Copy Markdown
Collaborator

@roussel-ryan I will open a separate issue to remove Python 3.10 support, feel free to do that in this PR for now to unblock

@whs92

whs92 commented Jun 6, 2026

Copy link
Copy Markdown
Member

Can you give a quick overview of the advantages of using Xopt over AX? Why might I use one or the other? Or is there just an existing community using Xopt that we want to serve?

@roussel-ryan

roussel-ryan commented Jun 7, 2026

Copy link
Copy Markdown
Author

Hi, there are several advantages to using Xopt over Ax for blop, primarily due to our focus on R&D towards accelerator / beam physics, however we do not intend to replace Ax completely. Some of the reasons:

  • Xopt supports other optimization algorithms that can be used for online operation / optimization including Simplex, RCDS, Extremum Seeking, Genetic algorithms, and multiple variants of BO (most based on botorch, just as Ax is). We will shortly be adding methods for Reinforcement Learning and algorithms provided by scipy minimize
  • We have added features to BO that are not included out of the box in Ax as it is currently implemented in blop, including first class support for trust region BO, time-dependent / contextual BO, multi-fidelity BO, interpolated measurements etc. (see https://journals.aps.org/prab/abstract/10.1103/PhysRevAccelBeams.27.084801)
  • Xopt is wrapped by Badger https://github.com/xopt-org/Badger which provides a GUI interface for running optimization in control rooms. Utilizing Xopt generators in blop takes a step forward for creating a GUI that works for blop
  • The same algorithms provided by Xopt used in online control via blop can be easily applied towards simulations and arbitrary problems, improving consistent use of algorithms across problems for users

Finally, supporting Xopt in blop more closely connects R&D efforts in accelerators and photon beamlines, allowing developments in one field to benefit the other. This PR is motivated by discussions this past week at the DSSI workshop for autonomous beamline control at BNL with @thopkins32 @tacaswell @mrakitin and others

@whs92

whs92 commented Jun 8, 2026

Copy link
Copy Markdown
Member

@roussel-ryan I am particularly interested in adding context to optimization. Thanks for your explanation.

@roussel-ryan

Copy link
Copy Markdown
Author

Good to hear, please keep an eye on xopt-org/Xopt#425 which should be in the next release

@whs92

whs92 commented Jun 8, 2026

Copy link
Copy Markdown
Member

As far as I know adding additional observations for context was already supported by the earlier pre-AX version of blop. Whatever we come up with, blop should abstract away the differences (if they exist) between the different back ends so that if I want to provide context (or anything else) I shouldn't care whether I am talking to AX or XopT in the background.

@roussel-ryan

Copy link
Copy Markdown
Author

Based on previous discussions, we wanted to try to keep the Ax/Xopt interfaces separate (see previous comments above) and not include a translation layer to unify the interfaces to the user. I think we should discuss this further, but it may be a good initial step to get Xopt support capability integrated into blop first and then work on improving the user interface. I want to hear other folks opinions on the matter

@roussel-ryan

Copy link
Copy Markdown
Author

I've addressed all the issues on my side, I didn't make any changes to tutorials/xrt-kb-mirrors.md so I think that might be an issue that you all want to work on

@roussel-ryan roussel-ryan marked this pull request as ready for review June 8, 2026 15:52

@thopkins32 thopkins32 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial review done. I'll follow up with a more in-depth one after I get clarification on one point.

Comment on lines +41 to +43
self._next_id = 0
self._params_by_id: dict[int | str, dict[str, Any]] = {}
self._seed_state_from_existing_data()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the Xopt docs, is the data frame index of self._generator.data something we can use instead of doing ID tracking in Blop? I don't want to duplicate state tracking here if Xopt already has a mechanism for this.

The reason we have an ID associated with every suggestion is that when we evaluate multiple points in a single optimizer iteration (e.g., RE(optimize(..., n_points=5))) we may have a more optimal sampling route than the default order provided by the optimizer. Bluesky always emits events in the order they were collected (and we cache this reordering information in the Bluesky metadata). Therefore, to match Bluesky's event/collection order with the optimizer suggestion order, we need to track IDs for each suggestion.

@thopkins32

Copy link
Copy Markdown
Collaborator

Also, I merged the change removing Python 3.10 support if you would like to rebase or merge main into this branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants