Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6614a90
Add MAPDL launcher support for HPC and process management
germa89 Feb 13, 2026
fc4c73d
chore: merge remote-tracking branch 'origin/main' into refactor/launc…
germa89 Feb 13, 2026
ba29c57
chore: adding changelog file 4416.miscellaneous.md [dependabot-skip]
pyansys-ci-bot Feb 13, 2026
fb90508
Apply suggestions from code review
germa89 Feb 16, 2026
92a8222
ci: auto fixes from pre-commit.com hooks.
pre-commit-ci[bot] Feb 16, 2026
64052fc
fix: improve handling of command execution and directory readiness in…
germa89 Feb 16, 2026
48ff5bb
Merge branch 'refactor/launcher.py' of https://github.com/ansys/pymap…
germa89 Feb 16, 2026
09a926a
Merge branch 'main' into refactor/launcher.py
germa89 Feb 16, 2026
2688f5b
feat: removing old launcher tests
germa89 Feb 16, 2026
8ff0b10
feat: Add unit tests for launcher module components
germa89 Feb 16, 2026
06f3492
feat: enhance launcher connection with additional parameters and impr…
germa89 Feb 16, 2026
fbf3c99
fix: increase maxfail limit in pytest configuration to allow more tes…
germa89 Feb 16, 2026
96a0378
feat: update pytest arguments for local and remote testing workflows
germa89 Feb 17, 2026
625ad10
feat: add fixture to patch get_mapdl_path for testing environment
germa89 Feb 17, 2026
67ca5b4
feat: deprecate start_timeout parameter in launcher functions and upd…
germa89 Feb 17, 2026
dbe3520
fix: add missing newline before module docstring in xpl.py
germa89 Feb 17, 2026
e95c4fe
docs: Enhance documentation for network and process management functions
germa89 Feb 17, 2026
5458489
chore: merge remote-tracking branch 'origin/main' into refactor/launc…
germa89 Feb 17, 2026
d2dac30
feat: enhance environment detection and preparation tests for Ubuntu …
germa89 Feb 17, 2026
b67d14c
feat: enhance environment detection and preparation tests for Ubuntu …
germa89 Feb 17, 2026
3a8ff69
feat: add comprehensive tests for socket and process handling in netw…
germa89 Feb 17, 2026
9f7117c
feat: add comprehensive tests for SLURM resource calculation and job …
germa89 Feb 17, 2026
b3dd7e5
feat: enhance tests for process handling in launcher module with comp…
germa89 Feb 17, 2026
9319fcd
feat: add comprehensive tests for SLURM resource calculation and job …
germa89 Feb 17, 2026
bcb1e0b
feat: add tests for IP address resolution and deprecate start_timeout…
germa89 Feb 17, 2026
e2576b6
feat: enhance tests for PyPIM integration with comprehensive coverage…
germa89 Feb 17, 2026
d5bb008
build: update ansys-tools-visualization-interface version constraint
germa89 Feb 18, 2026
b84f7a8
build: update ansys-tools-visualization-interface version constraint …
germa89 Feb 18, 2026
a050779
feat: implementing launch_mapdl_process.
germa89 Feb 18, 2026
7c08bd1
chore: merge branch 'refactor/launcher.py' into tests/adding-more-tes…
germa89 Feb 18, 2026
4d848c4
build: adding python 3.10 versions on dependencies to fix uv run issu…
germa89 Feb 18, 2026
6c9ff6c
chore: merge branch 'refactor/launcher.py' into tests/adding-more-tes…
germa89 Feb 18, 2026
23ba24d
feat: enhance CLI argument handling and suppress logging in start fun…
germa89 Feb 18, 2026
506847f
chore: merge remote-tracking branch 'origin/main' into refactor/launc…
germa89 Feb 19, 2026
8d7ab72
fix: update exclude-paths in dependabot.yml to remove leading slash
germa89 Feb 19, 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
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ updates:
exclude:
- "ansys-tools-visualization-interface"
exclude-paths:
- "/doc/source/examples/extended_examples/**"
- "doc/source/examples/extended_examples/**"
groups:
minimal:
patterns:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-remote.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
PYANSYS_OFF_SCREEN: True
PYMAPDL_DB_PORT: 21002 # default won't work on GitHub runners
PYMAPDL_DB_PORT2: 21003 # default won't work on GitHub runners
PYMAPDL_DEBUG_TESTING: True
PYMAPDL_DEBUG_TESTING: False
PYMAPDL_GRPC_TRANSPORT: 'insecure'
PYMAPDL_PORT: 21000 # default won't work on GitHub runners
PYMAPDL_PORT2: 21001 # for the pool testing and default won't work on GitHub runners
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/4416.miscellaneous.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Launcher according to modules
1 change: 1 addition & 0 deletions doc/source/api/launcher.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ library `ansys-tools-common.path <ansys_tools_common_>`_.
get_default_ansys_path
get_default_ansys_version
launch_mapdl
launch_mapdl_process
close_all_local_instances


