Skip to content

Commit 88284cc

Browse files
authored
Merge branch 'main' into ah/pipeline_vis
2 parents 758b6f2 + 9207941 commit 88284cc

File tree

6 files changed

+129
-44
lines changed

6 files changed

+129
-44
lines changed

README.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,21 +207,36 @@ Make sure you build the application (if applicable) before running it.
207207

208208
## Cleanup
209209

210-
You can run the command below to reset your `build` directory:
210+
> [!IMPORTANT]
211+
> Many applications use custom container environments with specific build and runtime dependencies. If you encounter issues with missing or broken build tools between different applications, clearing the build cache should be your first troubleshooting step.
211212
212-
```sh
213-
./holohub clear-cache
214-
```
213+
Clear cache directories using the `clear-cache` command:
215214

216-
In some cases you may also want to clear out datasets downloaded by applications to the `data` folder:
215+
```sh
216+
# Clear all cache folders (build, data, install)
217+
./holohub clear-cache
217218

218-
```sh
219-
rm -rf ./data
220-
```
219+
# Clear specific cache types
220+
./holohub clear-cache --build # Build folders only
221+
./holohub clear-cache --data # Data folders only
222+
./holohub clear-cache --install # Install folders only
223+
224+
# Combine flags to clear multiple types
225+
./holohub clear-cache --build --data
226+
227+
# Preview what would be removed without actually deleting
228+
./holohub clear-cache --dryrun
229+
./holohub clear-cache --build --dryrun
230+
```
221231

222-
Note that many applications supply custom container environments with build and runtime dependencies.
223-
Failing to clean the build cache between different applications may result in unexpected behavior where build
224-
tools or libraries appear to be broken or missing. Clearing the build cache is a good first check to address those issues.
232+
> [!TIP]
233+
> If you encounter permission issues when clearing cache, run the command inside a container with root privileges:
234+
>
235+
> ```sh
236+
> ./holohub run-container --as-root -- ./holohub clear-cache
237+
> ```
238+
>
239+
> This is safer than using `sudo` directly, as it maintains proper container isolation and avoids changing file ownership.
225240
226241
## Contributing
227242

operators/dds/base/README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
### DDS Base Operator
1+
# DDS Base Operator
22

33
The DDS Base Operator provides a base class which can be inherited by any
44
operator class which requires access to a DDS domain.
55

