Skip to content

Commit 102cc64

Browse files
committed
feat: Add complete cuslide2 plugin implementation with tests and benchmarks
1 parent 576180b commit 102cc64

File tree

19 files changed

+5194
-152
lines changed

19 files changed

+5194
-152
lines changed

cpp/plugins/cucim.kit.cuslide2/CMakeLists.txt

Lines changed: 118 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ set(CUCIM_PLUGIN_NAME "cucim.kit.cuslide2")
2828
include(SuperBuildUtils)
2929
include(CuCIMUtils)
3030

31+
################################################################################
32+
# Set cmake policy
33+
################################################################################
34+
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19")
35+
cmake_policy(SET CMP0110 NEW) # For add_test() to support arbitrary characters in test name
36+
endif()
37+
3138
################################################################################
3239
# Basic setup
3340
################################################################################
@@ -92,23 +99,25 @@ include(ExternalProject)
9299
# Setup CXX11 ABI
93100
# : Adds CXX11 ABI definition to the compiler command line for targets in the current directory,
94101
# whether added before or after this command is invoked, and for the ones in sub-directories added after.
95-
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) # TODO: create two library, one with CXX11 ABI and one without it.
102+
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) # TODO: create two library, one with CXX11 ABI and one without it.
96103

97104
################################################################################
98-
# Define dependencies
105+
# Define dependencies - PURE nvImageCodec (minimal dependencies)
99106
################################################################################
100107
superbuild_depend(fmt)
101-
superbuild_depend(libjpeg-turbo) # libjpeg-turbo should be located before libtiff as libtiff depends on libjpeg-turbo
102-
superbuild_depend(libopenjpeg)
103-
superbuild_depend(libtiff)
104-
superbuild_depend(catch2)
108+
# REMOVED: CPU decoder dependencies (nvImageCodec handles all compression)
109+
# superbuild_depend(libjpeg-turbo)
110+
# superbuild_depend(libopenjpeg)
111+
# superbuild_depend(libtiff)
112+
# superbuild_depend(libdeflate)
105113
superbuild_depend(openslide)
114+
# Testing dependencies
115+
superbuild_depend(catch2)
106116
superbuild_depend(googletest)
107117
superbuild_depend(googlebenchmark)
108118
superbuild_depend(cli11)
109119
superbuild_depend(pugixml)
110120
superbuild_depend(json)
111-
superbuild_depend(libdeflate)
112121
superbuild_depend(nvimgcodec)
113122

