Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
937d55f
Update get-extensions and setup-environment logic for new major exten…
mrmundt Apr 15, 2026
8e9fbe0
Default should still be 3.4.2
mrmundt Apr 15, 2026
c8c1791
Make error more informative
mrmundt Apr 15, 2026
6acfdda
Add warning; fix path logic in multiple locations
mrmundt Apr 15, 2026
0b5f02c
Need the legacy_distro_map for pre 4
mrmundt Apr 15, 2026
4366931
Add a new subset of core tests that run the new IDAES release
mrmundt Apr 15, 2026
7cbee91
Arch logic wasn't exactly right
mrmundt Apr 15, 2026
71a92c2
Update name for clarity
mrmundt Apr 15, 2026
131abdb
See what happens with mac versions
mrmundt Apr 23, 2026
5c12d62
Merge branch 'main' into new-idaes-ext
mrmundt Jun 9, 2026
8c0dc3a
Merge branch 'main' into new-idaes-ext
mrmundt Jun 17, 2026
d373260
Resolve differences
mrmundt Jun 17, 2026
c2caff3
Let's try to get more info on what linux is doing
mrmundt Jun 17, 2026
9accd2f
Merge branch 'IDAES:main' into new-idaes-ext
mrmundt Jun 25, 2026
6aea4f4
Hard-coded bin_directory lookup path that doesn't work with new releases
mrmundt Jun 30, 2026
fa8dca3
Whoops, whole test suite please
mrmundt Jun 30, 2026
f561b07
It's being too verbose; also, turn off intel because it has fundament…
mrmundt Jun 30, 2026
34c31f0
missed a thing
mrmundt Jun 30, 2026
3fb3395
Begin to resolve some test issues that have more obvious solutions
mrmundt Jul 1, 2026
0339f0a
Merge branch 'new-idaes-ext' of github.com:mrmundt/idaes-pse into new…
mrmundt Jul 1, 2026
e66ae1d
Make both forwards and backwards comp
mrmundt Jul 1, 2026
812285a
Merge branch 'main' into new-idaes-ext
mrmundt Jul 16, 2026
090b3f7
Update tests to dynamically remove IDAES dir
mrmundt Jul 16, 2026
5e93577
fix negative numbers in soec design
dallan-keylogic Jul 16, 2026
c657600
Maybe it got uninstalled or confused about ampl stuff
mrmundt Jul 16, 2026
41799f7
Change the action to take a version to make this whole thing easier
mrmundt Jul 16, 2026
c19aaf4
fix model diagnostics issues
dallan-keylogic Jul 16, 2026
2808b07
See if we can rework SCIP path
mrmundt Jul 16, 2026
a6b918f
Mac is dumb because of library paths
mrmundt Jul 16, 2026
2955ec2
more iterations
dallan-keylogic Jul 17, 2026
43a8522
Merge branch 'new-idaes-ext' into idaes-ext-test-fixes
dallan-keylogic Jul 17, 2026
fc74fb0
skip demo flowsheet
dallan-keylogic Jul 17, 2026
d91fa37
Merge pull request #2 from dallan-keylogic/idaes-ext-test-fixes
mrmundt Jul 21, 2026
ba2fc24
xfail
dallan-keylogic Jul 21, 2026
dd37df4
reverse_ordering
dallan-keylogic Jul 21, 2026
eff2322
remember to change other file
dallan-keylogic Jul 21, 2026
ad0a6c5
Turn off mac tests
mrmundt Jul 21, 2026
2952d21
Whoops
mrmundt Jul 21, 2026
3c2fdbd
Need a whole slew of new integration tests
mrmundt Jul 21, 2026
b10e0f6
What is the result
mrmundt Jul 21, 2026
3191d1c
Blah
mrmundt Jul 21, 2026
463d6a9
UNDO THIS COMMIT: Testing new changes from @dallan-keylogic
mrmundt Jul 22, 2026
de712af
skip
dallan-keylogic Jul 22, 2026
e7acf65
Merge branch 'new-idaes-ext-fixed' into new-idaes-ext
dallan-keylogic Jul 22, 2026
ad0fb65
revert to IDAES examples
dallan-keylogic Jul 22, 2026
6115c68
Remove erroneous print statement
mrmundt Jul 23, 2026
211207b
Change names of tests; incorporate Doug's coverage change
mrmundt Jul 23, 2026
ee492e3
Don't need special macOS logic when we don't test that
mrmundt Jul 23, 2026
37024e7
Add a variety of unit tests to attempt to increase coverage
mrmundt Jul 24, 2026
0b07216
Merge branch 'main' into new-idaes-ext
mrmundt Jul 24, 2026
5408d93
Unnecessary test
mrmundt Jul 24, 2026
7991459
Set default version to 4.0.0rc2; see if codecov fix helps
mrmundt Jul 24, 2026
b0b9fb5
Revert because eh
mrmundt Jul 24, 2026
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
25 changes: 24 additions & 1 deletion .github/actions/setup-idaes/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ inputs:
description: pip install target (dist name and optionally version constraint) of AMPL SCIP solver to install
required: false
default: ampl-module-scip
version:
description: >-
IDAES extensions release to install (e.g. 4.0.0rc2). If unset, the default
release is installed. For releases 4.x and newer, the '--extra petsc'
option is omitted, since PETSc is bundled in the base package.
required: false
default: ''
runs:
using: "composite"
steps:
Expand Down Expand Up @@ -42,9 +49,25 @@ runs:
# idaes --version
- name: Install extensions
shell: bash -l {0}
env:
IDAES_EXT_VERSION: ${{ inputs.version }}
run: |
# Build up the get-extensions arguments based on the requested release.
get_ext_args=()
major=""
if [ -n "$IDAES_EXT_VERSION" ]; then
get_ext_args+=(--release "$IDAES_EXT_VERSION")
# Extract the leading integer of the version (e.g. "4" from "4.0.0rc2")
major="${IDAES_EXT_VERSION%%.*}"
fi
# PETSc is bundled in the base package for 4.x+ releases, so only request
# it as an extra for older releases (or when no version is specified).
if [ -z "$major" ] || [ "$major" -lt 4 ]; then
get_ext_args+=(--extra petsc)
fi

echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --extra petsc --verbose
idaes get-extensions "${get_ext_args[@]}" --verbose
echo '::endgroup::'

# extra dependencies must be installed on Ubuntu 24.04
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ jobs:
uses: ./.github/actions/setup-idaes
with:
install-target: -r requirements-dev.txt
version: '4.0.0rc2'
- name: Add pytest CLI options for coverage
if: matrix.cov-report
run: |
Expand All @@ -131,7 +132,7 @@ jobs:
run: conda install -c conda-forge pandoc
- name: Run pytest (not integration)
run: |
pytest --pyargs idaes -m "not integration"
python -m pytest --cov=idaes --pyargs idaes -m "not integration"
- name: Upload coverage report as GHA workflow artifact
if: matrix.cov-report
uses: actions/upload-artifact@v7
Expand Down Expand Up @@ -306,4 +307,4 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON_VERSION }}
os: linux
job-name: compat
job-name: compat
3 changes: 3 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ jobs:
uses: ./.github/actions/setup-idaes
with:
install-target: -r requirements-dev.txt
version: '4.0.0rc2'
- name: Run pytest (integration)
run: pytest --pyargs idaes -m integration

Expand Down Expand Up @@ -196,6 +197,7 @@ jobs:
uses: ./.github/actions/setup-idaes
with:
install-target: -r requirements-dev.txt
version: '4.0.0rc2'
- name: Fetch and run examples
uses: ./.github/actions/run-examples
with:
Expand Down Expand Up @@ -254,6 +256,7 @@ jobs:
uses: ./.github/actions/setup-idaes
with:
install-target: ${{ matrix.pip-install-target }}
version: '4.0.0rc2'
- name: Remove dependencies installable with pip but not with conda
# NOTE some dependencies that are installed by default with pip are not available through conda
# so they're not installed if IDAES is installed with `conda -c conda-forge idaes-pse`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ are not necessarily realistic.
m.fs.soec.oxygen_side_outlet_temperature.fix(1023)
m.fs.soec.water_utilization.fix(0.7)
iscale.calculate_scaling_factors(m)
m.fs.soec.initialize(optarg={"max_iter":30})
m.fs.soec.initialize(optarg={"max_iter":30, "bound_relax_factor": 0})
return m

