diff --git a/applications/aja_video_capture/cpp/CMakeLists.txt b/applications/aja_video_capture/cpp/CMakeLists.txt index 8a8562a1d..959db9918 100644 --- a/applications/aja_video_capture/cpp/CMakeLists.txt +++ b/applications/aja_video_capture/cpp/CMakeLists.txt @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +find_package(holoscan 3.0 REQUIRED) + # Create example add_executable(aja_capture aja_capture.cpp @@ -39,7 +41,7 @@ if(BUILD_TESTING) set(RECORDING_DIR ${CMAKE_CURRENT_BINARY_DIR}/recording_output) set(SOURCE_VIDEO_BASENAME video_replayer_output) - set(VALIDATION_FRAMES_DIR ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/) + set(VALIDATION_FRAMES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../tests/) file(MAKE_DIRECTORY ${RECORDING_DIR}) @@ -51,7 +53,7 @@ if(BUILD_TESTING) # Patch the current example to enable recording the rendering window add_custom_command(OUTPUT aja_capture_test.cpp COMMAND patch -u -o aja_capture_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/aja_capture.cpp - ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/cpp_aja_capture.patch + ${CMAKE_CURRENT_SOURCE_DIR}/../tests/cpp_aja_capture.patch ) # Create the test executable @@ -78,17 +80,17 @@ if(BUILD_TESTING) ) # Add the test and make sure it runs - add_test(NAME EXAMPLE_CPP_AJA_CAPTURE_TEST + add_test(NAME AJA_CAPTURE_CPP_TEST COMMAND ${CMAKE_CURRENT_BINARY_DIR}/aja_capture_test ${CONFIG_FILE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) - set_tests_properties(EXAMPLE_CPP_AJA_CAPTURE_TEST PROPERTIES + set_tests_properties(AJA_CAPTURE_CPP_TEST PROPERTIES PASS_REGULAR_EXPRESSION "Scheduler stopped: Some entities are waiting for execution" ) # Add a test to check the validity of the frames - add_test(NAME EXAMPLE_CPP_AJA_CAPTURE_RENDER_TEST - COMMAND python3 ${Holoscan-examples_SOURCE_DIR}/../scripts/video_validation.py + add_test(NAME AJA_CAPTURE_CPP_RENDER_TEST + COMMAND python3 ${CMAKE_SOURCE_DIR}/utilities/video_validation.py --source_video_dir ${RECORDING_DIR} --source_video_basename ${SOURCE_VIDEO_BASENAME} --output_dir ${RECORDING_DIR} @@ -96,8 +98,8 @@ if(BUILD_TESTING) WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) - set_tests_properties(EXAMPLE_CPP_AJA_CAPTURE_RENDER_TEST PROPERTIES - DEPENDS EXAMPLE_CPP_AJA_CAPTURE_TEST + set_tests_properties(AJA_CAPTURE_CPP_RENDER_TEST PROPERTIES + DEPENDS AJA_CAPTURE_CPP_TEST PASS_REGULAR_EXPRESSION "Valid video output!" ) diff --git a/applications/aja_video_capture/python/CMakeLists.txt b/applications/aja_video_capture/python/CMakeLists.txt index 95093439e..972b6f99d 100644 --- a/applications/aja_video_capture/python/CMakeLists.txt +++ b/applications/aja_video_capture/python/CMakeLists.txt @@ -25,7 +25,7 @@ if(BUILD_TESTING) set(RECORDING_DIR ${CMAKE_CURRENT_BINARY_DIR}/recording_output) set(SOURCE_VIDEO_BASENAME python_aja_capture_output) - set(VALIDATION_FRAMES_DIR ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/) + set(VALIDATION_FRAMES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../tests/) file(MAKE_DIRECTORY ${RECORDING_DIR}) @@ -38,26 +38,26 @@ if(BUILD_TESTING) # Patch the current example to enable recording the rendering window add_custom_command(OUTPUT aja_capture_test.py COMMAND patch -u -o aja_capture_test.py ${CMAKE_CURRENT_SOURCE_DIR}/aja_capture.py - ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/python_aja_capture.patch + ${CMAKE_CURRENT_SOURCE_DIR}/../tests/python_aja_capture.patch ) add_custom_target(python_aja_capture_test ALL DEPENDS "aja_capture_test.py" ) - add_test(NAME EXAMPLE_PYTHON_AJA_CAPTURE_TEST + add_test(NAME AJA_CAPTURE_PYTHON_TEST COMMAND python3 aja_capture_test.py --config python_aja_capture_config.yaml WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - set_tests_properties(EXAMPLE_PYTHON_AJA_CAPTURE_TEST PROPERTIES + set_tests_properties(AJA_CAPTURE_PYTHON_TEST PROPERTIES DEPENDS "aja_capture_test.py" PASS_REGULAR_EXPRESSION "Scheduler stopped: Some entities are waiting for execution" ) # Add a test to check the validity of the frames - add_test(NAME EXAMPLE_PYTHON_AJA_CAPTURE_RENDER_TEST - COMMAND python3 ${Holoscan-examples_SOURCE_DIR}/../scripts/video_validation.py + add_test(NAME AJA_CAPTURE_PYTHON_RENDER_TEST + COMMAND python3 ${CMAKE_SOURCE_DIR}/utilities/video_validation.py --source_video_dir ${RECORDING_DIR} --source_video_basename ${SOURCE_VIDEO_BASENAME} --output_dir ${RECORDING_DIR} @@ -65,8 +65,8 @@ if(BUILD_TESTING) WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) - set_tests_properties(EXAMPLE_PYTHON_AJA_CAPTURE_RENDER_TEST PROPERTIES - DEPENDS EXAMPLE_PYTHON_AJA_CAPTURE_TEST + set_tests_properties(AJA_CAPTURE_PYTHON_RENDER_TEST PROPERTIES + DEPENDS AJA_CAPTURE_PYTHON_TEST PASS_REGULAR_EXPRESSION "Valid video output!" ) diff --git a/applications/aja_video_capture/python/aja_capture.py b/applications/aja_video_capture/python/aja_capture.py index 70767e3be..3d12ebda7 100644 --- a/applications/aja_video_capture/python/aja_capture.py +++ b/applications/aja_video_capture/python/aja_capture.py @@ -19,7 +19,9 @@ from holoscan.conditions import CountCondition from holoscan.core import Application -from holoscan.operators import AJASourceOp, HolovizOp +from holoscan.operators import HolovizOp + +from holohub.aja_source import AJASourceOp class AJACaptureApp(Application): diff --git a/applications/aja_video_capture/tests/0001.png b/applications/aja_video_capture/tests/0001.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0001.png differ diff --git a/applications/aja_video_capture/tests/0002.png b/applications/aja_video_capture/tests/0002.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0002.png differ diff --git a/applications/aja_video_capture/tests/0003.png b/applications/aja_video_capture/tests/0003.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0003.png differ diff --git a/applications/aja_video_capture/tests/0004.png b/applications/aja_video_capture/tests/0004.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0004.png differ diff --git a/applications/aja_video_capture/tests/0005.png b/applications/aja_video_capture/tests/0005.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0005.png differ diff --git a/applications/aja_video_capture/tests/0006.png b/applications/aja_video_capture/tests/0006.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0006.png differ diff --git a/applications/aja_video_capture/tests/0007.png b/applications/aja_video_capture/tests/0007.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0007.png differ diff --git a/applications/aja_video_capture/tests/0008.png b/applications/aja_video_capture/tests/0008.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0008.png differ diff --git a/applications/aja_video_capture/tests/0009.png b/applications/aja_video_capture/tests/0009.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0009.png differ diff --git a/applications/aja_video_capture/tests/0010.png b/applications/aja_video_capture/tests/0010.png new file mode 100644 index 000000000..00b60d974 Binary files /dev/null and b/applications/aja_video_capture/tests/0010.png differ diff --git a/applications/aja_video_capture/tests/cpp_aja_capture.patch b/applications/aja_video_capture/tests/cpp_aja_capture.patch new file mode 100644 index 000000000..46d6d634f --- /dev/null +++ b/applications/aja_video_capture/tests/cpp_aja_capture.patch @@ -0,0 +1,37 @@ +diff --git a/applications/aja_video_capture/cpp/aja_capture.cpp b/applications/aja_video_capture/cpp/aja_capture.cpp +index 890ec9ab..8431555c 100644 +--- a/applications/aja_video_capture/cpp/aja_capture.cpp ++++ b/applications/aja_video_capture/cpp/aja_capture.cpp +@@ -19,6 +19,11 @@ + #include + + #include ++ ++#include ++#include ++#include ++ + class App : public holoscan::Application { + public: + void compose() override { +@@ -30,6 +35,21 @@ class App : public holoscan::Application { + + // Flow definition + add_flow(source, visualizer, {{"video_buffer_output", "receivers"}}); ++ ++ // Recorder to validate the video output ++ std::shared_ptr recorder_format_converter; ++ recorder_format_converter = make_operator( ++ "recorder_format_converter", ++ Arg("in_dtype", std::string("rgba8888")), ++ Arg("out_dtype", std::string("rgb888"))); ++ auto recorder = make_operator( ++ "recorder", ++ Arg("directory", std::string(RECORDING_DIR)), ++ Arg("basename", std::string(SOURCE_VIDEO_BASENAME))); ++ add_flow(visualizer, recorder_format_converter, {{"render_buffer_output", "source_video"}}); ++ add_flow(recorder_format_converter, recorder); ++ visualizer->add_arg(Arg("enable_render_buffer_output", true)); ++ visualizer->add_arg(Arg("allocator", make_resource("allocator"))); + } + }; diff --git a/applications/aja_video_capture/tests/python_aja_capture.patch b/applications/aja_video_capture/tests/python_aja_capture.patch new file mode 100644 index 000000000..1ce8e9aa5 --- /dev/null +++ b/applications/aja_video_capture/tests/python_aja_capture.patch @@ -0,0 +1,37 @@ +diff --git a/applications/aja_video_capture/python/aja_capture.py b/applications/aja_video_capture/python/aja_capture.py +index 3d12ebda..7d43943f 100644 +--- a/applications/aja_video_capture/python/aja_capture.py ++++ b/applications/aja_video_capture/python/aja_capture.py +@@ -20,6 +20,8 @@ import os + from holoscan.conditions import CountCondition + from holoscan.core import Application + from holoscan.operators import HolovizOp ++from holoscan.operators import VideoStreamRecorderOp, FormatConverterOp ++from holoscan.resources import UnboundedAllocator + + from holohub.aja_source import AJASourceOp + +@@ -46,6 +48,23 @@ class AJACaptureApp(Application): + visualizer = HolovizOp(self, name="holoviz", **self.kwargs("holoviz")) + + self.add_flow(source, visualizer, {("video_buffer_output", "receivers")}) ++ recorder_format_converter = FormatConverterOp( ++ self, ++ name="recorder_format_converter", ++ in_dtype="rgba8888", ++ out_dtype="rgb888", ++ pool=UnboundedAllocator(self, name="pool") ++ ) ++ recorder = VideoStreamRecorderOp( ++ self, ++ name="recorder", ++ **self.kwargs("recorder") ++ ) ++ ++ visualizer.add_arg(allocator=UnboundedAllocator(self, name="allocator")) ++ ++ self.add_flow(visualizer, recorder_format_converter, {("render_buffer_output", "source_video")}) ++ self.add_flow(recorder_format_converter, recorder) + + + def main(config_file): diff --git a/applications/endoscopy_out_of_body_detection/python/main.py b/applications/endoscopy_out_of_body_detection/python/main.py index 4778ca8bf..dc72614e5 100644 --- a/applications/endoscopy_out_of_body_detection/python/main.py +++ b/applications/endoscopy_out_of_body_detection/python/main.py @@ -20,7 +20,6 @@ from holoscan.core import Application from holoscan.operators import ( - AJASourceOp, FormatConverterOp, InferenceOp, InferenceProcessorOp, @@ -28,6 +27,8 @@ ) from holoscan.resources import UnboundedAllocator +from holohub.aja_source import AJASourceOp + class EndoscopyOutOfBodyDetectionApp(Application): """Endoscopy Out-of-Body Detection""" diff --git a/applications/holochat/README.md b/applications/holochat/README.md index afe2c3100..db9c73cbf 100644 --- a/applications/holochat/README.md +++ b/applications/holochat/README.md @@ -22,13 +22,13 @@ HoloChat is an AI-driven chatbot, built on top of a **locally hosted Code-Llama **If running local LLM**: - **GPU**: NVIDIA dGPU w/ >= 28 GB VRAM - **Memory**: \>= 28 GB of available disk memory - - Needed to download [fine-tuned Code Llama 34B](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/models/phind-codellama-34b-v2-q5_k_m) and [BGE-Large](https://huggingface.co/BAAI/bge-large-en) embedding model + - Needed to download [fine-tuned Code Llama 34B](https://huggingface.co/TheBloke/Phind-CodeLlama-34B-v2-GGUF) and [BGE-Large](https://huggingface.co/BAAI/bge-large-en) embedding model *Tested using [NVIDIA IGX Orin](https://www.nvidia.com/en-us/edge-computing/products/igx/) w/ RTX A6000 and [Dell Precision 5820 Workstation](https://www.dell.com/en-us/shop/desktop-computers/precision-5820-tower-workstation/spd/precision-5820-workstation/xctopt5820us) w/ RTX A6000 ## Running HoloChat: 🏃💨 **When running HoloChat, you have two LLM options:** -- Local: Uses [Phind-CodeLlama-34B-v2]((https://huggingface.co/Phind/Phind-CodeLlama-34B-v2)) running on your local machine using Llama.cpp +- Local: Uses [Phind-CodeLlama-34B-v2](https://huggingface.co/Phind/Phind-CodeLlama-34B-v2) running on your local machine using Llama.cpp - Remote: Uses [Llama-3-70b-Instruct](https://build.nvidia.com/meta/llama3-70b) using the [NVIDIA NIM API](https://build.nvidia.com/explore/discover) ### TLDR; 🥱 @@ -46,7 +46,7 @@ echo "NVIDIA_API_KEY=" > ./applications/holochat/.env ### Build Notes: ⚙️ **Build Time:** -- HoloChat uses a [PyTorch container](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch) from [NGC](https://catalog.ngc.nvidia.com/?filters=&orderBy=weightPopularDESC&query=) and may also download the [~23 GB Phind LLM](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/models/phind-codellama-34b-v2-q5_k_m) from NGC. As such, the first time building this application **will likely take ~45 minutes** depending on your internet speeds. However, this is a one-time set-up and subsequent runs of HoloChat should take seconds to launch. +- HoloChat uses a [PyTorch container](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch) from [NGC](https://catalog.ngc.nvidia.com/?filters=&orderBy=weightPopularDESC&query=) and may also download the [~23 GB Phind LLM](https://huggingface.co/TheBloke/Phind-CodeLlama-34B-v2-GGUF) from HuggingFace. As such, the first time building this application **will likely take ~45 minutes** depending on your internet speeds. However, this is a one-time set-up and subsequent runs of HoloChat should take seconds to launch. **Build Location:** diff --git a/applications/holochat/holochat.sh b/applications/holochat/holochat.sh index 23ef55ddd..6edcd8787 100755 --- a/applications/holochat/holochat.sh +++ b/applications/holochat/holochat.sh @@ -54,9 +54,7 @@ function build_db { function download_llama { mkdir -p "$BASE_DIR/docs" if [ ! -f "$BASE_DIR/models/phind-codellama-34b-v2.Q5_K_M.gguf" ]; then - wget -nc -P "$BASE_DIR/models" https://api.ngc.nvidia.com/v2/models/nvidia/clara-holoscan/phind-codellama-34b-v2-q5_k_m/versions/2.0/zip - unzip -n "$BASE_DIR/models/zip" -d "$BASE_DIR/models/" - rm "$BASE_DIR/models/zip" + wget -nc -P "$BASE_DIR/models" https://huggingface.co/TheBloke/Phind-CodeLlama-34B-v2-GGUF/resolve/main/phind-codellama-34b-v2.Q5_K_M.gguf else echo "Model already exists, skipping download." fi