114123
################################################################################
@@ -131,90 +140,45 @@ find_package(cucim CONFIG REQUIRED
131140
# Define compile options
132141
################################################################################
133142

143+
if(NOT BUILD_SHARED_LIBS)
144+
set(BUILD_SHARED_LIBS ON)
145+
endif()
146+
134147
################################################################################
135148
# Add library: cucim
136149
################################################################################
137150

138-
# NOTE: Commented out for infrastructure-only PR. Will be enabled in follow-up PR
139-
# with actual implementation once source files are added.
140-
# TODO: Uncomment this section when src/ directory is added with implementation
141-
142151
message(STATUS "=============================================================")
143-
message(STATUS "cuslide2 infrastructure validation - Dependencies verified:")
144-
message(STATUS " ✓ fmt")
145-
message(STATUS " ✓ libjpeg-turbo")
146-
message(STATUS " ✓ libopenjpeg")
147-
message(STATUS " ✓ libtiff")
148-
message(STATUS " ✓ libdeflate")
149-
message(STATUS " ✓ nvImageCodec")
150-
message(STATUS " ✓ pugixml")
151-
message(STATUS " ✓ json")
152-
message(STATUS " ✓ openslide")
152+
message(STATUS "cuslide2 PURE nvImageCodec - Dependencies:")
153+
message(STATUS " ✓ fmt (logging)")
154+
message(STATUS " ✓ nvImageCodec (GPU-accelerated JPEG/JPEG2000/deflate/LZW)")
155+
message(STATUS " ✓ pugixml (XML metadata parsing)")
156+
message(STATUS " ✓ json (JSON metadata)")
157+
message(STATUS " ✓ openslide (for testing)")
158+
message(STATUS " ✓ googletest, catch2, googlebenchmark, cli11 (testing)")
153159
message(STATUS "")
154-
message(STATUS "Infrastructure setup complete!")
155-
message(STATUS "Next step: Add src/ directory with cuslide2 implementation")
160+
message(STATUS "Build configured: Pure GPU-accelerated decoding with tests!")
156161
message(STATUS "=============================================================")
157162

158-
# For infrastructure-only PR: Create a dummy target so build succeeds
159-
# This will be replaced with actual library in follow-up PR
160-
add_custom_target(${CUCIM_PLUGIN_NAME}
161-
COMMAND ${CMAKE_COMMAND} -E echo "cuslide2 infrastructure-only: No library to build - dependencies verified"
162-
COMMENT "Infrastructure-only build - no plugin binary generated"
163-
)
164-
165-
# TODO: Replace dummy target with real library when source files exist
166-
if(FALSE) # Change to TRUE when source files exist
167-
# Add library
168-
# Use local src/ implementation with nvImageCodec support
169-
set(CUSLIDE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide)
170-
add_library(${CUCIM_PLUGIN_NAME} MODULE
171-
${CUSLIDE_SRC_DIR}/cuslide.cpp
172-
${CUSLIDE_SRC_DIR}/cuslide.h
173-
${CUSLIDE_SRC_DIR}/deflate/deflate.cpp
174-
${CUSLIDE_SRC_DIR}/deflate/deflate.h
175-
${CUSLIDE_SRC_DIR}/jpeg/libjpeg_turbo.cpp
176-
${CUSLIDE_SRC_DIR}/jpeg/libjpeg_turbo.h
177-
${CUSLIDE_SRC_DIR}/jpeg/libnvjpeg.cpp
178-
${CUSLIDE_SRC_DIR}/jpeg/libnvjpeg.h
179-
${CUSLIDE_SRC_DIR}/jpeg2k/color_conversion.cpp
180-
${CUSLIDE_SRC_DIR}/jpeg2k/color_conversion.h
181-
${CUSLIDE_SRC_DIR}/jpeg2k/color_table.h
182-
${CUSLIDE_SRC_DIR}/jpeg2k/libopenjpeg.cpp
183-
${CUSLIDE_SRC_DIR}/jpeg2k/libopenjpeg.h
184-
${CUSLIDE_SRC_DIR}/loader/nvjpeg_processor.cpp
185-
${CUSLIDE_SRC_DIR}/loader/nvjpeg_processor.h
186-
${deps-libopenjpeg_SOURCE_DIR}/src/bin/common/color.c # for color_sycc_to_rgb() and color_apply_icc_profile()
187-
${CUSLIDE_SRC_DIR}/lzw/lzw.cpp
188-
${CUSLIDE_SRC_DIR}/lzw/lzw.h
189-
${CUSLIDE_SRC_DIR}/lzw/lzw_libtiff.cpp
190-
${CUSLIDE_SRC_DIR}/lzw/lzw_libtiff.h
191-
${CUSLIDE_SRC_DIR}/raw/raw.cpp
192-
${CUSLIDE_SRC_DIR}/raw/raw.h
193-
${CUSLIDE_SRC_DIR}/tiff/ifd.cpp
194-
${CUSLIDE_SRC_DIR}/tiff/ifd.h
195-
${CUSLIDE_SRC_DIR}/tiff/tiff.cpp
196-
${CUSLIDE_SRC_DIR}/tiff/tiff.h
197-
${CUSLIDE_SRC_DIR}/tiff/types.h
198-
# nvImageCodec decoder implementation
199-
${CUSLIDE_SRC_DIR}/nvimgcodec/nvimgcodec_decoder.cpp
200-
${CUSLIDE_SRC_DIR}/nvimgcodec/nvimgcodec_decoder.h
201-
${CUSLIDE_SRC_DIR}/nvimgcodec/nvimgcodec_manager.h
202-
${CUSLIDE_SRC_DIR}/nvimgcodec/nvimgcodec_tiff_parser.cpp
203-
${CUSLIDE_SRC_DIR}/nvimgcodec/nvimgcodec_tiff_parser.h)
204-
205-
# compile color.c for libopenjpeg with c++
206-
set_source_files_properties(${deps-libopenjpeg_SOURCE_DIR}/src/bin/common/color.c
207-
PROPERTIES
208-
LANGUAGE C
209-
CMAKE_CXX_VISIBILITY_PRESET default
210-
CMAKE_C_VISIBILITY_PRESET default
211-
CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
212-
213-
# Ignore warnings in existing source code from libjpeg-turbo
214-
set_source_files_properties(${CUSLIDE_SRC_DIR}/jpeg/libjpeg_turbo.cpp
215-
PROPERTIES
216-
COMPILE_OPTIONS "-Wno-error" # or, "-Wno-write-strings;-Wno-clobbered"
217-
)
163+
# Add library - PURE nvImageCodec implementation (no CPU fallbacks)
164+
add_library(${CUCIM_PLUGIN_NAME}
165+
# Main plugin interface
166+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/cuslide.cpp
167+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/cuslide.h
168+
# TIFF structure management (uses nvImageCodec for parsing)
169+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/tiff/ifd.cpp
170+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/tiff/ifd.h
171+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/tiff/tiff.cpp
172+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/tiff/tiff.h
173+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/tiff/types.h
174+
# nvImageCodec decoding and TIFF parsing (GPU-accelerated)
175+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/nvimgcodec/nvimgcodec_decoder.cpp
176+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/nvimgcodec/nvimgcodec_decoder.h
177+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/nvimgcodec/nvimgcodec_manager.h
178+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/nvimgcodec/nvimgcodec_tiff_parser.cpp
179+
${CMAKE_CURRENT_SOURCE_DIR}/src/cuslide/nvimgcodec/nvimgcodec_tiff_parser.h)
180+
181+
# No special source file properties needed for pure nvImageCodec implementation
218182

219183
# Compile options
220184
set_target_properties(${CUCIM_PLUGIN_NAME}
@@ -229,25 +193,30 @@ target_compile_features(${CUCIM_PLUGIN_NAME} PRIVATE cxx_std_17)
229193
# Use generator expression to avoid `nvcc fatal : Value '-std=c++17' is not defined for option 'Werror'`
230194
target_compile_options(${CUCIM_PLUGIN_NAME} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Werror -Wall -Wextra>)
231195

232-
# Link libraries
196+
# Link libraries - PURE nvImageCodec (no CPU decoder dependencies)
233197
target_link_libraries(${CUCIM_PLUGIN_NAME}
234198
PRIVATE
235199
deps::fmt
236200
cucim::cucim
237-
deps::libtiff
238-
deps::libjpeg-turbo
239-
deps::libopenjpeg
240-
deps::libopenjpeg-lcms2
241201
deps::pugixml
242202
deps::json
243-
deps::libdeflate
244-
$<TARGET_NAME_IF_EXISTS:deps::nvimgcodec>
203+
deps::nvimgcodec
245204
)
246205

247-
# Add nvImageCodec compile definition if the target exists
206+
# Add nvImageCodec compile definition if the target exists and has content
248207
if(TARGET deps::nvimgcodec)
249-
target_compile_definitions(${CUCIM_PLUGIN_NAME} PRIVATE CUCIM_HAS_NVIMGCODEC)
250-
message(STATUS "✓ nvImageCodec enabled - GPU-accelerated JPEG/JPEG2000 decoding available")
208+
get_target_property(NVIMGCODEC_LOCATION deps::nvimgcodec IMPORTED_LOCATION)
209+
get_target_property(NVIMGCODEC_INTERFACE_LINK deps::nvimgcodec INTERFACE_LINK_LIBRARIES)
210+
211+
# Check if it's a real target (has location or interface links) vs dummy target
212+
if(NVIMGCODEC_LOCATION OR NVIMGCODEC_INTERFACE_LINK OR TARGET nvimgcodec::nvimgcodec)
213+
target_compile_definitions(${CUCIM_PLUGIN_NAME} PRIVATE CUCIM_HAS_NVIMGCODEC)
214+
message(STATUS "✓ nvImageCodec enabled - GPU-accelerated JPEG/JPEG2000 decoding available")
215+
else()
216+
message(STATUS "⚠ nvImageCodec target exists but is dummy - GPU acceleration disabled")
217+
endif()
218+
else()
219+
message(STATUS "⚠ nvImageCodec target not found - GPU acceleration disabled")
251220
endif()
252221
if (TARGET CUDA::nvjpeg_static)
253222
target_link_libraries(${CUCIM_PLUGIN_NAME}
@@ -271,7 +240,8 @@ target_include_directories(${CUCIM_PLUGIN_NAME}
271240
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
272241
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
273242
PRIVATE
274-
${CMAKE_CURRENT_SOURCE_DIR}/src
243+
${CMAKE_CURRENT_SOURCE_DIR}/../cucim.kit.cuslide/src
244+
${CMAKE_CURRENT_SOURCE_DIR}/src # Include cuslide2 src for nvimgcodec headers
275245
)
276246

277247
# Do not generate SONAME as this would be used as plugin
@@ -291,67 +261,63 @@ set_target_properties(${CUCIM_PLUGIN_NAME} PROPERTIES OUTPUT_NAME "${CUCIM_PLUGI
291261

292262
################################################################################
293263
# Add tests
294-
#########################################################std#######################
295-
# NOTE: Commented out for infrastructure-only PR. Will be enabled in follow-up PR
296-
# with actual implementation.
297-
# add_subdirectory(tests)
298-
# add_subdirectory(benchmarks)
264+
################################################################################
265+
add_subdirectory(tests)
266+
add_subdirectory(benchmarks)
299267

300268
################################################################################
301269
# Install
302270
################################################################################
303-
# NOTE: Disabled for infrastructure-only PR
304-
# TODO: Uncomment when library target exists
305-
# set(INSTALL_TARGETS
306-
# ${CUCIM_PLUGIN_NAME}
307-
# # cuslide_tests # Disabled for infrastructure-only PR
308-
# # cuslide_benchmarks # Disabled for infrastructure-only PR
309-
# )
310-
#
311-
# install(TARGETS ${INSTALL_TARGETS}
312-
# EXPORT ${CUCIM_PLUGIN_NAME}-targets
313-
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
314-
# COMPONENT ${CUCIM_PLUGIN_NAME}_Runtime
315-
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
316-
# COMPONENT ${CUCIM_PLUGIN_NAME}_Runtime
317-
# NAMELINK_COMPONENT ${CUCIM_PLUGIN_NAME}_Development
318-
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
319-
# COMPONENT ${CUCIM_PLUGIN_NAME}_Development
320-
# )
321-
#
322-
# # Currently cuslide plugin doesn't have include path so comment out
323-
# # install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
324-
# install(EXPORT ${CUCIM_PLUGIN_NAME}-targets
325-
# FILE
326-
# ${CUCIM_PLUGIN_NAME}-targets.cmake
327-
# NAMESPACE
328-
# ${PROJECT_NAME}::
329-
# DESTINATION
330-
# ${CMAKE_INSTALL_LIBDIR}/cmake/${CUCIM_PLUGIN_NAME})
331-
#
332-
# # Write package configs
333-
# include(CMakePackageConfigHelpers)
334-
# configure_package_config_file(
335-
# ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config.cmake.in
336-
# ${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config.cmake
337-
# INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CUCIM_PLUGIN_NAME}
338-
# )
339-
# write_basic_package_version_file(
340-
# ${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config-version.cmake
341-
# VERSION ${PROJECT_VERSION}
342-
# COMPATIBILITY AnyNewerVersion
343-
# )
344-
# install(
345-
# FILES
346-
# ${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config.cmake
347-
# ${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config-version.cmake
348-
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CUCIM_PLUGIN_NAME}
349-
# )
350-
#
351-
#
352-
# set(CMAKE_EXPORT_PACKAGE_REGISTRY ON)
353-
# export(PACKAGE ${CUCIM_PLUGIN_NAME})
354-
355-
endif() # End of if(FALSE) block for infrastructure-only PR
271+
set(INSTALL_TARGETS
272+
${CUCIM_PLUGIN_NAME}
273+
cuslide_tests
274+
cuslide_benchmarks
275+
)
276+
277+
install(TARGETS ${INSTALL_TARGETS}
278+
EXPORT ${CUCIM_PLUGIN_NAME}-targets
279+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
280+
COMPONENT ${CUCIM_PLUGIN_NAME}_Runtime
281+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
282+
COMPONENT ${CUCIM_PLUGIN_NAME}_Runtime
283+
NAMELINK_COMPONENT ${CUCIM_PLUGIN_NAME}_Development
284+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
285+
COMPONENT ${CUCIM_PLUGIN_NAME}_Development
286+
)
287+
288+
# Currently cuslide plugin doesn't have include path so comment out
289+
# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
290+
install(EXPORT ${CUCIM_PLUGIN_NAME}-targets
291+
FILE
292+
${CUCIM_PLUGIN_NAME}-targets.cmake
293+
NAMESPACE
294+
${PROJECT_NAME}::
295+
DESTINATION
296+
${CMAKE_INSTALL_LIBDIR}/cmake/${CUCIM_PLUGIN_NAME})
297+
298+
# Write package configs
299+
include(CMakePackageConfigHelpers)
300+
configure_package_config_file(
301+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config.cmake.in
302+
${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config.cmake
303+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CUCIM_PLUGIN_NAME}
304+
)
305+
write_basic_package_version_file(
306+
${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config-version.cmake
307+
VERSION ${PROJECT_VERSION}
308+
COMPATIBILITY AnyNewerVersion
309+
)
310+
install(
311+
FILES
312+
${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config.cmake
313+
${CMAKE_CURRENT_BINARY_DIR}/cmake/${CUCIM_PLUGIN_NAME}-config-version.cmake
314+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CUCIM_PLUGIN_NAME}
315+
)
316+
317+
318+
set(CMAKE_EXPORT_PACKAGE_REGISTRY ON)
319+
export(PACKAGE ${CUCIM_PLUGIN_NAME})
320+
321+
# REMOVED: endif() - no longer needed since we removed the if(TRUE) wrapper
356322

357323
unset(BUILD_SHARED_LIBS CACHE)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#
2+
# Copyright (c) 2020, NVIDIA CORPORATION.
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
16+
################################################################################
17+
# Add executable: cuslide_benchmarks
18+
################################################################################
19+
add_executable(cuslide_benchmarks main.cpp config.h)
20+
#set_source_files_properties(main.cpp PROPERTIES LANGUAGE CUDA) # failed with CLI11 library
21+
22+
set_target_properties(cuslide_benchmarks
23+
PROPERTIES
24+
CXX_STANDARD 17
25+
CXX_STANDARD_REQUIRED YES
26+
CXX_EXTENSIONS NO
27+
)
28+
target_compile_features(cuslide_benchmarks PRIVATE ${CUCIM_REQUIRED_FEATURES})
29+
# Use generator expression to avoid `nvcc fatal : Value '-std=c++17' is not defined for option 'Werror'`
30+
target_compile_options(cuslide_benchmarks PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Werror -Wall -Wextra>)
31+
target_compile_definitions(cuslide_benchmarks
32+
PUBLIC
33+
CUSLIDE_VERSION=${PROJECT_VERSION}
34+
CUSLIDE_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
35+
CUSLIDE_VERSION_MINOR=${PROJECT_VERSION_MINOR}
36+
CUSLIDE_VERSION_PATCH=${PROJECT_VERSION_PATCH}
37+
CUSLIDE_VERSION_BUILD=${PROJECT_VERSION_BUILD}
38+
)
39+
target_link_libraries(cuslide_benchmarks
40+
PRIVATE
41+
cucim::cucim
42+
deps::googlebenchmark
43+
deps::openslide
44+
deps::cli11
45+
)

0 commit comments

Comments
 (0)