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

Remove deprecated gurobipy addConstr call #3350

Merged
merged 11 commits into from
Aug 28, 2024

Conversation

quantresearch1
Copy link
Contributor

Summary/Motivation:

With both the previous and latest major gurobi versions, we get a deprecation warning when calling model.addConstr.

Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.

import gurobipy as gp
m = gp.Model()
Restricted license - for non-production use only - expires 2025-11-24
x = m.addVar()
m.addConstr(lhs=x+1, sense=gp.GRB.EQUAL, rhs=0)
:1: DeprecationWarning: Deprecated, pass a TempConstr or use Model.addLConstr
<gurobi.Constr Awaiting Model Update>

Changes proposed in this PR:

  • Use the constraint's degree to either call addLConstr or addQConstr

Legal Acknowledgement

By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the BSD license.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

@quantresearch1
Copy link
Contributor Author

Hi, I am currently testing this PR by running: python examples/pyomo/columngeneration/cutting_stock.py gurobi_persistent
It seems that my change calls gurobipy.Model before the deferred import are resolved, has anybody encountered this kind of error before ? I don't think it's related to my installation setup as the main branch runs fine.

File "d:\dev\pyomo\pyomo\solvers\plugins\solvers\GUROBI.py", line 38, in
from .gurobi_direct import gurobipy_available
File "d:\dev\pyomo\pyomo\solvers\plugins\solvers\gurobi_direct.py", line 100, in
class GurobiModel(gurobipy.Model):
File "d:\dev\pyomo\pyomo\common\dependencies.py", line 170, in getattr
return getattr(_mod, attr)
File "d:\dev\pyomo\pyomo\common\dependencies.py", line 77, in getattr
raise DeferredImportError(self._moduleunavailable_message())
pyomo.common.errors.DeferredImportError: The gurobipy module (an optional Pyomo dependency) failed to import: NameError: name 'GurobiDirect' is not defined

con.canonical_form(), self._max_constraint_degree
)
# elif isinstance(con, LinearCanonicalRepn):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this commented block something that should be kept ? Happy to leave it as is to minimize the diff

Copy link
Member

Choose a reason for hiding this comment

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

I think that is completely removable (looking back, I think LinearCanonicalRepn disappeared from Pyomo more than 7 years ago).

@jsiirola
Copy link
Member

Hi, I am currently testing this PR by running: python examples/pyomo/columngeneration/cutting_stock.py gurobi_persistent It seems that my change calls gurobipy.Model before the deferred import are resolved, has anybody encountered this kind of error before ? I don't think it's related to my installation setup as the main branch runs fine.

Yes - the problem is your definition of the GurobiModel class:

class GurobiModel(gurobipy.Model):

Parsing / compiling this definition (during module import) accesses the Model attribute on the gurobipy object (at this point, it is a DeferredImportModule object and not the gurobipy module). That attribute access triggers the deferred import system to attempt the import, which will fail if gurobipy is not actually available.

The simplest "workaround" might be something like:

class GurobiModel(gurobipy.Model if gurobipy_available else object):

However, that will run afoul of another test in the Pyomo unittest system: this solution still triggers the gurobipy import - when you implicitly cast gurobipy_available to a bool as part of the if. Because this module gets imported as part of pyomo.environ, this would force the import of gurobipy as part of pyomo.environ - and we have a test that checks that optional dependencies are not automatically imported by pyomo.environ.

The better solution is probably to define an _addConstr private method on the GurobiDirect class instead of defining a "wrapper" model class.

@quantresearch1
Copy link
Contributor Author

Thank you so much for your help @jsiirola, I have implemented your suggestion, and it works great!

@blnicho blnicho changed the title [WIP] Remove deprecated gurobipy addConstr call Remove deprecated gurobipy addConstr call Aug 20, 2024
@blnicho
Copy link
Member

blnicho commented Aug 20, 2024

@quantresearch1 I removed the [WIP] marking from the title to check the test status on this PR. Is this ready for review or still work in progress?

jsiirola
jsiirola previously approved these changes Aug 20, 2024
@quantresearch1
Copy link
Contributor Author

@blnicho thanks, let me fix the unit tests first before asking for a review

@quantresearch1
Copy link
Contributor Author

@blnicho I think I have fixed it. The issue was that for NumericConstant expression, the degree is 0. I would incorrectly raise a DegreeError as I was expecting _get_expr_from_pyomo_repn to only give me degrees 1 or 2

@quantresearch1
Copy link
Contributor Author

@jsiirola The win/3.9 build failed with a segmentation in conda, should I just give the CI another run ? Sorry I am not sure how to debug this issue.

Platform: win-64
Collecting package metadata (repodata.json): ...working... done
/c/Users/runneradmin/.bash_profile: line 347: 781 Segmentation fault ( "$CONDA_EXE" $_CE_M $_CE_CONDA "$@" )
Solving environment: ...working...
Error: Process completed with exit code 139

@jsiirola
Copy link
Member

@quantresearch1: the windows failure is an issue with conda that crops up with surprising regularity (the error is happening while trying to set up the conda environment and has nothing to do with Pyomo). Usually waiting a couple hours and re-running that job will clear it.

@quantresearch1
Copy link
Contributor Author

Great to see all checks are now passing. May I merge it ?

@mrmundt mrmundt merged commit cda2d02 into Pyomo:main Aug 28, 2024
32 checks passed
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.

5 participants