Expand Down
37 changes: 37 additions & 0 deletions doc/source/getting_started/launcher.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,43 @@
description of the :func:`launch_mapdl() <ansys.mapdl.core.launcher.launch_mapdl>` function.


Launch MAPDL process without creating a client
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sometimes you may want to launch a MAPDL process without immediately creating a
client connection. This is useful for:

* Starting MAPDL from the command-line interface (CLI)

Check warning on line 51 in doc/source/getting_started/launcher.rst

View workflow job for this annotation

GitHub Actions / Documentation style doc

[vale] reported by reviewdog 🐶 [Google.WordList] Use 'command-line tool' instead of 'CLI'. Raw Output: {"message": "[Google.WordList] Use 'command-line tool' instead of 'CLI'.", "location": {"path": "doc/source/getting_started/launcher.rst", "range": {"start": {"line": 51, "column": 51}}}, "severity": "WARNING"}
* Managing multiple MAPDL instances programmatically
* Launching MAPDL in a separate process for later connection

For these scenarios, you can use the :func:`launch_mapdl_process() <ansys.mapdl.core.launcher.launch_mapdl_process>`
function, which starts MAPDL and returns connection information without creating a client:

.. code:: pycon

>>> from ansys.mapdl.core.launcher import launch_mapdl_process
>>> ip, port, pid = launch_mapdl_process(nproc=4, port=50052)
>>> print(f"MAPDL is running at {ip}:{port} (PID: {pid})")
MAPDL is running at 127.0.0.1:50052 (PID: 12345)

You can later connect to this instance using the :class:`Mapdl <ansys.mapdl.core.Mapdl>` class:

.. code:: pycon

>>> from ansys.mapdl.core import Mapdl
>>> mapdl = Mapdl(ip=ip, port=port)

This approach gives you more control over the MAPDL process lifecycle and allows
you to manage the process independently from the client connection.

.. note::
The :func:`launch_mapdl_process() <ansys.mapdl.core.launcher.launch_mapdl_process>`
function always starts a new MAPDL instance. It cannot be used to connect to
an existing instance. Use :func:`launch_mapdl() <ansys.mapdl.core.launcher.launch_mapdl>`
with ``start_instance=False`` for that purpose.


Connect PyMAPDL to a local MAPDL instance
-----------------------------------------

Expand Down
14 changes: 9 additions & 5 deletions doc/source/user_guide/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,13 @@ If you want to specify an argument, for instance the port, then you need to call
Success: Launched an MAPDL instance (PID=18238) at 127.0.0.1:50054


This ``pymapdl start`` command aims to replicate the function
:func:`ansys.mapdl.core.launcher.launch_mapdl`. Hence, you can use
some of the arguments which this function allows.
For instance, you could specify the working directory:
This ``pymapdl start`` command uses the
:func:`ansys.mapdl.core.launcher.launch_mapdl_process` function internally
to start MAPDL without creating a client connection. The command returns the
connection information (IP, port, and PID) that you can use to connect later.

Some of the arguments that :func:`ansys.mapdl.core.launcher.launch_mapdl` allows
are also available in the CLI. For instance, you could specify the working directory:

.. tab-set::

Expand All @@ -80,7 +83,8 @@ For instance, you could specify the working directory:
Success: Launched an MAPDL instance (PID=32612) at 127.0.0.1:50052


For more information, see :func:`ansys.mapdl.core.launcher.launch_mapdl`.
For more information about the underlying function, see
:func:`ansys.mapdl.core.launcher.launch_mapdl_process`.


