Skip to content

Commit e9de08a

Browse files
committed
Merge branch 'develop' into feature/20250625-IntegrationWithJuMP
2 parents f76c973 + d848779 commit e9de08a

19 files changed

+255
-63
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "AOCoptimizer"
22
uuid = "ba4aa9bd-6938-48c2-966f-258481ba1c4a"
33
authors = ["Kirill Kalinin <kkalinin@microsoft.com>", "Christos Gkantsidis <chrisgk@microsoft.com>"]
4-
version = "0.1.0"
4+
version = "0.2.1"
55

66
[deps]
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"

docs/src/manual/installation.md

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,90 @@
11
# Installation
22

3-
TODO: Provide installation instructions for the package.
4-
In addition, add steps to test that installation has been successful
5-
both when CUDA is and is not used, document installation problems and
6-
differences between platforms.
3+
## Prerequisites
4+
5+
In case you don't have Julia installed, please refer to the
6+
[Julia installation guide](https://julialang.org/install/).
7+
(Although the easiest way is to use the Julia installer directly,
8+
it's better to follow the instructions from the installation guide.)
9+
10+
If you have not used Julia before, you may want to create a new
11+
project from which you will use the `AOCoptimizer` package.
12+
Start Julia in your working directory with `julia`and run the following commands
13+
(they will create a new directory called `MyProject`, and initialize
14+
the project in it):
15+
16+
```julia
17+
using Pkg
18+
Pkg.generate("MyProject")
19+
```
20+
21+
(A better way to create a new project is by using the
22+
[PkgSkeleton.jl](https://github.com/tpapp/PkgSkeleton.jl) package.
23+
24+
If you want to use CUDA, you will also need to make sure that
25+
the drivers for your GPU are installed and that the CUDA Toolkit
26+
is available on your system. You can find the installation instructions
27+
on the [NVIDIA CUDA Toolkit page](https://developer.nvidia.com/cuda-downloads).
28+
29+
## Adding `AOCoptimizer.jl` to your project
30+
31+
(If you have just created a new project, with the instructions above,
32+
make sure to `cd` into the `MyProject` directory first and then start Julia
33+
with `julia --project`, or alternatively activate the new project from
34+
inside Julia with `Pkg.activate("MyProject")`.)
35+
36+
Add the `AOCoptimizer` package to your project by running the following command
37+
(make sure you have used `using Pkg` first):
38+
39+
```julia
40+
Pkg.add(url="https://github.com/microsoft/AOCoptimizer.jl")
41+
```
42+
43+
If the above does not work with the error
44+
`ERROR: invalid git HEAD (reference 'refs/head/master' not found)`
45+
please try the following:
46+
47+
```julia
48+
Pkg.dev(url="https://github.com/microsoft/AOCoptimizer.jl#main")
49+
```
50+
51+
If you also want to use `CUDA` or `JuMP`,
52+
you should also install the corresponding packages.
53+
For the case of `CUDA`, run:
54+
55+
```julia
56+
Pkg.add("CUDA")
57+
```
58+
59+
For `JuMP`, run:
60+
61+
```julia
62+
Pkg.add("JuMP")
63+
Pkg.add("MathOptInterface")
64+
```
65+
66+
Verify that the `AOCoptimizer` package is installed correctly by running:
67+
68+
```julia
69+
Pkg.test("AOCoptimizer")
70+
```
71+
72+
## Adding `AOCoptimizer.jl` as a dependency to your project
73+
74+
The approach described in the previous section works for projects
75+
that either add the `Manifest.toml` file to the repository (in general not recommended),
76+
or for projects that don't use version control at all. The reason is that
77+
the `URL` of the `AOCoptimizer` package doesn't appear in the `Project.toml` file,
78+
hence, creating problems for other developers who want to use the project
79+
that depends on `AOCoptimizer`.
80+
81+
Instead, for such projects manually modify your `Project.toml` file to contain
82+
the following statements:
83+
84+
```toml
85+
[deps]
86+
AOCoptimizer = "ba4aa9bd-6938-48c2-966f-258481ba1c4a"
87+
88+
[sources]
89+
AOCoptimizer = {url = "https://github.com/microsoft/AOCoptimizer.jl"}
90+
```

docs/src/reference/reference.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,15 @@ Solver.@make_sampler
174174
```
175175

176176
```@docs
177-
Solver.sample!
177+
Solver.sample_mixed_ising!
178178
```
179179

180180
```@docs
181181
Solver.sample_qumo!
182182
```
183183

184184
```@docs
185-
Solver.sample_binary!
185+
Solver.sample_positive_qumo!
186186
```
187187

188188
```@docs
@@ -194,7 +194,11 @@ Solver.SamplerTracer.SamplerWithPlan
194194
```
195195

196196
```@docs
197-
Solver.sample_with_tracer!
197+
Solver.sample_qumo_with_tracer!
198+
```
199+
200+
```@docs
201+
Solver.sample_mixed_ising_with_tracer!
198202
```
199203

200204
### Exploration
@@ -204,15 +208,15 @@ Solver.@make_exploration
204208
```
205209

206210
```@docs
207-
Solver.explore
211+
Solver.explore_mixed_ising
208212
```
209213

210214
```@docs
211215
Solver.explore_qumo
212216
```
213217

214218
```@docs
215-
Solver.explore_binary
219+
Solver.explore_positive_qumo
216220
```
217221

218222
```@docs
@@ -284,15 +288,15 @@ Solver.@make_solver
284288
```
285289

286290
```@docs
287-
Solver.solve
291+
Solver.solve_mixed_ising
288292
```
289293

290294
```@docs
291295
Solver.solve_qumo
292296
```
293297

294298
```@docs
295-
Solver.solve_binary
299+
Solver.solve_positive_qumo
296300
```
297301

298302
```@docs

docs/src/tutorials/example.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ using Dates
2424
using JSON
2525
using AOCoptimizer
2626
using AOCoptimizer: graph_cut_from_hamiltonian
27-
using AOCoptimizer.Solver: solve, find_best, get_solver_results_summary
27+
using AOCoptimizer.Solver: solve_mixed_ising, find_best
28+
using AOCoptimizer.Solver: get_solver_results_summary
2829
2930
# Necessary to explicitly initialize the AOCoptimizer package
3031
AOCoptimizer.init()
@@ -38,7 +39,7 @@ graph = Float32.([
3839
])
3940
4041
# observe that we optimize the negative of the adjacency matrix of the graph
41-
sol = solve(Float32, -graph, Second(10))
42+
sol = solve_mixed_ising(Float32, -graph, Second(10))
4243
best = find_best(sol)
4344
cut = graph_cut_from_hamiltonian(graph, best.Objective)
4445
println("Energy: ", best.Objective, "; Cut: ", cut)
@@ -74,7 +75,7 @@ while the last four variables are continuous (in the range ``[-1, 1]``).
7475
```@example MixedIsing
7576
using Dates
7677
using AOCoptimizer
77-
using AOCoptimizer.Solver: solve, find_best
78+
using AOCoptimizer.Solver: solve_mixed_ising, find_best
7879
7980
AOCoptimizer.init()
8081
@@ -100,7 +101,7 @@ q = Float32.([
100101
145
101102
])
102103
103-
sol = solve(Float32, Q, q, number_of_binaries, Second(10))
104+
sol = solve_mixed_ising(Float32, Q, q, number_of_binaries, Second(10))
104105
best = find_best(sol)
105106
```
106107

@@ -118,6 +119,16 @@ println("Continuous: ", best.Vars[number_of_binaries+1:end])
118119

119120
## Solving a simple `QUMO` problem
120121

122+
Let's solve now a simple optimization problem that combines
123+
both binary and continuous variables (`QUMO`). In the example
124+
below, we have 3 binary variables and 4 continuous variables.
125+
Using the default interface, it is expected that the first
126+
variables are binary; e.g., in the example below, the
127+
variable `number_of_binaries` signifies that the first 3 variables
128+
are binary, and this parameter is passed to the `solve_qumo` function.
129+
Moreover, it is expected that the first `number_of_binaries` diagonal
130+
elements of the matrix `Q` are zero.
131+
121132
```@example QUMO
122133
using Dates
123134
using AOCoptimizer

notebooks/benchmark-clamping.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ cpu_y = rand(T, matrix_size, experiments);
162162
@benchmark AOCoptimizer.Solver.enforce_inelastic_wall_ising!(cpu_x)
163163

164164
# The binary shortcut to the walls
165-
@benchmark AOCoptimizer.Solver.enforce_inelastic_wall_binary!(cpu_x)
165+
@benchmark AOCoptimizer.Solver.enforce_inelastic_wall_positive!(cpu_x)
166166

167167
# ### Two arrays: the inelastic wall implementation with clamp
168168
@benchmark combine_clamp!(cpu_x, cpu_y)
@@ -182,7 +182,7 @@ cpu_y = rand(T, matrix_size, experiments);
182182
@benchmark AOCoptimizer.Solver.enforce_inelastic_wall_ising!(cpu_x, cpu_y)
183183

184184
# The binary shortcut to the walls
185-
@benchmark AOCoptimizer.Solver.enforce_inelastic_wall_binary!(cpu_x, cpu_y)
185+
@benchmark AOCoptimizer.Solver.enforce_inelastic_wall_positive!(cpu_x, cpu_y)
186186

187187
# ## GPU based implementations
188188

@@ -364,7 +364,7 @@ end
364364

365365
# The binary shortcut to the walls
366366
CUDA.@bprofile begin
367-
AOCoptimizer.Solver.enforce_inelastic_wall_binary!(gpu_x)
367+
AOCoptimizer.Solver.enforce_inelastic_wall_positive!(gpu_x)
368368
CUDA.synchronize()
369369
end
370370

@@ -401,7 +401,7 @@ end
401401

402402
# The binary shortcut to the walls
403403
CUDA.@bprofile begin
404-
AOCoptimizer.Solver.enforce_inelastic_wall_binary!(gpu_x, gpu_y)
404+
AOCoptimizer.Solver.enforce_inelastic_wall_positive!(gpu_x, gpu_y)
405405
CUDA.synchronize()
406406
end
407407

notebooks/benchmark-exploration.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ setup = AOCoptimizer.Solver.make_setup(annealing, gradient, momentum, dt, 16);
4545
# ## Run in the CPU
4646

4747
@benchmark begin
48-
result = AOCoptimizer.Solver.explore(
48+
result = AOCoptimizer.Solver.explore_mixed_ising(
4949
problem,
5050
setup,
5151
batch_size,
@@ -67,7 +67,7 @@ CUDA.synchronize();
6767
# Benchmark the exploration function in the GPU
6868
# (here we avoid the use `CUDA.@bprofile`, which seems to not work correctly).
6969

70-
g_result = AOCoptimizer.Solver.explore(
70+
g_result = AOCoptimizer.Solver.explore_mixed_ising(
7171
g_problem,
7272
g_setup,
7373
batch_size,
@@ -79,7 +79,7 @@ g_result = AOCoptimizer.Solver.explore(
7979
CUDA.synchronize();
8080

8181
CUDA.@time begin
82-
g_result = AOCoptimizer.Solver.explore(
82+
g_result = AOCoptimizer.Solver.explore_mixed_ising(
8383
g_problem,
8484
g_setup,
8585
batch_size,

notebooks/benchmark-sampler.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ delta = annealing / iterations;
5353
dt = T(0.1);
5454

5555
# Default sampler
56-
@benchmark Solver._sample_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
56+
@benchmark Solver._sample_mixed_ising_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
5757

5858
# Binary sampler
59-
@benchmark Solver._sample_binary_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
59+
@benchmark Solver._sample_positive_qumo_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
6060

6161
# QUMO sampler
6262
@benchmark Solver._sample_qumo_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
@@ -91,13 +91,13 @@ dt = T(0.1);
9191

9292
# Default sampler
9393
CUDA.@bprofile begin
94-
Solver._sample_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
94+
Solver._sample_mixed_ising_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
9595
CUDA.synchronize()
9696
end
9797

9898
# Binary sampler
9999
CUDA.@bprofile begin
100-
Solver._sample_binary_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
100+
Solver._sample_positive_qumo_internal!(interactions, nothing, binaries, gradient, momentum, x, y, fields, spins, annealing, delta, dt, iterations)
101101
CUDA.synchronize()
102102
end
103103

notebooks/benchmark-solver.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ graph = create_random_graph(T, n);
3333
engine_cpu = AOCoptimizer.Solver.EngineLocalCpu();
3434
engine_gpu = AOCoptimizer.Solver.EngineCuda(0);
3535

36-
# sol = AOCoptimizer.Solver.solve(Float32, graph, Second(60));
36+
# sol = AOCoptimizer.Solver.solve_mixed_ising(Float32, graph, Second(60));
3737

3838
# ## Benchmark in the CPU
3939

40-
sol = AOCoptimizer.Solver.solve(Float32, graph, Second(60); engine=engine_cpu);
40+
sol = AOCoptimizer.Solver.solve_mixed_ising(Float32, graph, Second(60); engine=engine_cpu);
4141
println(JSON.json(AOCoptimizer.Solver.extract_runtime_information(sol), 4))
4242

4343
# ## Benchmark in the GPU
44-
sol = AOCoptimizer.Solver.solve(Float32, graph, Second(60); engine=engine_gpu);
44+
sol = AOCoptimizer.Solver.solve_mixed_ising(Float32, graph, Second(60); engine=engine_gpu);
4545
println(JSON.json(AOCoptimizer.Solver.extract_runtime_information(sol), 4))
4646

4747
# ## System information

notebooks/evaluate-max_cut.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ for filename in filenames
9191

9292
timeout = estimate_processing_time(size(graph, 1))
9393

94-
sol = AOCoptimizer.Solver.solve(T, -graph, timeout; engine=engine)
94+
sol = AOCoptimizer.Solver.solve_mixed_ising(T, -graph, timeout; engine=engine)
9595
perf = AOCoptimizer.Solver.get_solver_results_summary(sol)
9696
max_cut = AOCoptimizer.graph_cut_from_hamiltonian(graph, perf.obj_best_found)
9797

src/FileFormats/qio.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ read_ising(filename::AbstractString)::Ising{Float64} = read_ising(Float64, filen
269269
Read a QIO problem from a file with name `filename` or from an IO stream `io`.
270270
Optional type parameter `T` specifies the elementary type used in the the problem (e.g., Float64 or Float32).
271271
"""
272+
function read_qio end
273+
272274
function read_qio(::Type{T}, filename::AbstractString)::QIOProblem where {T<:Real}
273275
problem = _read_json_file(filename)
274276
problem_type = problem["type"]

0 commit comments

Comments
 (0)