Skip to content

Commit ad165e4

Browse files
authored
Bump to MadNLP 0.10, ExaModels 0.11 (#45)
1 parent 28b3d8c commit ad165e4

11 files changed

Lines changed: 68 additions & 55 deletions

File tree

Project.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@ version = "0.3.1"
44

55
[deps]
66
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
7-
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
87
ExaModels = "1037b233-b668-4ce9-9b63-f9f681f55dd2"
98
ExaPowerIO = "14903efe-9500-4d7f-a589-7ab7e15da6de"
9+
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
1010

1111
[compat]
12-
JSON = "0.21"
13-
ExaModels = "0.9"
12+
CUDA = "6"
13+
ExaModels = "0.11"
1414
ExaPowerIO = "0.3"
15-
MadNLP = "0.8"
16-
MadNLPGPU = "0.7"
17-
CUDA = "5"
15+
JSON = "0.21"
16+
MadNLP = "0.10"
17+
MadNLPGPU = "0.10"
1818
julia = "1.11"
1919

2020
[extras]
2121
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
22+
CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e"
2223
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
2324
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
2425
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
@@ -29,4 +30,4 @@ PowerModels = "c36e90e8-916a-50a6-bd94-075b64ef4655"
2930
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3031

3132
[targets]
32-
test = ["Test", "MadNLP", "MadNLPGPU", "KernelAbstractions", "CUDA", "Ipopt", "JuMP", "NLPModelsJuMP", "PowerModels"]
33+
test = ["Test", "MadNLP", "MadNLPGPU", "KernelAbstractions", "CUDA", "CUDSS", "Ipopt", "JuMP", "NLPModelsJuMP", "PowerModels"]

docs/Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ MadNLPGPU = "d72a61cc-809d-412f-99be-fd81f4b8a598"
1010
ExaModelsPower = "2fff4b78-0b6c-428d-bac8-85ccea8c4bdf"
1111

1212
[compat]
13-
CUDA = "5"
14-
ExaModels = "0.9"
13+
CUDA = "6"
14+
ExaModels = "0.11"
1515

1616
[sources]
17-
ExaModelsPower = {path = ".."}
17+
ExaModelsPower = {path = ".."}

docs/src/mpopf_demo.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ model, vars, cons = mpopf_model(
1212
backend = CUDABackend(),
1313
corrective_action_ratio = 0.3
1414
)
15-
result = madnlp(model; tol=1e-6)
15+
result = madnlp(model; tol=1e-6, kkt_system = MadNLP.SparseCondensedKKTSystem, linear_solver = MadNLPGPU.CUDSSSolver)
1616

1717
# If the user would like to provide more complex demand profiles, they can provide their own input files. The number of rows in each input file should match the number of buses in the static OPF datafile, and the number of columns will dictate the number of time periods in the MP model.
1818
# First, download the example load profile datafiles.
@@ -45,7 +45,7 @@ model, vars, cons = mpopf_model(
4545
)
4646

4747
#Solve
48-
result = madnlp(model; tol=1e-6)
48+
result = madnlp(model; tol=1e-6, kkt_system = MadNLP.SparseCondensedKKTSystem, linear_solver = MadNLPGPU.CUDSSSolver)
4949

5050
## MPOPF with storage
5151
# The MPOPF model can also be constructed with storage considerations. We model storage using the model proposed in __[Geth, Coffrin, Fobes 2020](https://arxiv.org/pdf/2004.14768)__. This requires inputting a modified datafile containing storage parameters. When modeling MPOPF with storage, all of the aforementioned tuneable parameters are still available. We also allow the user to specify whether or not to model the charging/discharging complementarity constraint. This is set to false by default to avoid potential numerical error.
@@ -70,7 +70,7 @@ model, vars, cons = mpopf_model(
7070
backend = CUDABackend(),
7171
storage_complementarity_constraint = false
7272
)
73-
result = madnlp(model; tol=1e-6)
73+
result = madnlp(model; tol=1e-6, kkt_system = MadNLP.SparseCondensedKKTSystem, linear_solver = MadNLPGPU.CUDSSSolver)
7474
result.objective
7575

7676
# ExaModelsPower also provides a secondary option to avoid dealing with complementarity constraints. The user can specify a function that computesloss in battery level as a smooth function of discharge rate and the storage devices thermal rating parameter. We provide an arbitrary example function to demonstrate the modeling capability.
@@ -88,7 +88,7 @@ model, vars, cons = mpopf_model(
8888
backend = CUDABackend(),
8989
storage_complementarity_constraint = false
9090
)
91-
result = madnlp(model; tol=1e-6)
91+
result = madnlp(model; tol=1e-6, kkt_system = MadNLP.SparseCondensedKKTSystem, linear_solver = MadNLPGPU.CUDSSSolver)
9292
result.objective
9393

9494
# Despite the example discharge function being generated somewhat arbitrarily, the resultant objective values remain quite close for both the smooth and piecewise charge/discharge functions.

docs/src/opf_demo.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ model, vars, cons = ac_opf_model(
2121
model
2222

2323
# Once the model is built, we can generate a solution using MadNLP.
24-
result = madnlp(model; tol=1e-6)
24+
result = madnlp(model; tol=1e-6, kkt_system = MadNLP.SparseCondensedKKTSystem, linear_solver = MadNLPGPU.CUDSSSolver)
2525

2626
# Once a solution has been generated, the values of any of the variables in the model can be unpacked using the vars NamedTuple.
2727
solution(result, vars.vm)[1:10]

src/dcopf.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function build_dcopf(data, user_callback; backend = nothing, T = Float64, core =
5555

5656

5757
vars2, cons2 = user_callback(core, vars, cons)
58-
model =ExaModel(core; kwargs...)
58+
model = ExaModel(core; prod = true, kwargs...)
5959

6060
vars = (;vars..., vars2...)
6161
cons = (;cons..., cons2...)
@@ -90,7 +90,7 @@ function dcopf_model(
9090
user_callback = dummy_extension,
9191
kwargs...,
9292
)
93-
data = parse_ac_power_data(filename)
93+
data = parse_ac_power_data(filename, T)
9494
data = convert_data(data, backend)
9595

9696
return build_dcopf(data, user_callback; backend = backend, T = T, kwargs...)

src/mpopf.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
function parse_mp_power_data(filename, N, corrective_action_ratio)
1+
function parse_mp_power_data(filename, N, corrective_action_ratio, T = Float64)
22

3-
data = parse_ac_power_data(filename)
3+
data = parse_ac_power_data(filename, T)
44

55
nbus = length(data.bus)
66

@@ -27,7 +27,7 @@ function update_load_data(busarray, curve)
2727
for x in 1:size(busarray, 1)
2828
b = busarray[x, t]
2929
busarray[x, t] = (
30-
b=ExaPowerIO.BusData(
30+
b=ExaPowerIO.BusData{typeof(b.b.pd)}(
3131
b.b.i,
3232
b.b.bus_i,
3333
b.b.type,
@@ -53,7 +53,7 @@ function update_load_data(busarray, pd, qd, baseMVA)
5353
for (idx ,pd_t) in pairs(pd)
5454
b = busarray[idx[1], idx[2]]
5555
busarray[idx[1], idx[2]] = (
56-
b=ExaPowerIO.BusData(
56+
b=ExaPowerIO.BusData{typeof(b.b.pd)}(
5757
b.b.i,
5858
b.b.bus_i,
5959
b.b.type,
@@ -235,7 +235,7 @@ function build_mpopf(data, Nbus, N, form, user_callback; backend = nothing, T =
235235
end
236236

237237
vars2, cons2 = user_callback(core, vars, cons)
238-
model =ExaModel(core; kwargs...)
238+
model = ExaModel(core; prod = true, kwargs...)
239239

240240
vars = (;vars..., vars2...)
241241
cons = (;cons..., cons2...)
@@ -255,7 +255,7 @@ function build_mpopf(data, Nbus, N, discharge_func::Function, form, user_callbac
255255
end
256256

257257
vars2, cons2 = user_callback(core, vars, cons)
258-
model =ExaModel(core; kwargs...)
258+
model = ExaModel(core; prod = true, kwargs...)
259259

260260
vars = (;vars..., vars2...)
261261
cons = (;cons..., cons2...)
@@ -421,7 +421,7 @@ function mpopf_model(
421421
)
422422

423423
@assert length(curve) > 0
424-
data = parse_mp_power_data(filename, N, corrective_action_ratio)
424+
data = parse_mp_power_data(filename, N, corrective_action_ratio, T)
425425
update_load_data(data.busarray, curve)
426426
data = convert_data(data,backend)
427427
Nbus = size(data.bus, 1)
@@ -447,7 +447,7 @@ function mpopf_model(
447447
kwargs...,
448448
)
449449

450-
data = parse_mp_power_data(filename, N, corrective_action_ratio)
450+
data = parse_mp_power_data(filename, N, corrective_action_ratio, T)
451451
update_load_data(data.busarray, pd, qd, data.baseMVA[])
452452
data = convert_data(data,backend)
453453
Nbus = size(data.bus, 1)
@@ -473,7 +473,7 @@ function mpopf_model(
473473
)
474474

475475
@assert length(curve) > 0
476-
data = parse_mp_power_data(filename, N, corrective_action_ratio)
476+
data = parse_mp_power_data(filename, N, corrective_action_ratio, T)
477477
update_load_data(data.busarray, curve)
478478
data = convert_data(data,backend)
479479
Nbus = size(data.bus, 1)
@@ -500,7 +500,7 @@ function mpopf_model(
500500
)
501501

502502

503-
data = parse_mp_power_data(filename, N, corrective_action_ratio)
503+
data = parse_mp_power_data(filename, N, corrective_action_ratio, T)
504504
update_load_data(data.busarray, pd, qd, data.baseMVA[])
505505
data = convert_data(data,backend)
506506
Nbus = size(data.bus, 1)

src/opf.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function build_polar_opf(data, user_callback; backend = nothing, T=Float64, kwar
8888
)
8989

9090
vars2, cons2 = user_callback(core, vars, cons)
91-
model =ExaModel(core; kwargs...)
91+
model = ExaModel(core; prod = true, kwargs...)
9292

9393
vars = (;vars..., vars2...)
9494
cons = (;cons..., cons2...)
@@ -186,7 +186,7 @@ function build_rect_opf(data, user_callback; backend = nothing, T=Float64, kwarg
186186
)
187187

188188
vars2, cons2 = user_callback(core, vars, cons)
189-
model =ExaModel(core; kwargs...)
189+
model = ExaModel(core; prod = true, kwargs...)
190190

191191
vars = (;vars..., vars2...)
192192
cons = (;cons..., cons2...)
@@ -222,7 +222,7 @@ function ac_opf_model(
222222
kwargs...,
223223
)
224224

225-
data = parse_ac_power_data(filename)
225+
data = parse_ac_power_data(filename, T)
226226
data = convert_data(data, backend)
227227

228228
if form == :polar

src/parser.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
convert_data(data::N, backend) where {names,N<:NamedTuple{names}} =
22
NamedTuple{names}(convert_array(d, backend) for d in data)
33

4-
function parse_ac_power_data(filename)
4+
function parse_ac_power_data(filename, T = Float64)
55
_, f = splitdir(filename)
66
name, _ = splitext(f)
77

88
@info "Loading matpower file"
99

1010
library = isfile(filename) ? nothing : :pglib
11-
data = ExaPowerIO.parse_matpower(filename; library)
11+
data = ExaPowerIO.parse_matpower(T, filename; library)
1212

1313
data = (
1414
baseMVA = [data.baseMVA],

src/scopf.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ function goc3_model(
807807
end
808808

809809
vars2, cons2 = user_callback(core, vars, cons)
810-
model =ExaModel(core; kwargs...)
810+
model = ExaModel(core; prod = true, kwargs...)
811811

812812
vars = (;vars..., vars2...)
813813
cons = (;cons..., cons2...)

test/opf_tests.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
# On a CUDA backend, MadNLP's defaults (SparseKKTSystem + MUMPS) are CPU-only and cannot
2+
# assemble the KKT matrix from device arrays, so solve the condensed system with cuDSS on
3+
# the GPU. On the CPU, pin the linear solver to Umfpack: MadNLP 0.10 changed the sparse
4+
# default to MUMPS, which drives these OPFs into restoration, whereas Umfpack (the default
5+
# through MadNLP 0.8, and what main uses) converges cleanly.
6+
function exasolve(model, backend; kwargs...)
7+
opts = backend isa CUDABackend ?
8+
(; kkt_system = MadNLP.SparseCondensedKKTSystem, linear_solver = MadNLPGPU.CUDSSSolver) :
9+
(; linear_solver = MadNLP.UmfpackSolver)
10+
return madnlp(model; opts..., kwargs...)
11+
end
12+
113
function test_case3(result, result_pm, result_nlp_pm, pg, qg, p, q)
214
test_static_case(result, result_pm, result_nlp_pm, pg, qg)
315

@@ -70,7 +82,7 @@ function sc_tests(filename, backend, T)
7082
uc_filename = filename*"_solution.json"
7183
filename = filename*".json"
7284
model, cons, vars, lengths, sc_data_array = ExaModelsPower.goc3_model(filename, uc_filename; backend=backend, T=T)
73-
result = madnlp(model; max_iter=5, tol=1e-2)
85+
result = exasolve(model, backend; max_iter=5, tol=1e-2)
7486
end
7587

7688
function test_dcopf_case(result, result_pm, pg, pf)

0 commit comments

Comments
 (0)