Stop MAPDL instances
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ addopts = [
"--durations=30",
"--log-file-level=DEBUG",
"--log-file=pytest.log",
"--maxfail=2",
"--maxfail=2000",
"--profile",
"--profile-svg",
"--random-order",
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/mapdl/core/_numpy_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
removed or deprecated in newer versions.

NumPy 2.0+ Compatibility
=========================
========================

NumPy removed in1d in version 2.0 (replaced by numpy.isin), but some of our
dependencies may still reference it, causing AttributeError on import.
Expand Down
101 changes: 56 additions & 45 deletions src/ansys/mapdl/core/cli/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,102 +192,113 @@ def start(
replace_env_vars: Dict[str, str], # ignored
version: Union[int, str],
) -> None:
from ansys.mapdl.core.launcher import launch_mapdl
import logging

if mode:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'mode'.\nIgnoring argument."
)
from ansys.mapdl.core.launcher import launch_mapdl_process

if loglevel:
if mode is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'loglevel'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'mode'. Ignoring argument."
)

if cleanup_on_exit:
if cleanup_on_exit is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'cleanup_on_exit'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'cleanup_on_exit'. Ignoring argument."
)

if start_instance:
if start_instance is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'start_instance'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'start_instance'. Ignoring argument."
)

if ip:
if ip is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'ip'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'ip'. Ignoring argument."
)

if clear_on_connect:
if clear_on_connect is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'clear_on_connect'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'clear_on_connect'. Ignoring argument."
)

if log_apdl:
if log_apdl is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'log_apdl'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'log_apdl'. Ignoring argument."
)

if remove_temp_dir_on_exit:
if remove_temp_dir_on_exit is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'remove_temp_dir_on_exit'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'remove_temp_dir_on_exit'. Ignoring argument."
)

if print_com:
if print_com is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'print_com'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'print_com'. Ignoring argument."
)

if add_env_vars:
if add_env_vars is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'add_env_vars'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'add_env_vars'. Ignoring argument."
)

if replace_env_vars:
if replace_env_vars is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'replace_env_vars'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'replace_env_vars'. Ignoring argument."
)

if license_server_check:
if license_server_check is not None:
click.echo(
click.style("Warn:", fg="yellow")
+ " The following argument is not allowed in CLI: 'license_server_check'.\nIgnoring argument."
+ " The following argument is not allowed in CLI: 'license_server_check'. Ignoring argument."
)

# Ignoring env var if using CLI
if "PYMAPDL_START_INSTANCE" in os.environ:
os.environ.pop("PYMAPDL_START_INSTANCE")

out = launch_mapdl(
exec_file=exec_file,
just_launch=True,
run_location=run_location,
jobname=jobname,
nproc=nproc,
ram=ram,
override=override,
additional_switches=additional_switches,
start_timeout=start_timeout,
port=port,
license_type=license_type,
version=version,
)
# Suppress all logging to stdout when using CLI
from ansys.mapdl.core import LOG

if not loglevel:
LOG.setLevel(
logging.CRITICAL + 1
) # Set to a level higher than CRITICAL to suppress all logs
if LOG.std_out_handler:
LOG.std_out_handler.setLevel(logging.CRITICAL + 1)

try:
ip_addr, port_num, pid = launch_mapdl_process(
exec_file=exec_file,
run_location=run_location,
jobname=jobname,
nproc=nproc,
ram=ram,
override=override,
additional_switches=additional_switches,
start_timeout=start_timeout,
port=port,
license_type=license_type,
version=version,
loglevel=loglevel, # Set to highest level to suppress all logging
)

except Exception as e:
click.echo(click.style("ERROR:", fg="red") + f" {e}")
exit(1)

if len(out) == 3:
header = f"Launched an MAPDL instance (PID={out[2]}) at "
if pid is not None:
header = f"Launched an MAPDL instance (PID={pid}) at "
else:
header = "Launched an MAPDL instance at "

click.echo(click.style("Success: ", fg="green") + header + f"{out[0]}:{out[1]}")
click.echo(click.style("Success: ", fg="green") + header + f"{ip_addr}:{port_num}")
Loading
Loading