Skip to content

Commit 2b90904

Browse files
committed
Add ipopt autoload
1 parent 5f5ffcf commit 2b90904

File tree

3 files changed

+48
-19
lines changed

3 files changed

+48
-19
lines changed

src/pyoptinterface/_src/codegen_llvm.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,21 @@ def create_indirect_load_store(module: ir.Module):
226226
graph_op.sinh: "sinh",
227227
graph_op.sqrt: "sqrt",
228228
graph_op.tan: "tan",
229-
graph_op.tanh: "tanh"
229+
graph_op.tanh: "tanh",
230230
}
231231

232232
math_ops = set(op2name.keys())
233233

234234
binary_ops = set([graph_op.pow])
235235

236+
236237
def create_llvmir_basic_functions(module: ir.Module):
237238
create_azmul(module)
238239
create_sign(module)
239240
create_direct_load_store(module)
240241
create_indirect_load_store(module)
241242

242-
for (op, op_name) in op2name.items():
243+
for op, op_name in op2name.items():
243244
if op in binary_ops:
244245
func_type = ir.FunctionType(D, [D, D])
245246
else:

src/pyoptinterface/_src/ipopt.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from io import StringIO
22
import types
3+
import logging
4+
import platform
35

46
from llvmlite import ir
57

6-
from .ipopt_model_ext import RawModel, ApplicationReturnStatus
8+
from .ipopt_model_ext import RawModel, ApplicationReturnStatus, load_library
79
from .codegen_c import generate_csrc_prelude, generate_csrc_from_graph
810
from .jit_c import TCCJITCompiler
911
from .codegen_llvm import create_llvmir_basic_functions, generate_llvmir_from_graph
@@ -29,6 +31,33 @@
2931
from .aml import make_nd_variable
3032

3133

34+
def detected_libraries():
35+
libs = []
36+
37+
# default names
38+
default_libnames = {
39+
"Linux": ["libipopt.so"],
40+
"Darwin": ["libpopt.dylib"],
41+
"Windows": ["ipopt-3.dll", "ipopt.dll", "libipopt-3.dll", "libipopt.dll"],
42+
}[platform.system()]
43+
libs.extend(default_libnames)
44+
45+
return libs
46+
47+
48+
def autoload_library():
49+
libs = detected_libraries()
50+
for lib in libs:
51+
ret = load_library(lib)
52+
if ret:
53+
logging.info(f"Loaded IPOPT library: {lib}")
54+
return True
55+
return False
56+
57+
58+
autoload_library()
59+
60+
3261
def compile_functions_c(backend: RawModel, jit_compiler: TCCJITCompiler):
3362
io = StringIO()
3463

@@ -294,9 +323,10 @@ def get_constraint_primal(model, constraint):
294323
dim = constraint.dim
295324
values = [model.get_constraint_primal(index + i) for i in range(dim)]
296325
return values
297-
326+
298327
raise ValueError(f"Unknown constraint type: {type(constraint)}")
299328

329+
300330
def get_constraint_dual(model, constraint):
301331
if isinstance(constraint, ConstraintIndex):
302332
return model.get_constraint_dual(constraint.index)
@@ -305,7 +335,7 @@ def get_constraint_dual(model, constraint):
305335
dim = constraint.dim
306336
values = [model.get_constraint_dual(index + i) for i in range(dim)]
307337
return values
308-
338+
309339
raise ValueError(f"Unknown constraint type: {type(constraint)}")
310340

311341

tests/nlp.py renamed to tests/test_nlp.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,15 @@
44
import pyoptinterface as poi
55
from pyoptinterface import ipopt
66

7-
IPOPT_PATH = r"D:\Ipopt\bin\ipopt-3.dll"
8-
9-
if not ipopt.load_library(IPOPT_PATH):
7+
if not ipopt.is_library_loaded():
108
exit(1)
119

1210

1311
def test_ipopt():
1412
model = ipopt.Model()
1513

16-
x = model.add_variable(lb=0.0, ub=10.0, start=0.8)
17-
y = model.add_variable(lb=0.0, ub=10.0, start=0.5)
14+
x = model.add_variable(lb=0.1, ub=10.0, start=0.8)
15+
y = model.add_variable(lb=0.1, ub=10.0, start=0.5)
1816

1917
model.add_linear_constraint(x + y, poi.Eq, 1.0)
2018

@@ -93,7 +91,7 @@ def all_nlfuncs(vars):
9391
if f == poi.acosh:
9492
v = f(x + 1)
9593
elif f == poi.pow:
96-
v = f(x, x)
94+
v = f(x, 2)
9795
else:
9896
v = f(x)
9997
values.append(v)
@@ -103,7 +101,9 @@ def all_nlfuncs(vars):
103101
all_nlfuncs_f = model.register_function(all_nlfuncs, var=["x"], name="all_nlfuncs")
104102
N = len(nl_funcs)
105103
B = 1e10
106-
all_nlfuncs_con = model.add_nl_constraint(all_nlfuncs_f, [x], poi.In, lb=[-B] * N, ub=[B] * N)
104+
all_nlfuncs_con = model.add_nl_constraint(
105+
all_nlfuncs_f, [x], poi.In, lb=[-B] * N, ub=[B] * N
106+
)
107107

108108
model.optimize()
109109

@@ -120,19 +120,17 @@ def all_nlfuncs(vars):
120120
obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)
121121
assert obj_value == pytest.approx(math.exp(x_value) + math.exp(y_value))
122122

123-
con_values = model.get_constraint_attribute(all_nlfuncs_con, poi.ConstraintAttribute.Primal)
124-
123+
con_values = model.get_constraint_attribute(
124+
all_nlfuncs_con, poi.ConstraintAttribute.Primal
125+
)
126+
125127
correct_con_values = []
126128
for f in py_funcs:
127129
if f == math.acosh:
128130
v = f(x_value + 1)
129131
elif f == math.pow:
130-
v = f(x_value, x_value)
132+
v = f(x_value, 2)
131133
else:
132134
v = f(x_value)
133135
correct_con_values.append(v)
134136
assert con_values == pytest.approx(correct_con_values)
135-
136-
137-
if __name__ == "__main__":
138-
test_ipopt()

0 commit comments

Comments
 (0)