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

Fix SNOPT printout encoding and skip printing import warnings #392

Merged
merged 7 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyoptsparse/pyCONMIN/pyCONMIN.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# import the compiled module
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
conmin = try_import_compiled_module_from_path("conmin", THIS_DIR)
conmin = try_import_compiled_module_from_path("conmin", THIS_DIR, raise_warning=True)

Check warning on line 20 in pyoptsparse/pyCONMIN/pyCONMIN.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyCONMIN/pyCONMIN.py#L20

Added line #L20 was not covered by tests


class CONMIN(Optimizer):
Expand Down
2 changes: 1 addition & 1 deletion pyoptsparse/pyNSGA2/pyNSGA2.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# import the compiled module
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
nsga2 = try_import_compiled_module_from_path("nsga2", THIS_DIR)
nsga2 = try_import_compiled_module_from_path("nsga2", THIS_DIR, raise_warning=True)

Check warning on line 19 in pyoptsparse/pyNSGA2/pyNSGA2.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyNSGA2/pyNSGA2.py#L19

Added line #L19 was not covered by tests


class NSGA2(Optimizer):
Expand Down
2 changes: 1 addition & 1 deletion pyoptsparse/pyOpt_constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

# Local modules
from .pyOpt_error import Error, pyOptSparseWarning
from .pyOpt_types import Dict1DType

Check warning on line 11 in pyoptsparse/pyOpt_constraint.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyOpt_constraint.py#L11

Added line #L11 was not covered by tests
from .pyOpt_utils import INFINITY, _broadcast_to_array, convertToCOO
from .types import Dict1DType


class Constraint:
Expand Down
2 changes: 1 addition & 1 deletion pyoptsparse/pyOpt_gradient.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Local modules
from .pyOpt_MPI import MPI
from .pyOpt_optimization import Optimization
from .types import Dict1DType, Dict2DType
from .pyOpt_types import Dict1DType, Dict2DType

Check warning on line 11 in pyoptsparse/pyOpt_gradient.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyOpt_gradient.py#L11

Added line #L11 was not covered by tests


class Gradient:
Expand Down
2 changes: 1 addition & 1 deletion pyoptsparse/pyOpt_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from .pyOpt_constraint import Constraint
from .pyOpt_error import Error
from .pyOpt_objective import Objective
from .pyOpt_types import Dict1DType, Dict2DType, NumpyType

Check warning on line 18 in pyoptsparse/pyOpt_optimization.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyOpt_optimization.py#L18

Added line #L18 was not covered by tests
from .pyOpt_utils import (
ICOL,
IDATA,
Expand All @@ -28,7 +29,6 @@
scaleRows,
)
from .pyOpt_variable import Variable
from .types import Dict1DType, Dict2DType, NumpyType


class Optimization:
Expand Down
File renamed without changes.
11 changes: 8 additions & 3 deletions pyoptsparse/pyOpt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
mat = {'csr':[rowp, colind, data], 'shape':[nrow, ncols]} # A csr matrix
mat = {'csc':[colp, rowind, data], 'shape':[nrow, ncols]} # A csc matrix
"""

# Standard Python modules
import importlib
import os
Expand All @@ -24,7 +25,7 @@

# Local modules
from .pyOpt_error import Error
from .types import ArrayType
from .pyOpt_types import ArrayType

Check warning on line 28 in pyoptsparse/pyOpt_utils.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyOpt_utils.py#L28

Added line #L28 was not covered by tests

# Define index mnemonics
IROW = 0
Expand Down Expand Up @@ -576,7 +577,9 @@
return value


def try_import_compiled_module_from_path(module_name: str, path: Optional[str] = None) -> Union[types.ModuleType, str]:
def try_import_compiled_module_from_path(

Check warning on line 580 in pyoptsparse/pyOpt_utils.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pyOpt_utils.py#L580

Added line #L580 was not covered by tests
module_name: str, path: Optional[str] = None, raise_warning: bool = False
) -> Union[types.ModuleType, str]:
"""
Attempt to import a module from a given path.

Expand All @@ -586,6 +589,8 @@
The name of the module
path : Optional[str]
The path to import from. If None, the default ``sys.path`` is used.
raise_warning : bool
If true, raise an import warning. By default false.

Returns
-------
Expand All @@ -600,7 +605,7 @@
try:
module = importlib.import_module(module_name)
except ImportError as e:
if path is not None:
if raise_warning:
Copy link
Contributor

Choose a reason for hiding this comment

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

What are the scenarios where we don't want to raise a warning when the import fails? Even if it's from THIS_DIR we should probably raise an error

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right now on the main branch, running e.g. example/hs015.py will emit the following warnings for me:

