pyedb 0.60.0__py3-none-any.whl → 0.61.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyedb might be problematic. Click here for more details.
- pyedb/__init__.py +1 -1
- pyedb/configuration/cfg_components.py +35 -7
- pyedb/dotnet/database/cell/hierarchy/component.py +8 -6
- pyedb/dotnet/database/cell/hierarchy/model.py +1 -28
- pyedb/dotnet/database/cell/hierarchy/s_parameter_model.py +10 -14
- pyedb/dotnet/database/cell/hierarchy/spice_model.py +13 -7
- pyedb/dotnet/database/components.py +5 -1
- pyedb/dotnet/database/edb_data/padstacks_data.py +5 -3
- pyedb/dotnet/database/modeler.py +2 -1
- pyedb/dotnet/database/padstack.py +187 -1
- pyedb/dotnet/edb.py +70 -1
- pyedb/generic/general_methods.py +21 -0
- pyedb/grpc/database/definition/materials.py +1 -1
- pyedb/grpc/database/definition/padstack_def.py +16 -9
- pyedb/grpc/database/padstacks.py +201 -6
- pyedb/grpc/database/primitive/padstack_instance.py +90 -0
- pyedb/grpc/edb.py +70 -1
- pyedb/grpc/rpc_session.py +16 -3
- pyedb/workflows/__init__.py +21 -0
- pyedb/workflows/job_manager/__init__.py +21 -0
- pyedb/workflows/job_manager/backend/__init__.py +21 -0
- pyedb/workflows/job_manager/backend/job_manager_handler.py +910 -0
- pyedb/workflows/job_manager/backend/job_submission.py +1169 -0
- pyedb/workflows/job_manager/backend/service.py +1663 -0
- pyedb/workflows/job_manager/backend/start_service.py +86 -0
- pyedb/workflows/job_manager/backend/submit_job_on_scheduler.py +168 -0
- pyedb/workflows/job_manager/backend/submit_local_job.py +166 -0
- pyedb/workflows/utilities/__init__.py +21 -0
- pyedb/workflows/utilities/cutout.py +1 -1
- pyedb/workflows/utilities/hfss_log_parser.py +446 -0
- {pyedb-0.60.0.dist-info → pyedb-0.61.0.dist-info}/METADATA +7 -4
- {pyedb-0.60.0.dist-info → pyedb-0.61.0.dist-info}/RECORD +34 -24
- {pyedb-0.60.0.dist-info → pyedb-0.61.0.dist-info}/WHEEL +0 -0
- {pyedb-0.60.0.dist-info → pyedb-0.61.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
4
|
+
# SPDX-License-Identifier: MIT
|
|
5
|
+
#
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
Start the PyEDB Job-Manager service via JobManagerHandler.
|
|
27
|
+
|
|
28
|
+
Usage
|
|
29
|
+
-----
|
|
30
|
+
$ python start_service.py --host 0.0.0.0 --port 9090
|
|
31
|
+
✅ Job-manager backend listening on http://0.0.0.0:9090
|
|
32
|
+
Press Ctrl-C to shut down gracefully.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
import argparse
|
|
36
|
+
import signal
|
|
37
|
+
import sys
|
|
38
|
+
import threading
|
|
39
|
+
|
|
40
|
+
from pyedb.workflows.job_manager.backend.job_manager_handler import JobManagerHandler
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def parse_cli() -> argparse.Namespace:
|
|
44
|
+
parser = argparse.ArgumentParser(description="Start the PyEDB asynchronous job-manager service.")
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--host",
|
|
47
|
+
type=str,
|
|
48
|
+
default="localhost",
|
|
49
|
+
help="IP address or hostname to bind the server (default: localhost)",
|
|
50
|
+
)
|
|
51
|
+
parser.add_argument(
|
|
52
|
+
"--port",
|
|
53
|
+
type=int,
|
|
54
|
+
default=8080,
|
|
55
|
+
help="TCP port to listen on (default: 8080)",
|
|
56
|
+
)
|
|
57
|
+
return parser.parse_args()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def main():
|
|
61
|
+
args = parse_cli()
|
|
62
|
+
|
|
63
|
+
handler = JobManagerHandler(host=args.host, port=args.port)
|
|
64
|
+
handler.start_service() # non-blocking; spins up daemon thread + aiohttp
|
|
65
|
+
|
|
66
|
+
print(f"✅ Job-manager backend listening on http://{handler.host}:{handler.port}")
|
|
67
|
+
|
|
68
|
+
# Graceful shutdown on Ctrl-C
|
|
69
|
+
stop_event = threading.Event()
|
|
70
|
+
|
|
71
|
+
def _shutdown(sig, frame):
|
|
72
|
+
print("\nShutting down...")
|
|
73
|
+
stop_event.set()
|
|
74
|
+
|
|
75
|
+
signal.signal(signal.SIGINT, _shutdown)
|
|
76
|
+
signal.signal(signal.SIGTERM, _shutdown)
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
stop_event.wait() # keep main thread alive
|
|
80
|
+
finally:
|
|
81
|
+
handler.close()
|
|
82
|
+
sys.exit(0)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == "__main__":
|
|
86
|
+
main()
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
# --------------- submit_job_on_scheduler.py -----------------
|
|
24
|
+
#!/usr/bin/env python3
|
|
25
|
+
"""
|
|
26
|
+
Submit an HFSS job to the *scheduler* back-end service.
|
|
27
|
+
|
|
28
|
+
The service must be running (default: localhost:8080) before this script is executed.
|
|
29
|
+
To start it:
|
|
30
|
+
|
|
31
|
+
python -m pyedb.workflows.job_manager.backend.job_manager_handler
|
|
32
|
+
|
|
33
|
+
Usage
|
|
34
|
+
-----
|
|
35
|
+
# Get help
|
|
36
|
+
python submit_job_on_scheduler.py --help
|
|
37
|
+
|
|
38
|
+
# Explicit values
|
|
39
|
+
python submit_job_on_scheduler.py \
|
|
40
|
+
--host 127.0.0.1 \
|
|
41
|
+
--port 8080 \
|
|
42
|
+
--project-path "/tmp/jobs/job1.aedb" \
|
|
43
|
+
--partition default \
|
|
44
|
+
--nodes 1 \
|
|
45
|
+
--cores-per-node 8
|
|
46
|
+
|
|
47
|
+
# Use defaults (localhost:8080, 1 node, 1 core, partition default)
|
|
48
|
+
python submit_job_on_scheduler.py \
|
|
49
|
+
--project-path "/tmp/jobs/job1.aedb"
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
Submit an HFSS job to the SLURM back-end service.
|
|
54
|
+
Same CLI as submit_local_job.py, but forces SLURM execution.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
import argparse
|
|
58
|
+
import asyncio
|
|
59
|
+
import logging
|
|
60
|
+
from pathlib import Path
|
|
61
|
+
import sys
|
|
62
|
+
|
|
63
|
+
import aiohttp
|
|
64
|
+
|
|
65
|
+
from pyedb.workflows.job_manager.backend.job_submission import (
|
|
66
|
+
SchedulerOptions,
|
|
67
|
+
SchedulerType,
|
|
68
|
+
create_hfss_config,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
logging.basicConfig(level=logging.INFO, format="%(levelname)s | %(message)s")
|
|
72
|
+
logger = logging.getLogger(__name__)
|
|
73
|
+
|
|
74
|
+
DEFAULT_HOST = "localhost"
|
|
75
|
+
DEFAULT_PORT = 8080
|
|
76
|
+
DEFAULT_PARTITION = "default"
|
|
77
|
+
DEFAULT_NODES = 1
|
|
78
|
+
DEFAULT_CORES_PER_NODE = 1
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
async def submit_slurm_job(
|
|
82
|
+
*,
|
|
83
|
+
host: str,
|
|
84
|
+
port: int,
|
|
85
|
+
project_path: str,
|
|
86
|
+
partition: str,
|
|
87
|
+
nodes: int,
|
|
88
|
+
cores_per_node: int,
|
|
89
|
+
) -> None:
|
|
90
|
+
"""Send the SLURM job-configuration to the REST endpoint."""
|
|
91
|
+
backend_url = f"http://{host}:{port}"
|
|
92
|
+
|
|
93
|
+
# 1. Build the *generic* scheduler options that SLURM understands
|
|
94
|
+
scheduler_opts = SchedulerOptions(
|
|
95
|
+
queue=partition,
|
|
96
|
+
nodes=nodes,
|
|
97
|
+
cores_per_node=cores_per_node,
|
|
98
|
+
time="24:00:00", # you can expose --time if you wish
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# 2. Create the HFSS config (scheduler_type=SLURM is the key)
|
|
102
|
+
cfg = create_hfss_config(
|
|
103
|
+
project_path=project_path,
|
|
104
|
+
scheduler_options=scheduler_opts,
|
|
105
|
+
)
|
|
106
|
+
cfg.auto = True # keep the original behaviour
|
|
107
|
+
|
|
108
|
+
# 3. POST it
|
|
109
|
+
timeout = aiohttp.ClientTimeout(total=60)
|
|
110
|
+
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
111
|
+
try:
|
|
112
|
+
async with session.post(
|
|
113
|
+
f"{backend_url}/jobs/submit",
|
|
114
|
+
json={
|
|
115
|
+
"config": cfg.model_dump(mode="json", exclude_defaults=False),
|
|
116
|
+
"priority": 0,
|
|
117
|
+
},
|
|
118
|
+
) as resp:
|
|
119
|
+
status = resp.status
|
|
120
|
+
try:
|
|
121
|
+
reply = await resp.json()
|
|
122
|
+
except Exception:
|
|
123
|
+
reply = await resp.text()
|
|
124
|
+
|
|
125
|
+
if 200 <= status < 300:
|
|
126
|
+
logger.info("Job submitted successfully (status=%s)", status)
|
|
127
|
+
logger.debug("Server reply: %s", reply)
|
|
128
|
+
else:
|
|
129
|
+
logger.error("Job submission failed (status=%s): %s", status, reply)
|
|
130
|
+
except Exception as exc:
|
|
131
|
+
logger.exception("Failed to submit job to %s: %s", backend_url, exc)
|
|
132
|
+
sys.exit(2)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def parse_cli() -> argparse.Namespace:
|
|
136
|
+
parser = argparse.ArgumentParser(description="Submit an HFSS job to the scheduler back-end service.")
|
|
137
|
+
parser.add_argument("--host", default=DEFAULT_HOST)
|
|
138
|
+
parser.add_argument("--port", type=int, default=DEFAULT_PORT)
|
|
139
|
+
parser.add_argument("--project-path", required=True, type=Path)
|
|
140
|
+
parser.add_argument("--partition", default=DEFAULT_PARTITION)
|
|
141
|
+
parser.add_argument("--nodes", type=int, default=DEFAULT_NODES)
|
|
142
|
+
parser.add_argument("--cores-per-node", type=int, default=DEFAULT_CORES_PER_NODE)
|
|
143
|
+
return parser.parse_args()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def main() -> None:
|
|
147
|
+
args = parse_cli()
|
|
148
|
+
if not args.project_path.exists():
|
|
149
|
+
logger.error("Project path does not exist: %s", args.project_path)
|
|
150
|
+
sys.exit(1)
|
|
151
|
+
if args.nodes <= 0 or args.cores_per_node <= 0:
|
|
152
|
+
logger.error("--nodes and --cores-per-node must be positive")
|
|
153
|
+
sys.exit(1)
|
|
154
|
+
|
|
155
|
+
asyncio.run(
|
|
156
|
+
submit_slurm_job(
|
|
157
|
+
host=args.host,
|
|
158
|
+
port=args.port,
|
|
159
|
+
project_path=str(args.project_path),
|
|
160
|
+
partition=args.partition,
|
|
161
|
+
nodes=args.nodes,
|
|
162
|
+
cores_per_node=args.cores_per_node,
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
if __name__ == "__main__":
|
|
168
|
+
main()
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
4
|
+
# SPDX-License-Identifier: MIT
|
|
5
|
+
#
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
|
|
25
|
+
"""
|
|
26
|
+
Submit an HFSS job to the local job-manager service.
|
|
27
|
+
Job Submission is done via REST API asynchronously.
|
|
28
|
+
The service must be running locally (default: localhost:8080) prior to executing this script.
|
|
29
|
+
To start the service, run this command in another terminal:
|
|
30
|
+
python -m pyedb.workflows.job_manager.backend.job_manager_handler
|
|
31
|
+
|
|
32
|
+
Usage examples
|
|
33
|
+
--------------
|
|
34
|
+
# Get help
|
|
35
|
+
python submit_job.py --help
|
|
36
|
+
|
|
37
|
+
# Submit with explicit values
|
|
38
|
+
python submit_local_job.py \
|
|
39
|
+
--host 127.0.0.1 \
|
|
40
|
+
--port 8080 \
|
|
41
|
+
--project-path "D:\\Temp\\test_jobs\\test1.aedb" \
|
|
42
|
+
--num-cores 8
|
|
43
|
+
|
|
44
|
+
# Use defaults (localhost:8080, 8 cores)
|
|
45
|
+
python submit_local_job.py --project-path "D:\\Temp\\test_jobs\\test1.aedb"
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
import argparse
|
|
49
|
+
import asyncio
|
|
50
|
+
import logging
|
|
51
|
+
from pathlib import Path
|
|
52
|
+
import sys
|
|
53
|
+
from typing import Any, cast
|
|
54
|
+
|
|
55
|
+
import aiohttp
|
|
56
|
+
|
|
57
|
+
from pyedb.workflows.job_manager.backend.job_submission import (
|
|
58
|
+
MachineNode,
|
|
59
|
+
create_hfss_config,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
logger = logging.getLogger(__name__)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async def submit_job(*, host: str, port: int, project_path: str, num_cores: int) -> None:
|
|
66
|
+
"""Send the job-configuration to the REST endpoint."""
|
|
67
|
+
backend_url = f"http://{host}:{port}"
|
|
68
|
+
cfg = create_hfss_config(project_path=project_path)
|
|
69
|
+
|
|
70
|
+
# Ensure we have at least one machine node and configure it
|
|
71
|
+
if not cfg.machine_nodes:
|
|
72
|
+
cfg.machine_nodes.append(MachineNode())
|
|
73
|
+
|
|
74
|
+
# Use a typed reference to avoid static-analysis/indexing warnings
|
|
75
|
+
node = cast(MachineNode, cfg.machine_nodes[0])
|
|
76
|
+
node.cores = num_cores
|
|
77
|
+
node.max_cores = num_cores
|
|
78
|
+
|
|
79
|
+
# Use a reasonable timeout for network operations
|
|
80
|
+
timeout = aiohttp.ClientTimeout(total=60)
|
|
81
|
+
|
|
82
|
+
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
83
|
+
try:
|
|
84
|
+
async with session.post(
|
|
85
|
+
f"{backend_url}/jobs/submit",
|
|
86
|
+
json={
|
|
87
|
+
"config": cfg.model_dump(mode="json", exclude_defaults=False),
|
|
88
|
+
"priority": 0,
|
|
89
|
+
},
|
|
90
|
+
) as resp:
|
|
91
|
+
status = resp.status
|
|
92
|
+
# Try to parse JSON reply safely; fall back to text
|
|
93
|
+
try:
|
|
94
|
+
reply: Any = await resp.json()
|
|
95
|
+
except Exception:
|
|
96
|
+
reply = await resp.text()
|
|
97
|
+
|
|
98
|
+
if 200 <= status < 300:
|
|
99
|
+
logger.info("Job submit successful (status=%s)", status)
|
|
100
|
+
logger.debug("Reply: %s", reply)
|
|
101
|
+
else:
|
|
102
|
+
logger.error("Job submit failed (status=%s): %s", status, reply)
|
|
103
|
+
except asyncio.CancelledError:
|
|
104
|
+
# Re-raise cancellation so callers can handle it
|
|
105
|
+
raise
|
|
106
|
+
except Exception as exc: # pragma: no cover - defensive logging
|
|
107
|
+
logger.exception("Failed to submit job to %s: %s", backend_url, exc)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def parse_cli() -> argparse.Namespace:
|
|
111
|
+
parser = argparse.ArgumentParser(description="Submit an HFSS job to the local job-manager service.")
|
|
112
|
+
parser.add_argument(
|
|
113
|
+
"--host",
|
|
114
|
+
default="localhost",
|
|
115
|
+
help="Job-manager host (default: localhost)",
|
|
116
|
+
)
|
|
117
|
+
parser.add_argument(
|
|
118
|
+
"--port",
|
|
119
|
+
type=int,
|
|
120
|
+
default=8080,
|
|
121
|
+
help="Job-manager port (default: 8080)",
|
|
122
|
+
)
|
|
123
|
+
parser.add_argument(
|
|
124
|
+
"--project-path",
|
|
125
|
+
required=True,
|
|
126
|
+
type=Path,
|
|
127
|
+
help="Full path to the .aedb project",
|
|
128
|
+
)
|
|
129
|
+
parser.add_argument(
|
|
130
|
+
"--num-cores",
|
|
131
|
+
type=int,
|
|
132
|
+
default=8,
|
|
133
|
+
help="Number of cores to allocate (default: 8)",
|
|
134
|
+
)
|
|
135
|
+
return parser.parse_args()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def main() -> None:
|
|
139
|
+
args = parse_cli()
|
|
140
|
+
|
|
141
|
+
# Configure basic logging if the caller didn't
|
|
142
|
+
if not logging.getLogger().handlers:
|
|
143
|
+
logging.basicConfig(level=logging.INFO)
|
|
144
|
+
|
|
145
|
+
# Basic sanity checks
|
|
146
|
+
if not args.project_path.exists():
|
|
147
|
+
logger.error("Error: project path does not exist: %s", args.project_path)
|
|
148
|
+
print(f"Error: project path does not exist: {args.project_path}", file=sys.stderr)
|
|
149
|
+
sys.exit(1)
|
|
150
|
+
if args.num_cores <= 0:
|
|
151
|
+
logger.error("Error: --num-cores must be positive")
|
|
152
|
+
print("Error: --num-cores must be positive", file=sys.stderr)
|
|
153
|
+
sys.exit(1)
|
|
154
|
+
|
|
155
|
+
asyncio.run(
|
|
156
|
+
submit_job(
|
|
157
|
+
host=args.host,
|
|
158
|
+
port=args.port,
|
|
159
|
+
project_path=str(args.project_path),
|
|
160
|
+
num_cores=args.num_cores,
|
|
161
|
+
)
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
if __name__ == "__main__":
|
|
166
|
+
main()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|