# create a flowsheet with the SOEC model
Expand Down
21 changes: 20 additions & 1 deletion idaes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,27 @@ def _ensure_external_functions_libs_in_env(
):
libraries_str = os.environ.get(var_name, "")
libraries = [lib for lib in libraries_str.split(sep) if lib.strip()]

# External function libraries may live in either the old flat layout
# (<data>/bin) or the new install-prefix layout (<data>/lib). Search both,
# then fall back to a bare lookup that relies on LD_LIBRARY_PATH/PATH having
# already been configured by config.setup_environment().
search_dirs = []
if bin_directory is not None:
lib_directory = os.path.join(os.path.dirname(bin_directory), "lib")
if os.path.isdir(lib_directory):
search_dirs.append(lib_directory)
search_dirs.append(bin_directory)

for func_name in ext_funcs:
lib: Optional[str] = find_library(os.path.join(bin_directory, func_name))
lib: Optional[str] = None
for d in search_dirs:
lib = find_library(os.path.join(d, func_name))
if lib is not None:
break
if lib is None:
# Last resort: let find_library use the configured search paths.
lib = find_library(func_name)
if lib is not None and lib not in libraries:
libraries.append(lib)
os.environ[var_name] = sep.join(libraries)
Expand Down
159 changes: 128 additions & 31 deletions idaes/commands/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@
import click

import idaes
from idaes.config import base_platforms, binary_distro_map, binary_arch_map
from idaes.config import canonical_arch, canonical_distro
from idaes.config import (
base_platforms,
binary_distro_map,
binary_arch_map,
canonical_arch,
canonical_distro,
release_major,
)
import idaes.commands.util.download_bin
from idaes.commands import cb

Expand All @@ -47,44 +53,113 @@ def print_footer(echo=click.echo, width=65):
echo("=" * width)


def _get_extensions_root(bin_directory=None):
"""
Return the root directory where IDAES extensions are installed.

Old layout:
~/.idaes/bin/...
New layout:
~/.idaes/{bin,lib,include,share,...}
"""
if bin_directory is not None:
return bin_directory

# New layout
data_dir = idaes.data_directory
if any(
os.path.exists(os.path.join(data_dir, p))
for p in (
"lib",
"VERSION_SOLVERS.md",
"VERSION_FUNCTIONS.md",
"LICENSE.md",
"LICENSE_FUNCTIONS.md",
)
):
return data_dir

# Fallback to old layout
return idaes.bin_directory


def _find_extensions_file(filename, bin_directory=None):
"""
Find a metadata file in either the new or old extensions layout.
"""
root = _get_extensions_root(bin_directory=bin_directory)

candidates = [
os.path.join(root, filename),
os.path.join(root, "bin", filename),
os.path.join(idaes.bin_directory, filename),
]

for path in candidates:
if os.path.isfile(path):
return path
return None


def print_extensions_version(library_only=False, bin_directory=None):
print_header("Build Versions")
if bin_directory is None:
bin_directory = idaes.bin_directory

if not library_only:
v = os.path.join(bin_directory, "version_solvers.txt")
try:
with open(v, "r") as f:
solver_file = _find_extensions_file(
"VERSION_SOLVERS.md", bin_directory
) or _find_extensions_file("version_solvers.txt", bin_directory)
if solver_file is not None:
with open(solver_file, "r") as f:
v = f.readline().strip()
except FileNotFoundError:
else:
v = "no version file found"
click.echo("Solvers: v{}".format(v))
v = os.path.join(bin_directory, "version_lib.txt")
try:
with open(v, "r") as f:
click.echo(f"Solvers: {v}")

library_file = _find_extensions_file(
"VERSION_FUNCTIONS.md", bin_directory
) or _find_extensions_file("version_lib.txt", bin_directory)
if library_file is not None:
with open(library_file, "r") as f:
v = f.readline().strip()
except FileNotFoundError:
else:
v = "no version file found"
click.echo("Library: v{}".format(v))
click.echo(f"Library: {v}")