.../pyoptsparse/pyoptsparse/pyIPOPT/pyIPOPT.py:28: UserWarning: pyipoptcore module could not be imported from .../repos/pyoptsparse/pyoptsparse/pyIPOPT.
  pyipoptcore = try_import_compiled_module_from_path("pyipoptcore", THIS_DIR)
.../pyoptsparse/pyoptsparse/pyNLPQLP/pyNLPQLP.py:20: UserWarning: nlpqlp module could not be imported from .../pyoptsparse/pyoptsparse/pyNLPQLP.
  nlpqlp = try_import_compiled_module_from_path("nlpqlp", THIS_DIR)

Without the changes in this PR, we always print warnings (at import time) if we cannot import these libraries. Given that they are optional and not installed by pyOptSparse, I don't think we will want this for end users. The PR changes this behaviour so that warnings are not emitted by default. Note that errors are raised at instantiation time if import fails and this PR does not change that behaviour.

warnings.warn(
f"{module_name} module could not be imported from {path}.",
stacklevel=2,
Expand Down
2 changes: 1 addition & 1 deletion pyoptsparse/pySLSQP/pySLSQP.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# import the compiled module
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
slsqp = try_import_compiled_module_from_path("slsqp", THIS_DIR)
slsqp = try_import_compiled_module_from_path("slsqp", THIS_DIR, raise_warning=True)

Check warning on line 20 in pyoptsparse/pySLSQP/pySLSQP.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pySLSQP/pySLSQP.py#L20

Added line #L20 was not covered by tests


class SLSQP(Optimizer):
Expand Down
12 changes: 4 additions & 8 deletions pyoptsparse/pySNOPT/pySNOPT.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@
self.setOption("Total real workspace", lenrw)

cw = np.empty((lencw, 8), dtype="|S1")
cw[:] = " "

Check warning on line 388 in pyoptsparse/pySNOPT/pySNOPT.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pySNOPT/pySNOPT.py#L388

Added line #L388 was not covered by tests
iw = np.zeros(leniw, np.intc)
rw = np.zeros(lenrw, float)
snopt.sninit(iPrint, iSumm, cw, iw, rw)
Expand Down Expand Up @@ -444,11 +445,6 @@
start = np.array(self.getOption("Start"))
ObjAdd = np.array(0.0, float)
ProbNm = np.array(self.optProb.name, "c")
cdummy = -1111111 # this is a magic variable defined in SNOPT for undefined strings
cw[51, :] = cdummy # we set these to cdummy so that a placeholder is used in printout
cw[52, :] = cdummy
cw[53, :] = cdummy
cw[54, :] = cdummy
xs = np.concatenate((xs, np.zeros(ncon, float)))
bl = np.concatenate((blx, blc))
bu = np.concatenate((bux, buc))
Expand Down Expand Up @@ -701,11 +697,11 @@
if name == "Problem Type":
snopt.snset(value, iPrint, iSumm, inform, cw, iw, rw)
elif name == "Print file":
snopt.snset(name + " " + f"{iPrint}", iPrint, iSumm, inform, cw, iw, rw)
snopt.snset(f"{name} {iPrint}", iPrint, iSumm, inform, cw, iw, rw)

Check warning on line 700 in pyoptsparse/pySNOPT/pySNOPT.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pySNOPT/pySNOPT.py#L700

Added line #L700 was not covered by tests
elif name == "Summary file":
snopt.snset(name + " " + f"{iSumm}", iPrint, iSumm, inform, cw, iw, rw)
snopt.snset(f"{name} {iSumm}", iPrint, iSumm, inform, cw, iw, rw)

Check warning on line 702 in pyoptsparse/pySNOPT/pySNOPT.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pySNOPT/pySNOPT.py#L702

Added line #L702 was not covered by tests
else:
snopt.snset(name + " " + value, iPrint, iSumm, inform, cw, iw, rw)
snopt.snset(f"{name} {value}", iPrint, iSumm, inform, cw, iw, rw)

Check warning on line 704 in pyoptsparse/pySNOPT/pySNOPT.py

View check run for this annotation

Codecov / codecov/patch

pyoptsparse/pySNOPT/pySNOPT.py#L704

Added line #L704 was not covered by tests
elif isinstance(value, float):
snopt.snsetr(name, value, iPrint, iSumm, inform, cw, iw, rw)
elif isinstance(value, int):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_nonexistent_path(self):
if "snopt" in key:
sys.modules.pop(key)
with self.assertWarns(UserWarning):
module = try_import_compiled_module_from_path("snopt", "/a/nonexistent/path")
module = try_import_compiled_module_from_path("snopt", "/a/nonexistent/path", raise_warning=True)
self.assertTrue(isinstance(module, str))

def test_sys_path_unchanged(self):
Expand Down
Loading