|
25 | 25 | # Subprocess is needed to start the backend. But
|
26 | 26 | # the input is controlled by the library. Excluding bandit check.
|
27 | 27 | import subprocess # nosec B404
|
28 |
| -from typing import Dict, Optional |
| 28 | +from typing import Any, Dict, Optional, Union |
29 | 29 |
|
30 | 30 | from ansys.mapdl.core import LOG
|
31 | 31 | from ansys.mapdl.core.launcher.local import processing_local_arguments
|
|
40 | 40 | from ansys.mapdl.core.mapdl_grpc import MapdlGrpc
|
41 | 41 |
|
42 | 42 |
|
43 |
| -def launch_mapdl_grpc(): |
| 43 | +def launch_mapdl_grpc( |
| 44 | + exec_file: Optional[str] = None, |
| 45 | + run_location: Optional[str] = None, |
| 46 | + jobname: str = "file", |
| 47 | + *, |
| 48 | + nproc: Optional[int] = None, |
| 49 | + ram: Optional[Union[int, str]] = None, |
| 50 | + mode: Optional[str] = None, |
| 51 | + override: bool = False, |
| 52 | + loglevel: str = "ERROR", |
| 53 | + additional_switches: str = "", |
| 54 | + start_timeout: Optional[int] = None, |
| 55 | + port: Optional[int] = None, |
| 56 | + cleanup_on_exit: bool = True, |
| 57 | + start_instance: Optional[bool] = None, |
| 58 | + clear_on_connect: bool = True, |
| 59 | + log_apdl: Optional[Union[bool, str]] = None, |
| 60 | + remove_temp_dir_on_exit: bool = False, |
| 61 | + license_server_check: bool = False, |
| 62 | + license_type: Optional[bool] = None, |
| 63 | + print_com: bool = False, |
| 64 | + add_env_vars: Optional[Dict[str, str]] = None, |
| 65 | + replace_env_vars: Optional[Dict[str, str]] = None, |
| 66 | + version: Optional[Union[int, str]] = None, |
| 67 | + running_on_hpc: bool = True, |
| 68 | + launch_on_hpc: bool = False, |
| 69 | + mapdl_output: Optional[str] = None, |
| 70 | + **kwargs: Dict[str, Any], |
| 71 | +) -> MapdlGrpc: |
| 72 | + """Start MAPDL locally with gRPC interface. |
| 73 | +
|
| 74 | + Parameters |
| 75 | + ---------- |
| 76 | + exec_file : str, optional |
| 77 | + The location of the MAPDL executable. Will use the cached |
| 78 | + location when left at the default :class:`None` and no environment |
| 79 | + variable is set. |
| 80 | +
|
| 81 | + The executable path can be also set through the environment variable |
| 82 | + :envvar:`PYMAPDL_MAPDL_EXEC`. For example: |
| 83 | +
|
| 84 | + .. code:: console |
| 85 | +
|
| 86 | + export PYMAPDL_MAPDL_EXEC=/ansys_inc/v211/ansys/bin/mapdl |
| 87 | +
|
| 88 | + run_location : str, optional |
| 89 | + MAPDL working directory. Defaults to a temporary working |
| 90 | + directory. If directory doesn't exist, one is created. |
| 91 | +
|
| 92 | + jobname : str, optional |
| 93 | + MAPDL jobname. Defaults to ``'file'``. |
| 94 | +
|
| 95 | + nproc : int, optional |
| 96 | + Number of processors. Defaults to ``2``. If running on an HPC cluster, |
| 97 | + this value is adjusted to the number of CPUs allocated to the job, |
| 98 | + unless the argument ``running_on_hpc`` is set to ``"false"``. |
| 99 | +
|
| 100 | + ram : float, optional |
| 101 | + Total size in megabytes of the workspace (memory) used for the initial |
| 102 | + allocation. The default is :class:`None`, in which case 2 GB (2048 MB) is |
| 103 | + used. To force a fixed size throughout the run, specify a negative |
| 104 | + number. |
| 105 | +
|
| 106 | + mode : str, optional |
| 107 | + Mode to launch MAPDL. Must be one of the following: |
| 108 | +
|
| 109 | + - ``'grpc'`` |
| 110 | + - ``'console'`` |
| 111 | +
|
| 112 | + The ``'grpc'`` mode is available on ANSYS 2021R1 or newer and |
| 113 | + provides the best performance and stability. |
| 114 | + The ``'console'`` mode is for legacy use only Linux only prior to 2020R2. |
| 115 | + This console mode is pending depreciation. |
| 116 | + Visit :ref:`versions_and_interfaces` for more information. |
| 117 | +
|
| 118 | + override : bool, optional |
| 119 | + Attempts to delete the lock file at the ``run_location``. |
| 120 | + Useful when a prior MAPDL session has exited prematurely and |
| 121 | + the lock file has not been deleted. |
| 122 | +
|
| 123 | + loglevel : str, optional |
| 124 | + Sets which messages are printed to the console. ``'INFO'`` |
| 125 | + prints out all ANSYS messages, ``'WARNING'`` prints only |
| 126 | + messages containing ANSYS warnings, and ``'ERROR'`` logs only |
| 127 | + error messages. |
| 128 | +
|
| 129 | + additional_switches : str, optional |
| 130 | + Additional switches for MAPDL, for example ``'aa_r'``, the |
| 131 | + academic research license, would be added with: |
| 132 | +
|
| 133 | + - ``additional_switches="-aa_r"`` |
| 134 | +
|
| 135 | + Avoid adding switches like ``-i``, ``-o`` or ``-b`` as these are already |
| 136 | + included to start up the MAPDL server. See the notes |
| 137 | + section for additional details. |
| 138 | +
|
| 139 | + start_timeout : float, optional |
| 140 | + Maximum allowable time to connect to the MAPDL server. By default it is |
| 141 | + 45 seconds, however, it is increased to 90 seconds if running on HPC. |
| 142 | +
|
| 143 | + port : int |
| 144 | + Port to launch MAPDL gRPC on. Final port will be the first |
| 145 | + port available after (or including) this port. Defaults to |
| 146 | + ``50052``. You can also provide this value through the environment variable |
| 147 | + :envvar:`PYMAPDL_PORT`. For instance ``PYMAPDL_PORT=50053``. |
| 148 | + However the argument (if specified) has precedence over the environment |
| 149 | + variable. If this environment variable is empty, it is as it is not set. |
| 150 | +
|
| 151 | + cleanup_on_exit : bool, optional |
| 152 | + Exit MAPDL when python exits or the mapdl Python instance is |
| 153 | + garbage collected. |
| 154 | +
|
| 155 | + start_instance : bool, optional |
| 156 | + When :class:`False`, connect to an existing MAPDL instance at ``ip`` |
| 157 | + and ``port``, which default to ip ``'127.0.0.1'`` at port ``50052``. |
| 158 | + Otherwise, launch a local instance of MAPDL. You can also |
| 159 | + provide this value through the environment variable |
| 160 | + :envvar:`PYMAPDL_START_INSTANCE`. |
| 161 | + However the argument (if specified) has precedence over the environment |
| 162 | + variable. If this environment variable is empty, it is as it is not set. |
| 163 | +
|
| 164 | + clear_on_connect : bool, optional |
| 165 | + Defaults to :class:`True`, giving you a fresh environment when |
| 166 | + connecting to MAPDL. When if ``start_instance`` is specified |
| 167 | + it defaults to :class:`False`. |
| 168 | +
|
| 169 | + log_apdl : str, optional |
| 170 | + Enables logging every APDL command to the local disk. This |
| 171 | + can be used to "record" all the commands that are sent to |
| 172 | + MAPDL via PyMAPDL so a script can be run within MAPDL without |
| 173 | + PyMAPDL. This argument is the path of the output file (e.g. |
| 174 | + ``log_apdl='pymapdl_log.txt'``). By default this is disabled. |
| 175 | +
|
| 176 | + remove_temp_dir_on_exit : bool, optional |
| 177 | + When ``run_location`` is :class:`None`, this launcher creates a new MAPDL |
| 178 | + working directory within the user temporary directory, obtainable with |
| 179 | + ``tempfile.gettempdir()``. When this parameter is |
| 180 | + :class:`True`, this directory will be deleted when MAPDL is exited. |
| 181 | + Default to :class:`False`. |
| 182 | + If you change the working directory, PyMAPDL does not delete the original |
| 183 | + working directory nor the new one. |
| 184 | +
|
| 185 | + license_server_check : bool, optional |
| 186 | + Check if the license server is available if MAPDL fails to |
| 187 | + start. Only available on ``mode='grpc'``. Defaults :class:`False`. |
| 188 | +
|
| 189 | + license_type : str, optional |
| 190 | + Enable license type selection. You can input a string for its |
| 191 | + license name (for example ``'meba'`` or ``'ansys'``) or its description |
| 192 | + ("enterprise solver" or "enterprise" respectively). |
| 193 | + You can also use legacy licenses (for example ``'aa_t_a'``) but it will |
| 194 | + also raise a warning. If it is not used (:class:`None`), no specific |
| 195 | + license will be requested, being up to the license server to provide a |
| 196 | + specific license type. Default is :class:`None`. |
| 197 | +
|
| 198 | + print_com : bool, optional |
| 199 | + Print the command ``/COM`` arguments to the standard output. |
| 200 | + Default :class:`False`. |
| 201 | +
|
| 202 | + add_env_vars : dict, optional |
| 203 | + The provided dictionary will be used to extend the MAPDL process |
| 204 | + environment variables. If you want to control all of the environment |
| 205 | + variables, use the argument ``replace_env_vars``. |
| 206 | + Defaults to :class:`None`. |
| 207 | +
|
| 208 | + replace_env_vars : dict, optional |
| 209 | + The provided dictionary will be used to replace all the MAPDL process |
| 210 | + environment variables. It replace the system environment variables |
| 211 | + which otherwise would be used in the process. |
| 212 | + To just add some environment variables to the MAPDL |
| 213 | + process, use ``add_env_vars``. Defaults to :class:`None`. |
| 214 | +
|
| 215 | + version : float, optional |
| 216 | + Version of MAPDL to launch. If :class:`None`, the latest version is used. |
| 217 | + Versions can be provided as integers (i.e. ``version=222``) or |
| 218 | + floats (i.e. ``version=22.2``). |
| 219 | + To retrieve the available installed versions, use the function |
| 220 | + :meth:`ansys.tools.path.path.get_available_ansys_installations`. |
| 221 | + You can also provide this value through the environment variable |
| 222 | + :envvar:`PYMAPDL_MAPDL_VERSION`. |
| 223 | + For instance ``PYMAPDL_MAPDL_VERSION=22.2``. |
| 224 | + However the argument (if specified) has precedence over the environment |
| 225 | + variable. If this environment variable is empty, it is as it is not set. |
| 226 | +
|
| 227 | + running_on_hpc: bool, optional |
| 228 | + Whether detect if PyMAPDL is running on an HPC cluster. Currently |
| 229 | + only SLURM clusters are supported. By default, it is set to true. |
| 230 | + This option can be bypassed if the :envvar:`PYMAPDL_RUNNING_ON_HPC` |
| 231 | + environment variable is set to :class:`True`. |
| 232 | + For more information, see :ref:`ref_hpc_slurm`. |
| 233 | +
|
| 234 | + launch_on_hpc : bool, Optional |
| 235 | + If :class:`True`, it uses the implemented scheduler (SLURM only) to launch |
| 236 | + an MAPDL instance on the HPC. In this case you can pass the |
| 237 | + '`scheduler_options`' argument to |
| 238 | + :func:`launch_mapdl() <ansys.mapdl.core.launcher.launch_mapdl>` |
| 239 | + to specify the scheduler arguments as a string or as a dictionary. |
| 240 | + For more information, see :ref:`ref_hpc_slurm`. |
| 241 | +
|
| 242 | + mapdl_output : str, optional |
| 243 | + Redirect the MAPDL console output to a given file. |
| 244 | +
|
| 245 | + kwargs : dict, Optional |
| 246 | + These keyword arguments are interface-specific or for |
| 247 | + development purposes. For more information, see Notes. |
| 248 | +
|
| 249 | + scheduler_options : :class:`str`, :class:`dict` |
| 250 | + Use it to specify options to the scheduler run command. It can be a |
| 251 | + string or a dictionary with arguments and its values (both as strings). |
| 252 | + For more information visit :ref:`ref_hpc_slurm`. |
| 253 | +
|
| 254 | + set_no_abort : :class:`bool` |
| 255 | + *(Development use only)* |
| 256 | + Sets MAPDL to not abort at the first error within /BATCH mode. |
| 257 | + Defaults to :class:`True`. |
| 258 | +
|
| 259 | + force_intel : :class:`bool` |
| 260 | + *(Development use only)* |
| 261 | + Forces the use of Intel message pass interface (MPI) in versions between |
| 262 | + Ansys 2021R0 and 2022R2, where because of VPNs issues this MPI is |
| 263 | + deactivated by default. |
| 264 | + See :ref:`vpn_issues_troubleshooting` for more information. |
| 265 | + Defaults to :class:`False`. |
| 266 | +
|
| 267 | + Returns |
| 268 | + ------- |
| 269 | + MapdlGrpc |
| 270 | + An instance of Mapdl. |
| 271 | + """ |
44 | 272 | args = processing_local_arguments(locals())
|
45 |
| - if args.get("mode", "grpc") != "grpc": |
46 |
| - raise ValueError("Invalid 'mode'.") |
| 273 | + |
47 | 274 | args["port"] = get_port(args["port"], args["start_instance"])
|
48 | 275 |
|
49 | 276 | start_parm = generate_start_parameters(args)
|
50 | 277 |
|
51 |
| - # Early exit for debugging. |
52 |
| - if args["_debug_no_launch"]: |
53 |
| - # Early exit, just for testing |
54 |
| - return args # type: ignore |
55 |
| - |
56 | 278 | # Check the license server
|
57 | 279 | if args["license_server_check"]:
|
58 | 280 | LOG.debug("Checking license server.")
|
59 | 281 | lic_check = LicenseChecker(timeout=args["start_timeout"])
|
60 | 282 | lic_check.start()
|
61 | 283 |
|
62 |
| - ######################################## |
63 |
| - # Launch MAPDL with gRPC |
64 |
| - # ---------------------- |
65 |
| - # |
66 |
| - cmd = generate_mapdl_launch_command( |
67 |
| - exec_file=args["exec_file"], |
68 |
| - jobname=args["jobname"], |
69 |
| - nproc=args["nproc"], |
70 |
| - ram=args["ram"], |
71 |
| - port=args["port"], |
72 |
| - additional_switches=args["additional_switches"], |
| 284 | + ######################################## |
| 285 | + # Launch MAPDL with gRPC |
| 286 | + # ---------------------- |
| 287 | + # |
| 288 | + cmd = generate_mapdl_launch_command( |
| 289 | + exec_file=args["exec_file"], |
| 290 | + jobname=args["jobname"], |
| 291 | + nproc=args["nproc"], |
| 292 | + ram=args["ram"], |
| 293 | + port=args["port"], |
| 294 | + additional_switches=args["additional_switches"], |
| 295 | + ) |
| 296 | + |
| 297 | + try: |
| 298 | + # Launching MAPDL |
| 299 | + process = launch_grpc( |
| 300 | + cmd=cmd, |
| 301 | + run_location=args["run_location"], |
| 302 | + env_vars=args["env_vars"], |
| 303 | + launch_on_hpc=args.get("launch_on_hpc"), |
| 304 | + mapdl_output=args.get("mapdl_output"), |
73 | 305 | )
|
74 | 306 |
|
75 |
| - try: |
76 |
| - # |
77 |
| - process = launch_grpc( |
78 |
| - cmd=cmd, |
79 |
| - run_location=args["run_location"], |
80 |
| - env_vars=env_vars, |
81 |
| - launch_on_hpc=args.get("launch_on_hpc"), |
82 |
| - mapdl_output=args.get("mapdl_output"), |
83 |
| - ) |
84 |
| - |
85 |
| - # Local mapdl launch check |
86 |
| - check_mapdl_launch( |
87 |
| - process, args["run_location"], args["start_timeout"], cmd |
88 |
| - ) |
89 |
| - |
90 |
| - except Exception as exception: |
91 |
| - LOG.error("An error occurred when launching MAPDL.") |
92 |
| - |
93 |
| - if args["license_server_check"]: |
94 |
| - LOG.debug("Checking license server.") |
95 |
| - lic_check.check() |
96 |
| - |
97 |
| - raise exception |
98 |
| - |
99 |
| - if args["just_launch"]: |
100 |
| - out = [args["ip"], args["port"]] |
101 |
| - if hasattr(process, "pid"): |
102 |
| - out += [process.pid] |
103 |
| - return out |
104 |
| - |
105 |
| - ######################################## |
106 |
| - # Connect to MAPDL using gRPC |
107 |
| - # --------------------------- |
108 |
| - # |
109 |
| - try: |
110 |
| - mapdl = MapdlGrpc( |
111 |
| - cleanup_on_exit=args["cleanup_on_exit"], |
112 |
| - loglevel=args["loglevel"], |
113 |
| - set_no_abort=args["set_no_abort"], |
114 |
| - remove_temp_dir_on_exit=args["remove_temp_dir_on_exit"], |
115 |
| - log_apdl=args["log_apdl"], |
116 |
| - process=process, |
117 |
| - use_vtk=args["use_vtk"], |
118 |
| - **start_parm, |
119 |
| - ) |
120 |
| - |
121 |
| - except Exception as exception: |
122 |
| - LOG.error("An error occurred when connecting to MAPDL.") |
123 |
| - raise exception |
124 |
| - |
125 |
| - return mapdl |
| 307 | + # Local mapdl launch check |
| 308 | + check_mapdl_launch(process, args["run_location"], args["start_timeout"], cmd) |
| 309 | + |
| 310 | + except Exception as exception: |
| 311 | + LOG.error("An error occurred when launching MAPDL.") |
| 312 | + |
| 313 | + if args["license_server_check"]: |
| 314 | + LOG.debug("Checking license server.") |
| 315 | + lic_check.check() |
| 316 | + |
| 317 | + raise exception |
| 318 | + |
| 319 | + ######################################## |
| 320 | + # Connect to MAPDL using gRPC |
| 321 | + # --------------------------- |
| 322 | + # |
| 323 | + try: |
| 324 | + mapdl = MapdlGrpc( |
| 325 | + cleanup_on_exit=args["cleanup_on_exit"], |
| 326 | + loglevel=args["loglevel"], |
| 327 | + set_no_abort=args["set_no_abort"], |
| 328 | + remove_temp_dir_on_exit=args["remove_temp_dir_on_exit"], |
| 329 | + log_apdl=args["log_apdl"], |
| 330 | + process=process, |
| 331 | + use_vtk=args["use_vtk"], |
| 332 | + **start_parm, |
| 333 | + ) |
| 334 | + |
| 335 | + except Exception as exception: |
| 336 | + LOG.error("An error occurred when connecting to MAPDL.") |
| 337 | + raise exception |
| 338 | + |
| 339 | + return mapdl |
126 | 340 |
|
127 | 341 |
|
128 | 342 | def launch_grpc(
|
|
0 commit comments