holoscan-cli 2.9.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.
Files changed (39) hide show
  1. holoscan_cli/__init__.py +35 -0
  2. holoscan_cli/__main__.py +164 -0
  3. holoscan_cli/common/argparse_types.py +156 -0
  4. holoscan_cli/common/artifact_sources.py +160 -0
  5. holoscan_cli/common/constants.py +119 -0
  6. holoscan_cli/common/dockerutils.py +521 -0
  7. holoscan_cli/common/enum_types.py +49 -0
  8. holoscan_cli/common/exceptions.py +126 -0
  9. holoscan_cli/common/sdk_utils.py +195 -0
  10. holoscan_cli/common/utils.py +137 -0
  11. holoscan_cli/logging.json +37 -0
  12. holoscan_cli/nics/__init__.py +15 -0
  13. holoscan_cli/nics/nics.py +33 -0
  14. holoscan_cli/package-source.json +32 -0
  15. holoscan_cli/packager/__init__.py +15 -0
  16. holoscan_cli/packager/arguments.py +148 -0
  17. holoscan_cli/packager/config_reader.py +180 -0
  18. holoscan_cli/packager/container_builder.py +426 -0
  19. holoscan_cli/packager/manifest_files.py +217 -0
  20. holoscan_cli/packager/models.py +90 -0
  21. holoscan_cli/packager/package_command.py +197 -0
  22. holoscan_cli/packager/packager.py +124 -0
  23. holoscan_cli/packager/parameters.py +603 -0
  24. holoscan_cli/packager/platforms.py +426 -0
  25. holoscan_cli/packager/templates/Dockerfile.jinja2 +479 -0
  26. holoscan_cli/packager/templates/dockerignore +92 -0
  27. holoscan_cli/packager/templates/tools.sh +414 -0
  28. holoscan_cli/py.typed +14 -0
  29. holoscan_cli/runner/__init__.py +15 -0
  30. holoscan_cli/runner/resources.py +185 -0
  31. holoscan_cli/runner/run_command.py +207 -0
  32. holoscan_cli/runner/runner.py +340 -0
  33. holoscan_cli/version/__init__.py +15 -0
  34. holoscan_cli/version/version.py +53 -0
  35. holoscan_cli-2.9.0.dist-info/LICENSE +201 -0
  36. holoscan_cli-2.9.0.dist-info/METADATA +102 -0
  37. holoscan_cli-2.9.0.dist-info/RECORD +39 -0
  38. holoscan_cli-2.9.0.dist-info/WHEEL +4 -0
  39. holoscan_cli-2.9.0.dist-info/entry_points.txt +4 -0