print_footer()
return 0


def print_license():
print_header("License Information")
fpath = os.path.join(idaes.bin_directory, "license.txt")
try:

license_files = [
_find_extensions_file("LICENSE.md"),
_find_extensions_file("LICENSE_FUNCTIONS.md"),
_find_extensions_file("license.txt"),
_find_extensions_file("license_lib.txt"),
]

printed = False
seen = set()
for fpath in license_files:
if fpath is None or fpath in seen:
continue
seen.add(fpath)
with open(fpath, "r") as f:
for line in f.readlines():
click.echo(line.strip())
except FileNotFoundError:
for line in f:
click.echo(line.rstrip())
click.echo("")
printed = True

if not printed:
click.echo("no license file found")
click.echo("")

print_footer()
return 0


def print_build_info():
def print_build_info(release):
fd, _ = idaes.commands.util.download_bin._get_file_downloader(False, None)

print_header("Build Information")
Expand All @@ -111,7 +186,7 @@ def print_build_info():
_, platform = idaes.commands.util.download_bin._get_arch_and_platform(fd, "auto")
arch = machine()
to_platform = canonical_distro(platform)
to_mach = canonical_arch(arch)
to_mach = canonical_arch(arch, release=release, platform=to_platform)
to_build = f"{to_platform}-{to_mach}"
has_build = to_build in base_platforms

Expand Down Expand Up @@ -179,7 +254,9 @@ def get_extensions(
"""Main sub-command."""
cmd_name = "idaes get-extensions"
if info:
print_build_info()
if release is None:
release = idaes.config.default_binary_release
print_build_info(release)
return
if url is None and release is None:
# the default release is only used if neither a release or url is given
Expand Down Expand Up @@ -217,8 +294,16 @@ def get_extensions(
for k, i in d.items():
click.echo(f"{k:14}: {i}")
else:
# If `to` is None, we default to idaes.bin_directory.
print_extensions_version(library_only=library_only, bin_directory=to)
# With the newest release of the IDAES extensions, the files
# are one level up, similar to a standard install prefix
# structure. So we will manually set the path to save
# some time.
if release_major(release) >= 4:
print_extensions_version(
library_only=library_only, bin_directory=idaes.data_directory
)
else:
print_extensions_version(library_only=library_only, bin_directory=to)
else:
click.echo("\n* You must provide a download URL for IDAES binary files.")

Expand All @@ -235,6 +320,7 @@ def hash_extensions(release, path):
hfile = f"sha256sum_{release}.txt"
if path is not None:
hfile = os.path.join(path, hfile)
major = release_major(release)

def _write_hash(fp, pack, plat):
f = f"idaes-{pack}-{plat}.tar.gz"
Expand All @@ -249,14 +335,21 @@ def _write_hash(fp, pack, plat):

with open(hfile, "w") as f:
for plat in idaes.config.base_platforms:
for pack in ["solvers", "lib"]:
_write_hash(f, pack, plat)
for plat in idaes.config.base_platforms:
for pack, sp in idaes.config.extra_binaries.items():
if plat not in sp:
continue
if major >= 4:
packs = ["solvers", "functions"]
else:
packs = ["solvers", "lib"]

for pack in packs:
_write_hash(f, pack, plat)

if major < 4:
for plat in idaes.config.base_platforms:
for pack, sp in idaes.config.extra_binaries.items():
if plat not in sp:
continue
_write_hash(f, pack, plat)


@cb.command(name="bin-platform", help="Show the compatible binary build.")
@click.option("--distro", default="auto")
Expand All @@ -266,7 +359,11 @@ def bin_platform(distro):
_, platform = idaes.commands.util.download_bin._get_arch_and_platform(
fd, distro
)
click.echo(idaes.commands.util.download_bin._get_release_platform(platform))
click.echo(
idaes.commands.util.download_bin._get_release_platform(
platform, idaes.config.default_binary_release
)
)
except idaes.commands.util.download_bin.UnsupportedPlatformError:
click.echo(
f"No supported binaries found for {platform}. "
Expand Down
Loading
Loading