6-
This operator requires an installation of [RTI Connext Express](https://content.rti.com/l/983311/2025-07-08/q5x1n8) to provide access to the DDS domain, as specified by the [OMG Data-Distribution Service](https://www.omg.org/omg-dds-portal/). To obtain a license/activation key, please [click here](https://content.rti.com/l/983311/2025-07-25/q6729c). Please see the [usage rules](https://www.rti.com/products/connext-express) for Connext Express.
6+
This operator requires an installation of [RTI Connext](https://content.rti.com/l/983311/2025-07-08/q5x1n8) to provide access to the DDS domain, as specified by the [OMG Data-Distribution Service](https://www.omg.org/omg-dds-portal/).
77

8-
#### `holoscan::ops::DDSOperatorBase`
8+
You can obtain a license/activation key for RTI Connext directly from RTI by downloading it [here](https://content.rti.com/l/983311/2025-07-25/q6729c). For additional information on RTI Connext and how it integrates with NVIDIA products, please refer to the [RTI-NVIDIA integration page](https://www.rti.com/products/third-party-integrations/nvidia).
9+
10+
If you have questions, please email [[email protected]](mailto:[email protected]).
11+
12+
## `holoscan::ops::DDSOperatorBase`
913

1014
Base class which provides the parameters and members required to access a
1115
DDS domain.
@@ -14,7 +18,7 @@ For more documentation about how these parameters (and other similar
1418
inheriting-class parameters) are used, see the
1519
[RTI Connext Documentation](https://community.rti.com/documentation).
1620

17-
##### Parameters
21+
### Parameters
1822

1923
- **`qos_provider`**: URI for the DDS QoS Provider
2024
- type: `std::string`
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
1-
### DDS Shape Subscriber Operator
1+
# DDS Shape Subscriber Operator
22

33
The DDS Shape Subscriber Operator subscribes to and reads from the `Square`, `Circle`, and
44
`Triangle` shape topics as used by the [RTI Shapes Demo](https://www.rti.com/free-trial/shapes-demo).
55
It will then translate the received shape data to an internal `Shape` datatype for output
66
to downstream operators.
77

8-
This operator requires an installation of [RTI Connext Express](https://content.rti.com/l/983311/2025-07-08/q5x1n8) to provide access to the DDS domain, as specified by the [OMG Data-Distribution Service](https://www.omg.org/omg-dds-portal/). To obtain a license/activation key, please [click here](https://content.rti.com/l/983311/2025-07-25/q6729c). Please see the [usage rules](https://www.rti.com/products/connext-express) for Connext Express.
8+
This operator requires an installation of [RTI Connext](https://content.rti.com/l/983311/2025-07-08/q5x1n8) to provide access to the DDS domain, as specified by the [OMG Data-Distribution Service](https://www.omg.org/omg-dds-portal/).
99

10-
#### `holoscan::ops::DDSShapesSubscriberOp`
10+
You can obtain a license/activation key for RTI Connext directly from RTI by downloading it [here](https://content.rti.com/l/983311/2025-07-25/q6729c). For additional information on RTI Connext and how it integrates with NVIDIA products, please refer to the [RTI-NVIDIA integration page](https://www.rti.com/products/third-party-integrations/nvidia).
11+
12+
If you have questions, please email [[email protected]](mailto:[email protected]).
13+
14+
## `holoscan::ops::DDSShapesSubscriberOp`
1115

1216
Operator class for the DDS Shapes Subscriber.
1317

1418
This operator also inherits the parameters from [DDSOperatorBase](../base/README.md).
1519

16-
##### Parameters
20+
### Parameters
1721

1822
- **`reader_qos`**: The name of the QoS profile to use for the DDS DataReader
1923
- type: `std::string`
2024

21-
##### Outputs
25+
### Outputs
2226

2327
- **`output`**: Output shapes, translated from those read from DDS
2428
- type: `holoscan::ops::DDSShapesSubscriberOp::Shape`

operators/dds/video/README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
1-
### DDS Video Operators
1+
# DDS Video Operators
22

33
The DDS Video Operators allow applications to read or write video buffers
44
to a DDS databus, enabling communication with other applications via the
55
[VideoFrame](VideoFrame.idl) DDS topic.
66

7-
This operator requires an installation of [RTI Connext Express](https://content.rti.com/l/983311/2025-07-08/q5x1n8) to provide access to the DDS domain, as specified by the [OMG Data-Distribution Service](https://www.omg.org/omg-dds-portal/). To obtain a license/activation key, please [click here](https://content.rti.com/l/983311/2025-07-25/q6729c). Please see the [usage rules](https://www.rti.com/products/connext-express) for Connext Express.
7+
This operator requires an installation of [RTI Connext](https://content.rti.com/l/983311/2025-07-08/q5x1n8) to provide access to the DDS domain, as specified by the [OMG Data-Distribution Service](https://www.omg.org/omg-dds-portal/).
88

9-
#### `holoscan::ops::DDSVideoPublisherOp`
9+
You can obtain a license/activation key for RTI Connext directly from RTI by downloading it [here](https://content.rti.com/l/983311/2025-07-25/q6729c). For additional information on RTI Connext and how it integrates with NVIDIA products, please refer to the [RTI-NVIDIA integration page](https://www.rti.com/products/third-party-integrations/nvidia).
10+
11+
If you have questions, please email [[email protected]](mailto:[email protected]).
12+
13+
## `holoscan::ops::DDSVideoPublisherOp`
1014

1115
Operator class for the DDS video publisher. This operator accepts `VideoBuffer` objects
1216
as input and publishes each buffer to DDS as a [VideoFrame](VideoFrame.idl).
1317

1418
This operator also inherits the parameters from [DDSOperatorBase](../base/README.md).
1519

16-
##### Parameters
20+
### Parameters
1721

1822
- **`writer_qos`**: The name of the QoS profile to use for the DDS DataWriter
1923
- type: `std::string`
2024
- **`stream_id`**: The ID to use for the video stream
2125
- type: `uint32_t`
2226

23-
##### Inputs
27+
### Inputs
2428

2529
- **`input`**: Input video buffer
2630
- type: `nvidia::gxf::VideoBuffer`
2731

28-
#### `holoscan::ops::DDSVideoSubscriberOp`
32+
## `holoscan::ops::DDSVideoSubscriberOp`
2933

3034
Operator class for the DDS video subscriber. This operator reads from the
3135
[VideoFrame](VideoFrame.idl) DDS topic and outputs each received frame as
3236
`VideoBuffer` objects.
3337

3438
This operator also inherits the parameters from [DDSOperatorBase](../base/README.md).
3539

36-
##### Parameters
40+
### Parameters
3741

3842
- **`reader_qos`**: The name of the QoS profile to use for the DDS DataReader
3943
- type: `std::string`
@@ -42,7 +46,7 @@ This operator also inherits the parameters from [DDSOperatorBase](../base/README
4246
- **`allocator`**: Allocator used to allocate the output data
4347
- type: `std::shared_ptr<Allocator>`
4448

45-
##### Outputs
49+
### Outputs
4650

4751
- **`output`**: Output video buffer
4852
- type: `nvidia::gxf::VideoBuffer`

utilities/cli/holohub.py

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ def _create_parser(self) -> argparse.ArgumentParser:
388388
)
389389
self.subparsers["test"] = test
390390
test.add_argument("project", nargs="?", help="Project to test")
391+
test.add_argument(
392+
"--local", action="store_true", help="Test locally instead of in container"
393+
)
391394
test.add_argument("--verbose", action="store_true", help="Print extra output")
392395
test.add_argument(
393396
"--dryrun", action="store_true", help="Print commands without executing them"
@@ -433,6 +436,11 @@ def _create_parser(self) -> argparse.ArgumentParser:
433436
clear_cache.add_argument(
434437
"--dryrun", action="store_true", help="Print commands without executing them"
435438
)
439+
clear_cache.add_argument("--build", action="store_true", help="Clear build folders only")
440+
clear_cache.add_argument("--data", action="store_true", help="Clear data folders only")
441+
clear_cache.add_argument(
442+
"--install", action="store_true", help="Clear install folders only"
443+
)
436444
clear_cache.set_defaults(func=self.handle_clear_cache)
437445

438446
# Add vscode command
@@ -833,7 +841,9 @@ def handle_test(self, args: argparse.Namespace) -> None:
833841
container.dryrun = args.dryrun
834842
container.verbose = args.verbose
835843

836-
if not skip_docker_build:
844+
is_local_mode = bool(args.local or os.environ.get("HOLOHUB_BUILD_LOCAL"))
845+
846+
if not is_local_mode and not skip_docker_build:
837847
build_args = args.build_args or ""
838848
extra_scripts = (getattr(args, "extra_scripts", None) or []).copy()
839849

@@ -864,11 +874,14 @@ def handle_test(self, args: argparse.Namespace) -> None:
864874
# TAG is used in CTest scripts by default
865875
if getattr(args, "build_name_suffix", None):
866876
tag = args.build_name_suffix
877+
elif is_local_mode:
878+
tag = "local"
867879
else:
868-
if skip_docker_build:
869-
image_name = getattr(args, "img", None) or container.image_name
870-
else:
871-
image_name = args.base_img or container.default_base_image()
880+
image_name = (
881+
(getattr(args, "img", None) or container.image_name)
882+
if skip_docker_build
883+
else (args.base_img or container.default_base_image())
884+
)
872885
tag = image_name.split(":")[-1]
873886

874887
ctest_cmd = f"{xvfb} ctest "
@@ -919,6 +932,23 @@ def handle_test(self, args: argparse.Namespace) -> None:
919932
if args.verbose:
920933
ctest_cmd += "-VV "
921934

935+
if is_local_mode:
936+
print(
937+
holohub_cli_util.format_cmd(f"cd {HoloHubCLI.HOLOHUB_ROOT}", is_dryrun=args.dryrun)
938+
)
939+
if not args.dryrun:
940+
os.chdir(HoloHubCLI.HOLOHUB_ROOT)
941+
942+
env = os.environ.copy()
943+
env["PYTHONPATH"] = (
944+
f"{env.get('PYTHONPATH', '')}:{self.DEFAULT_SDK_DIR}/python/lib:{self.HOLOHUB_ROOT}"
945+
)
946+
env["HOLOHUB_DATA_PATH"] = str(self.DEFAULT_DATA_DIR)
947+
env.setdefault("HOLOSCAN_INPUT_PATH", str(self.DEFAULT_DATA_DIR))
948+
949+
holohub_cli_util.run_command(["bash", "-c", ctest_cmd], dry_run=args.dryrun, env=env)
950+
return
951+
922952
container.run(
923953
img=getattr(args, "img", None),
924954
use_tini=True,
@@ -2013,21 +2043,48 @@ def handle_install(self, args: argparse.Namespace) -> None:
20132043
extra_args=extra_args,
20142044
)
20152045

2046+
def _collect_cache_dirs(self, patterns: list[str], default_dir=None) -> list:
2047+
"""Helper to collect cache directories matching patterns."""
2048+
dirs = []
2049+
if default_dir is not None:
2050+
dirs.append(default_dir)
2051+
for pattern in patterns:
2052+
for path in HoloHubCLI.HOLOHUB_ROOT.glob(pattern):
2053+
if path.is_dir() and path not in dirs:
2054+
dirs.append(path)
2055+
return dirs
2056+
20162057
def handle_clear_cache(self, args: argparse.Namespace) -> None:
20172058
"""Handle clear-cache command"""
2059+
# Determine which folders to clear
2060+
clear_build = getattr(args, "build", False)
2061+
clear_data = getattr(args, "data", False)
2062+
clear_install = getattr(args, "install", False)
2063+
2064+
# If no flags are provided, clear all (backward compatibility)
2065+
clear_all = not (clear_build or clear_data or clear_install)
2066+
20182067
if args.dryrun:
20192068
print(Color.blue("Would clear cache folders:"))
20202069
else:
20212070
print(Color.blue("Clearing cache..."))
20222071

2023-
cache_dirs = [
2024-
self.DEFAULT_BUILD_PARENT_DIR,
2025-
self.DEFAULT_DATA_DIR,
2026-
]
2027-
for pattern in ["build", "build-*", "data", "data-*", "install"]:
2028-
for path in HoloHubCLI.HOLOHUB_ROOT.glob(pattern):
2029-
if path.is_dir() and path not in cache_dirs:
2030-
cache_dirs.append(path)
2072+
cache_dirs = []
2073+
2074+
# Collect build folders if needed
2075+
if clear_all or clear_build:
2076+
cache_dirs.extend(
2077+
self._collect_cache_dirs(["build", "build-*"], self.DEFAULT_BUILD_PARENT_DIR)
2078+
)
2079+
2080+
# Collect data folders if needed
2081+
if clear_all or clear_data:
2082+
cache_dirs.extend(self._collect_cache_dirs(["data", "data-*"], self.DEFAULT_DATA_DIR))
2083+
2084+
# Collect install folders if needed
2085+
if clear_all or clear_install:
2086+
cache_dirs.extend(self._collect_cache_dirs(["install", "install-*"]))
2087+
20312088
for path in set(cache_dirs):
20322089
if path.exists() and path.is_dir():
20332090
if args.dryrun:

utilities/cli/util.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,14 +580,15 @@ def find_hsdk_build_rel_dir(local_sdk_root: Optional[Union[str, Path]] = None) -
580580

581581
def get_compute_capacity() -> str:
582582
"""Get GPU compute capacity"""
583-
if not shutil.which("nvidia-smi"):
583+
nvidia_smi = shutil.which("nvidia-smi")
584+
if not nvidia_smi:
584585
return "0.0"
585586
try:
586587
output = subprocess.check_output(
587-
["nvidia-smi", "--query-gpu=compute_cap", "--format=csv,noheader"]
588+
[nvidia_smi, "--query-gpu=compute_cap", "--format=csv,noheader"]
588589
)
589590
return output.decode().strip().split("\n")[0]
590-
except subprocess.CalledProcessError:
591+
except (subprocess.CalledProcessError, OSError):
591592
return "0.0"
592593

593594

0 commit comments

Comments
 (0)