holoscan 2.1.0__cp38-cp38-manylinux_2_35_aarch64.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 (138) hide show
  1. holoscan-2.1.0.data/purelib/holoscan/__init__.py +121 -0
  2. holoscan-2.1.0.data/purelib/holoscan/cli/__init__.py +32 -0
  3. holoscan-2.1.0.data/purelib/holoscan/cli/__main__.py +159 -0
  4. holoscan-2.1.0.data/purelib/holoscan/cli/common/argparse_types.py +154 -0
  5. holoscan-2.1.0.data/purelib/holoscan/cli/common/artifact_sources.py +144 -0
  6. holoscan-2.1.0.data/purelib/holoscan/cli/common/constants.py +120 -0
  7. holoscan-2.1.0.data/purelib/holoscan/cli/common/dockerutils.py +506 -0
  8. holoscan-2.1.0.data/purelib/holoscan/cli/common/enum_types.py +52 -0
  9. holoscan-2.1.0.data/purelib/holoscan/cli/common/exceptions.py +132 -0
  10. holoscan-2.1.0.data/purelib/holoscan/cli/common/sdk_utils.py +180 -0
  11. holoscan-2.1.0.data/purelib/holoscan/cli/common/utils.py +131 -0
  12. holoscan-2.1.0.data/purelib/holoscan/cli/logging.json +37 -0
  13. holoscan-2.1.0.data/purelib/holoscan/cli/nics/__init__.py +18 -0
  14. holoscan-2.1.0.data/purelib/holoscan/cli/nics/nics.py +34 -0
  15. holoscan-2.1.0.data/purelib/holoscan/cli/packager/__init__.py +18 -0
  16. holoscan-2.1.0.data/purelib/holoscan/cli/packager/arguments.py +137 -0
  17. holoscan-2.1.0.data/purelib/holoscan/cli/packager/config_reader.py +181 -0
  18. holoscan-2.1.0.data/purelib/holoscan/cli/packager/container_builder.py +349 -0
  19. holoscan-2.1.0.data/purelib/holoscan/cli/packager/manifest_files.py +220 -0
  20. holoscan-2.1.0.data/purelib/holoscan/cli/packager/models.py +93 -0
  21. holoscan-2.1.0.data/purelib/holoscan/cli/packager/package_command.py +183 -0
  22. holoscan-2.1.0.data/purelib/holoscan/cli/packager/packager.py +123 -0
  23. holoscan-2.1.0.data/purelib/holoscan/cli/packager/parameters.py +534 -0
  24. holoscan-2.1.0.data/purelib/holoscan/cli/packager/platforms.py +405 -0
  25. holoscan-2.1.0.data/purelib/holoscan/cli/packager/sdk_downloader.py +147 -0
  26. holoscan-2.1.0.data/purelib/holoscan/cli/packager/templates/Dockerfile.jinja2 +191 -0
  27. holoscan-2.1.0.data/purelib/holoscan/cli/packager/templates/dockerignore +93 -0
  28. holoscan-2.1.0.data/purelib/holoscan/cli/packager/templates/tools.sh +416 -0
  29. holoscan-2.1.0.data/purelib/holoscan/cli/py.typed +0 -0
  30. holoscan-2.1.0.data/purelib/holoscan/cli/runner/__init__.py +18 -0
  31. holoscan-2.1.0.data/purelib/holoscan/cli/runner/resources.py +174 -0
  32. holoscan-2.1.0.data/purelib/holoscan/cli/runner/run_command.py +204 -0
  33. holoscan-2.1.0.data/purelib/holoscan/cli/runner/runner.py +306 -0
  34. holoscan-2.1.0.data/purelib/holoscan/cli/version/__init__.py +18 -0
  35. holoscan-2.1.0.data/purelib/holoscan/cli/version/version.py +50 -0
  36. holoscan-2.1.0.data/purelib/holoscan/conditions/__init__.py +45 -0
  37. holoscan-2.1.0.data/purelib/holoscan/conditions/_conditions.cpython-38-aarch64-linux-gnu.so +0 -0
  38. holoscan-2.1.0.data/purelib/holoscan/core/__init__.py +367 -0
  39. holoscan-2.1.0.data/purelib/holoscan/core/_core.cpython-38-aarch64-linux-gnu.so +0 -0
  40. holoscan-2.1.0.data/purelib/holoscan/executors/__init__.py +26 -0
  41. holoscan-2.1.0.data/purelib/holoscan/executors/_executors.cpython-38-aarch64-linux-gnu.so +0 -0
  42. holoscan-2.1.0.data/purelib/holoscan/graphs/__init__.py +32 -0
  43. holoscan-2.1.0.data/purelib/holoscan/graphs/_graphs.cpython-38-aarch64-linux-gnu.so +0 -0
  44. holoscan-2.1.0.data/purelib/holoscan/gxf/__init__.py +57 -0
  45. holoscan-2.1.0.data/purelib/holoscan/gxf/_gxf.cpython-38-aarch64-linux-gnu.so +0 -0
  46. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_holoscan_wrapper.so +0 -0
  47. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_holoscan_wrapper_lib.so +0 -0
  48. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_ucx_holoscan.so +0 -0
  49. holoscan-2.1.0.data/purelib/holoscan/lib/gxf_extensions/libgxf_ucx_holoscan_lib.so +0 -0
  50. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_app.so +0 -0
  51. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_core.so +0 -0
  52. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_cuda.so +0 -0
  53. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_logger.so +0 -0
  54. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_multimedia.so +0 -0
  55. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_sample.so +0 -0
  56. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_serialization.so +0 -0
  57. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_std.so +0 -0
  58. holoscan-2.1.0.data/purelib/holoscan/lib/libgxf_ucx.so +0 -0
  59. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_core.so.2.1.0 +0 -0
  60. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer.so.2.1.0 +0 -0
  61. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer_onnx_runtime.so.2.1.0 +0 -0
  62. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer_torch.so.2.1.0 +0 -0
  63. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_infer_utils.so.2.1.0 +0 -0
  64. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_logger.so.2.1.0 +0 -0
  65. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_aja.so.2.1.0 +0 -0
  66. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_async_ping_rx.so.2.1.0 +0 -0
  67. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_async_ping_tx.so.2.1.0 +0 -0
  68. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_bayer_demosaic.so.2.1.0 +0 -0
  69. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_format_converter.so.2.1.0 +0 -0
  70. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_gxf_codelet.so.2.1.0 +0 -0
  71. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_holoviz.so.2.1.0 +0 -0
  72. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_inference.so.2.1.0 +0 -0
  73. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_inference_processor.so.2.1.0 +0 -0
  74. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_ping_rx.so.2.1.0 +0 -0
  75. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_ping_tx.so.2.1.0 +0 -0
  76. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_segmentation_postprocessor.so.2.1.0 +0 -0
  77. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_v4l2.so.2.1.0 +0 -0
  78. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_video_stream_recorder.so.2.1.0 +0 -0
  79. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_op_video_stream_replayer.so.2.1.0 +0 -0
  80. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_spdlog_logger.so.2.1.0 +0 -0
  81. holoscan-2.1.0.data/purelib/holoscan/lib/libholoscan_viz.so.2.1.0 +0 -0
  82. holoscan-2.1.0.data/purelib/holoscan/lib/libucm.so.0.0.0 +0 -0
  83. holoscan-2.1.0.data/purelib/holoscan/lib/libucp.so.0.0.0 +0 -0
  84. holoscan-2.1.0.data/purelib/holoscan/lib/libucs.so.0.0.0 +0 -0
  85. holoscan-2.1.0.data/purelib/holoscan/lib/libucs_signal.so.0.0.0 +0 -0
  86. holoscan-2.1.0.data/purelib/holoscan/lib/libuct.so.0.0.0 +0 -0
  87. holoscan-2.1.0.data/purelib/holoscan/lib/libyaml-cpp.so.0.7.0 +0 -0
  88. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libucm_cuda.so.0.0.0 +0 -0
  89. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_cma.so.0.0.0 +0 -0
  90. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_cuda.so.0.0.0 +0 -0
  91. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_cuda_gdrcopy.so.0.0.0 +0 -0
  92. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_ib.so.0.0.0 +0 -0
  93. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libuct_rdmacm.so.0.0.0 +0 -0
  94. holoscan-2.1.0.data/purelib/holoscan/lib/ucx/libucx_perftest_cuda.so.0.0.0 +0 -0
  95. holoscan-2.1.0.data/purelib/holoscan/logger/__init__.py +37 -0
  96. holoscan-2.1.0.data/purelib/holoscan/logger/_logger.cpython-38-aarch64-linux-gnu.so +0 -0
  97. holoscan-2.1.0.data/purelib/holoscan/network_contexts/__init__.py +28 -0
  98. holoscan-2.1.0.data/purelib/holoscan/network_contexts/_network_contexts.cpython-38-aarch64-linux-gnu.so +0 -0
  99. holoscan-2.1.0.data/purelib/holoscan/operators/__init__.py +93 -0
  100. holoscan-2.1.0.data/purelib/holoscan/operators/aja_source/__init__.py +22 -0
  101. holoscan-2.1.0.data/purelib/holoscan/operators/aja_source/_aja_source.cpython-38-aarch64-linux-gnu.so +0 -0
  102. holoscan-2.1.0.data/purelib/holoscan/operators/bayer_demosaic/__init__.py +24 -0
  103. holoscan-2.1.0.data/purelib/holoscan/operators/bayer_demosaic/_bayer_demosaic.cpython-38-aarch64-linux-gnu.so +0 -0
  104. holoscan-2.1.0.data/purelib/holoscan/operators/format_converter/__init__.py +23 -0
  105. holoscan-2.1.0.data/purelib/holoscan/operators/format_converter/_format_converter.cpython-38-aarch64-linux-gnu.so +0 -0
  106. holoscan-2.1.0.data/purelib/holoscan/operators/gxf_codelet/__init__.py +67 -0
  107. holoscan-2.1.0.data/purelib/holoscan/operators/gxf_codelet/_gxf_codelet.cpython-38-aarch64-linux-gnu.so +0 -0
  108. holoscan-2.1.0.data/purelib/holoscan/operators/holoviz/__init__.py +230 -0
  109. holoscan-2.1.0.data/purelib/holoscan/operators/holoviz/_holoviz.cpython-38-aarch64-linux-gnu.so +0 -0
  110. holoscan-2.1.0.data/purelib/holoscan/operators/inference/__init__.py +23 -0
  111. holoscan-2.1.0.data/purelib/holoscan/operators/inference/_inference.cpython-38-aarch64-linux-gnu.so +0 -0
  112. holoscan-2.1.0.data/purelib/holoscan/operators/inference_processor/__init__.py +23 -0
  113. holoscan-2.1.0.data/purelib/holoscan/operators/inference_processor/_inference_processor.cpython-38-aarch64-linux-gnu.so +0 -0
  114. holoscan-2.1.0.data/purelib/holoscan/operators/ping_rx/__init__.py +45 -0
  115. holoscan-2.1.0.data/purelib/holoscan/operators/ping_tx/__init__.py +46 -0
  116. holoscan-2.1.0.data/purelib/holoscan/operators/segmentation_postprocessor/__init__.py +23 -0
  117. holoscan-2.1.0.data/purelib/holoscan/operators/segmentation_postprocessor/_segmentation_postprocessor.cpython-38-aarch64-linux-gnu.so +0 -0
  118. holoscan-2.1.0.data/purelib/holoscan/operators/v4l2_video_capture/__init__.py +23 -0
  119. holoscan-2.1.0.data/purelib/holoscan/operators/v4l2_video_capture/_v4l2_video_capture.cpython-38-aarch64-linux-gnu.so +0 -0
  120. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_recorder/__init__.py +22 -0
  121. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_recorder/_video_stream_recorder.cpython-38-aarch64-linux-gnu.so +0 -0
  122. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_replayer/__init__.py +22 -0
  123. holoscan-2.1.0.data/purelib/holoscan/operators/video_stream_replayer/_video_stream_replayer.cpython-38-aarch64-linux-gnu.so +0 -0
  124. holoscan-2.1.0.data/purelib/holoscan/resources/__init__.py +138 -0
  125. holoscan-2.1.0.data/purelib/holoscan/resources/_resources.cpython-38-aarch64-linux-gnu.so +0 -0
  126. holoscan-2.1.0.data/purelib/holoscan/schedulers/__init__.py +32 -0
  127. holoscan-2.1.0.data/purelib/holoscan/schedulers/_schedulers.cpython-38-aarch64-linux-gnu.so +0 -0
  128. holoscan-2.1.0.data/purelib/holoscan-2.1.0.pth +1 -0
  129. holoscan-2.1.0.dist-info/LICENSE.txt +202 -0
  130. holoscan-2.1.0.dist-info/METADATA +111 -0
  131. holoscan-2.1.0.dist-info/NOTICE.txt +170 -0
  132. holoscan-2.1.0.dist-info/NVIDIA-AI-PRODUCT-EULA.txt +243 -0
  133. holoscan-2.1.0.dist-info/RECORD +138 -0
  134. holoscan-2.1.0.dist-info/WHEEL +5 -0
  135. holoscan-2.1.0.dist-info/axle.lck +0 -0
  136. holoscan-2.1.0.dist-info/entry_points.txt +3 -0
  137. holoscan-2.1.0.dist-info/symlinks.txt +72 -0
  138. holoscan-2.1.0.dist-info/top_level.txt +3 -0