@@ -0,0 +1,414 @@
1
+ #!/bin/bash
2
+
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4
+ # SPDX-License-Identifier: Apache-2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #===============================================================================
18
+ # Default values for environment variables.
19
+ #===============================================================================
20
+
21
+ init_globals() {
22
+ if [ "$0" != "/bin/bash" ] && [ "$0" != "bash" ]; then
23
+ SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
24
+ export RUN_SCRIPT_FILE="$(readlink -f "$0")"
25
+ else
26
+ export RUN_SCRIPT_FILE="$(readlink -f "${BASH_SOURCE[0]}")"
27
+ fi
28
+
29
+ export TOP=$(dirname "${RUN_SCRIPT_FILE}")
30
+
31
+ export HOLOSCAN_APPLICATION="${HOLOSCAN_APPLICATION:=/opt/holoscan/app}"
32
+ export HOLOSCAN_INPUT_PATH="${HOLOSCAN_INPUT_PATH:=/var/holoscan/input}"
33
+ export HOLOSCAN_OUTPUT_PATH="${HOLOSCAN_OUTPUT_PATH:=/var/holoscan/output}"
34
+ export HOLOSCAN_WORKDIR="${HOLOSCAN_WORKDIR:=/var/holoscan/}"
35
+ export HOLOSCAN_MODEL_PATH="${HOLOSCAN_MODEL_PATH:=/opt/holoscan/models/}"
36
+ export HOLOSCAN_DOCS="${HOLOSCAN_DOCS:=/opt/holoscan/docs/}"
37
+ export HOLOSCAN_CONFIG_PATH="${HOLOSCAN_CONFIG_PATH:=/var/holoscan/app.config}"
38
+ export HOLOSCAN_APP_MANIFEST_PATH="${HOLOSCAN_APP_MANIFEST_PATH:=/etc/holoscan/app.json}"
39
+ export HOLOSCAN_PKG_MANIFEST_PATH="${HOLOSCAN_PKG_MANIFEST_PATH:=/etc/holoscan/pkg.json}"
40
+ }
41
+
42
+ ################################################################################
43
+ # Utility functions
44
+ ################################################################################
45
+
46
+
47
+ c_str() {
48
+ local old_color=39
49
+ local old_attr=0
50
+ local color=39
51
+ local attr=0
52
+ local text=""
53
+ local mode="color"
54
+ if [ "${1:-}" = "color" ]; then
55
+ mode="color"
56
+ shift
57
+ elif [ "${1:-}" = "nocolor" ]; then
58
+ mode="nocolor"
59
+ shift
60
+ fi
61
+
62
+ for i in "$@"; do
63
+ case "$i" in
64
+ r|R)
65
+ color=31
66
+ ;;
67
+ g|G)
68
+ color=32
69
+ ;;
70
+ y|Y)
71
+ color=33
72
+ ;;
73
+ b|B)
74
+ color=34
75
+ ;;
76
+ p|P)
77
+ color=35
78
+ ;;
79
+ c|C)
80
+ color=36
81
+ ;;
82
+ w|W)
83
+ color=37
84
+ ;;
85
+
86
+ z|Z)
87
+ color=0
88
+ ;;
89
+ esac
90
+ case "$i" in
91
+ l|L|R|G|Y|B|P|C|W)
92
+ attr=1
93
+ ;;
94
+ n|N|r|g|y|b|p|c|w)
95
+ attr=0
96
+ ;;
97
+ z|Z)
98
+ attr=0
99
+ ;;
100
+ *)
101
+ text="${text}$i"
102
+ esac
103
+ if [ "${mode}" = "color" ]; then
104
+ if [ ${old_color} -ne ${color} ] || [ ${old_attr} -ne ${attr} ]; then
105
+ text="${text}\033[${attr};${color}m"
106
+ old_color=$color
107
+ old_attr=$attr
108
+ fi
109
+ fi
110
+ done
111
+ /bin/echo -en "$text"
112
+ }
113
+
114
+ c_echo() {
115
+ # Select color/nocolor based on the first argument
116
+ local mode="color"
117
+ if [ "${1:-}" = "color" ]; then
118
+ mode="color"
119
+ shift
120
+ elif [ "${1:-}" = "nocolor" ]; then
121
+ mode="nocolor"
122
+ shift
123
+ else
124
+ if [ ! -t 1 ]; then
125
+ mode="nocolor"
126
+ fi
127
+ fi
128
+
129
+ local old_opt="$(shopt -op xtrace)" # save old xtrace option
130
+ set +x # unset xtrace
131
+
132
+ if [ "${mode}" = "color" ]; then
133
+ local text="$(c_str color "$@")"
134
+ /bin/echo -e "$text\033[0m"
135
+ else
136
+ local text="$(c_str nocolor "$@")"
137
+ /bin/echo -e "$text"
138
+ fi
139
+ eval "${old_opt}" # restore old xtrace option
140
+ }
141
+
142
+ echo_err() {
143
+ >&2 echo "$@"
144
+ }
145
+
146
+ c_echo_err() {
147
+ >&2 c_echo "$@"
148
+ }
149
+
150
+ newline() {
151
+ echo
152
+ }
153
+
154
+ info() {
155
+ c_echo_err W "$(date -u '+%Y-%m-%d %H:%M:%S') [INFO] " Z "$@"
156
+ }
157
+
158
+ error() {
159
+ c_echo_err R "$(date -u '+%Y-%m-%d %H:%M:%S') [ERROR] " Z "$@"
160
+ }
161
+
162
+ fatal() {
163
+ if [ -n "$*" ]; then
164
+ c_echo_err R "$(date -u '+%Y-%m-%d %H:%M:%S') [FATAL] " Z "$@"
165
+ echo_err
166
+ fi
167
+ if [ -n "${SCRIPT_DIR}" ]; then
168
+ exit 1
169
+ else
170
+ kill -INT $$ # kill the current process instead of exit in shell environment.
171
+ fi
172
+ }
173
+
174
+ run_command() {
175
+ local status=0
176
+ local cmd="$*"
177
+
178
+ [ "$(echo -n "$@")" = "" ] && return 1 # return 1 if there is no command available
179
+
180
+ if [ "${DO_DRY_RUN}" != "true" ]; then
181
+ "$@"
182
+ status=$?
183
+ fi
184
+
185
+ return $status
186
+ }
187
+
188
+
189
+ #===============================================================================
190
+ # Section: Show
191
+ #===============================================================================
192
+
193
+ print() {
194
+ # Parse CLI arguments next
195
+ ARGS=("$@")
196
+ if [ "$ARGS" = "" ]; then
197
+ ARGS=*
198
+ fi
199
+
200
+ local i
201
+ local arg
202
+ for i in "${!ARGS[@]}"; do
203
+ arg="${ARGS[i]}"
204
+ if [[ "$arg" = "*" || "$arg" = "" ]]; then
205
+ opt=all
206
+ fi
207
+ if [ "$arg" = "app" ]; then
208
+ opt=app
209
+ fi
210
+ if [ "$arg" = "pkg" ]; then
211
+ opt=pkg
212
+ fi
213
+ done
214
+ newline
215
+ if [[ "$opt" = "all" || "$opt" = "app" ]]; then
216
+ if [ -f "${HOLOSCAN_APP_MANIFEST_PATH}" ]; then
217
+ c_echo "============================== app.json =============================="
218
+ run_command cat ${HOLOSCAN_APP_MANIFEST_PATH} | jq
219
+ else
220
+ c_echo_err "${HOLOSCAN_APP_MANIFEST_PATH} does not exists!"
221
+ fi
222
+ fi
223
+ newline
224
+ if [[ "$opt" = "all" || "$opt" = "pkg" ]]; then
225
+ if [ -f "${HOLOSCAN_PKG_MANIFEST_PATH}" ]; then
226
+ c_echo "============================== pkg.json =============================="
227
+ run_command cat ${HOLOSCAN_PKG_MANIFEST_PATH} | jq
228
+ else
229
+ c_echo_err "${HOLOSCAN_PKG_MANIFEST_PATH} does not exists!"
230
+ fi
231
+ fi
232
+ newline
233
+ }
234
+
235
+ print_env() {
236
+ run_command env -0 | sort -z | tr '\0' '\n'
237
+ }
238
+ #===============================================================================
239
+ # Section: Export
240
+ #===============================================================================
241
+
242
+ copy_app() {
243
+ info "Copying application from ${HOLOSCAN_APPLICATION} to ${EXPORT_ROOT}/app"
244
+ if [ -d "${HOLOSCAN_APPLICATION}" ]; then
245
+ run_command cp -r ${HOLOSCAN_APPLICATION} ${EXPORT_ROOT}/app
246
+ else
247
+ info "'${HOLOSCAN_APPLICATION}' cannot be found."
248
+ fi
249
+ newline
250
+ }
251
+
252
+ copy_configs() {
253
+ if [ ! -d "${EXPORT_ROOT}/config/" ]
254
+ then
255
+ mkdir -p ${EXPORT_ROOT}/config/
256
+ fi
257
+
258
+ info "Copying application manifest file from ${HOLOSCAN_APP_MANIFEST_PATH} to ${EXPORT_ROOT}/config/app.json"
259
+ if [ -f "${HOLOSCAN_APP_MANIFEST_PATH}" ]; then
260
+ run_command cp ${HOLOSCAN_APP_MANIFEST_PATH} ${EXPORT_ROOT}/config/app.json
261
+ else
262
+ info "application manifest file '${HOLOSCAN_APP_MANIFEST_PATH}' cannot be found."
263
+ fi
264
+
265
+ info "Copying pkg manifest file from ${HOLOSCAN_PKG_MANIFEST_PATH} to ${EXPORT_ROOT}/config/pkg.json"
266
+ if [ -f "${HOLOSCAN_PKG_MANIFEST_PATH}" ]; then
267
+ run_command cp ${HOLOSCAN_PKG_MANIFEST_PATH} ${EXPORT_ROOT}/config/pkg.json
268
+ else
269
+ info "package manifest file '${HOLOSCAN_PKG_MANIFEST_PATH}' cannot be found."
270
+ fi
271
+
272
+ local CONFIG_FILE_NAME=$(basename ${HOLOSCAN_CONFIG_PATH})
273
+ info "Copying application configuration from ${HOLOSCAN_CONFIG_PATH} to ${EXPORT_ROOT}/config/$CONFIG_FILE_NAME"
274
+ if [ -f "${HOLOSCAN_CONFIG_PATH}" ]; then
275
+ run_command cp ${HOLOSCAN_CONFIG_PATH} ${EXPORT_ROOT}/config/$CONFIG_FILE_NAME
276
+ else
277
+ info "Application configuration'${HOLOSCAN_CONFIG_PATH}' cannot be found."
278
+ fi
279
+ newline
280
+ }
281
+
282
+ copy_models() {
283
+ info "Copying models from ${HOLOSCAN_MODEL_PATH} to ${EXPORT_ROOT}/models"
284
+ if [ -d "${HOLOSCAN_MODEL_PATH}" ]; then
285
+ run_command cp -r ${HOLOSCAN_MODEL_PATH} ${EXPORT_ROOT}/models
286
+ else
287
+ info "'${HOLOSCAN_MODEL_PATH}' cannot be found."
288
+ fi
289
+ newline
290
+ }
291
+
292
+ copy_docs() {
293
+ info "Copying documentation from ${HOLOSCAN_DOCS} to ${EXPORT_ROOT}/docs"
294
+ if [ -d "${HOLOSCAN_DOCS}" ]; then
295
+ run_command cp -r ${HOLOSCAN_DOCS} ${EXPORT_ROOT}/docs
296
+ else
297
+ info "'${HOLOSCAN_DOCS}' cannot be found."
298
+ fi
299
+ newline
300
+ }
301
+
302
+ check_permission(){
303
+ test -w $@
304
+ if [ $? -ne 0 ]; then
305
+ fatal "Permission error: ensure the directory is created on the host first before using the 'extract' command."
306
+ fi
307
+ }
308
+
309
+
310
+ copy() {
311
+ EXPORT_ROOT=/var/run/holoscan/export
312
+
313
+ if [ -d "${EXPORT_ROOT}" ]
314
+ then
315
+ if [ -d "${EXPORT_ROOT}/app" ]; then
316
+ check_permission "${EXPORT_ROOT}/app"
317
+ copy_app
318
+ elif [ -d "${EXPORT_ROOT}/config" ]; then
319
+ check_permission "${EXPORT_ROOT}/config"
320
+ copy_configs
321
+ elif [ -d "${EXPORT_ROOT}/models" ]; then
322
+ check_permission "${EXPORT_ROOT}/models"
323
+ copy_models
324
+ elif [ -d "${EXPORT_ROOT}/docs" ]; then
325
+ copy_docs "${EXPORT_ROOT}/docs"
326
+ else
327
+ check_permission "${EXPORT_ROOT}"
328
+ copy_app
329
+ copy_configs
330
+ copy_models
331
+ copy_docs
332
+ fi
333
+ else
334
+ fatal "No volume mount found ${EXPORT_ROOT}."
335
+ fi
336
+ }
337
+
338
+ #===============================================================================
339
+
340
+
341
+ print_usage() {
342
+ local YELLOW='\033[0;93m' # YELLOW
343
+ local RED='\033[0;91m' # YELLOW
344
+ local NC='\033[0m' # No Color
345
+ c_echo "USAGE: /var/holoscan/tools [command] [arguments]..."
346
+ c_echo " Command List"
347
+ c_echo " ${YELLOW}extract${NC} --------------------------- Extract data based on mounted volume paths."
348
+ c_echo " /var/run/holoscan/export/app extract the application"
349
+ c_echo " /var/run/holoscan/export/config extract app.json and pkg.json manifest files and application YAML."
350
+ c_echo " /var/run/holoscan/export/models extract models"
351
+ c_echo " /var/run/holoscan/export/docs extract documentation files"
352
+ c_echo " /var/run/holoscan/export extract all of the above"
353
+ c_echo " ${RED}IMPORTANT${NC}: ensure the directory to be mounted for data extraction is created first on the host system"
354
+ c_echo " and has the correct permissions. If the directory had been created by the container previously"
355
+ c_echo " with the user and group being root, please delete it and manually create it again."
356
+ c_echo " ${YELLOW}show${NC} ----------------------------- Print manifest file(s): [app|pkg] to the terminal."
357
+ c_echo " ${YELLOW}app${NC} print app.json"
358
+ c_echo " ${YELLOW}pkg${NC} print pkg.json"
359
+ c_echo " ${YELLOW}env${NC} ------------------------- Print all environment variables to the terminal."
360
+ }
361
+
362
+
363
+ main() {
364
+ if [ "$1" = "show" ]; then
365
+ shift
366
+ print "$@"
367
+ elif [ "$1" = "env" ]; then
368
+ shift
369
+ print_env
370
+ elif [ "$1" = "extract" ]; then
371
+ shift
372
+ copy
373
+ elif [ "$1" = "help" ]; then
374
+ shift
375
+ print_usage
376
+ else # all other commands will launch the application
377
+ local command=$(jq -r '.command | fromjson | join(" ")' ${HOLOSCAN_APP_MANIFEST_PATH} 2>/dev/null)
378
+ if [ -n "${command}" ]; then
379
+ args=$(printf " %s" "${@}")
380
+ info "Launching application ${command} ${args:1}..."
381
+ eval ${command} "$@"
382
+ exit_code=$?
383
+ if [ $exit_code -ne 0 ] && [ -f /.dockerenv ] && [ "$HOLOSCAN_HOSTING_SERVICE" != "HOLOSCAN_RUN" ]; then
384
+ newline
385
+ c_echo "================================================================================================"
386
+ c_echo "Application exited with ${exit_code}."
387
+ newline
388
+ newline
389
+ c_echo nocolor "When running inside docker, ensure that the runtime is set to nvidia with required arguments."
390
+ newline
391
+ c_echo nocolor "For example:"
392
+ c_echo nocolor "docker run --runtime nvidia \\"
393
+ c_echo nocolor " --gpus all \\"
394
+ c_echo nocolor " -it \\"
395
+ c_echo nocolor " -e NVIDIA_DRIVER_CAPABILITIES=all \\"
396
+ c_echo nocolor " -e DISPLAY=\$DISPLAY \\"
397
+ c_echo nocolor " -v /tmp/.X11-unix:/tmp/.X11-unix \\"
398
+ c_echo nocolor " -v \${MY-INPUT-DATA}:/var/holoscan/input \\"
399
+ c_echo nocolor " my-container-image[:tag]"
400
+ newline
401
+ c_echo "================================================================================================"
402
+ newline
403
+ fi
404
+ else
405
+ fatal "Failed to launch application; failed to read/parse command from ${HOLOSCAN_APP_MANIFEST_PATH}."
406
+ fi
407
+ fi
408
+ }
409
+
410
+ init_globals
411
+
412
+ if [ -n "${SCRIPT_DIR}" ]; then
413
+ main "$@"
414
+ fi
holoscan_cli/py.typed ADDED
@@ -0,0 +1,14 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
@@ -0,0 +1,15 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ from .runner import execute_run_command # noqa: F401
@@ -0,0 +1,185 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ import logging
16
+ import re
17
+ from typing import Optional, Union
18
+
19
+ from ..common.constants import Constants, DefaultValues
20
+ from ..common.exceptions import InvalidSharedMemoryValueError
21
+
22
+ logger = logging.getLogger("runner")
23
+
24
+
25
+ def get_shared_memory_size(
26
+ pkg_info: dict,
27
+ worker: bool,
28
+ driver: bool,
29
+ fragments: str,
30
+ user_shm_size: Optional[str],
31
+ ) -> Optional[float]:
32
+ """Queries the pkg.json file for shared memory requirement of the application
33
+
34
+ Args:
35
+ pkg_info (dict): package manifest
36
+ worker (bool): start the application as App Worker
37
+ driver (bool): start the application as App Driver
38
+ fragments (str): comma-separated list of fragments
39
+ user_shm_size (Optional[str]): user provided share memory size
40
+
41
+ Returns:
42
+ float: shared memory value in bytes
43
+ """
44
+
45
+ if user_shm_size == "config":
46
+ return _read_shm_size_from_config(pkg_info, worker, driver, fragments)
47
+ elif user_shm_size is not None:
48
+ return _convert_to_bytes(user_shm_size)
49
+ else:
50
+ return None
51
+
52
+
53
+ def _read_shm_size_from_config(
54
+ pkg_info: dict, worker: bool, driver: bool, fragments: str
55
+ ) -> float:
56
+ """Queries the pkg.json file for shared memory requirement of the application
57
+
58
+ Args:
59
+ pkg_info (dict): package manifest
60
+ worker (bool): start the application as App Worker
61
+ driver (bool): start the application as App Driver
62
+ fragments (str): comma-separated list of fragments
63
+
64
+ Returns:
65
+ float: shared memory value in bytes
66
+ """
67
+ resources = pkg_info.get("resources") if pkg_info is not None else None
68
+
69
+ if resources is None:
70
+ return DefaultValues.DEFAULT_SHM_SIZE
71
+
72
+ max_value: float = 0
73
+ global_shared_memory_size = _convert_to_bytes(
74
+ resources.get(
75
+ Constants.RESOURCE_SHARED_MEMORY_KEY, DefaultValues.DEFAULT_SHM_SIZE
76
+ )
77
+ )
78
+
79
+ resources_fragments = resources.get("fragments", {})
80
+ if worker:
81
+ if fragments is None or fragments.lower() == "all":
82
+ max_value = _find_maximum_shared_memory_value_from_all_fragments(
83
+ resources_fragments
84
+ )
85
+ else:
86
+ max_value = _find_maximum_shared_memory_value_from_matching_fragments(
87
+ resources_fragments, fragments
88
+ )
89
+ max_value = max(max_value, global_shared_memory_size)
90
+ else:
91
+ if driver:
92
+ max_value = global_shared_memory_size
93
+ else:
94
+ max_value = _find_maximum_shared_memory_value_from_all_fragments(
95
+ resources_fragments
96
+ )
97
+ max_value = max(max_value, global_shared_memory_size)
98
+
99
+ return max_value
100
+
101
+
102
+ def _find_maximum_shared_memory_value_from_matching_fragments(
103
+ resources_fragments: dict, fragments: str
104
+ ) -> Optional[float]:
105
+ """Scan matching fragments for the maximum shared memory value.
106
+
107
+ Args:
108
+ resources_fragments (Dict): fragment resources; resources->fragments
109
+ fragments (str): comma-separated list of fragments to match
110
+
111
+ Returns:
112
+ Optional[float]: maximum shred memory value or zero if no fragments found.
113
+ """
114
+ user_fragments = fragments.split(",")
115
+ fragment_values = [
116
+ _convert_to_bytes(val[Constants.RESOURCE_SHARED_MEMORY_KEY])
117
+ for key, val in resources_fragments.items()
118
+ if Constants.RESOURCE_SHARED_MEMORY_KEY in val and key in user_fragments
119
+ ]
120
+
121
+ if fragment_values:
122
+ return max(fragment_values)
123
+ else:
124
+ return 0
125
+
126
+
127
+ def _find_maximum_shared_memory_value_from_all_fragments(
128
+ resources_fragments: dict,
129
+ ) -> Optional[float]:
130
+ """Scan all fragments for the maximum shared memory value.
131
+
132
+ Args:
133
+ resources_fragments (Dict): fragment resources; resources->fragments
134
+
135
+ Returns:
136
+ Optional[float]: maximum shred memory value or zero if no fragments found.
137
+ """
138
+ fragment_values = [
139
+ _convert_to_bytes(val[Constants.RESOURCE_SHARED_MEMORY_KEY])
140
+ for _, val in resources_fragments.items()
141
+ if Constants.RESOURCE_SHARED_MEMORY_KEY in val
142
+ ]
143
+
144
+ if fragment_values:
145
+ return max(fragment_values)
146
+ else:
147
+ return 0
148
+
149
+
150
+ def _convert_to_bytes(raw_value: Union[str, float, int]) -> float:
151
+ """Converts data measurements in string to float.
152
+
153
+ Supported units are Mi|MiB (mebibytes), Gi|GiB (gibibytes), MB|m (megabytes) and
154
+ GB|g (gigabytes)
155
+
156
+ Args:
157
+ raw_value (str): data measurement with a number and a supporting unit.
158
+
159
+ Returns:
160
+ float: number of bytes
161
+ """
162
+
163
+ if type(raw_value) in [float, int]:
164
+ return raw_value
165
+
166
+ result = re.search(r"([.\d]+)\s*(Mi|MiB|Gi|GiB|MB|GB|m|g)", raw_value)
167
+
168
+ if result is not None:
169
+ value = float(result.group(1))
170
+ if result.group(2) in ["Mi", "MiB"]:
171
+ return value * 1048576
172
+ if result.group(2) in ["Gi", "GiB"]:
173
+ return value * 1073741824
174
+ if result.group(2) == "MB":
175
+ return value * 1000000
176
+ if result.group(2) == "GB":
177
+ return value * 1000000000
178
+ if result.group(2) == "m":
179
+ return value * 1000000
180
+ if result.group(2) == "g":
181
+ return value * 1000000000
182
+
183
+ raise InvalidSharedMemoryValueError(
184
+ f"Invalid/unsupported shared memory value: {raw_value}. "
185
+ )