@@ -0,0 +1,121 @@
1
+ """
2
+ SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ """ # noqa: E501
17
+
18
+ # We import cli, core and gxf to make sure they're available before other modules that rely on them
19
+ from . import cli, core, gxf
20
+
21
+ __all__ = ["as_tensor", "cli", "core", "gxf"]
22
+
23
+
24
+ def as_tensor(obj):
25
+ if hasattr(obj, "__cuda_array_interface__") or hasattr(obj, "__array_interface__"):
26
+ # Workaround for bug in CuPy<13.0.0a1 where strides of ndarray with all but 1 dimension a
27
+ # singleton, could become order='F' strides instead of the expected order='C' strides.
28
+ # See:
29
+ # https://github.com/cupy/cupy/pull/7438
30
+ # https://github.com/cupy/cupy/pull/7457
31
+ # https://forums.developer.nvidia.com/t/known-issue-in-cupy-affecting-tensor-interop/244423
32
+ #
33
+ # Here we force any array that is both C and F contiguous to have C-ordered strides
34
+ # We do this for both NumPy and CuPy arrays for consistency.
35
+
36
+ # nd-array, but with only 1 non-singleton dimension
37
+ nd_singleton = (obj.ndim > 1) and (sum(tuple(s > 1 for s in obj.shape)) == 1)
38
+ if nd_singleton and obj.flags.forc:
39
+ # determine expected strides for a C-contiguous array
40
+ expected_strides = [
41
+ 1,
42
+ ] * obj.ndim
43
+ expected_strides[obj.ndim - 1] = obj.itemsize
44
+ for i in range(obj.ndim - 2, -1, -1):
45
+ expected_strides[i] = expected_strides[i + 1] * obj.shape[i + 1]
46
+ expected_strides = tuple(expected_strides)
47
+
48
+ # make a copy to force stride update if they do not match
49
+ if obj.strides != expected_strides:
50
+ if hasattr(obj, "__cuda_array_interface__"):
51
+ try:
52
+ import cupy as cp
53
+
54
+ if isinstance(obj, cp.ndarray):
55
+ # use as_strided to avoid a copy
56
+ obj = cp.lib.stride_tricks.as_strided(
57
+ obj, shape=obj.shape, strides=expected_strides
58
+ )
59
+ return core.Tensor.as_tensor(obj)
60
+ except ImportError:
61
+ pass
62
+ elif hasattr(obj, "__array_interface__"):
63
+ try:
64
+ import numpy as np
65
+
66
+ if isinstance(obj, np.ndarray):
67
+ # use as_strided to avoid a copy
68
+ obj = np.lib.stride_tricks.as_strided(
69
+ obj, shape=obj.shape, strides=expected_strides
70
+ )
71
+ return core.Tensor.as_tensor(obj)
72
+ except ImportError:
73
+ pass
74
+ # update strides by making an explicit copy
75
+ try:
76
+ obj = obj.copy(order="C")
77
+ except (AttributeError, TypeError):
78
+ import warnings
79
+
80
+ warnings.warn(
81
+ "Unexpected strides encountered during call to `as_tensor` and no copy "
82
+ "method was available. Leaving the strides unchanged.",
83
+ stacklevel=2,
84
+ )
85
+
86
+ return core.Tensor.as_tensor(obj)
87
+
88
+
89
+ as_tensor.__doc__ = core.Tensor.as_tensor.__doc__
90
+
91
+
92
+ # Other modules are exposed to the public API but will only be lazily loaded
93
+ _EXTRA_MODULES = [
94
+ "conditions",
95
+ "executors",
96
+ "graphs",
97
+ "logger",
98
+ "operators",
99
+ "resources",
100
+ "schedulers",
101
+ ]
102
+ __all__.extend(_EXTRA_MODULES)
103
+
104
+
105
+ # Autocomplete
106
+ def __dir__():
107
+ return __all__
108
+
109
+
110
+ # Lazily load extra modules
111
+ def __getattr__(name):
112
+ import importlib
113
+ import sys
114
+
115
+ if name in _EXTRA_MODULES:
116
+ module_name = f"{__name__}.{name}"
117
+ module = importlib.import_module(module_name) # import
118
+ sys.modules[module_name] = module # cache
119
+ return module
120
+ else:
121
+ raise AttributeError(f"module {__name__} has no attribute {name}")
@@ -0,0 +1,32 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2024 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 undwer the License.
15
+ """
16
+ .. autosummary::
17
+ :toctree: _autosummary
18
+
19
+ common
20
+ packager
21
+ runner
22
+ version
23
+ """
24
+
25
+ import os
26
+ import sys
27
+
28
+ __title__ = "holoscan.cli"
29
+ _current_dir = os.path.abspath(os.path.dirname(__file__))
30
+ if sys.path and os.path.abspath(sys.path[0]) != _current_dir:
31
+ sys.path.insert(0, _current_dir)
32
+ del _current_dir
@@ -0,0 +1,159 @@
1
+ """
2
+ SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ """ # noqa: E501
17
+
18
+ import argparse
19
+ import json
20
+ import logging
21
+ import logging.config
22
+ import os
23
+ from pathlib import Path
24
+ from typing import List, Optional, Union
25
+
26
+ from .common.enum_types import Platform, PlatformConfiguration
27
+
28
+ logging.getLogger("docker.api.build").setLevel(logging.WARNING)
29
+ logging.getLogger("docker.auth").setLevel(logging.WARNING)
30
+ logging.getLogger("docker.utils.config").setLevel(logging.WARNING)
31
+ logging.getLogger("urllib3.connectionpool").setLevel(logging.WARNING)
32
+ logging.getLogger("urllib3").setLevel(logging.WARNING)
33
+
34
+ LOG_CONFIG_FILENAME = "logging.json"
35
+
36
+
37
+ def parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
38
+ from .packager.package_command import create_package_parser
39
+ from .runner.run_command import create_run_parser
40
+
41
+ if argv is None:
42
+ import sys
43
+
44
+ argv = sys.argv
45
+ argv = list(argv) # copy argv for manipulation to avoid side-effects
46
+
47
+ # We have intentionally not set the default using `default="INFO"` here so that the default
48
+ # value from here doesn't override the value in `LOG_CONFIG_FILENAME` unless the user indends
49
+ # to do so. If the user doesn't use this flag to set log level, this argument is set to "None"
50
+ # and the logging level specified in `LOG_CONFIG_FILENAME` is used.
51
+
52
+ command_name = os.path.basename(argv[0])
53
+ program_name = "holoscan" if command_name == "__main__.py" else command_name
54
+ parent_parser = argparse.ArgumentParser()
55
+
56
+ parent_parser.add_argument(
57
+ "-l",
58
+ "--log-level",
59
+ dest="log_level",
60
+ type=str.upper,
61
+ choices=["DEBUG", "INFO", "WARN", "ERROR", "CRITICAL"],
62
+ help="set the logging level (default: INFO)",
63
+ )
64
+
65
+ parser = argparse.ArgumentParser(
66
+ parents=[parent_parser],
67
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
68
+ add_help=False,
69
+ prog=program_name,
70
+ )
71
+
72
+ subparser = parser.add_subparsers(dest="command")
73
+
74
+ # Parser for `package` command
75
+ create_package_parser(subparser, "package", parents=[parent_parser])
76
+
77
+ # Parser for `run` command
78
+ create_run_parser(subparser, "run", parents=[parent_parser])
79
+
80
+ # Parser for `version` command
81
+ subparser.add_parser(
82
+ "version", formatter_class=argparse.HelpFormatter, parents=[parent_parser], add_help=False
83
+ )
84
+
85
+ # Parser for `nics` command
86
+ subparser.add_parser(
87
+ "nics", formatter_class=argparse.HelpFormatter, parents=[parent_parser], add_help=False
88
+ )
89
+ args = parser.parse_args(argv[1:])
90
+ args.argv = argv # save argv for later use in runpy
91
+
92
+ # Print help if no command is specified
93
+ if args.command is None:
94
+ parser.print_help()
95
+ parser.exit()
96
+
97
+ if args.command == "package":
98
+ if args.platform[0] == Platform.X64Workstation:
99
+ args.platform_config = PlatformConfiguration.dGPU
100
+ elif args.platform_config is None:
101
+ parser.error(f"'--platform-config' is required for '{args.platform[0].value}'")
102
+
103
+ return args
104
+
105
+
106
+ def set_up_logging(level: Optional[str], config_path: Union[str, Path] = LOG_CONFIG_FILENAME):
107
+ """Initializes the logger and sets up logging level.
108
+
109
+ Args:
110
+ level (str): A logging level (DEBUG, INFO, WARN, ERROR, CRITICAL).
111
+ log_config_path (str): A path to logging config file.
112
+ """
113
+ # Default log config path
114
+ log_config_path = Path(__file__).absolute().parent / LOG_CONFIG_FILENAME
115
+
116
+ config_path = Path(config_path)
117
+
118
+ # If a logging config file that is specified by `log_config_path` exists in the current folder,
119
+ # it overrides the default one
120
+ if config_path.exists():
121
+ log_config_path = config_path
122
+
123
+ config_dict = json.loads(log_config_path.read_bytes())
124
+
125
+ if level is not None and "root" in config_dict:
126
+ config_dict["root"]["level"] = level
127
+ logging.config.dictConfig(config_dict)
128
+
129
+
130
+ def main(argv: Optional[List[str]] = None):
131
+ args = parse_args(argv)
132
+
133
+ set_up_logging(args.log_level)
134
+
135
+ if args.command == "package":
136
+ from .packager.packager import execute_package_command
137
+
138
+ execute_package_command(args)
139
+
140
+ elif args.command == "run":
141
+ from .runner.runner import execute_run_command
142
+
143
+ execute_run_command(args)
144
+
145
+ elif args.command == "version":
146
+ from .common.artifact_sources import ArtifactSources
147
+ from .version.version import execute_version_command
148
+
149
+ artifact_sources = ArtifactSources()
150
+ execute_version_command(args, artifact_sources)
151
+
152
+ elif args.command == "nics":
153
+ from .nics.nics import execute_nics_command
154
+
155
+ execute_nics_command(args)
156
+
157
+
158
+ if __name__ == "__main__":
159
+ main()
@@ -0,0 +1,154 @@
1
+ """
2
+ SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ """ # noqa: E501
17
+
18
+ import argparse
19
+ import os
20
+ from pathlib import Path
21
+ from typing import List
22
+
23
+ from .constants import SDK
24
+ from .enum_types import Platform, PlatformConfiguration, SdkType
25
+
26
+
27
+ def valid_dir_path(path: str, create_if_not_exists: bool = True) -> Path:
28
+ """Helper type checking and type converting method for ArgumentParser.add_argument
29
+ to convert string input to pathlib.Path if the given path exists and it is a directory path.
30
+ If directory does not exist, create the directory and convert string input to pathlib.Path.
31
+
32
+ Args:
33
+ path: string input path
34
+
35
+ Returns:
36
+ If path exists and is a directory, return absolute path as a pathlib.Path object.
37
+
38
+ If path exists and is not a directory, raises argparse.ArgumentTypeError.
39
+
40
+ If path doesn't exist, create the directory and return absolute path as a pathlib.Path
41
+ object.
42
+ """
43
+ path = os.path.expanduser(path)
44
+ dir_path = Path(path).absolute()
45
+ if dir_path.exists():
46
+ if dir_path.is_dir():
47
+ return dir_path
48
+ else:
49
+ raise argparse.ArgumentTypeError(
50
+ f"Expected directory path: '{dir_path}' is not a directory"
51
+ )
52
+
53
+ if create_if_not_exists:
54
+ # create directory
55
+ dir_path.mkdir(parents=True)
56
+ return dir_path
57
+
58
+ raise argparse.ArgumentTypeError(f"No such directory: '{dir_path}'")
59
+
60
+
61
+ def valid_existing_dir_path(path: str) -> Path:
62
+ """Helper type checking and type converting method for ArgumentParser.add_argument
63
+ to convert string input to pathlib.Path if the given path exists and it is a directory path.
64
+
65
+ Args:
66
+ path: string input path
67
+
68
+ Returns:
69
+ If path exists and is a directory, return absolute path as a pathlib.Path object.
70
+
71
+ If path doesn't exist or it is not a directory, raises argparse.ArgumentTypeError.
72
+ """
73
+ return valid_dir_path(path, False)
74
+
75
+
76
+ def valid_existing_path(path: str) -> Path:
77
+ """Helper type checking and type converting method for ArgumentParser.add_argument
78
+ to convert string input to pathlib.Path if the given file/folder path exists.
79
+
80
+ Args:
81
+ path: string input path
82
+
83
+ Returns:
84
+ If path exists, return absolute path as a pathlib.Path object.
85
+
86
+ If path doesn't exist, raises argparse.ArgumentTypeError.
87
+ """
88
+ path = os.path.expanduser(path)
89
+ file_path = Path(path).absolute()
90
+ if file_path.exists():
91
+ return file_path
92
+ raise argparse.ArgumentTypeError(f"No such file/folder: '{file_path}'")
93
+
94
+
95
+ def valid_platforms(platforms_str: str) -> List[Platform]:
96
+ """Helper type checking and type converting method for ArgumentParser.add_argument
97
+ to convert platform strings to Platform enum if values are valid.
98
+
99
+ Args:
100
+ platforms_str: string comma separated platforms values
101
+ Returns:
102
+ If all values are valid, convert all values to Platform enum.
103
+
104
+ Otherwise, raises argparse.ArgumentTypeError.
105
+ """
106
+
107
+ platforms = platforms_str.lower().split(",")
108
+ platform_enums = []
109
+ for platform in platforms:
110
+ if platform not in SDK.PLATFORMS:
111
+ raise argparse.ArgumentTypeError(f"{platform} is not a valid option for --platforms.")
112
+ platform_enums.append(Platform(platform))
113
+
114
+ return platform_enums
115
+
116
+
117
+ def valid_platform_config(platform_config_str: str) -> PlatformConfiguration:
118
+ """Helper type checking and type converting method for ArgumentParser.add_argument
119
+ to convert platform configuration string to PlatformConfigurations enum if value is valid.
120
+
121
+ Args:
122
+ platform_config_str: a platforms configuration value
123
+ Returns:
124
+ If the value is valid, convert the value to PlatformConfigurations enum.
125
+
126
+ Otherwise, raises argparse.ArgumentTypeError.
127
+ """
128
+
129
+ platform_config_str = platform_config_str.lower()
130
+ if platform_config_str not in SDK.PLATFORM_CONFIGS:
131
+ raise argparse.ArgumentTypeError(
132
+ f"{platform_config_str} is not a valid option for --platform-config."
133
+ )
134
+
135
+ return PlatformConfiguration(platform_config_str)
136
+
137
+
138
+ def valid_sdk_type(sdk_str: str) -> SdkType:
139
+ """Helper type checking and type converting method for ArgumentParser.add_argument
140
+ to convert sdk string to SdkType enum if value is valid.
141
+
142
+ Args:
143
+ sdk_str: sdk string
144
+ Returns:
145
+ If the value is valid, convert the value to SdkType enum.
146
+
147
+ Otherwise, raises argparse.ArgumentTypeError.
148
+ """
149
+
150
+ sdk_str = sdk_str.lower()
151
+ if sdk_str not in SDK.SDKS:
152
+ raise argparse.ArgumentTypeError(f"{sdk_str} is not a valid option for --sdk.")
153
+
154
+ return SdkType(sdk_str)
@@ -0,0 +1,144 @@
1
+ """
2
+ SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ """ # noqa: E501
17
+
18
+ import json
19
+ import logging
20
+ from typing import Any, List, Optional
21
+
22
+ import requests
23
+
24
+ from .enum_types import Arch, PlatformConfiguration, SdkType
25
+ from .exceptions import InvalidSourceFileError, ManifestDownloadError
26
+
27
+
28
+ class ArtifactSources:
29
+ """Provides default artifact source URLs with the ability to override."""
30
+
31
+ SectionDebianPackages = "debian-packages"
32
+ SectionBaseImages = "base-images"
33
+ SectionBuildImages = "build-images"
34
+ SectionHealthProbe = "health-probes"
35
+ ManifestFileUrl = (
36
+ "https://edge.urm.nvidia.com/artifactory/sw-holoscan-cli-generic/artifacts.json"
37
+ )
38
+ EdgeROToken = "eyJ2ZXIiOiIyIiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYiLCJraWQiOiJLcXV1ZVdTTlRjSkhqTFhGLTJCSnctX0lkRnY0eVhqREJyNEdWMU5Gc2NJIn0.eyJzdWIiOiJqZnJ0QDAxZHRqNnF0ZWNmcnB6MXJrNmg2cjAwd2FkXC91c2Vyc1wvc3ZjLWhvbG9zY2FuLWNsaS1wdWJsaWMtcm8iLCJzY3AiOiJtZW1iZXItb2YtZ3JvdXBzOnN2Yy1ob2xvc2Nhbi1jbGktcHVibGljLWdyb3VwIiwiYXVkIjoiamZydEAwMWR0ajZxdGVjZnJwejFyazZoNnIwMHdhZCIsImlzcyI6ImpmcnRAMDFkdGo2cXRlY2ZycHoxcms2aDZyMDB3YWRcL3VzZXJzXC9ycGFsYW5pc3dhbXkiLCJpYXQiOjE3MDY1NzA1NjUsImp0aSI6IjlmNmEyMmM1LTk5ZTItNGRlMi1hMDhiLTQxZjg2NzIyYmJjNyJ9.Y0gfyW2F0kxiKnMhGzNCyRRE2DNrDW6CUj5ozrQiIvAbSbhohskFcFmP836PU4p3ZQTzbYk9-bBwrqoPDUaZf8p9AW9GZ3mvlU2BxK0EQ-F4oKxA1_Z7agZ0KKcmcrfWnE4Ffy53qAD8PTk5vdcznpYOBpJtF4i16j2QcXvhVGGEqUyGa7_sONdK0sevb3ZztiEoupi4gD2wPTRn30rjpGIiFSDKiswAQwoyF_SqMCQWOBEeXMISp8hkEggUpvPrESv2lbpjgaKuEJ1CikbivYTJCcoqpgH7E72FXr1sB9jfwrFD8pkjtRpGGDxN43waXy4f3Ctr8_rpbmCvwSa9iw" # noqa: E501
39
+
40
+ def __init__(self) -> None:
41
+ self._logger = logging.getLogger("common")
42
+ self._supported_holoscan_versions = ["2.0.0", "2.1.0"]
43
+
44
+ @property
45
+ def holoscan_versions(self) -> List[str]:
46
+ return self._supported_holoscan_versions
47
+
48
+ def base_images(self, version) -> List[Any]:
49
+ return self._data[version][SdkType.Holoscan.value][ArtifactSources.SectionBaseImages]
50
+
51
+ def build_images(self, version) -> List[Any]:
52
+ return self._data[version][SdkType.Holoscan.value][ArtifactSources.SectionBuildImages]
53
+
54
+ def health_probe(self, version) -> List[Any]:
55
+ return self._data[version][ArtifactSources.SectionHealthProbe]
56
+
57
+ def load(self, uri: str):
58
+ """Overrides the default values from a given JSON file.
59
+ Validates top-level attributes to ensure the file is valid
60
+
61
+ Args:
62
+ file (Path): Path to JSON file
63
+ """
64
+ if uri.startswith("https"):
65
+ self._download_manifest_internal(uri)
66
+ elif uri.startswith("http"):
67
+ raise ManifestDownloadError(
68
+ "Downloading manifest files from non-HTTPS servers is not supported."
69
+ )
70
+ else:
71
+ self._logger.info(f"Using CLI manifest file from {uri}...")
72
+ with open(uri) as file:
73
+ temp = json.load(file)
74
+
75
+ try:
76
+ self.validate(temp)
77
+ self._data = temp
78
+ except Exception as ex:
79
+ raise InvalidSourceFileError(f"{uri} is missing required data: {ex}") from ex
80
+
81
+ def validate(self, data: Any):
82
+ self._logger.debug("Validating CLI manifest file...")
83
+
84
+ for key in data:
85
+ item = data[key]
86
+ assert SdkType.Holoscan.value in item
87
+ holoscan = item[SdkType.Holoscan.value]
88
+
89
+ assert ArtifactSources.SectionDebianPackages in holoscan
90
+ assert ArtifactSources.SectionBaseImages in holoscan
91
+ assert ArtifactSources.SectionBuildImages in holoscan
92
+
93
+ for config in PlatformConfiguration:
94
+ assert config.value in holoscan[ArtifactSources.SectionBaseImages]
95
+ assert config.value in holoscan[ArtifactSources.SectionBuildImages]
96
+
97
+ def download_manifest(self):
98
+ self._download_manifest_internal(
99
+ ArtifactSources.ManifestFileUrl,
100
+ {"Authorization": f"Bearer {ArtifactSources.EdgeROToken}"},
101
+ )
102
+
103
+ def _download_manifest_internal(self, url, headers=None):
104
+ self._logger.info("Downloading CLI manifest file...")
105
+ manifest = requests.get(url, headers=headers)
106
+
107
+ try:
108
+ manifest.raise_for_status()
109
+ except Exception as ex:
110
+ raise ManifestDownloadError(
111
+ f"Error downloading manifest file from {url}: {manifest.reason}"
112
+ ) from ex
113
+ else:
114
+ self._data = manifest.json()
115
+ self.validate(self._data)
116
+
117
+ def debian_packages(
118
+ self, version: str, architecture: Arch, platform_configuration: PlatformConfiguration
119
+ ) -> Optional[str]:
120
+ """Gets the URI of a Debian package based on the version,
121
+ the architecture and the platform configuration.
122
+
123
+ Args:
124
+ version (str): version of package
125
+ architecture (Arch): architecture of the package
126
+ platform_configuration (PlatformConfiguration): platform configuration of the package
127
+
128
+ Returns:
129
+ Optional[str]: _description_
130
+ """
131
+ debian_sources = self._data[version][SdkType.Holoscan.value][
132
+ ArtifactSources.SectionDebianPackages
133
+ ]
134
+
135
+ if architecture == Arch.amd64 and architecture.value in debian_sources:
136
+ return debian_sources[architecture.value]
137
+ elif (
138
+ architecture == Arch.arm64
139
+ and architecture.value in debian_sources
140
+ and platform_configuration.value in debian_sources[architecture.value]
141
+ ):
142
+ return debian_sources[architecture.value][platform_configuration.value]
143
+
144
+ return None